2015-09-16 15:49:20 microsoftMSDNNET 阅读数 2634
  • ARKit视觉风暴

    课程介绍 本套课程从技术理念到项目实践,教大家系统掌握ARKit技术开发,随心打造iOS端AR增强现实应用。由一开始的开发环境搭建,到Unity ARKit Plugin、ARFoundation ARKit等不同时期技术的讲解。从平面模型放置、识别图片、手势交互、3D物体识别、面部AR贴纸、光照估计、环境探针、多人 AR技术,甚至包含ARKit3.0的动作捕捉技术等。除了以上课程内容,更加入了随着技术更新与时俱进更新的ARKit连载技术教学内容。 课程收益 轻松理解ARKit的技术原理,从零到一创建自己的第一个AR项目。 学习Unity ARKit Plugin经典技术,了解ARKit中的常见概念和原理。 学会在 ARFoundation 中使用ARKit,进行企业级AR项目开发。 学会如何在AR项目里播放模型动画,通过触屏手势交互实现模型的旋转和缩放。 了解ARKit的图片识别,掌握AR卡片、AR书籍的实现方法。 学会使用面部增强技术,实现热门短视频应用的AR贴纸效果,实现面部表情追踪。 学会使用ARKit物体检测技术,实现3D物体识别,可以广泛应用于工业、建筑、古董、玩具手办、艺展览等不同场景。 学习ARKit中的经典交互案例,优化AR项目的用户体验。 熟练使用环境纹理、光照估计技术,让AR内容随当前现实场景自动变化调节,看起来更加真实。 基于World Map、Collaborative Session AR技术,实现AR场景的持久化及多人AR体验效果。

    18 人正在学习 去看看 翟喜峰

Unity3D中UI图片模糊,不清晰解决怎么解决
很久没写博文,今天刚好有同事问到:NGUI为什么做的界面图片那么模糊,比美术给的图片相比不是很清晰。
其实这个问题解决方法很简单,只要把NGUI生成的图集的图片类型改成“GUI”或者“Advance”(去掉generate mip maps),而且Filter Mode都选择(Point)。
这样即可。

2019-12-10 19:48:49 zhunju0089 阅读数 32
  • ARKit视觉风暴

    课程介绍 本套课程从技术理念到项目实践,教大家系统掌握ARKit技术开发,随心打造iOS端AR增强现实应用。由一开始的开发环境搭建,到Unity ARKit Plugin、ARFoundation ARKit等不同时期技术的讲解。从平面模型放置、识别图片、手势交互、3D物体识别、面部AR贴纸、光照估计、环境探针、多人 AR技术,甚至包含ARKit3.0的动作捕捉技术等。除了以上课程内容,更加入了随着技术更新与时俱进更新的ARKit连载技术教学内容。 课程收益 轻松理解ARKit的技术原理,从零到一创建自己的第一个AR项目。 学习Unity ARKit Plugin经典技术,了解ARKit中的常见概念和原理。 学会在 ARFoundation 中使用ARKit,进行企业级AR项目开发。 学会如何在AR项目里播放模型动画,通过触屏手势交互实现模型的旋转和缩放。 了解ARKit的图片识别,掌握AR卡片、AR书籍的实现方法。 学会使用面部增强技术,实现热门短视频应用的AR贴纸效果,实现面部表情追踪。 学会使用ARKit物体检测技术,实现3D物体识别,可以广泛应用于工业、建筑、古董、玩具手办、艺展览等不同场景。 学习ARKit中的经典交互案例,优化AR项目的用户体验。 熟练使用环境纹理、光照估计技术,让AR内容随当前现实场景自动变化调节,看起来更加真实。 基于World Map、Collaborative Session AR技术,实现AR场景的持久化及多人AR体验效果。

    18 人正在学习 去看看 翟喜峰

详细讲解篇幅可能有点长,直接上图和资源(实现的具体步骤往下看)

GIF图看起来有点卡顿, 实际上运行是流畅的。

码云:https://gitee.com/NCAA_admin/Alert.git

具体实现步骤

1.创建一个背景图片Background并设置相应属性值

