繁体   English   中英

Unity 构建错误:找不到类型或命名空间名称“Editor”

[英]Unity build error: The type or namespace name 'Editor' could not be found

我有一个脚本Item.cs负责设置玩家库存中项目的参数。 在其中,我连接 Unity 编辑器库并创建一个继承自编辑器 class 的 class。 直到最近,我还在使用 Unity 版本2020.3.0f1 ,一切正常,但现在我安装了2021.3.9f1 ,但我开始遇到问题。

构建项目时,出现以下错误:

Assets\Inventory\Items.cs(31,31):错误 CS0246:找不到类型或命名空间名称“Editor”(您是否缺少 using 指令或程序集引用?)

Assets\Inventory\Items.cs(30,5):错误 CS0246:找不到类型或命名空间名称“CustomEditorAttribute”(您是否缺少 using 指令或程序集引用?)

Assets\Inventory\Items.cs(30,5):错误 CS0246:找不到类型或命名空间名称“CustomEditor”(您是否缺少 using 指令或程序集引用?)

Assets\Inventory\Items.cs(32,28): 错误 CS0115: 'Items.ItemsEditor.OnInspectorGUI()': 找不到合适的方法来覆盖

代码:

using UnityEngine;
using UnityEditor;

public class Items : MonoBehaviour {
   public enum itemTypes { Weapon, Potion, Amulet }
   public enum potionType { Health, Poison, Strong, Beer }
   public enum amuletType { Health, Defense, Speed }

   [Header("Main Settings")]
   public itemTypes ItemTypes;
   [HideInInspector] public GameObject Model;
   [HideInInspector] public Texture2D Icon;
   [HideInInspector] public string itemName;
   [HideInInspector] public int itemNum;

   // Weapon
   [HideInInspector] public float damage;
   [HideInInspector] public float atackSpeed;
   [HideInInspector] public int broken;

   // Potion
   [HideInInspector] public potionType Potion = potionType.Health;
   [HideInInspector] public float healthOfset;
   [HideInInspector] public bool processingEffect;

   // Amulet
   [HideInInspector] public amuletType Amulet = amuletType.Health; 
   [HideInInspector] public float amuletValue;
    
   [CustomEditor(typeof(Items))]
   public class ItemsEditor : Editor {
      public override void OnInspectorGUI() {
         base.OnInspectorGUI();
         Items items = (Items) target;
         DrawMain(items);
         EditorGUILayout.Space();
      
         switch (items.ItemTypes) {
            case itemTypes.Weapon:
               WeaponSettings();
               break;
            case itemTypes.Potion:
               PotionSettings();
               break;
            case itemTypes.Amulet:
               AmuletSettings();
               break;
         }
         serializedObject.ApplyModifiedProperties();
      }

      void DrawMain(Items items) {
         EditorGUILayout.PropertyField(serializedObject.FindProperty("Icon"));
         EditorGUILayout.PropertyField(serializedObject.FindProperty("Model"));
         EditorGUILayout.PropertyField(serializedObject.FindProperty("itemNum"));
         EditorGUILayout.PropertyField(serializedObject.FindProperty("itemName"));
         EditorGUILayout.Space();
      }

      void WeaponSettings() {
         EditorGUILayout.PropertyField(serializedObject.FindProperty("damage"));
         EditorGUILayout.PropertyField(serializedObject.FindProperty("atackSpeed"));
      }

      void PotionSettings() {
         EditorGUILayout.PropertyField(serializedObject.FindProperty("Potion"));
         EditorGUILayout.PropertyField(serializedObject.FindProperty("healthOfset"));
         EditorGUILayout.PropertyField(serializedObject.FindProperty("processingEffect"));
      }

      void AmuletSettings() {
         EditorGUILayout.PropertyField(serializedObject.FindProperty("Amulet"));
         EditorGUILayout.PropertyField(serializedObject.FindProperty("amuletValue"));
      }
   }
}

