[英]Unity set Gameobject based on parameter 'Type'
我想创建一个策略游戏。 当我单击操作栏中的“ BuildHouse”按钮时,我希望我的经理注册应建造的建筑物。
我所有的建筑物都是组件,因此我尝试将建筑物类型作为参数传递。
我的按钮执行
public void BuildFarm()
{
buildManager.SetBuilding(typeof(Farm)); // Farm is a child of Building
}
现在, BuildManager
知道了建筑物的类型。 我尝试遍历所有建筑物预制件,然后选择与类型匹配的预制件。
public class BuildManager : MonoBehaviour
{
[SerializeField]
private GameObject[] buildings;
public void SetBuilding(Type buildingType)
{
GameObject targetBuilding = buildings.Where(currentBuilding => buildingType == currentBuilding.GetComponent<Building>().GetType()).First();
}
}
我不知道是否有更好的方法来使BuildManager
知道要构建什么。 如果这个想法根本不好,请提供一种更好的实施方式。
在我看来,按组件类型过滤绝对好。 如果您具有“ Farm
和“ House
组件,并且它们都是建筑物,那么很自然地用继承层次结构来表达它。
关于使用enum
:枚举最适合表示简单状态或良好指定的,不太可能更改的值,例如一周中的几天 。 一周的第8天没有,对吧? 另一方面,您可能想自由扩展可用建筑物的列表,并且每个建筑物可能实现不同的游戏逻辑。 一种更自然的表达方式是创建类层次结构。 而且当这些类就位时,为相同的事情添加一个enum
是多余的。
就是说,我建议您对代码进行一些改进。
public void SetBuilding<TBuilding>() where TBuilding : IBuilding
{
GameObject targetBuilding = buildings
.Where(currentBuilding =>
typeof(TBuilding) == currentBuilding.GetComponent<Building>().GetType())
.SingleOrDefault();
if(targetBuilding == null)
{
// throw or log an error here
}
else
{
// instantiate
}
}
如果在编译时始终知道buildingType
则可以使用泛型。 它使对该方法的调用更具可读性: buildManager.SetBuilding<Farm>();
注意where TBuilding : IBuilding
约束。 使您的Farm
和House
类实现一个通用的接口IBuilding
(它也可以是一个通用的基类): class Farm : Component, IBuilding
。 通过此编译器,确保您无法调用诸如buildManager.SetBuilding<int>();
类的东西buildManager.SetBuilding<int>();
SingleOrDefault
确保只有一个这样的GO。 如果不超过1,则返回null。 如果是这种情况,请抛出或记录错误。 我知道您要确保buildings
数组正确,但是您应该使用代码强制执行。
我建议定义一个enum
:
enum BuildingType
{
Farm,
House,
...
}
然后,您可以为Building
定义Type
属性:
public class Building
{
...
BuildingType Type { get; set; }
...
}
然后,您可以像这样调用SetBuilding
(也许使用switch
):
public void SetBuilding(BuildingType buildingType)
{
// act according to buildingType
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.