Game Development Community

how to make shapes moving?

by Isidore · in Torque Game Engine · 06/15/2002 (1:31 pm) · 13 replies

Hello!

I am completely new to Torque SDK.

I face a simple problem: I have a DTS 3d model and I would like to make it move.

I having already checked all the forums, I cannot find any information on this.

Could some one tell me what files should I edit?
I am really completely lost :(

All i succeeded till now is inserting my model as a TSStatic. I would just like to make it move, like a NPC.

The purpose of this would be to add a basic NPC.
I checked the NPC support thread and the bots thread, but I am still unsure about the way to do it.
(with the NPC support, I could insert my model, but it still doesnt move. and as for the bots, I wouldnt want this NPC to have tons of stats and parameters)

If someone any information for a newbie like me...

Thanks anyway for your having read this.


Isidore

#1
06/16/2002 (4:12 am)
I really go blindly...

Should I make a derived class from ShapeBase
then override the createMove() function?

Or someone has another idea?

It is really difficult to learn how to use this engine...
#2
06/16/2002 (6:31 am)
If you are looking into adding NPC's check out the aiPlayer code (aiPlayer.cc and aiPlayer.h)
They aren't included in the VC++6 WorkSpace but the files are there, just add them both to the game/ directory.
Good Luck
#3
06/16/2002 (4:04 pm)
Thanks for your advice!

I checked these files, but it seems it was not exactly what I was looking for. Bots are far too much than what I expect from NPC.

Anyway, I could solve the problem by derivating the ShapeBase class, and force to create a move when the object is not controlled by a client (as it is the case for a NPC)

Thanks anyway!

Laurent
#4
06/17/2002 (9:00 am)
I had some responses to your other post in "engine" forum:
www.garagegames.com/index.php?sec=mg&mod=forums&page=result.thread&qt=3608

What do you have in mind to force the move of non-client-controlled shapes?
#5
06/17/2002 (2:25 pm)
Hi Desmond!

Thank you for your reply!
I read your other post. As I am new to Torque, I didn't even know we could animate the shape from the script. ehe ^^;
great anyway!

"What do you have in mind to force the move of non-client-controlled shapes?"
My goal is to have NPC in the games.
(ie: not a bot which have the same abilities as a player)

I checked the aiPlayer function. I tried and added a bot as well. It works nice. The problem is, I am not sure whether
I have much "control" on the bot.
The bot is not only a moving shape. It derives mysteriously from an aiConnection class
(no idea what it is. now you can see I am a real newbie :) )
I guessed (probably wrongly) that the bot would be some kind of "emulated" client.

I wanted a NPC, with defined properties, which can move and be animated.

I checked your other post. It enables to animate the shape, but it doesn't seem to enable moving them, does it?
I kept on reading the forum's posts, and I found one on "moving shapes"

http://www.garagegames.com/index.php?sec=mg&mod=forums&page=result.thread&qt=4735

So I made a PlayerNPC / PlayerNPCData class (based on Player/PlayerData), I forced a move when it is not client-controlled.

And the result of this is that I have a now NPC who I force running around, can jump etc, with a class which I can control easily.

The problem of this is: the way I did it now, its AI will be located in the PlayerNPC class.
Which is it self a ShapeBase derived object. Putting AI in a Shape class doesnt look very "appropriate" (^_^;)

I am pretty sure there is a better way to do it, but I haven't found it.

Anyway thanks for your post!

Laurent
#6
06/17/2002 (2:56 pm)
just take aiPlayer as a base to build your npc, you'll simply be using different datablocks, not the default player ones, ie with less energy, or diff speeds, etc..
#7
06/17/2002 (7:58 pm)
The problem (for me anyway) is that I haven't figured out a way to access the animation threads for the aiPlayer (which derives characteristics from the player class). Now, I understand that some of the animations are keyed to movement parameters (so the run thread is called when a setMove() is called. But what if I want a "scratchButt" animation; how would I access that thread (like in the shapeBase playThread).

