在Unity编辑器模式下,根据配置文件动态生成代码可以通过编写自定义编辑器脚本实现。以下是一些场景下的5个简化示例,分别说明如何基于不同的配置数据来生成对应的C#代码:
示例1:基于ScriptableObject的配置生成类
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#类,该类包含了与配置中每个名称相对应的游戏对象字段。
示例2:预制体路径列表生成加载代码
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目录加载的预制体引用。
示例3:动画剪辑生成动画控制器片段
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#方法调用逻辑。
示例4:Excel配置表生成序列化类
// 假设我们有一个工具能够读取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表头一一对应。
示例5:UI元素及其事件绑定生成代码
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经典脚本(11-20)
50个开发必备的Python经典脚本(21-30)
50个开发必备的Python经典脚本(31-40)
50个开发必备的Python经典脚本(41-50)
————————————————文章来源:https://www.toymoban.com/news/detail-832493.html
最后我们放松一下眼睛文章来源地址https://www.toymoban.com/news/detail-832493.html
到了这里,关于Unity 通过配置文件生成代码的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!