• 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 Tocs · Feb 14, 2013 at 02:35 PM · startlocalpositionunity 3.5setactiverecursively

transform.localPosition is <0,0,0> in Start() when activated by SetActiveRecursively

It seems when I enable a object via SetActiveRecursively, that it's local position is thought to be <0,0,0> in it's Start(). The object's local position is not <0,0,0>, and it has been carefully positioned relative to it's parent. I need that value to be preserved. So how do I get the local position without doing something stupid like creating an extra variable I have to set from the inspector.

To give you a better idea of what I mean.

 //In some object's GUI function
 public GameObject FooInstance;
 
 void OnGUI()
 {
     if (GUILayout.Button("DooFoo", GUILayout.Width(Screen.width / 3), GUILayout.Height(75)))
     {
         FooInstance.SetActiveRecursively(true);
         Started = true;
     }
 }
 
 //Deep in Foo's tree of objects there's a component
 Vector3 HomePosition;
 void Start ()
 {
     HomePosition = transform.localPosition;
     MonoBehaviour.print(HomePosition); //Prints (0.0, 0.0, 0.0), but the object is not at the local origin.
 }

The script functions as expected when I have the object pre-activated from in the inspector, the error only occurs when I activate it from the script.

Comment
Add comment · Show 1
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 Tocs · Feb 21, 2013 at 03:30 PM 0
Share

Really? No answers? Well then I guess I'll just assume it's a bug in Unity.

3 Replies

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

Answer by Tocs · Feb 21, 2013 at 06:26 PM

While I didn't have enough information in the post to determine the issue. I still consider it a bug in unity. When SetActiveRecursively is called it begins to activate the child objects. But it doesn't complete this action before beginning to call updates to objects in the tree.

This violates reasonably intuitive rules of initialization. Just like members of a class are initialized, one would expect the children of an activated object to be initialized before updates were processed. Especially in an architecture that encourages multiple levels of objects.

I wouldn't have expected something similar to a race condition to emerge on something that is single threaded. But I suspect it's a result of "lazy initialization". AKA, the object's start isn't called until the object is needed by the internals of unity. I suspect this because adding an empty Update() function to the component suddenly remedies the issue. The object isn't recognized as needed when a member function is called. Perhaps there's some way to notify an object that it's needed?

So when an object higher up in the tree of objects modified the position of a lower object in the tree, the lower object wasn't initialized and the variable it accessed was still it's default value and not it's actual value. Which also makes me wonder where localPosition is stored before an object is activated...

Here's a sample showing the issue.BreaksUnity.zip


breaksunity.zip (247.4 kB)
Comment
Add comment · Show 1 · 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 Bunny83 · Feb 21, 2013 at 11:27 PM 0
Share

Unity works exactly as it should. Your problem is simply that you assign your HomePosition back to your local position "before" you actually store it.

If you read the docs on Start you can read that start is called just before any of the Update methods is called the first time. This is only the case when the scene loads. After the game is running there's not direct relation between different scripts.

If the scene load is done and the game is already running, the Start method of a script is always called right before it's own Update function when it's active for the first time. When you activate two or more scripts / object in the same frame, they will get their Start and Update methods called in this order:

 script A: Start
 script A: Update
 
 script B: Start
 script B: Update

What you've done here is you set the localPosition of script B in Update of script A. That means you overwrite the initial position of object B with the initial value of HomePosition which is 0,0,0.

After that Start of script B is called which will store the localPosition (which is now 0,0,0) in HomePosition.

That's actually the reason why you should use Awake to initialize the object itself and use Start for interaction with other objects.

ps: your Thread.Sleep is totally useless except that it will make your game pause for 100ms. Unity's scripting engine runs in a single thread, so if you pause the thread for 100ms nothing will happen in between.

pps: "children" of gameobjects are not really children. Only the transform components are in a hierarchical structure but each gameobject works on it's own, especially in Unity3.5. In Unity4 the active state will actually propergate doen to the children. So the active state of the parent acts as a pre condition for the childs.

ppps: most of those things can easily be spotted by placing some Debug.Log's in your scripts.

pppps: The deserialization of the objects in a scene happens between the constructor call when the object is created and the Awake call. So inside of Awake this object should be fully deserialized and should be placed at the position that was serialized.

avatar image
0

Answer by Bunny83 · Feb 21, 2013 at 04:19 PM

No matter what i do i can't reproduce what you describe. I have a gameobject with a nested child-tree. Every child has a script that prints it's name and localPosition in Start. All child gameobjects are deactivated in the inspector. The parent has a script that uses SetActiveRecursively(true); (which is actually deprecated but still works) when you press a button. I've moved all childs to certain local positions and when i press the button at runtime i get a print from each child with it's correct localPosition.

I've have even 5 childs, so it definitely works as it should. I'm pretty sure there's no bug in unity (why everyone's first guess is "it might be a bug"?). In most cases it's a fault in your own code. The only person that can debug your script is you.

Comment
Add comment · Show 2 · 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 Tocs · Feb 21, 2013 at 06:29 PM 0
Share

SetActiveRecursively isn't deprecated in 3.5,see tags. While I didn't supply enough information to discover the error, I still don't see it unreasonable to expect a bug in Unity. Given the far abstracted black boxed level everything is working at and how much the editor hangs. Unity is still (I$$anonymous$$O) young and while it makes a lot of things really simple, it still has a ways to go on others. Hopefully my answer will be approved by the moderators soon, as it contains a sample which reproduces the issue.

avatar image Bunny83 · Feb 21, 2013 at 11:30 PM 0
Share

@Tocs: It's good to use tags since they help others to find the question when they have the same issue. However if it's an important detail about your question it should be mentioned in the description as well.

avatar image
0

Answer by Dave-Carlile · Feb 14, 2013 at 02:39 PM

Does the transform have a parent? The localPosition is the position relative to the parent, or if there is no parent then it's the world space position.

So, if there's a parent, and the object is at < 0, 0 ,0 > relative to the parent, then localPosition will be < 0, 0, 0 >.

Try using transform.position instead?

Comment
Add comment · Show 1 · 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 Tocs · Feb 14, 2013 at 03:23 PM 0
Share

The object is 4 deep inside a tree of gameobject's so it has a parent. Also when I have the object pre-activated from the inspector, everything functions fine.

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.

Welcome to Unity Answers

If you’re new to Unity Answers, please check our User Guide to help you navigate through our website and refer to our FAQ for more information.

Before posting, make sure to check out our Knowledge Base for commonly asked Unity questions.

Check our Moderator Guidelines if you’re a new moderator and want to work together in an effort to improve Unity Answers and support our users.

Follow this Question

Answers Answers and Comments

11 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

Related Questions

Initialising List array for use in a custom Editor 1 Answer

Class isnt having Start called 1 Answer

unity doesnt start after registering 2 Answers

Help from start 3 Answers

How do I start game paused 2 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