Laurent, what did you do in your NPCData class to get a shape to move? Could you share some of that with me? I think I'm looking for the same thing as you are.
#8
06/18/2002 (2:31 am)
To tell the truth, I don't understand exactly the aiPlayer class.
I am not sure how it works...

Quote:
"aiPlayer (which derives characteristics from the player class)."

well, this the link I don't manage to see.
in the code, we have

class AIPlayer : public AIConnection
class AIConnection : public GameConnection
class GameConnection : public NetConnection
class NetConnection : public ConnectionProtocol, public SimGroup

which, as far as I can guess, means that the AIPlayer kind of emulates a client
No idea where the link to the player class is, though
But as I said, I am very new and I haven't understood much of the engine yet :)

"Laurent, what did you do in your NPCData class to get a shape to move?
Could you share some of that with me? "

Sure.

- My NPC data is for now a simple copy of the player class.
as same as player.cc and player.h describe the classes PlayerData and Player, I added
files player_npc.cc and player_npc.h that described PlayerNPCData and PlayerData
(ie: copy paste, replace "Player" by "PlayerNPC" :D )

Indeed, all the movement code/collision check and so on is managed in the player class. so, I though it was a good start

- Next, I added a virtual function in ShapeBase.h

virtual bool create_move(Move* my_move_struct);

(if the shape creates a move, it fills in the movement structure and return true. otherwise returns false

so the default create_move funtion, in shapeBase.cc, looks like

bool ShapeBase::create_move(Move* my_move_struct)
{
  // no default move
  return false;
}



This function is the one that enables a shape to create its movement

- in the gameProcess.cc, there is a loop which moves objects
line 171 in void ProcessList::advanceObjects()

// Each object is either advanced a single tick, or if it's
// being controlled by a client, ticked once for each pending move.
if (obj->mTypeMask & ShapeBaseObjectType) {
  ShapeBase* pSB = static_cast<ShapeBase*>(obj);
  GameConnection* con = pSB->getControllingClient();
  if (con && con->getControlObject() == pSB) {
    Move* movePtr;
    U32 m,numMoves;
    con->getMoveList(&movePtr, &numMoves);
    for (m = 0; m < numMoves && pSB->getControllingClient() == con; )
      obj->processTick(&movePtr[m++]);
      con->clearMoves(m);
    continue;
  }
}

the NPC is not client controlled, so I changed the function to call the create_move function if the shape is not
client-controlled

if (con && con->getControlObject() == pSB) {

  [...]
 
  } else { // if not client controlled
    Move shape_move;
    if(pSB->create_move(&shape_move)){
      obj->processTick(&shape_move); // processes move if any
    }
  }



(I write this code from what I remember, I don't have the files in front of me :)
there are probably compilation bugs =/ )

- last, I forced the the NPC running :
in PlayerNPC.h I added

virtual bool create_move(Move* my_move_struct);

and in PlayerNPC.cc, I added a custom create_move function:

bool PlayerNPC::create_move(Move* my_move_struct)
{
   my_move_struct->px=16; // no idea what it is, it is the value I saw in player in the debugger
   my_move_struct->py=16; // idem
   my_move_struct->pz=16; // idem

   my_move_struct->pyaw=0;   // not sure here
   my_move_struct->ppitch=0; // idem
   my_move_struct->proll=0;  // idem

   // force running
   my_move_struct->x=0.0;  // 
   my_move_struct->y=1.0;   // go forward
   my_move_struct->z=0.0;  

   my_move_struct->yaw=M_PI/30.0; // force turning
   my_move_struct->pitch=0.0;
   my_move_struct->roll=0.0;

   //U32 id;               // sync'd between server & client - debugging tool.
   //U32 sendCount;

   my_move_struct->freeLook=false;   // not sure
   for(int i=0;i< MaxTriggerKeys; i++){
     my_move_struct->trigger[i]=false;
   }
   
  return true;
}

I added a player_npc.cs file (here I don't remember how I did it exactly. I am really not familiar with scripts)
but after adding the NPC from the editor, it kept on running on a circular movement

Besides, it has all the collision detection handled in the player class, the movement calculation (when climbing slopes etc)

I am not sure if it helps, but that is the only solution I found for now.

Quote:"I think I'm looking for the same thing as you are."
Let's find a proper solution to handle NPCs then :).
There is surely a better way to handle them than the way I do it for the moment :D

Thanks for the tips in your post anyway. I am still at the stage of discovering and exploring the SDK ;)

Laurent

PS: sorry if I screwed up with the Markup Lite (I haven't posted much)
#9
06/18/2002 (10:21 am)
Did you also create a PlayerNPCObjectType in ObjectTypes.cc?
Or set:
mTypeMask |= ShapeBaseObjectType;
#10
06/18/2002 (1:04 pm)
mmm... no . Should I
for the moment it uses the same as the player
PlayerObjectType or sth that looks like.

But I am not sure what this corresponds too :)

Laurent
#11
06/18/2002 (1:10 pm)
Hmmm,not sure; is this a shapebase or player object
I have some other questions/thoughts also:

1) How did you add your npc to the world?

