105 lines
3.8 KiB
C#
105 lines
3.8 KiB
C#
using Boxfriend.Extensions;
|
|
using Boxfriend.Input;
|
|
using KinematicCharacterController;
|
|
using UnityEngine;
|
|
|
|
namespace Boxfriend.Player
|
|
{
|
|
[RequireComponent(typeof(InputDispatcher))]
|
|
[RequireComponent(typeof(KinematicCharacterMotor))]
|
|
public class PlayerMotor : MonoBehaviour, ICharacterController
|
|
{
|
|
[SerializeField, InspectorOnly] private KinematicCharacterMotor _characterMotor;
|
|
[SerializeField, InspectorOnly] private InputDispatcher _input;
|
|
[SerializeField, InspectorOnly] private Animator _animator;
|
|
|
|
private bool _isSprinting;
|
|
private float _yRotation;
|
|
private float _gravityVelocity;
|
|
private Vector3 _moveDirection;
|
|
private Vector3 _groundNormal = Vector3.up;
|
|
|
|
[SerializeField, InspectorOnly] private float _moveSpeed;
|
|
[SerializeField, InspectorOnly] private float _defaultGravity;
|
|
[SerializeField, InspectorOnly] private float _jumpForce;
|
|
|
|
|
|
private void Awake ()
|
|
{
|
|
_input.OnLook += OnLook;
|
|
_input.OnMove += OnMove;
|
|
_input.OnJump += OnJump;
|
|
_input.OnSprint += OnSprint;
|
|
|
|
_characterMotor.CharacterController = this;
|
|
}
|
|
|
|
private void OnLook (Vector2 delta) => _yRotation = Mathf.Repeat(_yRotation + delta.x, 360);
|
|
private void OnMove (Vector2 inputDir) => _moveDirection = inputDir.To3D();
|
|
|
|
private void OnSprint (bool sprinting) => _isSprinting = sprinting;
|
|
private void OnJump ()
|
|
{
|
|
if (!_characterMotor.GroundingStatus.IsStableOnGround)
|
|
return;
|
|
|
|
|
|
_characterMotor.ForceUnground();
|
|
_groundNormal = Vector3.up;
|
|
_gravityVelocity = _jumpForce;
|
|
}
|
|
|
|
public void UpdateRotation (ref Quaternion currentRotation, float deltaTime) => currentRotation = Quaternion.Euler(0, _yRotation, 0);
|
|
|
|
public void UpdateVelocity (ref Vector3 currentVelocity, float deltaTime)
|
|
{
|
|
if (!_characterMotor.GroundingStatus.IsStableOnGround)
|
|
{
|
|
_gravityVelocity += _defaultGravity * deltaTime;
|
|
currentVelocity.y = _gravityVelocity;
|
|
return;
|
|
}
|
|
|
|
_gravityVelocity = 0;
|
|
|
|
var moveDir = transform.TransformDirection(_moveDirection);
|
|
var direction = _characterMotor.GetDirectionTangentToSurface(moveDir, _groundNormal);
|
|
direction *= _isSprinting ? _moveSpeed * 1.5f : _moveSpeed;
|
|
direction.y += _gravityVelocity;
|
|
|
|
currentVelocity = direction;
|
|
}
|
|
|
|
public void BeforeCharacterUpdate (float deltaTime) { }
|
|
|
|
public void PostGroundingUpdate (float deltaTime) { }
|
|
|
|
public void AfterCharacterUpdate (float deltaTime)
|
|
{
|
|
_animator.SetFloat("Speed", _moveDirection.z);
|
|
_animator.SetFloat("Turns", _moveDirection.x);
|
|
}
|
|
|
|
public bool IsColliderValidForCollisions (Collider coll) => coll != _characterMotor.Capsule;
|
|
|
|
public void OnGroundHit (Collider hitCollider, Vector3 hitNormal, Vector3 hitPoint,
|
|
ref HitStabilityReport hitStabilityReport) => _groundNormal = hitNormal;
|
|
|
|
public void OnMovementHit (Collider hitCollider, Vector3 hitNormal, Vector3 hitPoint,
|
|
ref HitStabilityReport hitStabilityReport)
|
|
{ }
|
|
|
|
public void ProcessHitStabilityReport (Collider hitCollider, Vector3 hitNormal, Vector3 hitPoint, Vector3 atCharacterPosition,
|
|
Quaternion atCharacterRotation, ref HitStabilityReport hitStabilityReport)
|
|
{ }
|
|
|
|
public void OnDiscreteCollisionDetected (Collider hitCollider) { }
|
|
|
|
private void Reset ()
|
|
{
|
|
_characterMotor = GetComponent<KinematicCharacterMotor>();
|
|
_input = GetComponent<InputDispatcher>();
|
|
}
|
|
}
|
|
}
|