Unity构建错误:CS0103和缺少上下文'EditorUtility'和'AssetDatabase'。

huangapple go评论158阅读模式
英文:

Unity Build Error: CS0103 and Missing Context for 'EditorUtility' and 'AssetDatabase

问题

I would like to write a question on Stack Overflow to seek advice on a problem I encountered in Unity. My project involves the movement of a 3D tooth. In the project, we allow users who are dentists to import a CSV file containing the positions of each tooth. We then copy the file into our project folder. When the user clicks the "Next Week" button, the program should save the new tooth positions into a new CSV file with a name formatted as "Week + n" incrementally. The program should also retrieve the latest CSV file values to use in the next week. This allows the user to move the tooth according to their preference. Additionally, the user should be able to save and export the values as an STL file by clicking the "Save and Export" button.

However, when building the program for Windows, I encountered the following error:

UnityEditor.BuildPlayerWindow+BuildMethodException: 4 errors
at UnityEditor.BuildPlayerWindow+DefaultBuildMethods.BuildPlayer (UnityEditor.BuildPlayerOptions options) [0x002da] in :0
at UnityEditor.BuildPlayerWindow.CallBuildMethods (System.Boolean askForBuildLocation, UnityEditor.BuildOptions defaultBuildOptions) [0x00080] in :0
UnityEngine.GUIUtility:ProcessEvent (int,intptr,bool&)

error CS0103: The name 'EditorUtility' does not exist in the current context
error CS0103: The name 'AssetDatabase' does not exist in the current context
Build completed with a result of 'Failed' in 3 seconds (2931 ms)
UnityEngine.GUIUtility:ProcessEvent (int,intptr,bool&)

Could you please assist me in resolving this issue?enter image description here

英文:

I would like to write a question on Stack Overflow to seek advice on a problem I encountered in Unity. My project involves the movement of a 3D tooth. In the project, we allow users who are dentists to import a CSV file containing the positions of each tooth. We then copy the file into our project folder. When the user clicks the "Next Week" button, the program should save the new tooth positions into a new CSV file with a name formatted as "Week + n" incrementally. The program should also retrieve the latest CSV file values to use in the next week. This allows the user to move the tooth according to their preference. Additionally, the user should be able to save and export the values as an STL file by clicking the "Save and Export" button.

However, when building the program for Windows, I encountered the following error:

UnityEditor.BuildPlayerWindow+BuildMethodException: 4 errors
at UnityEditor.BuildPlayerWindow+DefaultBuildMethods.BuildPlayer (UnityEditor.BuildPlayerOptions options) [0x002da] in <f0ee2a9540cd43e39476c433595ea0f7>:0
at UnityEditor.BuildPlayerWindow.CallBuildMethods (System.Boolean askForBuildLocation, UnityEditor.BuildOptions defaultBuildOptions) [0x00080] in <f0ee2a9540cd43e39476c433595ea0f7>:0
UnityEngine.GUIUtility:ProcessEvent (int,intptr,bool&)

error CS0103: The name 'EditorUtility' does not exist in the current context
error CS0103: The name 'AssetDatabase' does not exist in the current context
Build completed with a result of 'Failed' in 3 seconds (2931 ms)
UnityEngine.GUIUtility:ProcessEvent (int,intptr,bool&)

Could you please assist me in resolving this issue?enter image description here

using UnityEngine.UI;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using CsvManagement;
using System.IO;
using UnityEditor;
using UnityEngine.UI;

namespace Submit
{
    public class SubmitManager : MonoBehaviour
    {
        public GameObject teeth;
        public CsvExampleObjectSpawner csv = new CsvExampleObjectSpawner();
           
        public static int countweek;
        public static string filename;
        
        public void submit()
        {
            if(CsvExampleObjectSpawner.next == 1)
            {
                countweek = countweek + 1;
                filename = &quot;week&quot;+countweek+&quot;.csv&quot;;
                csv.wirteCSV(filename);     
                AssetDatabase.Refresh();
          

                //สร้าง Gameobject teeth ขึ้นมา 
                StartCoroutine(NextScenes());
            }

            else
            {
                Debug.Log(&quot;Please sellect file&quot;);
            }
            
            
        }


