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

实现方式

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添加脚本

 public class MouseController : MonoBehaviour {

     /// <summary>
/// Recycles the mouse.
/// </summary>
public void RecycleMouse()
{
// Destroy(transform.parent.gameObject); //对象池回收.
MousePool.Instance.RecycleMouse(transform.parent.gameObject);
} //被打到时的触发方法.
void OnTriggerEnter(Collider other)
{
if(other.tag == "Hammer")
{
print("Score");
RecycleMouse();
}
} }

在四个关键帧位置设置Capsule的Position分别为(0, -1, 0),(0, 0, 0),(0, 0, 0),(0, -1, 0)

将Mouse拖为预设体

锤子的动画状态机:

布置洞口

为了能看到地鼠的出没,我这里用PS简单的做了一张有有透明洞口的png图片:

<=这里有一张看不见的图片。。。

新建一个Material,将Shader该为Transparent/Diffuse,把上面那张图片拖上去

新建9个Cube,把刚才新建的Material赋予它,改变位置和大小,调整摄像机,最终结果如下:

下面是锤子上的代码:

 public class HammerController : MonoBehaviour {

     Animator anim;
Transform head; void Start () {
anim = this.GetComponent<Animator>();
head = GameObject.Find("Head").transform;
} Vector3 newPosition;
Vector3 screenPos; void Update () {
MouseShow();
HammerMove();
} //记时器.
float timer = ; //地鼠的预设体.
public GameObject mousePrefab;
int ranIndexX;
int ranIndexY; //Mouse出现的方法.
void MouseShow()
{
timer += Time.deltaTime;
//每过1s生产一个地鼠.
if(timer > )
{
timer -= ;
ranIndexX = Random.Range(, );
ranIndexY = Random.Range(, );
//通过对象池生成地鼠.
MousePool.Instance.InstantiateMouse(mousePrefab, new Vector3(ranIndexX * , , ranIndexY * ), Quaternion.identity);
}
} //锤子的移动和动画控制器.
void HammerMove()
{
if(Input.GetMouseButtonDown())
{
anim.SetTrigger("Attack");
} //将锤子的坐标转换为其在屏幕上的坐标,并保持y轴位置不变.
screenPos = Camera.main.WorldToScreenPoint(new Vector3(transform.position.x, , transform.position.z)); //鼠标位置.
newPosition = new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenPos.z); //将得到的屏幕坐标转换为世界坐标.
transform.position = Camera.main.ScreenToWorldPoint(newPosition);
} }

最后是对象池的代码:

 public class MousePool  {

     //对象池.
Dictionary<string, List<GameObject>> pool = new Dictionary<string, List<GameObject>>(); //单例模式.
private static MousePool instance;
public static MousePool Instance {
get {
if(instance == null)
{
instance = new MousePool();
}
return instance;
}
}
private MousePool(){} //对象的存储类别.
string tags;
GameObject mouse; //对象池管理方法.
public GameObject InstantiateMouse(GameObject prefab, Vector3 position, Quaternion rotation)
{
tags = prefab.tag; //如果对象池中存在该类别并且数码大于0,则从对象池中取出该对象,否则实例化一个该对象.
if(pool.ContainsKey(tags) && pool[tags].Count > )
{
mouse = pool[tags][];
pool[tags].Remove(mouse);
mouse.transform.position = position;
mouse.transform.rotation = rotation;
mouse.SetActive(true);
}else{
if(!pool.ContainsKey(tags))
{
pool.Add(tags, new List<GameObject>());
}
mouse = GameObject.Instantiate(prefab, position, rotation) as GameObject;
}
return mouse;
} //回收方法.
public void RecycleMouse(GameObject mouse)
{
pool[mouse.tag].Add(mouse);
mouse.SetActive(false);
} }

好了,游戏基本完成

网页版预览

