C# 如果我在父类中使其可见,如何查看children类的字段?

C# 如果我在父类中使其可见,如何查看children类的字段?,c#,unity3d,C#,Unity3d,我有一个障碍类型的枚举,我使用它将障碍父类的公共实例更改为特定的子类 [ExecuteInEditMode] public class ObstacleDefiner : MonoBehaviour{ public enum ObstacleType { Box, BoxRot }; public ObstacleType type; private ObstacleType actualType; public Obstacle obstacleDefine; void Upda

我有一个障碍类型的枚举,我使用它将障碍父类的公共实例更改为特定的子类

[ExecuteInEditMode]
public class ObstacleDefiner : MonoBehaviour{
 public enum ObstacleType { Box, BoxRot };
 public ObstacleType type;
 private ObstacleType actualType;

 public Obstacle obstacleDefine;

 void Update()
 {
     if(actualType != type)
     {
         AdaptObstacleToType();
     }
 }

 private void AdaptObstacleToType()
 {
    obstacleDefine = GetObstacle();
    actualType = type;
 }

 Obstacle GetObstacle()
 {
    Obstacle obstacle;

    switch (type)
    {
        case ObstacleType.Box:
            obstacle = new Box(this.gameObject);
            return obstacle;

        case ObstacleType.BoxRot:
            obstacle = new BoxRot(this.gameObject);
            return obstacle;

        default:
            return obstacle = new Obstacle(this.gameObject);
     }
 }
}
[System.Serializable]
public class Obstacle
{
  //Campos comunes a todos los obstáculos
  [HideInInspector]
  public GameObject obstacle;
  public float fallSpeed;

  //Funcionalidades especificas para cada tipo de obstáculo
  public bool hasRot;
  public bool hasSkill;

  public Obstacle(GameObject obstacle)
  {
      this.obstacle = obstacle;
  }
}
这是我定义障碍物类型的主类的代码

我想在inspector中看到的不仅仅是父类的字段,还有特定子类的字段

[ExecuteInEditMode]
public class ObstacleDefiner : MonoBehaviour{
 public enum ObstacleType { Box, BoxRot };
 public ObstacleType type;
 private ObstacleType actualType;

 public Obstacle obstacleDefine;

 void Update()
 {
     if(actualType != type)
     {
         AdaptObstacleToType();
     }
 }

 private void AdaptObstacleToType()
 {
    obstacleDefine = GetObstacle();
    actualType = type;
 }

 Obstacle GetObstacle()
 {
    Obstacle obstacle;

    switch (type)
    {
        case ObstacleType.Box:
            obstacle = new Box(this.gameObject);
            return obstacle;

        case ObstacleType.BoxRot:
            obstacle = new BoxRot(this.gameObject);
            return obstacle;

        default:
            return obstacle = new Obstacle(this.gameObject);
     }
 }
}
[System.Serializable]
public class Obstacle
{
  //Campos comunes a todos los obstáculos
  [HideInInspector]
  public GameObject obstacle;
  public float fallSpeed;

  //Funcionalidades especificas para cada tipo de obstáculo
  public bool hasRot;
  public bool hasSkill;

  public Obstacle(GameObject obstacle)
  {
      this.obstacle = obstacle;
  }
}
这是障碍父亲类的代码,它是show,因为我声明了一个障碍变量类型,但在适配器中,我创建了一个特定子类的新障碍类型

[System.Serializable]
public class Box : Obstacle
{

   public Box(GameObject obstacle) : base(obstacle)
   {
       //El tipo más básico de obstáculo
       hasRot = false;
       hasSkill = false;
   }
}

[System.Serializable]
public class BoxRot : Obstacle
{
  public float rotSpeed;

  public BoxRot(GameObject obstacle) : base(obstacle)
  {
      //El tipo más básico de obstáculo
      hasRot = true;
      hasSkill = false;
      rotSpeed = fallSpeed;
  }
}
最后,这两类是我遇到的两类障碍

那么如何在检查器中显示这些特定类型障碍物的字段?

问题是,我仅使用父类的字段获得此可视化。
我认为你做不到,不管怎么说,都不是很简单。您可以在ObstacleDefiner中声明,它是您在inspector中看到的脚本/组件:

