在ILRuntime中可能会需要继承协程,所以我们需要自己写一个协程适配器。
在ILRuntime文件夹内新建一个Adaptor文件夹,并在其中新建CoroutineAdaptor
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 using ILRuntime.CLR.Method;using ILRuntime.Runtime.Enviorment;using ILRuntime.Runtime.Intepreter;using System.Collections;using System.Collections.Generic;public class CoroutineAdaptor : CrossBindingAdaptor { static CrossBindingFunctionInfo<object > m_Current = new CrossBindingFunctionInfo<object >("Current" ); public override System.Type BaseCLRType => null ; public override System.Type AdaptorType => typeof (Adaptor); public override System.Type[] BaseCLRTypes => new System.Type[] {typeof (IEnumerator<object >) , typeof (IEnumerator) , typeof (System.IDisposable)}; public override object CreateCLRInstance (AppDomain appdomain, ILTypeInstance instance ) { return new Adaptor(appdomain,instance); } public class Adaptor : IEnumerator <object >, System.IDisposable , IEnumerator , CrossBindingAdaptorType { private AppDomain m_AppDomain; private ILTypeInstance m_ILTypeInstance; private IMethod m_GetCurrent; private IMethod m_DisposeMethod; private IMethod m_MoveNextMethod; private IMethod m_ResetMethod; private IMethod m_ToStringMethod; public Adaptor () { } public Adaptor (AppDomain appDomain,ILTypeInstance instance ) { m_AppDomain = appDomain; m_ILTypeInstance = instance; } public ILTypeInstance ILInstance { get { return m_ILTypeInstance; } } public object Current { get { if (m_GetCurrent == null ) { m_GetCurrent = m_ILTypeInstance.Type.GetMethod("get_Current" ,0 ); if (m_GetCurrent == null ) { m_GetCurrent = m_ILTypeInstance.Type.GetMethod("System.Collections.IEnumerator.get_Current" ,0 ); } } if (m_GetCurrent != null ) { object result = m_AppDomain.Invoke(m_GetCurrent, m_ILTypeInstance,null ); return result; } else { return null ; } } } public void Dispose () { if (m_DisposeMethod != null ) { m_AppDomain.Invoke(m_DisposeMethod,m_ILTypeInstance,null ); } else { m_DisposeMethod = m_ILTypeInstance.Type.GetMethod("Dispose" , 0 ); if (m_DisposeMethod == null ) { m_DisposeMethod = m_ILTypeInstance.Type.GetMethod("System.IDisposable.Dispose" , 0 ); } } } public bool MoveNext () { if (m_MoveNextMethod == null ) { m_MoveNextMethod = m_ILTypeInstance.Type.GetMethod("MoveNext" , 0 ); } if (m_MoveNextMethod != null ) { bool result = (bool )m_AppDomain.Invoke(m_MoveNextMethod,m_ILTypeInstance,null ); return result; } else { return false ; } } public void Reset () { if (m_ResetMethod != null ) { m_AppDomain.Invoke(m_ResetMethod,m_ILTypeInstance,null ); } else { m_ResetMethod = m_ILTypeInstance.Type.GetMethod ("Reset" , 0 ); } } public override string ToString () { if (m_ToStringMethod == null ) { m_ToStringMethod = m_AppDomain.ObjectType.GetMethod("ToString" , 0 ); } IMethod m = m_ILTypeInstance.Type.GetVirtualMethod(m_ToStringMethod); if (m != null || m is ILMethod) { return m_ILTypeInstance.ToString(); } else { return m_ILTypeInstance.Type.FullName; } } } }
协程适配器注册 先在ILRuntimeCLRBinding
中注册
1 2 3 4 5 6 static void InitILRuntime (AppDomain domain ){ domain.RegisterCrossBindingAdaptor(new InheritanceAdaptor()); domain.RegisterCrossBindingAdaptor(new CoroutineAdaptor()); }
点击ILRuntime/Generate CLR Binding Code by Analysis
重新生成绑定文件
然后再在ILRuntimeManager
里面注册
1 2 3 4 5 6 7 8 9 10 void InitializeILRuntime () { m_AppDomain.RegisterCrossBindingAdaptor(new InheritanceAdaptor()); m_AppDomain.RegisterCrossBindingAdaptor(new CoroutineAdaptor()); ILRuntime.Runtime.Generated.CLRBindings.Initialize(m_AppDomain); }
协程测试 在HotFix工程中添加TestCoroutine
文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 using UnityEngine;namespace HotFix { public class TestCoroutine { public static void RunTest () { GameStart.Instance.StartCoroutine(MyCoroutine()); } static System.Collections.IEnumerator MyCoroutine () { Debug.Log("协程开始:" + Time.time); yield return new WaitForSeconds (2 ) ; Debug.Log("协程结束" + Time.time); } } }
然后再在ILRuntimeManager
的OnHotFixLoaded
中执行
1 2 3 4 void OnHotFixLoaded () { m_AppDomain.Invoke("HotFix.TestCoroutine" ,"RunTest" ,null ,null ); }