#c# #unity3d #rigid-bodies
#c# #unity3d #твердые тела
Вопрос:
всякий раз, когда я поворачиваю свой велосипед, кажется, что он скользит. Вот сценарий
[SerializeField] float turn;
[SerializeField] float maxSpeed;
[SerializeField] GameObject bikeParts;
[SerializeField] float tilt = 20f;
Rigidbody rb;
float lastY;
void Start()
{
rb = GetComponent<Rigidbody>();
}
void Update()
{
float straightMov = Input.GetAxis("Vertical");
float horizontalMov = Input.GetAxis("Horizontal");
ControlStraightMov(straightMov);
ControlWeightTurning(horizontalMov);
lastY = transform.position.y;
}
private void ControlWeightTurning(float horizontalMov)
{
Vector3 bikePartsRot = bikeParts.transform.eulerAngles;
bikePartsRot.x = tilt * horizontalMov;
bikeParts.transform.eulerAngles = bikePartsRot;
transform.Rotate(0f, (turn * Time.deltaTime) * horizontalMov, 0f);
}
private void ControlStraightMov(float straightMov)
{
if (straightMov > 0)
{
rb.AddRelativeForce((accel * Time.deltaTime) * -straightMov, 0f, 0f);
}
else if (straightMov < 0)
{
rb.AddRelativeForce(((accel / 1.3f * Time.deltaTime) * -straightMov), 0f, 0f);
}
}
Всякий раз, когда велосипед набирает скорость, становится очень сложно поворачивать велосипед, потому что добавленная сила продолжает перемещать велосипед в направлении, отличном от направления, в котором стоит велосипед, как мне применить ту силу, с которой он сталкивался раньше, в направлении, в котором он находится сейчас, чтобы он не чувствовалнравится скользить?
Я пытался решить эту проблему, но просто не могу, потому что я новичок в unity.
Ответ №1:
как мне применить ту силу, с которой он сталкивался раньше, в направлении, в котором он находится сейчас
Не уверен, что это будет правильно, но вы, вероятно, могли бы сделать это, например
private void Update ()
{
...
rb.velocity = transform.forward * rb.velocity.magnitude;
}
Который сохранит текущую скорость и просто перенаправит ее в новое прямое направление.
В общем, обратите внимание: всякий раз, когда возникает Rigidbody
проблема, вы не хотите устанавливать какие-либо манипуляции через Transform
компонент, а только через Rigidbody
.
Поэтому вам не следует делать
bikeParts.transform.eulerAngles = bikePartsRot;
transform.Rotate(0f, (turn * Time.deltaTime) * horizontalMov, 0f);
но оба раза лучше рассчитать целевое вращение и пройти, например rb.MoveRotation
, in FixedUpdate
.
Что может выглядеть примерно так
float horizontalMove;
void Update()
{
var straightMove = Input.GetAxis("Vertical");
// Get and store the input in Update
horizontalMove = Input.GetAxis("Horizontal");
ControlStraightMov(straightMove);
lastY = transform.position.y;
}
private void FixedUpdate ()
{
// Handle it in FixedUpdate
ControlWeightTurning(horizontalMove);
}
private void ControlWeightTurning(float horizontalMove)
{
var bikePartsRot = bikeParts.transform.eulerAngles;
bikePartsRot.x = tilt * horizontalMove;
// Calculate the new final rotation
var newRotation = Quaternion.Euler(bikePartsRot) * Quaternion.Euler(Vector3.up * (turn * Time.deltaTime) * horizontalMove));
// Apply it only via the Rigidbody
rb.MoveRotation(newRotation);
}