Subclassing without creating a variable

Hia

I have a class that makes use of 5 separate classes. Each of the 5 classes will only ever be used as part of this first class so I didn’t want to create a separate file for each. This is even more true because of the fact that the reason I created the classes was merely for the purpose of having arrays of custom data when instantiating the first class.

So now I have 1 class that makes use of 5 more classes, all classes defined inside 1 script file. Now I want to extend the first class via a new subclass but to use it I must create a variable of the type of first class and use that variable inside my new script file. This works fine, but in the inspector all the variables of the first class are hidden underneath the member name I created…

the alternative is to create a new class that extends the first one but then I still need to create a variable of THAT class.

So my options are to have my subclass’s members visible in the inspector and have the main class’s members hidden inside one of those members, or I must have ALL members hidden inside a single member…

Is there no way of creating a subclass of the first class so that all the variables would be exposed in the root of the inspector?

Thanks in advance

p.s. I am using JavaScript, b.t.w…

I think you are confusing some terminology.

A ‘sub-class’ is a class that inherits all members and functionality from another class. In UnityScript, that would be done using the ‘extends’ keyword. The process of extending a class does not create any additional variables by itself.

What you seem to be talking about, is adding member variables of class B to a class A while having the members of B visible in the editor as members of A (hiding the actual hierarchy). As far as I know, this is not possible (or, as far as I’m concerned, desirable :P).

Inheritance using the ‘extends’ keyword does have the behaviour you want (i.e. if B inherits from A, the editor will show all variables of A as direct members of B). However, if A and B do not have an ‘is a kind of’ relationship (like in ‘an oak is a kind of tree’), it is unwise to use inheritance.

An option I have not tried before (or so long ago I don’t recall any more)

What about creating 2 files and saying the one extends the other. Can that be done?

I have noticed the @require statement will add a component to an object, but then I would have 2 separate components and the members from the one won’t be available inside the other without first creating, yet again, another variable through which to access it… At least now the variables are all in the root of the inspector, but now you have to modify variables in two components instead of one so that is even worse than the first way…

So @require is out of the question, but isn’t there something line an @insert that I could use instead?

That is exactly that I want to do.

One class handles AI and movement between waypoints and that is all it does. It has an array of waypoints as a public member.

Then I create a sentry subclass from that and this new class handles the rage of view and methods of alert the character has.
I could then also create a marine subclass from the second class and incorporate fighting AI into this class.

When I attach the Marine.js file to an object, I want to be able to change the view distance from subclass 1 as well as the weapon selections available in subclass 2 and still have it behave as in the original class if nothing else triggers an additional response. What I don’t want is to have 3 components in the inspector.

//firstclass.js
class BaseAI extends Object
{}

//secondclass.js
class Sentry extends BaseAI
{}
var Soldier_Sentry : Sentry;

//thirdclass.js
class Marine extends Sentry
{}
var Soldier_Marine : Marine;

As you can see in the above example, depending on wether I add secondclass.js or thirdclass.js to the prefab, I will either have Soldier_Sentry or Soldier_Marine available as a member of the script.

Of course I have the option of creating a 4th file and placing the variable in there and then creating all the functions as

function setRange(val : float)
{
Soldier_Marine.range = val;
}

or I could create the function inside Sentry and then say

Soldier_Marine.setRange(20);

which is the better way, but both ways work as expected. Both of them give me the inheritance I am looking for. What I don’t want, though, is that file1.js would show up in the inspector with a member of Soldier_Marine and inside that member will be the all the other members… I would like to skip that entire level of abstraction from the inspector.

Is this impossible, you say?

Since Unity treats a file as a class, basically what I want to do is subclass a file like I subclass a Class, but I read somewhere that a file automatically extends one of the Unity base classes so I assume that is not possible… or is it?

The behavior you’re talking about is the default behavior (in “JavaScript”).

So in JavaScript a file named Foo.js automatically creates a class “Foo” that is a subclass of MonoBehavior. In other words, if your script file contains no:

class Foo extends SuperClass {
}

then this is inferred to be:

class Foo extends MonoBehavior {
}

But if you use class … extends you can determine what you inherit from, what your class is called, and you can define multiple classes in one source file.

In general, I’d suggest that you use a “mixin” class strategy rather than a “subclass” strategy. This is how Unity’s own class library tends to work and it also seems to result in smaller, simpler, more maintainable scripts.

E.g. instead of implementing AI, AI_with_gun extends AI, AI_with_boat extends AI, AI_with_boat_and_gun extends AI, think more like AI_boat and AI_gun, and then assign both to a boat with a gun.

This is exactly how Transform, Component, Collider, and so forth work with each other, and it’s very easy to work with.

Indeed.

An AI script implements an ability. A sentry is not ‘a kind of AI’, it has AI. If you use inheritance and you discover later on in your project that some new type of Sentry needs a different AI implementation, you have a problem as you will need to make it inherit from a different base class (thereby breaking any code that expects Sentries to be of type AIBase). If you use the component based approach, as podperson suggested, it would be a simple matter of swapping out the old AI component for the new one and everything still works as expected.

Phoei… when I found that extends was available I jumped for joy… now it seems I should try and avoid it wherever possible… Only use it for data structures, not code that does anything…

Very disappointing… :frowning:

The very idea behind using it was the abstraction of unchangeable code and user manageable code for the purpose of making the variable part of the class smaller and more easily manageable. It is one thing to make thing “just work no matter what” and making code that is neat and clean and yet another thing to make code that is neat, clean and easy to read/ understand/ maintain.

I prefer to stay away from the first one, do mostly everything I can the second way, but every now and then I feel generous and place other people’s needs before my neat-freak-fetish-like way of coding and actually try and make it with “the next person to use my code” in mind…

:slight_smile:

Awww, well… you know what they say about the re-inventing of the wheel, yes? I guess I’ll just have to stick to doing it the way everyone else does it…

Thanks for the info. Much appreciated

I don’t understand why you believe object composition is “just work no matter what” and inheritance is “clean and easy to read/understand/maintain”. Both approaches have pros and cons, some problems are best solved with one, some with the other.

Unity picked composition for implementing GameObjects and I believe that to be the better choice (for usability, but also for maintainability) for the problem at hand. In my previous job I wrote a completely inheritance based rendering library. After working Unity for a while, I now believe that using inheritance for most of the structure was a bad idea ;).

Nahhh… Misunderstanding…

Sloppy coding that barely manages to run… THAT is bad coding… What you do on day 1… :wink: Then you get better and learn to get a bit more flexible in your coding and become more modular…
Composition is a neat and tidy form of modular coding but,
Inheritance, in my eyes, was supposed to be super clean ultimate coding…

I wanted to do something that looks amazingly simple to the end user, but it seems the middle-path is the best option.

'Wuzal I meant…

It has long been discussed that Inheritance hierarchies for game development are, in general, a poor idea.

Component models have superseded them in recent years. The messiness of most inheritance approaches is what led to the Component model to begin with. Example discussion:

http://cowboyprogramming.com/2007/01/05/evolve-your-heirachy/

Inheritance hierarchy is bad for any software.

You would commonly try to avoid it and instead approach such problems with the decorator pattern which gives you benefits from the inheritance without the hardcode binding against it.

I sure am learning a lot…

/me scribles some notes…

Thanks for that link!