Unity把字符串动态编译成类对象代码以及反射修改字段

文章目录

      • 实例1:动态编译C#代码并执行
      • 实例2:使用反射获取和设置私有字段
      • 实例3:通过反射调用方法
      • 实例4:反射遍历所有MonoBehaviour组件的方法
      • 实例5:反射探针(Reflection Probes)

Unity中的动态编程通常指的是在运行时创建、修改和执行代码的能力,这可能包括动态生成脚本或使用反射机制来访问和操作程序集中的类型、成员等。反射则是.NET框架(Unity基于此构建)提供的一个强大的功能,它允许你在运行时检查类型信息、调用方法、获取和设置字段值等。

以下是五个与Unity中动态编程和反射相关的代码实例:

实例1:动态编译C#代码并执行

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

public class DynamicCodeExample : MonoBehaviour
{
    public string DynamicScript = @"
        using UnityEngine;
        public class RuntimeGeneratedClass : MonoBehaviour
        {
            void Update()
            {
                Debug.Log(""This code was dynamically generated at runtime!"");
            }
        }";

    void Start()
    {
        // 动态编译代码
        var provider = new CSharpCodeProvider();
        var parameters = new CompilerParameters(new[] { "mscorlib.dll", "UnityEngine.dll" });
        parameters.GenerateInMemory = true;
        var results = provider.CompileAssemblyFromSource(parameters, DynamicScript);

        if (results.Errors.Count == 0)
        {
            // 获取编译后的类型并实例化
            Type generatedType = results.CompiledAssembly.GetType("RuntimeGeneratedClass");
            GameObject go = new GameObject();
            generatedType.GetConstructor(Type.EmptyTypes).Invoke(new object[] { go });
        }
        else
        {
            foreach (var error in results.Errors)
            {
                Debug.LogError(error.ToString());
            }
        }
    }
}

注意:虽然上述代码演示了如何动态编译C#脚本,但在移动平台上并不支持这种做法,因为移动设备上不允许实时编译代码。

实例2:使用反射获取和设置私有字段

public class ReflectionExample : MonoBehaviour
{
    private int _hiddenValue = 42;

    void Start()
    {
        // 获取当前类的类型引用
        Type thisType = GetType();

        // 找到私有字段
        FieldInfo hiddenField = thisType.GetField("_hiddenValue", BindingFlags.NonPublic | BindingFlags.Instance);

        // 读取私有字段的值
        int currentValue = (int)hiddenField.GetValue(this);
        Debug.Log($"Current value of the hidden field: {currentValue}");

        // 修改私有字段的值
        hiddenField.SetValue(this, 24);
        Debug.Log($"New value of the hidden field after reflection update: {(_hiddenValue)}");
    }
}

实例3:通过反射调用方法

public class MyClass
{
    public void MyMethod(string message)
    {
        Debug.Log($"Called MyMethod with message: {message}");
    }
}

public class ReflectionMethodCall : MonoBehaviour
{
    void Start()
    {
        MyClass instance = new MyClass();

        // 获取类型及其方法
        Type myClassType = typeof(MyClass);
        MethodInfo methodInfo = myClassType.GetMethod("MyMethod");

        // 创建参数数组
        object[] parameters = new object[] { "Hello from reflection!" };

        // 动态调用方法
        methodInfo.Invoke(instance, parameters);
    }
}

实例4:反射遍历所有MonoBehaviour组件的方法

public class ReflectionComponentMethods : MonoBehaviour
{
    void Start()
    {
        Component[] components = GetComponents<MonoBehaviour>();

        foreach (Component component in components)
        {
            Type type = component.GetType();

            MethodInfo[] methods = type.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);

            foreach (MethodInfo method in methods)
            {
                Debug.Log($"Found method: {method.Name}");
            }
        }
    }
}

实例5:反射探针(Reflection Probes)

尽管名为“反射”,但Unity中的Reflection Probe实际是一种全局光照技术,用于捕捉场景周围的环境光照,并将其应用到对象表面以模拟真实世界的反射效果。以下是如何通过代码配置反射探针的一个简略示例:

public class ReflectionProbeSetup : MonoBehaviour
{
    public ReflectionProbe probe;

    void Start()
    {
        // 设置反射探针属性
        probe.mode = ReflectionProbeMode.Baked; // 设置为烘焙模式
        probe.timeSlicingMode = ReflectionProbeTimeSlicingMode.AllFramesIfStatic; // 静态对象每帧更新
        probe.refreshMode = ReflectionProbeRefreshMode.ViaScripting; // 通过脚本手动更新

        // 更新反射探针
        probe.RenderProbe();
    }
}

请注意,这里的“反射”并非.NET的反射机制,而是Unity中特定于渲染的技术术语。在Unity中,.NET反射主要应用于程序结构层面的运行时分析和操控,而反射探针是光照系统的一部分。

python推荐学习汇总连接:
50个开发必备的Python经典脚本(1-10)

50个开发必备的Python经典脚本(11-20)

50个开发必备的Python经典脚本(21-30)

50个开发必备的Python经典脚本(31-40)

50个开发必备的Python经典脚本(41-50)
————————————————

​最后我们放松一下眼睛
在这里插入图片描述

你可能感兴趣的:(unity,游戏引擎)