Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 14 Next capture
2021 2022 2023
2 captures
12 Jun 22 - 14 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 BCFEGAmes · Mar 09, 2020 at 09:55 PM · static variableexecution order

Execution order of static variable value change in update

A student in a game design class "hacked" a plate stacking function ingeniously: using a third person controller with a trigger box attached in front, he can collect "plates" staggered on a plane "On trigger enter" by pressing a button (position of plate object goes off screen) and drop all collected plates by pressing another button (position of plates goes to trigger box position), at first the plates would spawn overlapping, and here is the hack: He used a static variable "Object Counter" on a script attached to each plate, it increases on each pick, and decreases on dropping. He passed the value of the counter to the Y position of the object (x & z are determined by trigger box position) and the plates are dropped in a stack! I was surprised that each plate always had a unique value for counter, even if all are dropped on the same Update call. I've seen threads about order within an Update cycle being undetermined, but is this problematic in a meaningful way? He should probably do a for loop, and have an array of picked plates, but I was impressed how one line of code with a static counter in multiple GOs updates worked so smooth. I believe the order is out of his control, but are there fundamental flaws to this approach?

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

1 Reply

· Add your reply
  • Sort: 
avatar image
0

Answer by Fragsteel · Mar 09, 2020 at 10:18 PM

If the object counter variable is being incremented/decremented immediately after each put/drop, before another can be put/dropped, I don't see how order can make a difference.

You are correct that the order that Update() is called between GameObjects is generally arbitrary (assuming he didn't change the script execution order). But if he sets a static variable, it will be applied instantly, and will therefore be changed before the next Update() is called.

If I can make some assumptions about how the code is written, that static function can basically serve as the first available "slot" in a stack of plates, where each "slot" is a Y position. For simplicity's sake, I'll say that each plate is 1m tall (even though that's almost certainly not true) just so that it gets incremented by 1 each time.

Before any plates are dropped, the number of dropped plates is 0, so the first available "slot" is Y=0. Then if a plate's Update() tells it to be dropped, it will appear at Y=0, and immediately set that "slot" to 1 before any other Update() functions get to be called. So then when the next plate hits its Update() (no matter which plate) the "slot" will be 1, and it'll appear at Y=1, on top of the first plate, and set the slot to 2, etc.

I have a slight feeling that it's not 100% understood what a static variable does. Each plate never in fact "had a unique value for counter" because that's impossible for a static value; all instances of a class share the same value for a given static value, as static means it's not tied to an object/instantiation, but the class itself. It's just that each time a plate drops, the value that all plates share gets changed before another plate uses it.

I do think it's a clever solution. The only thing I don't like about it is that it would not work if there were multiple trigger boxes, as dropping a plate on one box would cause plates dropped on another trigger box to appear elevated. I'd instead have that value as a non-static value on a script on the trigger box. I'd also personally want to move the logic that makes the plates appear out of Update(), instead triggered by events, but that's just me.

Comment
Add comment · Show 3 · 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 BCFEGAmes · Mar 09, 2020 at 10:50 PM 0
Share

Thanks for the fast reply, the slot analogy does indeed work. What surprised me was that I was under the assumption that an update call on multiple game objects, each accessing the same static variable in the same Update frame, would have received the same value for that variable, even if within that update cycle the variable gets changed. I guess it's not actually a parallel operation, unity must somehow cycle all gameobjects and call update in a sequence. If I recall, this is deter$$anonymous$$ed by the location of the gameobject on the memory "stack"... As this was a game design class, not program$$anonymous$$g, the gameplay loop rather than the code take priority, and the student came up with a "simple" solution!

avatar image Fragsteel BCFEGAmes · Mar 10, 2020 at 09:27 PM 0
Share

Yup! Pretty much any $$anonymous$$onobehaviour function you can work with (Start, Update, etc.) is called on the main thread. Generally, nothing's really parallel in Unity unless it's something more in the background or separate from your scripts (like a lot of rendering stuff on the GPU), you explicitly called an async Unity function (like Jobs stuff), or if you started a separate thread yourself (via normal C# threading stuff).

Even coroutines, which feel asynchronous, are actually on the main thread, and just run before most logic each frame, and basically just pause for a frame when you call yield return.

This diagram is quite helpful: https://docs.unity3d.com/$$anonymous$$anual/ExecutionOrder.html

So generally, until you're pretty advanced, you don't have to think about asynchronous code unless you want to implement something specific yourself.

It's still important that you recognize that the order between GameObjects having their $$anonymous$$onobehaviour event functions called is arbitrary. That can come into play if a method in one object assumes that a method in another object has already gone off. This usually causes issues in Start() and Awake(), less so Update().

For example, say you have Object A and Object B with different scripts. Object A has some value called "target", and in Start() it calls something like`ShootAt(target);`. But say you don't define what its target is in the Inspector. Object B's Start() has something like FindObjectOfType<ObjectA>().target = this; so that as soon as its Start() goes off, Object A knows what to shoot at. This might cause problems, but might not. If Object B's Start() goes off first, Object A will know what to shoot at when its Start() goes off. But if Object A's Start() happens first, you'll get a null reference exception since target wasn't set yet.

avatar image BCFEGAmes · Mar 09, 2020 at 10:56 PM 0
Share

recreated the effect for testing, add this to multiple identical game objects.

 public class staticCounter : $$anonymous$$onoBehaviour
 {
     public static int counter = 0;
     public int myCounter = 0;
    
    void Update()
     {
         if (Input.GetButtonDown("Fire2"))
         {
             myCounter = counter;
             Debug.Log(gameObject.name + "has counter of" + counter);
             counter--;
         }
     }
     
     void On$$anonymous$$ouseDown()
     {
         counter++;
         Debug.Log(gameObject.name + "has counter of" + counter);
     }
 }

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

123 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

Related Questions

some behavior on over-shoulder view and static var in update() 0 Answers

Collider keypad 0 Answers

Coroutine, Start() and Update() execution order 1 Answer

How is the following code from 'Space Shooter' Tutorial Working? 1 Answer

Why does it seem as if my code is exuting in wrong order? 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