Game Development Community

Dynamic Control of Overhead Cam distance

by Gibby · in Torque 3D Professional · 12/17/2014 (2:50 pm) · 13 replies

Greets all:

Per the title, I'm trying to dynamically control how far the OverheadCam can be moved from the player.
I'm trying to set it up so that inventory/environment/gameplay varies how far it can go...

#1
12/18/2014 (6:16 am)
I don't think there is a built-in way to do this.

You could just check distance from player as you move the camera and nudge it back a little toward the player if it's greater than your specified distance. Might have to extend the camera class a little - I'm not sure catching it in the key binding function would work as intended....
#2
12/18/2014 (9:12 am)
@Richard
Quote:I don't think there is a built-in way to do this.

I figured as much. I'm wondering if I changed the %adjustment in the following code if it would work. So far my attempts have failed...


// Adjusts the height of the camera using the mouse wheel
function serverCmdadjustCamera(%client, %adjustment)
{
   if(%client.camera.controlMode $= "OrbitObject")
   {
      if(%adjustment == 1)
         %n = %client.camera.camDist + 0.5;
      else
         %n = %client.camera.camDist - 0.5;
      
      if(%n < 0.5)
         %n = 0.5;
         
      if(%n > 15)
         %n = 15.0;
         
      %client.camera.setOrbitObject(%client.player, %client.camera.getRotation(), 
        0, %n, %n);
      %client.camera.camDist = %n;
   }
   if(%client.camera.controlMode $= "Overhead")
   {
      %client.camera.position = VectorAdd(%client.camera.position, "0 0 " @ %adjustment);//Gibby - will it work here?
   }
}
#3
12/19/2014 (5:52 am)
The %adjustment variable is a binary "up/down" flag.

<redacted - extraneous>

EDIT - I realized that you are in Overhead and not OrbitObject, so I added a distance check to the Overhead block. I also just remembered that this is only called when using the mouse wheel to change distance. In Overhead mode the camera is controlled by the movement keys, which don't go through the keybindings the same way (default.bind.cs):
//------------------------------------------------------------------------------
// Movement Keys
//------------------------------------------------------------------------------

$movementSpeed = 1; // m/s

function setSpeed(%speed)
{
   if(%speed)
      $movementSpeed = %speed;
}

// totally pulled this out of my rear end....
function clampPositionToDist(%pos1, %pos2, %dist)
{
    %adjVec = VectorSub(%pos1, %pos2);
    %lenAdj = VectorLen(%adjVec);
    %nrmAdj = VectorNormalize(%adjVec);
    %sclAdj = VectorScale(%nrmAdj, %lenAdj - %dist);
    
    return %sclAdj;
}

$MINCAMDIST = 0.5;
$MAXCAMDIST = 15.0;
function moveleft(%val)
{
    // maybe?
    %object = ServerConnection.getControlObject();
    if(%object.isInNamespaceHierarchy("Camera"))
    {
        %pos = %object.position;
        if(isObject(%object.player))
        {
            %playerPos = %object.player.position;
            %dist = VectorDist(%pos, %playerPos);
            if(%dist < $MINCAMDIST)
            {
                %object.position = clampPositionToDist(%pos, %playerPos, $MINCAMDIST);
                return;
            }
            if(%dist > $MAXCAMDIST)
            {
                %object.position = clampPositionToDist(%pos, %playerPos, $MAXCAMDIST);
                return;
            }
            $mvLeftAction = %val * $movementSpeed;
        }
    }
    else
        $mvLeftAction = %val * $movementSpeed;
}
Then you'd have to add that same block to all of the other moveX() functions. I have no idea if that'll work, or if ServerConnection.getControlObject().player will be valid - it should be if you add it on the camera as a field in spawn.
#4
01/08/2015 (9:42 am)
@Richard:

Sorry to take so long to get back, I hadn't seen your reply. I tried your suggestion but it doesn't seem to work. I'm wondering if it's in the ServerConnection.getControlObject() somewhere...
#5
01/09/2015 (5:15 am)
The server uses the camera location of the client in order to determine what should be scoped to the client. Bearing this in mind, you probably shouldn't be setting its position directly on the client - they might end up seeing things that they're not supposed to, or not seeing things that should be there because the server doesn't know they should be visible.

In Camera.cpp, around line 700 is the code that performs the camera movement for overhead mode. Add a check in there that clears move->x,y and z if the camera is more than a certain distance from the clients player.
#6
01/09/2015 (9:14 am)
@Guy:

Thanks! I'll give that a try...
#7
01/09/2015 (10:13 am)
@Guy:

Okay, so I copied bits from the OrbitCam to OverheadCam, I now have a maximum and current distance (around line 275):

//-> Gibby Overhead Cam Limit
   mMaxOverheadDist = 25.0f;
   mCurOverheadDist = 0.0f;
   //<- Gibby Overhead Cam Limit

per your suggestion, I'm modding the OverheadCam at 700ish:

//-> Gibby Overhead Cam Limit
	 GameConnection* conCL = getControllingClient();
	 GameConnection* conObj = conCL->getControlObject();//WRONG!!!
         MatrixF retObj;
         conObj->getRenderEyeTransform( &retObj );
         conPos = retObj.getPosition();
		 //<- Gibby Overhead Cam Limit

don't have setter/getters done yet because I'm stumped (perhaps I'm a bit under-caffienated) at how to get the client player and not control object position in code...
#8
01/09/2015 (5:24 pm)
If the Player is not the control object, there may not be a way to get it from code, unless you hack into the scripted dynamic variables and look for "player", if that assumption holds.
#9
01/10/2015 (12:51 am)
Yeah, good point, that's a problem. The engine doesn't know that an uncontrolled player belongs to any clients, that's only a script-side thing.
#10
01/10/2015 (7:41 am)
hmmm well what if one were to use the parts of OrbitCam to lock it to an object?
#11
01/11/2015 (12:31 am)
Yeah, both track and orbit modes use the orbitObject, so that is a good option.
#12
01/11/2015 (8:59 am)
I know this is somewhat out of this thread's scope but...

@Guy/Dan is there a way to stop the camera from controlling what gets ghosted and instead just ghost everything that is flagged as visible on the server?
#13
01/28/2015 (6:13 am)
Hey, I just had a dumb idea -

Make an inside-out box like bounds but the extent that you want to restrict your camera to, attach it to the player's avatar, then set it to only collide with cameras.

It could work....