赞
踩
using UnityEngine; using UnityEditor; using System.IO; [CreateAssetMenu(fileName = "NewConfig.asset", menuName = "Configuration/New Config")] public class ConfigurationSO : ScriptableObject { public string[] GameObjectNames; [MenuItem("Assets/Generate Code From Config")] static void GenerateCode() { var config = Selection.activeObject as ConfigurationSO; if (config != null) { StringBuilder sb = new StringBuilder(); foreach (var name in config.GameObjectNames) { sb.AppendLine($"public GameObject {name};"); } string className = "GeneratedConfig"; string filePath = Path.Combine(Application.dataPath, $"Scripts/{className}.cs"); File.WriteAllText(filePath, $@" using UnityEngine; public class {className} {{ {sb.ToString()} }} "); AssetDatabase.Refresh(); } else { Debug.LogError("Please select a ConfigurationSO asset."); } } }
这个例子中,我们创建了一个ScriptableObject类型ConfigurationSO
,其中包含一个字符串数组用于存储游戏对象名称。当用户通过菜单命令“Assets/Generate Code From Config”执行时,会根据这些名称动态生成一个新的C#类,该类包含了与配置中每个名称相对应的游戏对象字段。
using UnityEngine; using UnityEditor; using System.Collections.Generic; using System.IO; public class PrefabLoaderGenerator : Editor { [MenuItem("Assets/Generate Prefab Loader")] static void GeneratePrefabLoader() { var prefabPaths = new List<string>(); foreach (var guid in Selection.assetGUIDs) { var path = AssetDatabase.GUIDToAssetPath(guid); if (PrefabUtility.GetPrefabAssetType(AssetDatabase.LoadMainAssetAtPath(path)) == PrefabAssetType.Regular) { prefabPaths.Add(path); } } if (prefabPaths.Count > 0) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < prefabPaths.Count; i++) { var name = Path.GetFileNameWithoutExtension(prefabPaths[i]); sb.AppendLine($"public GameObject {name}Prefab {{ get {{ return Resources.Load(\"{prefabPaths[i]}\") as GameObject; }} }}"); } string className = "PrefabLoader"; string filePath = Path.Combine(Application.dataPath, $"Scripts/{className}.cs"); File.WriteAllText(filePath, $@" using UnityEngine; public static class {className} {{ {sb.ToString()} }} "); AssetDatabase.Refresh(); } else { Debug.LogError("Please select one or more prefabs."); } } }
此例中,选择多个预制体后,编辑器将生成一个静态类,其成员为对应预制体路径的属性,并且返回从Resources目录加载的预制体引用。
using UnityEngine; using UnityEditor; using UnityEngine.Animations.Rigging; using System.Linq; public class AnimationClipControllerGenerator : EditorWindow { [MenuItem("Assets/Generate Animation Controller")] static void GenerateController() { var clips = Selection.objects.OfType<AnimationClip>().ToList(); if (clips.Any()) { AnimatorController ac = new AnimatorController(); ac.name = "GeneratedAnimatorController"; foreach (var clip in clips) { var stateMachine = ac.layers[0].stateMachine; var newState = stateMachine.AddStateMachineBehaviour(typeof(Playables.PlayableState)); newState.motion = clip; newState.name = clip.name; } string controllerPath = AssetDatabase.GenerateUniqueAssetPath("Assets/_Generated/GeneratedAnimatorController.controller"); AssetDatabase.CreateAsset(ac, controllerPath); // 这里是假设要生成控制代码,但实际AnimatorController不需要额外C#代码控制 // 若需要,可以写入如切换动画状态的函数代码到指定文件 } else { Debug.LogError("Please select one or more animation clips."); } } }
虽然这个例子并不直接生成C#代码,而是动态地构建了AnimatorController层级结构(Unity内置功能),若需生成相关C#控制代码,则可进一步扩展以根据生成的状态机结构创建相应的C#方法调用逻辑。
// 假设我们有一个工具能够读取Excel并转换成TSV格式文本 public class ExcelToCSClassGenerator : Editor { [MenuItem("Assets/Generate C# Class from Excel")] static void GenerateClassFromExcel() { // 省略了读取和解析Excel的过程,假设已得到键值对集合 Dictionary<string, string> tableData = ReadExcelDataAsDictionary("SettingSrc/Test.xls"); StringBuilder sb = new StringBuilder(); sb.AppendLine("using UnityEngine;"); sb.AppendLine("[System.Serializable]"); sb.AppendLine("public class ExcelConfig {"); foreach (var pair in tableData) { sb.AppendLine($" public string {pair.Key} {{ get; set; }} = \"{pair.Value}\";"); } sb.Append("}"); string className = "ExcelConfig"; string filePath = Path.Combine(Application.dataPath, $"Scripts/{className}.cs"); File.WriteAllText(filePath, sb.ToString()); AssetDatabase.Refresh(); } static Dictionary<string, string> ReadExcelDataAsDictionary(string excelPath) { // 实现从Excel文件读取数据到字典的方法 // 这里省略了具体实现细节 return new Dictionary<string, string>(); // 返回样本空字典,实际应填充数据 } }
这里展示了如何根据Excel表格中的键值对生成一个带有属性的C#类,类中属性与Excel表头一一对应。
using UnityEngine.UIElements; using UnityEditor.UIElements; using UnityEditor; using System.Linq; public class UIElementCodeGenerator : EditorWindow { [MenuItem("UI/Generate UI Bindings")] static void GenerateUIBindings() { VisualElement root = GetActiveUIRootElement(); if (root != null) { StringBuilder sb = new StringBuilder(); foreach (VisualElement element in root.Query().OfType<Button>()) { var name = element.name; var methodBinding = GetBoundMethodName(element); // 获取绑定的回调方法名 sb.AppendLine($"public void OnButton_{name}Clicked() {{ /* Call {methodBinding} */ }}"); } string className = "UIBindings"; string filePath = Path.Combine(Application.dataPath, $"Scripts/UI/{className}.cs"); File.WriteAllText(filePath, $@" using UnityEngine; using UnityEngine.Events; public class {className} : MonoBehaviour {{ {sb.ToString()} }} "); AssetDatabase.Refresh(); } } static string GetBoundMethodName(VisualElement element) { // 省略获取按钮绑定的UnityEvent回调方法名的逻辑 return "OnButtonClick"; // 返回样本方法名,实际应提取真实方法名 } static VisualElement GetActiveUIRootElement() { // 获取当前选中的UI根元素,此处省略具体实现 return null; // 返回样本null,实际应返回UI根元素 } }
在这个例子中,我们遍历UI界面元素树,找到所有的按钮并根据它们的名字生成响应的点击事件处理方法,这些方法可以在UI相关的MonoBehaviour脚本中被调用。
python推荐学习汇总连接:
50个开发必备的Python经典脚本(1-10)
50个开发必备的Python经典脚本(41-50)
————————————————
最后我们放松一下眼睛
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。