Hello, I have a little problem I'm hoping someone can give me some advice on. I'll also probably use this thread for any future questions I have. The first is with using inheritance in javascript in Unity. I've used inheritance a little bit in Flash actionscript, but I'm not a very experienced programmer. I want to have a class called Event that handles checking when an event happens. Then I would have a series of classes that inherit from Event that have different specifics for what happens when a particular overridden function is used, such as EventAcceleration that would increase the acceleration of the player's avatar. I did a search on these forums, and found this thread which helped a lot. So I have a javascript file for Event which begins Code (csharp): class Event extends MonoBehaviour { and a file for EventAcceleration which begins Code (csharp): class EventAcceleration extends Event { But when I try to add EventAcceleration as a component to an object, I get the error: Code (csharp): Can't add script behaviour EventAcceleration. The script needs to derive from MonoBehaviour! Can anyone tell me what I might be doing wrong?
Hmm, what you tried looks alright to me from a normal standpoint (even if my C# is really rusty), but Unity has a few extra restrictions. According to the documentation every class must explicitly derive from Monobehaviour. Even plain old C# also doesn't do multiple inheritance, so that's out too. Perhaps this page might offer some help: http://www.c-sharpcorner.com/Upload...ance11082005004843AM/MultipleInheritance.aspx However, I haven't tried C# in Unity, I'm using Unity as an excuse to learn javascript!
I think the problem is that Event is a class defined by Unity, which does not inherit from MonoBehaviour! http://unity3d.com/support/documentation/ScriptReference/Event.html If we had namespaces, you could still use the name Event in a different namespace. All you can do is name the Base class differently. MyEvent for example.
Thanks for the replies. That doesn't seem to be the answer, Der Dude. I tried renaming the Event class, and the extends line in EventAcceleration, but I still got the same error. It sounds like DMJ is saying that what I am trying to do is not possible in Unity. Is this right? I'm going to either have to put code for all of my different Events into the same script, or duplicate code across multiple scripts?
No, I use inheritance all the time with C#, just like you are doing here. I never use JavaScript, so I can't tell you if it possible or not with that. @DMJ: Not every class must inherit from MonoBehaviour, just the base-class.
I just tried to reproduce the problem, but it works for me! I attatched the Scripts here. I added a simple OnGUI function to the extended event to see if Unity works right with the event. It does
I am always happy to be proven wrong when it makes my life (or someone else's life) easier for me to be wrong
Well, using your scripts doesn't give me any errors. I'll start adding in the functionality of my old scripts and see where it goes wrong. Thanks Der Dude.
No problem. Something that might be causing your problems are the filenames. Are they all named like the class that are in them?
Yes, they all had the same filename as their class name. I've got all of the old Event functionality working in your MyEvent, so I don't know what the problem was. I'm now at the point of trying to override a function from the base class in the extended class. But I'm not sure how to do this in Unity javascript. The only search results I've found say that 'override' doesn't work in Unity javascript. The aim is for the Update() function in the MyEvent class to check common conditions, and then use a function called PerformEvent(), which would be different for each extended version of the class.
When overriding, you simply call the parent function from the child and add any additional functionality beneath it. I'll post an example if I can find my notes...
May I ask why you don't use C# instead of JavaScript? When using inheritance and other Object-Oriented techniques I find C# to be much more transparent (and better documented!) than JavaScript.
The only reason would be that the tutorials and examples I've used so far have all used javascript. I've had no experience with either language before.
I would recommend you switch to C# if you continue using Object-Oriented techniques such as this. This is just my opinion, but I think it is just inherently clearer what the code means when you have such a strongly typed language. It gets rather confusing in JavaScript. Converting JavaScript to C# isn't too hard. But it is a pain in the neck to convert a whole project. So if you want to switch, do so soon I learned that the hard way a few years back... If you need help with the C# specifics, you can PM me if I don't see your thread. I'll be glad to help.
Here you go. No reason to switch to C#, you can do most everything you need in javascript and type a whole lot less! Code (csharp): class MyParentClass{ function MyParentClass(){ //constructor //place initialization routines here if needed } function MyFunction(){ Debug.Log("Original function called"); } } class MyChildClass extends MyParentClass{ function MyChildClass(){ //constructor super(); // calls MyParentClass constructor //add additional functionality here } function MyFunction(){ super.MyFunction(); //calls original MyParentClass function //add additional functionality here Debug.Log("New function called"); } }
Code (csharp): test = MyChildClass(); test.MyFunction(); The console should show that both functions, the original parent and extended child were accessed.
Hmm. Thanks tonyd. I'm not sure that applies to what I'm trying to do, though. What I have is something along the lines of this: Code (csharp): class TimelineEvent extends MonoBehaviour { function Update() { // If conditions go here PerformEvent(); } function PerformEvent() { // This function remains empty } } Code (csharp): class TimelineEventAcceleration extends TimelineEvent { function PerformEvent() { // Stuff happens here } } The update function in the parent class is the one that calls the PerformEvent function. But I want it to use the functionality in the PerformEvent function of the child class. My previous experience with inheritance is with Flash Actionscript 3, where I did something very similar to what I describe above. Der Dude, would you be able to give me an example of how to do this in C#? If it is easier, I might switch to it now.
Use the super keyword to access the parent class functions and properties from the child class. You can't access children from their parents.
Sure: Code (csharp): public abstract class MyEvent : MonoBehaviour { public void Update() { // If Conditions here PerformEvent(); } public abstract void PerformEvent(); } Code (csharp): public class MyExtendedEvent : MyEvent { public override void PerformEvent() { // Perform! } } You can prevent other scripts from calling PerformEvent by making it protected (instead of public). Then only subclasses of event can call this method. This is another advantage of using a properly object-oriented language like C#.
I think I've got this working now. This is what I've ended up with: Code (csharp): class TimelineEvent extends MonoBehaviour { function EventTimeIsNow() { If (conditions == true) { return true } else { return false } } } Code (csharp): class TimelineEventAcceleration extends TimelineEvent { function Update() { if (super.EventTimeIsNow()) { PerformEvent(); } } function PerformEvent() { // Stuff! } } It's not ideal - I was trying to make it as easy as possible for the other members of my group to add new types of event, without having to do anything other than make a script with a new PerformEvent() function. But I think this will do. I've got a better idea about how all this works in both javascript and C# now, anyway - I did an experiment into converting the project into C# as well. Thanks, everyone.
This is totally possible using a properly object-oriented language like C# and I would recommend this kind of code-design as you save yourself work. Checkout my example, it should do what you want. When working in a team C# has another nice feature: you can split up one class onto many files. Just add the modifier "partial" in your class header. Like this: FileA.cs Code (csharp): public partial class MyClass {} FileB.cs Code (csharp): public partial class MyClass {} When compiled the parts of the class are put together again. It behaves just like a single class, except you can work independantly on the files.
Actually, I've just figured out what I was doing wrong in my converted C# version of the project, so I might do as you suggest and carry on in C#. Thanks.
roBurky, You can do as you intended in javascript, much more simply. No C# required: Code (csharp): class TimelineEvent extends MonoBehaviour { virtual function PerformEvent() {} } class TimelineEventAcceleration extends TimelineEvent { function PerformEvent() { // If the PerformEvent method of TimelineEvent has an implementation, uncomment this line to call it. //super.PerformEvent(); // Implement TimelineEventAcceleration-specific PerformEvent behavior here: return; } } Note that if you use Unitron, the virtual keyword will not show up as a known keyword. Neither will super. Both are supported by Unity, however. Now you can take object instances of all sorts of derived events, explicitly or implicitly cast them to your TimelineEvent base class, and call their respective PerformEvent methods polymorphically. No downcasting or knowledge of the specific child class type is necessary. For example, let's say you wanted to implement an event handler to which these events would be passed. You can just do this: Code (csharp): function ProcessEvent(event: TimelineEvent) { event.PerformEvent(); return; } You can pass any event object instance to this method, regardless of its class type, as long as that class (or a parent) extends your TimelineEvent class. Note also that the PerformEvent function in the parent class must be defined with empty brackets, but it will treated as purely virtual unless you call it via the super identifier as noted in the example above, or your child class overrides the method. In the later case, as noted, you have to call the parent's PerformEvent method from within the child's method via super if you want both to be called. Frankly, I don't like the ambiguity between virtual methods and purely virtual methods in the way this was implemented in javascript. Incidentally, C# addresses this clearly through the override keyword. Unfortunately, there is a lot of misinformation on the forum regarding inheritance and polymorphism in javascript. This may be because virtual methods/functions weren't always supported in Unity javascript (I haven't been around long enough to know for sure) and because of the dearth of information in the documentation. I love C# as much as much as the next guy, but if you choose to switch, you should do so based on correct information. There are many things you can do in C# and can't do in javascript, but this is not one of them.