{"id":1334,"date":"2022-07-04T14:47:28","date_gmt":"2022-07-04T06:47:28","guid":{"rendered":"https:\/\/www.mapleriver.cn\/?p=1334"},"modified":"2022-07-04T14:47:28","modified_gmt":"2022-07-04T06:47:28","slug":"unity-%e5%8a%a8%e6%80%81%e7%bc%96%e8%af%91","status":"publish","type":"post","link":"https:\/\/www.mapleriver.cn\/?p=1334","title":{"rendered":"Unity \u52a8\u6001\u7f16\u8bd1"},"content":{"rendered":"<p>&emsp;\u00a0&emsp;\u4f17\u6240\u5468\u77e5\uff0c\u5728Unity\u4e2d\u6bcf\u6b21\u6211\u4eec\u4fee\u6539C#\u4ee3\u7801\u540e\uff0cUnity\u90fd\u8981\u8f6c\u4e00\u4f1a\u83ca\u82b1\uff0c\u800c\u8f6c\u83ca\u82b1\u7684\u76ee\u7684\u5c31\u662f\u628a\u65b0\u7684\u4ee3\u7801\u91cd\u65b0\u7f16\u8bd1\u6210dll\u3002<br \/>\n&emsp;\u00a0&emsp;\u800c\u4e14\u5728Unity\u4e2d\u5176\u5b9e\u6709\u4e00\u4e2a\u8fd0\u884c\u65f6\u7f16\u8bd1dll\u7684\u9009\u9879\uff0c\u5728preferences\u5185\uff0c\u4f46\u662f\u8fd9\u4e2a\u9009\u9879\u4ecd\u7136\u4e0d\u80fd\u5b8c\u5168\u6ee1\u8db3\u6211\u4eec\u7684\u9700\u6c42\uff0c\u56e0\u4e3a\u4ed6\u8fd8\u662f\u8981\u8f6c\u83ca\u82b1\uff0c\u800c\u4e14\u5982\u679c\u811a\u672c\u4fee\u6539\u4e86\u5f53\u524d\u4f7f\u7528\u7684\u7269\u4f53\uff0c\u6781\u5927\u6982\u7387\u4f1a\u62a5\u9519999+\u7684~<br \/>\n<a href=\"https:\/\/www.mapleriver.cn\/wp-content\/uploads\/2022\/07\/unitySetting.png\"><img decoding=\"async\" src=\"https:\/\/www.mapleriver.cn\/wp-content\/uploads\/2022\/07\/unitySetting.png\" alt=\"\" \/><\/a><\/p>\n<h4>1.CodeDomProvider\u4e0e\u52a8\u6001\u7f16\u8bd1<\/h4>\n<p>&emsp;\u00a0&emsp;CodeDomProvider\u53ef\u4ee5\u5e2e\u6211\u4eec\u52a8\u6001\u7f16\u8bd1dll\uff0c\u800c\u8fd9\u4e2a\u7c7b\u4f7f\u7528\u8d77\u6765\u4e5f\u5f88\u7b80\u5355\uff1a<a href=\"http:\/\/t.zoukankan.com\/mantian-p-2886644.html\">\u8fd9\u91cc<\/a>\u63d0\u4f9b\u4e86\u4e00\u4e2a\u7b80\u5355\u7684\u4f8b\u5b50\u3002<\/p>\n<pre><code class=\"language-C#\">\/\/ \u8bbe\u5b9a\u7f16\u8bd1\u53c2\u6570,DLL\u4ee3\u8868\u9700\u8981\u5f15\u5165\u7684Assemblies\nCompilerParameters cplist = new CompilerParameters();\ncplist.GenerateExecutable = false;\n\/\/ \u751f\u6210\u540e\u76f4\u63a5\u52a0\u8f7d\u5230\u5185\u5b58\u4e2d\ncplist.GenerateInMemory = true;\n\/\/ \u6dfb\u52a0\u5176\u4ed6\u7a0b\u5e8f\u96c6\u7684\u5f15\u7528\ncplist.ReferencedAssemblies.Add(&quot;System.dll&quot;);\ncplist.ReferencedAssemblies.Add(&quot;System.XML.dll&quot;);\ncplist.ReferencedAssemblies.Add(&quot;System.Data.dll&quot;);\n\n\/\/ \u7f16\u8bd1\u4ee3\u7406\u7c7b\uff0cC# CSharp\u90fd\u53ef\u4ee5\nCodeDomProvider provider1 = CodeDomProvider.CreateProvider(&quot;CSharp&quot;);\n\n\/\/ \u6587\u4ef6\u6570\u7ec4\uff0c\u6211\u53ea\u9700\u8981\u4e00\u4e2afile\nstring[] sources = new string[1];\nsources[0]=@&quot;d:\\TableModel.cs&quot;;\n\n\/\/ \u5f00\u59cb\u7f16\u8bd1\u54af\uff01\u4ece\u6587\u4ef6\u7f16\u8bd1\uff01\u56e0\u4e3a\u4e0a\u9762\u6211\u4eec\u4f20\u7684\u6587\u4ef6\u561b\nCompilerResults cr = provider1.CompileAssemblyFromFile(cplist, sources);\nif (true == cr.Errors.HasErrors)\n{\n    System.Text.StringBuilder sb = new System.Text.StringBuilder();\n    foreach (System.CodeDom.Compiler.CompilerError ce in cr.Errors)\n    {\n        sb.Append(ce.ToString());\n        sb.Append(System.Environment.NewLine);\n    }\n    throw new Exception(sb.ToString());\n}\n\n\/\/ \u83b7\u5f97\u7c7b\u7684Type, \u5982\u679c\u8981\u751f\u6210\u5b9e\u4f8b\uff0c\u9700\u8981\u8c03\u7528assembly.CreateInstance\nSystem.Reflection.Assembly assembly = cr.CompiledAssembly;\nType t = assembly.GetType(@namespace + &quot;.&quot; + &quot;TableModel&quot;, true, true);<\/code><\/pre>\n<p>&emsp;\u00a0&emsp;\u4ece\u4e0a\u9762\u7684\u4ee3\u7801\u4e2d\u6211\u4eec\u53ef\u4ee5\u770b\u51fa\u6765\uff0c\u6574\u4e2a\u7684\u7f16\u8bd1\u6d41\u7a0b\u5176\u5b9e\u53ea\u6d89\u53ca\u4e09\u4e2a\u7c7b\u578b\uff1aCodeDomProvider\u3001CompilerParameters\u548cCompilerResults\u3002\u5176\u4e2d\uff1a<\/p>\n<ul>\n<li>CodeDomProvider\u4e3a\u7f16\u8bd1\u4ee3\u7406\u7c7b\uff0c\u5176\u5b9e\u5c31\u662f\u8fd9\u4e2a\u7c7b\u578b\u8d1f\u8d23\u7f16\u8bd1~<\/li>\n<li>CompilerParameters\u4e3a\u7f16\u8bd1\u65f6\u9700\u8981\u7684\u53c2\u6570\uff0c\u5305\u62ec\u4e86\u8fd9\u4e2a\u7c7b\u578b\u9700\u8981\u4f9d\u8d56\u54ea\u4e9b\u5176\u4ed6\u7a0b\u5e8f\u96c6\uff0c\u662f\u5426\u52a0\u8f7d\u5230\u5185\u5b58\u7b49\u3002<\/li>\n<li>CompilerResults\u4e3a\u6700\u7ec8\u7f16\u8bd1\u540e\u7684\u7ed3\u679c<\/li>\n<\/ul>\n<h4>2.Unity\u4e0e\u52a8\u6001\u7f16\u8bd1<\/h4>\n<p>&emsp;\u00a0&emsp;\u4e0a\u9762\u52a8\u6001\u7f16\u8bd1\u7684\u5927\u6982\u6d41\u7a0b\u6211\u4eec\u5df2\u7ecf\u4e86\u89e3\u4e86\uff0c\u90a3\u4e48\u5728Unity\u5185\u5982\u4f55\u8fdb\u884c\u52a8\u6001\u7f16\u8bd1\u5462\uff1f\u6bd5\u7adf\u4e0a\u9762\u5728\u7f16\u8bd1\u65f6\u5df2\u7ecf\u77e5\u9053\u65b0\u7684\u7a0b\u5e8f\u96c6\u4f9d\u8d56\u4e86\u54ea\u4e9b\u7a0b\u5e8f\u96c6\u3002<br \/>\n&emsp;\u00a0&emsp;\u4e0d\u8fc7\u65e9\u5c31\u6709\u5927\u4f6c\u5df2\u7ecf\u5b9e\u73b0\u4e86\uff1a<a href=\"https:\/\/www.shuzhiduo.com\/A\/E35p0m1L5v\/\">Unity\u52a8\u6001\u7f16\u8bd1<\/a><br \/>\n&emsp;\u00a0&emsp;\u6548\u679c\uff1a<br \/>\n<div class=\"wp-gp-pp-container\" style=\"width: 996px; height: 388px\" data-width=\"996\" data-height=\"388\" data-media-id=\"1336\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.mapleriver.cn\/wp-content\/uploads\/2022\/07\/DynamicCompile_gif_thumbnail.jpeg\" id=\"wp-gp-pp--id-1336--thumbnail\" class=\"wp-gp-pp-gif-thumbnail\" width=\"996\" height=\"388\" alt=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"\" id=\"wp-gp-pp--id-13361289873559\" class=\"wp-gp-pp-gif\" width=\"996\" height=\"388\" alt=\"\"><div class=\"wp-gp-pp-overlay\"> <div class=\"wp-gp-pp-play-button\">GIF<\/div> <\/div> <\/div><br \/>\n&emsp;\u00a0&emsp;\u800c\u4e14\u5077\u5b8c\u4ee3\u7801\u53d1\u73b0\u53ef\u4ee5\u76f4\u63a5\u7528~\u4e0d\u8fc7\u8fd8\u662f\u8e29\u5230\u4e86\u51e0\u4e2a\u5751\uff1a<\/p>\n<pre><code class=\"language-C#\">if (_compileParams == null)\n{\n    _compileParams = new CompilerParameters();\n    \/\/ Add ALL of the assembly references\n    foreach (var assembly in \nAppDomain.CurrentDomain.GetAssemblies().Where(a=&gt;!a.IsDynamic))\n    {\n        _compileParams.ReferencedAssemblies.Add(assembly.Location);\n    }\n    _compileParams.GenerateExecutable = false;\n    _compileParams.GenerateInMemory = true;\n}<\/code><\/pre>\n<p>&emsp;\u00a0&emsp;\u5728\u83b7\u53d6\u4f9d\u8d56\u7684\u7a0b\u5e8f\u96c6\u65f6\uff1a<code>AppDomain.CurrentDomain.GetAssemblies()<\/code>\uff0c\u8fd9\u91cc\u83b7\u53d6\u5230\u7684\u7a0b\u5e8f\u96c6\u5305\u542b\u4e86\u5176\u4ed6\u7684\u52a8\u6001\u7a0b\u5e8f\u96c6\uff0c\u800c\u52a8\u6001\u7a0b\u5e8f\u96c6\u662f\u65e0\u6cd5\u4f9d\u8d56\u5176\u4ed6\u52a8\u6001\u7a0b\u5e8f\u96c6\u7684\uff0c\u5426\u5219\u4f1a\u62a5\u9519\uff1a<code>The invoked member is not supported in a dynamic module.<\/code><br \/>\n&emsp;\u00a0&emsp;\u6240\u4ee5\u5728\u6e90\u4ee3\u7801\u4e2d\u7528Linq\u6e05\u7406\u4e86\u4e00\u4e0b\u52a8\u6001\u7a0b\u5e8f\u96c6~<br \/>\n&emsp;\u00a0&emsp;\u6b64\u5916\u6e90\u4ee3\u7801\u4e2d\u5c06\u7a0b\u5e8f\u96c6\u751f\u6210\u5230\u4e86temp\u6587\u4ef6\u5939\u4e0b\uff0c\u5e76\u6ca1\u6709\u76f4\u63a5\u52a0\u8f7d\u5230\u5185\u5b58\u4e2d\u3002\u6240\u4ee5\u8fd8\u8981\u540e\u9762loaddll\uff0c\u4f46\u662f\u6211\u5acc\u9ebb\u70e6\u76f4\u63a5\u52a0\u5230\u5185\u5b58\u4e86~<code>_compileParams.GenerateInMemory = true;<\/code><br \/>\n&emsp;\u00a0&emsp;\u5b8c\u6574\u4ee3\u7801\uff1a<br \/>\nDynamicCodeHelper:<\/p>\n<pre><code class=\"language-C#\">using Microsoft.CSharp;\nusing System;\nusing System.CodeDom.Compiler;\nusing System.Linq;\nusing System.Reflection;\nusing System.Text;\nusing UnityEngine;\npublic class DynamicCodeHelper\n{\n\u00a0 \u00a0 private CSharpCodeProvider _provider;\n\u00a0 \u00a0 private CSharpCodeProvider Provider\n\u00a0 \u00a0 {\n\u00a0 \u00a0 \u00a0 \u00a0 get\n\u00a0 \u00a0 \u00a0 \u00a0 {\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 if (_provider == null)\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 {\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 _provider = new CSharpCodeProvider();\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 }\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 return _provider;\n\u00a0 \u00a0 \u00a0 \u00a0 }\n\u00a0 \u00a0 }\n\u00a0 \u00a0 private CompilerParameters _compileParams;\n\u00a0 \u00a0 private CompilerParameters CompileParams\n\u00a0 \u00a0 {\n\u00a0 \u00a0 \u00a0 \u00a0 get\n\u00a0 \u00a0 \u00a0 \u00a0 {\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 if (_compileParams == null)\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 {\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 _compileParams = new CompilerParameters();\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \/\/ Add ALL of the assembly references\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies().Where(a=&gt;!a.IsDynamic))\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 {\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 _compileParams.ReferencedAssemblies.Add(assembly.Location);\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 }\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 _compileParams.GenerateExecutable = false;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 _compileParams.GenerateInMemory = true;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 }\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 _compileParams.OutputAssembly = DynamicCodeWindow.OUTPUT_DLL_DIR + &quot;\/DynamicCodeTemp&quot; + Time.realtimeSinceStartup + &quot;.dll&quot;;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 return _compileParams;\n\u00a0 \u00a0 \u00a0 \u00a0 }\n\u00a0 \u00a0 }\n\u00a0 \u00a0 public void ExcuteDynamicCode(string codeStr, bool isUseTextAsAllContent)\n\u00a0 \u00a0 {\n\u00a0 \u00a0 \u00a0 \u00a0 if (codeStr == null) codeStr = &quot;&quot;;\n\u00a0 \u00a0 \u00a0 \u00a0 string generatedCode;\n\u00a0 \u00a0 \u00a0 \u00a0 if (isUseTextAsAllContent)\n\u00a0 \u00a0 \u00a0 \u00a0 {\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 generatedCode = codeStr;\n\u00a0 \u00a0 \u00a0 \u00a0 }\n\u00a0 \u00a0 \u00a0 \u00a0 else\n\u00a0 \u00a0 \u00a0 \u00a0 {\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 generatedCode = GenerateCode(codeStr);\n\u00a0 \u00a0 \u00a0 \u00a0 }\n\u00a0 \u00a0 \u00a0 \u00a0 Debug.Log(&quot;[DynamicCode] Compile Start: &quot; + generatedCode);\n\u00a0 \u00a0 \u00a0 \u00a0 CompilerResults compileResults = Provider.CompileAssemblyFromSource(CompileParams, generatedCode);\n\u00a0 \u00a0 \u00a0 \u00a0 if (compileResults.Errors.HasErrors)\n\u00a0 \u00a0 \u00a0 \u00a0 {\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 Debug.LogError(&quot;[DynamicCode] \u7f16\u8bd1\u9519\u8bef\uff01&quot;);\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 var msg = new StringBuilder();\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 foreach (CompilerError error in compileResults.Errors)\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 {\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 msg.AppendFormat(&quot;Error ({0}): {1}\\n&quot;,\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 error.ErrorNumber, error.ErrorText);\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 }\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 throw new Exception(msg.ToString());\n\u00a0 \u00a0 \u00a0 \u00a0 }\n\u00a0 \u00a0 \u00a0 \u00a0 \/\/ \u901a\u8fc7\u53cd\u5c04\uff0c\u8c03\u7528DynamicCode\u7684\u5b9e\u4f8b\n\u00a0 \u00a0 \u00a0 \u00a0 \/\/AppDomain a = AppDomain.CreateDomain(AppDomain.CurrentDomain.FriendlyName);\n\u00a0 \u00a0 \u00a0 \u00a0 Assembly objAssembly = compileResults.CompiledAssembly;\n\u00a0 \u00a0 \u00a0 \u00a0 DynamicCodeWindow.ColorDebug(&quot;[DynamicCode] Gen Dll FullName: &quot; + objAssembly.FullName);\n\u00a0 \u00a0 \u00a0 \u00a0 DynamicCodeWindow.ColorDebug(&quot;[DynamicCode] Gen Dll Location: &quot; + objAssembly.Location);\n\u00a0 \u00a0 \u00a0 \u00a0 DynamicCodeWindow.ColorDebug(&quot;[DynamicCode] PathToAssembly: &quot; + compileResults.PathToAssembly);\n\u00a0 \u00a0 \u00a0 \u00a0 object objDynamicCode = objAssembly.CreateInstance(&quot;DynamicCode&quot;);\n\u00a0 \u00a0 \u00a0 \u00a0 MethodInfo objMI = objDynamicCode.GetType().GetMethod(&quot;CodeExecute&quot;);\n\u00a0 \u00a0 \u00a0 \u00a0 objMI.Invoke(objDynamicCode, null);\n\u00a0 \u00a0 }\n\u00a0 \u00a0 private string GenerateCode(string methodCode)\n\u00a0 \u00a0 {\n\u00a0 \u00a0 \u00a0 \u00a0 StringBuilder sb = new StringBuilder();\n\u00a0 \u00a0 \u00a0 \u00a0 sb.Append(@&quot;using System;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 using UnityEngine;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 public class DynamicCode {\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 public void CodeExecute() {\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 &quot;);\n\u00a0 \u00a0 \u00a0 \u00a0 sb.Append(methodCode);\n\u00a0 \u00a0 \u00a0 \u00a0 sb.Append(&quot;}}&quot;);\n\u00a0 \u00a0 \u00a0 \u00a0 string code = sb.ToString();\n\u00a0 \u00a0 \u00a0 \u00a0 return code;\n\u00a0 \u00a0 }\n}<\/code><\/pre>\n<p>DynamicCodeWindow:<\/p>\n<pre><code class=\"language-C#\">#if UNITY_EDITOR_WIN\nusing UnityEditor;\nusing UnityEngine;\n\/\/\/ &lt;summary&gt;\n\/\/\/ \u5b57\u7b26\u4e32\u7f16\u8bd1\u6210DLL\u8f7d\u5165\uff0c\u53ea\u5728\u7f16\u8f91\u5668\u4e2d\u4f7f\u7528\n\/\/\/ &lt;\/summary&gt;\npublic class DynamicCodeWindow : EditorWindow\n{\n\u00a0 \u00a0 \/\/ \u751f\u6210\u5728 ..\\Client\\Client\\Temp\\DynamicCode\\DynamicCodeTemp.dll\n\u00a0 \u00a0 public const string OUTPUT_DLL_DIR = @&quot;Temp\\DynamicCode&quot;;\n\u00a0 \u00a0 [MenuItem(&quot;TestTool\/DynamicRun&quot;)]\n\u00a0 \u00a0 private static void Open()\n\u00a0 \u00a0 {\n\u00a0 \u00a0 \u00a0 \u00a0 GetWindow&lt;DynamicCodeWindow&gt;();\n\u00a0 \u00a0 }\n\u00a0 \u00a0 private static DynamicCodeHelper _instance;\n\u00a0 \u00a0 private static DynamicCodeHelper Helper\n\u00a0 \u00a0 {\n\u00a0 \u00a0 \u00a0 \u00a0 get\n\u00a0 \u00a0 \u00a0 \u00a0 {\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 if (_instance == null)\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 {\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 _instance = new DynamicCodeHelper();\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 }\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 return _instance;\n\u00a0 \u00a0 \u00a0 \u00a0 }\n\u00a0 \u00a0 }\n\u00a0 \u00a0 private bool isUseTextAsAllContent;\n\u00a0 \u00a0 private string content = @&quot;Debug.Log(&quot;&quot;Hello&quot;&quot;);&quot;;\n\u00a0 \u00a0 private void OnGUI()\n\u00a0 \u00a0 {\n\u00a0 \u00a0 \u00a0 \u00a0 isUseTextAsAllContent = EditorGUILayout.ToggleLeft(&quot;\u5b8c\u5168\u4f7f\u7528\u6587\u672c\u4f5c\u4e3a\u7f16\u8bd1\u5185\u5bb9\uff08\u624b\u52a8\u6dfb\u52a0using\u7b49\uff09&quot;, isUseTextAsAllContent);\n\u00a0 \u00a0 \u00a0 \u00a0 content = EditorGUILayout.TextArea(content, GUILayout.Height(200));\n\u00a0 \u00a0 \u00a0 \u00a0 if (GUILayout.Button(&quot;\u6267\u884c\u4ee3\u7801&quot;))\n\u00a0 \u00a0 \u00a0 \u00a0 {\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 Run(content, isUseTextAsAllContent);\n\u00a0 \u00a0 \u00a0 \u00a0 }\n\u00a0 \u00a0 \u00a0 \u00a0 if (GUILayout.Button(&quot;\u91cd\u7f6e\u5185\u5bb9&quot;))\n\u00a0 \u00a0 \u00a0 \u00a0 {\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 if (isUseTextAsAllContent)\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 {\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 content = @&quot;using System;\nusing UnityEngine;\npublic class DynamicCode {\n\u00a0 \u00a0 public void CodeExecute() {\n\u00a0 \u00a0 \u00a0 \u00a0 Debug.Log(&quot;&quot;Hello&quot;&quot;);\n\u00a0 \u00a0 }\n}&quot;;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 }\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 else\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 {\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 content = @&quot;Debug.Log(&quot;&quot;Hello&quot;&quot;);&quot;;\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 }\n\u00a0 \u00a0 \u00a0 \u00a0 }\n\u00a0 \u00a0 \u00a0 \u00a0 if (GUILayout.Button(&quot;\u65b0\u5efa\/\u6253\u5f00\u7f13\u5b58\u76ee\u5f55&quot;))\n\u00a0 \u00a0 \u00a0 \u00a0 {\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 if (!System.IO.Directory.Exists(OUTPUT_DLL_DIR))\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 {\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 System.IO.Directory.CreateDirectory(OUTPUT_DLL_DIR);\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 }\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 System.Diagnostics.Process.Start(OUTPUT_DLL_DIR);\n\u00a0 \u00a0 \u00a0 \u00a0 }\n\u00a0 \u00a0 }\n\u00a0 \u00a0 private static void Run(string code, bool isUseTextAsAllContent)\n\u00a0 \u00a0 {\n\u00a0 \u00a0 \u00a0 \u00a0 ColorDebug(&quot;[DynamicCode] Start......&quot;);\n\u00a0 \u00a0 \u00a0 \u00a0 string codetmp = code;\n\u00a0 \u00a0 \u00a0 \u00a0 Helper.ExcuteDynamicCode(codetmp, isUseTextAsAllContent);\n\u00a0 \u00a0 \u00a0 \u00a0 ColorDebug(&quot;[DynamicCode] End......&quot;);\n\u00a0 \u00a0 }\n\u00a0 \u00a0 public static void ColorDebug(string content)\n\u00a0 \u00a0 {\n\u00a0 \u00a0 \u00a0 \u00a0 Debug.Log(string.Format(&quot;&lt;color=#ff8400&gt;{0}&lt;\/color&gt;&quot;, content));\n\u00a0 \u00a0 }\n}\n#endif<\/code><\/pre>\n<h4>3.\u52a8\u6001\u7f16\u8bd1+Unity Hooker<\/h4>\n<p>&emsp;\u00a0&emsp;\u5176\u5b9e\u52a8\u6001\u7f16\u8bd1\u5230\u8fd9\u5df2\u7ecf\u5dee\u4e0d\u591a\u53ef\u4ee5\u7ed3\u675f\u4e86\uff0c\u4f46\u662f\u6211\u4eec\u4e4b\u524d\u8fd8\u7814\u7a76\u8fc7\u4e00\u4e0b\u4e0b<a href=\"https:\/\/www.mapleriver.cn\/?p=551\">UnityHooker<\/a>\u3002\u90a3\u4e48\u6211\u4eec\u80fd\u4e0d\u80fd\u628a\u8fd9\u4e24\u4e2a\u4e1c\u897f\u7ed3\u5408\u4e00\u4e0b\u5462\uff1f<br \/>\n&emsp;\u00a0&emsp;\u6211\u4eec\u8c03\u8bd5\u7684\u65f6\u5019\u7ecf\u5e38\u4f1a\u6709\u903b\u8f91\u5341\u5206\u590d\u6742\uff0c\u4f46\u662f\u53c8\u4e0d\u77e5\u9053\u662f\u4ec0\u4e48\u903b\u8f91\u5bfc\u81f4\u7684\u4e00\u4e9b\u6bd4\u5982GameObject\u4e0d\u77e5\u9053\u88ab\u8c01\u7ed9\u6fc0\u6d3b\/\u9690\u85cf\u4e86\u3002\u90a3\u4e48\u6211\u4eec\u7684\u52a8\u6001\u7f16\u8bd1\u4e0eHooker\u5c31\u53ef\u4ee5\u5927\u663e\u8eab\u624b\u4e86\uff01<br \/>\n<div class=\"wp-gp-pp-container\" style=\"width: 874px; height: 608px\" data-width=\"874\" data-height=\"608\" data-media-id=\"1338\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.mapleriver.cn\/wp-content\/uploads\/2022\/07\/DynamicHook_gif_thumbnail.jpeg\" id=\"wp-gp-pp--id-1338--thumbnail\" class=\"wp-gp-pp-gif-thumbnail\" width=\"874\" height=\"608\" alt=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"\" id=\"wp-gp-pp--id-13381555387657\" class=\"wp-gp-pp-gif\" width=\"874\" height=\"608\" alt=\"\"><div class=\"wp-gp-pp-overlay\"> <div class=\"wp-gp-pp-play-button\">GIF<\/div> <\/div> <\/div><br \/>\n&emsp;\u00a0&emsp;\u5c31\u50cf\u4e0a\u56fe\u4e00\u6837\uff0c\u6709\u4e00\u6bb5\u83ab\u540d\u5176\u5999\u7684\u903b\u8f91\u4e00\u76f4\u5728\u5f00\u5173\u67d0\u4e2a\u9884\u5236\u4f53\uff08\u5f53\u7136\u662f\u6211\u968f\u4fbf\u5199\u7684\uff01\uff09\uff0c\u4f46\u662f\u6211\u4eec\u53c8\u4e00\u65f6\u4e4b\u95f4\u627e\u4e0d\u5230\u5bf9\u5e94\u903b\u8f91\u5728\u54ea\uff0c\u6216\u8005\u8bf4\u60f3\u5728SetActive\u7684\u65f6\u5019\u63d2\u5165\u4e00\u6bb5\u903b\u8f91\u3002\u90a3\u4e48\u53ea\u8981\u628a\u6211\u4eec\u5728\u4e00\u8fb9\u5199\u597d\u7684Hook\u903b\u8f91\uff08\u5f53\u7136\u662f\u7f16\u8f91\u5668\u91cc\u5199\u597d\u7684\u590d\u5236\u8fc7\u6765\u7684\uff09\u903b\u8f91\u52a8\u6001\u7f16\u8bd1\u8fdb\u6765\uff0c\u5c31\u53ef\u4ee5\u52a8\u6001\u7684\u6dfb\u52a0\u4ee3\u7801\uff0c\u8c03\u8bd5\u4ee3\u7801\u4e86\uff01<\/p>\n<pre><code class=\"language-C#\">\/*\n * \u5bf9 GameObject.SetActive \u8fdb\u884chook\u7684\u6d4b\u8bd5\u7528\u4f8b\n *\/\nusing System;\nusing System.Reflection;\nusing UnityEngine;\nusing Hook;\n\n\/\/[InitializeOnLoad]\npublic class DynamicCode\n{\n    private static MethodHook _hook;\n\n    public void CodeExecute()\n    {\n        if (_hook == null)\n        {\n            Type type = typeof(GameObject).Assembly.GetType(&quot;UnityEngine.GameObject&quot;);\n\n            MethodInfo miTarget = type.GetMethod(&quot;SetActive&quot;, BindingFlags.Instance | BindingFlags.Public);\n\n            type = typeof(DynamicCode);\n            MethodInfo miReplacement = type.GetMethod(&quot;SetActiveNew&quot;, BindingFlags.Static | BindingFlags.NonPublic);\n            MethodInfo miProxy = type.GetMethod(&quot;SetActiveProxy&quot;, BindingFlags.Static | BindingFlags.NonPublic);\n\n            _hook = new MethodHook(miTarget, miReplacement, miProxy);\n\n            Debug.Log(&quot;Hooked&quot;);\n            _hook.Install();\n        }\n    }\n\n    private static void SetActiveNew(GameObject go, bool value)\n    {\n        SetActiveProxy(go, value);\n        Debug.LogFormat(&quot;[Hooked] [{0}] SetActive {1}&quot;, go.name, value);\n    }\n\n    private static void SetActiveProxy(GameObject go, bool value)\n    {\n        \/\/ dummy\n    }\n}<\/code><\/pre>\n<p>&emsp;\u00a0&emsp;Hook\u7684\u903b\u8f91\u4e5f\u5f88\u7b80\u5355\uff0c\u4e4b\u524d\u4e5f\u6709\u4ecb\u7ecd\u8fc7\u4e86\uff0c\u5c31\u662f\u4f7f\u7528\u4e24\u4e2a\u51fd\u6570\u66ff\u6362\u539f\u6709\u51fd\u6570\u5730\u5740\u3002\u53ea\u4e0d\u8fc7\u524d\u9762\u7684\u52a8\u6001\u7f16\u8bd1\u4ee3\u7801\u4e2d\u9650\u5b9a\u4e86\u7c7b\u540d\u548c\u6267\u884c\u7684\u51fd\u6570\u540d\uff0c\u8fd9\u91cc\u628a\u5bf9\u5e94\u7684\u51fd\u6570\u66ff\u6362\u4e86\u4e00\u4e0b\u5c31\u53ef\u4ee5\u7528\u4e86~<\/p>\n","protected":false},"excerpt":{"rendered":"<p>&emsp;\u00a0&emsp;\u4f17\u6240\u5468\u77e5\uff0c\u5728Unity\u4e2d\u6bcf\u6b21\u6211\u4eec\u4fee\u6539C#\u4ee3\u7801\u540e\uff0cUnity\u90fd\u8981\u8f6c\u4e00\u4f1a\u83ca\u82b1\uff0c\u800c\u8f6c\u83ca\u82b1\u7684 [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[34],"tags":[],"class_list":["post-1334","post","type-post","status-publish","format-standard","hentry","category-unity-editor"],"_links":{"self":[{"href":"https:\/\/www.mapleriver.cn\/index.php?rest_route=\/wp\/v2\/posts\/1334","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.mapleriver.cn\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.mapleriver.cn\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.mapleriver.cn\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.mapleriver.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1334"}],"version-history":[{"count":2,"href":"https:\/\/www.mapleriver.cn\/index.php?rest_route=\/wp\/v2\/posts\/1334\/revisions"}],"predecessor-version":[{"id":1341,"href":"https:\/\/www.mapleriver.cn\/index.php?rest_route=\/wp\/v2\/posts\/1334\/revisions\/1341"}],"wp:attachment":[{"href":"https:\/\/www.mapleriver.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1334"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.mapleriver.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1334"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.mapleriver.cn\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1334"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}