unity动态执行C#代码「终于解决」

unity动态执行C#代码「终于解决」好久没写文章了,主要还是之前公司项目时间紧,任务重,导致下班了就没心情开电脑了,到家倒头就睡了,今天趁稍微空闲就赶紧把最近写的一个小功能记录下,

欢迎大家来到IT世界,在知识的湖畔探索吧!

好久没写文章了,主要还是之前公司项目时间紧,任务重,导致下班了就没心情开电脑了,到家倒头就睡了,今天趁稍微空闲就赶紧把最近写的一个小功能记录下,以便以后能用上。

unity动态执行C#代码「终于解决」

unity动态执行C#代码「终于解决」

公司项目由于以lua为主,所以很容易实现动态执行代码,举个例子,游戏运行中,某个数据显示不对,这个时候就能在不关闭游戏运行的情况下,直接将写好的代码粘贴进输入框执行,就能知道是服务器传的数据问题还是客户端的问题。再举个例子,在播放新手动画时,策划说某个角色的点的位置不好,得换个位置,虽然我们能直接把角色拖到某个位置上来看效果,但如果有寻路的话,就没法知道这个点是不是能通过寻路来走到了,这个时候就可以写一段代码让角色自己走到想要去的点来看效果,而不用关闭游戏,然后写完代码再走一堆流程到需要测试的地方看效果。个人觉得能节省一点时间。那么问题来了,lua能这么做,C#能不能呢?于是我搜索了很多网页,终于让我找到了方法,不过还是有一些小问题,比如UnityEngine.dll文件加载不了,自己编写的脚本的所在的dll名字,还有就是像上图一样有输入框的地方等。以下就是实现动态执行C#代码的脚本。

类名:DynamicCodeHelper

using System;
using System.Reflection;
using Microsoft.CSharp;
using System.CodeDom.Compiler;
using System.Text;
using UnityEngine;
 
public class DynamicCodeHelper : MonoBehaviour
{
    public void ExcuteDynamicCode(string codeStr="") {
        string[] strList = codeStr.Split(';');
        // 1.CSharpCodePrivoder
        CSharpCodeProvider objCSharpCodePrivoder =new CSharpCodeProvider();
 
        // 2.ICodeComplier
        ICodeCompiler objICodeCompiler = objCSharpCodePrivoder.CreateCompiler();
 
        // 3.CompilerParameters
        CompilerParameters objCompilerParameters =new CompilerParameters();
        objCompilerParameters.ReferencedAssemblies.Add("System.dll");
        objCompilerParameters.ReferencedAssemblies.Add(Application.dataPath.Replace("Assets", "Library") + "/ScriptAssemblies/Assembly-CSharp.dll");
        objCompilerParameters.ReferencedAssemblies.Add(Application.dataPath.Replace("Assets", "MyDll") + "/UnityEngine.CoreModule.dll");//尝试过通过写文本配置来加载,结果不行会报错,如果有大佬解决了请留言告诉我,万分感谢
        objCompilerParameters.GenerateExecutable =false;
        objCompilerParameters.GenerateInMemory =true;
 
        // 4.CompilerResults
        CompilerResults cr = objICodeCompiler.CompileAssemblyFromSource(objCompilerParameters, GenerateCode(strList));
 
        if (cr.Errors.HasErrors)
        {
            Debug.LogError("编译错误:");
            foreach (CompilerError err in cr.Errors)
            {
                Debug.LogError(err.ErrorText);
            }
        }
        else
        {
            // 通过反射,调用DynamicCode的实例
            Assembly objAssembly = cr.CompiledAssembly;
            object objDynamicCode = objAssembly.CreateInstance("DynamicCodeGenerate.DynamicCode");
            MethodInfo objMI = objDynamicCode.GetType().GetMethod("CodeExecute");
            objMI.Invoke(objDynamicCode, null);
        }
    }
 
    static string GenerateCode(string[] strList)
    {
        StringBuilder sb =new StringBuilder();
        sb.Append("using System;");
        sb.Append(Environment.NewLine);
        sb.Append("using UnityEngine;");
        sb.Append(Environment.NewLine);
        sb.Append("namespace DynamicCodeGenerate");
        sb.Append(Environment.NewLine);
        sb.Append("{");
        sb.Append(Environment.NewLine);
        sb.Append("      public class DynamicCode");
        sb.Append(Environment.NewLine);
        sb.Append("      {");
        sb.Append(Environment.NewLine);
        sb.Append("          public void CodeExecute()");
        sb.Append(Environment.NewLine);
        sb.Append("          {");
        sb.Append(Environment.NewLine);
        foreach (string str in strList)
        {
            if (str != "")
            {
                sb.Append(string.Format("               {0};", str.Replace("\n", "")));
                sb.Append(Environment.NewLine);
            }
        }
        sb.Append("          }");
        sb.Append(Environment.NewLine);
        sb.Append("      }");
        sb.Append(Environment.NewLine);
        sb.Append("}");
 
        string code = sb.ToString();
        Debug.LogError(code);
 
        return code;
    }
}

欢迎大家来到IT世界,在知识的湖畔探索吧!

unity动态执行C#代码「终于解决」

unity动态执行C#代码「终于解决」

unity动态执行C#代码「终于解决」

简单说明:1.UnityEngine.dll已经被分割了,所以这里加载的是UnityEngine.CoreModule.dll,我的路径在E:\Unity 2019.2.4f1\Unity\Editor\Data\Managed\UnityEngine\UnityEngine.CoreModule.dll,也就是在编辑器安装路径的Editor\Data\Managed\UnityEngine\UnityEngine.CoreModule.dll。我是创建了和Assets同级的一个文件夹,命名为MyDll,这样一些需要加载的dll我就全放这里了,

2.我们在unity新增的C#脚本都是在Assembly-CSharp.dll这个程序集里,而这个程序集的路径就是在和Assets同级的Library底下的ScriptAssemblies文件夹里。

3.Editor脚本如下。

类名:DynamicCodeEditor

欢迎大家来到IT世界,在知识的湖畔探索吧!using UnityEditor;
using UnityEngine;
 
[CustomEditor(typeof(DynamicCodeHelper))]
public class DynamicCodeEditor : Editor
{
    string runCode = @"Debug.LogError(""test your code here!"");";
 
    public override void OnInspectorGUI()
    {
        GUILayout.Label("DynamicC#Code", GUILayout.Width(100));
        runCode = GUILayout.TextArea(runCode,GUILayout.Height(500));
        if (GUILayout.Button("RunAnyCode"))
        {
            RunAnyCode(runCode);
        }
        base.OnInspectorGUI();
    }
 
    public void RunAnyCode(string code)
    {
        var t = target as DynamicTest;
        t.ExcuteDynamicCode(code);
    }
}

这样就能在输入框中写代码,并动态执行了。

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://itzsg.com/18320.html

(0)

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

联系我们YX

mu99908888

在线咨询: 微信交谈

邮件:itzsgw@126.com

工作时间:时刻准备着!

关注微信