2015-06-04 18 views
17

Po kilku eksperymentach wyposażyłem pustą (HeadCam) w szyję postaci. Ten fragment umożliwia synchroniczne obracanie głowicy z CardboardHead/Camera.W jaki sposób ciało postaci może być ciągle obracane, gdy jego głowa jest już obrócona o 60 ° '?

void LateUpdate() { 
    neckBone.transform.rotation = Camera.transform.rotation * Quaternion.Euler(0,0,-90); 
    Camera.transform.position = HeadCam.transform.position; 
} 

enter image description here

ramiona postać nie powinno poruszać się tylko kiedy głowica obraca się, dopóki mieści się w zakresie -60 ° do 60 °, po czym ja jak przenieść cały znak z ramionami nadal widoczny . Poniższa metoda działa tak długo, jak długo postać nie jest obracana o więcej niż 180 °, po tym jak znaki zmieniają się o 180 °, w jaki sposób mogę uzyskać stały obrót?

void LateUpdate() { 
    Quaternion camRot = Camera.transform.rotation * Quaternion.Euler(0,0,-90);     
    neckBone.transform.rotation = camRot; 
    float yrot = camRot.eulerAngles.y; 
    float ydelta = 0; 
    if (yrot < 300f && yrot > 180) { 
     ydelta = yrot - 300f; 
    } 
    if (yrot > 60f && yrot < 180) { 
     ydelta = yrot - 60; 
    } 
    playerObj.transform.rotation = Quaternion.Euler(0, ydelta, 0); 
    Camera.transform.position = HeadCam.transform.position; 
} 

enter image description here

apletu Java do testowania jednostkowego algorytmu: https://github.com/3dbug/blender/blob/master/HeadCamRot.java

+0

nie można użyć animacji łatwiejszy do tego celu? – leAthlon

+0

@leAthlon to wirtualna aplikacja reallity, w której obroty muszą być w czasie rzeczywistym stosowane zgodnie z ruchem kamer. Zasadniczo zobaczysz siebie, gdy spojrzysz w dół. – stacker

+0

Nie jestem pewien co do rzeczywistości wirtualnej - być może skrypt mouselook z prefabrykatów unity5 może ci pomóc – leAthlon

Odpowiedz

1

Wreszcie znalazłem rozwiązanie tego problemu:

private float bodyRot = 0F; 
private float FOV = 70f; 

void LateUpdate() { 
    if (neckBone != null) { 
     Quaternion camRotQ = CameraFacing.transform.rotation * Quaternion.Euler(0,0,-90); 
     neckBone.transform.rotation = camRotQ; 
     float camRot = camRotQ.eulerAngles.y; 

     float delta = camRot- bodyRot; 
     if (delta > 180) { 
      delta -= 360; 
     } 
     if (delta < -180) { 
      delta += 360; 
     } 
     if (Math.Abs(delta) > FOV) { 
      if ((delta > FOV || delta < -180) && delta < 180) { 
       bodyRot = camRot - FOV; 
      } 
      delta = camRot- bodyRot; 
      if ((delta < FOV || delta > 180)) { 
       bodyRot = camRot + FOV; 
      } 
     } 
     playerObj.transform.rotation = Quaternion.Euler(0, bodyRot, 0); 
     CameraFacing.transform.position = cameraMount.transform.position; 
    } 
} 
3

Możliwym rozwiązaniem byłoby:

// Transform of the full body of the character. 
Transform body; 
// Transform of the head (child of |body| component). 
Transform head; 
// Maximum delta angle in degrees. 
float maxAngle = 60.0f; 

void RotateCharacter(Quaternion target) { 
    // Rotate head as much as possible without exceeding the joint angle. 
    head.rotation = Quaternion.RotateTowards (body.rotation, target, maxAngle); 
    // Complete the remainder of the rotation by body. 
    body.rotation = target * Quaternion.Inverse (head.localRotation); 
} 

Proszę pamiętać, że może trzeba ograniczyć zakaz - wcześniej obroty poziome, tzn. założyłem, że podałem x & z kątami przekazanego obrót nie przekroczy wartości maxAngle. Poza tym powinno być całkiem proste dodanie tego ograniczenia również w powyższej funkcji, jeśli zajdzie taka potrzeba.

Mam nadzieję, że to pomaga.

+0

Dzięki, co powinno być używane jako cel? Obecnie czytam obrót z kamery Cardboard i obliczenia na niej podstawy. – stacker

+0

Orientacja kamery tektury (Transform.rotation) powinna być w tym przypadku celem. Oczywiście, jeśli twój model postaci ma jakąś początkową orientację, tj. Nie jest identyczny z początkową orientacją kamery, powinieneś wziąć to pod uwagę, aby dopasować jej końcowy obrót. – anokta

+0

Jeszcze raz dziękuję, to prawdopodobnie zająć więcej czasu, aby to naprawić. Kiedy znajdę rozwiązanie, opublikuję go tutaj. Problem można zredukować do zachowania Jedności, aby obrócić obrót o 0 i 360 °, więc obliczenia muszą wziąć to pod uwagę. "Quaternion.RotateTowards" może być bardzo pomocny w niektórych przypadkach. – stacker