2.设置Canvas的属性和Game窗口的比例

3.创建一个弹窗的遮罩蒙版 名为Alert的Image,参数设置如下

4.在Alert下创建一个弹出的信息框 名为Message的Image,各参数设置如下

5.在Message下创建一个文本对象 Text,参数设置如下

6.接在也在Alert下创建两个按钮 Confirm和Cancel

7.其中两个按钮的Text参数分别如下

8.创建一个Shader的蒙版,在Assets下创建Shaders文件夹,在Shaders文件夹下创建名为Blur的Shader脚本

10.Shader脚本,内容如下(关于Shader的实现原理和步骤,有时间再做一个专题的解析)

// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'

Shader "Custom/Blur"
{
	// 属性
	Properties
	{
		// 定义 1-255 范围的半径 默认 1
		_Radius("Radius", Range(1, 255)) = 1
	}

	Category
	{
		Tags{ "Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType" = "Opaque" }

		SubShader
	{

	GrabPass
	{
		Tags{ "LightMode" = "Always" }
	}

	Pass
	{
		Tags{ "LightMode" = "Always" }
		
		CGPROGRAM
		#pragma vertex vert
		#pragma fragment frag
		#pragma fragmentoption ARB_precision_hint_fastest
		#include "UnityCG.cginc"

	struct appdata_t
	{
		float4 vertex : POSITION;
		float2 texcoord: TEXCOORD0;
	};

	struct v2f
	{
		float4 vertex : POSITION;
		float4 uvgrab : TEXCOORD0;
	};

	v2f vert(appdata_t v)
	{
		v2f o;
		o.vertex = UnityObjectToClipPos(v.vertex);
#if UNITY_UV_STARTS_AT_TOP
		float scale = -1.0;
#else
		float scale = 1.0;
#endif
		o.uvgrab.xy = (float2(o.vertex.x, o.vertex.y*scale) + o.vertex.w) * 0.5;
		o.uvgrab.zw = o.vertex.zw;
		return o;
	}

	sampler2D _GrabTexture;
	float4 _GrabTexture_TexelSize;
	float _Radius;

	half4 frag(v2f i) : COLOR
	{
		half4 sum = half4(0,0,0,0);

#define GRABXYPIXEL(kernelx, kernely) tex2Dproj( _GrabTexture, UNITY_PROJ_COORD(float4(i.uvgrab.x + _GrabTexture_TexelSize.x * kernelx, i.uvgrab.y + _GrabTexture_TexelSize.y * kernely, i.uvgrab.z, i.uvgrab.w)))

		sum += GRABXYPIXEL(0.0, 0.0);
		int measurments = 1;

		for (float range = 0.1f; range <= _Radius; range += 0.1f)
		{
			sum += GRABXYPIXEL(range, range);
			sum += GRABXYPIXEL(range, -range);
			sum += GRABXYPIXEL(-range, range);
			sum += GRABXYPIXEL(-range, -range);
			measurments += 4;
		}

		return sum / measurments;
	}
		ENDCG
	}
		GrabPass
	{
		Tags{ "LightMode" = "Always" }
	}

		Pass
	{
		Tags{ "LightMode" = "Always" }

		CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma fragmentoption ARB_precision_hint_fastest
#include "UnityCG.cginc"

		struct appdata_t
	{
		float4 vertex : POSITION;
		float2 texcoord: TEXCOORD0;
	};

	struct v2f
	{
		float4 vertex : POSITION;
		float4 uvgrab : TEXCOORD0;
	};

	v2f vert(appdata_t v)
	{
		v2f o;
		o.vertex = UnityObjectToClipPos(v.vertex);
#if UNITY_UV_STARTS_AT_TOP
		float scale = -1.0;
#else
		float scale = 1.0;
#endif
		o.uvgrab.xy = (float2(o.vertex.x, o.vertex.y*scale) + o.vertex.w) * 0.5;
		o.uvgrab.zw = o.vertex.zw;
		return o;
	}

	sampler2D _GrabTexture;
	float4 _GrabTexture_TexelSize;
	float _Radius;

	half4 frag(v2f i) : COLOR
	{

		half4 sum = half4(0,0,0,0);
		float radius = 1.41421356237 * _Radius;

#define GRABXYPIXEL(kernelx, kernely) tex2Dproj( _GrabTexture, UNITY_PROJ_COORD(float4(i.uvgrab.x + _GrabTexture_TexelSize.x * kernelx, i.uvgrab.y + _GrabTexture_TexelSize.y * kernely, i.uvgrab.z, i.uvgrab.w)))

		sum += GRABXYPIXEL(0.0, 0.0);
		int measurments = 1;

		for (float range = 1.41421356237f; range <= radius * 1.41; range += 1.41421356237f)
		{
			sum += GRABXYPIXEL(range, 0);
			sum += GRABXYPIXEL(-range, 0);
			sum += GRABXYPIXEL(0, range);
			sum += GRABXYPIXEL(0, -range);
			measurments += 4;
		}

		return sum / measurments;
	}
		ENDCG
	}
	}
	}
}