2) It might be easier to use/extend the AIPlayer to access the player animations better (more control). Before this thread got started, that was the direction I was searching: in addition to the 8 primary animations that are derived from the player class, there must be a way to access other animations built into the model. If this can be done there would be no need for a playerNPC class (I think). Then within the aiplayer.cc functions to access (i.e. playThread) the non-primary animations.
#12
06/19/2002 (5:43 am)
Hi Desmond!

Quote:1) How did you add your npc to the world?

mmm... I made a player_npc.cs based on player.cs
basically, I replaced all the PlayerData to PlayerNPCData

then I added a new Category
("Armor" -> "NPC")

and replaced all the (Armor::) functions to NPC::

then added it from the editor

Quote:2) It might be easier to use/extend the AIPlayer to access the player animations better (more control).

mmm... more control on the NPC, maybe.
(anyway attacking directly the ShapeBase, gives the most control on the shape doesn't it?)

Quote:
If this can be done there would be no need for a
playerNPC class (I think). Then within the aiplayer.cc functions to access (i.e. playThread)
the non-primary animations

I see. by the way, I just noticed the Player* m_player in the aiPlayer.h.
Finally I see the link :)

so to make a NPC, it would look like a class AIPlayerNPC based on AIConnection,
with a member variable PlayerNPC* m_player?

All we would need to do is to fill in its move list in a way or another in fact.
I am not sure where, though

And I think we still need a PlayerNPC class don't we?
because the Player class is linked to the PlayerData.
aren't those that define the NPC?
Besides the Player class describes the player humanoid shape and physics.
a NPC could be non humanoidm and use different parameters than the one in the Player class

so, where to store the NPC-only parameters?

Maybe I am just misunderstanding everything...

Anyway thanks for your advice!

Laurent
#13
06/20/2002 (2:01 am)
I wonder if aiPlayer suits for a NPC in fact...

There is something that seems weird:

I read in aiPlayer.cc:

// Add the connection to the client group
   SimGroup *g = Sim::getClientGroup();
   g->addObject( aiPlayer );

and further on:

// Execute the connect console function, this is the same 
   // onConnect function invoked for normal client connections
   Con::executef( aiPlayer, 2, "onConnect", name );

It looks that the aiPlayer really emulates a client and connects it to the server. The only difference with a Player is that this client is not human controlled.

I read somewhere earlier that the number of player in a games is limited to 128.
If a NPC is to be count as a Client, this means we cannot have more than 128 player+NPCs?

This is quite limiting for a RPG for example.

or maybe I mistake somewhere...

Laurent