/
/玩家运动
/
using UnityEngine;
[RequireComponent(typeof(CapsuleCollider))]
[RequireComponent(typeof(CharacterController))]
[RequireComponent(typeof(Rigidbody))]
public class MyPlayerController : MonoBehaviour
{
//与地面状态 跳跃,下降,接地
public enum GroundState : byte { Jumping, Falling, Grounded }
[Header("人物控制器")]
public CharacterController characterController;
[Header("移动速度")]
[Range(1, 20)]
public float moveSpeedMultiplier = 8f;
[Header("旋转速度")]
[Range(1f, 200f)]
[Tooltip("最大旋转速度")]
public float maxTurnSpeed = 100f;//最大旋转速度
[Range(.5f, 5f)]
[Tooltip("旋转值")]
public float turnDelta = 3f;//旋转值
[Header("跳跃速度")]
[Range(0.1f, 1f)]
[Tooltip("初始跳跃速度")]
public float initialJumpSpeed = 0.2f;//初始跳跃速度
[Range(1f, 10f)]
public float maxJumpSpeed = 5f;//最大跳跃速度
[Range(0.1f, 1f)]
[Tooltip("跳跃值")]
public float jumpDelta = 0.2f;//跳跃值
[Header("自动判断-不要修改")]
[Tooltip("与地面状态")]
public GroundState groundState = GroundState.Grounded;
[Range(-1f, 1f)]
[Tooltip("左右移动值")]
public float horizontal;
[Range(-1f, 1f)]
[Tooltip("前后移动值")]
public float vertical;
[Range(-200f, 200f)]
[Tooltip("旋转速度")]
public float turnSpeed;
[Range(-10f, 10f)]
[Tooltip("跳跃速度")]
public float jumpSpeed;
[Range(-1.5f, 1.5f)]
[Tooltip("动画速度值")]
public float animVelocity;
[Range(-1.5f, 1.5f)]
[Tooltip("动画旋转值")]
public float animRotation;
[Tooltip("速度")]
public Vector3Int velocity;
[Tooltip("方向")]
public Vector3 direction;
void OnValidate()
{
if (characterController == null)
characterController = GetComponent<CharacterController>();
characterController.skinWidth = 0.02f;
characterController.minMoveDistance = 0f;
GetComponent<Rigidbody>().isKinematic = true;
}
void Update()
{
if (!characterController.enabled)
return;
HandleTurning();
HandleJumping();
HandleMove();
// Reset ground state
if (characterController.isGrounded)
groundState = GroundState.Grounded;
else if (groundState != GroundState.Jumping)
groundState = GroundState.Falling;
// Diagnostic velocity...FloorToInt for display purposes
velocity = Vector3Int.FloorToInt(characterController.velocity);
}
/// <summary>
/// 处理旋转
/// </summary>
//在空中转弯也可以…
void HandleTurning()
{
// Q和E相互抵消,使转数减小到0。
if (Input.GetKey(KeyCode.Q))
turnSpeed = Mathf.MoveTowards(turnSpeed, -maxTurnSpeed, turnDelta);
if (Input.GetKey(KeyCode.E))
turnSpeed = Mathf.MoveTowards(turnSpeed, maxTurnSpeed, turnDelta);
// 如果同时按下,将转弯速度降至零。
if (Input.GetKey(KeyCode.Q) && Input.GetKey(KeyCode.E))
turnSpeed = Mathf.MoveTowards(turnSpeed, 0, turnDelta);
// 如果两者都不按,将转弯速度降至零。
if (!Input.GetKey(KeyCode.Q) && !Input.GetKey(KeyCode.E))
turnSpeed = Mathf.MoveTowards(turnSpeed, 0, turnDelta);
transform.Rotate(0f, turnSpeed * Time.deltaTime, 0f);
}
/// <summary>
/// 处理跳跃
/// </summary>
void HandleJumping()
{
// 可变力跳跃。
// 起跳从起飞时的初始动力开始,跳得更高/更远
// 玩家按住空格键。跳跃能力的增加逐渐减少
// 每一帧直到 达到maxJumpSpeed,或者玩家释放空格键,
// 然后变成下落状态,直到落地。
if (groundState != GroundState.Falling && Input.GetKey(KeyCode.Space))
{
if (groundState != GroundState.Jumping)
{
// 初始功率启动跳转。
groundState = GroundState.Jumping;
jumpSpeed = initialJumpSpeed;
}
else
// 跳跃已经开始了……随着时间的推移,向maxJumpSpeed方向增加能量。
jumpSpeed = Mathf.MoveTowards(jumpSpeed, maxJumpSpeed, jumpDelta);
// 如果电源已达到maxJumpSpeed,则更改为下落直到接地。
// /这可以防止在空中时过度使用跳跃力量。
if (jumpSpeed == maxJumpSpeed)
groundState = GroundState.Falling;
}
else if (groundState != GroundState.Grounded)
{
// 处理跑下悬崖和/或玩家释放空格键。
groundState = GroundState.Falling;
jumpSpeed = Mathf.Min(jumpSpeed, maxJumpSpeed);
jumpSpeed += Physics.gravity.y * Time.deltaTime;
}
else
jumpSpeed = Physics.gravity.y * Time.deltaTime;
}
/// <summary>
/// 处理移动
/// </summary>
void HandleMove()
{
// 捕获输入
horizontal = Input.GetAxis("Horizontal");
vertical = Input.GetAxis("Vertical");
// 创建不带jumpSpeed (y轴)的初始方向矢量。
direction = new Vector3(horizontal, 0f, vertical);
// 所以对角扫射不是速度优势。
direction = Vector3.ClampMagnitude(direction, 1f);
// 将方向从局部空间转换为世界空间。
direction = transform.TransformDirection(direction);
// 乘以所需的地面速度。
direction *= moveSpeedMultiplier;
// 添加跳跃速度到方向作为最后一步。
direction.y = jumpSpeed;
// 最后移动角色。
characterController.Move(direction * Time.deltaTime);
}
}
控制人物运动
最新推荐文章于 2025-05-01 23:12:03 发布