x


Accessing inheriting scripts

Situation: I have two scripts, one named WeaponCore and another names AssaultRifle which inherites from WeaponCore. WeaponCore has a function in it, that is called "GetAmmo".

Problem: Now I want to scan a transform if there's a component attached, which inherites from WeaponCore(because maybe the player holds one which has a script named "Pistol" or s. e. attached). For this, I use foreach and GetComponents(WeaponCore)

Question1: So, how can I call functions of a component, of which I don't now the type/name?

Question2: If a use GetComponent(WeaponCore) on a transform, which has "AssaultRifle" attached, does it return nothing or the AR-Script?

I can C# and Unityscript, so feel free to use the language you want^^

more ▼

asked May 23 '11 at 12:52 PM

Andreas Hagen gravatar image

Andreas Hagen
67 11 12 18

(comments are locked)
10|3000 characters needed characters left

3 answers: sort voted first

You can use the keyword is to test an object for its type before you attempt to call its functions. It is used like this:

if (GetComponent<WeaponCore>() is Pistol)
{
    // Call Pistol method
}

I assume WeaponCore is a script that inherits from MonoBehavior, right? If that is so, then AssaultRifle or Pistol also inherit from MonoBehavior, since their base class does. Therefore, if you use GetComponent on a GameObject that has AssaultRifle attached, it should return AssaultRifle, because AssaultRifle is of the same type of WeaponCore due to the inheritance. I.e. when Unity does a search for components of type WeaponCore behind the curtains, it'll test true against a component of type AssaultRifle.

more ▼

answered May 23 '11 at 01:03 PM

CHPedersen gravatar image

CHPedersen
6k 13 22 61

Will this work with pragma strict? Sounds handy :)

May 23 '11 at 01:11 PM demize2010

@demize2010: Sure :D that's the whole point of OOP languages.

May 23 '11 at 05:41 PM Bunny83

It should. I code in C# and don't use dynamic typing so I don't usually have problems with it, but all pragma strict does is force you to apply static typing as you code. That shouldn't have any effect on the is-keyword.

May 23 '11 at 05:44 PM CHPedersen

Note: in the section "// Call Pistol method" stated above, you can also explicitly call methods only in the Pistol class by using "as": (GetComponent<WeaponCore>() as Pistol).ShootYourselfInFoot()

Of course you could just use GetComponent<Pistol>().ShootYourselfInFoot(), but usually you want to do only one call to GetComponent(), since it is kinda expensive:

WeaponCore myWeapon=GetComponent<WeaponCore>();

if(myWeapon is Pistol){

(myWeapon as Pistol).ShootYourselfInFoot();

}

May 23 '11 at 05:55 PM Wolfram

They're not functions, but keywords. :) They, and all other keywords, are documented on Microsoft Developer's Network (MSDN) here: http://msdn.microsoft.com/en-us/library/x53a06bb%28v=vs.71%29.aspx

May 25 '11 at 08:27 PM CHPedersen
(comments are locked)
10|3000 characters needed characters left

To be honest my preference would be to have just a single Weapon script which has state changes eg

var isPistol : boolean;
var isAssualtRifle : boolean;
var pistolAmmoLimit : int = 30;
var assualtRifleLimit : int = 7;
var pistolAmmo : int = pistolAmmoLimit;
var assualtRifleLimitAmmo : int = assualtRifleLimit;
var pistolObject : GameObject;
var assualtRifleObject : GameObject;



function GetAmmo(){

if (isPistol){
//Do something
}

if (isAssualtRifle{
//Do something
}

function Fire(){

if (isPistol){
    //Do something
    }

if (isAssualtRifle{
    //Do something
    }    
}

}

more ▼

answered May 23 '11 at 01:10 PM

demize2010 gravatar image

demize2010
945 19 22 35

This might be fine for small objects, but as the amount of code grows, this practice can quickly get unwieldy and disorganized. Imagine having 20 weapon types. Now you have ~60 lines of just if statements (repeated for every function).

Using inheritance allows you to separate your concerns so you don't have to sift through every weapon type to find the code you want to change, and instead of checking what the weapon type is every time, you can just call the function you need and the object already knows what to do based on the behavior defined either in the base class or overridden in the inherited class.

The result is a much cleaner, more maintainable solution.

Jul 03 '12 at 09:45 PM AerieC_7
(comments are locked)
10|3000 characters needed characters left

You question is a bit confusing. You want to call a function but you don't know which name the function has? That doesn't make much sense to me. The advantage of inheritance is that you implement a function GetAmmo in your base class and make it "virtual". Now any derived class can override the function. If you access a derived class (eg your AssaultRifle) via base-class-reference (WeaponCore) you can call the function GetAmmo() (declared in WeaponCore) but it actually will invoke the overridden function.

public class WeaponCore : MonoBehaviour
{
    public virtual int GetAmmo()
    {
        return 0;
    }
    public virtual void Fire()
    {
        // The base class can't fire
    }
}

public class AssaultRifle : WeaponCore
{
    private int m_Ammo;
    public override int GetAmmo()
    {
        return m_Ammo;
    }
    public override void Fire()
    {
        // Implement here how the AssaultRifle should fire
    }
}

// Somewhere else
WeaponCore[] weapons = GetComponents<WeaponCore>()
foreach(WeaponCore weapon in weapons)
{
    if (weapon.GetAmmo()>0)
        weapon.Fire();
}
more ▼

answered May 23 '11 at 05:59 PM

Bunny83 gravatar image

Bunny83
45.5k 11 49 207

(comments are locked)
10|3000 characters needed characters left
Your answer
toggle preview:

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this question

By Email:

Once you sign in you will be able to subscribe for any updates here

By RSS:

Answers

Answers and Comments

Topics:

x337
x234
x136

asked: May 23 '11 at 12:52 PM

Seen: 1293 times

Last Updated: Jul 03 '12 at 09:45 PM