【Unity3D基础】让物体动起来②--UGUI鼠标点击逐帧移动
背景
上一篇通過鼠標(biāo)移動(dòng)的代碼很簡單,所以看的人也不多,但是還是要感謝“武裝三藏”在博客園給出的評(píng)論和支持,希望他也能看到第二篇,其實(shí)可以很簡單,而且是精靈自控制,關(guān)鍵是代碼少是我喜歡的方式,也再次印證了Unity3d的復(fù)雜性(同樣的功能多次封裝),代碼如下:
public class DebugTest : MonoBehaviour { RectTransform m_Rect;void Start () { m_Rect = GetComponent<RectTransform>(); }void Update() { if(Input.GetMouseButtonUp(0)) { m_Rect.position = Input.mousePosition; }}}
效果如下(由于效果基本相似,接上一篇的預(yù)覽圖):
這一篇主要解決上一篇最后提出的問題,也就是通過這樣鼠標(biāo)移動(dòng)物體時(shí)不夠平滑的,不管有多遠(yuǎn)都是瞬移過去的,視覺體驗(yàn)不夠優(yōu)秀。
本文旨在通過Update中逐幀移動(dòng)。達(dá)到平滑移動(dòng)的效果
原理
1、記錄鼠標(biāo)點(diǎn)擊的點(diǎn),這個(gè)點(diǎn)是如果是屏幕坐標(biāo)
2、將這個(gè)屏幕坐標(biāo)轉(zhuǎn)換成世界坐標(biāo)
3、使用鼠標(biāo)的世界坐標(biāo)-精靈的世界坐標(biāo)||也可以使用鼠標(biāo)的本地坐標(biāo)-精靈的本地坐標(biāo)
4、通過3獲得移動(dòng)方向,做插值在Update里面移動(dòng)精靈
5、移動(dòng)精靈可以使用世界坐標(biāo)移動(dòng),也可以通過local本地坐標(biāo)移動(dòng)
實(shí)現(xiàn)1
通過UGUI 事件系統(tǒng)中的IPointerClickHandler實(shí)現(xiàn)鼠標(biāo)點(diǎn)擊,然后在Update中逐幀移動(dòng),所有坐標(biāo)使用LocalPosition,原理很簡單這里代碼不啰嗦
private RectTransform childPlayTransform;private float speed =10.0f;private Vector2 pointClickPostion;private Vector3 currentLocalPostion;private Vector3 moveDirect;// Use this for initializationvoid Start (){//獲得Image的TransformchildPlayTransform = transform.Find("Image").GetComponent<RectTransform>();}// Update is called once per framevoid Update (){currentLocalPostion = childPlayTransform.localPosition;Vector3 targetPosition = moveDirect * speed + currentLocalPostion;childPlayTransform.localPosition = Vector3.Lerp(currentLocalPostion, targetPosition, Time.deltaTime*4f);}public void OnPointerClick(PointerEventData eventData){Vector2 localPoint;//在矩形范圍內(nèi)檢測,全局鼠標(biāo)點(diǎn)擊點(diǎn),到local點(diǎn)的轉(zhuǎn)換RectTransformUtility.ScreenPointToLocalPointInRectangle(transform.GetComponent<RectTransform>() , eventData.position,eventData.enterEventCamera, out localPoint);pointClickPostion = localPoint;moveDirect = new Vector3(pointClickPostion.x, pointClickPostion.y, 0) - currentLocalPostion;moveDirect.z = 0;moveDirect.Normalize();}
實(shí)現(xiàn)2
通過Unity3d 輸入系統(tǒng)Input輸入得鼠標(biāo)位置,然后再Update中使用世界坐標(biāo)進(jìn)行精靈的逐幀平移,代碼如下:
private Transform spriteTransform;Vector3 direction;Vector3 spriteCurentPoistion;Vector3 targetPosition;float speed = 2.0f;void Start () {spriteTransform = transform.Find("Image") as Transform;}// Update is called once per framevoid Update () {spriteCurentPoistion = spriteTransform.position;//向量加法(向鼠標(biāo)方向)targetPosition = direction * speed + spriteCurentPoistion;spriteTransform.position = targetPosition;}public void OnPointerClick(PointerEventData eventData){Vector3 mouseWorldPointer = new Vector3(eventData.position.x, eventData.position.y, 0);//屏幕坐標(biāo)轉(zhuǎn)換成世界坐標(biāo)//Vector3 mouseWorldPointer = Camera.main.ScreenToWorldPoint(mouseScreenPointer);//向量減法獲得指向鼠標(biāo)點(diǎn)的方向direction = mouseWorldPointer - spriteTransform.position;direction.z = 0;direction.Normalize();Debug.Log(string.Format("x:{0},y:{1}-- {2},{3}", mouseWorldPointer.x, mouseWorldPointer.y, eventData.position.x, eventData.position.y));}
問題記錄
在試驗(yàn)的時(shí)候遇到一些小問題,特此記錄,也希望高手路過慷慨回答
1、關(guān)于進(jìn)行顯性插值函數(shù)
Vector3.Lerp(currentLocalPostion, targetPosition, Time.deltaTime*4f);
實(shí)際這是一個(gè)公式也很簡單,就是我看教程(Unity3d)的時(shí)候Time.deltaTime這個(gè)值很大,而實(shí)際中發(fā)現(xiàn)這個(gè)值很小,造成插值的時(shí)候很微量的移動(dòng),不知為何只能乘以一個(gè)系數(shù)
2、關(guān)于Unity3d的Input輸入的函數(shù)提示很弱
比如 eventData.position和Input.mousePosition到底是什么坐標(biāo)是屏幕坐標(biāo)還是世界坐標(biāo),文檔模棱兩可并沒有說明
總結(jié)
在實(shí)現(xiàn)一個(gè)如此小的功能,給人深刻影響的可以使用的方法很多,遇到一些知識(shí)點(diǎn),原理也很簡單,但你不深入?yún)s得不到答案。這個(gè)世界就像快餐,變得太快。
轉(zhuǎn)載于:https://www.cnblogs.com/IlidanStormRage/p/5993772.html
總結(jié)
以上是生活随笔為你收集整理的【Unity3D基础】让物体动起来②--UGUI鼠标点击逐帧移动的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 跨域解决方案大全
- 下一篇: AmazeUI基本样式