Connection Issues With OrbitCamera

There are no stupid questions, just stupid answers.
5 posts Page 1 of 1
Steve_Yorkshire
Posts: 202
Joined: Tue Feb 03, 2015 10:30 pm
 
by Steve_Yorkshire » Fri Feb 03, 2017 5:37 pm
Stock 3.9 - no code changes:

Does anyone have any ideas what is happening and/or why?



I'm using orbitCamera to get a topdown/isometric view. When moving beyond levelInfo visibleDistance from starting position it appears to lose controlObject connection - but I actually still have control of the playerObject and can walk it back into range.

TS changes: scripts/server/gamecore.cs (function GameCore::spawnPlayer) My changes listed as //YORKS in caps
function GameCore::spawnPlayer(%game, %client, %spawnPoint, %noControl)
{
//echo (%game @"\c4 -> "@ %game.class @" -> GameCore::spawnPlayer");

if (isObject(%client.player))
{
// The client should not already have a player. Assigning
// a new one could result in an uncontrolled player object.
error("Attempting to create a player for a client that already has one!");
}

// Attempt to treat %spawnPoint as an object
if (getWordCount(%spawnPoint) == 1 && isObject(%spawnPoint))
{
// Defaults
%spawnClass = $Game::DefaultPlayerClass;
%spawnDataBlock = $Game::DefaultPlayerDataBlock;

// Overrides by the %spawnPoint
if (isDefined("%spawnPoint.spawnClass"))
{
%spawnClass = %spawnPoint.spawnClass;
%spawnDataBlock = %spawnPoint.spawnDatablock;
}
else if (isDefined("%spawnPoint.spawnDatablock"))
{
// This may seem redundant given the above but it allows
// the SpawnSphere to override the datablock without
// overriding the default player class
%spawnDataBlock = %spawnPoint.spawnDatablock;
}

%spawnProperties = %spawnPoint.spawnProperties;
%spawnScript = %spawnPoint.spawnScript;

// Spawn with the engine's Sim::spawnObject() function
%player = spawnObject(%spawnClass, %spawnDatablock, "",
%spawnProperties, %spawnScript);

// If we have an object do some initial setup
if (isObject(%player))
{
// Pick a location within the spawn sphere.
%spawnLocation = GameCore::pickPointInSpawnSphere(%player, %spawnPoint);
%player.setTransform(%spawnLocation);

}
else
{
// If we weren't able to create the player object then warn the user
// When the player clicks OK in one of these message boxes, we will fall through
// to the "if (!isObject(%player))" check below.
if (isDefined("%spawnDatablock"))
{
MessageBoxOK("Spawn Player Failed",
"Unable to create a player with class " @ %spawnClass @
" and datablock " @ %spawnDatablock @ ".\n\nStarting as an Observer instead.",
"");
}
else
{
MessageBoxOK("Spawn Player Failed",
"Unable to create a player with class " @ %spawnClass @
".\n\nStarting as an Observer instead.",
"");
}
}
}
else
{

// Create a default player
%player = spawnObject($Game::DefaultPlayerClass, $Game::DefaultPlayerDataBlock);

if (!%player.isMemberOfClass("Player"))
warn("Trying to spawn a class that does not derive from Player.");

// Treat %spawnPoint as a transform
%player.setTransform(%spawnPoint);
}

// If we didn't actually create a player object then bail
if (!isObject(%player))
{
// Make sure we at least have a camera
%client.spawnCamera(%spawnPoint);

return;
}

/* //YORKS OUT START
// Update the default camera to start with the player
if (isObject(%client.camera) && !isDefined("%noControl"))
{
if (%player.getClassname() $= "Player")
%client.camera.setTransform(%player.getEyeTransform());
else
%client.camera.setTransform(%player.getTransform());
}
*/ //YORKS OUT END

// Add the player object to MissionCleanup so that it
// won't get saved into the level files and will get
// cleaned up properly
MissionCleanup.add(%player);

// Store the client object on the player object for
// future reference
%player.client = %client;

// If the player's client has some owned turrets, make sure we let them
// know that we're a friend too.
if (%client.ownedTurrets)
{
for (%i=0; %i<%client.ownedTurrets.getCount(); %i++)
{
%turret = %client.ownedTurrets.getObject(%i);
%turret.addToIgnoreList(%player);
}
}

// Player setup...
if (%player.isMethod("setShapeName"))
%player.setShapeName(%client.playerName);

if (%player.isMethod("setEnergyLevel"))
%player.setEnergyLevel(%player.getDataBlock().maxEnergy);

if (!isDefined("%client.skin"))
{
// Determine which character skins are not already in use
%availableSkins = %player.getDatablock().availableSkins; // TAB delimited list of skin names
%count = ClientGroup.getCount();
for (%cl = 0; %cl < %count; %cl++)
{
%other = ClientGroup.getObject(%cl);
if (%other != %client)
{
%availableSkins = strreplace(%availableSkins, %other.skin, "");
%availableSkins = strreplace(%availableSkins, "\t\t", ""); // remove empty fields
}
}

// Choose a random, unique skin for this client
%count = getFieldCount(%availableSkins);
%client.skin = addTaggedString( getField(%availableSkins, getRandom(%count)) );
}

%player.setSkinName(%client.skin);

// Give the client control of the player
%client.player = %player;
%camera = %client.camera;//YORKS

//YORKS cheats for ease of use
%player.setName("hero");
%camera.setName("cam");

// Give the client control of the camera if in the editor
if( $startWorldEditor )
{
%control = %client.camera;
%control.mode = "Fly";
EditorGui.syncCameraGui();
}
else
%control = %player;

//YORKS NEW START
%client.camera.setOrbitObject(%control, "1.308996 0 0" , 5.0, 20.0, 20.0,true, "0 -3.2 0", false);
%client.setControlObject(%control); //- Set the control object to the player
%client.setCameraObject(%client.camera); //- Set the camera object to the camera

toggleFirstPerson(1);
echo("client and camera " @ %client SPC %client.camera);
//YORKS NEW END

// Allow the player/camera to receive move data from the GameConnection. Without this
// the user is unable to control the player/camera.
//if (!isDefined("%noControl"))//YORKS OUT
// %client.setControlObject(%control);//YORKS OUT
}


