1+ function table_to_string (t )
2+ local result = " ["
3+ for k ,v in pairs (t ) do
4+ result = result .. string.format (" %s:%s," ,k ,v )
5+ end
6+ return result .. " ]"
7+ end
8+
9+
10+ -- the api provides us with 3 globals
11+ print (entity )
12+ print (script )
13+ print (world )
14+
15+ -- we first retrieve ID's for our component and resource by their short name (long name/full path also work)
16+ local my_component_type = world :get_type_by_name (" MyComponent" )
17+
18+ -- then ask the world to give us a reference to `MyComponent` on the entity we just spawned
19+ -- resources work the same way, but we use `get_resource` instead of `get_component`
20+ -- the comp object is resolved to a `bevy_script_api::script_ref::ReflectValue` which implements UserData.
21+ -- we can use a custom proxy instead (by implementing LuaProxyable), but this is the simplest way to get started.
22+ local comp = world :get_component (entity , my_component_type )
23+ print (" Before script: " , comp )
24+
25+ print (" ============" )
26+
27+ -- the index metamethod on ReflectValue's uses bevy's reflection mechanism on top of some custom sub-reflection logic to
28+ -- allow reflecting inside Options, Vectors etc.
29+ -- when we index into ReflectValue's we either get back a custom proxy or another ReflectValue
30+
31+ -- the LuaBevyAPIProvider provides us custom proxies for many bevy types as well as std types.
32+ -- all of these implementations can be overridden via the bevy TypeRegistry
33+ comp .usize = 2
34+ print (" comp.usize after assigning to 2: " , comp .usize )
35+
36+ -- vec's and matrices have custom __index and __newindex overrides
37+ print (" comp.vec2 before: " , comp .vec2 )
38+ comp .vec2 [1 ] = 69
39+ print (" comp.vec2 after: " , comp .vec2 )
40+
41+ -- Option's get converted to nil or the value inside
42+ print (" comp.option_vec3 before: " , comp .option_vec3 )
43+ comp .option_vec3 = Vec3 .new (2 ,1 ,3 )
44+ print (" comp.option_vec3 after: " , comp .option_vec3 )
45+
46+ -- reflection via index is indexed starting at 1, unlike in Rust to match Lua's indexing
47+ print (" comp.option_vec3[1] before: " , comp .option_vec3 [1 ])
48+ comp .option_vec3 [1 ] = 5
49+ print (" comp.option_vec3[1] after: " , comp .option_vec3 [1 ])
50+
51+ print (" ============" )
52+
53+ -- Vec<T> references get converted to a custom proxy `LuaVec<T>` which is
54+ -- also assignable via lua tables
55+
56+ print (" comp.vec_of_option_bools before: " , table_to_string (comp .vec_of_option_bools ))
57+ comp .vec_of_option_bools = {true ,false ,true }
58+ print (" comp.vec_of_option_bools after assignment: " , table_to_string (comp .vec_of_option_bools ))
59+
60+ print (" comp.vec_of_option_bools[1] before: " , comp .vec_of_option_bools [1 ])
61+ comp .vec_of_option_bools [1 ] = false
62+ print (" comp.vec_of_option_bools[1] after: " , comp .vec_of_option_bools [1 ])
63+
64+ -- there are some additional methods available on LuaVec proxies imitating the Vec<T> api
65+ print (" comp.vec_of_option_bools before insert: " , table_to_string (comp .vec_of_option_bools ))
66+ comp .vec_of_option_bools :insert (1 ,nil )
67+ print (" comp.vec_of_option_bools after insert: " , table_to_string (comp .vec_of_option_bools ))
68+
69+ print (" comp.vec_of_option_bools before push: " , table_to_string (comp .vec_of_option_bools ))
70+ comp .vec_of_option_bools :push (false )
71+ print (" comp.vec_of_option_bools after push: " , table_to_string (comp .vec_of_option_bools ))
72+
73+ print (" comp.vec_of_option_bools len after push: " , # comp .vec_of_option_bools )
74+
75+ print (" comp.vec_of_option_bools before pop: " , table_to_string (comp .vec_of_option_bools ))
76+ print (comp .vec_of_option_bools :pop ())
77+ print (" comp.vec_of_option_bools after pop: " , table_to_string (comp .vec_of_option_bools ))
78+
79+ print (" the pairs inside comp.vec_of_option_bools: " )
80+ for k ,v in pairs (comp .vec_of_option_bools ) do
81+ print (string.format (" - %s:%s" ,k ,v ))
82+ end
83+
84+ comp .vec_of_option_bools :clear ()
85+ print (" comp.vec_of_option_bools after clear: " , table_to_string (comp .vec_of_option_bools ))
86+
87+ print (" comp.vec_of_option_bools len after clear: " , # comp .vec_of_option_bools )
88+ print (" ============" )
89+
90+ print (" comp.option_vec_of_bools before: " , table_to_string (comp .option_vec_of_bools ))
91+ print (comp .option_vec_of_bools :pop ())
92+ print (" comp.option_vec_of_bools after pop: " , table_to_string (comp .option_vec_of_bools ))
93+
94+
95+ print (" comp.option_vec_of_bools len after pop: " , # comp .option_vec_of_bools )
96+
97+ print (" the pairs inside comp.option_vec_of_bools: " )
98+ for k ,v in pairs (comp .option_vec_of_bools ) do
99+ print (string.format (" - %s:%s" ,k ,v ))
100+ end
101+
102+ print (" ============" )
103+
104+ local complex_vec_op = Vec3 .new (0 ,1 ,0 ):any_orthonormal_vector () + comp .mat3 .x_axis
105+ print (" (0,1,0).any_orthonormal_vector() + mat3.x_axis is: " , complex_vec_op )
106+
107+ local new_mat3 = Mat3 .from_cols (Vec3 .new (1 ,0 ,0 ),Vec3 .new (0 ,1 ,0 ),Vec3 .new (0 ,0 ,- 1 ))
108+ print (" new_mat3 is:" , new_mat3 )
109+
110+ comp .vec2 = comp .vec2 + comp .vec2
111+ comp .usize = comp .vec2 :min_element ()
112+ comp .f32 = comp .f32 + comp .f32 + comp .vec2 :min_element ()
113+ comp .vec2 = Vec2 .new (2 ,1 )
114+ comp .quat = Quat .from_xyzw (3 ,2 ,1 ,4 )
115+ comp .mat3 .x_axis = Vec3 .new (69 ,69 ,69 )
116+
117+ print (" ============" )
118+
119+ -- this is an example of something impossible to achieve with plain bevy reflection under the hood
120+ comp .mat3 [1 ][1 ] = 42
121+
122+ -- now let's retrieve these again to see if we actually changed their values permanently
123+ comp = world :get_component (entity ,my_component_type )
124+
125+ print (" After script:" )
126+ print (comp )
127+
128+ world :exit ()
0 commit comments