[英]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.