Всё, как в обычном платформере.
И у меня есть игрок.
Передвижение платформы и игрока сделано с помощью velocity.
У игрока и у платформы есть твердое тело. У игрока оно dynamic, у платформы kinematic.
Код написан по ролику с ютуба (не судите за архитектуру, мне самому она не нравится).
Общий смысл кода такой - когда игрок встает на платформу, скрипт игрока получает ссылку на твердое тело платформы.
В кода игрока, из ссылки на твердое тело платформы получаем её velocity и если игрок на платформе складываем velocity игрока и velocity платформы.
Итого, создается иллюзия, что игрок стоит на движущейся платформе, едет вместе с ней.
И всё работает.
Но когда платформа меняет направление - дошла до точки и начинает движение в другую сторону, игрок как бы проскальзывает на платформе, незначительно смещается по инерции в направлении предыдущего движения.
Например - платформа едет слева на право и меняет направление движения на противоположное. В момент смены движения игрок незначительно сместится слева на право, как будто есть инерция.
Это как при резкой остановке машины, пассажир смещается вперед, по ходу движения.
Вот часть кода игрока
Синтаксис:
Используется csharp
private void FixedUpdate()
{
if (PlayerIsOnPlatform == true)
{
// Add the velocity of the player and velocity of the platform, to create the effect of a player riding on a platform.
// platformRigidbody2D - we get from the platform code, when the player enters the platform collider.
float platformSpeed = platformRigidbody2D.velocity.y;
float verticalMovement = platformRigidbody2D.gravityScale > 0 ? platformSpeed : -platformSpeed;
playerRigidbody2D.velocity = new Vector2((horizontalInput * playerRunSpeed) + platformRigidbody2D.velocity.x, verticalMovement);
}
else
{
// Simple player movement on the ground
playerRigidbody2D.velocity = new Vector2(horizontalInput * playerRunSpeed, playerRigidbody2D.velocity.y);
}
}
{
if (PlayerIsOnPlatform == true)
{
// Add the velocity of the player and velocity of the platform, to create the effect of a player riding on a platform.
// platformRigidbody2D - we get from the platform code, when the player enters the platform collider.
float platformSpeed = platformRigidbody2D.velocity.y;
float verticalMovement = platformRigidbody2D.gravityScale > 0 ? platformSpeed : -platformSpeed;
playerRigidbody2D.velocity = new Vector2((horizontalInput * playerRunSpeed) + platformRigidbody2D.velocity.x, verticalMovement);
}
else
{
// Simple player movement on the ground
playerRigidbody2D.velocity = new Vector2(horizontalInput * playerRunSpeed, playerRigidbody2D.velocity.y);
}
}
Вот часть кода платформы
Синтаксис:
Используется csharp
private void Start()
{
targetPosition = positionB.position;
DirectionCalculate();
}
// There may be a bug in this method, a movement inconsistency
private void FixedUpdate()
{
// Задаем движение платформе.
platformRigidbody2D.velocity = platformMoveDirection * platformSpeed;
// Изменяем направление движения платформы на противоположное, если она находится близко к точке слева или справа.
if (Vector2.Distance(transform.position, positionA.position) < 0.05f)
{
targetPosition = positionB.position;
DirectionCalculate();
}
else if (Vector2.Distance(transform.position, positionB.position) < 0.05f)
{
targetPosition = positionA.position;
DirectionCalculate();
}
}
private void DirectionCalculate()
{
platformMoveDirection = (targetPosition - transform.position).normalized;
}
private void OnTriggerEnter2D(Collider2D collision)
{
if (collision.gameObject.CompareTag("PlayerGroundCheck"))
{
// Возможно, игрока не нужно делать частью платформы.
player.transform.SetParent(transform);
playerController.PlatformRigidbody2D = platformRigidbody2D;
playerController.PlayerIsOnPlatform = true;
}
}
private void OnTriggerExit2D(Collider2D collision)
{
if (collision.gameObject.CompareTag("PlayerGroundCheck"))
{
player.transform.SetParent(null);
playerController.PlayerIsOnPlatform = false;
}
}
{
targetPosition = positionB.position;
DirectionCalculate();
}
// There may be a bug in this method, a movement inconsistency
private void FixedUpdate()
{
// Задаем движение платформе.
platformRigidbody2D.velocity = platformMoveDirection * platformSpeed;
// Изменяем направление движения платформы на противоположное, если она находится близко к точке слева или справа.
if (Vector2.Distance(transform.position, positionA.position) < 0.05f)
{
targetPosition = positionB.position;
DirectionCalculate();
}
else if (Vector2.Distance(transform.position, positionB.position) < 0.05f)
{
targetPosition = positionA.position;
DirectionCalculate();
}
}
private void DirectionCalculate()
{
platformMoveDirection = (targetPosition - transform.position).normalized;
}
private void OnTriggerEnter2D(Collider2D collision)
{
if (collision.gameObject.CompareTag("PlayerGroundCheck"))
{
// Возможно, игрока не нужно делать частью платформы.
player.transform.SetParent(transform);
playerController.PlatformRigidbody2D = platformRigidbody2D;
playerController.PlayerIsOnPlatform = true;
}
}
private void OnTriggerExit2D(Collider2D collision)
{
if (collision.gameObject.CompareTag("PlayerGroundCheck"))
{
player.transform.SetParent(null);
playerController.PlayerIsOnPlatform = false;
}
}
Как это исправить, чтобы игрок никуда не смещался?