Creating Objects using Scripts#
Notice
This page is still work in progress and may contain inaccurate information.
In many types of games, you'll likely want to be able to create and place objects entirely via game scripts. This can be as simple as dropping an enemy's weapon or equipment upon death, or as involved as an open-world sandbox game - where nearly all of the game world is created at runtime.
In this tutorial, we'll go over how you can place new objects at runtime, using the following approaches:
- Placing instances of an existing tag
- Creating entirely new tags at runtime
Placing Tags#
Creating instances of an existing tag on disk is simple. For our example, we'll do this from our scenario script, but you can place objects using any script. We'll assume that you've followed past tutorials and have created a rotator
tag class and tag. If this isn't the case, ensure you've completed the 'Scripting Tags and Tag Classes' tutorial.
First, remove the existing rotator
tag from your scenario in Sapien. Next, open your script in Visual Studio, and override the Ready()
method. This will be called when the scenario tag is ready and has finished loading.
In this method, we'll call BlamAPI::World::Drop()
, providing the tag path for our rotator tag, along with the desired world position. In our case, we'll assume you placed your rotator tag in a folder named sample_tags
, and named it cube.rotator
. The function will return a pointer to the BlamWorldObject
of the newly placed instance, or nullptr
if the object couldn't be placed.
That's it - you've placed an object, entirely from scripts! When finished, your script should look something like this:
void ExampleScenarioScript::Ready()
{
BlamWorldObject* instance = BlamAPI::World::Drop("/sample_tags/cube.rotator", { 2.0f, 0.0f, 4.0f });
if (instance)
{
// It worked!
}
}
Creating Tags#
While placing pre-made tags will satisfy most requirements, some projects may demand that all-new tags are created at runtime. This, too, is quite simple. We'll once again be using our existing scenario script, without having dropped any tag instance during Ready()
.
To create a new rotator
tag instance, you'll first need to create a new rotator
tag. To do so, call BlamAPI::Tags::CreateRotatorTag()
, which will be declared in the .cpp and .h files for your tag class you created earlier. Provide the new tag path or name as the first argument - this can generally be anything you want, as long as it is a unique path. For our example, we'll provide it the name /memtags/rotator_test.rotator
.
From here, you can edit the tag data as shown in earlier tutorials, making sure to poke changes when finished. When you've set it up as you like, you can treat it like any other tag - and so to finish up, we'll drop the tag into the world just like before. When finished, your script should look something like the following:
void ExampleScenarioScript::Ready()
{
rotator* tag = BlamAPI::Tags::CreateRotatorTag("/memtags/rotator_test.rotator");
tag->renderable->tag_path = "/objects/shared/primitives/cube.primitive";
tag->renderable->Resolve();
tag->rotation_speed = 5;
tag->rotation_amount = { 20, 10, 5 };
BlamWorldObject* instance = BlamAPI::World::Drop("/memtags/rotator_test.rotator", { 8.0f, 3.0f, 4.0f });
if (instance)
{
// It worked!
}
}
And just like that, you've created a tag in memory and placed an instance of it!