How to rotate without inheritance?

I have a problem with my script, originally it was using parenting to create a relationship between the child and parent objects and it was perfect. I would run rotatearound each child object giving it the parent’s position. However, this parenting relationship makes the child inherit the scale and rotation rate of the parent when i literally only want it to inherit the parent.

Now I’ve changed my code to allow the child objects to inherit the Transform of the parent now and each update they’re runing a “self” rotate and a rotatearound in update, but every time i try to calculate the difference in position between the targetTransform (the parent) and the child, i end up with either all the objects fixed in a single position, or all the children clearly orbiting the wrong coordinates and flying off the camera.

using UnityEngine;
using System.Collections;

public class CO : MonoBehaviour {

string COName;
int COOffset;           //Distance from Parent object, relative of course
int COdegrees;          //How many degrees per second will the object rotate
Transform targetTransform;    //This is the location of the "parent" object to use for local coordinate settings

// Use this for initialization
void Start () {
}

// Update is called once per frame
void Update () {
    if (targetTransform != null) {  //If the parent is null, we're dealing with the Star, so we don't need to rotate it around it's parent.
                    transform.RotateAround (targetTransform.position, Vector3.up, 50 * Time.deltaTime);
            }
        transform.Rotate (Vector3.up, COdegrees * Time.deltaTime);  //Rotate clockwise around the parent
}

public void positionObject(int tCOOffset, int tCOdegrees, Transform tTransform) //Set the initial position on creation, will be updated later.
{
    COdegrees = tCOdegrees;
    COOffset = tCOOffset;
    targetTransform = tTransform;
    transform.position = new Vector3(0,0,COOffset);  //Set initial position of child object
}

public void nameObject(string tName)
{
    COName = tName;
}

public Transform getSelf()
{
            return this.transform;
}
void OnMouseDown ()
{
    print (COName); 
    print (transform.position);
    print (transform.parent);
}

}

I think you could update your question to include your example with the solar system. That will make it easier to help you

3 Answers

3

I can give you come code that will do what you want to do, but I think you are missing a simple solution:

  • Create a empty game object
  • In the editor, make both the ‘targetTransform’ game object and this game object a child of the empty game object.
  • Apply movement script to empty game object
  • Apply rotation to child ‘Target’ as necessary
  • Use RotateAround as necessary on this game object

I'm going to try this. Out of curiosity though, what would the code be? I don't really like the idea of each object having an empty child object in the hierarchy simply for orbit mechanics. So I'd be willing to try the code solution down the line too. The only problem with this though is that if I have multiple child objects going around the same object (Think, Moons around a planet), I'd need one child object per moon, which means that there's easily going to be a heap of empty GOs just for coordination.

Using the analogy of planet/moon, you only need one empty game object per planet.

If you only want to follow the position of some gameObject you can make a component that saves an initial difference, and then adjusts its position every update to targetGameObject.position + adjustment.

I wouldn't have a clue how to calculate initial difference, would it involve time.DeltaTime()?

initialDifference = tranform.position - targetGameObject.transform.position;

would that account for the rotation offset as well? Or would this basically undo any rotatearound movement that my object makes each update?

It would ignore rotation (which is what I thought you wanted). So Update() would look like transform.position = targetGameObject.transform.position + initialDifference; That would make this object look like it's parented to the targetGameObject, but it wouldnt' respond to rotation or scaling.

What i'm trying to do is create a model of a solar system. So basically i want the scaling and rotation of the parent object to be ignored (so it doesn't super accelerate the child when it's given it's own rotation value), but keep it rotating around the parent, just like a real moon or planet would.

If you want to model a solar system then you could make empty game objects that have eg the earth and the moon as children. This object would have the earths position but would not rotate. Then any scale or rotation of the earth would not affect the moon but the moons position would be inherited from their common parent. The moon could have an extra parent which you could rotate in order to have the moon orbit the earth.

I tried this in a basic Sun -> Earth -> Moon set up, but the objects were still receiving scaling and rotation values from the parents all the way up the hierarchy. I should clarify it works for one level, but not for the lower levels, So the Sun-> Planets is fine, but a planet-> moon relationship suffers from distortion at that point.

Maybe I was unclear. Your example would be sun_container->sun and sun_container -> earth_container -> earth and so on. Then you can do what you want with sun transform without changing earth. But you can also move the entire solar system by moving sun_container if you need to. Or make the earth orbit closer to the sun by,moving its container and the moon will retain its position relative to the earth

thanks, yea, I think I had them backwards in my test, and it actually solves a future problem about having objects orbit their baryceters. Thanks!

No problem, happy to help!