白泽图

  • 文章
    • Unity渲染
    • Unity项目开发
    • 工具
    • 数学
    • 算法
    • 网站搭建
    • 网络&操作系统
蒋程个人博客
互联网技术经验总结&分享
  1. 首页
  2. Unity项目开发
  3. 正文

Unity C#代码动态编译

2022-04-27 663点热度 0人点赞 0条评论
        static void GenerateCode()
        {
            UnityEngine.Debug.LogError("编译");
            var code = @"
using UnityEditor;
using TBC.Timeline;
namespace TBC.Editor.Timeline
{
    [CustomEditor(typeof(TBCParticleClip))]
    public class BattleParticleInspector : UnityEditor.Editor
    {
        public override void OnInspectorGUI()
        {

        }
    }
}";
            CodeDomProvider provider = CodeDomProvider.CreateProvider("C#");//创建编译器
            CompilerParameters options = new CompilerParameters();//创建编译器参数

            options.ReferencedAssemblies.Add("E:/TLBB/game/client/TLProject/Library/ScriptAssemblies/TBC.Framework.Editor.dll");
            options.ReferencedAssemblies.Add("D:/Program Files/Unity 2019.4.35f1/Editor/Data/Managed/UnityEditor.dll");//为当前程序集添加引用
            options.ReferencedAssemblies.Add("D:/Program Files/Unity 2019.4.35f1/Editor/Data/Managed/UnityEngine/UnityEngine.CoreModule.dll");
            options.ReferencedAssemblies.Add("E:/TLBB/game/client/TLProject/Library/ScriptAssemblies/Unity.Timeline.dll");
            options.ReferencedAssemblies.Add("E:/TLBB/game/client/TLProject/Library/ScriptAssemblies/TBC.Framework.dll");
            options.ReferencedAssemblies.Add("D:/Program Files/Unity 2019.4.35f1/Editor/Data/Managed/UnityEngine.dll");
            options.ReferencedAssemblies.Add("E:/TLBB/game/client/TLProject/Library/ScriptAssemblies/Unity.Timeline.Editor.dll");
            


            options.GenerateExecutable = false;// 是否生成exe文件
            options.GenerateInMemory = true;// 是否在内存输出 


            options.OutputAssembly = "E:/TLBB/game/client/TLProject/Library/AutoGenerate.dll";


            CompilerResults cr = provider.CompileAssemblyFromSource(options, code);//直接执行
            if (cr.Errors.HasErrors)
            {
                UnityEngine.Debug.LogError("编译错误:");
                foreach (CompilerError err in cr.Errors)
                    UnityEngine.Debug.LogError(err.ErrorText);
            }
            else
            {
                UnityEngine.Debug.Log("编译成功!"); 
            }
             
            Assembly[] arr = AppDomain.CurrentDomain.GetAssemblies();
            foreach (var ass in arr)
            {
                if (ass.FullName.Contains("AutoGenerate"))
                {
                    UnityEngine.Debug.LogError("-------在当前域中--------");
                    UnityEngine.Debug.LogError(ass.FullName);
                }
            }

        }

命名空间

using System.Reflection;
//动态编译用的
using System.CodeDom.Compiler;

注意点:

1.引用的dll必须填写绝对路径,否则找不到

2.如果引用的dll引用了其他的dll,也需要添加,先后顺序无所谓,如果没有引用会报错,根据报错引用即可

3.options.GenerateInMemory 与 options.OutputAssembly 需要设置,当 options.GenerateInMemory = true 且 options.OutputAssembly 有路径,路径有效即可,位置随意,那么动态编译后会自动被Unity的域加载,如果需要使用,反射即可

4.生成的UnityEditor相关的dll,如上面,虽然被Unity加载了,但无法执行,只能把dll放到unity的Asset下才行

案例说明

TBCClipInspector 是我放在自定义程序集 TBC.Framework.Editor.dll (这个Dll引用了Unity.Timeline.Editor.dll,TBCClip里引用了Unity.Timeline.dll)下的一个代码,主要是用于隐藏 Inspector面板的Script属性,代码如下

namespace TBC.Editor.Timeline
{
    [CustomEditor(typeof(TBCClip))]
    public class TBCClipInspector : UnityEditor.Editor
    {
        public override void OnInspectorGUI()
        {

            EditorGUI.BeginChangeCheck();
            serializedObject.Update();

            SerializedProperty property = serializedObject.GetIterator();
            bool expanded = true;
            while (property.NextVisible(expanded))
            {
                expanded = false;
                if (SkipField(property.propertyPath))
                    continue;
                EditorGUILayout.PropertyField(property, true);
            }

            serializedObject.ApplyModifiedProperties();
            EditorGUI.EndChangeCheck();
        }


        static bool SkipField(string fieldName)
        {
            return fieldName == "m_Script";
        }
    }
}

所以如果继承TBCClip的类想有这个功能,对应的Inspector代码要继承TBCClipInspector,这才想设计一个属性标签用来动态生成对应的Inspector代码,可惜生成出来的dll必须放到Asset下才生效,失去了一开始的意义,(还不如直接生成代码文件),后续会用Dll注入试一下,本文只是记录实验过程,以及动态编译的方法

标签: 暂无
最后更新:2022-04-27

蒋程

这个人很懒,什么都没留下

点赞
< 上一篇
下一篇 >

文章评论

您需要 登录 之后才可以评论

COPYRIGHT © 2023 白泽图. ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang

登录
注册|忘记密码?