I have a semicircle like game object which I made by putting two arcs in an empty game object (SCircle) and rotating the 15° (for left arc) and -15° (for right arc) as seen below.
SCircle
has an Orientation
enum with two valuesLeft
(rotates SCircle to 45°) and Right
(rotates SCircle
to -45°) as seen in the image below.
I use the following coroutine to move 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 the individual arcs by 30° (in opposite directions) from say, Orientation Left
, as seen below in the coroutine and image:
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);
}
Since SCircle
Coroutine is activated by a mouse click, I have the case where the individual arcs coroutine is run and before it is complete the parent SCircle
coroutine is also run. In this case the arcs end up moving from Left
to A, which is not the behavior I need. I would want the behavior of them ending up at B when moving from the Left
. Likewise, from B, when the SCircle
coroutine is run while the arcs coroutine is in progress the orientation will return to the Left
.
Please note that the blue arrow represents the movement of the left Arc, the red represents the right Arc and the black represents movement of SCircle
- the parent object.
Child objects automatically rotate with parents. You shouldn't need, or have, to set the child rotation at all.
I believe the issue you're having is caused by the fact that as you rotate the individual arcs, what they're rotating around is also rotating itself.
In other words, your SCircle's axes are rotating, and your arcs are using those same axes to determine their own rotations. So if you look at your example A, you tell it to rotate in world space by -90, then immediately tell to rotate in world space by 30. To solve this, you want to get the arcs to rotate locally, not in world space.
I think you can solve this 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 alter your code so that:
To rotate the blue and red arcs individually you rotate their arcCenters,
To rotate the whole configuration, rotate SCircle. This will in turn rotate both ArcCenters, which will in turn rotate both the arcs irrespective of how they are oriented relative to each other, or whether they are rotating themselves.
Note: Also, I've read that people are using Quaternions a lot less these days since they don't really make sense when you read the code. You might want to change your code to normal rotations to make it more readable.
If you have the setup listed above, use something like:
to spin circle:
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'd need to add lerps in and stuff but this should get you started).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With