2017-10-05 41 views
7

Mam obiekt podobny do półkola, który stworzyłem, umieszczając dwa łuki w pustym obiekcie gry (SCircle) i obracając o 15 ° (po lewej łuk) i -15 ° (dla łuku prawego), jak pokazano poniżej.Jak obrócić obiekt nadrzędny podczas obracania obiektu podrzędnego do określonego kąta za pomocą współprogramów

enter image description here

SCircle ma Orientation wyliczenia z dwóch wartości Left obraca SCircle (do 45 °) i obraca SCircleRight (-45 ° C), jak widać na rysunku poniżej.

enter image description here

używam następujący współprogram przenieść SCircle między kierunkami.

IEnumerator RotateLeftOrRight(Vector3 byAngles, float inTime) 
{ 
    Quaternion fromAngle = gameObject.transform.rotation ; 
    Quaternion toAngle = Quaternion.Euler (transform.eulerAngles); 


    if (circOrientation == Orientation.Left) { 
     toAngle = Quaternion.Euler (gameObject.transform.eulerAngles - byAngles); 
     circOrientation = Orientation.Right; 

    } 
    else if (circOrientation == Orientation.Right) { 

     toAngle = Quaternion.Euler (gameObject.transform.eulerAngles + byAngles); 
     circOrientation = Orientation.Left; 
    } 


    for(float t = 0f ; t <= 1f ; t += Time.deltaTime/inTime) 
    { 
     gameObject.transform.rotation = Quaternion.Lerp(fromAngle, toAngle, t) ; 
     yield return null ; 

    } 
    gameObject.transform.rotation = Quaternion.Lerp(fromAngle, toAngle, 1); 
} 

Ja również bardzo podobny współprogram przenieść poszczególne łuki o 30 ° (w przeciwnych kierunkach) od powiedzmy Orientacja Left, jak pokazano poniżej w współprogram i obrazu:

IEnumerator RotateArc(GameObject arcGO, Vector3 byAngles, float inTime) 
{ 
    Quaternion fromAngle = arcGO.transform.rotation ; 
    Quaternion toAngle = Quaternion.Euler (arcGO.transform.eulerAngles); 

    if (rightArc.arcOrientation == Arc.Orientation.Down) { 
     toAngle = Quaternion.Euler (arcGO.transform.eulerAngles + byAngles); 
     rightArc.arcOrientation = Arc.Orientation.Up; 

    } 
    else if (rightArc.arcOrientation == Arc.Orientation.Down) { 

     toAngle = Quaternion.Euler (arcGO.transform.eulerAngles - byAngles); 
     rightArc.arcOrientation = Arc.Orientation.Up; 
    } 


    for(float t = 0f ; t <= 1f ; t += Time.deltaTime/inTime) 
    { 
     arcGO.transform.rotation = Quaternion.Lerp(fromAngle, toAngle, t) ; 
     yield return null ; 

    } 
    arcGO.transform.rotation = Quaternion.Lerp(fromAngle, toAngle, 1); 

} 

enter image description here

od SCircle współprogram jest aktywowany poprzez kliknięcie myszą, mam sprawę gdzie współprogram poszczególne łuki jest prowadzony i przed jej zakończeniem rodzic SCircle współprogram jest również biegnij. W tym przypadku łuki kończą się przejściem z Left na A, co nie jest zachowaniem, którego potrzebuję. Chciałbym, aby ich zachowanie zakończyło się na B, gdy przechodzimy z Left. Podobnie, od B, kiedy coroutine SCircle jest uruchamiany podczas trwania coroutine łuków orientacja powróci do Left.

Należy zauważyć, że niebieska strzałka reprezentuje ruch lewego łuku, czerwony oznacza prawy łuk, a czarny reprezentuje ruch obiektu SCircle - obiektu nadrzędnego.

enter image description here

+1

Dla pewności, chcesz przesunąć te dwa łuki w tym samym czasie, ale w innym kierunku, a także chcesz, aby ruch się zakończył w tym samym czasie? Jeśli tak, który obiekt jest rodzicem innego? – Programmer

+0

@ Programator 'SCircle' jest obiektem nadrzędnym, utworzonym z pustego obiektu zawierającego lewy i prawy łuk. Nie chciałbym, aby ruch się skończył w tym samym czasie, ponieważ obrót korony łuków potomnych zaczyna się przed obróceniem koronyny rodzicielskiego "łuku". Dlatego rotacja łuków potomnych powinna kończyć się przed rodzicem. Wystarczy, że dojdzie do momentu, w którym oba współprogramy będą działać jednocześnie. Ogólnie rzecz biorąc, każdy coroutine powinien na swój czas. – Bane

+0

pokaż nam kod do obracania łuków o 30 stopni. Czy przypadkiem ustawiasz rotację łuków zamiast rotacji lokalnej? – lockstock

Odpowiedz

0

Uważam, że problem masz jest spowodowane faktem, że jak obracać poszczególne łuki, co oni obraca się wokół obracającego się również.

Innymi słowy, twoje osie łuku kołowego obracają się, a twoje łuki wykorzystują te same osie, aby określić własne obroty. Jeśli więc spojrzysz na swój przykład A, powinieneś go obrócić w przestrzeni świata o -90, a następnie natychmiast powiedzieć, aby obrócić się w przestrzeni świata o 30. Aby rozwiązać ten problem, chcesz, aby łuki obracały się lokalnie, a nie w przestrzeni świata .

myślę, że można rozwiązać ten problem poprzez utworzenie tej struktury:

Empty GameObject SCircle

------ Empty GameObject BlueArcCenter -> pozycja 0,0,0

- --------- niebieski łuk -> zmień pozycję tutaj, aby przesunąć go od zera ex: (promień, 0, 0)

------ Empty gameObject RedArcCenter -> position (0, 0,0)

----------- czerwony łuk -> zmiana pozycji tutaj, aby zrównoważyć od zera ex: (- promień, 0, 0)

Teraz zmienia swój kod tak, że:

Aby obracać łuki w kolorze niebieskim i czerwonym, obracaj ich łuk,

Aby obrócić całą konfigurację, obróć łuk. To z kolei obróci oba ArcCenters, które z kolei obrócą oba łuki, niezależnie od tego, jak są zorientowane względem siebie, czy też same się obracają.

Uwaga: Również czytałem, że ludzie używają kwaterniony dużo mniej tych dni, ponieważ tak naprawdę nie ma sensu, kiedy odczytać kodu. Możesz zmienić swój kod na normalne obroty, aby był bardziej czytelny.

Jeśli konfiguracja wymienionych powyżej, należy użyć coś takiego:

się kręcić koło:

thisSCircle.transform.Rotate(0, -90, 0, Space.Self); 

obracania łuki wokół ich wspólnego środka:

blueArcCenter.transform.Rotate(0, -30, 0, Space.Self) 
redArcCemter.transform.Rotate(0, 30, 0, Space.Self) 

(ci, że trzeba dodać lerp i wi, ale to powinno ci zacząć).