11.在Assets下创建一个名Materials文件夹,在Materials文件夹下创建名为MaskBlur的Material材质

12.在Alert下指定MaskBlur材质,并设置材质的模糊值为5

13.为了使交互效果具有动画的过度感,在编辑器顶部的菜单栏中 Windows>Asset Store 下打开资源商店

14.搜索DoTween关键词,并进入下载

15.下载完成后点击导入即可

16.在Assets下创建Scripts文件夹,在Scripts下创建Alert.cs脚本

17.Alert.cs脚本内容

using UnityEngine;
using DG.Tweening;
using UnityEngine.UI;
using UnityEngine.EventSystems;
//显示Alert会话
public class Alert : MonoBehaviour
{
    public static Alert Instance;
    private void Awake()
    {
        Instance = this;
    }
    [Tooltip("会话对象")] public RectTransform m_alert;
    //获取ui blur(alert)初始大小
    private Vector2 _uiBlurSize;
    //获取ui blur(alert)初始scale
    private Vector2 _uiBlurScale;
    //透明遮罩层
    private RectTransform _transparentMask;
    //透明遮罩层的初始颜色值值
    private Color _transparentMaskColor;
    //获取confirm
    private RectTransform _confirm;
    //获取confirm初始大小
    private Vector2 _confirmSize;
    //获取confirm初始scale
    private Vector2 _confirmScale;
    //获取text对象
    private Text _text;
    //获取text的大小
    private Vector2 _textSize;
    //获取text scale
    private Vector2 _textScale;
    void Start()
    {
        //判断并且赋值
        if (!m_alert)
        {
            m_alert = transform.GetComponent<RectTransform>();
        }
        //获取uiblur(alert)初始大小
        _uiBlurSize = m_alert.rect.size;
        _uiBlurScale = m_alert.localScale;
        //获取透明遮罩层
        _transparentMask = m_alert.GetChild(0).GetComponent<RectTransform>();
        //透明遮罩层的颜色
        _transparentMaskColor = _transparentMask.GetComponent<Image>().color;
        //获取confirm
        _confirm = m_alert.GetChild(1).GetComponent<RectTransform>();
        //获取confirm初始大小
        _confirmSize = _confirm.rect.size;
        _confirmScale = _confirm.localScale;
        //获取text对象
        _text = _confirm.GetChild(0).GetComponent<Text>();
        //获取text的大小
        _textSize = _text.GetComponent<RectTransform>().rect.size;
        _textScale = _text.rectTransform.localScale;
        //确定取消按钮
        _Confirm();
        _Cancel();
        //初始设置隐藏
        if (m_hideOnStart)
            _SetHideImmediate();
    }

