Chcę płynnie obracać obiekt (płaszczyzna) w oparciu o listę kątów (Pitch, Roll i Yaw) otrzymanych z wywołania API. Obiektem odpowiedzi jest Rootresponse poniżej

public class ResponseData
{
    public List<int> x; //roll
    public List<int> y; //yaw
    public List<int> z; //pitch
}

public class RootResponse
{
    public ResponseData data;
    public string status; //status of the api call
}

Próbowałem zapętlić wartości każdej klatki w metodzie FixedUpdate za pomocą pętli while przy użyciu poniższego fragmentu kodu. Spowoduje to zgłoszenie wyjątku "ArgumentOutOfRange".

Jeśli używam kąta transform.Roatate lub Quarternion zgodnie z dokumentacją, mogę uzyskać tylko ostateczną pozycję.

Jakie jest najlepsze podejście, jakie mogę wybrać w tym przypadku?

void FixedUpdate(){
    if(shouldUpdate) { //set to true for a success response from the api call
        while(ind < dataLen) {
            transform.position = Vector3.MoveTowards(new Vector3(batData.x[ind], batData.y[ind], batData.z[ind]), new Vector3(batData.x[ind+1], batData.y[ind + 1], batData.z[ind + 1]), speed * Time.deltaTime);
            ind++; //to increment the index every frame
        }
    }
}
1
Lohit Peesapati 14 listopad 2018, 01:35

1 odpowiedź

Najlepsza odpowiedź

(Prawdopodobnie) nie chcesz stosować wszystkich obrotów w obrębie jednej klatki bez względu na prędkość obrotową.

Powinieneś raczej śledzić, jak bardzo obracasz się podczas pracy w kolejce tej klatki i wyjść z pętli while, jeśli ją spotkasz.

public float maxAngleRotatePerFrame = 5f;

void FixedUpdate(){
    if(shouldUpdate) { //set to true for a success response from the api call
        // Keep track of how far we've traveled in this frame.
        float angleTraveledThisFrame = 0f;

        // Rotate until we've rotated as much as we can in a single frame, 
        // or we run out of rotations to do.
        while (angleTraveledThisFrame < maxAngleRotatePerFrame && ind < dataLen) {
            // Figure out how we want to rotate and how much that is
            Quaternion curRot = transform.rotation;
            Quaternion goalRot = Quaternion.Euler(
                    batData.x[ind],
                    batData.y[ind],
                    batData.z[ind]
                    );
            float angleLeftInThisInd =  Quaternion.Angle(curRot, goalRot);

            // Rotate as much as we can toward that rotation this frame
            float curAngleRotate = Mathf.Min(
                    angleLeftInThisInd, 
                    maxAngleRotatePerFrame - angleTraveledThisFrame
                    );

            transform.rotation = Quaternion.RotateTowards(curRot, goalRot, curAngleRotate);

            // Update how much we've rotated already. This determines
            // if we get to go through the while loop again.
            angleTraveledThisFrame += curAngleRotate;

            if (angleTraveledThisFrame < maxAngleRotatePerFrame ) {  
                // If we have more rotating to do this frame,
                // increment the index.
                ind++;

                if (ind==dataLen) {
                    // If you need to do anything when you run out of rotations, 
                    // you can do it here.
                }
            }
        }
    }
}
1
Ruzihm 14 listopad 2018, 02:26