背景
首先還是先聲明自己是比較笨的一個人,總是找不到高效的學習方法,目前自己學習Unity3D的方式主要是兩種,一種是直接看高質量的源碼,另一種是光看不行還要自己動手,自己寫一些有代表性的小程序,這也是本文的由來。
誠然,現在已經不是Unity3D發展的黃金期了,很多知識點已經有很多朋友總結分享了,但由於Unity3D的客觀性就是依賴插件很厲害,這樣就會照成插件滿天飛,通用性不強,還有過時的風險,還有就是網上很多朋友發的帖子很多並不是學習總結,只是對於Unity3D IDE的使用及一些API的羅列,或者是一些游戲Demo的完整教程。自己一直想從另一個角度來學習一下,也就是單純從游戲的角度(我們常說的業務邏輯的角度),其實以前很多VC游戲教程都是這種思路,就是從一個很小的功能開始學,逐個知識點積累最后完成一個相對復雜完整的Demo程序。所以本文就從最小的讓物體動起來開始。
說明
文章的視角基本着眼的是從簡單到復雜功能的學習理解,所以是主要是基於2D的,也就是從Untiy2D開始,同時也會穿插一些3D部分,
所以最好使用具有Unity2D功能的Unity3D客戶端,好像是4.3以后吧
效果圖鎮樓
需求描述和分析
本章的需求很簡單,就是“通過在屏幕中點擊鼠標,在2d視圖中控制物體進行移動”。在別的平台和引擎中簡直是Hello world級別的需求在Unity3d中卻變得有些棘手了,主要有幾個問題困擾着我,
1、IO輸入是怎么樣的;
2、鼠標事件是如何接收的;
3、移動動畫是如何實現的;
“原理很簡單,現實很殘酷”,Unity3d的開放性造成了所謂的插件和庫很多,顯得凌亂。這里還是按照自己的慣性思維來了,按照別的平台的教程,
A、首先要有一個容器,
B、在容器上放置需要移動的精靈,
C、通過容器接收鼠標事件,
D、事件驅動精靈移動
這里UGui中采用容器的概念(或者我還不知道別的庫也有),所以先在UGui中實現,
第一步,加一個Panel對象
第二步,導入一個精靈的圖片資源
第三步,加一個2d的Image對象,設置其sprite為剛才導入的圖片資源
第四步,給Panel對象綁定一個腳本,PanelController,
樹結構
加圖資源后
綁定代碼
具體代碼如下
using UnityEngine; using System.Collections; using UnityEngine.EventSystems; public class PanelController: MonoBehaviour , IPointerClickHandler { private Transform childPlayTransform; private Transform parentCanvasTransform; // Use this for initialization void Start () { //獲得Image的Transform childPlayTransform = transform.Find("Image"); parentCanvasTransform = transform.parent; } // Update is called once per frame void Update () { } public void OnPointerClick(PointerEventData eventData) { Debug.Log(string.Format("x:{0},y:{1}", eventData.position.x, eventData.position.y)); Debug.Log(string.Format("button x:{0},y:{1}", childPlayTransform.localPosition.x, childPlayTransform.localPosition.y)); Vector2 localPoint; //在矩形范圍內檢測,全局鼠標點擊點,到local點的轉換 RectTransformUtility.ScreenPointToLocalPointInRectangle(transform as RectTransform, eventData.position, eventData.enterEventCamera, out localPoint); childPlayTransform.localPosition = localPoint; } }
代碼雖然少,但是核心的知識點就是世界坐標、相機坐標和局部坐標的轉換也就是下面的這個函數
// // 摘要: // Does the RectTransform contain the screen point as seen from the given camera? // // 參數: // rect: // The RectTransform to test with. // // screenPoint: // The screen point to test. // // cam: // The camera from which the test is performed from. // // 返回結果: // True if the point is inside the rectangle. public static bool RectangleContainsScreenPoint(RectTransform rect, Vector2 screenPoint, Camera cam); public static bool ScreenPointToLocalPointInRectangle(RectTransform rect, Vector2 screenPoint, Camera cam, out Vector2 localPoint);
總結
雖然功能很少,但是也有幾個知識點,一個是Unity3d的坐標系統,一個是坐標轉換的基礎知識,一個是Unity3d Gui的事件處理方式,特此記錄。功能上有點小缺陷就是精靈的移動是瞬移的,也就是鼠標指到哪里移動到哪里(確實我也沒有看出有什么不平滑),留到下篇繼續吧。