public Obstacle obstacleDefine;
所以检查员会显示障碍物是什么。在编译代码之后,没有什么可以改变这一点

无论如何,我认为使用子类来处理这些事情是个坏主意。你可以做统一本身所做的事情,拥抱组合而不是继承,聚合你需要的部分

因此,您可以创建Box和(如果有很多,可能作为shape的子类)以及Rotation作为它们自己的类,并根据需要将它们作为附加脚本组件添加到对象中


就像Unity本身有单独的变换、网格渲染器、网格过滤器、刚体等组件一样。

好吧,我终于找到了一个很好的解决方案,唯一复杂的是你必须学习如何使用编辑器和查看文档

使用序列化属性,我们可以显式分配任何类型的数据。 在这种情况下,我想要的是分配我的障碍类型的类,以便在屏幕上显示它们以及它们的所有公共变量,以使我的工作更轻松

基本上,过程如下所示,首先我们定义一个序列化对象,将包含我们希望在编辑器中使用的信息的类分配给该对象(在我的例子中是前面提到的类)。 然后使用该对象,我们可以搜索任何类型的数据,并将其显式分配给序列化属性

然后是在屏幕上显示它的问题,在我的例子中,我根据枚举更改属性的实例,以便根据障碍物的类型显示更新的屏幕

在这里,我将生成的脚本与在编辑器中使用该脚本的过程一起保留。

public class ObstacleMaker : MonoBehaviour
{
   public enum ObstacleType { Box, BoxElastic, BoxNinja, BoxTornado, BoxElectro };
   public ObstacleType type;

   public Obstacle obstacle = new Obstacle();

   public Box box = new Box();

   public BoxElastic boxElastic = new BoxElastic();
}
using UnityEditor;

[CustomEditor(typeof(ObstacleMaker)), CanEditMultipleObjects]
public class ObstacleDefiner : Editor
{
   ObstacleMaker obstacleScript;
   SerializedObject GetTarget;

   #region TYPE OF OBSTACLES
   SerializedProperty Box;
   SerializedProperty BoxElastic;
   SerializedProperty ObstacleInstance;
   #endregion

   private void OnEnable()
   {
       obstacleScript = (ObstacleMaker)target;

       GetTarget = new SerializedObject(obstacleScript);

       #region TIPOS DE OBSTACULOS
       Box = GetTarget.FindProperty("box");
       BoxElastic = GetTarget.FindProperty("boxElastic");
       ObstacleInstance = GetTarget.FindProperty("obstacle");
       #endregion
   }

   public override void OnInspectorGUI()
   {
       //Update our list
       GetTarget.Update();

       using (new EditorGUILayout.VerticalScope("HelpBox"))
       {
           obstacleScript.type = 
           (ObstacleMaker.ObstacleType)EditorGUILayout.EnumPopup("Obstacle Type", 
           obstacleScript.type);

           if(GUILayout.Button("Set Obstacle"))
           {
               obstacleScript.SetObstacle();
           }

           EditorGUILayout.Space();

           switch (obstacleScript.type)
           {
               case ObstacleMaker.ObstacleType.Box:
                   EditorGUILayout.PropertyField(Box);
                   break;
               case ObstacleMaker.ObstacleType.BoxElastic:
                   EditorGUILayout.PropertyField(BoxElastic);
                   break;
               default:
                   EditorGUILayout.PropertyField(ObstacleInstance);
                   break;
           }
      }
  }
该类包含实例化的障碍类型,可在编辑器中使用。

public class ObstacleMaker : MonoBehaviour
{
   public enum ObstacleType { Box, BoxElastic, BoxNinja, BoxTornado, BoxElectro };
   public ObstacleType type;

   public Obstacle obstacle = new Obstacle();

   public Box box = new Box();

   public BoxElastic boxElastic = new BoxElastic();
}
using UnityEditor;

[CustomEditor(typeof(ObstacleMaker)), CanEditMultipleObjects]
public class ObstacleDefiner : Editor
{
   ObstacleMaker obstacleScript;
   SerializedObject GetTarget;

   #region TYPE OF OBSTACLES
   SerializedProperty Box;
   SerializedProperty BoxElastic;
   SerializedProperty ObstacleInstance;
   #endregion

