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
1
Question by Eugenii · Jun 16, 2012 at 04:21 PM · updatefixedupdateontriggerstayoperatorexecution order

OnTriggerStay execution order/rate

Hello!

Is OnTriggerStay executed in different timer rather than FixedUpdate? And is it run in different thread rather than Update function?

I compare distance to checkpoint in OnTriggerStay and if it is smaller than some value, the next checkpoint is selected. All movement actions and distance calculation done in Update or FixedUpdate functions (I tried two ways). According to Unity's help "Execution Order...", it should work fine. But sometimes checkpoint is changed with an old distance value (to previous point) while it has to be recalculated in Fixed/Update function, but it seems this didn't happen.
When I add a check for an Update execution, strange pauses in some movement actions appeared. Is there any error?
Thanks

 void Update () {
 transform.position=Vector3.MoveTowards(transform.position,hBeacon.position,curSpeed*Time.deltaTime);
 distance=(hBeacon.position-transform.position).magnitude;
 testBool=true;
 }
 
 void OnTriggerStay (Collider other){
     if(testBool){
         if(other.transform==hBeacon&distance<=0.1F){
         hBeacon=Globals.beacon[ind].transform;
         }
     testBool=false;
     }
 }
Comment
Add comment · Show 9
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 fafase · Jun 16, 2012 at 05:46 PM 1
Share

Do you intend to use & or do you mean &&?

avatar image fafase · Jun 17, 2012 at 06:40 AM 1
Share

But do you know there is a difference between & and &&. If you want to check if smg AND smg else are true, you do if(smg && smgelse)

if(smg & smgelse) means you are "anding" the binary values of the variables. & alone is a bit operator and operating at the binary level.

Ex (simplified):

var a=1;

var b=2;

if(a&&b) returns true because both are non 0

if(a&b) returns 0

because 00000001 AND 00000010 =00000000 binary

avatar image whydoidoit · Jun 17, 2012 at 09:09 AM 1
Share

Yes but 01 & 10 = false and 01 && 10 = true. Don't use & unless you are checking for a bit.

avatar image fafase · Jun 17, 2012 at 09:19 AM 1
Share

Hm... Let's a=null and b=null, then if(a&b) produces false?

No, you get an error. The compiler expects two binary values but null is nothing you would have to convert it from ASCII to Int.

And what will produce if(01001001)? true because it is not 00000000?

yes it does but you need to convert it to int also. I would think the compiler does not consider a binary value here but more likely the 1 001 001 (1 million...)

you would have to use:

var a = System.Convert.ToInt32("01001001",2);

if(a)

avatar image whydoidoit · Jun 17, 2012 at 09:37 AM 1
Share

The real point is that in C a bool was an int, but in C# a bool is a bool and an int is an int.

You can't do if( someBool & someInt).

  //doesn't work
  If( true & 1)

Type safety is your friend dont return or use an int when you want true and false

Show more comments

3 Replies

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

Answer by aliakbo · Aug 26, 2012 at 02:03 PM

I've been struggling with this issue all afternoon!

My OnTriggerStay and Update/FixedUpdate methods were not in sync resulting is split-second undesired effects.

I finally found the solution when I read in the OnTriggerStay docs that this function can be a co-routine. I simply added a WaitForFixedUpdate in the correct location in my OnTriggerStay and it worked. They now both run in sync with each other. This even corrects the issue in Update.

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 Eugenii · Aug 27, 2012 at 03:36 AM 0
Share

Nice work! Now we have two solutions.

avatar image Winterblood · Apr 27, 2014 at 09:30 PM 0
Share

Note that this solution will delay the physics thread, which could slightly affect performance or reliability of the physics solve.

The physics is decoupled from the Update for a reason...use FixedUpdate ins$$anonymous$$d for things that need to be in lockstep with the physics.

avatar image whydoidoit · Apr 28, 2014 at 01:28 AM 2
Share

There is no physics thread and nothing will be delayed apart from the code after the WaitForFixedUpdate.

Physics runs as a catchup on the main thread.

avatar image
2

Answer by aldonaletto · Jun 16, 2012 at 08:06 PM

Collisions are detected in the physics cycle - not sure if before or after FixedUpdate. According to the docs, Unity processes an Update cycle (calling all Update, LateUpdate and coroutines), then start executing physics cycles, adding Time.fixedDeltaTime to the internal physics clock until it reaches the actual Unity clock. Since the physics engine only see its internal clock, it "thinks" to be always running at a fixed pace. If the frame rate is faster than the physics rate, you may have more than one Update cycle without any physics cycle in between (and no collision detection); conversely, several physics cycles may occur between updates when the frame rate is lower than the physics rate.
Anyway, I think you should use only Update, and OnTriggerEnter/Exit instead of Stay:

bool inTrigger = false; // is true while character inside current hBeacon trigger

void OnTriggerEnter(Collider other){ if (other.transform == hBeacon){ inTrigger = true; } }

