Search Unity

Is it really impossible to have a child object spin/rotate independently of the parent in UNITY??

Discussion in 'Scripting' started by Jeepster, Apr 23, 2019.

  1. Jeepster

    Jeepster

    Joined:
    Jan 23, 2014
    Posts:
    401
    Hi,

    So over the past few months I've encountered a seriously frustrating problem: I've made spinning wheel (3D object) that is a child of my camera which has a mouselook script on it. When the wheel is NOT a child object, it spins perfectly and upright, but as a child object, it's rotation is affected by the parent no matter what I try.

    This is the mouselook code on the camera:

    1. rotationX += Input.GetAxis("Mouse X") * lookSpeed;
    2. rotationY += Input.GetAxis("Mouse Y") * lookSpeed;
    3. transform.localRotation = Quaternion.AngleAxis(rotationX, Vector3.up);
    4. transform.localRotation *= Quaternion.AngleAxis(rotationY, Vector3.left);
    The wheel spins in relation to where and how fast I look around with the camera instead of simply staying in front of the camera and spinning on it's own y axis. I'm using AddTorque and I've tried with adding the torque using Vector3 or it's transform (see below) and it's the same result!! I'm going crazy over here. How come it's completely impossible to do something so painfully simple in Unity??? If anybody knows how to make something like this work please let me know!!!

    here's the spin wheel code:

    Code (CSharp):
    1.   void Awake()
    2.     {
    3.         gO = GetComponent<Rigidbody>();
    4.         gO.angularDrag = Random.Range(0f, 1.5f);
    5.         gO.AddTorque(transform.up * torque, ForceMode.Impulse  );
    6.  
    7.    
    8.     }
     
  2. lowbl_dan

    lowbl_dan

    Joined:
    Jan 22, 2019
    Posts:
    34
    the simplest way is to make it an independent object and do a follow script to follow the camera's position (Camera.main.transform.position + Camera.main.transform.forward * offset) etc. The child's rotation always be affected by the parent's rotation regardless.
     
  3. WheresMommy

    WheresMommy

    Joined:
    Oct 4, 2012
    Posts:
    890
    I do not really see the reason to parent something if you don't want to act it like a parent ;) Guess you have to use @lowbl_dan idea of doing your stuff.
     
  4. hpjohn

    hpjohn

    Joined:
    Aug 14, 2012
    Posts:
    2,190
    I'd say working as intended.
    If you were to spin a gyroscope and hold it infront of you, if you rotate up and down, due to physics (eg the Precession effect) the axis of rotation will change.
    What you want to acheive is inherantly non-physical, so stop relying on the physics engine to do it
    eg:
    Code (CSharp):
    1.     //Simple example, spins on local up axis at constant speed
    2.     public float speed;
    3.     private void Update()
    4.     {
    5.         transform.Rotate(Vector3.up, speed, Space.Self);
    6.     }
    7.  
    8.  
    9.     //complex example, spin speed slows down over time, button to reset spin
    10.     public float startSpeed = 10, damping = 0.01f;
    11.     float currentSpeed;
    12.     private void Start()
    13.     {
    14.         currentSpeed = startSpeed;
    15.     }
    16.     private void Update()
    17.     {
    18.         transform.Rotate(Vector3.up, currentSpeed, Space.Self);
    19.         currentSpeed = Mathf.Lerp(currentSpeed, 0, damping);
    20.     }
    21.     private void OnGUI()
    22.     {
    23.         if (GUILayout.Button("Spin"))
    24.         {
    25.             currentSpeed = startSpeed;
    26.         }
    27.     }
    28.  
     
    Jeepster likes this.
  5. Owen-Reynolds

    Owen-Reynolds

    Joined:
    Feb 15, 2012
    Posts:
    1,997
    Another way to look at that: the purpose of putting something as a child is to track the parent's position and rotation (and scale, but how often do we rescale parents?) Children act like they're glued to the parent, which is almost always what we want. Unity _could_ have added checkBoxes to disable changing the child's rotation. But that's so rare, and there are lots of ways to partly track a parent, they figured it would just clutter things.

    The code to fake a position-only child, for a non-child, isn't too hard: wheel.position=transform.position+transform.rotation*toWheel;. Or look up "unity position child" and search through similar questions for an explanation.
     
  6. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,528
    A child is specifically a 'transform child'... a child implies that it inherits its parent. If it's a transform child, and it should inherit... well then it inherits the transform.

    A transform is the translation, rotation, scale.

    So ipso facto, a child inherits the rotation of its parent.

    To do otherwise is counter-intuitive to the entire relationship you're establishing.
     
  7. Joe-Censored

    Joe-Censored

    Joined:
    Mar 26, 2013
    Posts:
    11,847
    If you don't want the motion of an object to be affected by its parent, you don't make it a child object. If you want to update position with the other object without affecting rotation you just set transform.position of the object to that of the other object in Update or LateUpdate.
     
  8. Owen-Reynolds

    Owen-Reynolds

    Joined:
    Feb 15, 2012
    Posts:
    1,997
    The thing is, Unity Transforms are lifted directly from 3D modeling software, and those give you options. Child bones in Blender can choose to not inherit rotation (I can barely model, so I assume there are more like that in the vast trove of buttons and modes I don't understand, especially in MAX).

    The OP's question is completely reasonable. It's what someone who knows _more_ about transforms than a programmer would ask. The real answer is that Unity has a simplified version of Transforms.
     
    Jeepster likes this.
  9. hpjohn

    hpjohn

    Joined:
    Aug 14, 2012
    Posts:
    2,190
    Not sure thats quite correct.
    Transforms are a rendering thing, not a modelling thing.
    In order for a renderer to know how to draw a model on screen, it needs the models' Transformation Matrix (in world space), and it calculates this by doing sequential matrix multiplication for every parent, grandparent, etc of that model until you have a matrix that represents the models transformation relative to world, not just to parent
     
  10. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,528
    This^

    And to have special tests to turn it on/off for specific parts of the matrix rotation injects branching into the otherwise linear arithmetic. Causing the calculation to be even slower.

    Now in 3d modeling software... there is definitely child/parent linking. Which will be used for animating and the sort. Now I know when those are exported to most formats (like fbx and obj) any toggling of what transformation to inherit aren't included. And when imported to game engines, like unity, they most certainly aren't included for obvious reasons.

    But in regards to staying in your respective 3d modeling software, you may or may not get this option while animating said things. I know w/ 3ds Max you do:
    https://knowledge.autodesk.com/supp...F0A288A2-29C0-49E7-9141-9966C794F3AD-htm.html

    Thing is, this is primarily used for animating (or so my artist tells me).

    As a result you get a lot of freedom in animating while in your art pipeline, but it then calculates the actual required transformations to result in that animation, and that information is exported into the key frames for the animation. At this point the toggling of what properties is lost and when you export your animations you receive full transformation key frames.

    This way the slow calculations are dealt with in the pipeline, rather than at runtime.

    ...

    Sure, you COULD do this at runtime. Just like you could have 16 samples per pixel ray traced rendering (the minimum pixar suggests for good looking lighting), but at what cost to your CPU and GPU?

    ...

    But in all fairness, I see what @Owen-Reynolds is saying. And looking at this from the perspective of say an artist rather than someone looking at this from the perspective of the rendering-compute performance.

    Yeah, one might wonder "why isn't this available"? And it's reasonable to ask that question. Most definitely.

    But the answer is... well... this long post.

    In a few more years though? Who knows...
     
    Jeepster likes this.
  11. Jeepster

    Jeepster

    Joined:
    Jan 23, 2014
    Posts:
    401
    Thank you everybody for your input. The reason I want the wheel to be a child object is because I'm making a multiplayer game with 10 different players to choose from, and it would simplify my weapons system: a slot machine type wheel that determines what weapon a specific player wins, when said player hits a gift box) By making the wheel and each available weapon child objects, all I would've had to do was to activate/deactivate child objects for whoever hits the gift box. If The wheel isn't a child, I have to figure out how to activate/deactivate the weapons of whoever hits the gift box (spawned characters are clones) and have the wheel spawn in front of said characters camera only, and then control what weapons are activated/deactivated on that character.

    So you see, that is way more complicated, at least for an amateur programmer like myself, then simply having a child object that can spin on it's own. If it were up for a vote, I'd vote for the checkbox in the inspector that allows for a child object to rotate on it's own, while still following the parents position. It seems like such a small thing, and I've read examples of people trying to make turret guns work and having the same issue. I don't think it's such a small minority of developers that would appreciate something like this :)
     
  12. Jeepster

    Jeepster

    Joined:
    Jan 23, 2014
    Posts:
    401
    @hpjohn IT WORKS!!!! I can't believe it works, but you're right on the money! The wheel stays in place in front of the camera, but rotates on it's own. Space.Self was the key. I've learned a valuable lesson today. Thank you so very much.
     
  13. Owen-Reynolds

    Owen-Reynolds

    Joined:
    Feb 15, 2012
    Posts:
    1,997
    Space.Self is extra. You can delete it and the code works the same.

    Your first code used AddTorque, which is from the physics system and always uses world coords (a torque around Y is always around the real-world Y). But transform.Rotate is a friendly shortcut for simple code-based spinning. It uses local space because most people want to spin around their own Y-axis. There's an option to use Space.World or Space.Self, but Self is the default.

    In general, whenever spinning (or moving) consider whether you want global or local space for it.
     
    Jeepster likes this.
  14. tmcdonald

    tmcdonald

    Joined:
    Mar 20, 2016
    Posts:
    160
    I can see why this would be annoying to the user. While there are certainly ways to do it, I would like it if Unity would allow for folders in the heirarchy - I suspect this situation arises when parent-child relationships are established for organizational purposes, rather than positional.
     
  15. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,528
    Yeah, folders would be really nice.