记录使用注入的方式为Unity编辑器实现扩展能力

这篇具有很好参考价值的文章主要介绍了记录使用注入的方式为Unity编辑器实现扩展能力。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

使用场景

  1. 当前项目编辑器中不方便存放或者提交扩展代码
  2. 相同的扩展功能需要在多个项目(编辑器)中使用
  3. 项目开发中,偶尔临时需要使用一个功能,想随时使用随时卸载

设计思路

  1. 使用进程注入,将一个c/c++ dll注入到当前运行的unity编辑器中
  2. 使用c/c++ dll调用mono的函数接口,比如mono_get_root_domain去获取unity的domain动态去加载想要加载的外部的扩展c# dll
  3. 在扩展c# dll中调用 EditorUtility.RequestScriptReload();来触发unity编辑器的重新编译,重载编辑器中的domain实现卸载外部c# dll的功能
  4. 在扩展c# dll中绑定EditorApplication.update事件,用来处理主线程的操作,比如AssetDatabase.Refresh();
  5. 使用jsonrpc协议,用来调用c# dll中的部分封装功能函数,可以实现在unity编辑器直接展示扩展窗口,或者将数据传至其他编辑器进行展示

初步实现

  1. 进程注入c/c++ dll
//远程进程插入dll bypid
bool DllInject::nsertDllToProcessByPid(DWORD Pid, const char* pDllName)
{
	// 提升权限
	//ImproveProcessPri();

	// 获取要插入的进程ID
	DWORD dwIDExplorer = Pid;
	if (dwIDExplorer == 0)
	{
		MEMBOX("Get Pro ID Error!\n");
		return false;
	}

	// 打开进程
	HANDLE hProcess = OpenProcess(/*PROCESS_ALL_ACCESS*/0x1F0FFF, FALSE, dwIDExplorer);
	if (hProcess == NULL)
	{
		MEMBOX("Open Process Error!\n");
		return false;
	}

	// 分配空间
	void* pDllPath = VirtualAllocEx(hProcess, 0, strlen(pDllName) + 1, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
	if (!pDllPath)
	{
		MEMBOX("pRemoteThread = NULL!\n");
		return false;
	}
	if (!WriteProcessMemory(hProcess, pDllPath, pDllName, strlen(pDllName) + 1, 0))
	{
		MEMBOX("WriteProcessMemory Fail!\n");
		return false;
	}



	//看有Game.exe 是否打开   .   打开了  GetProcAddress 是不准的  

	/*
	   1. 检测静态 变量是否存储
	   2.

	*/
	

	//卸载保护
	HMODULE h = GetModuleHandle("MessageHis.dat");
	if (h != NULL)
		FreeLibrary(h);


	PROC AdrMyDllDir = GetProcAddress(GetModuleHandle("Kernel32"), "LoadLibraryA");//(PROC)::GetProcAddress(::GetModuleHandle(TEXT("kernel32.dll")),"LoadLibraryA");

	// 创建远程线程
	HANDLE hThread = CreateRemoteThread(hProcess, 0, 0, (LPTHREAD_START_ROUTINE)AdrMyDllDir, pDllPath, 0, 0);
	if (!hThread)
	{
		MEMBOX("Remote thread faile.");
		//AfxMessageBox("远程线程创建失败");
		return false;
	}
	WaitForSingleObject(hThread, INFINITE); //等待运行完成
	CloseHandle(hThread);//这个CloseHandle是不会关掉远程线程的,TerminateThread能关掉
	VirtualFreeEx(hProcess, pDllPath, strlen(pDllName) + 1, MEM_RELEASE);
	CloseHandle(hProcess);
	MEMBOX("Remote Inject Dll Success");

	//AfxMessageBox("注入成功");
	return true;
}
  1. 调用mono接口加载c# dll
bool MonoInjecter::InjectMonoAssembly()
{
    //GetProcAddress
    /* grab the root domain */
   // domain = fnGetRootDomain();
   // fnThreadAttach(domain);

    log_trace("Hello %s %s", "fnGeDomainFriendlyName", fnGeDomainFriendlyName(domain));
    log_trace("Hello %s %s", "fnGetRootDir", fnGetRootDir());

    //----------------------------
    domain = fnGetDomainById(1);
    log_trace("Hello %s %ld", "fnGetRootDomain", domain);
    fnThreadAttach(domain);

    log_trace("Hello %s %s", "fnGeDomainFriendlyName", fnGeDomainFriendlyName(domain));
    log_trace("Hello %s %s", "fnGetRootDir", fnGetRootDir());
    //----------------------------

    /* open payload assembly */
    std::string assemblyDir;
    /* Grab our root directory*/
    assemblyDir.append(fnGetRootDir());
    assemblyDir.append(ASSEMBLY_PATH);
    assembly = fnAssemblyOpen(assemblyDir.c_str(), NULL);
    if (assembly == NULL) return false;
    log_trace("Hello %s %ld", "fnAssemblyOpen", assembly);
    image = fnAssemblyGetImage(assembly);
    if (image == NULL) return false;
    log_trace("Hello %s %ld", "fnAssemblyGetImage", image);
    klass = fnClassFromName(image, PAYLOAD_NAMESPACE, PAYLOAD_CLASS);
    if (klass == NULL) return false;
    log_trace("Hello %s %ld", "fnClassFromName", klass);
    /* grab the hack entrypoint */
    method = fnMethodFromName(klass, PAYLOAD_MAIN, 0);
    if (method == NULL) return false;
    log_trace("Hello %s %ld", "fnMethodFromName", method);
    /* call our entrypoint */
    fnRuntimeInvoke(method, NULL, NULL, NULL);
    log_trace("\nHello %s", "run mono dll!\n\n");

    return true;
}
  1. 简单实现一个编辑器工具用来查找当前已经打开的unity编辑器进程,然后进行注入
    记录使用注入的方式为Unity编辑器实现扩展能力,unity,编辑器,游戏引擎,imgui
  2. 由注入的c# dll调用的测试输出, 当前编辑器中是没有任何代码的
    记录使用注入的方式为Unity编辑器实现扩展能力,unity,编辑器,游戏引擎,imgui

测试环境

  1. 操作系统系统: windows 11 64位`, (不兼容32位)
  2. unity版本: 2021.3.15f1
  3. .NET6.0(第三方编辑器的实现)

文章来源地址https://www.toymoban.com/news/detail-556547.html

到了这里,关于记录使用注入的方式为Unity编辑器实现扩展能力的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • Unity使用VS编辑器打开项目失败解决办法

    Unity使用VS编辑器打开项目失败解决办法

    具体表现为:项目文件.sln无法打开,打开脚本文件后无法关联到Unity编辑器 报错信息可能不同,参考出错表现即可 首先去清除有逻辑错误的代码,先注释掉,不然后面可能会无法自动生成解决方案 然后关闭Unity编辑器,找到项目文件夹,删除我列出的文件 重新打开Unity,重

    2024年02月16日
    浏览(12)
  • 从零开始入门创作游戏——Unity编辑器的使用

    从零开始入门创作游戏——Unity编辑器的使用

    还没找到工作的我继续瞎折腾中,上次搭建环境就花了我3天的时间 从零开始入门创作游戏——Unity3d的环境搭建_默哀d的博客-CSDN博客 接下来是根据油土鳖的视频学习创作的一个小恐龙跳跳跳游戏,直接上手做一次学得更多 https://www.youtube.com/watch?v=UdM9DEys-rI 选择2D核心模板就可

    2024年02月05日
    浏览(16)
  • uniapp 微信小程序 editor富文本编辑器 api 使用记录

    uniapp 微信小程序 editor富文本编辑器 api 使用记录

    这里记录一下自己研究学习的结果 之前一直使用textarea 来进行内容的编辑。但是局限性还是太多,最近发现了editor。觉得很不错 uniapp的官方说明 https://uniapp.dcloud.io/component/editor.html 这里有个例子,看起来很棒。但是自己使用起来的时候, 怎么也没有官方demo上面的工具栏 !

    2024年02月09日
    浏览(15)
  • Unity 编辑器-查找所有未被使用的Prefab

    Unity 编辑器-查找所有未被使用的Prefab

    需求 接到一个需求,将Res里所有特效相关的prefab检查一下,没有使用的移除。 分析 先拆解一下需求,如下 代码 结果 结果如图所示。每组元素第一个为查找的prefab,之后的是使用了该prefab的预设或配表。 如果一组元素只有一个对象,则这个prefab无引用。 顶部的按钮为指定功

    2024年02月16日
    浏览(11)
  • unity 简单实现tilemap的保存和读取(以便用于关卡编辑器)

            最近在学习使用Tiledmap,用于制作地图确实很方便快捷,但总不能一个关卡就做一个prefab?还是必须将其保存为文本文件才行啊,于是有了以下的尝试:         先定义一个Tiledmap类,用于存储单个Tiledmap信息 tiles是保存的所有tile块。key为坐标值,value为使用的tile

    2024年02月13日
    浏览(12)
  • Sprite Editor图片编辑器的使用_unity基础开发教程

    Sprite Editor图片编辑器的使用_unity基础开发教程

    SpriteEditor是Unity引擎中的一个工具,用于创建和编辑2D图片。它提供了一系列功能,可以对图片进行剪裁、切割、翻转、旋转、调整大小等操作,以及设置图片的碰撞检测形状和渲染模式。 SpriteEditor可以帮助开发者将多张图片合并成动画精灵,并为每一帧设置播放时间和循环

    2024年02月01日
    浏览(9)
  • unity 通过 二维数组序列化 实现二维数组在编辑器面板查看和配置数据

    unity 通过 二维数组序列化 实现二维数组在编辑器面板查看和配置数据

    实现思路如下: 1、定义一个二维数组数据类 2、奖数据类标记为 Serializable  并实现 unity内置的  ISerializationCallbackReceiver接口,接口提供了序列化和反序列化方法,参见官方文档(文档中给出了字典的序列化方法):Unity - Scripting API: ISerializationCallbackReceiver 3、使用unity序列化

    2024年02月08日
    浏览(45)
  • 【Unity】AVPro使用踩坑,编辑器模式使用视频播放正常,打包后视频无法播放的问题

    【Unity】AVPro使用踩坑,编辑器模式使用视频播放正常,打包后视频无法播放的问题

    这个主要是AVPro的坑 一般使用会直接Browse给取文件路径,然后面板上面就能看到视频文件的名字,这个方法在编辑器模式下播放是可以获取到文件的,所以没问题。 但是打包后路径变化,拉取到的地址就不对了。 首先把视频资源改存到StreamingAssets文件夹路径下,然后路径获

    2024年02月16日
    浏览(66)
  • Unity编辑器扩展 | 编辑器扩展基础入门

    Unity编辑器扩展 | 编辑器扩展基础入门

    前言 当谈到游戏开发工具,Unity编辑器是一个备受赞誉的平台。它为开发者提供了一个强大且灵活的环境,使他们能够创建令人惊叹的游戏和交互式体验。 然而,Unity编辑器本身也是可以扩展和定制的,这为开发者提供了进一步提升工作流程和增强功能的机会。 在Unity 编辑器

    2024年02月10日
    浏览(45)
  • 【Unity编辑器扩展】 | 编辑器扩展入门基础

    【Unity编辑器扩展】 | 编辑器扩展入门基础

    前言 当谈到游戏开发工具,Unity编辑器是一个备受赞誉的平台。它为开发者提供了一个强大且灵活的环境,使他们能够创建令人惊叹的游戏和交互式体验。 然而,Unity编辑器本身也是可以扩展和定制的,这为开发者提供了进一步提升工作流程和增强功能的机会。 在Unity 编辑器

    2024年02月10日
    浏览(17)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包