標籤:public dir tar his update har isp led unity
背景
上一篇通過滑鼠移動的代碼很簡單,所以看的人也不多,但是還是要感謝“武裝三藏”在部落格園給出的評論和支援,希望他也能看到第二篇,其實可以很簡單,而且是精靈自控制,關鍵是代碼少是我喜歡的方式,也再次印證了Unity3d的複雜性(同樣的功能多次封裝),代碼如下:
public class DebugTest : MonoBehaviour{RectTransform m_Rect;void Start (){m_Rect = GetComponent<RectTransform>();}void Update(){if(Input.GetMouseButtonUp(0)){m_Rect.position = Input.mousePosition;}}}
效果如下(由於效果基本相似,接上一篇的預覽圖):
這一篇主要解決上一篇最後提出的問題,也就是通過這樣滑鼠移動物體時不夠平滑的,不管有多遠都是瞬移過去的,視覺體驗不夠優秀。
本文旨在通過Update中逐幀移動。達到平滑移動的效果
原理
1、記錄滑鼠點擊的點,這個點是如果是螢幕座標
2、將這個螢幕座標轉換成全局座標
3、使用滑鼠的全局座標-精靈的全局座標||也可以使用滑鼠的本地座標-精靈的本地座標
4、通過3獲得移動方向,做插值在Update裡面移動精靈
5、移動精靈可以使用全局座標移動,也可以通過local本地座標移動
實現1
通過UGUI 事件系統中的IPointerClickHandler實現滑鼠點擊,然後在Update中逐幀移動,所有座標使用LocalPosition,原理很簡單這裡代碼不囉嗦
private RectTransform childPlayTransform; private float speed =10.0f; private Vector2 pointClickPostion; private Vector3 currentLocalPostion; private Vector3 moveDirect; // Use this for initialization void Start () { //獲得Image的Transform childPlayTransform = transform.Find("Image").GetComponent<RectTransform>(); } // Update is called once per frame void 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; //在矩形範圍內檢測,全域滑鼠點擊點,到local點的轉換 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(); }
實現2
通過Unity3d 輸入系統Input輸入得滑鼠位置,然後再Update中使用全局座標進行精靈的逐幀平移,代碼如下:
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 frame void Update () { spriteCurentPoistion = spriteTransform.position; //向量加法(向滑鼠方向) targetPosition = direction * speed + spriteCurentPoistion; spriteTransform.position = targetPosition; } public void OnPointerClick(PointerEventData eventData) { Vector3 mouseWorldPointer = new Vector3(eventData.position.x, eventData.position.y, 0); //螢幕座標轉換成全局座標 //Vector3 mouseWorldPointer = Camera.main.ScreenToWorldPoint(mouseScreenPointer); //向量減法獲得指向滑鼠點的方向 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)); }
問題記錄
在實驗的時候遇到一些小問題,特此記錄,也希望高手路過慷慨回答
1、關於進行顯性插值函數
Vector3.Lerp(currentLocalPostion, targetPosition, Time.deltaTime*4f);
實際這是一個公式也很簡單,就是我看教程(Unity3d)的時候Time.deltaTime這個值很大,而實際中發現這個值很小,造成插值的時候很微量的移動,不知為何只能乘以一個係數
2、關於Unity3d的Input輸入的函數提示很弱
比如 eventData.position和Input.mousePosition到底是什麼座標是螢幕座標還是全局座標,文檔模稜兩可並沒有說明
總結
在實現一個如此小的功能,給人深刻影響的可以使用的方法很多,遇到一些知識點,原理也很簡單,但你不深入卻得不到答案。這個世界就像快餐,變得太快。
【Unity3D基礎】讓物體動起來②--UGUI滑鼠點擊逐幀移動