直接修改或者替换PlayerMovement_01.cs
using System. Collections ;
using System. Collections. Generic ;
using UnityEngine ;
public class PlayerMovement_02 : MonoBehaviour
{
private float moveSpeed;
public float walkSpeed = 7 ;
public float sprintSpeed = 10 ;
public float groundDrag = 5 ;
public float playerHeight = 2 ;
public LayerMask whatIsGround;
private bool grounded;
public float jumpForce = 6 ;
public float jumpCooldown = 0.25f ;
public float airMultiplier = 0.4f ;
private bool readyToJump = true ;
public float crouchSpeed = 3.5f ;
public float crouchYScale = 0.5f ;
private float startYScale;
public float maxSlopAngle = 40 ;
private RaycastHit slopeHit;
private bool exitingSlope = true ;
public KeyCode jumpKey = KeyCode. Space;
public KeyCode sprintKey = KeyCode. LeftShift;
public KeyCode crouchKey = KeyCode. LeftControl;
public Transform orientation;
private float h;
private float v;
private Vector3 moveDirection;
private Rigidbody rb;
public MovementState state;
public enum MovementState
{
walking,
sprinting,
crouching,
air
}
private void Start ( )
{
rb = GetComponent < Rigidbody> ( ) ;
rb. freezeRotation = true ;
startYScale = transform. localScale. y;
}
private void Update ( )
{
grounded = Physics. Raycast ( transform. position, Vector3. down, playerHeight * 0.5f + 0.2f , whatIsGround) ;
MyInput ( ) ;
SpeedControl ( ) ;
StateHandler ( ) ;
if ( grounded)
rb. drag = groundDrag;
else
rb. drag = 0 ;
}
private void FixedUpdate ( )
{
MovePlayer ( ) ;
}
private void MyInput ( )
{
h = Input. GetAxisRaw ( "Horizontal" ) ;
v = Input. GetAxisRaw ( "Vertical" ) ;
if ( Input. GetKey ( jumpKey) && readyToJump && grounded)
{
readyToJump = false ;
Jump ( ) ;
Invoke ( nameof ( ResetJump) , jumpCooldown) ;
}
if ( Input. GetKeyDown ( crouchKey) )
{
transform. localScale = new Vector3 ( transform. localScale. x, crouchYScale, transform. localScale. z) ;
rb. AddForce ( Vector3. down * 5f , ForceMode. Impulse) ;
}
if ( Input. GetKeyUp ( crouchKey) )
{
transform. localScale = new Vector3 ( transform. localScale. x, startYScale, transform. localScale. z) ;
}
}
private void MovePlayer ( )
{
moveDirection = orientation. forward * v + orientation. right * h;
if ( OnSlope ( ) && ! exitingSlope)
{
rb. AddForce ( GetSlopeMoveDirection ( ) * moveSpeed * 20f , ForceMode. Force) ;
if ( rb. velocity. y > 0 )
{
rb. AddForce ( Vector3. down * 80f , ForceMode. Force) ;
}
}
else if ( grounded)
{
rb. AddForce ( moveDirection. normalized * moveSpeed * 10f , ForceMode. Force) ;
}
else if ( ! grounded)
{
rb. AddForce ( moveDirection. normalized * moveSpeed * 10f * airMultiplier, ForceMode. Force) ;
}
rb. useGravity = ! OnSlope ( ) ;
}
private void SpeedControl ( )
{
if ( OnSlope ( ) && ! exitingSlope)
{
if ( rb. velocity. magnitude > moveSpeed)
{
rb. velocity = rb. velocity. normalized * moveSpeed;
}
}
else
{
Vector3 flatVel = new Vector3 ( rb. velocity. x, 0f , rb. velocity. z) ;
if ( flatVel. magnitude > moveSpeed)
{
Vector3 limitedVel = flatVel. normalized * moveSpeed;
rb. velocity = new Vector3 ( limitedVel. x, rb. velocity. y, limitedVel. z) ;
}
}
}
private void Jump ( )
{
exitingSlope = true ;
rb. velocity = Vector3. zero;
rb. AddForce ( transform. up * jumpForce, ForceMode. Impulse) ;
}
private void ResetJump ( )
{
readyToJump = true ;
exitingSlope = false ;
}
private void StateHandler ( )
{
if ( grounded && Input. GetKey ( sprintKey) )
{
state = MovementState. sprinting;
moveSpeed = sprintSpeed;
}
else if ( grounded)
{
state = MovementState. walking;
moveSpeed = walkSpeed;
}
else
{
state = MovementState. air;
}
if ( Input. GetKey ( crouchKey) )
{
state = MovementState. crouching;
moveSpeed = crouchSpeed;
}
}
private bool OnSlope ( )
{
if ( Physics. Raycast ( transform. position, Vector3. down, out slopeHit, playerHeight * 0.5f + 0.3f ) )
{
float angle = Vector3. Angle ( Vector3. up, slopeHit. normal) ;
return angle < maxSlopAngle && angle != 0 ;
}
return false ;
}
private Vector3 GetSlopeMoveDirection ( )
{
return Vector3. ProjectOnPlane ( moveDirection, slopeHit. normal) . normalized;
}
}