Game Development Community

Trying to develop an RTS camera

by Anthony Rosenbaum · in Torque Game Engine · 05/19/2004 (7:22 am) · 14 replies

Hello I have started some research developing an RTS camera. Basically a camera that can be moved and rotated indepenantly from the player.
Currently I am thingking of useing bot as the player avatar. Left clicking an area would tell the bot where to go. I have looked into some of the new camera classes that the community have been developed and nothing really has filled this niche.
Also I would like the camera movements to be tied to the mouse. Right clicking and draging to move thru the landscape, while using the mouse wheel to rotate. My inital attempts worked, to a degree, my main problem was the pitch and yaw control tended to cause the camera to keep moveing even when the mouse was left alone.
Here is the code
function yaw(%val)
{
   $mvRightAction += (getMouseAdjustAmount(%val) - $mvRightAction);
}

function pitch(%val)
{
   $mvBackwardAction += (getMouseAdjustAmount(%val) - $mvBackwardAction);
}
Right now the code doen't require any mouse buttons. binded.
Feel free to try this snippent maybe someone might figure out why it keep moving then the mouse is still.

#1
05/19/2004 (11:42 am)
Ok here is a vast improvement
function yaw(%val)
{
   //$mvYaw += getMouseAdjustAmount(%val);
   if($rtButtonDown)
     $mvLeftAction += (getMouseAdjustAmount(%val) - $mvLeftAction);
   else
    $mvLeftAction = 0;

   if($ltButtonDown)
     $mvDownAction += (getMouseAdjustAmount(%val) - $mvDownAction);
   else
     $mvDownAction = 0;
}

function pitch(%val)
{
  // $mvPitch += getMouseAdjustAmount(%val);
   if($rtButtonDown)
     $mvForwardAction += (getMouseAdjustAmount(%val) - $mvForwardAction);
   else
     $mvForwardAction = 0;

   if($ltButtonDown)
     $mvPitch += getMouseAdjustAmount(%val);

}
function rotateCamera(%val){
     // echo("rotation"@ %val);
      $mvYaw +=(%val * 0.001);
}
function parseMoveMent(%val)
{          //echo("right button down");
  if(%val)
   $rtButtonDown = true;
  else
   $rtButtonDown = false;
}
function parseLftMoveMent(%val)
{          //echo("left button down");
  if(%val)
   $ltButtonDown = true;
  else
   $ltButtonDown = false;
}
and thier binds
moveMap.bind(mouse0, "xaxis", yaw);
moveMap.bind(mouse0, "yaxis", pitch);
moveMap.bind(mouse0, "button1", parseMoveMent);
moveMap.bind(mouse0, "button0", parseLftMoveMent);
moveMap.bind(mouse0, "zaxis", rotateCamera);
#2
05/25/2004 (8:39 am)
Ok a week has past an major achomplishments on the work front. But with major achomplishments come major questions.

So far I have developed an interface as a gui, that controls the client's camera and binds a AIplayer to the gui also. When you use the right mouse you control camera panning, the mousewheel is used for camera zooming. Left clicking will tell the AIplayer where to go. This all works perfectly, on the server!

So then I decided to try multiplayer.Initally there were some major problems. My code was based around the editor,which has one camera for everone, well I fixed that issue by removing the static from those variables.So now each client CAN connect into the game and pan their camera around Yeah!

However when I tell the binded bot to move, as a client, I crash. Debugging tells me that the Point3F isn't set for the aiplayer or isn't right. There are other hints that point this way also.

Here are some images to help expain the next part of this post:
RTS Far

RTS Close

RTS Bot

RTS Lock

RTS Light

Aside from showing progress, there is some thing important in each of these images the "cross". The cross represent where the mouse point is in respect to the screen, this point is turned into a 3dMousEvent ( see EditTS.cc for details). Later this event is used to cast a ray to the terrain and draw the cross in worldspace on the screen.
Point3F startPnt = mLastEvent.pos;
   Point3F endPnt = mLastEvent.pos + mLastEvent.vec * 1000;
   RayInfo ri;
   hit = gServerContainer.castRay(startPnt,endPnt,TerrainObjectType,&ri);
   if(hit){
       ri.point.interpolate(startPnt, endPnt, ri.t);
       mMoveBotTo = ri.point;

dglDrawLine(Point3I(ri.point.x-50,ri.point.y,ri.point.z), Point3I(ri.point.x+50,ri.point.y,ri.point.z),ColorI(0,255,0));

dglDrawLine(Point3I(ri.point.x,ri.point.y-50,ri.point.z), Point3I(ri.point.x,ri.point.y+50,ri.point.z),ColorI(0,255,0));
}

