Hiya chaps.
I have a question regarding the implementation of a GTA 3 kind of system, where your character strafes and moves foward using the keyboard, and rotates using the mouse.
The only snag I've hit in creating this kind of thing is pretty major. Just how do you get the node to move foward according to it's rotation?
(I tried using the forum search but I think my browser is cooked, because I keeping getting the same results over and over for a previous search)
Thanks in advance for any help.
Node Movement Using Mouse && Keyboard
Node Movement Using Mouse && Keyboard
"I once had a koala bear infestation. It was the cutest infestation ever."
I'm not familiar with GTA so bear with me......
I assume you want a 3rd person camera like Tomb Raider etc?
If so you also have the problem that the camera is not point directly at the rotation of the node. The user swings the mouse, the character knows to turn left 30 degrees, the character doesn't do this straight away, there is a deliberate lag time of like 1 second. Then the camera also deliberately lags and only starts to move to the left once the character has started.
You also have the problem that the animation of the character, to look realisitic has to shift its weight before it moves (in case you quickly turn back the other way). This way you need one heading tracking the character, one heading for where the camera should end up (where the mouse is pointing) and another heading for the camera itself. And plenty of tricky animation for the character becuase it is a major part of the player's experience being in front of the camera the whole time.
Remember the game Draken? Witha chick and her dragon as the main characters? It was third person and the main character and the dragon's animations, models, textures etc were something like 35megs. This is because the main character and the dragon were in front of the camera the whole time and needed to look really good.
By no means is it impossible to do, it will just take a bit of doing.
I assume you want a 3rd person camera like Tomb Raider etc?
If so you also have the problem that the camera is not point directly at the rotation of the node. The user swings the mouse, the character knows to turn left 30 degrees, the character doesn't do this straight away, there is a deliberate lag time of like 1 second. Then the camera also deliberately lags and only starts to move to the left once the character has started.
You also have the problem that the animation of the character, to look realisitic has to shift its weight before it moves (in case you quickly turn back the other way). This way you need one heading tracking the character, one heading for where the camera should end up (where the mouse is pointing) and another heading for the camera itself. And plenty of tricky animation for the character becuase it is a major part of the player's experience being in front of the camera the whole time.
Remember the game Draken? Witha chick and her dragon as the main characters? It was third person and the main character and the dragon's animations, models, textures etc were something like 35megs. This is because the main character and the dragon were in front of the camera the whole time and needed to look really good.
By no means is it impossible to do, it will just take a bit of doing.
-= Want your C code to control real life robots? www.users.on.net/~symes =-
The engine will not do this for you - you have to write the code yourself. How you do it, depends on HOW you choose to store the position of your character and HOW does your game work. A short example in BASIC (engine agnostic):The only snag I've hit in creating this kind of thing is pretty major. Just how do you get the node to move foward according to it's rotation?
Code: Select all
10 let x=100
20 let y=100
30 let speed=10
40 let angle=0
50 print "coords:",x,y
60 if left then angle=angle+5
70 if right then angle=angle-5
80 if forward then x=x+speed*sin(angle):y=y+speed*cos(angle)
90 goto 50
Hope this helps.[/code][/quote]
It's actually quite easy.
You have a camera and a node ( your character ).
You need to maintain your 3 "world vectors" ( Right [ X Axis ], Forward [ Z Axis ], Up [ Y Axis ] ). After rotating your camera ( there are functions in Irrlicht to rotate vectors around certain axes in the vector class called - RotateXZBy(...), RotateXYBy(...) and RotateYZBy(...) ) you'll then need to re-calculate your "world vectors". Here's some simple code to do that, based on the camera postion and the node position -
This is not all, however, you also must now, when moving do it based off of these forward and right vectors, not the standard X and Z axis. So for instance, if you pushed the key to move you forward, you would do the following to move your node ( and camera forward )
Hope this helps, and you understand me, if not, ask away, I'm bad at explaining this stuff sometimes.
Oh, also, doing it this way, you'll need to maintain these vectors yourself. The CCameraSceneNode class in Irrlicht only maintains an UpVector.
You have a camera and a node ( your character ).
You need to maintain your 3 "world vectors" ( Right [ X Axis ], Forward [ Z Axis ], Up [ Y Axis ] ). After rotating your camera ( there are functions in Irrlicht to rotate vectors around certain axes in the vector class called - RotateXZBy(...), RotateXYBy(...) and RotateYZBy(...) ) you'll then need to re-calculate your "world vectors". Here's some simple code to do that, based on the camera postion and the node position -
Code: Select all
// Compute new forward vector (line of sight vector) ( Z Movement Axis )
forwardVector = node->getPosition ( ) - camera->GetPosition ( );
forwardVector.normalize ( );
// Compute new right vector ( X Movement Axis )
rightVector = WORLDUPVECTOR.crossProduct ( forwardVector );
rightVector.normalize ( );
// Compute new up vector ( Y Movement Axis )
upVector = forwardVector.crossProduct ( rightVector );
Code: Select all
movementVector = forwardVector * ( movementAmount );
nodePosition += movementVector;
cameraPosition += movementVector;
Oh, also, doing it this way, you'll need to maintain these vectors yourself. The CCameraSceneNode class in Irrlicht only maintains an UpVector.
The one trick, I haven't yet figured out, is how to rotate the camera and the node the same amount.
For example, I have, in my game so far, they keys setup so that W and S move forwards and backwads, Q and E strafe left and right, and A and D turn left and right. When turning, I turn teh node at 0.01f degrees each render pass. I call a function I have called RotateY2D and here's the code for it -
So when I press A to turn left, I do this -
The problem here is the node ends up rotating faster than the camera. I'm not sure how to go about lining them up, so that the camera is always directly behind the node, based on the direction the node is facing. If anyone's got any pointers on that, it'd be great!
For example, I have, in my game so far, they keys setup so that W and S move forwards and backwads, Q and E strafe left and right, and A and D turn left and right. When turning, I turn teh node at 0.01f degrees each render pass. I call a function I have called RotateY2D and here's the code for it -
Code: Select all
const float fPI = 3.14159265359f;
core::vector3df RotateY2D ( float degrees, core::vector3df center, core::vector3df rotation )
{
degrees *= fPI / 180.0f;
float cs = cosf ( degrees );
float sn = sinf ( degrees );
// Translate to the world's origin
rotation.X -= center.X;
rotation.Y -= center.Y;
// Rotate
rotation.Y = rotation.X * sn + rotation.Y * cs;
// Translate back
rotation.X += center.X;
rotation.Y += center.Y;
return rotation;
}
Code: Select all
if ( m_key_buffer[KEY_KEY_A] ) // Rotate Node Left
{
newNodeRotation = movementNode->getRotation ( );
newNodeRotation = RotateY2D ( 0.01f, newNodePosition, newNodeRotation );
movementNode->setRotation ( newNodeRotation );
cameraPosition.rotateXZBy ( 0.01f, newNodePosition );
Bah, this was so easy, and I was making it so complicated!!!
Anyways, to rotate say 1 degree around the Y axis, all you have to do is
Then, to rotate camera the same degrees, you just do -
Can't believe how simple this was and I made it so complicated! Should have read the help file more closely for Irrlicht!
Anyways, to rotate say 1 degree around the Y axis, all you have to do is
Code: Select all
core::vector3df rotation = node->getRotation ( );
rotation.Y += 1.0f;
node->setRotation ( rotation );
Code: Select all
nodePosition = node->getPosition ( );
cameraPosition = camera->getPosition ( );
cameraPosition.rotateXZBy ( 1.0f, nodePosition );