Coding the Creature: Mouse Projecting

Hello, i’m Pol Urós, a member of The Creature Dev team, and a programmer too 😉

As Kevin said yesterday, we are going to publish posts about game design and programming, and today we are going to publish the first programming post in the blog  (focusing on unrealscript).

With David (the other programer of The Creature) we started a blog about programming in unrealscript along with examples of aplicating that articles in the creature. I and David are going to publish a series of a programming articles, first publishing all the articles in our blog, and then new articles.

So here are the first post, about Mouse Projecting. (Note that first, the blog are focused on only programming questions, but this is the blog of our game, the posts from the blog are a bit technical but in the new posts we will try to make that posts more easy-to-read to all people visiting the blog)


Hello everyone, i’m writing this article to help anyone having troubles with mouse system and canvas Project/Deproject system to make the projection of the mouse from the HUD to the 3DWorld.

We are currently working on a project in that we need the mouse in the HUD, to be projected in our world. Our project is basically a 2D Platformer but in a 3D world. So, when I first think in projecting the mouse into the world I remembered a function in Canvas called Deproject ( ). This function supposedly takes a ScreenPosition and outputs a vector in the world space and a vector for the direction.

So looking at the screen at the top left corner we have debugging information internal of our game, the scene itself and the red mouse pointer (almost in the upper middle position).

At the first view, we can’t notice what is wrong in the mouse but we can identify accurately what is happening if we make a trick:

Putting the Mouse over the Pawn position, the position of the Mouse and the Pawn should be the same (note: X axis of the Mouse are the same as the Pawn in our 2D game).

I red-highlighted the zones in the debugging information that we should focus to see the problem. Here we can see that the position of the Pawn and the Mouse are not the same.

First, I think I’m doing something bad (and I can still miss something, but I don’t have more time to loose and experiment with Canvas.DeProject), but after some days of investigation, I can see what I’m doing wrong, so I tried another way to project the mouse.

The idea behind this other way is the following: Project the pawn to the hud and an arbitrary point in our 3DWorld that we know his coordinates in the 3DWorld. We know the distance between this 2 points in the World (I tried a point that is Y+100 and Z+100 of the Pawn), so we have to see the relation of this 2 points in the HUD, and, knowing where the Mouse in the HUD was, extrapolate the relation of the pawn and calculate manually the Mouse in the 3DWorld.

Explanation in-depth:

(Note: I calculate this into the HUD class, I save the mouse coordinates in 2D in the PlayerController, our classes are have “TC” in the name, so, you can figure easily how to include it to your game).

In the PostRender() function, we make a call to our function for the calculation:

01 local Vector pawn100;//this variable is to save the point 100 units far in X and Y from the Pawn
03 pawn100.X = (TCPawn(PlayerOwner.Pawn).Location).X;//as sayed before, we ignore X
05 pawn100.Y = (TCPawn(PlayerOwner.Pawn).Location).Y + 100;
07 pawn100.Z = (TCPawn(PlayerOwner.Pawn).Location).Z + 100;
09 CalculateMousePos( Canvas.Project(TCPawn(PlayerOwner.Pawn).Location).X, Canvas.Project(TCPawn(PlayerOwner.Pawn).Location).Y, Canvas.Project(pawn100).X,Canvas.Project(pawn100).Y);
11 //And we make the call to our function for the calculation

Now, we have our function:

01 function Vector2D CalculateMousePos(float PawnX, float PawnY, float Pawn2X, float Pawn2Y)//we don’t have to return nothing, but it’s ok
03 {
05 local Vector2D ret;
07 local float PawnXdef, PawnYdef, MouseX, MouseY;
09 PawnXdef = Pawn2X - PawnX;
11 PawnYdef = Pawn2Y - PawnY;//Here, we substract the values of the pawn and the pawn+100 projected to see the diference in the HUD of the two points.
13 PawnXdef = PawnXdef/100;
15 PawnYdef = PawnYdef/100;//100 are the number of units added from the world location of the pawn, so, dividing this from the distance from the two points calculated in the HUD, we can stablish a relation between points into the 3dworld/HUD
17 MouseX = PawnX - TCPlayerController(PlayerOwner).PlayerMouse.X;
19 MouseY = PawnY - TCPlayerController(PlayerOwner).PlayerMouse.Y;//Here we pick de difference of positions, between the pawn and the mouse
21 MouseX = MouseX*PawnXdef;
23 MouseY = MouseY*PawnYdef;//And having the relation previously calculated we calculate the position the mouse should be in the real world.
25 TCPlayerController(PlayerOwner).MousePosWorldLocation.X = (TCPawn(PlayerOwner.Pawn).Location).X;
27 TCPlayerController(PlayerOwner).MousePosWorldLocation.Y = (TCPawn(PlayerOwner.Pawn).Location).Y - MouseX;
29 TCPlayerController(PlayerOwner).MousePosWorldLocation.Z = (TCPawn(PlayerOwner.Pawn).Location).Z – MouseY;//And finally, we put the mouse into the 3DWorld.
31 }

Final notes:

-First, i have to say there is another way to set the mouse positions using fov and camera properties knowing the position of the 3dworld located into the fustrum, i think the way described avobe is lightly less complex.

-For our game, that is possible to climb walls, we have to tune it a bit because when the creature is 90degrees inclinated and 180 or 270, the orientation of the camera is not the same and the calculation is slightly different.


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: