如题,以下是我总结的3种方法:
我尽量将我的笔记遵守三个原则:简洁,清晰,不说废话,并且多是以归纳为主,总结各种方法及其优缺点,这样的话新人也能够在短时间内有条例地学会这些功能(虽然不会很深入就是)。
1.用Transform实现人物移动
这种方法不推荐,虽然很简单常用,但是人物在与碰撞体碰撞时会发生迷之抖动,所以咱们不多讲。
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
public float moveSpeed; // 移动速度
private float verticalInput;
private float horizontalInput;
private Rigidbody rb;
private void Awake()
{
rb = GetComponent<Rigidbody>();
}
private void Update()
{
//固定模版, 不过可以在unity里自己设置 “Vertical”, "Horizontal" 这样的关键字
verticalInput = Input.GetAxis("Vertical");
horizontalInput = Input.GetAxis("Horizontal");
}
private void FixedUpdate()
{
Move();
}
//用 Transform 控制人物移动
void Move()
{
Vector3 moveDir = transform.forward * verticalInput + transform.right * horizontalInput;
transform.position += moveDir * moveSpeed * Time.deltaTime;
}
}
(其实上面的Rigidbody完全可以不要,下文中我们只要改Move()里的代码就行,其他的不变)
2.用Rigidbody实现人物移动
用Rigidbody的话,比较常见的有三种方法,分别是其用 Position、 Velocity、 AddForce。
注意:
①不要忘了在物体上挂载Rigidbody组件。
②像这种跟物理模拟的操作,尽量在FixedUpdate里进行。
③如果没特殊需求的话,记得把Rigidbody组件里的Freeze Rotation 的 x,z 给打上勾,不然走着走着就亲吻大地了。
(1)MovePosition
优点:简单
缺点:①由于MovePosition方法忽略了物理引擎中的力、加速度和碰撞反应等因素,因此无法模拟真实的物理运动。这可能导致人物移动看起来不自然或缺乏真实感
②如果目标位置被障碍物占据,MovePosition方法可能会使人物穿过障碍物,而不是停下来或绕行。
void Move()
{
Vector3 moveDir = transform.forward * verticalInput + transform.right * horizontalInput;
rb.MovePosition(rb.position + moveDir * moveSpeed * Time.deltaTime);
}
(2)Velocity
优点:①简单
②Velocity方法考虑了物理引擎中的力、加速度和碰撞反应等因素,因此可以模拟更真实的物理运动
③通过直接设置速度,可以精确地控制人物的移动速度和方向。这对于实现角色的奔跑、加速和减速等动作非常有用。(像iwanna这种对精度很高的游戏,可以优先考虑用Velocity)
缺点:受到物理引擎中其他因素的影响(如重力、摩擦力等),可能导致人物移动轨迹偏离预期。(比如因为摩擦力卡在墙上)
void Move()
{
Vector3 moveDir = transform.forward * verticalInput + transform.right * horizontalInput;
rb.velocity = new Vector3(moveDir.x * moveSpeed, rb.velocity.y,
moveDir.z * moveSpeed);
}
(3)AddForce
优点:物理效果看起来自然,可以用于人物的跳跃,闪避等
缺点:一般只用于特殊的物件移动,比如:滚球、子弹之类的。
void Move()
{
Vector3 moveDir = transform.forward * verticalInput + transform.right * horizontalInput;
rb.AddForce(moveDir * moveSpeed);
}
3.用CharacterController实现人物移动
CharacterController中有两个用来移动的方法SimpleMove()和Move(),不过SimpleMove()不能实现跳跃,所以咱们直接用 Move() 。
注意:①不要忘了在物体上挂载CharacterController组件。
②CharacterController不自带重力,需要自己在代码中手写一个重力。
最后把它跟Rigidbody做个比较吧:
Rigidbody 可以处理复杂的物理系统,如推动物体等,但不适合处理爬坡和走楼梯
CharacterController恰恰相反,可以轻易处理理爬坡和走楼梯问题,但是不适合处理复杂的物理系统。
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
public float moveSpeed; // 移动速度
private float verticalInput;
private float horizontalInput;
private CharacterController characterController;
private float verticalVelocity;
private void Awake()
{
characterController = GetComponent<CharacterController>();
}
private void Update()
{
//固定模版, 不过可以在unity里自己设置 “Vertical”, "Horizontal" 这样的关键字
verticalInput = Input.GetAxis("Vertical");
horizontalInput = Input.GetAxis("Horizontal");
}
private void FixedUpdate()
{
Move();
}
void Move()
{
Vector3 moveDir = transform.forward * verticalInput + transform.right * horizontalInput;
//添加重力
if (!characterController.isGrounded)//如果人物不着地,则添加重力
{
//下落的速度等于 重力加速度 * 时间
verticalVelocity -= 9.8f * Time.deltaTime;
moveDir.y = verticalVelocity;
}
else
{
//将下落的速度设置为初始值
verticalVelocity = -0.5f;
}
characterController.Move(moveDir * moveSpeed * Time.deltaTime);
}
}
以上就是本次笔记的全部内容,由于本人也是最近开始尝试发博客,所以如果内容如果出现了问题,或者可以改进的地方,麻烦大家在评论区指出啦。
如果你觉得这篇博客对你有帮助的话,请多多点赞、关注、加收藏,谢谢啦!
ヾ(◍°∇°◍)ノ゙