|
A client-controlled player character. More...
Public Member Functions | |
bool | checkDismountPoint (Point3F oldPos, Point3F pos) |
Check if it is safe to dismount at this position. | |
void | clearControlObject () |
Clears the player's current control object. | |
int | getControlObject () |
Get the current object we are controlling. | |
string | getDamageLocation (Point3F pos) |
Get the named damage location and modifier for a given world position. | |
string | getState () |
Get the name of the player's current state. | |
bool | setActionThread (string name, bool hold=false, bool fsp=true) |
Set the main action sequence to play for this player. | |
bool | setArmThread (string name) |
Set the sequence that controls the player's arms (dynamically adjusted to match look direction). | |
bool | setControlObject (ShapeBase obj) |
Set the object to be controlled by this player. | |
Static Public Attributes | |
static bool | isRenderable |
Disables rendering of all instances of this type. | |
static bool | isSelectable |
Disables selection of all instances of this type. | |
static int | maxPredictionTicks |
Maximum number of ticks to predict on the client from the last known move obtained from the server. | |
static int | maxWarpTicks |
When a warp needs to occur due to the client being too far off from the server, this is the maximum number of ticks we'll allow the client to warp to catch up. | |
static float | minWarpTicks |
Fraction of tick at which instant warp occures on the client. | |
static bool | renderCollision |
Determines if the player's collision mesh should be rendered. | |
static bool | renderMyItems |
Determines if mounted shapes are rendered or not. | |
static bool | renderMyPlayer |
Determines if the player is rendered or not. |
A client-controlled player character.
The Player object is the main client-controlled object in an FPS, or indeed, any game where the user is in control of a single character. This class (and the associated datablock, PlayerData) allows you to fine-tune the movement, collision detection, animation, and SFX properties of the character. Player derives from ShapeBase, so it is recommended to have a good understanding of that class (and it's parent classes) as well.
The Player class supports the following modes of movement, known as poses:
The acceleration, maximum speed, and bounding box for each mode can be set independently using the PlayerData datablock. The player will automatically switch between swimming and one of the other 3 'dry' modes when entering/exiting the water, but transitions between the non-swimming modes are handled by controller input (such as holding down a key to begin crouching). $mvTriggerCount3 activates crouching, while $mvTriggerCount4 activates being prone.
It is important to set the bounding box correctly for each mode so that collisions with the player remain accurate:
The Player class supports jumping. While the player is in contact with a surface (and optionally has enough energy as defined by the PlayerData), $mvTriggerCount2 will cause the player to jump.
The Player class includes a simple jetpack behaviour allowing characters to 'jet' upwards while jumping. The jetting behaviour can be linked to the player's energy level using datablock properties as shown below:
datablock PlayerData( JetPlayer ) { ... jetJumpForce = 16.0 * 90; jetJumpEnergyDrain = 10; jetMinJumpEnergy = 25; jetMinJumpSpeed = 20; jetMaxJumpSpeed = 100; jetJumpSurfaceAngle = 78; }
This player will not be able to jet if he has less than 25 units of energy, and 10 units will be subtracted each tick.
If PlayerData::jetJumpFore is greater than zero then $mvTriggerCount1 will activate jetting.
The player may optionally move itself through the air while jumping or falling. This allows the player to adjust their trajectory while in the air, and is known as air control. The PlayerData::airControl property determines what fraction of the player's normal speed they may move while in the air. By default, air control is disabled (set to 0).
It is possible to have the player mount another object, such as a vehicle, just like any other SceneObject. While mounted, $mvTriggerCount2 will cause the player to dismount.
A Player may have other objects mounted to it, with each mounted object assigned to a slot. These Player mounted objects are known as images. See ShapeBase::mountImage(). If there is an image mounted to slot 0, $mvTriggerCount0 will trigger it. If the player dies this trigger is automatically released.
If there is an image mounted to slot 1, $mvTriggerCount1 will trigger it. Otherwise $mvTriggerCount1 will be passed along to the image in slot 0 as an alternate fire state.
The following sequences are used by the Player object to animate the character. Not all of them are required, but a model should have at least the root, run, back and side animations.
Looping sequence played when player is running sideways right.
Looping sequence played when player is crouched and moving sideways.
Looping sequence played when player is prone (lying down) and moving backward.
Looping sequence played when player is swimming and moving right.
Looping sequence played when player is jetting.
Sequence to control vertical arm movement (for looking) (start=full up, end=full down).
Sequence played when player is firing a heavy weapon (Based on ShapeBaseImageData).
An example of a player datablock appears below:
datablock PlayerData( BasicPlayerData ) { renderFirstPerson = true; shapeFile = "art/shapes/actors/gideon/gideon.dts"; computeCRC = true; cameraDefaultFov = 100.0; cameraMinFov = 5.0; cameraMaxFov = 120.0; cameraMaxDist = 3; debrisShapeName = "art/shapes/actors/common/debris_player.dts"; debris = PlayerDebris; aiAvoidThis = true; minLookAngle = -1.4; maxLookAngle = 1.4; maxFreelookAngle = 3.0; mass = 100; drag = 1.3; maxdrag = 0.4; density = 1.1; maxDamage = 100; maxEnergy = 60; repairRate = 0.33; energyPerDamagePoint = 75.0; rechargeRate = 0.256; // Running runForce = 48 * 90; runEnergyDrain = 0; minRunEnergy = 0; maxForwardSpeed = 8; maxBackwardSpeed = 6; maxSideSpeed = 6; %boundingBox = "1 1 2"; // Crouching crouchForce = 45.0 * 9.0; maxCrouchForwardSpeed = 4.0; maxCrouchBackwardSpeed = 2.0; maxCrouchSideSpeed = 2.0; crouchBoundingBox = "1 1 1.5"; // Prone proneForce = 45.0 * 9.0; maxProneForwardSpeed = 4.0; maxProneBackwardSpeed = 2.0; maxProneSideSpeed = 2.0; proneBoundingBox = "1 2 1"; // Underwater maxUnderwaterForwardSpeed = 8.4; maxUnderwaterBackwardSpeed = 7.8; maxUnderwaterSideSpeed = 7.8; swimBoundingBox = "1 2 2"; // Jumping jumpForce = 8.3 * 90; jumpEnergyDrain = 0; minJumpEnergy = 0; jumpDelay = 15; airControl = 0.3; recoverDelay = 9; recoverRunForceScale = 1.2; minImpactSpeed = 45; speedDamageScale = 0.4; pickupRadius = 0.75; // Damage location details boxNormalHeadPercentage = 0.83; boxNormalTorsoPercentage = 0.49; boxHeadLeftPercentage = 0; boxHeadRightPercentage = 1; boxHeadBackPercentage = 0; boxHeadFrontPercentage = 1; // Foot Prints decalData = PlayerFootprint; decalOffset = 0.25; footPuffEmitter = LightPuffEmitter; footPuffNumParts = 10; footPuffRadius = 0.25; dustEmitter = LiftoffDustEmitter; splash = PlayerSplash; splashVelocity = 4.0; splashAngle = 67.0; splashFreqMod = 300.0; splashVelEpsilon = 0.60; bubbleEmitTime = 0.4; splashEmitter[0] = PlayerWakeEmitter; splashEmitter[1] = PlayerFoamEmitter; splashEmitter[2] = PlayerBubbleEmitter; mediumSplashSoundVelocity = 10.0; hardSplashSoundVelocity = 20.0; exitSplashSoundVelocity = 5.0; // Control slope of runnable/jumpable surfaces runSurfaceAngle = 70; jumpSurfaceAngle = 80; maxStepHeight = 1.5; // two meters minJumpSpeed = 20; maxJumpSpeed = 30; horizMaxSpeed = 68; horizResistSpeed = 33; horizResistFactor = 0.35; upMaxSpeed = 80; upResistSpeed = 25; upResistFactor = 0.3; footstepSplashHeight = 0.35; // Footstep Sounds FootSoftSound = FootLightSoftSound; FootHardSound = FootLightHardSound; FootMetalSound = FootLightMetalSound; FootSnowSound = FootLightSnowSound; FootShallowSound = FootLightShallowSplashSound; FootWadingSound = FootLightWadingSound; FootUnderwaterSound = FootLightUnderwaterSound; FootBubblesSound = FootLightBubblesSound; movingBubblesSound = PlayerMoveBubblesSound; waterBreathSound = WaterBreathMaleSound; impactSoftSound = ImpactLightSoftSound; impactHardSound = ImpactLightHardSound; impactMetalSound = ImpactLightMetalSound; impactSnowSound = ImpactLightSnowSound; impactWaterEasy = ImpactLightWaterEasySound; impactWaterMedium = ImpactLightWaterMediumSound; impactWaterHard = ImpactLightWaterHardSound; exitingWater = ExitingWaterLightSound; groundImpactMinSpeed = 10.0; groundImpactShakeFreq = "4.0 4.0 4.0"; groundImpactShakeAmp = "1.0 1.0 1.0"; groundImpactShakeDuration = 0.8; groundImpactShakeFalloff = 10.0; };
bool Player::checkDismountPoint | ( | Point3F | oldPos, | |
Point3F | pos | |||
) |
Check if it is safe to dismount at this position.
Internally this method casts a ray from oldPos to pos to determine if it hits the terrain, an interior object, a water object, another player, a static shape, a vehicle (exluding the one currently mounted), or physical zone. If this ray is in the clear, then the player's bounding box is also checked for a collision at the pos position. If this displaced bounding box is also in the clear, then checkDismountPoint() returns true.
oldPos | The player's current position | |
pos | The dismount position to check |
void Player::clearControlObject | ( | ) |
Clears the player's current control object.
Returns control to the player. This internally calls Player::setControlObject(0).
int Player::getControlObject | ( | ) |
Get the current object we are controlling.
string Player::getDamageLocation | ( | Point3F | pos | ) |
Get the named damage location and modifier for a given world position.
the Player object can simulate different hit locations based on a pre-defined set of PlayerData defined percentages. These hit percentages divide up the Player's bounding box into different regions. The diagram below demonstrates how the various PlayerData properties split up the bounding volume:
While you may pass in any world position and getDamageLocation() will provide a best-fit location, you should be aware that this can produce some interesting results. For example, any position that is above PlayerData::boxHeadPercentage will be considered a 'head' hit, even if the world position is high in the sky. Therefore it may be wise to keep the passed in point to somewhere on the surface of, or within, the Player's bounding volume.
pos | A world position for which to retrieve a body region on this player. |
Posible locations:
Head modifiers:
Legs/Torso modifiers:
string Player::getState | ( | ) |
Get the name of the player's current state.
The state is one of the following:
bool Player::setActionThread | ( | string | name, | |
bool | hold = false , |
|||
bool | fsp = true | |||
) |
Set the main action sequence to play for this player.
name | Name of the action sequence to set | |
hold | Set to false to get a callback on the datablock when the sequence ends (PlayerData::animationDone()). When set to true no callback is made. | |
fsp | True if first person and none of the spine nodes in the shape should animate. False will allow the shape's spine nodes to animate. |
You cannot use setActionThread() to have the Player play one of the motion determined action animation sequences. These sequences are chosen based on how the Player moves and the Player's current pose. The names of these sequences are:
If the player moves in any direction then the animation sequence set using this method will be cancelled and the chosen mation-based sequence will take over. This makes great for times when the Player cannot move, such as when mounted, or when it doesn't matter if the action sequence changes, such as waving and saluting.
// Place the player in a sitting position after being mounted %player.setActionThread( "sitting", true, true );
bool Player::setArmThread | ( | string | name | ) |
Set the sequence that controls the player's arms (dynamically adjusted to match look direction).
name | Name of the sequence to play on the player's arms. |
bool Player::setControlObject | ( | ShapeBase | obj | ) |
Set the object to be controlled by this player.
It is possible to have the moves sent to the Player object from the GameConnection to be passed along to another object. This happens, for example when a player is mounted to a vehicle. The move commands pass through the Player and on to the vehicle (while the player remains stationary within the vehicle). With setControlObject() you can have the Player pass along its moves to any object. One possible use is for a player to move a remote controlled vehicle. In this case the player does not mount the vehicle directly, but still wants to be able to control it.
obj | Object to control with this player |
bool Player::isRenderable [static] |
bool Player::isSelectable [static] |
int Player::maxPredictionTicks [static] |
Maximum number of ticks to predict on the client from the last known move obtained from the server.
int Player::maxWarpTicks [static] |
When a warp needs to occur due to the client being too far off from the server, this is the maximum number of ticks we'll allow the client to warp to catch up.
float Player::minWarpTicks [static] |
Fraction of tick at which instant warp occures on the client.
bool Player::renderCollision [static] |
Determines if the player's collision mesh should be rendered.
This is mainly used for the tools and debugging.
bool Player::renderMyItems [static] |
Determines if mounted shapes are rendered or not.
Used on the client side to disable the rendering of all Player mounted objects. This is mainly used for the tools or debugging.
bool Player::renderMyPlayer [static] |
Determines if the player is rendered or not.
Used on the client side to disable the rendering of all Player objects. This is mainly for the tools or debugging.