- Home /
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.
}
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.
$$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.
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.
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
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");
}
}
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.
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.
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.
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
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.
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.
Your answer
![](https://koobas.hobune.stream/wayback/20220613160639im_/https://answers.unity.com/themes/thub/images/avi.jpg)