How to rotate a parent when rotating a child by a certain angle using coroutines

I have a semicircle, like a game object, which I made by putting two arcs in an empty game object (SCircle) and turning 15 ° (for the left arc) and -15 ° (for the right arc), as shown below.

enter image description here

SCircle has an Orientation jumper with two values Left (rotates the circular motion to 45 °) and Right (rotates the SCircle to -45 °), as shown in the image below.

enter image description here

I use the following coroutine to move the SCircle between orientations.

 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); } 

I also used a very similar coroutine to move individual arcs 30 ° (in opposite directions), such as Left Orientation, as shown in the coroutine and image below:

 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

Since SCircle Coroutine is activated with a mouse click, I have a case where a separate arcs coroutine command is executed and the parent SCircle coroutine is executed before its completion. In this case, the arcs end up moving from Left to A, which doesn't match the behavior I need. I would like their behavior to end in B when going from Left . Similarly, from B, when the SCircle coroutine command is SCircle during the execution of the arcs coroutine command, the orientation will return to Left .

Notice that the blue arrow represents the movement of the left arc, the red represents the right arc, and the black represents the movement of the SCircle parent object.

enter image description here

+7
c # unity3d
source share
1 answer

I believe that the problem you are facing is caused by the fact that when you rotate individual arcs, they rotate around.

In other words, the axes of your circle rotate, and your arcs use the same axes to determine their own rotations. Therefore, if you look at your example A, you will say that it rotates in world space by -90, and then immediately rotates in world space by 30. To solve this, you want the arcs to rotate locally and not in world space.

I think you can solve this problem by setting up this structure:

Empty GameObject SCircle

------ Empty gameObject BlueArcCenter → position 0,0,0

----------- blue arc → change position here to make it offset from zero ex: (radius, 0, 0)

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

----------- red arc → change position here to make it offset from zero ex: (- radius, 0, 0)

Now change your code so that:

To rotate the blue and red arcs alternately, you rotate their arcCenters,

To rotate the entire configuration, turn SCircle. This, in turn, will turn both ArcCenters, which in turn will turn both arcs regardless of how they are oriented relative to each other or themselves rotate.

Note: Also, I read that people use Quaternions a lot less these days, as they really don't make sense when you read the code. You might want to change your code to regular rotations to make it more readable.

If you have the setting above use something like:

in a circle of rotation:

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

To rotate arcs around their common center:

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

(you need to add lerps and stuff, but this should get you started).

0
source share

All Articles