- Home /
Using GetComponent with a subclass
Hi all!
I have a Vehicle
Script class with a Depart
method.
I have a set of subclasses: Car
, Motorcycle
, Truck
, Bus
, ... each vehicle behaves differently when Depart is called.
A main method SendVehicle(Vehicle vehicle)
is used to initiate and send a Vehicle.
Code is as follows
var vehicleScript = vehicleInstance.GetComponent<Vehicle>();
vehicleScript.Depart(...);
Unfortunately this calls Depart in the parent class, not the subclass!
Doing the following works perfectly fine!
if(vehicleType == Vehicles.Car)
{
Car carScript = vehicleInstance.GetComponent<Car>():
carScript.Depart(...);
}
Any idea what I've done wrong?
The reason I'm using subclasses is because I would like to abstract this in the first place.
Hope someone can help! :) Thanks!
I'm guessing you have both Vehicle
and it's subclasses attached to the object. When using GetComponent
the first thing that is searched for, is components that are of that type. The next thing that is searched for is a component that derives from that type. If you have both attached, it will only ever find Vehicle
when searching for Vehicle
.
It would be easier to answer if you gave us more information on the setup and the classes (not the content, just the setup ;) )
Answer by Seth-Bergman · Jul 25, 2013 at 11:08 PM
I think you need a virtual function.. here's a few example answers:
http://answers.unity3d.com/questions/135194/how-to-use-different-types-of-scripts-with-an-over.html
http://answers.unity3d.com/questions/33477/question-about-overriding-functions.html
Answer by Jamora · Jul 25, 2013 at 11:12 PM
If you have an implementation of Depart in Vehicle
and you do the first snippet, then you are calling the implementation of Vehicle.Depart, because you are handling Car
as type Vehicle
.
What you should be doing here is not provide an implementation of Depart in Vehicle
at all, by making it an abstract class and providing an abstract method declaration in Vehicle
.
public abstract void Depart();
Now, you need to have
public override void Depart(){/*implementation*/}
in all of your child classes for the second snippet to work as intended.
A slightly more complicated case
In case you have common functionality in Vehicle.Depart
that all children need to do when their Depart
is called, you need to instead have this in your Vehicle
class
public void Depart(){
/*shared functionality*/
SpecializedFunctionality();
}
protected abstract void SpecializedFunctionality();
and then you need to provide an implementation for SpecializedFunctionality
in all your child classes as before.
Abstract is actually a very special case where you want to force a subclass to implement this function and to prevent the creation of the base class itself. The "normal" way is to make the function virtual (abstract is a special kind of virtual) and you might override it in a subclass.
If you have shared functionality in the vehicle class you simply implement it in the Depart method of the base class. When you override the method in a subclass you can use base.Depart to call the Depart method of the base class.
Answer by Bunny83 · Jul 25, 2013 at 11:54 PM
Just to provide a full example:
public class Vehicle : MonoBehaviour
{
public virtual void Depart(string someParameter)
{
Debug.Log("Vehicle:Depart("+someParameter+")");
}
}
public class Car : Vehicle
{
public override void Depart(string someParameter)
{
base.Depart(someParameter);
Debug.Log("Car:Depart("+someParameter+")");
}
}
public class Truck : Vehicle
{
public override void Depart(string someParameter)
{
// We don't need / want the base function in this subclass, so we don't call the base method
// base.Depart(someParameter);
Debug.Log("Truck:Depart("+someParameter+")");
}
}
public class Bus : Vehicle
{
public override void Depart(string someParameter)
{
// The bus need to do some more stuff before calling the base method:
Debug.Log("Bus:Depart("+someParameter+")");
base.Depart(someParameter + " with changed parameter");
}
}
Some examples:
var vehicleScript = carInstance.GetComponent<Vehicle>();
vehicleScript.Depart("Sample one");
vehicleScript = truckInstance.GetComponent<Vehicle>();
vehicleScript.Depart("Sample Two");
vehicleScript = busInstance.GetComponent<Vehicle>();
vehicleScript.Depart("Sample Three");
This would print those lines:
Vehicle:Depart(Sample one)
Car:Depart(Sample one)
Truck:Depart(Sample Two)
Bus:Depart(Sample Three)
Vehicle:Depart(Sample Three with changed parameter)
Your answer
Follow this Question
Related Questions
Does Unity support multiple Inheritance? 3 Answers
The name 'Joystick' does not denote a valid type ('not found') 2 Answers
How can I access an inherited method from a separate (collided) object? 1 Answer
Does Unity support Inheritance and Subclassing? 9 Answers
Inheritance and using GetComponent 2 Answers