https://medium.com/ironequal/unity-character-controller-vs-rigidbody-a1e243591483
When you’re creating a new project with Unity, one of the first things you have to do is code your avatar’s controller. It’s very important and you can’t rush it or your gamefeel will probably be bad. There are a lot of different things to do, ranging from the inputs acquisition to the movements and feedbacks.
One of the first question I often ask myself is : “Should I use a Character Controller or a Rigidbody? ”. Today, through the example of a simple moving, jumping and dashing avatar, we will explore the two approaches.
Here is a github of the complete project: https://github.com/valgoun/CharacterController
用Unity创建一个新的工程时,要做的第一件事就是编写角色控制器。这很重要,且你无法匆忙的完成否则游戏感受就很差。这儿有很多不同的事情要做,从输入获取到移动和反馈。
我经常问自己的第一件事:我是否应该使用CharacterController,或者使用Rigidbody?今天,通过一个简单的小栗子(包括移动,跳跃,和冲刺),我们将探索这两种处理方式。
这里有github上完整的工程。
The Character Controller approach
Setup
image.png
image.png
地面检测:
CC中已经有一个变量表示是否在地面,但是有些buggy。所以自己来检测是否在地面,通过球形射线(3dgamekit中直接是朝下射线检测)。
_isGrounded = Physics.CheckSphere(_groundChecker.position, GroundDistance, Ground, QueryTriggerInteraction.Ignore);
if (_isGrounded && _velocity.y < 0)
_velocity.y = 0f;
冲刺:
Log曲线见前文https://www.jianshu.com/writer#/notebooks/27042843/notes/55176645
他函数的核心思路
if (Input.GetButtonDown("Dash"))
{
Debug.Log("Dash");
_velocity += Vector3.Scale(transform.forward,
DashDistance * new Vector3((Mathf.Log(1f / (Time.deltaTime * Drag.x + 1)) / -Time.deltaTime),
0,
(Mathf.Log(1f / (Time.deltaTime * Drag.z + 1)) / -Time.deltaTime)));
}
这步所做的事情:根据我们的朝向,把速度乘一个值,这个值依赖两个变量,DashDistance(固定值)及Drag(固定值,8)。我们需要一个Drag来模拟摩擦力否则不会停下来。然后应用这个Drag只需要使用下面的方法:
_velocity.x /= 1 + Drag.x * Time.deltaTime;
_velocity.y /= 1 + Drag.y * Time.deltaTime;
_velocity.z /= 1 + Drag.z * Time.deltaTime;
我的总结及他的总结:
它这个地方最复杂的就是那个数学公式,其实主要分两步,第一步是按下冲刺后初始化了速度,第二步是持续减速直到速度接近0。
第一步和第二步的函数是有一定关系的,我们知道他最后不管角色初速度为多少,最后设定跑了多远,那么就应该跑多远。
由此推断,此处用到了微积分,来实时计算它的速度。
由于微积分都忘了,所以暂且掠过。后面会写微积分的学习笔记。等都学完了再回来看。
image.png
三行简化
image.png
The Rigidbody approach
刚体在fixedupdate中进行物理更新(
This function is called by Unity before every “physic update”.
);锁住xz轴向旋转;
有四种方式給刚体应用力;MovePosition方法可以在遵循碰撞规则的基础上将刚体向目标点移动,同时不会改变刚体已有的速度(可以理解为偷偷的瞬移过去,但是刚体自己不知道,所以速度没变),由此,角色的移动可以与其他物理交互分离。
它的重力和阻力都在刚体上有自带的(这个摩擦力是三个轴向同时应用的与我们自己写的不同)
Main Difference
它们俩都根据碰撞器作出反应,但是有一些轻微的差异:
rigidbody方式会运行的更精确,哪怕使用了物理材质属性来进行计算反应;CC则更方便(宽容):它可以根据参数自动实现爬坡和脚步功能。
扩展
CC更简易一点,但是假如我们想实现更多的功能,刚体方式可能是更好的方式(俺觉得两个可以同时用)。刚体提供了很多物理交互的方式,而这些CC没有,因此假如使用了CC就得在这些方面写更多的代码。