问题
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:
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.
回答1:
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.
回答2:
Following @Adam Stox's answer, I share you a solution that usually work in this case (link tho the original answer):
Don't child the objects directly to a non-uniformly scaled parent - child this non-uniform object to an empty object, which will be the parent of the other objects too; since an empty object is scaled 1,1,1, childing other objects to it don't cause this problem.
I don't know your object hierarchy, but in the link you can find an example, so you can adapt to your specfic case.
回答3:
You could use the RigidbodyConstraints to lock the rotation in once axis.
The other option would be to fix the rotation in LateUpdate using a script.
If the problem only occurs on sprites, then try making it a child of a cube, where you disable the renderer.
回答4:
There could be more than one things at play, and it's hard to tell without seing the prefab hierarchy or the source of OVRGrabbable
.
One thing that comes to mind is that you should manipulate the position and rotation of the object through its rigidbody
The prefab could have a bunch of builtin transformation that persists, is everything properly align before you interact with the collider? Also somehow the rotation of the image to the collider is similar to the rotation of the collider relative to the world. Could it be that you nested two objects?
来源:https://stackoverflow.com/questions/51019842/persisting-angle-of-solid-objects-while-rotating