    /// <summary>
    /// 无动画立即隐藏
    /// </summary>
    public void _SetHideImmediate()
    {
        //设置隐藏
        m_alert.gameObject.SetActive(false);
        _confirm.gameObject.SetActive(false);
        _text.gameObject.SetActive(false);
        _transparentMask.gameObject.SetActive(false);
        //宽高设置0
        m_alert.DOScale(Vector3.zero, 0);
        _confirm.DOScale(Vector3.zero, 0);
        //设置遮罩层alpha = 0
        _transparentMask.GetComponent<Image>().DOFade(0, 0);
    }
    /// <summary>
    /// 开始时为隐藏状态
    /// </summary>
    [Tooltip("开始时为隐藏状态")]
    public bool m_hideOnStart = true;
    /// <summary>
    /// 隐藏
    /// </summary>
    public void _SetHide()
    {
        //设置隐藏
        _text.gameObject.SetActive(false);
        //宽高设置0
        m_alert.DOScale(Vector2.zero, _SetShow_duration)
            .onComplete = () =>
            {
                m_alert.gameObject.SetActive(false);
            };
        _confirm.DOScale(Vector2.zero, _SetShow_duration)
            .onComplete = () =>
            {
                _confirm.gameObject.SetActive(false);
            };
        //隐藏透明遮罩层
        _transparentMask.GetComponent<Image>().DOFade(0, _SetShow_duration)
            .onComplete = () =>
            {
                _transparentMask.gameObject.SetActive(false);
            };
    }
    /// <summary>
    /// 显示
    /// </summary>
    public void _SetShow()
    {
        //设置显示
        m_alert.gameObject.SetActive(true);
        _confirm.gameObject.SetActive(true);
        _transparentMask.gameObject.SetActive(true);
        //宽高设置成初始大小+5%再回到原来的大小
        m_alert.DOScale(_uiBlurScale + _uiBlurScale * 0.05f, _SetShow_duration)
            .onComplete = () =>
            {
                //完成后回到初始大小 时间为原来的1/5
                m_alert.DOScale(_uiBlurScale, _SetShow_duration / 5f);
            };
        _confirm.DOScale(_confirmScale + _confirmScale * 0.05f, _SetShow_duration)
            .onComplete = () =>
            {
                //完成后回到初始大小 时间为原来的1/5
                _confirm.DOScale(_confirmScale, _SetShow_duration / 5f);
                //并且显示text
                _text.gameObject.SetActive(true);
            };
        //显示透明遮罩层
        _transparentMask.GetComponent<Image>().DOFade(_transparentMaskColor.a, _SetShow_duration);
    }
    /// <summary>
    /// 显示动画时间
    /// </summary>
    private float _SetShow_duration = 0.3f;

    /// <summary>
    /// 按钮的hover效果
    /// </summary>
    /// <param name="button">按钮</param>
    public void _OnHover(Transform button)
    {
        if (!m_inited)
        {
            m_inited = true;
            //获取初始大小
            m_initialScale = transform.GetComponent<RectTransform>().localScale.x;
        }
        if (!button.GetComponent<EventTrigger>()) button.gameObject.AddComponent<EventTrigger>();
        EventTrigger trigger = button.GetComponent<EventTrigger>();
        EventTrigger.Entry entry = new EventTrigger.Entry();
        entry.eventID = EventTriggerType.PointerEnter;
        entry.callback = new EventTrigger.TriggerEvent();
        entry.callback.AddListener(delegate (BaseEventData baseEvent) {
            button.GetComponent<RectTransform>().DOScale(m_localScale, 0.3f);
        });
        trigger.triggers.Add(entry);

        EventTrigger.Entry entry2 = new EventTrigger.Entry();
        entry2.eventID = EventTriggerType.PointerExit;
        entry2.callback = new EventTrigger.TriggerEvent();
        entry2.callback.AddListener(delegate (BaseEventData baseEvent) {
            button.GetComponent<RectTransform>().DOScale(m_initialScale, 0.3f);
        });
        trigger.triggers.Add(entry2);
    }
    /// <summary>
    /// 变大尺度默认1
    /// </summary>
    [Tooltip("变大尺度默认1.2f")]
    public float m_localScale = 1.2f;
    /// <summary>
    /// 初始的大小
    /// </summary>
    private float m_initialScale;
    /// <summary>
    /// 是否被初始化
    /// </summary>
    private bool m_inited = false;

