UnityBiz/Assets/scripts/Movement/PlayerMovementController.cs
adamwi1000 e4f8167dd7 bank
bank
2024-09-11 18:59:01 +02:00

250 lines
7.2 KiB
C#

using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.UIElements;
namespace Player.Movement
{
public partial class PlayerMovementController : MonoBehaviour
{
public bool IsGrounded { get; private set; }
public bool IsCrouching { get; private set; }
public bool IsMoving { get; private set; }
public Vector3 Velocity
{
get => _rigidbody.velocity;
set => _rigidbody.velocity = value;
}
public float FrictionCoefficient {
get => frictionCoefficient;
set => frictionCoefficient = value;
}
public Vector3 Position => _rigidbody.position;
// refs
private Rigidbody _rigidbody;
private CapsuleCollider _capsuleCollider;
// private fields
private readonly GroundChecker _groundChecker = new();
private RaycastHit[] _hit;
private RaycastHit _hitMovement;
private float _timeSinceLanding;
private bool _wasGroundedLastFrame;
private void Awake()
{
_rigidbody = GetComponent<Rigidbody>();
_capsuleCollider = GetComponent<CapsuleCollider>();
_document = GetComponent<UIDocument>();
}
private void OnEnable()
{
jumpAction.action.performed += Jump;
slideAction.action.started += SlideStart;
slideAction.action.canceled += SlideEnd;
crouchAction.action.started += CrouchStart;
crouchAction.action.canceled += CrouchEnd;
sprintAction.action.started += SprintStart;
sprintAction.action.canceled += SprintEnd;
}
private void OnDisable()
{
jumpAction.action.performed -= Jump;
slideAction.action.started -= SlideStart;
slideAction.action.canceled -= SlideEnd;
crouchAction.action.started -= CrouchStart;
crouchAction.action.canceled -= CrouchEnd;
sprintAction.action.started -= SprintStart;
sprintAction.action.canceled -= SprintEnd;
}
private void Update()
{
//////// _bank.OpenBankUI();
IsGrounded = _groundChecker.IsGrounded(transform, _capsuleCollider.bounds, extraHeight, out _hit,
groundLayerMask);
// my brain's fried, idek why this works
if (IsGrounded)
{
if (_wasGroundedLastFrame)
{
_timeSinceLanding += Time.deltaTime;
}
else
{
_timeSinceLanding = 0;
}
}
else
{
_timeSinceLanding = 0;
}
_wasGroundedLastFrame = IsGrounded;
IsMovingCheck();
UpdateWhichSurfaceNormalToUse();
SlopeSlidingHandling();
UpdatePlayerRotation();
StaminaSystem();
}
private void UpdatePlayerRotation()
{
transform.rotation = Quaternion.Euler(0, playerCameraController.CameraRotationVector.y, 0);
}
private void IsMovingCheck()
{
var playerInput = moveAction.action.ReadValue<Vector2>();
IsMoving = playerInput.magnitude > 0;
}
private void UpdateWhichSurfaceNormalToUse()
{
float steepestAngle = 0;
var steepestRaycast = _hit[0];
foreach (var raycastHit in _hit)
{
var angle = Vector3.Angle(raycastHit.normal, Vector3.up);
if (angle > steepestAngle)
{
steepestAngle = angle;
steepestRaycast = raycastHit;
}
}
_hitMovement = steepestRaycast;
}
private void SlopeSlidingHandling()
{
_rigidbody.useGravity = !IsGrounded;
}
private void FixedUpdate()
{
SlideSpeedCheck();
if (IsGrounded && !NoFrictionLandTimeframeMet() && !IsMoving)
{
ApplyFriction();
}
if (!IsSliding)
{
Move();
}
}
private bool NoFrictionLandTimeframeMet()
{
return _timeSinceLanding < 0.1f;
}
private void ApplyFriction()
{
var velMag = _rigidbody.velocity.magnitude;
if (velMag <= 0f) return;
var normal = _hitMovement.normal;
var frictionForceMag = frictionCoefficient * velMag;
var counterForce = -_rigidbody.velocity * frictionForceMag / velMag;
counterForce.y = 0;
counterForce = Vector3.ProjectOnPlane(counterForce, normal);
_rigidbody.AddForce(counterForce, ForceMode.VelocityChange);
}
private void Move()
{
var playerInput = moveAction.action.ReadValue<Vector2>();
var movementDirection = new Vector3(playerInput.x, 0, playerInput.y);
var normal = _hitMovement.normal;
var cameraRotationVector = playerCameraController.CameraRotationVector;
cameraRotationVector = new Vector2(0, cameraRotationVector.y);
var cameraRotation = Quaternion.Euler(cameraRotationVector);
var desiredMovementDirection = cameraRotation * movementDirection;
var velocityInDirection = Vector3.Dot(_rigidbody.velocity, desiredMovementDirection);
var missingSpeed = maxMovementSpeed - velocityInDirection;
missingSpeed = Mathf.Clamp(missingSpeed, 0, acceleration);
var force = desiredMovementDirection * missingSpeed;
force = Vector3.ProjectOnPlane(force, normal);
// Debug.Log($"missing speed: {missingSpeed} rb velocity: {_rigidbody.velocity.magnitude} force: {force.magnitude}");
_rigidbody.AddForce(force, ForceMode.VelocityChange);
if (_rigidbody.velocity.magnitude > maxMovementSpeed && !NoFrictionLandTimeframeMet())
{
_rigidbody.velocity = _rigidbody.velocity.normalized * maxMovementSpeed;
}
}
private void OnDrawGizmosSelected()
{
if (!Application.isPlaying) return;
Gizmos.color = IsGrounded ? Color.green : Color.red;
var bounds = _capsuleCollider.bounds;
var toCenter = Vector3.down * (bounds.extents.y / 2);
Gizmos.DrawWireCube(bounds.center + toCenter + Vector3.down * extraHeight / 2,
new Vector3(bounds.size.x,
bounds.extents.y + extraHeight,
bounds.size.z));
Gizmos.color = Color.blue;
Gizmos.DrawLine(_hitMovement.point, _hitMovement.point + _hitMovement.normal * 5);
}
public void Move(Vector3 direction)
{
throw new System.NotImplementedException();
}
public void Teleport(Vector3 position, Quaternion rotation)
{
_rigidbody.position = position;
_rigidbody.rotation = rotation;
}
}
}