На сцене есть куб, на нем висит два скрипта - один отвечает за перемещение на определенное расстояние при нажатии кнопок WASD, второй отвечает за увеличение размера куба при соприкосновении с другим кубом с тэгом "Slime".
Скрипт, отвечающий за передвижение:
public class PlayerController : MonoBehaviour
{
public bool _isMoving;
public bool _isNearWall;
public bool _isGrounded;
public Vector3 _moveDirection;
private PlayerMechanics _mechanicsScript;
private void Start()
{
_mechanicsScript = GetComponent<PlayerMechanics>();
}
private void Update()
{
// Устанавливает направление движения
if (Input.GetAxis("Horizontal") < 0) _moveDirection = Vector3.left;
if (Input.GetAxis("Horizontal") > 0) _moveDirection = Vector3.right;
if (Input.GetAxis("Vertical") > 0) _moveDirection = Vector3.forward;
if (Input.GetAxis("Vertical") < 0) _moveDirection = Vector3.back;
// Начаинает перемещение при нажатии кнопки
if (_moveDirection != Vector3.zero && !_isMoving && _isGrounded)
{
StartCoroutine(Move(_moveDirection));
}
}
// Перемещение в направлении движения
private IEnumerator Move(Vector3 moveDirection)
{
_isMoving = true;
Vector3 startPos = transform.position;
Vector3 targetPos = transform.position + 2*moveDirection;
float startSize = _mechanicsScript._sizeLevel;
while (transform.position != targetPos)
{
transform.position = Vector3.MoveTowards(transform.position, targetPos, 3 * Time.deltaTime);
if (startSize != _mechanicsScript._sizeLevel)
{
targetPos.y = startSize + (_mechanicsScript._sizeLevel - 1) / 2;
startSize = _mechanicsScript._sizeLevel;
}
// Возвращение в начальную точку если игрок уперся в стену
if (_isNearWall)
{
yield return new WaitForSeconds(1f);
while (transform.position != startPos)
{
transform.position = Vector3.MoveTowards(transform.position, startPos, 3 * Time.deltaTime);
yield return new WaitForSeconds(Time.deltaTime);
}
yield return new WaitForSeconds(0.2f);
_isMoving = false;
_moveDirection = Vector3.zero;
yield break;
}
//Если не уперся в стену
yield return new WaitForSeconds(Time.deltaTime);
}
yield return new WaitForSeconds(0.2f);
_isMoving = false;
_moveDirection = Vector3.zero;
yield break;
}
// Проверяет соприкосновение с объектами
private void OnCollisionStay(Collision collision)
{
if (collision.gameObject.CompareTag("Wall")) _isNearWall = true;
if (collision.gameObject.CompareTag("Ground")) _isGrounded = true;
}
// Проверяет отсутстие соприкосновения с объектами
private void OnCollisionExit(Collision collision)
{
if (collision.gameObject.CompareTag("Wall")) _isNearWall = false;
if(collision.gameObject.CompareTag("Ground")) _isGrounded = false;
}
}
А это скрипт, отвечающий за увеличение размера:
public class PlayerMechanics : MonoBehaviour
{
public float _sizeLevel = 1;
private void OnCollisionEnter(Collision collision)
{
if (collision.gameObject.CompareTag("Slime"))
{
Destroy(collision.gameObject);
_sizeLevel += 0.4f;
ChangeSize(_sizeLevel);
}
}
private void ChangeSize(float sizeLevel)
{
transform.localScale = new Vector3(1, 1, 1) * sizeLevel;
}
}
Проблема в том, что при изменении размера куба - он начинает бесконечно прыгать на месте.
Мне кажется, что проблема заключается в расположении центра куба по оси Y.
Так как при изменении размера на 0.4 - центр куба также поднимается, но уже на 0.2.
Если Поставить вместо формулы
targetPos.y = startSize + (_mechanicsScript._sizeLevel - 1) / 2;
например что то такое
targetPos.y += 0.2f;
то проблема исчезнет, но до тех пор, пока куб не соприкоснется с большим количеством других кубов одновременно (именно поэтому я попытался вывести формулу, которая будет менять конечную точку по Y в зависимости от размера куба, но она заставляет куб прыгать на месте, как я написал выше)
В чем может заключаться проблема?