        IEnumerator NextScenes()
        {
            yield return new WaitForSeconds(0.5f);        
            SceneManager.LoadScene(&quot;Scene2&quot;);
                
        }
        
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using LINQtoCSV;
using System.IO;
using System.Linq;
using UnityEditor;
using UnityEngine.UI;
using CsvManagement;


namespace CsvManagement
{

    public class CsvExampleObjectSpawner : MonoBehaviour
    {
        private Dictionary&lt;string, GameObject&gt; prefabs = new Dictionary&lt;string, GameObject&gt;();

        [Tooltip(&quot;The prefabs for each object&quot;)]
        public GameObject[] objects;
        public GameObject myGameObjects;

        [Tooltip(&quot;The file that contains the objects to be spawned in this scene&quot;)]
        public TextAsset sceneDescriptor;
        string sourcePath;
        public static string filename;
        public Text FileName;
       
        //Path of asset in the unity&#39;s project.
        public static Stack&lt;string&gt; stackOfFiles = new Stack&lt;string&gt;();
        public static int next; 

        public List&lt;CsvSceneObject&gt; posOfTeeth = new List&lt;CsvSceneObject&gt;();

       
        void Awake()
        {
            //Store object names(12 teeth) into arrays.
            foreach(var obj in objects)
            {
                prefabs[obj.name] = obj;
                
            }


        }
      

        public void OpenFileExplorer()
        {
            sourcePath = EditorUtility.OpenFilePanel(&quot;Select the CSV file&quot;, &quot;&quot;, &quot;csv&quot;);
        
            if (!string.IsNullOrEmpty(sourcePath))
            {
                filename = Path.GetFileName(sourcePath);
                FileName.text = &quot;File Name : &quot; +filename;
               
                CheckEmptyFolderAndAddFile();
                next = 1;
               
                
            }
            else
            {
                // User canceled the dialog
                if(stackOfFiles == null)
                {
                    next = 0;
                }
                else
                {
                    Debug.Log(&quot;The user unselected the file.&quot;);
                }
                
                
            }
                
        }

        public void CheckEmptyFolderAndAddFile()
        {
            string path = &quot;Assets/Resources/&quot;;
            
            //ไม่มีไฟล์อยู่ใน resources
            if (Directory.GetFiles(path).Length == 0 &amp;&amp; Directory.GetDirectories(path).Length == 0)
            {
                Debug.Log(&quot;Directory is empty.&quot;);
                loadCSV();
                readCSV(filename, path);
                stackOfFiles.Push(filename); 
            }

            //มีไฟล์อยู่ใน resources
            else
            {          
                foreach (string file in Directory.GetFiles(path))
                {
                    File.Delete(file);
                    //AssetDatabase.Refresh();

                }

                //ใส่ไฟล์เข้าไปใน resources
                loadCSV();
                readCSV(filename, path);
                stackOfFiles.Push(filename);
                
            }
            
        }

    

        public void loadCSV()
        {
            string backupPath = Application.dataPath + &quot;/Resources/&quot;;
            File.Copy(sourcePath, Path.Combine(backupPath, filename));
           // AssetDatabase.Refresh();
           
            
        }

        public void readCSV(string filename, string path)
        { 
            string pathOfFile = path + filename;
            sceneDescriptor = AssetDatabase.LoadAssetAtPath(pathOfFile, typeof(TextAsset)) as TextAsset;
            CsvFileDescription inputFileDescription = new CsvFileDescription
            {
                SeparatorChar = &#39;,&#39;, 
                FirstLineHasColumnNames = true
            };

            using (var ms = new MemoryStream(sceneDescriptor.text.Length))
            {
                using (var txtWriter = new StreamWriter(ms))
                {
                    using (var txtReader = new StreamReader(ms))
                    {
                        txtWriter.Write(sceneDescriptor.text);
                        txtWriter.Flush();
                        ms.Seek(0, SeekOrigin.Begin);

                        //Read CSV file
                        CsvContext cc = new CsvContext();
                        cc.Read&lt;CsvSceneObject&gt;(txtReader, inputFileDescription)
                            .ToList()
                            .ForEach( so =&gt;
                            {
                                //Transform the position of 12 teeth.
                                myGameObjects = prefabs[so.PrefabName];
                                myGameObjects.transform.position = new Vector3(so.X, so.Y, so.Z);
                                myGameObjects.transform.Rotate(so.RoX, so.RoY, so.RoZ);
                                                        
                            });
                    }
                }
                
            }

            
        }

