- Home /
How to implement "PreUpdate" function
Hi,
I need to have a function in MonoBehaviour that is called before any Update functions of any other objects. LateUpdate is called after Update function and I would need something like "PreUpdate" that is called before.
Thanks in advance.
PS. FixedUpdate will not work because on very short frames it may be not called at all.
Actually this is one of the things that prevents Unity from being a 'real game engine', such granularity. Please request this at feedback.unity3d.com
You could modify the script execution order so that the script that needs to be executed before any other is. Find more information here.
Big thanks for responses. You are right I will try to explain what I am trying to achieve.
I have implemented a state machine that I use to control my main character and AI characters. States of this machines represent and implement behavior of different character tasks (i.e.: moving, jumping, standing etc.) These states have different logic and respond differently to player input. Each state implements functions:
OnEnter() - called after transition from different state
GetTriggeredTransition() - called before Update (used when we want to go to different state. When returns null - we do not change the state).
Update() - called when Update of given object should be called
LateUpdate() - called when LateUpdate of given object should be called
OnExit() - called before transition to different state
The problematic function is GetTriggeredTransition(). I use this function to build AI like this:
Being in PatrolState I check in this function if other player is close enough start chasing him. If yes then return transition to the ChaseThePlayerState.
If this function will be called after Update of any other character was called, there will be no consistency and world observed in GetTriggeredTransition() function will depend on execution order of $$anonymous$$onoBehaviour scripts. I want this function not only to be called before Update of this character but also before Update of any other characters that are using different state machines. Just like Update of one $$anonymous$$onoBehaviour is called before LateUpdate of any other $$anonymous$$onoBehaviour. So I want to get PreUpdate in $$anonymous$$onoBehaviour :).
I hope I was clear about what I want to do :)
So if you know a simple way how to get PreUpdate notification/event in $$anonymous$$onoBehaviour script I will be thankful.
PS. I have one solution on my $$anonymous$$d but I would like to hear yours before I confuse you with $$anonymous$$e :)
Another possibility is to use a driving class such that it is the only script that existis earlier in the execution order, and which raises an event during its Update phase. This way, you'll have PreUpdate called before update on whichever scripts are processing. Just un/subscribe during transition logic.
Answer by Jamora · Jan 14, 2014 at 03:13 PM
While tanoshimi's answer does seem to give the simplest way to achieve a "PreUpdate" using FixedUpdate (see the second link), there is a possibility FixedUpdate will not get called before each and every update only one time. I will propose a simple system which guarantees that a method is called before any logic in any Update is called. The solution relies heavily on the Script execution order of Unity, as suggested by iwaldrop.
You will need this script in a GameObject in every scene you require the PreUpdate. I recommend creating a prefab.
using UnityEngine;
using System.Collections;
public class FirstScript : MonoBehaviour {
public static event System.Action PreUpdate;
// Update is called once per frame
void Update () {
if(PreUpdate != null)
PreUpdate();
}
}
You will then need to set this script to be executed first. Open the Script Execution Order inspector, drag this script there and set it to execute first (above default time).
Then, in whichever script you require a PreUpdate function, just subscribe to the PreUpdate event in FirstScript. For example:
using UnityEngine;
using System.Collections;
public class NewBehaviourScript : MonoBehaviour {
void OnEnable () {
FirstScript.PreUpdate += HandlePreUpdate;
}
void HandlePreUpdate ()
{
Debug.Log("Preupdate in "+this.ToString() +" "+Time.frameCount);
}
void Update () {
Debug.Log("Update "+this.ToString() +" "+Time.frameCount);
}
void OnDisable(){
FirstScript.PreUpdate -= HandlePreUpdate;
}
}
HandlePreUpdate will always be called before any logic in any Update (except in FirstScript) is run.
If you require absolute control as to which PreUpdate is called first, you will have to modify FirstScript such that it maintains a List of functions which it calls, in order, from its Update.
Huh? I never said anything about using FixedUpdate! What I suggested was to create a new script, set to execute before all others, and calling any "PreUpdate" logic from the Update() function there (which is exactly the same as what you've demonstrated in code ;-)
it says FixedUpdate is run before any Update in the second link you gave.
Alas, FixedUpdate is not guaranteed to be called every frame, although it is up to interpretation as to whether it will be called often enough to work.
Thanks guys. I was thinking about similar way to solve this but your delegate solution seams really nice.
Answer by tanoshimi · Jan 12, 2014 at 08:14 AM
In general, it's helpful to explain the problem you are trying to solve, rather than the technical limitation that you believe prevents its solution. (Is there a reason, for example, that this couldn't be calculated in LateUpdate of the previous frame?)
However, it sounds like what you're trying to achieve could be done by placing all your "pre-update" logic in the Update() function of a new script, and setting that script to execute before all others:
Do note that calculating things in the previous frame and using that the next can generate a frame of latency (of around 16ms if you're running 60Hz). This may or not be an issue in your situation (it is in ours ;-) ).
Answer by unity_3KAIcHNkHzTZvw · Apr 19 at 03:44 PM
I know this is a very old thread, but after failing to succesfully implement any of the other solutions here (my problem wasn't compatible with any of them) I implemented this, and it works well for my purpose. I wanted to capture control info to make rebinding easier, and to get away from Unity's string-based key identifiers. It's not perfect for everyone, but it fits my use-case.
public class PlayerInput : MonoBehaviour
{
int lastCheckedFrame = -1;
InputState state;
public InputState State
{ get{
if( lastCheckedFrame != Time.frameCount )
{
state = new InputState();
lastCheckedFrame = Time.frameCount;
}
return state;
} }
}
public class InputState
{
float thrust = 0;
float roll = 0;
float pitch = 0;
float yaw = 0;
public InputState()
{
// Turn Input.GetAxis into variables here
}
}
Where is the relation to the OP's question, namely having a function that is called before any of the Update() calls?
Answer by MasterHoover · Aug 19, 2015 at 05:03 AM
Well, I think the reason the PreUpdate method isn't defined in Unity is because it isn't needed. My belief is that there is always a workaround.
If you absolutely want to change the state of your game before everything else, you can declare a function instead of all those Updates() that will be called by your StateMachine AFTER it has Updated its State.
First define a parent for all the objects that depends on the StateMachine
using UnityEngine;
using System.Collections;
// Parent for all objects that uses the StateMachine
// Mostly to be able to store all these scripts in a List<MyParentClass> variable
public abstract class ParentClass : MonoBehaviour
{
public abstract void ApplyConsequences();
}
Then use the parent classes on all your Objects that depends on the StateMachine.
using UnityEngine;
using System.Collections;
public class AnObject : ParentClass
{
void Awake()
{
// There you should add yourself in the memory of the StateMachine
// so it could then call all your ApplyStateMachineBehaviour() functions
MyStateMachine.Instance.MyObjects.Add(this);
// You might want to put the Awake in the parent instead, but not sure if it'll work.
// If you do be sure to remove abstract from ParentClass since you define a function.
}
public override void ApplyConsequences()
{
// There you define your desired effects
}
}
Finally use the defined function after you Update your StateMachine
public class MyStateMachine : MonoBehaviour
{
// A trick to be able to easily access one script from other scripts
// ===========================================
private static MyStateMachine instance;
void Awake()
{
instance = this;
}
public static MyStateMachine Instance
{
get{return instance;}
}
// ===========================================
private List<ParentClass> myObjects = new List<ParentClass>();
public List<ParentClass> MyObjects
{
get{return myObjects;}
}
void Update ()
{
UpdateState();
ApplyAllConsequences();
}
// There you Update your State
void UpdateState()
{
// ...
// ...
// ...
}
// There you call ALL ApplyConsequences()
void ApplyAllConsequences()
{
foreach(ParentClass obj in myObjects)
{
obj.ApplyConsequences();
}
}
}
Be warned that you will surely have to use the LateUpdate function since all Updates from all objects are processed simultaneously.
If your stuck in the LateUpdate, try to use a similar trick to order your functions properly. Define functions, and call the after another function.