Files
2025TapTapGameJam/Assets/Script/Gameplay/Player/PlayerMoveController.cs

133 lines
4.4 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System;
using Core;
using Script.Gameplay.Input;
using UnityEngine;
namespace Script.Gameplay.Player
{
public class PlayerMoveController : MonoBehaviour
{
[Header("Movement Settings")] [Tooltip("移动速度(米/秒)")]
public float speed = 5f;
[Tooltip("跳跃高度(米)")] public float jumpHeight = 2f;
[Tooltip("重力加速度(米/秒²)")] public float gravity = -9.81f;
[Header("Ground Check")] [Tooltip("检测地面的位置(通常为角色脚下)")]
public Transform groundCheck;
[Tooltip("地面检测半径")] public float groundDistance = 0.4f;
[Tooltip("地面层LayerMask")] public LayerMask groundMask;
private float initSpeed;
private CharacterController characterController;
private Vector3 velocity;
private bool isGrounded;
private InputManager inputManager;
private float lastGroundY;
private bool wasGroundedLastFrame;
[Tooltip("从高处落下时的伤害阈值(米)")] [SerializeField]
private float fallDamageThreshold = 3f; //伤害阈值
[Tooltip("推动物体的力量")] [SerializeField]
private float pushPower = 2f;
private void Awake()
{
characterController = GetComponent<CharacterController>();
if (characterController == null)
Debug.LogError("PlayerMoveController 需要 CharacterController 组件!");
initSpeed = speed;
}
private void Start()
{
inputManager = InputManager.Instance;
}
private void Update()
{
// 地面检测
bool isCurrentlyGrounded = groundCheck != null
? Physics.CheckSphere(groundCheck.position, groundDistance, groundMask)
: characterController.isGrounded;
// 记录离开地面时的高度
if (wasGroundedLastFrame && !isCurrentlyGrounded)
{
lastGroundY = transform.position.y;
}
// 落地检测
if (!wasGroundedLastFrame && isCurrentlyGrounded)
{
float fallHeight = lastGroundY - transform.position.y;
if (fallHeight > fallDamageThreshold) // 3米为伤害阈值可调整
{
int damage = Mathf.RoundToInt((fallHeight - 3f) * 10); // 每超出1米伤害10点
var playerController = GetComponent<PlayerController>();
if (playerController != null)
playerController.TakeDamage(damage);
}
}
wasGroundedLastFrame = isCurrentlyGrounded;
// 地面检测
if (groundCheck != null)
isGrounded = Physics.CheckSphere(groundCheck.position, groundDistance, groundMask);
else
isGrounded = characterController.isGrounded;
if (isGrounded && velocity.y < 0)
velocity.y = -2f; // 保持贴地
Vector2 inputMove = inputManager.Move;
// 获取输入
float x = inputMove.x;
float z = inputMove.y;
// 按玩家朝向移动
Vector3 move = transform.right * x + transform.forward * z;
characterController.Move(move * speed * Time.deltaTime);
// 跳跃
if (isGrounded && inputManager.JumpPressed)
{
velocity.y = Mathf.Sqrt(jumpHeight * -2f * gravity);
}
// 重力
velocity.y += gravity * Time.deltaTime;
characterController.Move(velocity * Time.deltaTime);
}
private void OnControllerColliderHit(ControllerColliderHit hit)
{
Rigidbody body = hit.collider.attachedRigidbody;
// 只推动带有刚体且非静态的物体
if (body != null && !body.isKinematic)
{
// 忽略从下方碰撞
if (hit.moveDirection.y < -0.3f) return;
Vector3 pushDir = new Vector3(hit.moveDirection.x, 0, hit.moveDirection.z);
body.AddForce(pushDir * pushPower, ForceMode.Impulse);
}
}
public void SetSpeed(float newSpeed)
{
speed = newSpeed;
}
public void ResetSpeed()
{
speed = initSpeed;
}
}
}