Game Development Community

Beginner's scripting question: Player control

by MarkH · in Torque Game Engine · 03/11/2008 (8:26 am) · 7 replies

Can somebody help me with these two beginner's questions:

1) How do I identify the player object in a .cs script?

2) How can I control the player? I need to do one or more of the following:
- query the player's position and direction of movement
- force the player to move in a specific direction (force a specific yaw)
- set the player's speed of forward motion

Apologies if this is covered somewhere - I tried to search the forums but found nothing. Maybe this is too basic?

Thanks for any help!

About the author

Recent Threads


#1
03/11/2008 (8:46 am)
TDN is a great resource for beginners. The forums are cool, but sometimes cumbersome to sift through.

TDN AI Page
#2
03/11/2008 (9:53 am)
Got it. So what I read in those pages provides answers to my questions as follows:

1) How do I identify the player object? Player == camera, is that right?

2) a - query the player's position and direction of movement?

If the previous answer is right, then I can use LocalClientConnection.camera.getTransform() to query position and rotation. I also guess that the rotation part of the transform "1 0 0 15.5" would indicate a 15.5 degree yaw?

b - force the player to move in a specific direction? My guess would be LocalClientConnection.camera.setTransform() - would this work? Or if I say with the example,
Bob.setMoveDestination(...) what do I need to replace "Bob" with to address the player? This brings me back to Question 1.

c - set the player's speed of forward motion?

Still no clue.

Thanks for your help!
#3
03/11/2008 (10:41 am)
Continue to search the TDN for scripting examples as that would seem like your primary difficulty.

learning how to use the scripting language is crucial. TDN Scripting

1) Player does not equal camera. Player == Player (the class). Searching the scripting files you find a Player creation method used by GameConnection (localclientconnection)

// important parts of it:
...
 // Create the player object
   %player = new Player() {
...
 // Player setup...
   %player.setTransform(%spawnPoint);
   %player.setShapeName(%this.name);
...
 // Give the client control of the player
   %this.player = %player;
   %this.setControlObject(%player);
...

We see that the player is set as the "Control Object" of the GameConnection. Well, using the .dump() method, we see that we can "getControlObject" from the GameConnection.

LocalClientConnection.dump();
...
  getControlCameraFov() - 
  [b]getControlObject() - [/b]
  getCount() - set.getCount()
...
%player = LocalClientConnection.getControlObject();

It now seems that we have %player access!

2) Player position
%pos = %player.getPosition();

direction of movement will have to be discovered on your own. eg. record several positions and derive your answer from that. If all you want is the current facing direction (rotation)
%mat = %player.getTransform();

Searching the engine we see that the function "getTransform()" does the following

ConsoleMethod( SceneObject, getTransform, const char*, 2, 2, "Get transform of object.")
{
	char *returnBuffer = Con::getReturnBuffer(256);
	const MatrixF& mat = object->getTransform();
	Point3F pos;
	mat.getColumn(3,&pos);
	AngAxisF aa(mat);
	dSprintf(returnBuffer,256,"%g %g %g %g %g %g %g",
		pos.x,pos.y,pos.z,aa.axis.x,aa.axis.y,aa.axis.z,aa.angle);
	return returnBuffer;
}

You have your "yaw" in there somewhere.

2b) specific direction of movement: couple things. a) figure out which buttons do what and why. You can control the object and use the "W A S D" keys to move it. setMoveDestination will not work on a "Player". It will work on an AIPlayer. If you give reasons why you want this sort of functionality, I might be able to give a better solution.

2c) speed of forward motion is defined in the datablock. Which are explained in the above link.
#4
03/11/2008 (5:22 pm)
(edited post to follow up)

Thanks, William - your code works. Since searching the forum for "localClientConnection.getControlObject returns only one hit, I thought I post some of my experiments here to share with others.

As you wrote, localClientConnection.dump() dumps long list of methods. Also, echo(LocalClientConnection.getAddress)); returns "local" as it is supposed to. So a server connection exists.

If you type commands in the console, the player variable should be global, so

$player = LocalClientConnection.getControlObject();

Now it is possible to play with the $player variable:

% echo ($player.getID());
1507

echo ($player.getPosition());
190.931 458.708 181.701

% echo ($player.getTransform());
190.931 458.708 181.701 0 0 1 1.97031

etc.

Thanks again. I'll continue posting questions or - hopefully - solutions.
#5
03/11/2008 (8:01 pm)
William Jonny Brannum wrote:

"setMoveDestination will not work on a "Player". It will work on an AIPlayer. If you give reasons why you want this sort of functionality, I might be able to give a better solution."

I'd like to have the player follow an exact trail defined by a series of 1500-2000 coordinates. The velocity would be provided by a treadmill or stationary bike. I have a script that, bound to a key, allows continuous forward motion (no big deal):

$continuous_forward = 0;
function toggleForward (%val)
{
if (%val) // Do this only on make, not on break.
{
$continuous_forward = ! $continuous_forward;
echo ("Continuous forward motion is set to ",$continuous_forward);
$mvForwardAction = $continuous_forward * $movementSpeed;
}
}

Now I need to control the player's yaw so that it follows closely the path defined by the vertices. I am mentioning the high number, because I think that waypoint markers would be impractical.

How would you do this? Thanks for any hints.
#6
03/11/2008 (9:03 pm)
You did half the work with the continuous forward function. There is another function in default.bind.cs that allows for yaw manipulation.

function yaw(%val)
{
   $mvYaw += getMouseAdjustAmount(%val);
}

It alters the $mvYaw variable which is linked with the mYaw variable member of the MoveManager

void MoveManager::init()
{
...
   Con::addVariable("mvPitch", TypeF32, &mPitch);
   Con::addVariable("mvYaw", TypeF32, &mYaw);
   Con::addVariable("mvRoll", TypeF32, &mRoll);
...
}

and accessed in GameConnection's getNextMove(Move&) function

bool GameConnection::getNextMove(Move &curMove)
{
...
   F32 pitchAdd = MoveManager::mPitchUpSpeed - MoveManager::mPitchDownSpeed;
   F32 yawAdd = MoveManager::mYawLeftSpeed - MoveManager::mYawRightSpeed;
   F32 rollAdd = MoveManager::mRollRightSpeed - MoveManager::mRollLeftSpeed;

   curMove.pitch = MoveManager::mPitch + pitchAdd;
   curMove.yaw = MoveManager::mYaw + yawAdd;
   curMove.roll = MoveManager::mRoll + rollAdd;
...
}

which is eventually called to during the player's processTick(Move *) function.

Long story short. Altering the $mvYaw variable will allow you to alter the players yaw. Probably not the best way to do it though... heh.

Why would you not use an AIPlayer for this? It sounds like almost everything is automated or run by script. Perfect job for an AIPlayer. You could create just a camera for you to see what they AI is doing. Check out the demo walkthrough. It has a camera that follows a preset path.
#7
03/12/2008 (8:01 am)
William,

thanks again for your help. You are right that $mvYaw can control the player's yaw, but it is tricky. The $mvYaw variable stores a relative yaw motion. For example if you enter

$mvYaw = 0.78;

the player will turn 45 degrees clockwise (positive=clockwise). Then, $mvYaw will become zero once the movement is completed.

So if you want an absolute orientation, it is necessary to first get the present yaw angle using %player.getTransform(); as described above. Note that getTransform() provides the rotation axis and the angle - both may carry signs. Then you'd have to compute the difference between present and desired yaw and store this in $mvYaw. The resulting yaw is close (but not exactly identical) to the desired one. A closed-loop feedback system would provide a possible solution.