使用Microsoft CSHARP Unity实施动态汇编的问题

发布于 2025-02-04 13:00:46 字数 4491 浏览 2 评论 0原文

使用Microsoft Csharp Unity实施动态汇编的问题。

它通常在Unity编辑器中起作用,但是在构建后调试时会发生以下错误。

这是我真正需要的功能,所以我一直在寻找很多功能,但是我找不到太多信息。任何帮助将不胜感激。

所讨论的代码:

using UnityEngine;
using System;
using Microsoft.CSharp;
using System.CodeDom.Compiler;
using System.Reflection;
using System.Text;

public class test : MonoBehaviour
{
    private void Start()
    {
        var assembly = Compile(@"
            using UnityEngine;
            using System.Collections;

            public class RuntimeCompiled : MonoBehaviour
            {
                public static RuntimeCompiled AddYourselfTo(GameObject host)
                {
                    return host.AddComponent<RuntimeCompiled>();
                }

                void Start()
                {
                    Debug.Log(""TEST"");
                }
            }");

        var runtimeType = assembly.GetType("RuntimeCompiled");
        var method = runtimeType.GetMethod("AddYourselfTo");
        var del = (Func<GameObject, MonoBehaviour>)
            Delegate.CreateDelegate(
            typeof(Func<GameObject, MonoBehaviour>),
            method
            );

        // We ask the compiled method to add its component to this.gameObject
        var addedComponent = del.Invoke(gameObject);

        // The delegate pre-bakes the reflection, so repeated calls don't
        // cost us every time, as long as we keep re-using the delegate.
    }

    public static Assembly Compile(string source)
    {
        // Replace this Compiler.CSharpCodeProvider wth aeroson's version
        // if you're targeting non-Windows platforms:
        var provider = new CSharpCodeProvider();
        var param = new CompilerParameters();

        // Add ALL of the assembly references
        foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
        {
            string cash_d = assembly.Location.ToString();
            if (!cash_d.Contains("mscorlib.dll"))
            {
                param.ReferencedAssemblies.Add(assembly.Location);
            }
        }

        // Or, uncomment just the assemblies you need...

        // System namespace for common types like collections.
        //param.ReferencedAssemblies.Add("System.dll");

        // This contains methods from the Unity namespaces:
        //param.ReferencedAssemblies.Add("UnityEngines.dll");

        // This assembly contains runtime C# code from your Assets folders:
        // (If you're using editor scripts, they may be in another assembly)
        //param.ReferencedAssemblies.Add("CSharp.dll");


        // Generate a dll in memory
        param.GenerateExecutable = false;
        param.GenerateInMemory = true;

        // Compile the source
        var result = provider.CompileAssemblyFromSource(param, source);

        if (result.Errors.Count > 0)
        {
            var msg = new StringBuilder();
            foreach (CompilerError error in result.Errors)
            {
                msg.AppendFormat("Error ({0}): {1}\n",
                  error.ErrorNumber, error.ErrorText);
            }
            throw new Exception(msg.ToString());
        }

        // Return the assembly
        return result.CompiledAssembly;
    }
}

以下是错误内容。

Multi - casting "[IP] -- [Port] 55354 [Flags] 2 [Guid] 344250057 [EditorId] 2120216054 [Version] 1048832 [Id] WindowsPlayer(2,DESKTOP---) [Debug] 1 [PackageName] WindowsPlayer [ProjectName] MRS_Main" to[225.0.0.222:54997]...
Starting managed debugger on port 56057
Initialize engine version: 2021.3.1f1(3b70a0754835)
[Subsystems] Discovering subsystems at path D:/ Documents / Unity / MRS_Main / build / MRS_Main_Data / UnitySubsystems
GfxDevice: creating device client; threaded = 1; jobified = 1
Direct3D:
Version: Direct3D 11.0[level 11.1]
    Renderer: NVIDIA GeForce RTX 3050 Laptop GPU(ID= 0x25a2)
    Vendor: NVIDIA
  VRAM:     3991 MB
  Driver:   30.0.14.9649
< RI > Initializing input.
< RI > Input initialized.
  < RI > Initialized touch support.
    UnloadTime: 0.779800 ms
    NotSupportedException: Microsoft.CSharp.CSharpCodeProvider::.ctor
      at Microsoft.CSharp.CSharpCodeProvider..ctor ()[0x00000] in <00000000000000000000000000000000>:0 

      at test.Compile (System.String source)[0x00001] in D:\Documents\Unity\MRS_Main\Assets\Scripts\test.cs:48 

