背景
首先還是先聲明自己是比較笨的一個人,總是找不到高效的學習方法,目前自己學習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的事件處理方式,特此記錄。功能上有點小缺陷就是精靈的移動是瞬移的,也就是鼠標指到哪里移動到哪里(確實我也沒有看出有什么不平滑),留到下篇繼續吧。




