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
0
Question by Shawn Miller · Aug 15, 2014 at 05:51 AM · c#updatehide

Is there a way to prevent the use of Update/FixedUpdate in child scripts?

From what I'm seeing, there's nothing that can be done to prevent their use, but I might be missing something. We already have a system in place which handles Update/FixedUpdate-like functionality better suited to what we're doing and would like to lock out their use solely to our base class. Since they're not even inherited functions, neither sealed nor private new work, with the former not even compiling for obvious reasons.

Is there something that can be done to prevent those functions from being used or do we simply have to ensure that no one uses them throughout the project?

Edit: To be more specific, this is the scenario.

 class BaseClass : MonoBehaviour {
   void Update() { /* core logic */ }
   public virtual void Tick(float dT);
 }
 
 class ChildClass : BaseClass {
   void Update() { ... } // Do not want this to ever run, but it does.
   public override void Tick(float dT) { ... } // This is where code should go.
 }


Comment
Add comment · Show 4
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 GameVortex · Aug 15, 2014 at 06:14 AM 0
Share

I am slightly confused as to what you are trying to achieve. Do you not want Unity to call the Update and FixedUpdate functions you have included in the child class, and ins$$anonymous$$d have the base class handle it? And you do not want anything outside of the base and child class to be able to call those functions?

Then you should set the functions as being protected ins$$anonymous$$d of public or private and the functions should be named something else than Update and FixedUpdate so Unity calls the correct ones in the base class.

avatar image Shawn Miller · Aug 15, 2014 at 06:29 AM 0
Share

$$anonymous$$y intention is for a scenario where you have a base class, which is the only class with access to those functions. All scripts in our project inherit from that class and have different functions which they specifically build into to handle that functionality.

This is less of an issue of requirement and more something I'd just like to keep from having to fix, as everyone can easily use those alternative functions. However, I'd like to be able to simply negate the possibility that someone might unintentionally overwrite the base class' implementation of Update/FixedUpdate. It's just a nice thing to have that I've grown accustomed to with C++ based engines.

avatar image GameVortex · Aug 15, 2014 at 07:44 AM 0
Share

Okay I understand then. As far as I know there is no way around that as nothing can prevent the child class from implementing the Update function and Unity will always call the Update function of the child class first.

avatar image meat5000 ♦ · Aug 15, 2014 at 06:33 PM 0
Share

Can you not simply not include the function? Or is it a case of something (Not a child) with an Update() and contained code, that you want to not run when it becomes a child?

In Hacktastic Pseudo Stylee:

 function Update()
 {
      PseudoUpdate();
 }
 
 function PseudoUpdate()
 {
    if(!child){Update-Code}
 }

Flexible? No. Ideal? No. Hacktastic? Definitely. Does it work? Probably :P

2 Replies

· Add your reply
  • Sort: 
avatar image
3

Answer by DeepwaterNewt · Aug 15, 2014 at 07:27 AM

Hey there,

sealed is definitely the answer, you may need a third class in the mix

See examples here: http://msdn.microsoft.com/en-us/library/aa645769(v=vs.71).aspx

I used the example from the above link to prevent overriding of a method, like this:

 class A : MonoBehaviour
 {
     public virtual void F() {
         Debug.Log("Class A, Method F");
     }
     public virtual void G() {
         Debug.Log("Class A, Method G");
     }
 }
 class B: A
 {
     sealed override public void F() {
         Debug.Log("Class B, Method F");
     } 
     override public void G() {
         Debug.Log("Class B, Method G");
     } 
 }
 class C: B
 {
     override public void G() {
         Debug.Log("Class C, Method G");
     } 
     override public void F() {
         Debug.Log("This will not work, gives error");
     } 
 }



Comment
Add comment · Show 6 · 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 Shawn Miller · Aug 15, 2014 at 07:49 AM 0
Share

The issue is that the $$anonymous$$onoBehaviour-specific functions aren't abstract/virtual functions to begin with. If you attempt something like: private sealed void Update() {}

Then Unity will yell at you because "classname.Update() cannot be sealed because it is not an override". Those functions appear to be some secret juju rather than member functions of $$anonymous$$onoBehaviour, otherwise this would be a simple fix.