    /// <summary>
    /// 确定
    /// </summary>
    public void _Confirm()
    {
        _OnHover(m_confirm);
        m_confirm.GetComponent<Button>().onClick.AddListener(delegate {
            _SetHide();
        });
    }
    /// <summary>
    /// 确定按钮
    /// </summary>
    [Tooltip("确定按钮")]
    public Transform m_confirm;
    /// <summary>
    /// 取消按钮
    /// </summary>
    public void _Cancel()
    {
        _OnHover(m_cancel);
        m_cancel.GetComponent<Button>().onClick.AddListener(delegate {
            _SetHide();
        });
    }
    [Tooltip("取消按钮")]
    public Transform m_cancel;

}

18.将Alert.cs脚本拖拽到Alert对象上,并分别将Confirm和Cancel对象拖拽到Alert对应的组件上

19.再在Assets>Scripts文件夹下新建键盘事件的脚本 KeyEvent.cs

20.KeyEvent.cs脚本内容

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class KeyEvent : MonoBehaviour
{
    /// <summary>
    /// 获取Alert组件
    /// </summary>
    private Alert alert;
    void Start()
    {
        //实例化组件
        alert = Alert.Instance;
    }

    void Update()
    {
        //键盘事件
        _KeyDown();
    }

    /// <summary>
    /// 按下键盘执行
    /// </summary>
    public void _KeyDown()
    {
        if (Input.GetKeyDown(KeyCode.Escape))
        {
            alert._SetShow();
        }
    }

}

21.在Hierarchy下新建一个脚本管理器的空物体Script,并将KeyEvent.cs脚本附在其上

22.为了让Hierarchy下的组件的层次更加明显,分别新建了三个空物体,具体如下

23.最后运行游戏,按下Esc键弹出信息框

结束:GIF效果图请看文章顶部!

2018-09-26 20:37:03 qq_37003027 阅读数 82
  • ARKit视觉风暴

    课程介绍 本套课程从技术理念到项目实践,教大家系统掌握ARKit技术开发,随心打造iOS端AR增强现实应用。由一开始的开发环境搭建,到Unity ARKit Plugin、ARFoundation ARKit等不同时期技术的讲解。从平面模型放置、识别图片、手势交互、3D物体识别、面部AR贴纸、光照估计、环境探针、多人 AR技术,甚至包含ARKit3.0的动作捕捉技术等。除了以上课程内容,更加入了随着技术更新与时俱进更新的ARKit连载技术教学内容。 课程收益 轻松理解ARKit的技术原理,从零到一创建自己的第一个AR项目。 学习Unity ARKit Plugin经典技术,了解ARKit中的常见概念和原理。 学会在 ARFoundation 中使用ARKit,进行企业级AR项目开发。 学会如何在AR项目里播放模型动画,通过触屏手势交互实现模型的旋转和缩放。 了解ARKit的图片识别,掌握AR卡片、AR书籍的实现方法。 学会使用面部增强技术,实现热门短视频应用的AR贴纸效果,实现面部表情追踪。 学会使用ARKit物体检测技术,实现3D物体识别,可以广泛应用于工业、建筑、古董、玩具手办、艺展览等不同场景。 学习ARKit中的经典交互案例,优化AR项目的用户体验。 熟练使用环境纹理、光照估计技术,让AR内容随当前现实场景自动变化调节,看起来更加真实。 基于World Map、Collaborative Session AR技术,实现AR场景的持久化及多人AR体验效果。

    18 人正在学习 去看看 翟喜峰

在unity3d中,我们经常需要往界面上添加图片,文本,这时候我们就得使用UI了。 creat->uI,里面就有各种各样的UI对象。
在我们设置了各种各样的Text、Button、Image之后,对于小白来说,没有经过他人的手把手操作,要想调整它们的位置是非常困难的。因为,就算通过Scence中的拖拽,在改变画面大小之后,上面的UIGameObject也会到处乱飞。

现在我讲一下解决过程:
第一步:creat->UI->想要的UI;
第二步: 切换到Scence,并且切换到2d视图(位于左上角);
第三步:点击UI对象,在左侧Inspector中,有一个RectTransform,里面左侧有一个四方形的视图;
第四步:点击视图,里面有各种选项,要想使得无论水平,还是垂直方向,UI对象随着画面的大小自动变换位置,适应画面,可以按住shift,选择右下角的图形。同理,若想按别的方向固定变化,可以选择对应的拉伸。

