using System.Collections; using System.Collections.Generic; using UnityEngine; public class SnakeMovement : MonoBehaviour { [Header("Child Objects")] [SerializeField] private List<Transform> _bodyParts = new List<Transform>(); [SerializeField] private float _minDistance = .25f; [SerializeField] private float _speed = 2f; [SerializeField] private float _bodyPartSpacing = 5f; //Interal vars private float _distance; private Transform _currBodyPart; private Transform _prevBodyPart; private Rigidbody2D _firstBodyPart; private bool _canMove = true; private Vector3 _newPosition; private float _time; private SpriteRenderer _sprite; private Transform _targetTransform; private Vector3 _relativePoint; private void Start() { if(_bodyParts.Count > 0) _firstBodyPart = _bodyParts[0].GetComponent<Rigidbody2D>(); } // Update is called once per frame void FixedUpdate() { if(_canMove) { for (int i = 1; i < _bodyParts.Count; i++) { //Get a reference the current and previous body part within the loop _currBodyPart = _bodyParts[i]; _prevBodyPart = _bodyParts[i - 1]; //Check the distance between the current and previous body parts _distance = Vector3.Distance(_prevBodyPart.position, _currBodyPart.position); //Calculate a new position _newPosition = _prevBodyPart.position; _newPosition.x = _bodyParts[i - 1].position.x + (_firstBodyPart.transform.localScale.x > 0 ? -_bodyPartSpacing : _bodyPartSpacing); _newPosition.y = _bodyParts[i - 1].position.y; //Calculate the timing for the slerp functions _time = Time.deltaTime * _distance / _minDistance * _speed; //Cap the time if (_time > 0.5f) _time = 0.5f; //Use slerp functions to apply a smooth motion _currBodyPart.position = Vector3.Slerp(_currBodyPart.position, _newPosition, _time); _currBodyPart.rotation = Quaternion.Slerp(_currBodyPart.rotation, _prevBodyPart.rotation, _time); //Lets flip the sprites based on prev body part position _sprite = _bodyParts[i].GetComponent<SpriteRenderer>(); _targetTransform = _bodyParts[i - 1].transform; _relativePoint = _bodyParts[i].transform.InverseTransformPoint(_targetTransform.position); if (_relativePoint.x > 0) _sprite.flipX = false; else _sprite.flipX = true; } } } public void StopSnakeMovement() { _canMove = false; } }