Guide: Interacting with game objects - AurieFramework/YYToolkit GitHub Wiki
Note
This guide is written with YYToolkit Next in mind. While it is possible to adapt the techniques below to YYTK Legacy, support will not be provided for such cases.
While making games, developers often use the concept of structs to group variables together. Internally, these structs are represented as YYObjectBase
objects. Variables are stored in a hashmap accessible under m_YYVarsMap
when using Internal Structure Access.
For demonstration purposes, let us access the item_value
variable, located inside self.my_struct.nested_struct
, and change its value to 50
.
This is the most verbose method, and is the only one that allows C++ code to safely access any struct's member variables. Due to the AurieStatus
value returned from the function, code can act upon the member variable not existing and gracefully exit.
AurieStatus last_status = AURIE_SUCCESS;
RValue* my_struct = nullptr;
// Access self.my_struct
last_status = module_interface->GetInstanceMember(
self,
"my_struct",
my_struct
);
if (!AurieSuccess(last_status)) { /* ... */ }
// Access my_struct.nested_struct
RValue* nested_struct = nullptr;
last_status = module_interface->GetInstanceMember(
*my_struct,
"nested_struct",
nested_struct
);
if (!AurieSuccess(last_status)) { /* ... */ }
// Access nested_struct.item_value
RValue* item_value = nullptr;
last_status = module_interface->GetInstanceMember(
*nested_struct,
"item_value",
item_value
);
if (!AurieSuccess(last_status)) { /* ... */ }
// Change item_value to 50
*item_value = 50;
A slightly cleaner way is to use the GetMember
and GetRefMember
methods of RValue
.
These functions are thin wrappers around GetInstanceMember
. They log errors to the console, and return nullptr
on failure instead of a status code. While both functions appear to do the same thing, there is a key difference between them.
-
GetMember
returns a copy of the variable.- Your code owns this copy, and changes to it will not reflect inside of the game's copy.
- The variable is safe to store for later use.
-
GetRefMember
returns a pointer to the variable.- The game owns the variable, and changes to it are instantly reflected inside of the game's variable.
- The pointer is not safe to store, as the parent object may be destroyed, invalidating it.
The two functions are best used in cases where the programmer still needs some level of error handling, but doesn't need the full status code that GetInstanceMember
provides.
// Convert self to an RValue
RValue rv_self = self;
// Access self.my_struct
RValue* my_struct = rv_self.GetRefMember("my_struct");
if (!my_struct) { /* ... */ }
// Access my_struct.nested_struct
RValue* nested_struct = my_struct->GetRefMember("nested_struct");
if (!nested_struct) { /* ... */ }
// Access nested_struct.item_value
RValue* item_value = nested_struct->GetRefMember("item_value");
if (!item_value) { /* ... */ }
// Change item_value to 50
*item_value = 50;
If you are absolutely sure that access to the variable cannot fail, you may choose to use the indexing operators.
While this syntax is by far the most eye-pleasing, it offers no error handling, and may crash your game if a non-existent variable is accessed.
// Convert self to an RValue
RValue rv_self = self;
// Access the item_value variable directly
rv_self["my_struct"]["nested_struct"]["item_value"] = 50;
Note
For const RValue
objects, the indexing operator does not return references, and instead returns copies.