您需要继承Editor

在 class 行中,您应该将其替换为MonoBehaviour

public class Items : Editor {

请注意,现在这个脚本不是MonoBehaviour ,所以它不会让你做某些事情。 例如,可能不会调用 Update 和 Start。

(在您的情况下,您可能不需要这个)如果您当前的 class 需要成为 MonoBehaviour,我会推荐一个新的 class 继承编辑器并保持这个相同。 您可以在新的 class 中执行所有 gui。


TL;DR 继承Editor

public class Items : Editor {

顾名思义, UnityEditor命名空间仅在 Unity 编辑器本身中可用,在编译构建时完全剥离/根本不包括在内。

通常有三种方法可以防止在构建期间编译编辑器代码

  • 将您的文件放在一个名为Editor的文件夹中 - 在构建过程中会忽略整个内容(另请参阅特殊文件夹名称
  • 将您的代码放入具有仅针对编辑器而不是其他目标平台编译的程序集定义的文件夹中
  • 使用条件编译

在您的情况下,最简单的方法是将与UnityEditor命名空间相关的所有内容包装在#if - #endif预处理器中,因为您将编辑器嵌入到类型本身中。

我通常更喜欢相同的顺便说一句,因为嵌入编辑器会产生一些优势,恕我直言:

  • 您可以直接使用nameof而不是硬编码的字符串 -> 容易出错且维护密集
  • 您甚至可以访问私有序列化字段 => 甚至可以再次使用nameof
  • 您立即知道,对于这种类型,存在一个自定义编辑器以及在哪里可以找到它,这在严格分离它们时并不是那么简单

顺便说一句,我不会直接接触target ,而是通过serializedObject完全接触 go 。

using UnityEngine;
#if UNITY_EDITOR // => Ignore from here to next endif if not in editor
using UnityEditor;
#endif

public class Items : MonoBehaviour 
{
   public enum itemTypes { Weapon, Potion, Amulet }
   public enum potionType { Health, Poison, Strong, Beer }
   public enum amuletType { Health, Defense, Speed }

   [Header("Main Settings")]
   public itemTypes ItemTypes;
   public GameObject Model;
   public Texture2D Icon;
   public string itemName;
   public int itemNum;

   // Weapon
   public float damage;
   public float atackSpeed;
   public int broken;

   // Potion
   public potionType Potion = potionType.Health;
   public float healthOfset;
   public bool processingEffect;

   // Amulet
   public amuletType Amulet = amuletType.Health; 
   public float amuletValue;
    
#if UNITY_EDITOR // => Ignore from here to next endif if not in editor
   [CustomEditor(typeof(Items))]
   public class ItemsEditor : Editor 
   {
      private SeriaizdProperty itemTypes;
      private SeriaizdProperty icon;
      private SeriaizdProperty model;
      private SeriaizdProperty itemNum;
      private SeriaizdProperty itemName;
      private SeriaizdProperty damage;
      private SeriaizdProperty atackSpeed;
      private SeriaizdProperty potion;
      private SeriaizdProperty healthOfset;
      private SeriaizdProperty processingEffect;
      private SeriaizdProperty amulet;
      private SeriaizdProperty amuletValue;
      

      private void OnEnable()
      {
          // it is enough to do these ONCE when the inspector is loaded

          // note that one huge advantage of having the Editor embedded into your class is that you can 
          // - and imho SHOULD - directly use "nameof" instead of going by hardcoded strings (-> error prone and maintenance intense)
          itemTypes = serializedObject.FindProperty(nameof(ItemTypes));
          icon = serializedObject.FindProperty(nameof(Icon));
          model = serializedObject.FindProperty(nameof(model));
          itemNum = serializedObject.FindProperty(nameof(itemNum));
          itemName = serializedObject.FindProperty(nameof(itemName));
          damage = serializedObject.FindProperty(nameof(damage));
          atackSpeed = serializedObject.FindProperty(nameof(atackSpeed));
          potion = serializedObject.FindProperty(nameof(Potion));
          healthOfset = serializedObject.FindProperty(nameof(healthOfset));
          processingEffect = serializedObject.FindProperty(nameof(processingEffect));
          amulet = serializedObject.FindProperty(nameof(Amulet));
          amuletValue = serializedObject.FindProperty(nameof(amuletValue));
      }

      public override void OnInspectorGUI() 
      {
         //base.OnInspectorGUI();

         // This is also required so the serialized poperties get updated
         // with the current actual values
         serializedObject.Update();

         DrawMain(items);
         EditorGUILayout.Space();
      
         switch (items.ItemTypes) 
         {
            case itemTypes.Weapon:
               WeaponSettings();
               break;

            case itemTypes.Potion:
               PotionSettings();
               break;

            case itemTypes.Amulet:
               AmuletSettings();
               break;
         }

         serializedObject.ApplyModifiedProperties();
      }

      void DrawMain(Items items) 
      {
         EditorGUILayout.PropertyField(icon);
         EditorGUILayout.PropertyField(model);
         EditorGUILayout.PropertyField(itemNum);
         EditorGUILayout.PropertyField(itemName);
         EditorGUILayout.Space();
      }

      void WeaponSettings() 
      {
         EditorGUILayout.PropertyField(damage);
         EditorGUILayout.PropertyField(atackSpeed);
      }

      void PotionSettings() 
      {
         EditorGUILayout.PropertyField(potion);
         EditorGUILayout.PropertyField(healthOfse);
         EditorGUILayout.PropertyField(processingEffect);
      }

      void AmuletSettings() 
      {
         EditorGUILayout.PropertyField(amulet);
         EditorGUILayout.PropertyField(amuletValue);
      }
   }
#endif
}

然而

现在请允许我问:为什么不使用正确的 inheritance 并在根本不需要任何自定义编辑器的情况下执行以下操作?

public abstract class Items : MonoBehaviour 
{
   [Header("Main Settings")]
   public GameObject Model;
   public Texture2D Icon;
   public string itemName;
   public int itemNum;
}

然后(当然每个都在单独的脚本文件中)

public class Weapon : Items
{
   [Header("Weapon Settings")]
   public float damage;
   public float atackSpeed;
   public int broken;
}

public class Potion : Items
{
    public enum PotionType { Health, Poison, Strong, Beer }

    [Header("Potion Settings")]
    public PotionType potionType;
    public float healthOfset;
    public bool processingEffect;
}

public class Amulet : Items
{
    public enum AmuletType { Health, Defense, Speed }

    [Header("Amulet Settings")]
    public AmuletType amuletType; 
    public float amuletValue;
}

现在,每当您需要在不同项目之间进行区分时,您只需执行

Items item = <Get from somewhere>;
switch(item)
{
    // This combines a type check and casting to the according type
    // in one go. Basically similar to former using 
    // if(item is Weapon weapon){ ... } else if(item is Potion potion) { ... }
    case Weapon weapon:
        // do something with a weapon e.g.
        Debug.Log($"weapon damage = {weapon.damage}", item);
        break;

    case Potion potion:
        // do something if it is a potion
        Debug.Log($"potion type = {potion.potionType}", item);
        break;

    case Amulet amulet:
        // do something if it is an amulet
        Debug.Log($"amulet type = {amulet.amuletType}", item);
        break;

    default:
        // a type you haven't handled so far -> either ignore or implement properly
        throw new ArgumentOutOfRangeException($"Type {item.GetType.AssemblyQualifiedName} is not handled yet!");
        break;
}

最后,这是否需要成为MonoBehaviour 看起来这可能是一个ScriptableObject或只是一个通用的

[Serializable] 
public class Items 
{ 
    ... 
}

然后,您宁愿为此实现自定义PropertyDrawer

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM