Game Development Community

Getting Player Rotation-Still Stuck

by Matt Hughson · in Torque Game Engine · 03/17/2006 (8:51 pm) · 12 replies

Hey Guys,

I'm working on something based off of a little code snippet I found on here. The problem is this line:
%headRot = player().getHeadRotation();
This gives me an error, as player() does not appear to be a defined function. Does anyone know an equivilent function call that will get me the players head rotation? I'm trying to find the direction the player is currently looking at.

Or even some hints as to where I might find an equivilent function would help!

Thanks!
Matt

#1
03/18/2006 (5:35 am)
That's because player() isn't a defined function :-)

The player is an object, usually referenced by the handle %player. getHeadRotation() is one of Player Class' methods.
so you should use this :
%headRot = %player.getHeadRotation();

HTH
#2
03/18/2006 (10:58 am)
Ok that makes sense. Problem is, I am doing this in "../client/default.bind.cs", and it can not find the object %player. I do see a player object in "../server/game.cs". Is there someway I can access that object?

Update:

I decided I would try and add an accessor function to the game.cs script:
function GameConnection::getPlayer(%this)
{
   echo("Entered getPlayer.  Returning " @ %this.player);
   return %this.player;
}
I tried it a half dozen other ways (without the "this" pointer, without being scoped to GameConnection, etc), but it does not seem to know about "player", although I can see it used in other functions within the scope:
function GameConnection::onClientLeaveGame(%this)
{
   if (isObject(%this.camera))
      %this.camera.delete();
   if (isObject(%this.advCamera))
      %this.advCamera.delete();
   if (isObject(%this.player))
      %this.player.delete();
}
I'm really new to this, and can not figure out what to do...

Matt
#3
03/18/2006 (12:28 pm)
The latter example should and will work if everything else is setup correctly.

%this in your case, will be the connection, ie the client.
The function in your first codeblock is not usable, as it's already in C++ code.

%this.player = %player;
#4
03/18/2006 (12:39 pm)
Yeah the second function works fine; just using it as an example. Can you suggest how I might do this though?

Matt
#5
03/18/2006 (12:42 pm)
Matt,

Bruno already explained it. What is it that you want further explained?
#6
03/18/2006 (12:48 pm)
Well, I understand what he was suggesting. The problem is that %player is not a defined object in the script I am in, which is why I tried to write the getPlayer function, since I saw that the GameConnection was accessing a player object. Thought maybe I could just return the player.

So as far as I can tell I still have no way of getting the player's rotation.

Edit: Just for reference, I'm basically trying to implement the chunk of code at the bottom of this thread.

Matt
#7
03/18/2006 (12:58 pm)
Saw your edit, and I'm editing my post now.

Edit:

The problem is that the code Glen posted (no offence Glen) does not work and does not have the correct syntax for TorqueScript. No wonder you're confused.

First off, you don't put () at the end of player, as it's a object.. not a function. Checking the console log would reveal this, and is something you always should do if your code does not work.

Secondly, the client ID is *not* exposed to the function, and that's the important part. This is why I said to use the GameConnection function as an example, because they did it there.

Example:

%name = "Matt";
checkHisName(%name); // Look at that, you're including the variable as an argument
// to the function. You have to do this in some way or another.

function checkHisName(%name) // and again
{
    echo(%name);
}

Are you with me? If you don't specify the arguments, the variable will be NULL. In your case, that's %this.

GameConnection is your local client, and does not work the same way.
I'm not good enough in english to explain how that special case works, but it's documented in TDN and is really not too hard to understand - but you have to know the basics about arguments first.
#8
03/18/2006 (1:38 pm)
Well first off, thanks for you patience Stefan!

I'm afraid I am still a little lost though...

I understand the idea of parameters and arguments (I come from a C/C++ background), and understand why sending an empty parameter list to a function that takes a parameter is wrong.

What I don't know, is what I should be sending it. But I think we might be confusing the issue a bit. I'm not even sure that I need to write this accessor function (getPlayer); that was just a stab at a solution. I mean if I am just sending an object that already has access to the player, then why even bother with this function?

I guess the easiest way to put this is: If you needed the player's current rotation for a calculation, how would you get it?

Maybe if I explain exactly my path of logic, and how I got to this point, it might help explain what I am confused about.

---

First I found that code snippet I linked to earlier. I copy and pasted it into my script:
// This is inside ../client/default.bind.cs

function updateAim()
{
    ...
}

// Also inside the same file, I binded mouse movement to that function
moveMap.bind( mouse, xaxis, updateAim );
moveMap.bind( mouse, yaxis, updateAim );

