using TMPro; using UnityEngine; using UnityEngine.InputSystem; [RequireComponent(typeof(Rigidbody))] [RequireComponent(typeof(PlayerInput))] public class PlayerMovement : MonoBehaviour { public PlayerData data; public MapData mapData; public TextMeshProUGUI freeAngleText; public TextMeshProUGUI coordsText; public TextMeshProUGUI directionText; public bool tiledDirection = false; new Rigidbody rigidbody; Vector2 moveInput; Vector3 moveDirection; Transform camTransform; MapData.Direction lastDirection; void Awake() { rigidbody = GetComponent(); var playerInput = GetComponent(); playerInput.actions["Move"].started += OnMove; playerInput.actions["Move"].performed += OnMove; playerInput.actions["Move"].canceled += OnMove; if (Camera.main != null) camTransform = Camera.main.transform; else Debug.LogError("Couldn't find the main camera."); } void Update() { Vector3 camForward = camTransform.forward; camForward.y = 0; camForward.Normalize(); //free moveDirection Vector3 direction = camForward * moveInput.y + camTransform.right * moveInput.x; float angle = Vector3.SignedAngle(Vector3.forward, direction, Vector3.up); freeAngleText.text = "FreeAngle: " + Mathf.RoundToInt(angle); lastDirection = GetDirection(direction); directionText.text = "Direction: " + lastDirection; var coords = mapData.WorldToAxial(transform.position); coordsText.text = "Coords: " + coords + "\nNeighbor: " + MapData.GetNeighbor(coords, lastDirection); if (tiledDirection) { Vector2 neighborCoords = MapData.GetNeighbor(coords, lastDirection); Vector3 neighborWorld = mapData.AxialToWorld(neighborCoords) + Vector3.up * transform.position.y; moveDirection = (neighborWorld - transform.position).normalized * direction.magnitude; }else moveDirection = direction; } float GetRoundAngleOffset(Vector3 direction) { float angle = Vector3.SignedAngle(Vector3.forward, moveDirection, Vector3.up); float deltaAngle = Mathf.Sign(angle) * 29; deltaAngle -= (deltaAngle + angle) % 60; return deltaAngle; } Vector3 RoundedDirection(Vector3 direction) => Quaternion.AngleAxis(GetRoundAngleOffset(direction), Vector3.up) * direction; MapData.Direction GetDirection(Vector3 direction) { float angle = Vector3.SignedAngle(Vector3.forward, direction, Vector3.up); float deltaAngle = GetRoundAngleOffset(direction); int index = (Mathf.RoundToInt(angle + deltaAngle) / 60 + (Mathf.Sign(angle) < 0 ? 6 : 0)) % 6; return (MapData.Direction) index; } void FixedUpdate() { if (moveDirection != Vector3.zero) { rigidbody.MovePosition(rigidbody.position + moveDirection * data.speed * Time.fixedDeltaTime); AlignGroundedRotation(); } } void AlignGroundedRotation() { Quaternion goalRot = Quaternion.LookRotation(moveDirection); Quaternion slerp = Quaternion.Slerp(transform.rotation, goalRot, data.turnSpeed * moveDirection.magnitude * Time.fixedDeltaTime); transform.rotation = slerp; } void OnMove(InputAction.CallbackContext ctx) { Vector2 input = ctx.ReadValue(); if (input.sqrMagnitude > 1f) input.Normalize(); moveInput = input; } void OnDrawGizmos() { Gizmos.color = Color.blue; /*for (float x = -20 ; x < 20; x += 0.5f) for (float z = -20; z < 20; z += 0.5f) { var coords = mapData.WorldToAxial(new Vector2(x, z)); Gizmos.DrawSphere(mapData.AxialToWorld(coords) + Vector3.up, 0.2f); }*/ var nearestAxial = mapData.WorldToAxial(new Vector2(transform.position.x, transform.position.z)); Gizmos.DrawSphere(mapData.AxialToWorld(nearestAxial) + Vector3.up, 0.2f); Gizmos.color = Color.green; var coords = MapData.GetNeighbor(nearestAxial, lastDirection); Gizmos.DrawSphere(mapData.AxialToWorld(coords) + Vector3.up, 0.2f); } }