Aside from allowing the dglDrawLine to take a Point3I instead of Point2I, everything here is out of the box Torque.

Some of my concerns come from the cameraMatrix in my
processCAmeraQuery there is this line
if (connection->getControlCameraTransform(0.032,&query->cameraMatrix))
however in onMouseMove there is
if ( GameGetCameraTransform(&mat, &vel) )

Both of which was used in EditTS


Or would my problem be that the ray is being casted by a gServerContainer

Anyway if any of you can help point me in the rigfht direction I would be most greatfull.
#3
05/25/2004 (9:48 am)
The client has no gServerContainer.

Also, are you sending a message to the server to tell it to move the bot, or are you trying to do it locally? The latter won't work.
#4
05/25/2004 (10:13 am)
Well replacing gServerContainer with gClientContainer got the cross to render. But when I click on the ground it crashes.

debug takes me here
void AIPlayer::setMoveDestination( const Point3F &location, bool slowdown )
{
[b]   mMoveDestination = location;[/b]
   mMoveState = ModeMove;
   mMoveSlowdown = slowdown;
}

So I am guess the message thing is needed. Could you please elaborate or point me in that direction.
#5
05/25/2004 (10:51 am)
Hm, hasnt this been done a couple of times before and is available as a resource?
#6
05/25/2004 (11:11 am)
Not that I know of
#8
05/25/2004 (6:28 pm)
@Stefan: He did say at the beginning that he looked at the community resources, and none really fit his parameters--and he's right. We're doing something similar (although our camera is more restrained), and while the Advanced Camera resource is an outstanding place to start, it doesn't quite describe his desired behaviour--I know, I've studied it for 2 days, heheh.
#9
05/26/2004 (6:16 am)
Advanced camera will not work for this I have tried =)
#10
05/26/2004 (8:31 am)
Anthony,

You're going to have to get your semantics matched up appropriately on the client and server. You can't do it all in the GUI control - some stuff is gonna have to get passed to the server and done there. :)
#11
05/26/2004 (3:11 pm)
For other people referance this resource is an absolute must http://www.garagegames.com/index.php?sec=mg&mod=resource&page=view&qid=4852
#12
05/27/2004 (7:03 am)
Ok I think I have 90% done

To summarize I have a Gui which controls a camera. You can also click on terrian to get differant location. By the use of the resource I pass the client's Id to the gui which is then transmitted via a net event.

like this
function GameConnection::onClientEnterGame(%this)
{ . . . 
//need to allow ghost list to be sent 
%this.schedule( 10000,"ghostList");
. . . 
}
then I send it to the client so it sets it on the correct GUI
function GameConnection::ghostList(%this){
    CommandToClient( %this, "SetAClientDragon", %this.GetGhostIndex( %this.player ));
}
Then I change Id to client Id and set it on the GUI
function ClientCmdSetAClientDragon( %DragonObjectGhostIndex ){
    %DragonObject = ServerConnection.ResolveGhost( %DragonObjectGhostIndex );
      RTSPlayGui.setDragon(%DragonObject); //GOOD FOR CLIENTs
      echo("client id is " @%DragonObject.getId());
}

Now my big problem is changing my clientId back into a serverObject.
The only thing that doesn't crash or hang up currently is this line
void BotMoveMentEvent::process(NetConnection *conn)
{
   Con::printf("Source Id is  %d  Bot Id is %d,Point is   %d : %d : %d", mSourceId, mId, pnt.x,pnt.y,pnt.z);
NetConnection* toServer = conn->getServerConnection();
SimObject *sim = toServer->resolveGhost(mId);
}
But I can't seem to do anything else useful. I am starting to get concerned I am doing this wrong. . . .any suggestions

Anthony
#13
07/26/2005 (11:12 am)
Is this forum still active??

how is your implementation???
#14
07/26/2005 (1:09 pm)
I can't speak for Anthony, but I do know that he has purchased the RTS-SK, and has been working actively with it, so my best guess is that his independent work was either scrapped, or folded into his personal engine based on top of the RTS-SK.

Of course, the RTS-SK has a fully functional RTS-style cam, and some adjustments and refinements have been posted to RTS-SK owners as resources for further enhancement.