Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by numberkruncher · Oct 01, 2012 at 03:52 AM · transformmathvectormatrix

How to avoid changing transform.parent?

Given the following game object hierarchy in Unity 3D:

 "Super Parent"    scale (2, 34, 5), rotation(45, 16, 20)
      |
      ----> "Parent of Container"   fixed-scale (1, 1, 1), fixed-rotation(0, 0, 0)
              |
              ----> "Container"   scale (1, 2, 3), fixed-rotation(0, -180, 0)
                      |
                      ----> "Nested"   scale (4, 5, 6), rotation(14, 54, 71)

In the following snippet I am achieving ths following:

  • Change local scale of "Container" without affecting the size of "Nested" in world space.

  • Change the scale of "Nested" using the local space of "Parent of Container".

As many will know the local scale of a parent game object will alter the visual scale of nested objects so that when they are measured using world space appear different. To counteract this the local scale of "Nested" must also be updated to compensate for the change so that its size in the world remains unchanged whilst the scale of the container is increased.

I have implemented this (and it is working) with the following solution:

 // Temporarily re-parent to "Parent of Container"
 nestedTransform.parent = container.parent;

 // I can now adjust the size of the container without affecting the
 // size of the "Nested" when measured in world space.
 containerTransform.localScale = newContainerScale;

 // Assign new scale to "Nested" using local space of "Parent of Container"
 nestedTransform.localScale = newScale;

 // Re-parent "Nested" into "Container"
 nestedTransform.parent = containerTransform;

 // In the case where `nestedTransform.localScale` is not actually changed,
 // after re-parenting it will be changed to (2, 2.5, 3) meaning that its
 // size in world space is unchanged whilst "Container" is larger.

Whilst this is achieving exactly what I need, the process of re-parenting game objects does all sorts of other processor intensive stuff that is not wanted.

How can the above be achieved using just matrices and vectors? For each transform there is a local-to-world and world-to-local matrix which might be useful here.

Comment
Add comment · Show 7
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image justinl · Oct 01, 2012 at 09:14 AM 0
Share

Is container.transform the same as containerTransform? You don't use container.transform but I'm wondering if that's the same thing as your containerTransform

avatar image numberkruncher · Oct 01, 2012 at 01:37 PM 0
Share

@justinl yes that's right, btw updated question with more clarity

avatar image Paulius-Liekis · Oct 01, 2012 at 02:30 PM 0
Share

I can write this conversion without reparenting, but it sounds to me that you might be overcomplicating something. Can you explain what's the actual use case?

avatar image numberkruncher · Oct 01, 2012 at 02:56 PM 0
Share

@Paulius Liekis the use case is quite difficult to explain, but maintaining the scaling in the same way as the `transform.parent` seems to is absolutely essential.

Initially I tried to just use `Vector3.Scale` and adjust the scales accordingly, which worked when all rotations were set to (0, 0, 0), but when rotations were different the scale axis became completely incorrect.

So I went back to basics and just used `transform.parent` to separate these objects, make the necessary changes, and then reassemble them. If I knew how to use matrices properly then I would have done it that way ins$$anonymous$$d (which I guess is what is happening under the hood of `transform.parent`.

The only problem with this approach is that `transform.parent` does a lot of other things too which are costly performance-wise. So I just want the transform aspect of it.

I hope that I am not being too vague...

avatar image Paulius-Liekis · Oct 01, 2012 at 03:49 PM 0
Share

Problem is that if you have non-zero rotations and you want to use non-uniform scale, then it's not possible to do in Unity, because that leads to scale-stretch effects. Unity can render scale-stretched objects, because it caculates World$$anonymous$$atrices from Transforms before rendering. But you can not counter act scale-stretch effect, because you would need 3x3 matrix for storing scale and Unity gives you only Vector3 (localScale). So in reality it's not possible to implement full anti-parent-scale solution in Unity.

Show more comments

2 Replies

· Add your reply
  • Sort: 
avatar image
1
Best Answer

Answer by numberkruncher · Feb 19, 2013 at 03:22 PM

Problem solved by performing all calculations using matrices instead and then decomposing into the separate position, rotation and scale values. These separate values can then be assigned to the transform component which correctly scales object without distorting it.

References:

This took me a little while to figure out, though here is some information which future readers may find useful:

  • http://answers.unity3d.com/questions/402280/how-to-decompose-a-trs-matrix.html

  • http://forum.unity3d.com/threads/170823-Update-scale-of-object-without-temporarily-re-parenting...

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

Answer by Paulius-Liekis · Oct 01, 2012 at 11:41 AM

Why do you do this parenting stuff at all? assigning localScale will never change scale of parent.


If we're talking about uniform scales you can do this:

 Vector3 oldPosition = nested.position;
 controller.localScale = Vector3.one * newScale;
 nested.position = oldPosition;
 nested.localScale = Vector3.one * (1 / newScale);
Comment
Add comment · Show 9 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image numberkruncher · Oct 01, 2012 at 01:38 PM 0
Share

Updated question for more clarity

avatar image numberkruncher · Oct 01, 2012 at 04:03 PM 0
Share

The re-parenting solution works in the exact same way as it does when using the Unity editor. If you create two objects A and B and then set the scale of A to (2, 3, 4) and the scale of B to (1, 1, 1) and then drag B into A then the local scale of B is changed automatically using the same mechanism as `transform.parent`.

If I want to change the scale of object A (container) without affecting the world-size of B (nested) then I must first un-parent B, make my changes to A, and then move B back inside A. In the editor the only solution is obviously dragging and dropping.

This makes use of the local spaces of each object and somehow converts to and from world space to ensure that the scale is updated properly. There must be a way to implement this because Unity already supports what I am after (the problem is that it does other intensive stuff as well when re-parenting).

avatar image Paulius-Liekis · Oct 01, 2012 at 04:13 PM 0
Share

Yes, you're that Editor does same thing as reparenting, but you're wrong that it works in all cases. Try setting non-uniform scales on both objects, then rotating child. Unparent. Re-parent. The look won't match. In some cases it might look very similar (non-noticable), in other cases it will be wrong.

avatar image numberkruncher · Oct 01, 2012 at 04:19 PM 0
Share

That should not pose an issue in this case because no rotation occurs whilst the object is temporarily un-parented. I have re-worded my question again with more explanation.

Also I have just tested what you said using the editor, and I cannot reproduce the error you speak of.

avatar image Paulius-Liekis · Oct 01, 2012 at 04:40 PM 2
Share

Here is an example: I made a scene. Unparented and reparented object about 10 times (no rotations in between). Results: http://dl.dropbox.com/u/7345821/Example/ScaleBefore.jpg http://dl.dropbox.com/u/7345821/Example/ScaleAfter.jpg

Show more comments

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

12 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Is there such a thing as Unity Algebra? 0 Answers

Affine transformations to Object 3 Answers

Math behind Transform.TransformPoint? 1 Answer

How to get relative transform between two objects? 2 Answers

Why is transform.up different than transform.localToWorldMatrix.MultiplyVector(Vector3.up) ? 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges