Search code examples
c#unity-game-enginegeometryvirtual-realityoculus

Persisting angle of solid objects while rotating


I am new to Unity and Oculus. I have a bunch of images (their path and other information are loaded from a JSON file) which I am trying to render in a VR room. And want to give the user an experience that he can move these images within that room using Oculus Touch.

I placed an Empty Object which has a script that iterates through JSON and creates a prefab object (which has Rigid body,Box Collider and OVRGrabbable -so that it can be grabbed in VR, components). Moreover this prefab object has a script which is responsible to load images in a Sprite.

What is working?

Images are getting rendered and can be grabbed and moved.

What is not working as desired?

I followed this tutorial, and as shown here angles of the cube are persisted pretty fine. But when an image is grabbed and rotated, it doesn't persist it's side angles. As shown in following image:

enter image description here

Question

Is there any way that I could fix it? I tried to look for it online but as I am new to Unity I am not quite sure what exactly I am missing.

Any clues would be really appreciated.


Solution

  • I think the problem lies in your hierarchy. Your Images game object (the parent of your DisplayImage) has a scale of (1.88,1,1). Trying to rotate child objects whose parent object have non-uniform scale in Unity gives you funky results. Try resetting the scale of your Images object to (1,1,1) and see if that helps.


    This behaviour occurs because of the nature of the "parent/child" relationship. The child's coordinate system is relative to it's parents. We can think of it as the parent defining a coordinate system for our children. This is what we call local space. So, when we perform any linear transformations on the parent, it's like we're performing them on the whole parent coordinate system that our children are using to define their orientation. So translating the parent will move all of its children with it, because our whole local coordinate space has moved with the parent. Note that our children will still have the same localPosition, but their global position will have changed.

    The same logic applies to scaling and rotation. Rotating the parent essentially rotates the whole coordinate space that our child is using around the center point of the parent (which would be the point (0,0,0) in local space). So all children would then be rotated as if they were an extension of the parent object.

    In our situation we've scaled our parent, thus scaling the whole coordinate system we use to define our child object. This means that anything using the parent's coordinate space will also be scaled according to the parent's scale. In our situation, the parent was scaled by (1.88,1,1). So everything attached to the parent was also scaled along the parent's X-Axis by 1.88, resulting in the weird effect seen in your screenshots. Despite rotating our child object, it's still scaled along the parent's X-axis.

    (Link to the official documentation on this.)

    The solution to this is to apply your linear transformations as deep in the hierarchy as possible. Here, instead of scaling the parent, scale the child. If the parent object needs to be scaled, or its scale changes on the fly, another solution would be to remove the child from the parent/child hierarchy and manipulate its transform based on the old parent's transform in a script. In this case you could set the unlinked child's position and rotation to the parent's position and rotation, but ignore the scale.