Question by
hurjm1006 · Apr 07, 2021 at 02:47 AM ·
scripting problemassembly
Mono.Cecil not apply script after first play
I'm first at Mono.Cecil using for injection ui code.
So I got a probelm. It works fine when first start editor.
But when I try to change script which one inherit Monobehavior after first play in editor, it's not apply at all.
In ILspy the codes are change properly and when I restart editor that changes apply.
I have no idea how to do it.
PLZ HELP ME!!!!
Here is my weaving code.
public static class UIWeaver
{
[InitializeOnLoadMethod]
public static void OnInitializeOnLoadMethod()
{
CompilationPipeline.assemblyCompilationFinished += OnCompilationFinished;
// We only need to run this once per session
// after that, all assemblies will be weaved by the event
if (!SessionState.GetBool("UIBINDER_WEAVED", false))
{
// reset session flag
SessionState.SetBool("UIBINDER_WEAVED", true);
WeaveExistingAssemblies();
}
}
public static void WeaveExistingAssemblies()
{
foreach (UnityAssembly assembly in CompilationPipeline.GetAssemblies())
{
if (File.Exists(assembly.outputPath))
{
OnCompilationFinished(assembly.outputPath, new CompilerMessage[0]);
}
}
#if UNITY_2019_3_OR_NEWER
EditorUtility.RequestScriptReload();
#else
UnityEditorInternal.InternalEditorUtility.RequestScriptReload();
#endif
}
private static void OnCompilationFinished(string assemblyPath, CompilerMessage[] messages)
{
Stopwatch sw = new Stopwatch();
sw.Start();
List<Type> derivedTypes = new List<Type>();
List<PropertyDefinition> properties = new List<PropertyDefinition>();
bool isModified = false;
#region Cecil
AssemblyDefinition currentAssembly = AssemblyDefinition.ReadAssembly(assemblyPath, new ReaderParameters { ReadWrite = true, ReadSymbols = true });
{
ModuleDefinition mainModule = currentAssembly.MainModule;
var p = currentAssembly.MainModule.Types.Where(o => o.IsClass).SelectMany(t => t.Properties);
if (p != null)
properties.AddRange(p);
foreach (PropertyDefinition pd in properties)
{
CustomAttribute attr = pd.CustomAttributes.SingleOrDefault(i => i.AttributeType.Name == nameof(UIBindable));
if (attr != null)
{
Mono.Cecil.Cil.MethodBody body = pd.SetMethod.Body;
ILProcessor processor = body.GetILProcessor();
var instructions = body.Instructions;
var targetInst = instructions.First();
processor.InsertBefore(targetInst, processor.Create(OpCodes.Nop));
processor.InsertBefore(targetInst, processor.Create(OpCodes.Ldarg_0));
processor.InsertBefore(targetInst, processor.Create(OpCodes.Ldstr, pd.Name));
processor.InsertBefore(targetInst, processor.Create(OpCodes.Ldarg_1));
Type gt;
switch (pd.PropertyType.MetadataType)
{
case MetadataType.Single:
{
gt = typeof(UIBindProxy<float>);
break;
}
case MetadataType.String:
{
gt = typeof(UIBindProxy<string>);
break;
}
case MetadataType.Int32:
{
gt = typeof(UIBindProxy<int>);
break;
}
default:
{
UnityDebug.LogError("Missing type " + pd.PropertyType.MetadataType);
continue;
}
}
MethodInfo gm = gt.GetMethod("UpdateValue");
MethodReference gr = mainModule.ImportReference(gm);
processor.InsertBefore(targetInst, processor.Create(OpCodes.Call, gr));
isModified = true;
}
}
if (isModified)
{
currentAssembly.Write(new WriterParameters { WriteSymbols = true });
}
}
#endregion
UnityEngine.Debug.Log("UI Weaving time: " + sw.ElapsedMilliseconds);
sw.Stop();
}
}
Comment
Your answer
![](https://koobas.hobune.stream/wayback/20220613031906im_/https://answers.unity.com/themes/thub/images/avi.jpg)