标签:
游戏中可能经常会遇到需要某个物体跟着鼠标移动,然后又需要把物体放在某个鼠标指定的位置
实现方式
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 }
好了,游戏基本完成
标签:
原文地址:http://www.cnblogs.com/zhenlong/p/4862390.html