Important
新版代码正在重构中
The codebase is currently under refactoring.
示例代码 (Example code)
Note
有任何新功能建议或 Bug,欢迎直接提交 Issue;当然也欢迎你动手修改代码后向本仓库发起 Pull Request。
New feature requests or bug reports are welcome via Issues, and Pull Requests are just as appreciated if you’d like to contribute code directly.
Warning
如果编译器支持,请务必开启 SEH(结构化异常处理)。
If your compiler supports it, please enable SEH (Structured Exception Handling).
Tip
高版本 Android 上可能出现的崩溃问题,请参考 此 Issue。
For potential crash issues on newer Android versions, see this issue.
- Windows
- Android
- Linux
- IOS
- HarmonyOS
- Camera
- Transform
- Component
- Object (Unity)
- LayerMask
- Rigidbody
- MonoBehaviour
- Renderer
- Mesh
- Behaviour
- Physics
- GameObject
- Collider
- Vector4
- Vector3
- Vector2
- Quaternion
- Bounds
- Plane
- Ray
- Rect
- Color
- Matrix4x4
- Array
- String
- Object (C#)
- Type (C#)
- List
- Dictionary
- Animator
- CapsuleCollider
- BoxCollider
- Time
- FieldInfo
- More...
- Mono注入 (Mono Inject)
- DumpToFile
- 附加线程 (Thread Attach / Detach)
- 修改静态变量值 (Modifying the value of a static variable)
- 获取对象 (Obtaining an instance)
- 创建C#字符串 (Create C# String)
- 创建C#数组 (Create C# Array)
- 创建C#对象 (Create C# instance)
- 世界坐标转屏幕坐标/屏幕坐标转世界坐标 (WorldToScreenPoint/ScreenToWorldPoint)
- 获取继承子类的名称 (Get the name of the inherited subclass)
- 获取函数地址(变量偏移) 及调用(修改/获取) (Get the function address (variable offset) and invoke (modify/get))
- 获取Gameobject组件 (Get GameObject component)
- More...
Caution
新版本强制性要求
Mandatory requirements for new versions
#define USE_GLM // 新版本不需要添加 (New versions do not need to be added) #include "UnityResolve.hpp"
#define WINDOWS_MODE 1 // 如果需要请改为 1 (1 if you need) #define ANDROID_MODE 0 #define LINUX_MODE 0
// Windows UnityResolve::Init(GetModuleHandle(L"GameAssembly.dll | mono.dll"), UnityResolve::Mode::Mono); // Linux、Android、IOS、HarmonyOS UnityResolve::Init(dlopen(L"GameAssembly.so | mono.so", RTLD_NOW), UnityResolve::Mode::Mono);
Tip
如果你是在游戏主线程使用或者通过Hook Update/LateUpdate 那么并不需要该功能
If you are using it on the main thread of the game or via Hook Update/LateUpdate, you don't need this feature
// C# GC Attach UnityResolve::ThreadAttach(); // C# GC Detach UnityResolve::ThreadDetach();
Tip
仅 Mono 模式可用
Only Mono mode is available
UnityResolve::AssemblyLoad assembly("./MonoCsharp.dll"); UnityResolve::AssemblyLoad assembly("./MonoCsharp.dll", "MonoCsharp", "Inject", "MonoCsharp.Inject:Load()");
const auto assembly = UnityResolve::Get("assembly.dll | 程序集名称.dll"); const auto pClass = assembly->Get("className | 类名称"); // assembly->Get("className | 类名称", "*"); // assembly->Get("className | 类名称", "namespace | 空间命名"); const auto field = pClass->Get<UnityResolve::Field>("Field Name | 变量名"); const auto fieldOffset = pClass->Get<std::int32_t>("Field Name | 变量名"); const int time = pClass->GetValue<int>(obj Instance | 对象地址, "time"); // pClass->GetValue(obj Instance*, name); = pClass->SetValue<int>(obj Instance | 对象地址, "time", 114514); // pClass->SetValue(obj Instance*, name, value); const auto method = pClass->Get<UnityResolve::Method>("Method Name | 函数名"); // pClass->Get<UnityResolve::Method>("Method Name | 函数名", { "System.String" }); // pClass->Get<UnityResolve::Method>("Method Name | 函数名", { "*", "System.String" }); // pClass->Get<UnityResolve::Method>("Method Name | 函数名", { "*", "", "System.String" }); // pClass->Get<UnityResolve::Method>("Method Name | 函数名", { "*", "System.Int32", "System.String" }); // pClass->Get<UnityResolve::Method>("Method Name | 函数名", { "*", "System.Int32", "System.String", "*" }); // "*" == "" const auto functionPtr = method->function; const auto method1 = pClass->Get<UnityResolve::Method>("method name1 | 函数名称1"); const auto method2 = pClass->Get<UnityResolve::Method>("method name2 | 函数名称2"); method1->Invoke<int>(114, 514, "114514"); // Invoke<return type>(args...); // Cast<return type, args...>(void); // Cast(UnityResolve::MethodPointer<return type, args...>&); const UnityResolve::MethodPointer<void, int, bool> ptr = method2->Cast<void, int, bool>(); ptr(114514, true); UnityResolve::MethodPointer<void, int, bool> add; ptr = method1->Cast(add); std::function<void(int, bool)> add2; method->Cast(add2); UnityResolve::Field::Variable<Vector3, Player> syncPos; syncPos.Init(pClass->Get<UnityResolve::Field>("syncPos")); auto pos = syncPos[playerInstance]; auto pos = syncPos.Get(playerInstance);
UnityResolve::DumpToFile("./output/");
const auto str = UnityResolve::UnityType::String::New("string | 字符串"); std::string cppStr = str.ToString();
const auto assembly = UnityResolve::Get("assembly.dll | 程序集名称.dll"); const auto pClass = assembly->Get("className | 类名称"); const auto array = UnityResolve::UnityType::Array<T>::New(pClass, size); std::vector<T> cppVector = array.ToVector();
const auto assembly = UnityResolve::Get("assembly.dll | 程序集名称.dll"); const auto pClass = assembly->Get("className | 类名称"); const auto pGame = pClass->New<Game*>();
Tip
仅 Unity 对象
Unity objects only
const auto assembly = UnityResolve::Get("assembly.dll | 程序集名称.dll"); const auto pClass = assembly->Get("className | 类名称"); std::vector<Player*> playerVector = pClass->FindObjectsByType<Player*>(); // FindObjectsByType<return type>(void); playerVector.size();
Camera* pCamera = UnityResolve::UnityType::Camera::GetMain(); Vector3 point = pCamera->WorldToScreenPoint(Vector3, Eye::Left); Vector3 world = pCamera->ScreenToWorldPoint(point, Eye::Left);
const auto assembly = UnityResolve::Get("UnityEngine.CoreModule.dll"); const auto pClass = assembly->Get("MonoBehaviour"); Parent* pParent = pClass->FindObjectsByType<Parent*>()[0]; std::string child = pParent->GetType()->GetFullName();
std::vector<T*> objs = gameobj->GetComponents<T*>(UnityResolve::Get("assembly.dll")->Get("class"))); // gameobj->GetComponents<return type>(Class* component) std::vector<T*> objs = gameobj->GetComponentsInChildren<T*>(UnityResolve::Get("assembly.dll")->Get("class"))); // gameobj->GetComponentsInChildren<return type>(Class* component) std::vector<T*> objs = gameobj->GetComponentsInParent<T*>(UnityResolve::Get("assembly.dll")->Get("class"))); // gameobj->GetComponentsInParent<return type>(Class* component)