码迷,mamicode.com
首页 > 其他好文 > 详细

屏幕坐标和世界坐标的转换+对象池技术(3D打地鼠小游戏)

时间:2015-10-08 23:15:29      阅读:277      评论:0      收藏:0      [点我收藏+]

标签:

游戏中可能经常会遇到需要某个物体跟着鼠标移动,然后又需要把物体放在某个鼠标指定的位置

实现方式

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打地鼠小游戏)

标签:

原文地址:http://www.cnblogs.com/zhenlong/p/4862390.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!