GameCreator 第三人称摄像头源码简单解析

GameCreator 第三人称摄像头源码简单解析

一. ShotCamera 初步了解

image-20231212233910027

本文解析的是GameCreator中的Shot Camera组件(脚本名为ShotCamera)的 Third Person(脚本类名为ShotTypeThirdPerson);(上图)

对于摄像头的输入模块,可视化编程模块以及属性获取不会涉及;

Third Person中有4个Kernel(以下简称内核), 下面是其在inspector中展示,我们需要记住大致作用和脚本类名

  1. ViewPort(这个是main camera的一些常规设置,在main camera组件中也可发现这些参数):

image-20231212234109415

  1. Look(这个就是指定跟随的目标):

​ inspector:

image-20231212234119197

​ 作用:

​ 脚本类名:ShotSystemLook

  1. Zoom(一般是通过鼠标滚轮缩小与目标的距离):

​ inspector:

image-20231212234129090

​ 作用:

​ 脚本类名:ShotSystemZoom

  1. Orbit(轨道的相关信息):

​ inspector:

image-20231212234136465

​ 作用:

​ 脚本类名:ShotSystemOrbit

如不清楚某个字段有什么作用,可自行查看官方样例,并且自行设置调试;

二. 脚本的继承关系

ShotTypeThirdPerson

类名以I开头的是Interface, 以T开头的是Abstract Class. 以下图中带三角形的箭头是继承, 不带三角形的箭头是组合

class ShotTypeThirdPerson -> abstract class TShotTypeLook -> abstract class TShotType -> interface IShotType

image-20231213000604279

4个内核都继承了TShotSystem

image-20231213001040913

TShotType和TshotSystem之间的依赖关系

image-20231213224949850

ShotCamera中会有个IShotType的字段, 也就是在inspector里面选的第三人称摄像机的接口,

ShotTypeThirdPerson里面有2个实现IShotSystem接口的字段,然后其父类TShotTypeLook也有个实现IShotSystem接口的ShotSystemLook字段;

三. ShotTypeThirdPerson类具体实现

接下来将会着重讲解ShotTypeThirdPerson是如何实现第三人称摄像头的

1. ShotSystemViewport(待补充)
2. ShotSystemLook

脚本位置如下:

image-20240306114659164

ShotTypeThirdPerson是这个类的派生类, 所以也可以点到基类里面找到

image-20240306113953395image-20240306114017380

我们可以在Update里面看到这个类是简单处理了摄像头的朝向, 让他看向目标, 不过后续会被其他update覆盖掉;

image-20240306114046383
3. ShotSystemZoom

脚本位置:image-20240306114608055

ShotTypeThirdPerson是这个类的派生类

image-20240306114454914

这个类里面有3个比较重要的属性:

  1. Level: 表示当前摄像头缩放的比例(0~1)

  2. MinDistance: 表示与目标物体的最小距离

  3. SmoothTime: 表示摄像头缩放到目标缩放的大致时间(用SmoothDamp函数)

image-20240306114925570

在update中, (75行-76行)通过对输入和分辨率的处理, 得到每一帧Level的变化量delta, 然后再用Clamp01()限定在0~1的区别;

最后就是用SmoothDamp()对Level平滑处理:

image-20240306123649176

至此, 我们已经知道了SmoothTime的作用, 但是MinDistance和Level在哪使用我们还不知道, 这2个属性需要在下一个脚本发挥真正作用;

4. ShotSystemOrbit

Orbit译为轨道

该脚本位置不再给出, 其就在ShotTypeThirdPerson中可以点入

image-20240306125420441

在ShotTypeThirdPerson的update中, 我们可以看到函数中先执行了ShotSystemZoom对象的update, 在执行ShotSystemOrbit的update之前我们还要执行ShotSystemOrbit的SyncWithZoom函数;

image-20240306125538533

为了搞清楚SyncWithZoom函数干了啥, 我们需要先了解ShotSystemOrbit类的属性.

ShotSystemOrbit在inspector暴露的属性还是很多滴, 其中MaxRadius意为轨道的最大半径, 其会在SyncWithZoom函数中使用

image-20240306131956807

SyncWithZoom函数中会通过Level缩放程度(0~1)乘上最大半径来获得实际轨道的半径, 并且为了与目标有最小距离, 需要加上最小半径;

这样只在ShotSystemZoom中的剩下2个属性就完成了它们的作用.

image-20240306130029187

接下来就是Orbit脚本自己的update函数

image-20240306134626241

首先168行-180行的 if 语句里面会先处理输入, sensitivityX是vertical垂直方向输入, sensitivityY是horizontal水平方向输入;

if (deltaInput == Vector2.zero)
这个判断语句的意思是没有输入, 就会执行ComputeAlign函数()
这个函数中会用到下面3个属性:
m_AlignWithTarget(对应下图中的AlignWithTarget属性): 
是否开启对齐物体(意思就是如果很长一段时间(Align Delay属性的值)不移动鼠标, 摄像头就会自动移动到人物的背后看向人物,
与卡拉彼丘游戏中的对齐类似,但不是完全相同,卡拉彼丘无论鼠标移动或不移动,只要超过了一定角度过了段时间就会对齐);
m_AlignDelay:时间限制
m_AlignSmoothTime:平滑对齐时间

image-20240306134737086

下面是ComputeAlign函数, 当到达m_AlignDelay时间后, 就会水平目标角度(m_OrbitAnglesTarget.y)进行平滑处理,

image-20240306135308178

前面是没有输入的情况, 如果有输入就要对目标角度进行增加, 如下函数

image-20240306155246812
ConstrainTargetAngles()函数如下, m_MaxPitch是最大的角度,范围是(1,179),除2后就小于90度.
所以x垂直方向角度是小于90度的,
而y水平方向是在(0,360)范围内
image-20240306151142624 image-20240306151424058

完成以上的角度约束后就可以对rotation进行平滑处理;

image-20240306155137387

接下来包括上面一步的操作都是反逻辑的(我们需要先找到摄像头在目标的什么方向,然后从物体的位置推算出摄像头的位置,而不是先得出位置,再得出方向);

GetTargetPosition函数获取到目标的位置;
lookRotation目标角度对应的四元数,将其与(0,0,1)相乘就得到了我们看向目标物体的方向
(其中原理是四元数乘向量就等于向量旋转,沿着四元数对应的角度);
知道这个向量后,由于知道目标位置,就可以知道当前摄像头的位置,然后求出position.
image-20240306155738758

这样我们就完成了跟随玩家的摄像头;

还有1点需要补充的是整个第三人称摄像头是在LateUpdate中由ShotCamera类(继承了mono)调用的;

下图中m_ShotType就是接口IShotType;其是摄像头的接口;

image-20240306164050427

还剩1个疑问,

  1. 摄像头移动位置为什么没有用SmoothDamp

Unity
GameCreator2
  • 作者: Mahiru (联系作者)
  • 发表时间: 2024/03/06 20:45
  • 更新时间: 2024/03/06 21:04
  • 留言 顶部