Game Development Community

GameCamera: a third person, aiming camera (that works!)

by Michael Bacon · in Torque Game Engine · 09/13/2007 (6:44 am) · 81 replies

Update: I have fixed the jitter and the issues I had with the network code. I think everything is working as it should be.


Well, I've been working on a new third person camera. I wanted the player to aim where my third person camera is looking.

This has been sought after by quite a few people including myself. I didn't find what I was looking for elsewhere so here is my attempt.

I've got the basics working. This camera was built on a HUGELY modified Advanced Camera but has pretty much grown into its own being. It is now called the GameCamera.

Features:
Third person camera
Player fires where camera is looking
The server controls where the camera should be


Caveats:
No server side interpolation is done (for instance if you switch targets the client side will interpolate the difference in like one tick but the server will have already been there. I hope to add this later.


Download here and add gameCamera.cc and gameCamera.h to your project in under the engine\game folder.

Video here shows the camera in action while fighting a bot.

------------------------------------------------

If you follow all the directions here (especially the one about setting the 'correctMuzzleVector = true' value on your weapon datablock) you will have a third person camera and a player that fires at the center of your screen.

------------------------------------------------

In order to implement the camera you need to make a few changes...
#21
09/28/2007 (3:24 am)
I did use the information from other resources for a lot of this work but I'm sure that the only change needed for the crosshair is commenting out that one section of the if statement. Make sure that you have a guiCrossHairHud element in your playgui. Other than that, if you have the capabilities put a breakpoint in the onRender method of the guiCrossHairHud and see if it is being called.

* I just double checked (did a DIFF between the two files) and the only change to the cross hair is the one above.
#22
09/28/2007 (5:51 am)
I did try a breakpoint and it is being called, so I have no clue what is going on. I also have checked the playgui and everything is there that is supposed to be. It's been quite awhile since I've had to use any of my C++ knowledge so it's taken me a bit to get back up to speed.

I think at this point I'm going to start with a fresh build of TGE 1.5.2 and go through those other resources, and then come back here to see the difference.

Speaking of which, Brian are you using TGE 1.5.2, or an older version? Just trying to see if maybe a different version might be the problem because there is some new gui elements in TGE 1.5.2, with health status being showed on the crosshair hud that, I think, wasn't there before.
#23
09/28/2007 (6:04 am)
I'm using 1.5.2 and my crosshair shows health status just fine. If you're thinking about starting with a fresh engine how about implementing the camera first?

I just have a feeling its something small, does the texture exist?
Did you alter the gui hud element parameters in any way (some resources suggest this).
Did the crosshair show up before you implemented this resource?
Has it been hidden somewhere else in code?

If the onRender method is being called and is not being exited early for some reason then I would think it would be a problem with your resources.
#24
09/28/2007 (6:47 pm)
Looks great except for the fact that I get really bad camera shaking when I move the target up or down. Any suggestions?
#25
09/29/2007 (3:09 am)
I have minor shaking issues mostly while falling. I'm not sure exactly why but I know that the server doesn't do any position interpolation (yet) so it might be that. However the client side is supposed to smoothly interpolate. I dunno.

Can you describe a little better what kind of environment you are using this in? Is it multi player or single player? Does it happen when you jump up and down or only when you fall a long distance?

It might also have to do with your target object. What is the target object?

Also make sure you are using the most current version of the source the original files I posted here had terrible shaking issues but the current versions are quite smooth.
#26
09/29/2007 (9:36 am)
I downloaded them last night shortly before I posted, and put the files into a fresh install of 1.5.2. The shaking occurs whether or not I am targetting a particular object or not. If I move the mouse vertically I get bad shaking. I was using the barebones FPS mission. I could FRAPs a video and put it on youtube or something of what is happening if that would help?
#27
09/29/2007 (10:51 am)
Well, I went ahead and tried to implement this myself on a clean install and to say the least I've hit a snag or two.

Edit: I noticed a small problem with this and corrected it...

First of all I made one posting boo-boo in gameProcess.cc
Change the two blocks of code that looks like this:
{
            control->processTick(&movePtr[[b]m++[/b]]);

            // give camera a chance to look at movement
            if (camera && camera->mProcessTick)
               camera->processTick(&movePtr[[b]m[/b]]);
         }

to this (notice the position of the ++'s (increment operators)):
{
            control->processTick(&movePtr[[b]m[/b]]);

            // give camera a chance to look at movement
            if (camera && camera->mProcessTick)
               camera->processTick(&movePtr[[b]m[/b]]);

            [b]m++;[/b]
         }


I found another bit that I forgot about that was keeping getCorrectedAim from even being called.

In ShapeImage.cc line 942 and line 965 - yes two IDENTICAL lines that need to both be modified from:
if (gc->isFirstPerson() && !gc->isAIControlled())
to..
if ([b]/*gc->isFirstPerson() &&*/[/b] !gc->isAIControlled())


Finally I don't know if this is affecting anything or not (I doubt it at this point but it may in the future) see this article www.garagegames.com/mg/forums/result.thread.php?qt=49714 about fixing accuracy in the way connection move values are sent.
#28
09/29/2007 (11:15 am)
Also, here is a better version of the mod to getCorrectedAim() this requires that you also $include "game/gameCamera.h" at the top of ShapeImage.cc
// Correct the aim based on where the camera is looking.
   // This only happens for the control object iff they are the camera
   // objects active target AND the camera is a GameCamera.
   bool set = false;
   if (GameConnection * gc = getControllingClient())
      if (!gc->isFirstPerson())
         if (gc->getControlObject() == this )   // only for the control object
            if (ShapeBase* camera = gc->getCameraObject())
               if (GameCamera* gameCamera = dynamic_cast<GameCamera *>(camera))
                  if (gameCamera->getTargetObject() == this)   // only for a game camera's target object
                  {
                     eyeMat = camera->getRenderTransform();
                     set = true;
                  }

   if (!set) {
      getEyeTransform(&eyeMat);
   }



After making the changes noted in th eabove two posts, the camera appears to be working in a fresh copy of TGE 1.5.2.
#29
09/30/2007 (9:08 pm)
Hello, Brian

After implementing your fix, everything work great.

I'm going to test this in many situation.

Now, no problems found.

Thanks
#30
10/11/2007 (8:35 pm)
I've tried this, after all the fixes, I still get errors upon compiling. This is after a clean install of TGE 1.5.2 .

Here's the error I'm getting
19>shapeImage.obj : error LNK2019: unresolved external symbol "public: class ShapeBase * __thiscall GameCamera::getTargetObject(void)" (?getTargetObject@GameCamera@@QAEPAVShapeBase@@XZ) referenced in function "public: bool __thiscall ShapeBase::getCorrectedAim(class MatrixF const &,class Point3F *)" (?getCorrectedAim@ShapeBase@@QAE_NABVMatrixF@@PAVPoint3F@@@Z)
19>../example/torqueDemo_DEBUG.exe : fatal error LNK1120: 1 unresolved externals

As far as the 3rd person crosshair, it still doesn't show up. I'm assuming I need to add the jpeg somewhere in the scripts, I just have to find it.
#31
10/12/2007 (4:18 am)
It doesn't sound like you added the two soruce files to the code project. It is saying that they dont exist. If you did add the files to the project then try a clean rebuild.

The crosshair just uses the stock crosshair. So if you removed the texture that it uses or removed the control from your play gui you will have to put it back.

I did this on a clean 1.5.2 and I relayed all the extra changes that needed to be made in that situation.

Does your corsshair show up in first person mode? By default (no changes to stock 1.5.2) it should.

If that one shows up than there shouldn't be any issues with this.
#32
10/12/2007 (5:10 am)
Ok, It will compile on a clean build, but the crosshair still does not show up. I'll look into the matter myself, because I have not altered anything except what you have told us to and this is on a clean install of TGE 1.5.2. Yes, the crossHair .PNG is there and it's still in the playGui, so there must be something else, but I'll find the problem.

Sorry to be such a pain. Great resource!
#33
10/12/2007 (6:42 am)
I didn't mean to come off sounding annoyed or anything.

I want this to work for you so you can tell other people how good it is :)

I really didn't have to do anything to the crosshair other than change that one if statement.
#34
10/12/2007 (7:50 am)
Don't worry Brian, I didn't mean it to sound that way, I'm just getting frustrated by this and after all the other things I've tried to do, this one I just can't get to work.

Everything else works but the crosshair. I've commented out that one section in the guiCrossHairhud.cc, but I'm betting there is another one somewhere and I'm just going to have to find it.
#35
10/12/2007 (5:06 pm)
Breakpoints are your best friend. Put one at the top of the onRender call and step through it to see what is happening.

The crosshair drawing is done by the parent GuiBitmapControl. I haven't touched that. There are two if statements in the OnRender method that you need to check.

The first one checks to make sure you have a connection, the second makes sure you have a control object and that is an Object type.

If those two if statements are false then it will call onRender for the bitmap control.
#36
10/20/2007 (11:49 am)
Brian this is great, thanks for posting this.

I have added to my project and it works great and the crosshair does show up if you change that line in guiCrossHairHud.cc .

I'm noticing that my player runs faster in First Person. In 3rd person he walks like normal speed and in First person he got a turbo...
Just wondering if that happens too in your version.
#37
10/20/2007 (4:57 pm)
Huh, I've never noticed that but I don't use First Person Mode.

If you could run some tests I'd be very interested. Just see if you can compare you're player's velocities both in and out of first person mode.

The only thing I can think of is that it is an illusion (like the difference between looking out the side of your car and looking out the front).

I certainly haven't changed any of the control code.
#38
10/20/2007 (5:16 pm)
Brain I see the exact same thing Hans is. I have players that mount vehicles as well so I had a good chance to look at the velocity thing.

The difference is not that you can run faster, but that you reach top speeds much quicker.
#39
10/20/2007 (6:54 pm)
Well its not just that. Try firing a weapon in 1st person. It has sped up everything.
#40
10/20/2007 (7:42 pm)
Wel I found the problem code, not sure why yet.

It is in void ProcessList::advanceObjects():

// give camera a chance to look at movement
               if (camera && camera->mProcessTick)
                  camera->processTick(&movePtr[m]);

Take this out and first person works but it messes up third person. I would really like to use this code so I will continue to play with it a bit more.