public class 玩家控制器 : MonoBehaviour
{
[Header("移动")]
public float 走速 = 6f;
public float 全速 = 10f;
public float 加速 = 12f;
public float 减速 = 25f;
public float 跳跃力量 = 2f;
public float 重力 = -19.62f;

[Header("耐力设置")]
public Image 耐力条;
public float 最大耐力 = 100f;
public float 耐力耗损 = 20f;
public float 耐力恢复 = 15f;
private float 当前耐力;
private bool 可以冲刺 = true;

[Header("看向")]
publicCamera 玩家相机;
public float 鼠标灵敏度 = 2f;
public float 看向限制 = 85f;

[Header("观察抖动")]
public float 走路抖动量 = 0.05f;
public float sprint抖动量 = 0.1f;
public float 走路抖动速度 = 14f;
public float sprint抖动速度 = 18f;
private float 默认Y坐标 = 0;
private float 计时器;

[Header("梯子设置")]
public float 爬行速度 = 4f;
private bool 是爬行 = false;

private CharacterController 控制器;
private Vector3 速度;
private Vector3 当前移动速度;
private float 垂直旋转 = 0f;
private bool 是否着地;

void Start()
{
    控制器 = GetComponent<CharacterController>();
    当前耐力 = 最大耐力;
    默认Y坐标 = 玩家相机.transform.localPosition.y;

    // 确保碰撞器的底部在模型的.pivot位置
    控制器.center = new Vector3(0, 控制器.height / 2f, 0);

    Cursor.lockState = CursorLockMode.Locked;
    Cursor.visible = false;
}

void Update()
{
    处理旋转();
    处理移动();
    处理耐力();
    处理观察抖动();
}

void HandleRotation()
{
    float 鼠标X = Input.GetAxis("Mouse X") * 鼠标灵敏度;
    float 鼠标Y = Input.GetAxis("Mouse Y") * 鼠标灵敏度;

    transform.Rotate(Vector3.up * 鼠标X);

    垂直旋转 -= 鼠标Y;
    垂直旋转 = Mathf.Clamp(垂直旋转, -看向限制, 看向限制);
    玩家相机.transform.localRotation = Quaternion.Euler(垂直旋转, 0f, 0f);
}

public void SetClimbing(bool 状态)
{
    是爬行 = 状态;
    速度.y = 0;
}

void HandleMovement()
{
    是否着地 = 控制器.isGrounded;

    if (是否着地 && 速度.y < 0)
    {
        速度.y = -2f;
    }

    if (是爬行)
    {
        float vInput = Input.GetAxisRaw("Vertical");
        Vector3爬行方向 = new Vector3(0, vInput * 爬行速度, 0);
        控制器.Move(爬行方向 * Time.deltaTime);
        速度.y = 0;
        return;
    }

    float 移动X = Input.GetAxisRaw("Horizontal");
    float 移动Z = Input.GetAxisRaw("Vertical");
    Vector3 输入方向 = (transform.right * 移动X + transform.forward * 移动Z).normalized;

    bool 是冲刺 = Input.GetKey(KeyCode.LeftShift) && 移动Z > 0 && 当前耐力 > 0 && 可以冲刺;

    float 目标速度 = 0f;
    if (输入方向.magnitude > 0)
    {
        目标速度 = 是冲刺 ? 全速 : 走速;
    }

    float 当前加速 = (输入方向.magnitude > 0) ? 加速 : 减速;
    当前移动速度 = Vector3.MoveTowards(当前移动速度, 输入方向 * 目标速度, 当前加速 * Time.deltaTime);

    if (Input.GetButtonDown("Jump") && 是否着地)
    {
        速度.y = Mathf.Sqrt(跳跃力量 * -2f * 重力);
    }

    速度.y += 重力 * Time.deltaTime;

    Vector3 总运动速度 = 当前移动速度;
    总运动速度.y = 速度.y;

    控制器.Move(总运动速度 * Time.deltaTime);
}

void HandleStamina()
{
    if (Input.GetKey(KeyCode.LeftShift) && 当前移动速度.magnitude > 走速 + 0.1f)
    {
        当前耐力 -= 耐力耗损 * Time.deltaTime;
    }
    else
    {
        当前耐力 += 耐力恢复 * Time.deltaTime;
    }

    当前耐力 = Mathf.Clamp(当前耐力, 0, 最大耐力);
    if (当前耐力 <= 0) 可以冲刺 = false;
    if (当前耐力 >= 20) 可以冲刺 = true;

    if (耐力条 != null) 耐力条.fillAmount = 当前耐力 / 最大耐力;
}

void HandleViewBob()
{
    if (!是否着地 || 是爬行) return;

    if (Mathf.Abs(当前移动速度.x) > 0.1f || Mathf.Abs(当前移动速度.z) > 0.1f)
    {
        bool 是冲刺 = Input.GetKey(KeyCode.LeftShift) && 当前耐力 > 0 && 可以冲刺;
        float 速度 = 是冲刺 ? sprint抖动速度 : 走路抖动速度;
        float 量 = 是冲刺 ? sprint抖动量 : 走路抖动量;

        计时器 += Time.deltaTime * 速度;

        玩家相机.transform.localPosition = new Vector3(
            玩家相机.transform.localPosition.x,
            默认Y坐标 + Mathf.Sin(计时器) * 量,
            玩家相机.transform.localPosition.z);
    }
    else
    {
        计时器 = 0;
        玩家相机.transform.localPosition = new Vector3(
            玩家相机.transform.localPosition.x,
            Mathf.Lerp(玩家相机.transform.localPosition.y, 默认Y坐标, Time.deltaTime * 走路抖动速度),
            玩家相机.transform.localPosition.z);
    }
}

}