Navigation
Setting controls for RTS units

From Wiki.ludiloom.com
Jump to: navigation, search

In this tutorial we show how to create the basic real-time strategy characters. The player will be able to select a character and click on the terrain to send it there. Also, we will configure the typical bird-eye camera used in RTS games.

Contents


We developed this tutorial inside an arena named CreatingRTSCharacter in the project Free4All. You may clone the arena and see this tutorial in action. Even better, you could create a new arena inside that project and follow this tutorial to create a RTS characters from scratch.

Character Object

Firstly, create an object called Character in the arena, using the default object template.

  • Right-click on the arena object in the tree >> new >> object, like so:
New Object
  • Name the object Character and select the object template default:
Create Object

In a "real" project, you should create this Character object as an Object Template in the rulebook and then create new characters from the template as needed.

Character Model

The first thing you need is a model for your character. Right-click on the object Character >> new >> model. This will open the Model Editor to create a 3d model. Name the model my_character_model, pick a mesh and press "Save". We used a mesh called aztec_warrior_blue, which is part of the Media Library Aztec. This Media Library is free, you just have to subscribe it in order to use the model.

Model Editor

The physics engine inside ludiloom has several features to manage character control: physics, movement, interpolation, etc.. We will show how to use these features in this tutorial. More about this interface here. After pressing "Save" in the Model Editor, open the Physics Editor. Choose "Character" in the physics type box.

Physics editor - character

Configuring the physics is mostly a task of tweaking, so you are more likely spend more time in the physics interface after the character is 'working' than at this point. You can find a more detailed explanation about this interface here, but here are some things you have to do:

  • Set the Mass to 100, so your character behaves properly to gravity and other physical forces.
  • Set synchronization to global only if the game is multi-player.
  • Enable collision and gravity.
  • Set the offset, scale and rotation of the capsule. If you look at the 3d model in the game scene while this editor is open, you'll see a green capsule around the model. This capsule is what really matters to the physics engine. Sometimes we have to adjust the capsule to the model. In our warrior model, we adjusted the vertical offset and the height of the capsule.
Note: You can't find the model, set its position to where you can see it (such as 50,50,50) using the Model Editor or the Scene Editor. Sometimes the models fall under the terrain once they receive physics.
  • Set the speed of the model. We set it to 50.
  • Configure the walking sound.

Selection Terrain Mesh Decal

Your character need to provide some kind of feedback to show whether it's selected or not. As in many RTS, we will add a little circle at the feet of the character. The best way to do that in ludiloom is to use a Terrain Mesh Decal. A mesh decal works like a plan that adapts to the shape of the terrain as it moves.

Firstly, we create a material that contains the texture to the mesh decal. To create a material, open the Material List from the menu bar and click New Material From Template. You can take a look at the Material Editor page for further details, but this is basically what we did:

We used a texture that belongs to the same Media Library Aztec and set the reject function to greater than 100. We named the material select_decal.

We will show how to create a Terrain Mesh Decal using the ludiloom API. Open the console (F11) and execute the following commands:

  1. char = Arena:getObjectsByName("Character")[1];
  2. model = char:getModel("my_character_model");

These lines initialize the variables char and model with the object Character and the model my_character_model, respectively.

Now, we can create the mesh decal itself:

  1. points = {{-20,-20},{20,-20},{20,20},{-20,20}};
  2. decal = char:createMeshDecal("selected_decal", points,"select_decal");
  3. decal:setPosition(0,1,0);
  4. decal:setDetailLevel(5);
  5. model:addRepresentation(decal);

The first line creates a set of points that form 40x40 a square, centered in the point (0,0). Then we create the mesh decal with the name selected_decal, with the set of points created before and using the material select_decal. Line 3 raises the mesh decal a bit from the ground to avoid z-fighting. Line 4 increases the detail so that the decal adjusts better to the terrain. Finally, we put the mesh decal inside the model. This way, the decal will follow the model as it moves across the terrain.

Interactions

goTo

To create the interaction to make the character move, right-click on the object Character >> new >> interaction. Each interaction contains a Lua script. Find out more about scripting in ludiloom here. Name the interaction as goTo.

Add interaction

Add a three parameter named posx, posy and posz with the type Number to the interaction, as shown in the picture above.

Write the script in the interaction to make the character walk to the point defined by posx, posy and posz:

  1. local m = this:getModel("my_character_model");
  2. m:goTo(posx,posy,posz);
  3. m:playAnimation("walk",4,true);

The line 1 binds the model of the character to the variable m. The variable this is the object that contains the interaction (Character), and my_character_model is the name of the character model previously created. Line 2 tells the character model to go to the position passed to the interaction. Finally, line 3 starts playing the animation walk in the model with speed 1 and in loop.

You find a complete description of the Lua API here. In this script, we used the functions getModel, goTo and playAnimation.

Animations come within the mesh. You can see the list of animations a mesh has in the Model Editor. Learn more about exporting models to ludiloom here.

stop

You have to create another interacton to stop the animation when the model reaches its destination. To create this interaction, right-click on the object Character >> new >> interaction and name it stop. This is the code that should be in the interaction:

  1. local m = this:getModel("my_character_model");
  2. m:stopAnimation("walk");