EDIT: visibleDistance and ghost distance thingy work fine in "normal" third person.
JeffR
Steering Committee
Steering Committee
Posts: 741
Joined: Tue Feb 03, 2015 9:49 pm
 
by JeffR » Sun Feb 05, 2017 6:26 pm
Hey Steve, try this:

in Camera::processTick, you have the main block of code that does most of the updating of position/rot stuff, contained within the if(move){ --- } block.

After that block, try adding this:

else
{
//We may just be acting as a dummy camera and observing, rather than being controlled. Make sure to update stuff in this case, as well
CameraMotionMode virtualMode = mMode;

VectorF posVec(0, 0, 0);
bool mustValidateEyePoint = false;
bool serverInterpolate = false;

// process input/determine translation vector
if (virtualMode == OrbitObjectMode)
{
if (virtualMode == OrbitObjectMode && bool(mOrbitObject))
{
// If this is a shapebase, use its render eye transform
// to avoid jittering.
GameBase *castObj = mOrbitObject;
ShapeBase* shape = dynamic_cast<ShapeBase*>(castObj);
if (shape != NULL)
{
MatrixF ret;
shape->getRenderEyeTransform(&ret);
mPosition = ret.getPosition();
}
else
{
// Hopefully this is a static object that doesn't move,
// because the worldbox doesn't get updated between ticks.
mOrbitObject->getWorldBox().getCenter(&mPosition);
}

setPosition(mPosition);
}
}
}


The issue basically is that the camera isn't the control object, so it doesn't get a move struct. It doesn't get a move struct, so it doesn't update it's position on the server. It doesn't update it's position on the server(even though the actual rendered position is updated on the client) meaning that the scope distance calculations never change because the camera hasn't 'moved'. So when the player moves too far from the camera, we leave scope.

The above code will make sure to update the camera's position if we're using ObjectOrbit mode, even in the event that the camera isn't directly controlled.

Let me know if that works for you and I'll get it PR'd in.
Steve_Yorkshire
Posts: 202
Joined: Tue Feb 03, 2015 10:30 pm
 
by Steve_Yorkshire » Sun Feb 05, 2017 9:33 pm
That seemed to do the trick, @
User avatar
JeffR
:D
No more disappearing player.
Steve_Yorkshire
Posts: 202
Joined: Tue Feb 03, 2015 10:30 pm
 
by Steve_Yorkshire » Mon Feb 06, 2017 5:57 pm
@
User avatar
JeffR
actually I just noticed that you don't need
bool mustValidateEyePoint = false;
bool serverInterpolate = false;


in as they aren't used if the camera is not the controlObject. If you want to keep your code nice and OCD'ly clean ;)
Johxz
Posts: 411
Joined: Sat Feb 07, 2015 11:37 pm
by Johxz » Mon Feb 06, 2017 8:25 pm
I was facing the same issue, I will just put this for reference.

- http://www.garagegames.com/community/fo ... ead/137218
- viewtopic.php?f=10&t=287#p2410
5 posts Page 1 of 1

Who is online

Users browsing this forum: No registered users and 2 guests