Untitled
unknown
plain_text
2 years ago
5.2 kB
3
Indexable
Never
using DG.Tweening; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using UnityEditor; using UnityEngine; using static UnityEditor.PlayerSettings; public class Trail { public Vector3 pos; public Quaternion rot; public Trail(Vector3 _pos, Quaternion _rot) { pos = _pos; rot = _rot; } } public class PlayerMovement : MonoBehaviour { [SerializeField] [Range(0, 2)] private float bodyDistance = 0.5f; [SerializeField] [Range(0.05f, 0.2f)] private float speedFrequency = 0.1f; [Range(0.05f, 0.2f)] private float rotationSpeed = 0.1f; private float interactionTime = 0.1f; private float maxAngle = 135f; private Transform tr; private Vector2 inputDir; private List<Transform> bodyPartsList; //Se utiliza para ir guardando las posiciones a las que va cada parte del cuerpo private Dictionary<int, List<Trail>> bodyPartsDic; private float timeElapsed; private bool newBodyAdded; private bool canRotate; private void Awake() { tr = transform; bodyPartsDic = new Dictionary<int, List<Trail>>(); } private void Update() { timeElapsed += Time.deltaTime; if (timeElapsed >= interactionTime) { canRotate = true; } } public void StartMovement() { MoveHead(); } public void SetMoveDirection(Vector2 _inputDir) { inputDir = _inputDir; } public void UpdateBodyParts(List<Transform> _bodyParts) { int indexPart = _bodyParts.Count - 1; int targetToFollow = _bodyParts.Count - 2; bodyPartsDic.Add(indexPart, new List<Trail>()); bodyPartsList = _bodyParts; if (indexPart > 0) { Trail r = new Trail(bodyPartsList[indexPart].position, bodyPartsList[indexPart].rotation); bodyPartsDic[targetToFollow].Add(r); newBodyAdded = true; } } private void MoveHead() { tr.DOMove(tr.position + (tr.forward * bodyDistance), speedFrequency).SetEase(Ease.Linear).OnComplete(() => { //si soy el único de la fila, no guardo mi posición if (bodyPartsList.Count > 1) { Trail r = new Trail(tr.position, tr.rotation); bodyPartsDic[0].Add(r); } if (newBodyAdded) { newBodyAdded = false; MoveBody(bodyPartsList[^1]); } if (canRotate) { CheckRotation(); } MoveHead(); }); } private void CheckRotation() { Vector3 desiredDirection = new Vector3(Mathf.Round(inputDir.x), 0, Mathf.Round(inputDir.y)); if (desiredDirection != Vector3.zero) { float angle = Vector3.Angle(tr.forward, desiredDirection); Quaternion desiredRot = Quaternion.identity; if (angle <= maxAngle && angle != 0) { if (desiredDirection == Vector3.forward) { desiredRot = Quaternion.Euler(0, 0, 0); } else if (desiredDirection == Vector3.back) { desiredRot = Quaternion.Euler(0, 180, 0); } else if (desiredDirection == Vector3.right) { desiredRot = Quaternion.Euler(0, 90, 0); } else if (desiredDirection == Vector3.left) { desiredRot = Quaternion.Euler(0, -90, 0); } tr.rotation = desiredRot; timeElapsed = 0; canRotate = false; } } } private void MoveBody(Transform bodyPart) { int bodyIndex = bodyPartsList.IndexOf(bodyPart); int targetToFollowIndex = bodyIndex - 1; if (bodyPartsDic.ContainsKey(bodyIndex)) { bodyPart.DOMove(bodyPartsDic[targetToFollowIndex][0].pos, speedFrequency).SetEase(Ease.Linear). OnComplete(() => OnCompleteMoveBody(bodyPart, targetToFollowIndex)); } } private void OnCompleteMoveBody(Transform bodyPart, int targetToFollowIndex) { bodyPartsDic[targetToFollowIndex].RemoveAt(0); //Si no soy el último de la fila, guardo mi posición if (bodyPartsList[^1] != bodyPart) { Trail r = new Trail(bodyPart.position, bodyPart.rotation); bodyPartsDic[targetToFollowIndex + 1].Add(r); } CheckBodyRotation(bodyPart, bodyPartsDic[targetToFollowIndex][0].rot); MoveBody(bodyPart); } private void CheckBodyRotation(Transform bodyPart, Quaternion targetToFollow) { if (bodyPart.rotation != targetToFollow) { bodyPart.DORotateQuaternion(targetToFollow, rotationSpeed).SetDelay(speedFrequency * 0.5f); } } }