Difference between revisions of "Add character to scene"
(11 intermediate revisions by the same user not shown) | |||
Line 28: | Line 28: | ||
Here you can add brain state variables that can be changed during the game. They are automatically saved when you save the game.<br> | Here you can add brain state variables that can be changed during the game. They are automatically saved when you save the game.<br> | ||
The variables <code>main_focus_type</code> and <code>main_def_exp</code> do not only contain a value but can also be used to set the actual focus and expression.<br> | The variables <code>main_focus_type</code> and <code>main_def_exp</code> do not only contain a value but can also be used to set the actual focus and expression.<br> | ||
− | Set <code>main_focus_type = STARE</code> and <code>main_def_exp = A_BIT_ANGRY</code>. This will make the character stare and you with an somewhat angry expression.</li> | + | Set <code>main_focus_type = STARE</code> and <code>main_def_exp = A_BIT_ANGRY</code>. This will make the character stare and you with an somewhat angry expression.<br> |
+ | Run XStoryPlayer and you should see that she follows you with an somewhat angry expression.</li> | ||
+ | <li>Now we want the alien character to keep walking around in the spaceship. Add two more waypoints to the scene like this:<br> | ||
+ | [[file:maya_waypoint1.jpg|600px]]<br> | ||
+ | Name them waypoint3 and waypoint4. Set the starting waypoint in the pose settings of the alien to waypoint3.<br> | ||
+ | Now start XStoryPlayer again. Press F6 to go into free view mode. "Fly" around the wall and you should see the alien behind it now. | ||
+ | </li> | ||
+ | <li>Now we will add some walking scripting. Walk planning is automatically calculated based on the the collision objects in the scene.<br> | ||
+ | In debug mode a file called <code>coll.tga</code> is created in the home directory of XStoryPlayer. It contains the path information.<br> | ||
+ | So we only have to redirect the character using the script and she walks by herself.<br> | ||
+ | Open the <code>/init/story/alien/brain/run.dat</code> file. It contains the code that is run for each brain.<br> | ||
+ | Replace the code with this: | ||
+ | <syntaxhighlight lang="cpp"> | ||
+ | #include "init/std/base/char/brain/code/run.dat" | ||
+ | |||
+ | //------------------------------------------- | ||
+ | |||
+ | <*state_run> | ||
+ | |||
+ | res = true; | ||
+ | |||
+ | case (state.dyn.me.do.state) | ||
+ | { | ||
+ | [RUN0] state_run0(); | ||
+ | } | ||
+ | |||
+ | </state_run> | ||
+ | |||
+ | |||
+ | //------------------------------------------- | ||
+ | |||
+ | |||
+ | <state_run0> | ||
+ | |||
+ | case (state.dyn.me.do.state2) | ||
+ | { | ||
+ | [NONE] | ||
+ | { | ||
+ | // Set timer to 20 seconds | ||
+ | do_set_timer(20); | ||
+ | |||
+ | state.dyn.me.do.state2 = START; | ||
+ | } | ||
+ | |||
+ | [START] | ||
+ | { | ||
+ | // Wait for timer | ||
+ | loc.ts = GetTs(); | ||
+ | [loc.ts < state.dyn.me.do.ts] return; | ||
+ | |||
+ | state.dyn.me.do.state2 = WALK1; | ||
+ | } | ||
+ | |||
+ | [WALK1] | ||
+ | { | ||
+ | // If busy with pose then wait | ||
+ | [state.dyn.me.pose.result == NONE] return; | ||
+ | |||
+ | // Walk towards waypoint4 and stand there | ||
+ | // No need to end exactly on this waypoint | ||
+ | loc.state.pose_type = STAND; | ||
+ | loc.state.waypoint = "waypoint4"; | ||
+ | loc.state.exact = 0; | ||
+ | SetPose(loc.state); | ||
+ | |||
+ | state.dyn.me.do.state2 = WALK2; | ||
+ | } | ||
+ | |||
+ | [WALK2] | ||
+ | { | ||
+ | // If busy with pose then wait | ||
+ | [state.dyn.me.pose.result == NONE] return; | ||
+ | |||
+ | // Walk towards waypoint3 and stand there | ||
+ | // No need to end exactly on this waypoint | ||
+ | loc.state.pose_type = STAND; | ||
+ | loc.state.waypoint = "waypoint3"; | ||
+ | loc.state.exact = 0; | ||
+ | SetPose(loc.state); | ||
+ | |||
+ | state.dyn.me.do.state2 = WALK1; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | </state_run0> | ||
+ | </syntaxhighlight> | ||
+ | This code will make the character walk between the two waypoints continuously.<br> | ||
+ | Start XStoryPlayer and after the player has gotten the feedback "Wait, I believe I hear someone coming...", you should see the alien girl walking by. | ||
+ | </li> | ||
+ | <li>Now give some feedback when you see the girl. Add this code to the player run.dat file: | ||
+ | <syntaxhighlight lang="cpp"> | ||
+ | [START3] | ||
+ | { | ||
+ | [state.dyn.me.avatar.id == ALIEN & | ||
+ | state.dyn.me.avatar.range <= 6] | ||
+ | { | ||
+ | feedback.s = "An alien girl?? Why is she looking so angry..."; | ||
+ | |||
+ | state.dyn.me.do.state2 = SEEN_ALIEN; | ||
+ | } | ||
+ | } | ||
+ | </syntaxhighlight> | ||
+ | Now after you see the alien girl you get this feedback. | ||
+ | </li> | ||
+ | <li>We want the alien girl to say something when you talk to her. The ref.dat file for the alien character can be used for this. | ||
+ | Open it and change the <code>ref.state.run0</code> code to this: | ||
+ | <syntaxhighlight lang="cpp"> | ||
+ | run0 | ||
+ | { | ||
+ | hello.greet = | ||
+ | { | ||
+ | talk.s = "Be quiet prisoner!"; | ||
+ | } | ||
+ | |||
+ | get.get = hello.greet; | ||
+ | if.get = hello.greet; | ||
+ | when.get = hello.greet; | ||
+ | where.get = hello.greet; | ||
+ | why.get = hello.greet; | ||
+ | set.get = hello.greet; | ||
+ | info.get = hello.greet; | ||
+ | word.get = hello.greet; | ||
+ | } | ||
+ | </syntaxhighlight> | ||
+ | When the character is in the RUN0 state it will receive talk events. We can use the <code>ref.state.run0</code> code variables to react on these talk events.<br> | ||
+ | Using the above code we basically react to any talk event and let the alien reply that you should be quiet.<br> | ||
+ | Start the story and say something to the alien when she walks by. She should respond like programmed. | ||
+ | </li> | ||
+ | <li>Now we want her to come to you when you talk to her. Before we can do that first edit the collider objects a bit.<br> | ||
+ | We want the girl not to collide with the outer cell colliders only the player. Change the scene.ini file likt this: | ||
+ | <syntaxhighlight lang="cpp"> | ||
+ | rb "collShape1" | ||
+ | { | ||
+ | physics | ||
+ | { | ||
+ | elem[0] {mesh = "collShape1";} | ||
+ | elem[1] {mesh = "collShape2";} | ||
+ | elem[2] {mesh = "collShape3"; coll_type = NONE; coll = MASK_VIEWER;} | ||
+ | elem[3] {mesh = "collShape4"; coll_type = NONE; coll = MASK_VIEWER;} | ||
+ | } | ||
+ | } | ||
+ | </syntaxhighlight> | ||
+ | Rerun the filemaker. <code>coll_type = NONE</code> ensures the collider is not used in the path planner for the character.<br> | ||
+ | <code>coll = VIEWER</code> ensures the character does not collide with the collider only the player. | ||
+ | </li> | ||
+ | <li> | ||
+ | Now change the character <code>ref.state.run0</code> code to this: | ||
+ | <syntaxhighlight lang="cpp"> | ||
+ | run0 | ||
+ | { | ||
+ | hello.greet = | ||
+ | { | ||
+ | // Run to cell when you talk to her | ||
+ | loc.state.pose_type = STAND; | ||
+ | loc.state.waypoint = "waypoint2"; | ||
+ | loc.state.speed = 2; | ||
+ | loc.state.exact = 0; | ||
+ | SetPose(loc.state); | ||
+ | |||
+ | // Store old state | ||
+ | state.dyn.me.do.prev_state = state.dyn.me.do.state2; | ||
+ | |||
+ | state.dyn.me.do.state2 = WALK_CELL; | ||
+ | } | ||
+ | |||
+ | get.get = hello.greet; | ||
+ | if.get = hello.greet; | ||
+ | when.get = hello.greet; | ||
+ | where.get = hello.greet; | ||
+ | why.get = hello.greet; | ||
+ | set.get = hello.greet; | ||
+ | info.get = hello.greet; | ||
+ | word.get = hello.greet; | ||
+ | } | ||
+ | </syntaxhighlight> | ||
+ | Also edit the alien character <code>run.dat</code> file and add:<br> | ||
+ | <syntaxhighlight lang="cpp"> | ||
+ | [WALK_CELL] | ||
+ | { | ||
+ | [state.dyn.me.pose.result == NONE] return; | ||
+ | |||
+ | talk.s = "Be quiet human!"; | ||
+ | |||
+ | // Proceed with old state | ||
+ | [state.dyn.me.do.prev_state == WALK1] | ||
+ | state.dyn.me.do.state2 = WALK2; | ||
+ | else | ||
+ | state.dyn.me.do.state2 = WALK1; | ||
+ | } | ||
+ | </syntaxhighlight> | ||
+ | So when you talk to her she goes into the WALK_CELL state and when she arrives at your cell she says "Be quiet human".<br> | ||
+ | After that she proceeds with her route.<br> | ||
+ | Test the newly added scripts now.</li> | ||
+ | <li>That was a pretty long tutorial. The story is starting to take shape.<br> | ||
+ | Before we proceed with the rest of the story it would be nice to change the cloth of the alien a bit.<br> | ||
+ | Continue with the next tutorial '[[Creating cloth]]'.</li> | ||
</ol> | </ol> |
Latest revision as of 15:46, 13 January 2015
In this tutorial we will add a female alien character to the scene. We will let her walk by the cell once in a while.
If you try to talk with her, she gets angry and says you should be quiet.
Steps
- Copy the files from the 'Tutorial resource pack' for this tutorial to the appropriate directories.
We will describe these files here briefly:
-
/init/story/alien
: This is the brain for the alien character. Just like the player each character has a brain. -
/scenes/capture
: These are the motion capture files used for the alien character. -
/scenes/character6
: These are the character and cloth meshes. -
/scenes/charobj
: These meshes are used for collision detection for characters in general. -
/scenes/sounds
: These files are the sound files used for the character. -
/scene/textures
: These files are the texture files used for the character.
-
- Now we need a location that is the starting point for this character.
Open the spaceship scenescene.ma
and create a duplicate instance of the waypoint object.
A duplicate instance copies only the instance of the object not the mesh itself. Name the copywaypoint2
and place it outside the cell like this:
- Open the
/init/story/alien/init.dat
file.
In the pose settings you see that thescene_id = SPACESHIP1
andwaypoint = "waypoint2"
.
The pose contains all pose settings for this character. The character is derived from the objectCHAR_BASE
, you can find more pose settings in the file:
/init/std/base/char/char_base.dat
. You see that the scene_id and waypoint are overridden. - Start the adbucted scene and if all went well, you should see an alien character outside your cell.
- Now lets make her look at you and change her expression. Open the
/init/story/alien/brain/dyn.dat
file. This file contains the dynamic state for the brain.
Here you can add brain state variables that can be changed during the game. They are automatically saved when you save the game.
The variablesmain_focus_type
andmain_def_exp
do not only contain a value but can also be used to set the actual focus and expression.
Setmain_focus_type = STARE
andmain_def_exp = A_BIT_ANGRY
. This will make the character stare and you with an somewhat angry expression.
Run XStoryPlayer and you should see that she follows you with an somewhat angry expression. - Now we want the alien character to keep walking around in the spaceship. Add two more waypoints to the scene like this:
Name them waypoint3 and waypoint4. Set the starting waypoint in the pose settings of the alien to waypoint3.
Now start XStoryPlayer again. Press F6 to go into free view mode. "Fly" around the wall and you should see the alien behind it now. - Now we will add some walking scripting. Walk planning is automatically calculated based on the the collision objects in the scene.
In debug mode a file calledcoll.tga
is created in the home directory of XStoryPlayer. It contains the path information.
So we only have to redirect the character using the script and she walks by herself.
Open the/init/story/alien/brain/run.dat
file. It contains the code that is run for each brain.
Replace the code with this:#include "init/std/base/char/brain/code/run.dat" //------------------------------------------- <*state_run> res = true; case (state.dyn.me.do.state) { [RUN0] state_run0(); } </state_run> //------------------------------------------- <state_run0> case (state.dyn.me.do.state2) { [NONE] { // Set timer to 20 seconds do_set_timer(20); state.dyn.me.do.state2 = START; } [START] { // Wait for timer loc.ts = GetTs(); [loc.ts < state.dyn.me.do.ts] return; state.dyn.me.do.state2 = WALK1; } [WALK1] { // If busy with pose then wait [state.dyn.me.pose.result == NONE] return; // Walk towards waypoint4 and stand there // No need to end exactly on this waypoint loc.state.pose_type = STAND; loc.state.waypoint = "waypoint4"; loc.state.exact = 0; SetPose(loc.state); state.dyn.me.do.state2 = WALK2; } [WALK2] { // If busy with pose then wait [state.dyn.me.pose.result == NONE] return; // Walk towards waypoint3 and stand there // No need to end exactly on this waypoint loc.state.pose_type = STAND; loc.state.waypoint = "waypoint3"; loc.state.exact = 0; SetPose(loc.state); state.dyn.me.do.state2 = WALK1; } } </state_run0>
This code will make the character walk between the two waypoints continuously.
Start XStoryPlayer and after the player has gotten the feedback "Wait, I believe I hear someone coming...", you should see the alien girl walking by. - Now give some feedback when you see the girl. Add this code to the player run.dat file:
[START3] { [state.dyn.me.avatar.id == ALIEN & state.dyn.me.avatar.range <= 6] { feedback.s = "An alien girl?? Why is she looking so angry..."; state.dyn.me.do.state2 = SEEN_ALIEN; } }
Now after you see the alien girl you get this feedback.
- We want the alien girl to say something when you talk to her. The ref.dat file for the alien character can be used for this.
Open it and change the
ref.state.run0
code to this:run0 { hello.greet = { talk.s = "Be quiet prisoner!"; } get.get = hello.greet; if.get = hello.greet; when.get = hello.greet; where.get = hello.greet; why.get = hello.greet; set.get = hello.greet; info.get = hello.greet; word.get = hello.greet; }
When the character is in the RUN0 state it will receive talk events. We can use the
ref.state.run0
code variables to react on these talk events.
Using the above code we basically react to any talk event and let the alien reply that you should be quiet.
Start the story and say something to the alien when she walks by. She should respond like programmed. - Now we want her to come to you when you talk to her. Before we can do that first edit the collider objects a bit.
We want the girl not to collide with the outer cell colliders only the player. Change the scene.ini file likt this:rb "collShape1" { physics { elem[0] {mesh = "collShape1";} elem[1] {mesh = "collShape2";} elem[2] {mesh = "collShape3"; coll_type = NONE; coll = MASK_VIEWER;} elem[3] {mesh = "collShape4"; coll_type = NONE; coll = MASK_VIEWER;} } }
Rerun the filemaker.
coll_type = NONE
ensures the collider is not used in the path planner for the character.
coll = VIEWER
ensures the character does not collide with the collider only the player. -
Now change the character
ref.state.run0
code to this:run0 { hello.greet = { // Run to cell when you talk to her loc.state.pose_type = STAND; loc.state.waypoint = "waypoint2"; loc.state.speed = 2; loc.state.exact = 0; SetPose(loc.state); // Store old state state.dyn.me.do.prev_state = state.dyn.me.do.state2; state.dyn.me.do.state2 = WALK_CELL; } get.get = hello.greet; if.get = hello.greet; when.get = hello.greet; where.get = hello.greet; why.get = hello.greet; set.get = hello.greet; info.get = hello.greet; word.get = hello.greet; }
Also edit the alien character
run.dat
file and add:
[WALK_CELL] { [state.dyn.me.pose.result == NONE] return; talk.s = "Be quiet human!"; // Proceed with old state [state.dyn.me.do.prev_state == WALK1] state.dyn.me.do.state2 = WALK2; else state.dyn.me.do.state2 = WALK1; }
So when you talk to her she goes into the WALK_CELL state and when she arrives at your cell she says "Be quiet human".
Test the newly added scripts now.
After that she proceeds with her route.
- That was a pretty long tutorial. The story is starting to take shape.
Before we proceed with the rest of the story it would be nice to change the cloth of the alien a bit.
Continue with the next tutorial 'Creating cloth'.