il2cpp_bridge_rs/structs/components/core/
unity_object.rs1use crate::api::cache;
3use crate::structs::components::Transform;
4use crate::structs::core::{Class, Il2cppObject, Object};
5use crate::structs::math::{Quaternion, Vector3};
6use crate::structs::Il2cppString;
7use std::ffi::c_void;
8use std::ops::Deref;
9
10#[repr(C)]
15#[derive(Debug, Clone, Copy)]
16pub struct UnityObject {
17 pub object: Object,
19 pub m_cached_ptr: *mut c_void,
21}
22
23impl UnityObject {
24 pub fn from_ptr(ptr: *mut c_void) -> Self {
26 let object = unsafe { Object::from_ptr(ptr) };
27 let m_cached_ptr = unsafe {
28 let offset = std::mem::size_of::<Il2cppObject>() as isize;
29 *(ptr.offset(offset) as *mut *mut c_void)
30 };
31 Self {
32 object,
33 m_cached_ptr,
34 }
35 }
36
37 pub fn as_ptr(&self) -> *mut c_void {
39 self.object.as_ptr()
40 }
41
42 pub fn get_name(&self) -> Result<String, String> {
44 unsafe {
45 let obj = Object::from_ptr(self.as_ptr());
46 let ptr = obj
47 .method("get_name")
48 .ok_or("Method 'get_name' not found")?
49 .call::<*mut Il2cppString>(&[])?;
50
51 if ptr.is_null() {
52 return Err("Name is null".to_string());
53 }
54
55 (*ptr)
56 .to_string()
57 .ok_or_else(|| "Failed to convert name to String".to_string())
58 }
59 }
60
61 pub fn to_string(&self) -> Result<String, String> {
63 unsafe {
64 let obj = Object::from_ptr(self.as_ptr());
65 let ptr = obj
66 .method("ToString")
67 .ok_or("Method 'ToString' not found")?
68 .call::<*mut Il2cppString>(&[])?;
69
70 if ptr.is_null() {
71 return Err("String is null".to_string());
72 }
73
74 (*ptr)
75 .to_string()
76 .ok_or_else(|| "Failed to convert String to String".to_string())
77 }
78 }
79 pub fn get_class() -> Option<Class> {
81 cache::coremodule().class("Object")
82 }
83
84 pub fn instantiate(original: &UnityObject) -> Result<UnityObject, String> {
86 unsafe {
87 let object_class = Self::get_class()
88 .ok_or_else(|| "Could not find UnityEngine.Object class".to_string())?;
89 let method = object_class
90 .method(("Instantiate", 1))
91 .ok_or("Method 'Instantiate' not found")?;
92
93 let ptr = method.call::<*mut c_void>(&[original.as_ptr()])?;
94
95 if ptr.is_null() {
96 return Err("Failed to instantiate object".to_string());
97 }
98
99 Ok(UnityObject::from_ptr(ptr))
100 }
101 }
102
103 pub fn instantiate_at(
105 original: &UnityObject,
106 position: Vector3,
107 rotation: Quaternion,
108 ) -> Result<UnityObject, String> {
109 unsafe {
110 let object_class = Self::get_class()
111 .ok_or_else(|| "Could not find UnityEngine.Object class".to_string())?;
112 let method = object_class
113 .method(("Instantiate", 3))
114 .ok_or("Method 'Instantiate' not found")?;
115
116 let ptr = method.call::<*mut c_void>(&[
117 original.as_ptr(),
118 &position as *const _ as *mut c_void,
119 &rotation as *const _ as *mut c_void,
120 ])?;
121
122 if ptr.is_null() {
123 return Err("Failed to instantiate object".to_string());
124 }
125
126 Ok(UnityObject::from_ptr(ptr))
127 }
128 }
129
130 pub fn instantiate_with_parent(
132 original: &UnityObject,
133 parent: &Transform,
134 ) -> Result<UnityObject, String> {
135 unsafe {
136 let object_class = Self::get_class()
137 .ok_or_else(|| "Could not find UnityEngine.Object class".to_string())?;
138 let method = object_class
139 .method(("Instantiate", 2))
140 .ok_or("Method 'Instantiate' not found")?;
141
142 let ptr = method.call::<*mut c_void>(&[original.as_ptr(), parent.as_ptr()])?;
143
144 if ptr.is_null() {
145 return Err("Failed to instantiate object".to_string());
146 }
147
148 Ok(UnityObject::from_ptr(ptr))
149 }
150 }
151
152 pub fn destroy(&self, time_delay: f32) -> Result<(), String> {
154 unsafe {
155 let object_class = Self::get_class()
156 .ok_or_else(|| "Could not find UnityEngine.Object class".to_string())?;
157 let method = object_class
158 .method("Destroy")
159 .ok_or("Method 'Destroy' not found")?;
160
161 method.call::<()>(&[self.as_ptr(), &time_delay as *const f32 as *mut c_void])?;
162 Ok(())
163 }
164 }
165
166 pub fn destroy_immediate(
168 obj: &UnityObject,
169 allow_destroying_assets: bool,
170 ) -> Result<(), String> {
171 unsafe {
172 let object_class = Self::get_class()
173 .ok_or_else(|| "Could not find UnityEngine.Object class".to_string())?;
174 let method = object_class
175 .method("DestroyImmediate")
176 .ok_or("Method 'DestroyImmediate' not found")?;
177
178 method.call::<()>(&[
179 obj.as_ptr(),
180 &allow_destroying_assets as *const bool as *mut c_void,
181 ])?;
182 Ok(())
183 }
184 }
185
186 pub fn dont_destroy_on_load(obj: &UnityObject) -> Result<(), String> {
188 unsafe {
189 let object_class = Self::get_class()
190 .ok_or_else(|| "Could not find UnityEngine.Object class".to_string())?;
191 let method = object_class
192 .method("DontDestroyOnLoad")
193 .ok_or("Method 'DontDestroyOnLoad' not found")?;
194
195 method.call::<()>(&[obj.as_ptr()])?;
196 Ok(())
197 }
198 }
199}
200
201impl Deref for UnityObject {
202 type Target = Object;
203
204 fn deref(&self) -> &Self::Target {
205 &self.object
206 }
207}