Now you need a listener to execute this interaction when the character stops. Right-click on the model my_character_model >> new >> listener:

Set the listener type to Physics, action to movement stop and interaction to stop. Press new.

toggleSelection

In this tutorial we will implement a simple mechanism where the player selects/deselects each unit by clicking on it. We need an attribute to keep the information whether this character is selected or not. Right-click on the Character object >> new >> attribute, and set it's name to selected and value to 1. This attribute will have the value 1 when the model is selected, 0 otherwise.

Create an interaction in the Character object called toggleSelection. The following script will implement the select/deselect mechanism:

  1. if this:getAttribute("selected") == "1" then
  2. this:getMeshDecal("selected_decal"):setVisible(false);
  3. this:setAttribute("selected",0);
  4. else
  5. this:getMeshDecal("selected_decal"):setVisible(true);
  6. this:setAttribute("selected",1);
  7. end

Finally, we need a listener on the character model to detect the mouse clicks. Right-click over the my_character_model representation >> new >> listener. Create the listener in the Listener Editor window like this:

  • Set the listener type to Mouse.
  • Set the action to Mouse Left pressed.
  • Choose the interaction toggleSelection.
  • Press new.

In the end, your Character object should contain the following elements:

Controlling the units

Creating several units

Typically, in a RTS, there are several units in the game scene. To ease the management of the units in our tutorial game, create a new object in the arena called Units. This object will be the container of the several characters (units) in the game. Just like you created the Character object Object, create another object called Units.

Time to make ourselves a small army! There are several ways to accomplish this:

  1. Select the Character object in the tree and copy/paste it into the Units object. Repeat this a couple of times.
  2. Open the console (F11) and execute the commands:

char = Arena:getObjectsByName("Character")[1]; units = Arena:getObjectsByName("Units")[1]; units:copyObject(char,"Unit1"); Repeat the last line to create more of them. The next image shows three created units called Unit1, Unit2 and Unit3 respectively:

In a "normal" RTS game in ludiloom, the character would have been created as an Object Template. In that case, the code to create more units would be: units = Arena:getObjectsByName("Units")[1]; new_unit = units:CreateObject("UnitTemplate","Unit1","");

Interactions

deselectAll

Create an interaction in the Arena (right-click on the Arena object in the tree >> new >> interaction) called deselectAll like this:

The sript is:

  1. local units = Arena:getObjectsByName("Units")[1];
  2.  
  3. for i,v in ipairs(units:getObjects()) do
  4. if v:getAttribute("selected") == "1" then
  5. v:exec("toggleSelected");
  6. end
  7. end

This cycles through all objects inside the object Units, in this case, through every unit in the game. If the unit is selected, then it deselects it by executing the interaction toggleSelected.

You can associate this interaction, for instance, with the event of right-clickling anywhere. Right-click on the Arena object in the tree >> new >> interaction. In the Listener Editor set the type to Mouse, the action to Mouse Right Pressed and the interaction to deselectAll, like this:

orderMove

We still need the interaction that implements the player's action of sending the selected units to a specific point. Create an interaction in the Arena object called orderMove that accepts a parameter called position that is an Array of Numbers.

This is its code:

  1. local units = Arena:getObjectsByName("Units")[1];
  2.  
  3. for i,v in ipairs(units:getObjects()) do
  4. if v:getAttribute("selected") == "1" then
  5. v:exec("goTo",position[1],position[2],position[3]);
  6. end
  7. end

This cycles through all objects inside the object Units, in this case, through every unit in the game. If the unit is selected, then it executes the interaction orderMove.

Finally, you need a listener to execute this interaction. This listener will detect the clicks on the terrain and send the click position to the orderMove script. Right-click on the Arena object in the tree >> new >> interaction. In the Listener Editor:

  • Set the type to Mouse.
  • Set the action to Mouse Left Pressed.
  • Set the interaction to orderMove.
  • Select the parameter position and press the button set.
  • Set the parameter value to Absolute Position.

Camera

Most RTS use the bird-eye view, and we will show how to configure one in ludiloom. Right-click on the Arena object in the tree >> new >> camera.

In the Camera Editor make the following changes:

  • Set the name to cam.
  • Set the Move Speed X to 10.
  • Set the Move Speed Z to 10.
  • Set the Move Limit X between 300 and 1200.
  • Set the Move Limit Z between 500 and 1500.

The terrain is 1500 (by default, you can change this in the Terrain Editor), so we limit the movement of the camera in a way that the player never sees the edges of the terrain.

  • Set the Min Zoom Distance to 200.
  • Set the Max Zoom Distance to 600.
  • Activate Use Screen Edges to Move the Camera.
  • Activate Use Mouse Wheel to Zoom.
  • Activate Use Terrain Height Instead of a Fixed One.
  • Press new.

Then, right-click on the camera and press rotate:

Press tab to change the widget to the correct axis and rotate the camera like this:

To activate this new camera, write in the console (F11):

Arena:setActiveCamera("cam");

Switch to play mode (alt + 1) and test your game!


 Toolbox
About ludiloom     Terms & Conditions     Privacy Policy     Contacts
ludiloom® is a registered Trademark of Tapestry Software, Lda.
© Tapestry Software, Lda. All rights reserved, 2005-2009.
Tapestry Software