RacerZ | Дата: Воскресенье, 24 Июля 2016, 18:43 | Сообщение # 1 |
уже был
Сейчас нет на сайте
| Итак, сделал "Гравикар", который должен удерживаться над поверхностью террейна. В этом процессе, в скрипте создается достаточно подъемная сила, которая корректируется высотой над террейном. Его можно конечно еще дорабатывать на условия рельефа террейна, но это не так важно сейчас. Проблема в том, что он от столкновения с чем-либо теряет правильное положение, и начинает наклонятся на стороны(влево, вправо, вперед, назад). Так конечно должно быть - это логично, на то она и физика. Но как заставить его принять снова правильное положение?
по Х нужно принимать 270, a по Z - 0; Y - не нужно трогать, пускай вращается, пока не остановится.
Код using UnityEngine; using System.Collections;
public class SelfStabilizator : MonoBehaviour { float normalX = 270; float normalY = 0; float normalZ = 0; Quaternion OriginRotation; Quaternion rotationX; Quaternion rotationZ; Quaternion rotationY;
public float angleX; public float angleY; public float angleZ;
public float anglex; public float anglez; public float angley;
public float gradX; public float gradZ;
void Start() { OriginRotation = transform.rotation; }
void FixedUpdate() { angleX = transform.rotation.eulerAngles.x; angleY = transform.rotation.eulerAngles.y; angleZ = transform.rotation.eulerAngles.z;
anglex = Mathf.LerpAngle(angleX, normalX, Time.deltaTime * 2); //angley = Mathf.LerpAngle(angleY, angleY, Time.deltaTime * 2); anglez = Mathf.LerpAngle(angleZ, normalZ, Time.deltaTime * 2);
gradX = anglex - angleX; gradZ = anglez - angleZ;
//rotationX = Quaternion.AngleAxis(gradX, new Vector3(1, 0, 1)); //rotationZ = Quaternion.AngleAxis(gradZ, new Vector3(0, 0, 1)); //rotationY = Quaternion.AngleAxis(0, new Vector3(0, 1, 0)); //Quaternion.FromToRotation(new Vector3(angleX, angleY, angleZ), new Vector3(anglex, angleY, anglez)); //transform.rotation *= rotationZ; //transform.rotation *= (rotationX * rotationZ); //transform.eulerAngles = new Vector3(anglex, angleY, anglez); //transform.Rotate(gradX,0, gradZ); //transform.rotation = Quaternion.Euler(270, transform.rotation.eulerAngles.y, transform.rotation.eulerAngles.z);
if (angleX != anglex) { transform.Rotate(gradX, 0, 0); } if (angleZ != anglez) { transform.Rotate(0, 0, gradZ); } } }
Пробовал разными способами, и они работают. Но у всех есть одна проблема. По Y постоянно происходят свободные вращение, может сам просто крутиться, может вести себя как бумеранг - с начала крутится правильно, потом внезапно в противоположную сторону.
Прошу совета, в чем может быть проблема.
|
|
| |
Lertmind | Дата: Воскресенье, 24 Июля 2016, 19:26 | Сообщение # 2 |
заслуженный участник
Сейчас нет на сайте
| Если у тебя non-Kinematic Rigidbody, то применять Rotate() нежелательно, как и другие манипуляции с Transform. В ответе How to stabilize angular motion (alignment) of hovering object? используется AddTorque(), что полагаю является единственным нормальным вариантов.
Сообщение отредактировал Lertmind - Воскресенье, 24 Июля 2016, 19:27 |
|
| |
RacerZ | Дата: Понедельник, 25 Июля 2016, 21:29 | Сообщение # 3 |
уже был
Сейчас нет на сайте
| Спасибо за ответ, так и поступлю. Добавлено (25 июля 2016, 21:29) --------------------------------------------- Просто идеально
Код using UnityEngine; using System.Collections;
public class HoverGyroskope : MonoBehaviour {
public float stability = 0.3f; public float speed = 2.0f; public Rigidbody rb;
void Start() { rb = GetComponent<Rigidbody>(); }
void FixedUpdate() { Vector3 predictedUp = Quaternion.AngleAxis( rb.angularVelocity.magnitude * Mathf.Rad2Deg * stability / speed, rb.angularVelocity ) * transform.up; Vector3 torqueVector = Vector3.Cross(predictedUp, Vector3.up); rb.AddTorque(torqueVector * speed * speed); } }
|
|
| |