        public void wirteCSV(string filename)
        {
            string pathOfFile = &quot;Assets/CsvWeek/&quot; +filename;
            for(int i = 0; i &lt; objects.Length; i++)
            {
                posOfTeeth.Add(
                    new CsvSceneObject
                    {
                        PrefabName = objects[i].name.ToString(),
                        X = objects[i].transform.position.x,
                        Y = objects[i].transform.position.y,
                        Z = objects[i].transform.position.z,
                        RoX = objects[i].transform.rotation.eulerAngles.x,
                        RoY = objects[i].transform.rotation.eulerAngles.y,
                        RoZ = objects[i].transform.rotation.eulerAngles.z


                    }
                );
       
                
            }
           
            CsvFileDescription outputFileDescription = new CsvFileDescription
            {
                SeparatorChar = &#39;,&#39;, 
                FirstLineHasColumnNames = true,
            };


            CsvContext cc = new CsvContext();
            cc.Write&lt;CsvSceneObject&gt;(posOfTeeth, pathOfFile, outputFileDescription);

            Debug.Log(&quot;Successfully wrote the file.&quot;);
            
        
        }
     
    }
}

答案1

得分: 1

不能在Unity Build中使用'EditorUtility'和'AssetDatabase'。

只能在Unity编辑器中访问这些类。此外,您应该将这些脚本放在'Editor'文件夹中。

如果您真的需要访问文件资源管理器,这里有一些链接(简而言之):

英文:

You cannot use neither 'EditorUtility' nor 'AssetDatabase' in Unity Build.

You can only access these classes in Unity Editor. Furthermore you should put these scripts in 'Editor' Folder.

If you really need to access File Explorer here are some links (TL;DR):

答案2

得分: 0

【Filipeak答案】1 是正确的,但我想强调一些细节。

为什么 UnityEditor 在构建时不起作用

当编写类似于Unity编辑器的解决方案(如工具、开发资产等)时,我们将访问Unity中未与游戏捆绑在一起的“区域” - 例如:Unity不需要将所有编辑器窗口模块与游戏一起打包编译,因为最终用户将不会与此界面交互。

轻松剥离代码

有一些方法可以在构建时剥离资产(或功能),而无需重新编码或手动切换类名:

  1. 使用文件夹:在使用Unity构建时有一些特殊的文件夹结构可供使用(查看此处)。因为你希望只在编辑器上运行一些代码,所以你可能需要将所有类创建在“Editor”文件夹中(请注意,此文件夹内的所有资产在构建时将不可用)。

  2. C#技巧 - 脚本定义符号:你可以定义脚本符号,以便编译器将根据其阅读你的代码。你可以使用它来检查UNITY_EDITOR符号,以便在Unity编辑器上运行时切换代码块。

在构建时与文件/目录交互

你可以在构建时与文件夹和用户文件进行交互。要做到这一点,请查看System.IO命名空间,其中包括了与用户操作系统文件系统进行交互的功能 - 请记住在针对不同平台时可能使用的不同路径/权限模式。

英文:

Filipeak answer is correct, but I'd like to nail down some details

Why UnityEditor does not work on build

When coding for Unity Editor alike solutions (such as tools, development assets, etc) we'll access "areas" of Unity that are not bundled with our game - for instance: there's no need for Unity to pack & compile all editor window modules with your game, since the end-user will not interact with this interface.

Stripping code easily

There are some ways to strip assets (or functions) when building withouth having to re-code or manually toggle class names:

  1. Using Folders : There are some special folders structure to use when building with unity (check this). As you'd like to get some code working only on editor, you may have to create all your classes inside "Editor" folder (note that all assets inside this will not be available on build)

  2. C# Technique - Script Definition Symbols : You can define scripting symbols so the compiler will read your code depending on that very block. You can use it to check UNITY_EDITOR symbol to whether toggle a code-block to run only when on Unity Editor

Interacting with files/directories on-build

You can interact with folders and user files while in build. To do it so, check the System.IO namespace, which will include functions to aid on interacting with your user OS file-system - please keep in mind the different path/permissions patterns that you may use when targeting different platforms

huangapple
  • 本文由 发表于 2023年5月28日 14:43:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/76350265.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定