Физический лифт Unity 3D дергается при движении
Написал простенький скрипт для лифта. Все работает хорошо за исключением подергивания то ли объектов(лифта или игрока), то ли камеры при движении игрока вместе с лифтом. Пробовал разные значения полей Interpolete и Collision Detection. Это сглаживает углы, но проблему не решает. Скрипт камеры работает в FixedUpdate так же как и передвижение персонажа.
Скрипт Elevator висит на объекте лифт на сцене:
using System.Collections;
using UnityEngine;
public class Elevator : MonoBehaviour
{
[SerializeField] AnimationCurve moovementCurve;
[SerializeField] protected float duration;
[SerializeField] protected float height;
[SerializeField] protected bool AtDownPosition = true;
private float startHeight;
private void Awake()
{
startHeight = transform.position.y;
}
private IEnumerator PlayAnimationUp()
{
float expiredTime = 0f;
float progress = 0f;
while (progress < 1)
{
expiredTime += Time.fixedDeltaTime;
progress = expiredTime / duration;
transform.position = new Vector3(transform.position.x, startHeight + moovementCurve.Evaluate(progress) * height, transform.position.z);
yield return null;
}
AtDownPosition = false;
}
private IEnumerator PlayAnimationDown()
{
float expiredTime = duration;
float progress = 1f;
while (progress > 0)
{
expiredTime -= Time.fixedDeltaTime;
progress = expiredTime / duration;
transform.position = new Vector3(transform.position.x, startHeight + moovementCurve.Evaluate(progress) * height, transform.position.z);
yield return null;
}
AtDownPosition = true;
}
public void ActivateElevator()
{
if(AtDownPosition)
StartCoroutine(PlayAnimationUp());
else
StartCoroutine(PlayAnimationDown());
}
private void OnTriggerEnter(Collider other)
{
if (other.GetComponent<HeroController>())
{
other.transform.parent = transform;
ActivateElevator();
}
}
private void OnTriggerExit(Collider other)
{
other.transform.parent = null;
}
}
Скрипт, отвечающий за передвижение игрока
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class HeroController : MonoBehaviour
{
//Oсновные параметры
[SerializeField] private float jumpForce;
[SerializeField] private float moveSpeed;
[SerializeField] private float maxSpeed;
[SerializeField] private float rotationSpeed;
[SerializeField] private float ExplosionJumpHeight;
[SerializeField] private float velocityToExplode;
[SerializeField] private int explosionDamage;
private bool canExplode = false;
private float damageJumpForce;
//Elements for buff system
Dictionary<string, MyDelegate> buffableStats;
private delegate IEnumerator MyDelegate(float newRadius, float buffCooldown);
//Ссылки на компоненты
[SerializeField] private GameObject LoseScreen;
[SerializeField] private Transform cameraRoot;
[SerializeField] private SurfaceSlider surfaceSlider;
[SerializeField] private VerticalAccelerator verticalAccelerator;
private HealthControll healthControll;
private MobileController mController;
private Animator ch_animator;
private Rigidbody rb;
private Explosion explosion;
//Переменные для хранения временных данных
private float defaultMoveSpeed;
private float defaultMaxSpeed;
public bool IsGrounded { get; private set; }
private Vector3 moveVector// направление передвижения
{
get
{
var horizontal = mController.Horizontal();
var vertical = mController.Vertical();
return new Vector3(horizontal, 0.0f, vertical);
}
}
//.......//
private void Start()
{
healthControll = GetComponent<HealthControll>();
explosion = GetComponent<Explosion>();
rb = GetComponent<Rigidbody>();
/*ch_animator = GetComponent<Animator>();*/
mController = GameObject.FindGameObjectWithTag("Joystick").GetComponent<MobileController>();
defaultMoveSpeed = moveSpeed;
defaultMaxSpeed = maxSpeed;
damageJumpForce = jumpForce;
}
private void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
Jump();
}
}
private void FixedUpdate()
{
SetCanExplode();
Move();
}
private void Move()
{
//вращение персонажа
if (moveVector.magnitude > 0.1f)
{
float rotationAngle = Mathf.Atan2(moveVector.x,moveVector.z) * Mathf.Rad2Deg + cameraRoot.eulerAngles.y;
Quaternion rotation = Quaternion.Euler(0f,rotationAngle,0f);
transform.rotation = Quaternion.Lerp(transform.rotation, rotation, rotationSpeed * Time.deltaTime);
}
//перемещение персонажа
// с инерцией
maxSpeed = defaultMaxSpeed * moveVector.magnitude;
Vector3 directionAlongSurface = surfaceSlider.Project(transform.forward);
float currentVelocityXY = (Mathf.Abs(rb.velocity.x) + Mathf.Abs(rb.velocity.z));
if (currentVelocityXY < maxSpeed)
{
Vector3 direction = IsGrounded ? directionAlongSurface : transform.forward;
rb.AddForce(direction * moveVector.magnitude * moveSpeed, ForceMode.Impulse);//метод передвижения
}
}
//.......//
}
Подозреваю, что проблема в том, что напрямую изменяю положение лифта через transform.position. Пробовал через Rigidbody.MovePosition, но движение тогда происходит неправильно(лифт не доходит до нужной точки и его тоже трясет):
Vector3 offset = new Vector3(0, startHeight + moovementCurve.Evaluate(progress) * height, 0);
rigidbody.MovePosition(offset);
Если знаете как переписать предыдущий блок кода, буду благодарен.

Ответы (1 шт):
Да, действительно проблема была в камере. Сменил метод обновления на LateUpdate и проблема решилась.
