Update 2018: They actually didn't do any of this and ended up dropping the ball so hard it's shocking.
As a reminder, here is the summary of what ScriptBehaviour
was described as:
- It's like MonoBehaviour2, and those will exist side by side for some time, for the benefits of maintaining backwards compatibility on one hand and advancing the architecture on the other.
- Better design of events.
- Discarding of "magic methods", these are either going to be virtual methods on the base class or defined in the interface. The goal is to have the IDE's support for these methods, and not have it mistyped and then silently not working.
That was all in the presentation and I didn't find any other sources about these topics so far. I want to comment on the last point, the removal of "magic methods" and give my personal thoughts on that. For a start, I am absolutely sure that Unity is going to get solid architecture on the way there. There is a lot of magic that Unity does for us and we aren't always conscious of all these things. However, I still want to give a couple of comments.
ScriptBehaviour as base class with virtual methods:
I have some pseudo-implementation in C# to demonstrate my points. Here goes:
public class ScriptBehaviour {
protected virtual void Start() { }
protected virtual void Update() { } }
public class MyScript1 : ScriptBehaviour {
protected override void Start () { }
protected override void Update () { } }
If the new ScriptBehaviour looks like this (and from what we heard at the conference it is likely), there are a couple of consequences:
We can't change access modifiers when using override in C#. If the Start()
in ScriptBehaviour
is made protected, then all the deriving classes must stay protected, and cannot be either private nor public. Same logic applies if base methods in ScriptBehaviour
are initially public. This is a bit of a problem, because it violates the encapsulation that we actually have right now. Personally I don't like this side effect. My guess is they will make them public just in case and use this method.
The solution could be to use new
instead of override
(the base implementation doesn't do anything anyway), but this actually doesn't get us anything:
public class MyScript2 : ScriptBehaviour {
private new void Start() { // Is legal, but no intellisense for Start in VS 2015
}
}
As soon as we type new, Intellisense in VS 2015 stops concluding what might come next (as it does with override) and we don't get the benefits of using this method at all. You may say that Unity can talk to VS people and get that as a feature, but we actually have that right now - as part of VSTU we just type in Ctrl + Shift + M and get the methods without this. What we do get is a warning if we use both new
and mistype the method name. This will not prevent running the game, but it does give the warning MyScript2.Starts() does not hide an inherited member
. The new
keyword is not required.
When the IDE does offer the method to override (using the override technique in point 1), it provides the default implementation that calls the base method. We will probably have to delete that call every time, and it may be confusing to beginners. I guess this is fixable through VSTU.
protected override void Start() {
base.Start();
}
It is possible that Unity could talk to C# and VS teams and make some special magic happen to mitigate these drawbacks.
Physics calls through interfaces:
public interface IOnTriggerEnter {
void OnTriggerEnter(Collider other);
}
public interface IOnTriggerStay {
void OnTriggerStay(Collider other);
}
public interface IOnTriggerExit {
void OnTriggerExit(Collider other);
}
public class NewBehaviourScript : ScriptBehaviour, IOnTriggerEnter, IOnTriggerExit, IOnTriggerStay {
public void OnTriggerEnter(Collider other) {
}
public void OnTriggerStay(Collider other) {
}
public void OnTriggerExit(Collider other) {
}
}
The calls to Physics may be have to be specified through interfaces instead of overriding them in the base class. This has also a couple of consequences:
The methods now must be public: they can't be private nor protected when being implemented through the interface. With base class we could get away with having at least protected.
I am presuming every call will have its own interface. This is based on Interface segregation principle from SOLID principles, so I would pretty much rule out the fat interface. Such fat interface would lead to having to implement all the methods in the group, which seems like more trouble than it is now. As a side effect, we could get quite a bit of interfaces to type beside the class name.
ScriptBehaviour and performance
We really can't say anything about the performance right now. My guess is Unity will do what is right to not negatively impact performance. If a virtual function call is more expensive than the way they are doing it now (presumably some kind of Invocation list), than they can call the methods just like they do right now.
Overall the increase in accessibility modifiers is not a huge issue, but it is worth considering in my opinion. This thing may not come any time soon, so we will see how right I was in my analysis. [Update 2018: Totally off, if it ended with this it would have been well.]