通过枚举类型自定义检查器,如

时间:2017-06-15 02:52:35

标签: c# unity3d enums

Inspector image

这是一个包含多种移动类型的平台类。 在航路点之间启动时,TypeA是AutoMove 当特定布尔值为true时,TypeB会随着重力而下降。 我通过选择自己的Enum类型来控制这些不同的行为。

我现在要做的是只能在检查器上看到那些与移动类型相匹配的变量,因为TypeA使用的是WayB完全忽略的路标系统,而检查员上剩下的所有未使用的变量都会让事情变得混乱乱。

我可以一次让他们成为自己的班级,但如果我坚持并尝试这样做:这可以做到吗?我该怎么办?

另一件要问的问题是,像我这样的课程在性能效率方面是否更好?要有自己的脚本课程?或者只是不要担心表演?如果没有显着的性能差异,我打算像我一样这样做。

编辑:添加了已发布的检查员以及指示。        红色是Enum选择要遵循的运动功能        1.是沿着航路点系统和漫游的运动类型之一        2.是与PC接触的机芯类型之一        3.是仅在有效布尔值为真时移动的移动类型之一

2 个答案:

答案 0 :(得分:1)

您需要实现自己的自定义检查器。这个主题有Unity's official tutorial。自定义检查器使用GUI类,当且仅当条件满足时,您需要检查条件并绘制字段。

以下是我从Change Inspector Variables Depending On Enum获取的示例代码。通过此代码,您将学习如何从目标类中动态获取enum字段的值。

~/Assets/PropertyHolder.cs

using System.Collections;
using UnityEngine;


public class PropertyHolder : MonoBehaviour
{
    public enum Status { A, B, C };

    public Status state;

    public int valForAB;

    public int valForA;
    public int valForC;

    public bool controllable;

    void Start()
    {

    }

    void Update()
    {

    }
}

~/Assets/Editor/PropertyHolderEditor.cs

using UnityEditor;
using UnityEngine;

[CustomEditor(typeof (PropertyHolder)), CanEditMultipleObjects]
public class PropertyHolderEditor : Editor
{

    public SerializedProperty
    state_Prop,
    valForAB_Prop,
    valForA_Prop,
    valForC_Prop,
    controllable_Prop;

    void OnEnable()
    {
        // Setup the SerializedProperties
        state_Prop = serializedObject.FindProperty("state");
        valForAB_Prop = serializedObject.FindProperty("valForAB");
        valForA_Prop = serializedObject.FindProperty("valForA");
        valForC_Prop = serializedObject.FindProperty("valForC");
        controllable_Prop = serializedObject.FindProperty("controllable");
    }

    public override void OnInspectorGUI()
    {
        serializedObject.Update();

        EditorGUILayout.PropertyField(state_Prop);

        PropertyHolder.Status st = (PropertyHolder.Status) state_Prop.enumValueIndex;

        switch (st)
        {
            case PropertyHolder.Status.A:
                EditorGUILayout.PropertyField(controllable_Prop, new GUIContent("controllable"));
                EditorGUILayout.IntSlider(valForA_Prop, 0, 10, new GUIContent("valForA"));
                EditorGUILayout.IntSlider(valForAB_Prop, 0, 100, new GUIContent("valForAB"));
                break;

            case PropertyHolder.Status.B:
                EditorGUILayout.PropertyField(controllable_Prop, new GUIContent("controllable"));
                EditorGUILayout.IntSlider(valForAB_Prop, 0, 100, new GUIContent("valForAB"));
                break;

            case PropertyHolder.Status.C:
                EditorGUILayout.PropertyField(controllable_Prop, new GUIContent("controllable"));
                EditorGUILayout.IntSlider(valForC_Prop, 0, 100, new GUIContent("valForC"));
                break;

        }

        serializedObject.ApplyModifiedProperties();
    }
}

这是如何检查bool&仅在符合条件时从Hide/Show properties dynamically in inspector绘制。修改布尔检查部分以比较使用上述代码找到的enum值。

public class MyScript : MonoBehaviour
{
    public bool flag;
    public int i = 1;
}

[CustomEditor(typeof (MyScript))]
public class MyScriptEditor : Editor
{
    void OnInspectorGUI()
    {
        var myScript = target as MyScript;

        myScript.flag = GUILayout.Toggle(myScript.flag, "Flag");

        if (myScript.flag)
            myScript.i = EditorGUILayout.IntSlider("I field:", myScript.i, 1, 100);

    }
}

将这两者结合起来,你应该得到你想要的行为。

答案 1 :(得分:0)

我认为制作3个独立的控制器脚本会更好地继承MovementType接口(如果你想将它们连在一起)。然后你只需要附上所需的控制器。因此,如果它自动移动,您只需附加自动移动脚本。

界面将确保所有3种类型保持某些操作方式并确保它们保持某些功能。我认为他们以某种方式相关,这就是为什么他们目前在同一个文件中。如果不是只创建没有接口的3个独立脚本。

界面可让您强制某些对象定义移动类型。

您目前设置方式的问题在于您有1个脚本执行4项操作。这违反了一些编程的最佳实践,尤其是Unity中的每个脚本应该可重用且只执行一项主要任务的想法。

已编辑以进行详细说明:

这个想法是划分行为。因此,如果您需要自动移动的内容,则可以创建单独的脚本。然后在将来,如果你想让其他东西自动移动,比如说一个类似云平台(思维马里奥)的不同类型的游戏对象,那么你也可以将你的自动移动脚本拖到那个游戏对象上。同样随着触摸,您可能希望平台下降,但您可能也希望砖有时会这样做。因此,对于您想要触摸的砖块,您也可以为它们重复使用该脚本。

ScriptableObjects可能不适用于此问题。它们适用于游戏中有抽象的东西,如库存。对于游戏中的实际对象,您希望使用带有脚本的标准GameObjects。