首页 > 解决方案 > 可以表示多个不同类的数据类型,这些类具有一些共同的属性,无需继承

问题描述

我正在统一使用 c#。我有一个名为 CarPart 的类,它派生自 MonoBehaviour(MB 是每个统一脚本的基类)。在这个类中,我声明了不能从任何基类派生的特定汽车零件类,因为统一检查器不会显示它们的属性,但它们需要单声道行为,所以我在从 MonoBehaviour 派生的类 (CarPart) 中声明了它们。

public class CarPart : MonoBehaviour {

    [System.Serializable] //required to show full objects in inspector
    public class Chassis {
        //common properties for all car parts
        public GameObject prefab;
        public int price;
        //specific properties for every car part
        public bool AWD;
        public int suspensionDepth;
        //specific implementation of equip for chassis
        public void equip() {
            //instantiate chassis as root object 
        }
    }
    [System.Serializable] //required to show full objects in inspector
    public class Engine {
        //common properties for all car parts
        public GameObject prefab;
        public int price;
        //specific properties for every car part
        public bool supportsAddOnExhaust;
        public int power;
        //specific implementation of Equip for engine
        public void Equip() {
            //instantiate engine as child object of chassis in hierarchy 
        }
    }
    //this code is heavily simplified
}

然后我有类 VehicleConfig,它是经理游戏对象的组件(这个 GO 在整个游戏中都处于活动状态)。VehicleConfig 与 GUI 通信并基于 GUI 输入配置车辆。它还声明了所有汽车组件,这些组件稍后将分配有来自检查器(功率、悬架深度)和 3D 模型(预制件)的特定值。

public class VehicleConfig : CarPart{
    public Chassis[] chassis; //assigned from inspector
    public Engine[] engines;  //assigned from inspector    
    //and more car components like these two...
    //arrays because there will be multiple to chose from each type        

    public void Setup (unknownDataType component) {
        component.Equip;
        DoSomethingWithCommonVariables(component.price, component.prefab);
    }
    //method called from GUI example:
    public void MountFirstEngine() {
        Setup(engines[0]);
    }
} 

我的问题是,我有更多特定的汽车组件,而不仅仅是引擎和底盘,而且它们都有更多的通用方法和特定的实现,然后只是 Equip()。Setup() 也比上面的例子复杂一点。所以我希望 Setup() 用一些数据类型重载,这些数据类型可以表示所有汽车部件(引擎、底盘......)的所有常用方法和属性,所以我可以重载 Setup(),例如将 Engines[0] 转换为那个特殊的数据类型。我知道有不同的方法可以用抽象类来实现这个功能,所有常见的抽象方法都是从中派生的引擎或机箱等类,并且会为这些方法提供某些实现,但正如我之前提到的,统一检查器无法显示派生类的成员变量。如果有人有建议、想法或完全不同的方法。我真的很感激提前提到它:) thx。

标签: c#classobjectunity3doverloading

解决方案


我不太确定抽象类有什么问题,但是您可以使用抽象类来实现您想要的并在检查器中提供可用的属性:

public abstract class CarElement
{
  //common properties for all car parts
  public GameObject prefab;
  public int price;
  public abstract void Equip();
}

[System.Serializable] //required to show full objects in inspector
public class Chassis : CarElement
{
    //specific properties for every car part
    public bool AWD;
    public int suspensionDepth;
    public override void Equip() { }
}

[System.Serializable] //required to show full objects in inspector
public class Engine : CarElement
{
    //specific properties for every car part
    public bool supportsAddOnExhaust;
    public int power;
    public override void Equip(){ }
}

public class VehicleConfig : CarPart
{
    public Chassis[] chassis; //assigned from inspector
    public Engine[] engines;  //assigned from inspector    
    //and more car components like these two...
    //arrays because there will be multiple to chose from each type        

    public void Setup(CarElement component)
    {
          component.Equip();
          DoSomethingWithCommonVariables(component.price, component.prefab);
    }
    //method called from GUI example:
    public void MountFirstEngine()
    {
        Setup(engines[0]);
    }
}

在此处输入图像描述


推荐阅读