void OnTriggerExit(Collider other){ if (other.transform == hBeacon){ inTrigger = false; } }

void Update(){ if (inTrigger){ // character inside trigger } }

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 Eugenii · Jun 17, 2012 at 08:08 AM 0
Share

Thanks! That solution works, but needs additional code for tracking collisions with objects (I also replace CollisionStay with Enter/Exit)...

avatar image KarlKarl2000 · Apr 03, 2016 at 11:05 AM 0
Share

Thank you!!!!

I was racking my brain all week to figure out the "onTriggerStay" bug I was having... basically it wasn't calling all the time.

Setting up the Bool ins$$anonymous$$d was the fix! So now I just call "enter" and "exit" and let the bool take the place of "stay" ... such a simple solution!!

avatar image
0

Answer by fafase · Jun 17, 2012 at 07:10 AM

I ran a little test for info about this with:

 var frame :int =0;
 function Update(){
     Debug.Log("Update "+frame+" "+Time.realtimeSinceStartup);}
 
 function LateUpdate(){
     Debug.Log("LateUpdate "+frame +" "+Time.realtimeSinceStartup);    
         frame++;}
 
 function OnCollisionEnter(other:Collision){
         Debug.Log("Collision "+frame+" " +Time.realtimeSinceStartup);}

Here is the result:

Update 44 1.143791

LateUpdate 44 1.145589

Collision 45 1.16041

Update 45 1.162351

To me, it looks like collision occurs on frame 44 to be detected and taken care of before any others on frame 45.

EDIT: Actually the documentation says it all:

 So in conclusion, this is the execution order for any given script:
 
     All Awake calls
     All Start Calls
     while (stepping towards variable delta time)
         All FixedUpdate functions
         Physics simulation
         OnEnter/Exit/Stay trigger functions
         OnEnter/Exit/Stay collision functions 
     Rigidbody interpolation applies transform.position and rotation
     OnMouseDown/OnMouseUp etc. events
     All Update functions
     Animations are advanced, blended and applied to transform
     All LateUpdate functions
     Rendering 
Comment
Add comment · Show 5 · 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 Eugenii · Jun 17, 2012 at 08:05 AM 0
Share

collision occurs on frame 44 to be detected and taken care of before any others on frame 45

So inspite of docs it would be always called before any update func, even fixed? Hm... it seems to be true. So the only way to make it work is to add a distance calculation in the body of "On...Stay" func...

Try this with a OnCollisionStay or OnTriggerStay. In docs they are executed after a fixedUpdate, before an Update.

But if you add a check for the Update cycle end, then it could skip some fixed timesteps. Without this check, it could be run twice before next Update or FixedUpdate cycle.

So the problem was: car touched 1st beacon and distance <$$anonymous$$, the next beacon is selected, Update func must recalculate distance to a 2nd beacon, but ins$$anonymous$$d this ...Stay func reads unchanged distance (to 1st point) and selects 3rd point while skipping 2nd.

avatar image fafase · Jun 17, 2012 at 08:57 AM 0
Share

The sentence you quote is somehow wrong, I will edit it.

The way it goes is that the collision occurs during frame 44, so update of frame 44 is running when collision happens. In frame 45, the collsion is first detected and processed, then the update is run. If you were to alter a value in your collision then in the update of the same frame it would be the new value.

On the other hand, FixedUpdate seems to be called first.

You would not use FixedUpdate and Update in the same script.

Running the little test I showed would give you the answer.

A command will not be run twice in the same frame.

avatar image Eugenii · Jun 17, 2012 at 09:34 AM 0
Share

On the other hand, FixedUpdate seems to be called first.

$$anonymous$$aybe, but as I remember it hadn't worked with a movement&distance calculation in FixedUpdate and checkpoint selection in OnTriggerStay... Or maybe I moved an object in Fixed and calculate distance in Update and that's why it didn't work. I have changed code, so don't have a simple way to test it.

avatar image fafase · Jun 17, 2012 at 09:58 AM 1
Share

The documentation shows that the Physics is in a loop (while) , when I do the same test with OnCollisionStay and FixedUpdate, LateUpdate is not printing meaning that as long as the object is colliding only the while/Physics section is looping, the rest is waiting.

avatar image Eugenii · Jun 17, 2012 at 11:36 AM 0
Share

Exactly! It is strange but I never thought that while in the doc means loop...
There is a new question: how long physic loop could run? $$anonymous$$aximum Allowed Timestep in Time $$anonymous$$anager? But then why did my trigger event fire after 300 frames (~2sec)?

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

9 People are following this question.

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

Related Questions

Ask for trigger-collision inside Update() 1 Answer

Slow motion all but one - yet another round, hopefully the last 6 Answers

2D physics jump issue. 1 Answer

Climb animation in Update or FixedUpdate or LateUpdate?, 1 Answer

Input and applying physics, Update or FixedUpdate? 3 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