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
1
Question by $$anonymous$$ · May 14, 2016 at 08:38 PM · scriptingbasicsupdate functionvirtual functions

Performance cost of implementing Update() in every script via inheritance?

Greetings,

I had it in mind to create a base MonoBehavior script class, which provides virtual base implementations of all the primary update functions: Update, FixedUpdate, and LastUpdate. Each game script would then inherit from this base class (instead of MonoBehavior), and simply override any of the functions that it needs.

A simple implementation of the idea looks like this:

 public class BehaviorBase : MonoBehaviour
 {
     [SerializeField]
     private bool _updateWhenPaused = false;
 
     public bool UpdateWhenPaused
     {
         get { return _updateWhenPaused; }
         set { _updateWhenPaused = value; }
     }

     // The GameStateManager is a singleton which tracks the paused/unpaused
     // state of the game
     protected GameStateManager GameState { get { return GameStateManager.Instance; } }
 
     private void Awake()
     {       
         OnAwake();
     }
 
     private void Start()
     {
         OnStart();
     }
 
     private void Update()
     {
         IfNotPaused(OnUpdate);
     }
 
     private void FixedUpdate()
     {
         IfNotPaused(OnFixedUpdate);
     }
 
     private void LateUpdate()
     {
         IfNotPaused(OnLateUpdate);
     }

     // Proxy function; will only call the provided action, if the game state
     // is 'not paused', or if the script is configured to Update when paused.
     private void IfNotPaused(Action action)
     {
         var paused = GameState.IsPaused;
         if(!paused || UpdateWhenPaused)
             action();
     }

     // Override these, to implement your initialization and update logic
     protected virtual void OnStart()  { }
     protected virtual void OnAwake()  { }
     protected virtual void OnUpdate()  { }
     protected virtual void OnFixedUpdate()  { }
     protected virtual void OnLateUpdate() { }
 }

And the child class could look like this:

 public class MyChildScript : BehaviorBase
 {
     protected override void OnUpdate()
     {
         // Update logic here.  
     }
 }

As you can see, this can be used to implement a convenient "Pause" system - the virtual OnUpdate*() functions are only called if the game is unpaused, or if the script has explicitly toggled its "UpdateWhenPaused" property.

The concern I have is; surely there is a reason Unity didn't implement this type of virtual function hierarchy in the first place? Is there going to be a noticable performance hit by implementing all these functions 'by default' in the base class?

Comment
Add comment · Show 3
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 flashframe · May 15, 2016 at 01:33 AM 1
Share

There's an interesting article about this on the Unity blog: http://blogs.unity3d.com/2015/12/23/1k-update-calls/

avatar image tanoshimi flashframe · May 15, 2016 at 07:10 AM 0
Share

Yes, great article, and some lively comments after too :)

avatar image $$anonymous$$ flashframe · May 15, 2016 at 12:17 PM 0
Share

Good article, thanks!

The conclusions it draws seem to have some caveats attached to them.

  • The performance is only visible when you have 10,000 scripts

  • Even then, it's only visible on a smartphone

  • Even then, you could get around it by having a single 'master update' function in some kind of manager script, which iterates over the rest of your scripts, calling your own special update function.

1 Reply

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

Answer by Bunny83 · May 15, 2016 at 11:52 AM

This is not recommended:

 IfNotPaused(OnUpdate);

Here you will create a new delegate instance each time you call the IfNotPause method. This will create garbage. Your IfNotPaused method should simply return a bool or you replace it with a property and do this:

 if (IfNotPaused)
     OnUpdate();

However keep in mind that if a MonoBehaviour implements a certain method it will be called by Unity which creates some overhead. A better implementation would be to either:

  • Don't implement any of the callbacks in the base class but only provide an "IsPaused" property so the actual implementation can do a simple early exit if they wish : it(IsPaused) return;

  • Implement helper classes one for each callback type and only attach those which are needed. You could use reflection in Awake to check if one of your callback has been overridden and subscribe the callback in the appropriate helper class.

One helper class could look like this:

 public class UpdateReceiver : MonoBehaviour
 {
     public event Action OnUpdate;
     void Update()
     {
         if (OnUpdate != null)
             OnUpdate();
     }
 }

So your base class could attach the appropriate Receiver component whenever it's needed and subscribe to the OnUpdate event dynamically.

However that approach has a lot of memory overhead as for each callback you would need a seperate Receiver class. The first approach is the most flexible with least overhead. So let the final child class decide if it want to handle a specific event and if it want to ignore it when the game is paused or not. Having all those OnStart, OnAwake, ... methods just makes life harder for everyone that is used to use Unity.

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 $$anonymous$$ · May 15, 2016 at 12:12 PM 0
Share

Your first approach seemed to be a happy compromise. I started to modify my base class, by removing all of the functions, and replaced it with a single boolean property: "ShouldUpdate". This returns true when the game is un-paused, or when the "Should update when paused" property is true.

In my $$anonymous$$d, I could simply place a clause at the top of all my update methods: if(!ShouldUpdate) return;

Halfway through the changes, I realized: if I had a script which I wanted to update regardless of the paused state, then I wouldn't even bother including that clause. It's pretty much only useful in scripts for which I want to skip updating when paused... which means the "ShouldUpdateWhenPaused" setting is also useless.

So I scrapped the entire base class. It doesn't provide much utility, once the virtual functions are gone.

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

4 People are following this question.

avatar image avatar image avatar image avatar image

Related Questions

Scripting Tutorial 1 Answer

Two GameObjects collide; only one OnCollisionEnter is triggered? 1 Answer

Can i Destroy GameObject on Load? 2 Answers

Im a beginner of Soomla, I have a lot of question:what to do next after creating my counter part of the MuffinRushAssets.cs? 1 Answer

Streaming and displaying score with photon? 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