295 lines
8.9 KiB
C#
295 lines
8.9 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 UIEvents _uiEvents;
|
|
|
|
// private fields
|
|
private readonly GroundChecker _groundChecker = new();
|
|
private RaycastHit[] _hit;
|
|
private RaycastHit _hitMovement;
|
|
private float _timeSinceLanding;
|
|
private bool _wasGroundedLastFrame;
|
|
private Inventory inventory;
|
|
[SerializeField] private UI_Inventory uiInventory;
|
|
[SerializeField] private GameObject modelPrefab;
|
|
ItemWorld ItemWorld;
|
|
private int cos;
|
|
Item item;
|
|
|
|
private void Awake()
|
|
{
|
|
_rigidbody = GetComponent<Rigidbody>();
|
|
_capsuleCollider = GetComponent<CapsuleCollider>();
|
|
_uiEvents = GetComponent<UIEvents>();
|
|
_document = GetComponent<UIDocument>();
|
|
inventory = new Inventory(); // Inicjalizuj inventory
|
|
|
|
}
|
|
|
|
|
|
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 OnTriggerEnter(Collider collider)
|
|
{
|
|
ItemWorld itemWorld = collider.GetComponent<ItemWorld>();
|
|
inventory = new Inventory();
|
|
uiInventory.SetInventory(inventory);
|
|
itemWorld.DestroySelf();
|
|
}
|
|
private void Update()
|
|
{
|
|
|
|
|
|
if (Input.GetKeyDown(KeyCode.B))
|
|
{
|
|
ItemWorld.SpawnItemWorld(new Vector3(30, 9, 27), new Item { itemType = Item.ItemType.BluePotion, amount = 1 });
|
|
|
|
|
|
}
|
|
|
|
if (Input.GetKeyDown(KeyCode.X))
|
|
{
|
|
DropItem();
|
|
|
|
|
|
}
|
|
if(Input.GetKeyDown(KeyCode.E))
|
|
{
|
|
|
|
inventory = new Inventory();
|
|
uiInventory.SetInventory(inventory);
|
|
|
|
}
|
|
|
|
|
|
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 DropItem()
|
|
{
|
|
if (inventory.GetItemList().Count > 0)
|
|
{
|
|
|
|
Item itemToDrop = inventory.GetItemList()[0]; // Pobierz pierwszy przedmiot z ekwipunku
|
|
inventory.RemoveItem(itemToDrop);
|
|
uiInventory.SetInventory(inventory);
|
|
|
|
|
|
Vector3 dropPosition = transform.position + transform.forward * 3; // Przed graczem
|
|
ItemWorld.SpawnItemWorld(dropPosition, itemToDrop);
|
|
Debug.Log(cos);
|
|
uiInventory.ClearInventoryItems();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
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;
|
|
}
|
|
|
|
}
|
|
}
|