c# - Unity 2D - 访问 GetComponent 的变量作为参数发送
问题描述
我有这个脚本来保存我的角色。我有很多 NPC,每个 NPC 都有自己的脚本。我想使用方法SaveCharacter
来保存每个 NPC。如何g.GetComponent<Warrior_Movement>()
作为参数发送并访问其变量?当我使用 时<T>
,我无法获取游戏对象脚本的变量。谢谢
void SaveCharacter(Character character, string gameObjectName)
{
GameObject g = GameObject.Find(gameObjectName);
character.position = new float[] { g.transform.position.x, g.transform.position.y, g.transform.position.z };
character.selectedScheme = g.GetComponent<Warrior_Movement>().selectedScheme;
character.currentWaypointIndex = g.GetComponent<Warrior_Movement>().currentWaypointIndex;
character.nextWaypointIndex = g.GetComponent<Warrior_Movement>().nextWaypointIndex;
character.loopSide = g.GetComponent<Warrior_Movement>().loopSide;
}
解决方案
问题
您不能使用变量将其传递给GetComponemt
like的通用版本
public void DoSomething(Type componemtType)
{
var component = GetComponent<componentType>();
}
因为用于实现泛型的类型必须是编译时常量,因此不能是变量(或只有一个是编译时常量)!
GetComponent
您可以使用like的非通用版本
public void DoSomething(Type componentType)
{
var component = GetComponent(componentType);
}
但您必须解析它才能访问特定于该组件的任何字段或方法:
var parsedComponent = component as componentType;
所以你不能这样做,因为用于的类型as
也必须是编译时常量,因此不能是变量。
解决方案1:共享基类
如果你所有不同的类都有你想要保存的公共字段,它们都应该从一个公共的基本类型继承,比如
// By making a class abstract it can not be instanced itself but only be implemented by subclasses
public abstract class BaseMovement : MonoBehaviour
{
// fields that will be inherited by subclasses
public int currentWaypointIndex;
public int nextWaypointIndex;
//...
// You could also have some generic methods that are implemented
// only in the subclasses like e.g. Getters for the values
// you want to access
public abstract string SaySomething();
}
而不是继承你的类,比如
public class Warrior_Movement : BaseMovement
{
// Inherits all fields of BaseMovement
//... additional type specific stuff
// If you have abstract methods in the base class
// every subclass has to implement all of them
public override string SaySomething()
{
return "Harr harr, I'm a warrior!";
}
}
public class Other_Movement : BaseMovement
{
// Inherits all fields of BaseMovement
// Additional type specific stuff
// If you have abstract methods in the base class
// every subclass has to implement all of them
public override string SaySomething ()
{
return "Harr harr, I'm ... something else :'D ";
}
}
比你可以使用类似的东西
void SaveCharacter(Character character, BaseMovent bMovement)
{
character.position = new float[] { bMovement.transform.position.x, bMovement.transform.position.y, bMovement.transform.position.z };
character.currentWaypointIndex = bMovement.currentWaypointIndex;
character.nextWaypointIndex = bMovement.nextWaypointIndex;
}
并称它为
GameObject g = GameObject.Find(gameObjectName);
var movement = g.GetComponemt<BaseMovement>();
SaveCharacter(someCharacter, movement);
解决方案 2:重载
或者,如果您对不同的组件使用不同的值,而不是使用共享基类,而是创建SaveCharacter
类似的重载
public void SaveCharacter(Character character, Warrior_Movement wMovement)
{
// Do stuff with wMovement
// ...
}
public void SaveCharacter (Character character, Other_Movement oMovement)
{
// Do stuff with oMovement
// ...
}
因此,无论何时使用SaveCharacter
传入的类型都会决定SaveCharacter
应该使用哪个实现。
至
当我使用 时,我无法获取游戏对象脚本的变量。
我不知道你到底是什么意思,但你可以使用例如访问GameObject
组件所附加的gameObject
bMovement.gameObject.SetActive(true);
注意:
如果可能的话,你应该避免使用Find
,因为它的性能非常强。尝试尽快获取引用,例如通过使用public GameObject
字段在检查器中引用它,或者如果它已实例化,则将其保存到变量中
var warrior = Instantiate (/*...*/);
并传递它。
推荐阅读
- node.js - 如何通过 $set 运算符更新嵌套数组对象中的多个字段
- ruby-on-rails - 我的 master.key 在哪里,我该如何重新生成它?
- python - 使用 pandas 模块在 Django 视图中读取 excel 文件
- javascript - 谷歌云功能有时有效,有时无效
- c# - 在 ListView 之间添加一个 gab
- javascript - 为 javascript 编写一个正则表达式以重复捕获组
- android - SwipeRefreshLayout 进度可绘制不会在 KitKat 上完全隐藏
- java - 编排多个 google API 客户端的最佳方式是什么?
- flutter - 使用 get API 获取 null 响应
- c - 我无法正确输入用户表单