[英]Unity game engine: get reference to dynamically added script
我有一個名為Weapon的基類和一些派生類,例如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();
}
}
麻煩當然是我不能將像Object這樣的偽類型用於SCRIPT_I_WANT_TO_REFERENCE,因為編譯器抱怨我試圖在何處訪問該腳本方法(如ShootWeapon())。
有什么辦法可以做到嗎?
非常感謝。
您可以嘗試使用界面。 像IWeapon這樣的東西,在其中定義了ShootWeapon。
interface IWeapon
{
void ShootWeapon();
}
然后,您只需在類定義的標頭中實現接口。
public class Weapon_Rifle : MonoBehaviour, IWeapon
{
void ShootWeapon()
{
...
}
}
這樣,您可以使用“是一個”關系中的界面來引用步槍。 您還可以定義需要從這兩個類訪問的任何其他方法,然后(必須)在這些類中實現。 您可以使用的類型是IWeapon來引用這兩個類。
您可以使用反射來做您想做的事情:
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();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.