標籤:
遊戲中可能經常會遇到需要某個物體跟著滑鼠移動,然後又需要把物體放在某個滑鼠指定的位置
實現方式
Camera.main.WorldToScreenPoint
Camera.main.ScreenToWorldPoint
3D打地鼠執行個體
我這裡用到的素材都比較簡陋,幾乎全是用Unity做的
首先是鎚子
就是兩個Cylinder,在把手的位置放一個空物體用於類比鎚子的動作,命名為Hammer,把鎚子作為Hammer的子物體,給Hammer添加Animation動畫:
在三個主要畫面格位置設定Hammer的Rotation,分布為(45, 0, 0),(-15, 0, 0),(45, 0, 0)
把鎚子頭部的Tag改為Hammer,並添加剛體,勾選UseGravity和IsKinematic,用於觸發打到地鼠事件
然後是地鼠
這裡就用Capsule代替了
然後給Capsule添加Animation動畫,並放在一個空物體上,命名為Mouse,更改Tag為Mouse
為Capsule添加指令碼
1 public class MouseController : MonoBehaviour { 2 3 /// <summary> 4 /// Recycles the mouse. 5 /// </summary> 6 public void RecycleMouse() 7 { 8 // Destroy(transform.parent.gameObject); 9 10 //對象池回收.11 MousePool.Instance.RecycleMouse(transform.parent.gameObject);12 }13 14 //被打到時的觸發方法.15 void OnTriggerEnter(Collider other)16 {17 if(other.tag == "Hammer")18 {19 print("Score");20 RecycleMouse();21 }22 }23 24 }
在四個主要畫面格位置設定Capsule的Position分別為(0, -1, 0),(0, 0, 0),(0, 0, 0),(0, -1, 0)
將Mouse拖為預設體
鎚子的動畫狀態機器:
布置洞口
為了能看到地鼠的出沒,我這裡用PS簡單的做了一張有有透明洞口的png圖片:
<=這裡有一張看不見的圖片。。。
建立一個Material,將Shader該為Transparent/Diffuse,把上面那張圖片拖上去
建立9個Cube,把剛才建立的Material賦予它,改變位置和大小,調整攝像機,最終結果如下:
下面是鎚子上的代碼:
1 public class HammerController : MonoBehaviour { 2 3 Animator anim; 4 Transform head; 5 6 void Start () { 7 anim = this.GetComponent<Animator>(); 8 head = GameObject.Find("Head").transform; 9 }10 11 Vector3 newPosition;12 Vector3 screenPos;13 14 void Update () {15 MouseShow();16 HammerMove();17 }18 19 //記時器.20 float timer = 0;21 22 //地鼠的預設體.23 public GameObject mousePrefab;24 int ranIndexX;25 int ranIndexY;26 27 //Mouse出現的方法.28 void MouseShow()29 {30 timer += Time.deltaTime;31 //每過1s生產一個地鼠.32 if(timer > 1)33 {34 timer -= 1;35 ranIndexX = Random.Range(0, 3);36 ranIndexY = Random.Range(0, 3);37 //通過對象池產生地鼠.38 MousePool.Instance.InstantiateMouse(mousePrefab, new Vector3(ranIndexX * 2, 0, ranIndexY * 2), Quaternion.identity);39 }40 }41 42 //鎚子的移動和動畫控制器.43 void HammerMove()44 {45 if(Input.GetMouseButtonDown(0))46 {47 anim.SetTrigger("Attack");48 }49 50 //將鎚子的座標轉換為其在螢幕上的座標,並保持y軸位置不變.51 screenPos = Camera.main.WorldToScreenPoint(new Vector3(transform.position.x, 1, transform.position.z));52 53 //滑鼠位置.54 newPosition = new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenPos.z);55 56 //將得到的螢幕座標轉換為全局座標.57 transform.position = Camera.main.ScreenToWorldPoint(newPosition);58 }59 60 }
最後是對象池的代碼:
1 public class MousePool { 2 3 //對象池. 4 Dictionary<string, List<GameObject>> pool = new Dictionary<string, List<GameObject>>(); 5 6 //單例模式. 7 private static MousePool instance; 8 public static MousePool Instance { 9 get {10 if(instance == null)11 {12 instance = new MousePool();13 }14 return instance;15 }16 }17 private MousePool(){}18 19 //對象的儲存類別.20 string tags;21 GameObject mouse;22 23 //對象池管理方法.24 public GameObject InstantiateMouse(GameObject prefab, Vector3 position, Quaternion rotation)25 {26 tags = prefab.tag;27 28 //如果對象池中存在該類別並且數位大於0,則從對象池中取出該對象,否則執行個體化一個該對象.29 if(pool.ContainsKey(tags) && pool[tags].Count > 0)30 {31 mouse = pool[tags][0];32 pool[tags].Remove(mouse);33 mouse.transform.position = position;34 mouse.transform.rotation = rotation;35 mouse.SetActive(true);36 }else{37 if(!pool.ContainsKey(tags))38 {39 pool.Add(tags, new List<GameObject>());40 }41 mouse = GameObject.Instantiate(prefab, position, rotation) as GameObject;42 } 43 return mouse;44 }45 46 //回收方法.47 public void RecycleMouse(GameObject mouse)48 {49 pool[mouse.tag].Add(mouse);50 mouse.SetActive(false);51 }52 53 }
好了,遊戲基本完成
網頁版預覽
PC版下載
螢幕座標和全局座標的轉換+對象池技術(3D打地鼠小遊戲)