      at test.Start ()[0x00006] in D:\Documents\Unity\MRS_Main\Assets\Scripts\test.cs:12 

Problems implementing dynamic compilation using Microsoft CSharp in Unity.

It works normally in the Unity editor, but the following error occurs when debugging after build.

It's a feature I really need, so I've been looking for it a lot, but I can't find much information. Any help would be greatly appreciated.

The code in question:

using UnityEngine;
using System;
using Microsoft.CSharp;
using System.CodeDom.Compiler;
using System.Reflection;
using System.Text;

public class test : MonoBehaviour
{
    private void Start()
    {
        var assembly = Compile(@"
            using UnityEngine;
            using System.Collections;

            public class RuntimeCompiled : MonoBehaviour
            {
                public static RuntimeCompiled AddYourselfTo(GameObject host)
                {
                    return host.AddComponent<RuntimeCompiled>();
                }

                void Start()
                {
                    Debug.Log(""TEST"");
                }
            }");

        var runtimeType = assembly.GetType("RuntimeCompiled");
        var method = runtimeType.GetMethod("AddYourselfTo");
        var del = (Func<GameObject, MonoBehaviour>)
            Delegate.CreateDelegate(
            typeof(Func<GameObject, MonoBehaviour>),
            method
            );

        // We ask the compiled method to add its component to this.gameObject
        var addedComponent = del.Invoke(gameObject);

        // The delegate pre-bakes the reflection, so repeated calls don't
        // cost us every time, as long as we keep re-using the delegate.
    }

    public static Assembly Compile(string source)
    {
        // Replace this Compiler.CSharpCodeProvider wth aeroson's version
        // if you're targeting non-Windows platforms:
        var provider = new CSharpCodeProvider();
        var param = new CompilerParameters();

        // Add ALL of the assembly references
        foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
        {
            string cash_d = assembly.Location.ToString();
            if (!cash_d.Contains("mscorlib.dll"))
            {
                param.ReferencedAssemblies.Add(assembly.Location);
            }
        }

        // Or, uncomment just the assemblies you need...

        // System namespace for common types like collections.
        //param.ReferencedAssemblies.Add("System.dll");

        // This contains methods from the Unity namespaces:
        //param.ReferencedAssemblies.Add("UnityEngines.dll");

        // This assembly contains runtime C# code from your Assets folders:
        // (If you're using editor scripts, they may be in another assembly)
        //param.ReferencedAssemblies.Add("CSharp.dll");


        // Generate a dll in memory
        param.GenerateExecutable = false;
        param.GenerateInMemory = true;

        // Compile the source
        var result = provider.CompileAssemblyFromSource(param, source);

        if (result.Errors.Count > 0)
        {
            var msg = new StringBuilder();
            foreach (CompilerError error in result.Errors)
            {
                msg.AppendFormat("Error ({0}): {1}\n",
                  error.ErrorNumber, error.ErrorText);
            }
            throw new Exception(msg.ToString());
        }

        // Return the assembly
        return result.CompiledAssembly;
    }
}

Below is the error content.

Multi - casting "[IP] -- [Port] 55354 [Flags] 2 [Guid] 344250057 [EditorId] 2120216054 [Version] 1048832 [Id] WindowsPlayer(2,DESKTOP---) [Debug] 1 [PackageName] WindowsPlayer [ProjectName] MRS_Main" to[225.0.0.222:54997]...
Starting managed debugger on port 56057
Initialize engine version: 2021.3.1f1(3b70a0754835)
[Subsystems] Discovering subsystems at path D:/ Documents / Unity / MRS_Main / build / MRS_Main_Data / UnitySubsystems
GfxDevice: creating device client; threaded = 1; jobified = 1
Direct3D:
Version: Direct3D 11.0[level 11.1]
    Renderer: NVIDIA GeForce RTX 3050 Laptop GPU(ID= 0x25a2)
    Vendor: NVIDIA
  VRAM:     3991 MB
  Driver:   30.0.14.9649
< RI > Initializing input.
< RI > Input initialized.
  < RI > Initialized touch support.
    UnloadTime: 0.779800 ms
    NotSupportedException: Microsoft.CSharp.CSharpCodeProvider::.ctor
      at Microsoft.CSharp.CSharpCodeProvider..ctor ()[0x00000] in <00000000000000000000000000000000>:0 

      at test.Compile (System.String source)[0x00001] in D:\Documents\Unity\MRS_Main\Assets\Scripts\test.cs:48 

      at test.Start ()[0x00006] in D:\Documents\Unity\MRS_Main\Assets\Scripts\test.cs:12 

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文