avatar image DeepwaterNewt · Aug 15, 2014 at 11:48 AM 0
Share

The code that I pasted above pretty much does what you want, you just need an additional class inbetween $$anonymous$$onoBehaviour and your BaseClass. Create an "Extended$$anonymous$$onoBehaviour" class, that overrides the Update method, and make it sealed, then derive your BaseClass from Extended$$anonymous$$onoBehaviour. That should do the trick.

avatar image Shawn Miller · Aug 15, 2014 at 05:34 PM 0
Share

I gave it a try just in case, the results were the same. Because you don't have to override Update, you can simply say, in class C void Update() and it will give you a compiler warning saying that C.Update() will override the implementation of B.Update().

The way Unity seems to work, it simply looks for an Update function and will take whatever the first function it encounters is and run it, regardless of anything, modifiers included. Beyond that, apparently sealed functions can even be overwritten in C#, which completely defeats the purpose of sealed.

I can still use this for quicker problem debugging since it does throw that compiler warning, which makes it easier to spot.

avatar image DeepwaterNewt · Aug 16, 2014 at 08:59 AM 1
Share

I managed to do what you wanted using three classes, ins$$anonymous$$d of two:

 class BaseClass : $$anonymous$$onoBehaviour {
     float count = 0;
     public virtual void Update() {
         count++; // Just to not spam the debug log
         if(count % 60 == 0) {
             count = 0;
             Debug.Log ("BaseClass Update() called");
         }
     }
     public virtual void Tick(float dT) {}
 }
 
 class $$anonymous$$iddleClass : BaseClass {
     float mcount = 0;
     public sealed override void Update() {
         mcount++; // Just to not spam the debug log
         if(mcount % 60 == 0) {
             mcount = 0;
             Debug.Log ("$$anonymous$$iddleClass Update() called");
         }
     }
     public override void Tick(float dT) {}
 }
 
 class ChildClass : $$anonymous$$iddleClass {
     float ccount = 0;
     public override void Update() {
         ccount++; // Just to not spam the debug log
         if(ccount % 60 == 0) {
             ccount = 0;
             Debug.Log ("ChildClass Update() called");
         }
     }
     public override void Tick(float dT) {}
 }

Unity immediately complains:

Assets/Scripts/ChildClass.cs(7,30): error CS0239: ChildClass.Update()': > cannot override inherited member > $$anonymous$$iddleClass.Update()' because it is sealed

avatar image DeepwaterNewt · Aug 16, 2014 at 09:06 AM 1
Share

You could even add, at the end of the $$anonymous$$iddleClass's Update() function, this:

 base.Update();

To call the BaseClass's Update() function as well.

Show more comments
avatar image
0

Answer by NicoVar · Oct 31, 2016 at 11:36 PM

If I understood correctly, you're trying to implement dirty updates and don't want your objects' scripts to be using Update() on their own.

Since Unity only allows Monobehaviours attached to GameObjects, what we did in a similar scenario is invert the control of things: instead of having a Monobehaviour script attached to a GameObject, we have a non-Monobehaviour script, with a reference to the GameObject, and we call our own DirtyUpdate() function and perform whatever we want on the GameObject.

However, not having a Monobehaviour will also prevent you from receiving all Unity events such as collisions, so keep that in mind.

The GameObject would not have any scripts attached to it. If you need Unity Editor control, you can use ScriptableObjects and also add references to it.

It's not the cleanest solution but it works.

However, this does not prevent anyone from creating a Monobehaviour and attaching to the GameObject.

On the other hand, you can have a safety check (if you're working on a large team, for instance, and are receiving scripts from multiple developers), that performs some tests on all the prefabs through Resources and check if GetComponent is true, then throw an exception.

Comment
Add comment · 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

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

25 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

Related Questions

Multiple Cars not working 1 Answer

Distribute terrain in zones 3 Answers

Update functions and performance 0 Answers

Unity to Check Arduino LED Status 0 Answers

How to make this code fire projectile once during the Update function? I know Update means every frame. 1 Answer


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