   private void OnEnable()
   {
       obstacleScript = (ObstacleMaker)target;

       GetTarget = new SerializedObject(obstacleScript);

       #region TIPOS DE OBSTACULOS
       Box = GetTarget.FindProperty("box");
       BoxElastic = GetTarget.FindProperty("boxElastic");
       ObstacleInstance = GetTarget.FindProperty("obstacle");
       #endregion
   }

   public override void OnInspectorGUI()
   {
       //Update our list
       GetTarget.Update();

       using (new EditorGUILayout.VerticalScope("HelpBox"))
       {
           obstacleScript.type = 
           (ObstacleMaker.ObstacleType)EditorGUILayout.EnumPopup("Obstacle Type", 
           obstacleScript.type);

           if(GUILayout.Button("Set Obstacle"))
           {
               obstacleScript.SetObstacle();
           }

           EditorGUILayout.Space();

           switch (obstacleScript.type)
           {
               case ObstacleMaker.ObstacleType.Box:
                   EditorGUILayout.PropertyField(Box);
                   break;
               case ObstacleMaker.ObstacleType.BoxElastic:
                   EditorGUILayout.PropertyField(BoxElastic);
                   break;
               default:
                   EditorGUILayout.PropertyField(ObstacleInstance);
                   break;
           }
      }
  }

这是使用编辑器显示我想要的类的类。

尝试将此属性添加到父对象:public float ChildFallSpeed{get{return this.barrier.fallSpeed;}set{this.障碍物.fallSpeed=value;}}请确保使用正确的标记。您的代码位于
c#
中,
unityscript
是一种JavaScript风格的自定义语言,类似于Unity以前使用的自定义语言,现在已被长期弃用。我曾想过使用组合而不是继承,但在这种情况下继承似乎更好,主要是因为它没有任何功能它们共享,但不同类型的障碍之间必须有所不同,因此对于重载和通用函数,这正是我所要寻找的。很好-是的,可以编写编辑器脚本来在Unity editor中显示自定义内容,很抱歉没有提到这一点。只是字面上的意思是,没有找到一种方法来实现由于C#的工作方式,默认的内置检查器可以为您这样做。没关系,重要的是它已经解决了。您完全正确的观点并帮助我找到了更好的解决方案,就是我不能让障碍类成为继承它的类。
public class ObstacleMaker : MonoBehaviour
{
   public enum ObstacleType { Box, BoxElastic, BoxNinja, BoxTornado, BoxElectro };
   public ObstacleType type;

   public Obstacle obstacle = new Obstacle();

   public Box box = new Box();

   public BoxElastic boxElastic = new BoxElastic();
}
using UnityEditor;

[CustomEditor(typeof(ObstacleMaker)), CanEditMultipleObjects]
public class ObstacleDefiner : Editor
{
   ObstacleMaker obstacleScript;
   SerializedObject GetTarget;

   #region TYPE OF OBSTACLES
   SerializedProperty Box;
   SerializedProperty BoxElastic;
   SerializedProperty ObstacleInstance;
   #endregion

   private void OnEnable()
   {
       obstacleScript = (ObstacleMaker)target;

       GetTarget = new SerializedObject(obstacleScript);

       #region TIPOS DE OBSTACULOS
       Box = GetTarget.FindProperty("box");
       BoxElastic = GetTarget.FindProperty("boxElastic");
       ObstacleInstance = GetTarget.FindProperty("obstacle");
       #endregion
   }

   public override void OnInspectorGUI()
   {
       //Update our list
       GetTarget.Update();

       using (new EditorGUILayout.VerticalScope("HelpBox"))
       {
           obstacleScript.type = 
           (ObstacleMaker.ObstacleType)EditorGUILayout.EnumPopup("Obstacle Type", 
           obstacleScript.type);

           if(GUILayout.Button("Set Obstacle"))
           {
               obstacleScript.SetObstacle();
           }

           EditorGUILayout.Space();

           switch (obstacleScript.type)
           {
               case ObstacleMaker.ObstacleType.Box:
                   EditorGUILayout.PropertyField(Box);
                   break;
               case ObstacleMaker.ObstacleType.BoxElastic:
                   EditorGUILayout.PropertyField(BoxElastic);
                   break;
               default:
                   EditorGUILayout.PropertyField(ObstacleInstance);
                   break;
           }
      }
  }