But when I ran the game and moved the mouse things were not working correctly. I checked the console, and saw that it didn't know what player() is. So, with some help, tried changing that function call to a variable:
function updateAim()
{
    ...
   // Changed from    %headRot = player().getHeadRotation();
   %headRot = %player.getHeadRotation();
}
This still didn't work, as the colsole told me that it could not find the player object. So I searched through the scripts and found this:
// In ../server/game.cs
function GameConnection::createPlayer(%this, %spawnPoint)
{
   if (%this.player > 0)  {
      // The client should not have a player currently
      // assigned.  Assigning a new one could result in 
      // a player ghost.
      error( "Attempting to create an angus ghost!" );
   }

   // Create the player object
   %player = new Player() {
      dataBlock = PlayerShape;
      client = %this;
   };
   ...
}
So I figured, "Ok, this GameConnection thing seems to know about a %player object, so I will write an accessor function to grab that player it creates".
// Added to ../server/game.cs
function GameConnection::getPlayer(%this)
{
   echo("Entered getPlayer.  Returning " @ %this.player);
   return %this.player;
}
I see now this was kind of dumb for a couple reasons. a) if I am sending in an object just to return a member it contains, this function is pointless. I could just access the member directly from where ever I was calling it. b) GameConnection doesn't actually contain a player object. I was thinking about this more like a C++ member variable, but it was just a local variable, created and then sent elsewhere before it was cleaned up when we leave the function:
// In ../server/game.cs
function GameConnection::createPlayer(%this, %spawnPoint)
{
   ...
   // Create the player object
   %player = new Player() {
      dataBlock = PlayerShape;
      client = %this;
   };
   MissionCleanup.add(%player);
   
   ...

   // Give the client control of the player
   %this.player = %player;
   %this.setControlObject(%player);

   ...
}
In this case, a spawnpoint object was sent in as the %this parameter.
// In ../server/game.cs
function GameConnection::onClientEnterGame(%this)
{
   ... 

   // Create a player object.
   %spawnPoint = pickSpawnPoint();
   %this.createPlayer(%spawnPoint);
}

Matt
#9
03/18/2006 (1:50 pm)
I may be wrong because I dont know your script but I think you are trying to access a server side object from a client script. Which doesnt work, if the object is ghosted then you need to access it by a ghost id.

You need to learn about networking after you have got the hang of the syntax.

Just think of it like this if you dont know about it.
There are two different simulations running at once the client and the server
The server will send the info to the client to be rendered, all the physics and things are simulated on the server. The client (You) can manipulate the simulation on the server by sending your input which is processed on the server

Thats a really bad explanation :p
#10
03/18/2006 (2:06 pm)
There may be a better way to put this but
A script on server side player.cs?
servercmd**function name**(%client)
{
%player = %client.getcontrolobject() // Not sure if its right, may get the camera not the playershape
%player.getrotation() // Not a real function %rotation = %player.rotation might work

// Calculate

}

client side
commandtoserver('**functionname**')
Make sure it has ' ... ' because this makes it a tagged string

somthing along that lines
#11
03/18/2006 (2:11 pm)
Thank you John! I'm gonna give it a crack in a bit!! I'll let yah know how it goes :P

Question though, is the client parameter implied? Or do I actually need to send something?

Matt
#12
03/18/2006 (2:34 pm)
Hi Matt,

You don't have to manually send any arguments over, this is handled automatically for you in commandToServer/Client, kinda.

If you want to get the rotation of the client player (aim is different) then I would do it this way ON THE SERVER:

%client.player = %player;
%rotation = %player.getTransform();
// and then grab the last three words by using string manipulators.
// that way you'll end up with the rotation XYZ.

It is that simple. But if you want the client to ASK the server what the rotation is, you'll have to do what Josh describes above. You use the same method, but request it in a different way.

You will also have to prefix your function with "serverCMD" so it can be callable by the client (this is to avoid functions on the server being callable when they should not, for instance to cheat)

I want to grab the position of the player on the server, requested by the client.

On the client, call this:
Quote:
commandToServer('requestPosition');

On the server, this is the function that will be called:
function serverCmdrequestPosition(%client) // this is filled automatically with the ID
{
    %player = %client.player; // just to make it look more clean
    %position = %player.getPosition(); // grab the position
    commandToClient(%client, 'updateGuiWithPositionblabla', %position); // send it back to 
// the client who asked for the information
}

I have a feeling I'm misunderstanding somewhere, but maybe it will help.