Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 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 ChristmasEve · Sep 18, 2017 at 08:00 PM · rotationgameobjecteditorpivot-point

Pivot vs center

I've seen a lot of posts similar to this but nothing so far that answers the question. You know when you have a prefab of a group of objects highlighted? There is an Editor button at the top left that toggles between "Center" and "Pivot". Highlight a prefab and switch to "R" for rotation. Keep clicking the Center/Pivot button. Obviously, Unity knows the difference between these two points because you can see the rotator sphere tool shift between the two points (if you object's pivot isn't center).

My question is, HOW do I get this offset? I want to throw my prefab into an empty GameObject and then give the single child an offset to counteract this difference. Thus far, I have been eyeballing this shift and changing the X and Z until there was no shift. I want to do this in code. My way is tedious! Please help :)

Comment
Add comment
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

2 Replies

· Add your reply
  • Sort: 
avatar image
1

Answer by Adam-Mechtley · Sep 18, 2017 at 08:34 PM

I don't know how complicated your prefab is, but the actual code used to collect the bounds that gets used for Tools.handlePosition is quite a bit more complex, totally arbitrary, and subject to change.

Today, as of 2017.1/2, it will first include the collider's bounds. It will then check if the object has a renderer and, if so, add its bounds. If there is no renderer, it will add the bounds of the MeshFilter if there is one. If there is neither a renderer nor mesh filterer, then it moves on to check a variety of component types (Light, which has its own bounds calculation; ReflectionProbe, RectTransform, and then ultimately just its Transform's position).

The only actual way to get the delta you want programmatically is something like:

 Tools.pivotMode = PivotMode.Center;
 var center = Tools.handlePosition;
 Tools.pivotMode = PivotMode.Pivot;
 var delta = center - Tools.handlePosition;
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 Bunny83 · Sep 18, 2017 at 08:23 PM

Do you really want the exact same result as Unity gives you? Unity does calculate the bounding volume of all objects selected. This is only based on the worldspace bounds of all Renderers and all Colliders on those objects.

So this should give you the same worldspace position as Unity when you select "center".:

 public static Vector3 CalculateCenter(params Transform[] aObjects)
 {
     Bounds b = new Bounds();
     foreach(var o in aObjects)
     {
         var renderers = o.GetComponentsInChildren<Renderer>();
         foreach(var r in renderers)
         {
             if (b.size == Vector3.zero)
                 b = r.bounds;
             else
                 b.Encapsulate(r.bounds);
         }
         var colliders = o.GetComponentsInChildren<Collider>();
         foreach (var c in colliders)
         {
             if (b.size == Vector3.zero)
                 b = c.bounds;
             else
                 b.Encapsulate(c.bounds);
         }
     }
     return b.center;
 }

Note that this method searches through the whole hierarchy downwards. So if you have a parent object, just pass the parent:

 Vector3 center = CalculateCenter(parent);
Comment
Add comment · Show 4 · 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 ChristmasEve · Sep 18, 2017 at 08:59 PM 0
Share

Thank you for your response!

I did do something similar before I posted this. I made a function that traverses only the renderers (not colliders) and I ended up with the same thing as your function returns for a particular prefab I have: (9.1f, 0, -4.1f)

In manually finding the difference between the pivot and center, I end up with something different: (-8.8f, 0, 8.2f).

I can't figure out why. But only if I shift X back by -8.8f and Z by 8.2f will I get the pivot to be right on top of the center, despite these results of using encapsulate recursively.

Any ideas ?

avatar image Bunny83 ChristmasEve · Sep 18, 2017 at 09:24 PM 0
Share

Well you must be doing something wrong. Either you initialize the Bounds with the world origin (note my if statement in the loops) or you do something wrong in your offsetting. See this image

The handle is the center handle and the 3 white lines are drawn inside OnDrawGizmos around the center position i calculated with my method. They are for sure identical.

How do you do the offsetting? The easiest way is to create the empty gameobject, positioning it at the calculated center and after that you add your object(s) as childs. When you use transform.parent = p; or transform.SetParent(p, true); the objects will keep their absolute position.

avatar image Bunny83 ChristmasEve · Sep 18, 2017 at 09:41 PM 0
Share

You can get my test script from my dropbox if you want to try it yourself. (direct download)

avatar image jvhgamer · Nov 12, 2018 at 05:40 PM 0
Share

Thanks for the comprehensive solution! Once the center is calculated, is this used via assigning it to an objects child.positions, the parent itself? Fiddling with the results trying to deter$$anonymous$$e how to correctly use the center. Could you clarify, @Bunny83?

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

137 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 avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image 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

How to specify the rotation angle in degrees, in the inspector? 2 Answers

Get the name of an instance's prefab at runtime? 0 Answers

Is there a way to access the inspector fields (not the component properties) through a unity editor script? 0 Answers

Mathf.MoveTowardsAngle is not working as predicted 1 Answer

My marble (Player/Gameobject) goes through the "play board" (gameobject). Why? 1 Answer


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