原理:
Anchor(锚点):是由两个Vector2的向量决定的,归化成两个点,分别为Min和Max,两个点确定一个矩形,Min确定左下角坐标,Max确定右上角坐标。
Pivot(中心):Pivot为矩形中心。显示Pivot可以在工具栏中选择Transform Tools的最后一个选项,或者使用快捷键T。

笔记:
1.Transform有 position 和 localPosition 属性,这两个分别代表在世界空间的绝对位置和相对于父级物体的相对位置。RectTransform引入了 anchoredPosition 和 anchoredPosition3D ,它们都是相对位置,但是相对的是自身的Anchor。当锚点全部重合时, anchoredPosition 代表的就是自身Pivot到Anchor的向量。

2.在Screen Space——Overlay的模式下,由于Canvas的世界尺寸与其像素尺寸在数值上相等,因此其rectTransform的position与其在屏幕空间的坐标在数值上也相等。这种模式下,要获取某个RectTransform的屏幕坐标,直接使用position就可以。在Screen Space——Camera的模式和World Space下,RectTransform的渲染与摄像机有关,在获取其屏幕坐标时,需要利用canvas.worldCamera,或者transform.TransformPoint等坐标转换函数进行坐标转换。

2019-07-03 01:16:00 Mr_Sun88 阅读数 396
  • ARKit视觉风暴

    课程介绍 本套课程从技术理念到项目实践,教大家系统掌握ARKit技术开发,随心打造iOS端AR增强现实应用。由一开始的开发环境搭建,到Unity ARKit Plugin、ARFoundation ARKit等不同时期技术的讲解。从平面模型放置、识别图片、手势交互、3D物体识别、面部AR贴纸、光照估计、环境探针、多人 AR技术,甚至包含ARKit3.0的动作捕捉技术等。除了以上课程内容,更加入了随着技术更新与时俱进更新的ARKit连载技术教学内容。 课程收益 轻松理解ARKit的技术原理,从零到一创建自己的第一个AR项目。 学习Unity ARKit Plugin经典技术,了解ARKit中的常见概念和原理。 学会在 ARFoundation 中使用ARKit,进行企业级AR项目开发。 学会如何在AR项目里播放模型动画,通过触屏手势交互实现模型的旋转和缩放。 了解ARKit的图片识别,掌握AR卡片、AR书籍的实现方法。 学会使用面部增强技术,实现热门短视频应用的AR贴纸效果,实现面部表情追踪。 学会使用ARKit物体检测技术,实现3D物体识别,可以广泛应用于工业、建筑、古董、玩具手办、艺展览等不同场景。 学习ARKit中的经典交互案例,优化AR项目的用户体验。 熟练使用环境纹理、光照估计技术,让AR内容随当前现实场景自动变化调节,看起来更加真实。 基于World Map、Collaborative Session AR技术,实现AR场景的持久化及多人AR体验效果。

    18 人正在学习 去看看 翟喜峰

                        Unity3D点击UI图片生成模型预设物


目录

1、博客介绍

2、内容

(1)演示

(2)生成

(3)生成物体移动

 3、推送

4、结语


1、博客介绍

翻出来了之前一个两年前Demo,顺手传上来了,通过点击按钮或者其他UI元素生成模型预设物,并且随鼠标移动。


2、内容

(1)演示

(2)生成

using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;

public class ClickButton : MonoBehaviour {

    public GameObject Cube;

    public GameObject Target;

    private Button _btnCreate;


	void Start () {

	    _btnCreate = GameObject.Find("Button").GetComponent<Button>();
		_btnCreate.AddListener(EventTriggerType.PointerDown,OnDownButton);

	}

    public void OnDownButton(BaseEventData baseEventData)
    {
        GameObject cubePre = Instantiate(Cube);
	    if (Camera.main != null)
	    {
		    Vector3 targetSpace = Camera.main.WorldToScreenPoint(Target.transform.position);
		    cubePre.transform.position= Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, targetSpace.z));
	    }
    }
}

生成脚本,,唯一注意的一点是,鼠标的屏幕坐标转世界坐标的时候,Z值选择场景内的某个物体作为参考值,必须将该物体的坐标转为屏幕坐标,再把转过的Z值组合鼠标点击位置转成世界坐标。

(3)生成物体移动

using UnityEngine;
using System.Collections;

public class CubeDragScript : MonoBehaviour {

	// Use this for initialization
	void Start () {
       
        StartCoroutine(OnMouseDown());
    }
	

    IEnumerator OnMouseDown()
    {
        if (Camera.main != null)
        {
            //三维物体世界坐标转屏幕坐标  
            Vector3 screenSpace = Camera.main.WorldToScreenPoint(transform.position);

            //完成两个步骤 1.由于鼠标的坐标系是2维,需要转换成3维的世界坐标系  

            //            2.只有3维坐标情况下才能来计算鼠标位置与物理的距离,offset即是差值

            //将鼠标屏幕坐标转为世界三维坐标,转换前的屏幕Z值套用Cube转换过得Z值,再算出Cube世界坐标与鼠标世界坐标的差值

            Vector3 offset = transform.position - Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenSpace.z));
        
            while (Input.GetMouseButton(0))

            {
           
                Camera.main.GetComponent<MouseOrbit>().enabled = false;
                
                //得到现在鼠标的屏幕坐标
                Vector3 curScreenSpace = new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenSpace.z);

                //物体的位置就是鼠标的世界坐标 + 差值
                Vector3 curPosition = Camera.main.ScreenToWorldPoint(curScreenSpace) + offset;

                transform.position = curPosition;
                //这个很重要,循环执行
                yield return null; 

            }
        }

        if (Camera.main != null) Camera.main.GetComponent<MouseOrbit>().enabled = true;
    }



}

注释一条条打的很清楚,直接看代码吧,MouseOrbit脚本是控制镜头旋转,拖动物体的时候禁用,需要源码和演示场景的跳转博主Github.


 3、推送

工程Github:https://github.com/KingSun5/Demo_UICreateObj


4、结语

       若是觉得博主的文章写的不错,不妨关注一下博主,点赞一下博文,另博主能力有限,若文中有出现什么错误的地方,欢迎各位评论指摘。

       QQ交流群:806091680(Chinar)

       该群为CSDN博主Chinar所创,推荐一下!我也在群里!

       本文属于原创文章,转载请著名作者出处并置顶!!!!

2016-12-27 12:48:32 xmousez 阅读数 17624
  • ARKit视觉风暴

    课程介绍 本套课程从技术理念到项目实践,教大家系统掌握ARKit技术开发,随心打造iOS端AR增强现实应用。由一开始的开发环境搭建,到Unity ARKit Plugin、ARFoundation ARKit等不同时期技术的讲解。从平面模型放置、识别图片、手势交互、3D物体识别、面部AR贴纸、光照估计、环境探针、多人 AR技术,甚至包含ARKit3.0的动作捕捉技术等。除了以上课程内容,更加入了随着技术更新与时俱进更新的ARKit连载技术教学内容。 课程收益 轻松理解ARKit的技术原理,从零到一创建自己的第一个AR项目。 学习Unity ARKit Plugin经典技术,了解ARKit中的常见概念和原理。 学会在 ARFoundation 中使用ARKit,进行企业级AR项目开发。 学会如何在AR项目里播放模型动画,通过触屏手势交互实现模型的旋转和缩放。 了解ARKit的图片识别,掌握AR卡片、AR书籍的实现方法。 学会使用面部增强技术,实现热门短视频应用的AR贴纸效果,实现面部表情追踪。 学会使用ARKit物体检测技术,实现3D物体识别,可以广泛应用于工业、建筑、古董、玩具手办、艺展览等不同场景。 学习ARKit中的经典交互案例,优化AR项目的用户体验。 熟练使用环境纹理、光照估计技术,让AR内容随当前现实场景自动变化调节,看起来更加真实。 基于World Map、Collaborative Session AR技术,实现AR场景的持久化及多人AR体验效果。

    18 人正在学习 去看看 翟喜峰