PC版下载

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

  1. Java对象池技术的原理及其实现

    看到一片有关于java 对象基础知识,故转载一下,同时学习一下. 摘 要 本文在分析对象池技术基本原理的基础上,给出了对象池技术的两种实现方式.还指出了使用对象池技术时所应注意的问题. 关键词 对象池 ...

  2. JedisCluster中应用的Apache Commons Pool对象池技术

    对象池技术在服务器开发上应用广泛.在各种对象池的实现中,尤其以数据库的连接池最为明显,可以说是每个服务器必须实现的部分.   apache common pool 官方文档可以参考:https://c ...

  3. Java中的对象池技术

    java中的对象池技术,是为了方便快捷地创建某些对象而出现的,当需要一个对象时,就可以从池中取一个出来(如果池中没有则创建一个),则在需要重复重复创建相等变量时节省了很多时间.对象池其实也就是一个内存 ...

  4. 对象池技术和通用实现GenericObjectPool

    对象池技术其实蛮常见的,比如线程池.数据库连接池 他们的特点是:对象创建代价较高.比较消耗资源.比较耗时: 比如 mysql数据库连接建立就要先建立 tcp三次握手.发送用户名/密码.进行身份校验.权 ...

  5. 基于Netty包中的Recycler实现的对象池技术详解

    一.业务背景 当项目中涉及到频繁的对象的创建和回收的时候,就会出现频繁GC的情况,这时就出现了池化的技术来实现对象的循环使用从而避免对象的频繁回收,Netty包下的Recycler就实现了这一功能.当 ...

  6. 大数据技术之_27_电商平台数据分析项目_02_预备知识 + Scala + Spark Core + Spark SQL + Spark Streaming + Java 对象池

    第0章 预备知识0.1 Scala0.1.1 Scala 操作符0.1.2 拉链操作0.2 Spark Core0.2.1 Spark RDD 持久化0.2.2 Spark 共享变量0.3 Spark ...

  7. 对象池与.net—从一个内存池实现说起

    本来想写篇关于System.Collections.Immutable中提供的ImmutableList里一些实现细节来着,结果一时想不起来源码在哪里--为什么会变成这样呢--第一次有了想写分析的源码 ...

  8. common-pool2对象池(连接池)的介绍及使用

    我们在服务器开发的过程中,往往会有一些对象,它的创建和初始化需要的时间比较长,比如数据库连接,网络IO,大数据对象等.在大量使用这些对象时,如果不采用一些技术优化,就会造成一些不可忽略的性能影响.一种 ...

  9. javascript设计模式学习之四——单例模式,缓存与对象池

    单例模式的定义:确保一个实例,并提供全局访问. 惰性单例的定义:只在需要的时候才创建对象. 在开发中,有些对象往往只需要一个,比如线程池.全局缓存.浏览器中的window对象等. java中的单例 关 ...

随机推荐

  1. PDF转换成Txt

    我的弱智想法是所有能转换成PDF的文件,就都用PDF预览,上传成功后开启一个线程把文档转换成PDF,PDF再转换成txt. 目的是把txt插入索引进行全文检索. 调用的时候 string filePa ...

  2. MATLAB符号极限、导数及级数求和

    作者:长沙理工大学 交通运输工程学院 王航臣 1.函数的极限 函数:limit 功能:求取函数的极限 语法: limit(f) limit(f,x,a) limit(f,x,a,'right') li ...

  3. Netty(6)源码-服务端与客户端创建

    原生的NIO类图使用有诸多不便,Netty向用户屏蔽了细节,在与用户交界处做了封装. 一.服务端创建时序图 步骤一:创建ServerBootstrap实例 ServerBootstrap是Netty服 ...

  4. EXCEL 数字统一转换成文本

    将excel中的数字统一转换成文本形式.即添加‘. 1.点击数据-分列. 2.分隔符号-下一步. 3.选择文本识别符号,如“‘”分号. 4. 选中文本-完成.

  5. iOS正则表达

    问题引入 1.要验证用户输入的密码长度是否满足6~18位的长度 ^.{6,18}$ 2.固定电话都是0区号-八位数字的格式,那么正则表达式的匹配如下 ^0\\d{2}\-?\\d{8}$ 3.对于密码 ...

  6. ArrayList构造函数

    //1.摘要: //初始化 System.Collections.ArrayList 类的新实例,该实例为空并且具有默认初始容量. // public ArrayList(); ArrayList a ...

  7. WPF Application

    Application类作为启动的入口,在VS中,通常自动代码为我们继承了Application类,这样做的有点,我还没有理解到,但是我们先学到这个知识点. 为了能够更好的控制整个启动过程,包括得到A ...

  8. Js的Url中传递中文参数乱码的解决

    一:Js的Url中传递中文参数乱码问题,重点:encodeURI编码,decodeURI解码: 1.传参页面Javascript代码: 2. 接收参数页面:test02.html 二:如何获取Url& ...

  9. layer ifram 弹出框

    父层 <div class="col-xs-4 text-left" style="padding-left: 50px;"><button ...

  10. css3-文字旋转

    <meta charset="utf-8"/><style> * {margin: 0; padding: 0;} ul { height: 80px; b ...