- Home /
How to access an instance of a class when the class isn't known
Hello,
I have a script called Main that does stuff when you make a mouse click. I have a script called Player and another called Soldier. The Soldier script defines a Soldier class and inherits from Player. Player has a function called playerSelected().
I want to query this function and run other functions from the Main script, but I don't know whether I'm calling Player or Soldier, or even GameObject. I tried GameObject to no avail.
Here's the update function of the Main script. It fails at selectedObject.playerSelected(false); because I'm passing it a GameObject when it should be getting a Player object or a Soldier object. How do I determine what kind of object is being passed. Am I going about this the wrong way entirely?
function Update () {
if (Input.GetMouseButtonDown (0)) {
objectName = common.getObjectNameFromTap();
selectedObject = GameObject.Find(selectedObjectName);
if (object != null)
{
object = GameObject.Find(objectName);
// deselect currently selected object
if (selectedObject)
selectedObject.playerSelected(false);
Answer by whebert · Mar 16, 2013 at 03:39 PM
The reason it fails at selectedObject.playerSelected(false) is because GameObjects know nothing about the method playerSelected(). What you need to do, is obtain a reference to your Player script from the GameObject, then proceed from there. Here is an example:
selectedObject = GameObject.Find(selectedObjectName);
// Test to make sure you got something back, not null
if(selectedObject)
{
// Now, see if the selectedObject has a Player script attached
var player : Player = selectedObject.GetComponent(Player);
if(player)
{
// The selectedOject IS a Player, do Player stuff with it.
// This will work for either a Player, or Soldier, since Soldier inherits from Player
player.playerSelected(false);
// If you want to see if the player is also a Soldier to do Soldier specific stuff
var soldier : Soldier = player as Soldier;
if(soldier)
{
// player IS also a Soldier
}
else
{
// player is NOT a Soldier
}
}
else
{
// The selectedObject is NOT a Player
}
}
Answer by nsxdavid · Mar 16, 2013 at 03:41 PM
Unity is a component-based architecture. Once you get this basic concept in your head, the rest is easy:
The GameObject is just a container of components. Some components are built-in, like Transform, and the rest come from scripts (when inherited from MonoBehavior). So in your case, the Player script defines a Player component.
When you add the Player component to the GameObject, the GameObject does not suddenly "become" a Player. It's still just a container of components where one of them happens to be Player.
Therefore, when you want to access a function on something, you have to get it's container (the GameObject like you did above) and look inside for the component that has the function (or method in C#) you want to call.
So in JavaScript:
var player:Player = selectedObject.GetComponent(Player);
player.playerSelected(false);
In C#
Player player = selectedObject.GetComponent<Player>();
player.playerSelected(false);
You can find discussion of access components here.
And remember, any GameObject an have many different components. It is best to structure your game code into individual components that have a very defined function (i.e. try not to dump everything into one class) and have them work with each other. But also keep in mind that a component might not be there! So check for null if there is any doubt.
Thanks for the assist! I'm still getting my head around the modularity of unity.