在上一篇文章里 Unity3D - 你导入的资源,并不是Unity使用的资源 介绍过,Unity使用的资源是你无法直接操作的,那么对于图片资源,我们应该如何去处理和优化工作流程呢?

图片资源的分类

在Unity中,图片一般可以分为两种:贴图(Texture)和精灵(Sprite)。我们可以简单的理解为3D(模型使用的)图片和2D(UI使用的)图片。在可以直接选择Texture Type去更改你的导入方式。

  • Texture
    • Texture一般作为3D模型上的贴图,需要有对应的材质球并关联到相应3D网格模型去使用。一般来说Texture会是一个长宽像素都是2的n次方的正方形,这也是大部分建模软件(如maya)规定的POT(Power Of Tow)。
    • 不过并不是说非POT图片就不能使用,只是在Unity的压缩上会很吃亏,而且你导入后Unity仍然会以POT方式去生成对应的图片。
    • POT实际上可以是长方形,只要长宽都是POT就可以,但是大部分建模软件上都会使用正方形。
  • Sprite
    • Sprite一般作为UI上的图片,一般不会去制作对应的材质球。在UGUI上一般是拖动到相应的控件上就可以了。
    • Sprite是一个资源导入的方式,一个资源导入后并非只能是单个Sprite,在Sprite Mode选项上可以选择Multiple去生成多个Sprite,不过需要在Sprite Editor选项上对图片进行切割,通常需要美术参与。
    • Sprite一般对大小不会做限制,UI需要多大就用多大,但是Unity在压缩上,对4的倍数分辨率的图片支持上会更好一点(应该是方便图片在POT下的位置计算),所以在制作时可以对PS的画布大小进行适当调整。
    • Sprite在导入设置完成后建议使用 Sprite Packer 进行打包,如果你确定不打包。。。那么建议你做成POT。。。
    • 在使用 Sprite Packer 打包图集后你会发现,Unity生成的图片都是POT的。

MiniMap

图片资源在导入为Sprite后,我们可以看到一个MiniMap选项,该选项是生成该图片的低分辨图片(1/2,1/4,1/8。。。),这些小图会使生成的资源文件变大1/3,但是在3D渲染时Unity会根据物体显示的大小(或者距离?)自动选择不同的分辨率以提高渲染效率。
一般来说,Sprite不会有这种需求,所以关闭这个选项可以减少包体的大小。

而对于Texture,同样可以取消。Texture和Sprite实际上只是Unity的两种预设,当你在Texture Mode上选择Advance时,你会有很完全的导入选项。如果你确定你的3D物体不会有很多的远近变化时,选择Advance,取消MiniMap会是一个很正确的选择。而对于一般的3D物体,MiniMap带来的效率提高是值得你和用户去花费这点储存空间的。

资源的源文件格式

既然Unity可以使用PSD,那么你何必让美术去导出png呢?
PSD在导入速度上不比png和jpg慢(理论上应该会快,没测试),不过文件大小确实会变大。但是如果直接使用PSD,并要求美术直接在项目目录里进行资源管理和维护,实际上是在团队流程中省出了所有不必要的压缩格式文件(再次强调,导入资源使用的文件大小并不会影响最终的包体大小 )。
当然如果经常出现美术破坏项目目录结构的情况(上传非必要文件,命名不规范等),还是把文件发给程序比较好,而这种情况使用psd还是png那就见仁见智了,psd没有预览还是很难受的。(一般程序猿学PSD的基本操作比美术学SVN或者Unity都要快的多)

Sprite Packer + AssetBundle的注意事项

当你在使用AssetBundle时,你的Sprite引用实际上是Sprite Packer生成的图集的引用。所以在AssetBundle上,即便你只使用到一个图集中的一个小像素,Unity也会将该图集完整地打入AssetBundle中。所以Sprite尽量在Bundle的分包基础上去分图集。

unity 3d UI图片切割

阅读数 236

第一改变图片为可切割的有两步

博文 来自: weixin_42116703
没有更多推荐了,返回首页