Unity菜单项生成脚本并附加GameObject问题排查与修复
问题分析与修复方案
一、File.WriteAllText启用后Debug失效的原因及修复
语法错误导致编译失败:
你的catch块中Debug.Log($"Faild to write: {ex}")缺少分号,这会导致代码无法编译,整个EditorWindow逻辑都无法正常执行,自然看不到Debug日志。文件写入逻辑漏洞:
当检测到文件已存在时,当前代码仅打印错误但仍会继续执行写入操作,应该在报错后直接返回,避免覆盖已有文件。
二、无法识别选中GameObject的原因及修复
大小写拼写错误:
Gameobject selected = Selection.activeGameObject;中的Gameobject应为GameObject(首字母O大写)。Debug.log(selected.transform.name);中的log应为Log(首字母L大写)。
类型获取方式不可靠:
刚生成的脚本仅通过System.Type.GetType(input_text)无法获取到类型,因为脚本尚未完成编译,且未指定程序集。更可靠的方式是通过AssetDatabase加载生成的脚本资源,再获取对应的类类型。空引用未处理:
在访问selected.transform.name前未判断selected是否为空,会触发空引用异常,需先判空再执行后续操作。
三、完整修复代码
using System; using System.IO; using UnityEditor; using UnityEngine; public class ScriptBundle : EditorWindow { private string input_text = ""; [MenuItem("Component/Custom Items/Script and Editor")] public static void ShowWindow() { ScriptBundle win = GetWindow<ScriptBundle>("Script + Editor Generator"); win.minSize = new Vector2(400, 100); win.maxSize = new Vector2(400, 100); win.position = new Rect(Screen.width / 2, Screen.height / 2, 400, 100); } private void OnEnable() { minSize = new Vector2(400, 100); maxSize = new Vector2(400, 100); position = new Rect(Screen.width / 2, Screen.height / 2, 400, 100); } private void OnGUI() { GUILayout.Label("Generate a script and its inspector editor script", EditorStyles.boldLabel); input_text = EditorGUILayout.TextField("Script Name: ", input_text); GUILayout.Space(10); if (GUILayout.Button("Generate")) { if (string.IsNullOrWhiteSpace(input_text)) { Debug.LogError("Script name cannot be empty!"); return; } Debug.Log(input_text); if (GenerateScript(input_text)) { AttachScriptToGameObject(input_text); } Close(); } } private bool GenerateScript(string input_text) { Debug.Log("Generate script"); string path = $"Assets/{input_text}.cs"; if (File.Exists(path)) { Debug.LogError("A script with this name already exists."); return false; } string template = @"using UnityEngine; public class {0} : MonoBehaviour {{ }}"; template = string.Format(template, input_text); try { File.WriteAllText(path, template); AssetDatabase.Refresh(); Debug.Log($"Script generated at: {path}"); return true; } catch (Exception ex) { Debug.LogError($"Failed to write script: {ex.Message}"); return false; } } private void AttachScriptToGameObject(string input_text) { GameObject selected = Selection.activeGameObject; if (selected == null) { Debug.LogError("No GameObject selected!"); return; } Debug.Log($"Selected GameObject: {selected.name}"); string scriptPath = $"Assets/{input_text}.cs"; MonoScript script = AssetDatabase.LoadAssetAtPath<MonoScript>(scriptPath); if (script == null) { Debug.LogError($"Failed to load script at path: {scriptPath}"); return; } Type scriptType = script.GetClass(); if (scriptType == null) { Debug.LogError($"Failed to get class type for script: {input_text}"); return; } selected.AddComponent(scriptType); Debug.Log($"Script {input_text} attached to {selected.name}"); } }
额外优化点
- 增加脚本名称为空的判断,避免无效操作。
- 将生成脚本的方法改为返回布尔值,仅在生成成功时尝试附加脚本。
- 使用字符串格式化优化模板代码,提升可读性。
- 细化错误日志,便于定位问题。
内容的提问来源于stack exchange,提问作者I_dk727
相关产品推荐
相关产品推荐

