这集视频主要做了两个事情。一个是重新实现上一节的鼠标控制逻辑,之前使用的是 Unity 自带的事件机制,这一节使用 C# 自带的事件机制;第二个是实现鼠标图标的设置。
1. C# event
我们将原先的 Unity 事件,改为 C# 委托:
- public event Action<Vector3> OnMouseClick;
改完可以发现,之前的代码并没有编译错误,基本的执行逻辑还是相同的。
由于目前委托的机制不像之前 Unity 的事件机制,不可以在 Unity 界面中进行拖拽指定对象,所以我们需要为 OnMouseClick 手动添加委托函数。
委托函数是不会定义在目前的 MouseManager 类里面的。所以为了能设置问题函数,我们将 MouseManager 定义为单例类:
如代码清单 1 所示,我们设置静态的单例类,并设置静态的 GetInstance() 函数用于访问。在 Awake 周期,我们对单例类进行赋值,并保持唯一性。
这边保持单例唯一的逻辑看着怪怪的。不清楚 gameObject 指代什么,先留作问题。
1.1 注册事件
我们新建名叫 PlayerController 的 C# 脚本,并挂载在人物对象上,用于注册人物的鼠标移动事件。
如代码清单 2 所示,在 Awake 生命周期获取人物的 Nav Mesh Agent 组件。MoveToTarget 就是需要注册的事件,它设置 destination 属性,实现移动。在 Start 生命周期我们可以直接访问单例类 MouseManager,来注册想要的事件。
至此,原先的鼠标控制人物移动的功能就“重写”完成了。
2. 设置鼠标指针
我们想实现的功能是:鼠标移动之处,如果是地面,鼠标指针显示一种样式;如果是怪物,指针显示另一种样式;以及其他不同的对象,鼠标指针都会随着指示变化。
鼠标设置可以通过 Cursor.SetCursor 函数实现。其函数原型为:
- void SetCursor(Texture2D texture, Vector2 hotspot, CursorMode cursorMode);
最主要的是第一个 2D 纹理贴图用于指定鼠标的图片。后面参数手册上可以看到,比如 hotspot 为用作目标点的从左上角开始的纹理偏移。
2.1 设置纹理贴图
我们首先挑选一张合适的样式图片,然后拖拽到 Assets 界面。如图 1 所示,我们可以对图片进行设置。Texture Type 设置为 Cursor;Max Size 设置为 32,防止原图片尺寸过大;最后点击 Apply 生效设置。
接着我们在之前的 MouseManager 类添加一个 2D 纹理公开变量:
- public Texture2D m_textureMove;
然后如图 2 所示,将之前设置好的图片拖拽到相应变量上就可以了,非常方便。
2.2 实现功能
当设置好鼠标相关的纹理贴图后,就可以开始实现鼠标样式改变的功能了。之前鼠标控制人物移动的步骤是,先判断鼠标是否进行过点击,然后再发出射线进行判断。但是现在鼠标指针样式的更改需要实时进行设置,因此需要对原先的逻辑进行一些修改。我们需要实时的发出射线进行检测。
如代码清单 3 所示,我们修改了 Update 生命周期中的逻辑(第 51 至 60 行)。这时候需要每次都发射射线(第 53 行),如果有物体碰撞再进行后续设置。SetCursorTexture() 函数中依据碰撞的内容来设置鼠标样式(第 38 行)。DoMouseEvent() 函数中进行原先控制移动的逻辑,如果点击了左键,则控制人物移动。
最终的效果如图 3 所示,可以看到鼠标指针被设置成了想要的样式。