2016-04-03 10 views
0

私は武器といくつかの派生クラスと呼ばれる基本クラスを持っています。 Weapon_Rifle、Weapon_Pistolなどユニティゲームエンジン:動的に追加されたスクリプトへの参照を取得する

別のクラスでは、武器の派生クラスが問題のGameObjectに存在するかどうかを参照する必要があります。 pseduocodeで私がやろうとしていることはこれです:

public class OtherClass : MonoBehaviour 
{ 

    public string weaponType; 
    public SCRIPT_I_WANT_TO_REFERENCE; 

    void Awake(){ 
      if(weaponType =="Rifle"){ 
       SCRIPT_I_WANT_TO_REFERENCE = GetComponent<Weapon_Rifle>(); 
      } else { 
       SCRIPT_I_WANT_TO_REFERENCE = GetComponent<Weapon_Pistol>(); // etc etc 
      } 
    } 

    void DoStuff(){ 
      SCRIPT_I_WANT_TO_REFERENCE.ShootWeapon(); 
    } 
} 

トラブルが私のようなそのスクリプトのメソッドにアクセスしようとする場所をコンパイラが文句として、私はSCRIPT_I_WANT_TO_REFERENCEのオブジェクトのようなダミータイプを使用することはできませんもちろんですShootWeapon()。

これはどのようにして行うことができますか?

多くのありがとうございます。

答えて

2

インターフェイスを使用できます。あなたがShootWeaponを持っているIWeaponのようなものが定義されています。

interface IWeapon 
{ 
    void ShootWeapon(); 
} 

次に、インターフェイスをクラス定義のヘッダーに実装するだけです。

public class Weapon_Rifle : MonoBehaviour, IWeapon 
{ 
    void ShootWeapon() 
    { 
     ... 
    } 
} 

このようにして、インターフェイスでライフルを "is a"関係で参照することができます。両方のクラスからアクセスする必要のある他のメソッドも定義できますし、クラス内で実装する必要があります。使用できるタイプは、両方のクラスを指すIWeaponです。

+0

ありがとうございます。 IWeaponはMonobehaviourから派生することができないので、Monobhaviourメソッドを使用する必要があるので、私はどのように武器を基本クラスとして使用するのですか?私は公共クラスWeapon:MonoBehaviour、IWeaponのようなものを持っていて、それから派生クラス、public class Weapon_Rifle:Weapon? – Absinthe

+0

実際には、Unityでは、クラスは2つの他のクラスから派生することはできませんが、MonoBehaviourから派生するとともに、好きなだけ多くのインターフェースを実装することができます。両方の武器クラスは依然としてMonoBehaviourから継承して、コンポーネントであるためWeapon_X:MonoBehaviour、IWeaponになります。必要に応じて、Unityのサイト[ここ](https://unity3d.com/learn/tutorials/modules/intermediate/scripting/interfaces)のインターフェースに関する良いイントロをチェックすることができます。 – cjmarsh

+0

ありがとう、私は武器の種類のための状態マシンのようなものを設定します – Absinthe

0

あなたがやりたいためにリフレクションを使用することができます。

var method = typeof(GameObject).GetMethod("GetComponent", new Type[] {}); 
var specific = method.MakeGenericMethod(typeof(Rifle)); 
var instance = specific.Invoke(shooter, null) as IWeapon; 

など。

using UnityEngine; 
using System; 
using System.Reflection; 
using NUnit.Framework; 

public interface IWeapon 
{ 
    void ShootAt(GameObject target); 
} 

public class Rifle : MonoBehaviour, IWeapon 
{ 
    public void ShootAt(GameObject target) 
    { 
     Debug.Log("Rifle"); 
    } 
} 

public class Shotgun : MonoBehaviour, IWeapon 
{ 
    public void ShootAt(GameObject target) 
    { 
     Debug.Log("Shotgun"); 
    } 
} 

public class WeaponTests 
{ 
    private GameObject Shooter() 
    { 
     var foo = new GameObject(); 
     foo.AddComponent<Shotgun>(); 
     foo.AddComponent<Rifle>(); 
     return foo; 
    } 

    private MethodInfo method = null; 
    private IWeapon GetWeaponByName(GameObject shooter, string name) 
    { 
     if (method == null) 
     { 
      // This is slow, cache the result 
      method = typeof(GameObject).GetMethod("GetComponent", new Type[] {}); 
     } 
     if (name == "Rifle") 
     { 
      MethodInfo specific = method.MakeGenericMethod(typeof(Rifle)); 
      return specific.Invoke(shooter, null) as IWeapon; 
     } 
     else if (name == "Shotgun") 
     { 
      MethodInfo specific = method.MakeGenericMethod(typeof(Shotgun)); 
      return specific.Invoke(shooter, null) as IWeapon; 
     } 
     return null; 
    } 

    [Test] 
    public void TestGetWeaponByName() 
    { 
     var target = new GameObject(); 
     var fixture = Shooter(); 
     IWeapon weapon; 

     weapon = GetWeaponByName(fixture, "Rifle"); 
     Assert.True(weapon != null); 
     weapon.ShootAt(target); 

     weapon = GetWeaponByName(fixture, "Shotgun"); 
     Assert.True(weapon != null); 
     weapon.ShootAt(target); 

     weapon = GetWeaponByName(fixture, "Laster"); 
     Assert.True(weapon == null); 
    } 
} 

特に、IWeaponの必要はありません。特定のインスタンスを簡単に直接読み込むことができます:

MethodInfo specific = method.MakeGenericMethod(typeof(Rifle)); 
var rifle = specific.Invoke(shooter, null) as Rifle; 
rifle.RifleSpecificThing(); 
関連する問題