unity_mirror_rs/unity_engine/
game_object.rs1use crate::commons::RevelArc;
2use crate::commons::RevelWeak;
3use crate::metadata_settings::metadata_component::MetadataComponentWrapper;
4use crate::metadata_settings::metadata_prefab::MetadataPrefab;
5use crate::unity_engine::mono_behaviour::MonoBehaviour;
6use crate::unity_engine::mono_behaviour_factory::MonoBehaviourFactory;
7use crate::unity_engine::transform::Transform;
8use crate::unity_engine::WorldManager;
9use once_cell::sync::Lazy;
10use rand::RngCore;
11use std::any::TypeId;
12use std::collections::HashMap;
13
14static mut COMPONENT_LOADING: Lazy<Vec<(RevelWeak<GameObject>, MetadataComponentWrapper)>> =
15 Lazy::new(|| vec![]);
16
17fn append_component_loading(
18 weak_game_object: RevelWeak<GameObject>,
19 component: MetadataComponentWrapper,
20) {
21 #[allow(static_mut_refs)]
22 unsafe {
23 COMPONENT_LOADING.push((weak_game_object, component));
24 }
25}
26
27fn component_loading() {
28 #[allow(static_mut_refs)]
29 unsafe {
30 COMPONENT_LOADING.reverse();
31 while let Some((arc_game_object, metadata_prefab)) = COMPONENT_LOADING.pop() {
32 GameObject::load_component(arc_game_object, &metadata_prefab);
33 }
34 }
35}
36
37#[derive(Default)]
38pub struct GameObject {
39 pub id: u64,
40 pub name: String,
41 pub asset_id: u32,
42 pub asset_path: String,
43 pub tag: String,
44 pub layer: i32,
45 pub is_static: bool,
46 is_active: bool,
47 pub transform: RevelArc<Transform>,
48 pub parent: RevelWeak<GameObject>,
49 pub children: HashMap<u64, RevelArc<GameObject>>,
50 component_mapping: HashMap<TypeId, Vec<usize>>,
52 pub components: Vec<Vec<RevelArc<Box<dyn MonoBehaviour>>>>,
54}
55
56impl GameObject {
57 pub(super) fn instance(metadata_prefab: &MetadataPrefab) -> RevelArc<GameObject> {
58 let arc_game_object = Self::new(RevelWeak::default(), metadata_prefab);
59 Self::recursive_children(arc_game_object.downgrade(), &metadata_prefab.children);
60 component_loading();
61 arc_game_object
62 }
63
64 pub fn instantiate(metadata_prefab: &MetadataPrefab) -> RevelArc<GameObject> {
65 log::debug!("Instantiate: {}", metadata_prefab.name);
66 let arc_game_object = Self::instance(metadata_prefab);
67 if let Some(world) = WorldManager::active_world().get() {
68 world.add_game_object(arc_game_object.clone());
69 }
70 arc_game_object
71 }
72
73 pub fn default() -> GameObject {
74 Self {
75 id: rand::rng().next_u64(),
76 ..Default::default()
77 }
78 }
79
80 fn new(parent: RevelWeak<GameObject>, metadata_prefab: &MetadataPrefab) -> RevelArc<GameObject> {
81 let mut rng = rand::rng();
83 let mut game_object = GameObject {
84 id: rng.next_u64(),
85 name: metadata_prefab.name.clone(),
86 tag: metadata_prefab.tag.clone(),
87 layer: metadata_prefab.layer,
88 is_static: metadata_prefab.is_static,
89 is_active: metadata_prefab.is_active,
90 asset_id: metadata_prefab.asset_id,
91 asset_path: metadata_prefab.asset_path.clone(),
92 parent: parent.clone(),
93 components: Default::default(),
94 transform: Default::default(),
95 children: HashMap::default(),
96 component_mapping: Default::default(),
97 };
98
99 let mut transform = Transform::new_with_metadata(&metadata_prefab.transform);
100
101 if let Some(parent_game_object) = parent.get() {
102 transform.parent = parent_game_object.transform.downgrade()
103 }
104
105 game_object.transform = RevelArc::new(transform);
106 let mut arc_game_object = RevelArc::new(game_object);
107
108 append_component_loading(
109 arc_game_object.downgrade(),
110 metadata_prefab.components.clone(),
111 );
112
113 arc_game_object.transform.game_object = arc_game_object.downgrade();
114 arc_game_object
115 }
116
117 fn recursive_children(parent: RevelWeak<GameObject>, children: &Vec<MetadataPrefab>) {
118 for metadata_prefab in children {
119 let arc_game_object = Self::new(parent.clone(), metadata_prefab);
120
121 let weak_game_object = arc_game_object.downgrade();
122
123 if let Some(parent) = parent.get() {
124 parent.children.insert(arc_game_object.id, arc_game_object);
125 }
126
127 if metadata_prefab.children.len() > 0 {
128 Self::recursive_children(weak_game_object.clone(), &metadata_prefab.children);
129 }
130
131 if let Some(game_object) = weak_game_object.get() {
132 for (_, children_game_object) in &game_object.children {
133 game_object
134 .transform
135 .children
136 .push(children_game_object.transform.downgrade());
137 }
138 }
139 }
140 }
141
142 fn load_component(
143 weak_game_object: RevelWeak<GameObject>,
144 component: &MetadataComponentWrapper,
145 ) {
146 for (full_path, component_settings) in component.group_by_full_name() {
147 let mono_behaviour_chain = MonoBehaviourFactory::create(
148 &full_path,
149 weak_game_object.clone(),
150 &component_settings,
151 );
152
153 let mut mono_behaviours = vec![];
154 for (mono_behaviour, type_id) in mono_behaviour_chain {
155 mono_behaviours.push((mono_behaviour, type_id));
157 }
158
159 if let Some(game_object) = weak_game_object.get() {
160 game_object.add_component(mono_behaviours);
161 }
162 }
163 }
164}
165
166impl GameObject {
167 pub fn add_component(&mut self, mono_behaviour_chain: Vec<(RevelArc<Box<dyn MonoBehaviour + 'static>>, TypeId)>) {
168 if mono_behaviour_chain.len() == 0 {
169 panic!("MonoBehaviourChain is empty");
170 }
171 let index = self.components.len();
172 let mut arc_mono_behaviours = Vec::new();
173 for (mono_behaviour, type_id) in mono_behaviour_chain {
174 arc_mono_behaviours.push(mono_behaviour);
175 if !self.component_mapping.contains_key(&type_id) {
176 self.component_mapping.insert(type_id, vec![index]);
177 } else {
178 if let Some(mapping) = self.component_mapping.get_mut(&type_id) {
179 mapping.push(index);
180 };
181 }
182 }
183 self.components.push(arc_mono_behaviours);
184
185 if let Some(component) = self.components.last_mut() {
186 if let Some(component) = component.last_mut() {
187 component.awake();
188 }
189 }
190 }
191
192 pub fn try_get_component<T: MonoBehaviour + 'static>(&self) -> Option<RevelWeak<Box<dyn MonoBehaviour>>> {
193 let type_id = TypeId::of::<T>();
194
195 let vec_index = self
196 .component_mapping
197 .get(&type_id)
198 .cloned()
199 .unwrap_or(vec![]);
200 if vec_index.len() == 0 {
201 return None;
202 }
203
204 Some(
205 self.components
206 .get(vec_index[0])?
207 .last()
208 .cloned()?
209 .downgrade(),
210 )
211 }
212
213 pub fn try_get_component2<T: MonoBehaviour + 'static>(&self) -> Option<RevelArc<Box<T>>> {
214 if let Some(weak_mono) = self.try_get_component::<T>() {
216 if let Some(weak_t) = weak_mono.downcast::<T>() {
217 return weak_t.upgrade();
218 }
219 }
220 None
221 }
222
223 pub fn get_components<T: MonoBehaviour + 'static>(&self) -> Vec<RevelWeak<Box<dyn MonoBehaviour>>> {
224 let type_id = TypeId::of::<T>();
225
226 let vec_index = self
227 .component_mapping
228 .get(&type_id)
229 .cloned()
230 .unwrap_or(vec![]);
231 if vec_index.len() == 0 {
232 return vec![];
233 }
234
235 let mut result = vec![];
236 for index in vec_index {
237 if let Some(component) = self.components.get(index) {
238 if let Some(component) = component.last() {
239 result.push(component.downgrade());
240 }
241 }
242 }
243 result
244 }
245
246 pub fn find_transform(&self, instance_id: &i32) -> Option<RevelWeak<Transform>> {
264 if self.transform.instance_id == *instance_id {
265 return Some(self.transform.downgrade());
266 }
267 for (_, children_game_object) in self.children.iter() {
268 if let Some(weak_transform) = children_game_object.find_transform(instance_id) {
269 return Some(weak_transform);
270 }
271 }
272 None
273 }
274
275 pub fn is_active(&self) -> bool {
276 self.is_active
277 }
278 pub fn set_active(&mut self, active: bool) {
279 self.is_active = active
280 }
281}
282
283static mut STARTED_COMPONENT: Vec<RevelWeak<Box<dyn MonoBehaviour>>> = Vec::new();
285
286macro_rules! recursive_event_fn {
287 ($($fn_name:ident),*) => {
288 $(
289 pub(crate) fn $fn_name(&mut self) {
290 for children_game_object in self.children.values_mut() {
291 children_game_object.$fn_name()
292 }
293 for component_chain in self.components.iter_mut() {
294 if let Some(component) = component_chain.last_mut() {
295 component.$fn_name();
296 }
297 }
298 }
299 )*
300 };
301}
302
303#[allow(unused)]
304impl GameObject {
305 recursive_event_fn!(
306 awake,
307 on_enable,
308 on_validate,
309 start,
310 fixed_update,
311 late_update,
312 on_disable
313 );
314
315 pub(crate) fn update(&mut self) {
316 for children_game_object in self.children.values_mut() {
317 children_game_object.update()
318 }
319 for component_chain in self.components.clone().iter_mut() {
320 if let Some(component) = component_chain.last_mut() {
321 #[allow(static_mut_refs)]
322 unsafe {
323 let started = STARTED_COMPONENT.iter().any(|weak_component| {
324 weak_component.ptr_eq(&component.downgrade())
325 });
326 if !started {
327 component.start();
328 STARTED_COMPONENT.push(component.downgrade())
329 }
330 }
331 component.update()
332 }
333 }
334 }
335
336 pub(crate) fn on_destroy(&mut self) {
337 for children_game_object in self.children.values_mut() {
338 children_game_object.on_destroy();
339 }
340 for component_chain in self.components.iter_mut() {
341 if let Some(component) = component_chain.last_mut() {
342 #[allow(static_mut_refs)]
343 unsafe {
344 STARTED_COMPONENT.retain(|weak_component| !weak_component.ptr_eq(&component.downgrade()));
345 }
346 component.on_destroy();
347 }
348 }
349 }
350}