Class TCastleWalkNavigation

Unit

Declaration

type TCastleWalkNavigation = class(TCastleMouseLookNavigation)

Description

Navigation by walking or flying (classic first-person shooter navigation) in a 3D scene. User can rotate and move camera using various keys, like arrows or AWSD. Mouse dragging and mouse look are also supported.

Hierarchy

Overview

Fields

Public nested const DefaultFallSpeedStart = 0.5;
Public nested const DefaultGrowSpeed = 1.0;
Public nested const DefaultJumpMaxHeight = 1.0;
Public nested const DefaultMinAngleFromGravityUp = Pi * 10 / 180;
Public nested const DefaultRotationHorizontalSpeed = Pi * 150 / 180;
Public nested const DefaultRotationVerticalSpeed = Pi * 100 / 180;
Public nested const DefaultFallSpeedIncrease = 13/12;
Public nested const DefaultJumpHorizontalSpeedMultiply = 2.0;
Public nested const DefaultJumpTime = 1.0 / 8.0;
Public nested const DefaultMouseDraggingHorizontalRotationSpeed = Pi * 0.1 / 180;
Public nested const DefaultMouseDraggingVerticalRotationSpeed = Pi * 0.1 / 180;
Public nested const DefaultMouseDraggingMoveSpeed = 0.01;
Public nested const DefaultMoveSpeedMin = 0.01;
Public nested const DefaultMoveSpeedMax = 10000.0;

Methods

Protected function ReallyEnableMouseDragging: boolean; override;
Protected procedure ProcessMouseLookDelta(const Delta: TVector2); override;
Protected function MoveAllowed( const OldPos: TVector3; ProposedNewPos: TVector3; out NewPos: TVector3; const BecauseOfGravity, CheckClimbHeight: Boolean): Boolean; override;
Public constructor Create(AOwner: TComponent); override;
Public destructor Destroy; override;
Public function PropertySections(const PropertyName: String): TPropertySections; override;
Public procedure Update(const SecondsPassed: Single; var HandleInput: boolean); override;
Public function AllowSuspendForInput: boolean; override;
Public function Press(const Event: TInputPressRelease): boolean; override;
Public function SensorTranslation(const X, Y, Z, Length: Double; const SecondsPassed: Single): boolean; override;
Public function SensorRotation(const X, Y, Z, Angle: Double; const SecondsPassed: Single): boolean; override;
Public procedure Init(const AInitialPosition, AInitialDirection, AInitialUp: TVector3; const AGravityUp: TVector3; const APreferredHeight: Single; const ARadius: Single); overload; deprecated 'use Viewport.Camera.SetWorldView, and set GravityUp, PreferredHeight, Radius and call CorrectPreferredHeight manually';
Public procedure Init(const box: TBox3D; const ARadius: Single); overload; deprecated 'use Viewport.Camera.SetWorldView, and set GravityUp, PreferredHeight, Radius and call CorrectPreferredHeight manually';
Public function DirectionInGravityPlane: TVector3; deprecated 'avoid using it, as it inherently has difficult cases: it is in TCastleCamera local coordinate space, it cannot be correct when Direction is parallel to gravity';
Public function Motion(const Event: TInputMotion): boolean; override;
Public procedure CancelFalling;
Public function MaxJumpDistance: Single;
Public function RealPreferredHeight: Single;
Public procedure FallOnTheGround;
Public procedure UpPrefer(const AUp: TVector3); deprecated 'use Viewport.Camera.UpPrefer';
Public procedure CorrectPreferredHeight;

Properties

Public property PreferGravityUpForRotations: boolean read FPreferGravityUpForRotations write FPreferGravityUpForRotations default true;
Public property PreferGravityUpForMoving: boolean read FPreferGravityUpForMoving write FPreferGravityUpForMoving default true;
Public property MinAngleFromGravityUp: Single read FMinAngleFromGravityUp write FMinAngleFromGravityUp default DefaultMinAngleFromGravityUp;
Public property FallSpeedStart: Single read FFallSpeedStart write FFallSpeedStart default DefaultFallSpeedStart;
Public property FallSpeedIncrease: Single read FFallSpeedIncrease write FFallSpeedIncrease default DefaultFallSpeedIncrease;
Public property Falling: boolean read FFalling write FFalling;
Public property FallingEffect: boolean read FFallingEffect write FFallingEffect default true;
Public property GrowSpeed: Single read FGrowSpeed write FGrowSpeed default DefaultGrowSpeed;
Public property JumpMaxHeight: Single read FJumpMaxHeight write FJumpMaxHeight default DefaultJumpMaxHeight;
Public property IsJumping: boolean read FIsJumping;
Public property JumpHorizontalSpeedMultiply: Single read FJumpHorizontalSpeedMultiply write FJumpHorizontalSpeedMultiply default DefaultJumpHorizontalSpeedMultiply;
Public property JumpTime: Single read FJumpTime write FJumpTime default DefaultJumpTime;
Public property IsCrouching: boolean read FIsCrouching;
Public property FallingOnTheGround: boolean read FFallingOnTheGround;
Public property IsOnTheGround: boolean read FIsOnTheGround;
Public property IsWalkingOnTheGround: boolean read FIsWalkingOnTheGround;
Public property IsAbove: boolean read FIsAbove;
Public property AboveHeight: Single read FAboveHeight;
Public property AboveGround: PTriangle read FAboveGround write FAboveGround;
Public property Input_Forward: TInputShortcut read FInput_Forward;
Public property Input_Backward: TInputShortcut read FInput_Backward;
Public property Input_LeftRotate: TInputShortcut read FInput_LeftRotate;
Public property Input_RightRotate: TInputShortcut read FInput_RightRotate;
Public property Input_LeftRot: TInputShortcut read FInput_LeftRotate; deprecated 'use Input_LeftRotate';
Public property Input_RightRot: TInputShortcut read FInput_RightRotate; deprecated 'use Input_RightRotate';
Public property Input_LeftStrafe: TInputShortcut read FInput_LeftStrafe;
Public property Input_RightStrafe: TInputShortcut read FInput_RightStrafe;
Public property Input_UpRotate: TInputShortcut read FInput_UpRotate;
Public property Input_DownRotate: TInputShortcut read FInput_DownRotate;
Public property Input_IncreasePreferredHeight: TInputShortcut read FInput_IncreasePreferredHeight;
Public property Input_DecreasePreferredHeight: TInputShortcut read FInput_DecreasePreferredHeight;
Public property Input_GravityUp: TInputShortcut read FInput_GravityUp;
Public property Input_Run: TInputShortcut read FInput_Run;
Public property Input_MoveSpeedInc: TInputShortcut read FInput_MoveSpeedInc;
Public property Input_MoveSpeedDec: TInputShortcut read FInput_MoveSpeedDec;
Public property Input_Jump: TInputShortcut read FInput_Jump;
Public property Input_Crouch: TInputShortcut read FInput_Crouch;
Public property MoveForward: boolean read FMoveForward write FMoveForward;
Public property MoveBackward: boolean read FMoveBackward write FMoveBackward;
Public property AllowSlowerRotations: boolean read FAllowSlowerRotations write FAllowSlowerRotations default true;
Public property CheckModsDown: boolean read FCheckModsDown write FCheckModsDown default true;
Public property RotationHorizontalPivot: Single read FRotationHorizontalPivot write FRotationHorizontalPivot default 0; deprecated 'use TCastleThirdPersonNavigation for real 3rd-person navigation';
Public property HeadBobbing: Single read FHeadBobbing write FHeadBobbing default DefaultHeadBobbing;
Public property HeadBobbingTime: Single read FHeadBobbingTime write FHeadBobbingTime default DefaultHeadBobbingTime;
Public property ClimbHeight: Single read FClimbHeight write FClimbHeight;
Published property MouseLook;
Published property MouseLookHorizontalSensitivity;
Published property MouseLookVerticalSensitivity;
Published property InvertVerticalMouseLook;
Published property RotationHorizontalSpeed: Single read FRotationHorizontalSpeed write FRotationHorizontalSpeed default DefaultRotationHorizontalSpeed;
Published property RotationVerticalSpeed: Single read FRotationVerticalSpeed write FRotationVerticalSpeed default DefaultRotationVerticalSpeed;
Published property MoveHorizontalSpeed: Single read FMoveHorizontalSpeed write FMoveHorizontalSpeed default 1.0;
Published property MoveVerticalSpeed: Single read FMoveVerticalSpeed write FMoveVerticalSpeed default 1.0;
Published property MoveSpeed: Single read FMoveSpeed write FMoveSpeed default 1.0;
Published property MoveSpeedMin: Single read FMoveSpeedMin write FMoveSpeedMin default DefaultMoveSpeedMin;
Published property MoveSpeedMax: Single read FMoveSpeedMax write FMoveSpeedMax default DefaultMoveSpeedMax;
Published property MouseDraggingHorizontalRotationSpeed: Single read FMouseDraggingHorizontalRotationSpeed write FMouseDraggingHorizontalRotationSpeed default DefaultMouseDraggingHorizontalRotationSpeed;
Published property MouseDraggingVerticalRotationSpeed: Single read FMouseDraggingVerticalRotationSpeed write FMouseDraggingVerticalRotationSpeed default DefaultMouseDraggingVerticalRotationSpeed;
Published property MouseDraggingMoveSpeed: Single read FMouseDraggingMoveSpeed write FMouseDraggingMoveSpeed default DefaultMouseDraggingMoveSpeed;
Published property MouseDragMode: TMouseDragMode read FMouseDragMode write FMouseDragMode default mdWalkRotate;
Published property Gravity: boolean read FGravity write FGravity default true;
Published property PreferredHeight: Single read FPreferredHeight write FPreferredHeight default DefaultPreferredHeight;
Published property CrouchHeight: Single read FCrouchHeight write FCrouchHeight default DefaultCrouchHeight;
Published property Radius;

Description

Fields

Public nested const DefaultFallSpeedStart = 0.5;

This item has no description.

Public nested const DefaultGrowSpeed = 1.0;

This item has no description.

Public nested const DefaultJumpMaxHeight = 1.0;

This item has no description.

Public nested const DefaultMinAngleFromGravityUp = Pi * 10 / 180;

This item has no description.

Public nested const DefaultRotationHorizontalSpeed = Pi * 150 / 180;

This item has no description.

Public nested const DefaultRotationVerticalSpeed = Pi * 100 / 180;

This item has no description.

Public nested const DefaultFallSpeedIncrease = 13/12;

This item has no description.

Public nested const DefaultJumpHorizontalSpeedMultiply = 2.0;

This item has no description.

Public nested const DefaultJumpTime = 1.0 / 8.0;

This item has no description.

Public nested const DefaultMouseDraggingHorizontalRotationSpeed = Pi * 0.1 / 180;

This item has no description.

Public nested const DefaultMouseDraggingVerticalRotationSpeed = Pi * 0.1 / 180;

This item has no description.

Public nested const DefaultMouseDraggingMoveSpeed = 0.01;

This item has no description.

Public nested const DefaultMoveSpeedMin = 0.01;

This item has no description.

Public nested const DefaultMoveSpeedMax = 10000.0;

This item has no description.

Methods

Protected function ReallyEnableMouseDragging: boolean; override;

This item has no description. Showing description inherited from TCastleNavigation.ReallyEnableMouseDragging.

Can we use mouse dragging. Checks UsingInput and so Valid already.

Protected procedure ProcessMouseLookDelta(const Delta: TVector2); override;

This item has no description.

Protected function MoveAllowed( const OldPos: TVector3; ProposedNewPos: TVector3; out NewPos: TVector3; const BecauseOfGravity, CheckClimbHeight: Boolean): Boolean; override;

This item has no description. Showing description inherited from TCastleNavigation.MoveAllowed.

Check collisions to determine can the object move. Object wants to move from OldPos to ProposedNewPos (in world coordinates).

Returns False if no move is allowed. Otherwise returns True and sets NewPos to the position where user should be moved.

If you're doing a simple check for collisions, you will always want to set NewPos to ProposedNewPos when returning True.

But you can also do more sophisticated calculations and sometimes not allow user to move to ProposedNewPos, but allow him to move instead to some other close position. For example when doing "wall sliding" (common in FPS games): when you're trying to walk "into the wall", you move along the wall instead.

It's allowed to modify NewPos when returning False. It makes no effect.

BecauseOfGravity says whether this move is caused by gravity dragging the player down. You can use BecauseOfGravity e.g. to implement TCastleViewport.PreventInfiniteFallingDown.

Implementation calls OnMoveAllowed and checks collisions through parent TCastleViewport, if CheckCollisions.

Public constructor Create(AOwner: TComponent); override;

This item has no description.

Public destructor Destroy; override;

This item has no description.

Public function PropertySections(const PropertyName: String): TPropertySections; override;

This item has no description. Showing description inherited from TCastleComponent.PropertySections.

Section where to show property in the editor.

Public procedure Update(const SecondsPassed: Single; var HandleInput: boolean); override;

This item has no description. Showing description inherited from TCastleUserInterface.Update.

Control may do here anything that must be continuously repeated. E.g. camera handles here falling down due to gravity, rotating model in Examine mode, and many more.

This method may be used, among many other things, to continuously react to the fact that user pressed some key (or mouse button). For example, if holding some key should move some 3D object, you should do something like:

if HandleInput then
begin
  if Container.Pressed[keyArrowRight] then
  begin
    Transform.Position := Transform.Position + Vector3(SecondsPassed * 10, 0, 0);
    HandleInput := false;
  end;
end;

Instead of directly using a key code, consider also using TInputShortcut that makes the input key nicely configurable. See engine tutorial about handling inputs.

Multiplying movement by SecondsPassed makes your operation frame-rate independent. Object will move by 10 units in a second, regardless of how many FPS your game has.

The code related to HandleInput is important if you write a generally-useful control that should nicely cooperate with all other controls, even when placed on top of them or under them. The correct approach is to only look at pressed keys/mouse buttons if HandleInput is True. Moreover, if you did check that HandleInput is True, and you did actually handle some keys, then you have to set HandleInput := false. This will prevent the other controls (behind the current control) from handling the keys (they will get HandleInput = False). And this is important to avoid doubly-processing the same key press, e.g. if two controls react to the same key, only the one on top should process it.

Note that to handle a single press / release (like "switch light on when pressing a key") you should rather use Press and Release methods. Use this method only for continuous handling (like "holding this key makes the light brighter and brighter").

To understand why such HandleInput approach is needed, realize that the "Update" events are called differently than simple mouse and key events like "Press" and "Release". "Press" and "Release" events return whether the event was somehow "handled", and the container passes them only to the controls under the mouse (decided by TCastleUserInterface.CapturesEventsAtPosition). And as soon as some control says it "handled" the event, other controls (even if under the mouse) will not receive the event.

This approach is not suitable for Update events. Some controls need to do the Update job all the time, regardless of whether the control is under the mouse and regardless of what other controls already did. So all controls (well, all controls that exist, in case of TCastleUserInterface, see TCastleUserInterface.Exists) receive Update calls.

So the "handled" status is passed through HandleInput. If a control is not under the mouse, it will receive HandleInput = False. If a control is under the mouse, it will receive HandleInput = True as long as no other control on top of it didn't already change it to False.

Public function AllowSuspendForInput: boolean; override;

This item has no description. Showing description inherited from TCastleUserInterface.AllowSuspendForInput.

Allow window containing this control to suspend waiting for user input. Typically you want to override this to return False when you do something in the overridden Update method.

In this class, this simply returns always True.

Public function Press(const Event: TInputPressRelease): boolean; override;

This item has no description. Showing description inherited from TCastleUserInterface.Press.

Override this method to react to user pressing a key, mouse button or mouse wheel. Return True if the event was handled, which prevents from passing this event to other UI controls.

When implementing in descendants it is best to override it like this:

function TMyControl.Press(const Event: TInputPressRelease): boolean;
begin
  Result := inherited;
  if Result then Exit; // exit if ancestor already handled this event

  if Event.IsKey(keyEnter) then
  begin
    // do something in reaction to Enter key
    ...
    // let engine know that this input event was handled
    Exit(true);
  end;

  if Event.IsMouseButton(buttonLeft) then
  begin
    // do something in reaction to left mouse button press
    ...
    // let engine know that this input event was handled
    Exit(true);
  end;
end;

These events are generated for all UI controls, whether they are considered "interactive" or not. These events are generated for non-interactive controls like TCastleRectangleControl or TCastleLabel as well. For example, these events ignore the TCastleButton.Enabled state, they are generated always (see https://github.com/castle-engine/castle-engine/issues/413 ). Use instead TCastleButton.OnClick to detect clicks on a button in a way that honors the TCastleButton.Enabled state.

When a control returns True from Press, it means it starts to "capture" subsequent mouse events: subsequent mouse moves and release will be send to this control even if mouse will move outside of this control.

The events Press and Release are passed to the parent only after the children had a chance to process this event. Overriding them makes sense if you draw something that "looks clickable" in TCastleUserInterface.Render, which is the standard place you should draw stuff. For example our TCastleButton draws there.

In contrast, the events PreviewPress and PreviewRelease are passed first to the parent control, before children have a chance to process this event. In partcular, overriding them makes sense if you draw something that "looks clickable" in TCastleUserInterface.RenderOverChildren.

Public function SensorTranslation(const X, Y, Z, Length: Double; const SecondsPassed: Single): boolean; override;

This item has no description. Showing description inherited from TCastleUserInterface.SensorTranslation.

Translation detected by 3D sensor. Used for example by 3Dconnexion devices.

Public function SensorRotation(const X, Y, Z, Angle: Double; const SecondsPassed: Single): boolean; override;

This item has no description. Showing description inherited from TCastleUserInterface.SensorRotation.

Rotation detected by 3D sensor. Used for example by 3Dconnexion devices.

Public procedure Init(const AInitialPosition, AInitialDirection, AInitialUp: TVector3; const AGravityUp: TVector3; const APreferredHeight: Single; const ARadius: Single); overload; deprecated 'use Viewport.Camera.SetWorldView, and set GravityUp, PreferredHeight, Radius and call CorrectPreferredHeight manually';

Warning: this symbol is deprecated: use Viewport.Camera.SetWorldView, and set GravityUp, PreferredHeight, Radius and call CorrectPreferredHeight manually

Set the most important properties of this navigation, in one call. Sets camera properties (Translation, Direction, Up).

Given here AInitialDirection, AInitialUp, AGravityUp will be normalized, and AInitialUp will be adjusted to be orthogonal to AInitialDirection (see Camera.SetWorldView).

Sets also PreferredHeight and Radius. PreferredHeight may be adjusted to be sensible (by calling CorrectPreferredHeight(ARadius)). You can pass ARadius = 0.0 if you really don't want this PreferredHeight adjustment.

Public procedure Init(const box: TBox3D; const ARadius: Single); overload; deprecated 'use Viewport.Camera.SetWorldView, and set GravityUp, PreferredHeight, Radius and call CorrectPreferredHeight manually';

Warning: this symbol is deprecated: use Viewport.Camera.SetWorldView, and set GravityUp, PreferredHeight, Radius and call CorrectPreferredHeight manually

Alternative Init that sets camera properties such that an object inside Box is more or less "visible good". Sets InitialCameraXxx properties to make it look right, sets current CameraXxx properties to InitialCameraXxx. Sets GravityUp to the same thing as InitialUp. Sets also PreferredHeight to make it behave "sensibly".

Public function DirectionInGravityPlane: TVector3; deprecated 'avoid using it, as it inherently has difficult cases: it is in TCastleCamera local coordinate space, it cannot be correct when Direction is parallel to gravity';

Warning: this symbol is deprecated: avoid using it, as it inherently has difficult cases: it is in TCastleCamera local coordinate space, it cannot be correct when Direction is parallel to gravity

This item has no description.

Public function Motion(const Event: TInputMotion): boolean; override;

This item has no description. Showing description inherited from TCastleUserInterface.Motion.

Motion of mouse or touch.

Public procedure CancelFalling;

If Falling, then this will force Falling to false without calling OnFallenDown. It's much like forcing the opinion that "camera is not falling down right now".

Note that if we will find out (e.g. in nearest Update) that camera is still too high above the ground, then we will start falling down again, setting Falling back to true. (but then we will start falling down from the beginning with initial falling down speed).

This is useful to call if you just changed Camera.Translation because e.g. the player teleported somewhere (or e.g. game levels changed). In this case you just want to forget the fact that camera was falling down — no consequences (like lowering player's health, fadeout etc.).

Public function MaxJumpDistance: Single;

Returns just JumpMaxHeight * PreferredHeight, see JumpMaxHeight for explanation.

Public function RealPreferredHeight: Single;

The PreferredHeight slightly modified by head bobbing and crouch. It can be useful for collision detection between camera and something.

Public procedure FallOnTheGround;

This makes a visual effect of camera falling down horizontally on the ground. Nice to use when player died, and you want to show that it's body falled on the ground. This works by gradually changing Camera.Up such that it gets orthogonal to GravityUp.

Public procedure UpPrefer(const AUp: TVector3); deprecated 'use Viewport.Camera.UpPrefer';

Warning: this symbol is deprecated: use Viewport.Camera.UpPrefer

Change up vector, keeping the direction unchanged. If necessary, the up vector provided here will be fixed to be orthogonal to direction. See TCastleTransform.UpPrefer for detailed documentation what this does.

Public procedure CorrectPreferredHeight;

Correct PreferredHeight based on Radius and on current HeadBobbing.

Exactly what and why is done: if you do any kind of collision detection with some Radius, then you should make sure that RealPreferredHeight is always >= of your Radius, otherwise strange effects may happen when crouching or when head bobbing forces camera to go down.

Exactly, the required equation is

MinimumRealPreferredHeight :=
  PreferredHeight * CrouchHeight * (1 - HeadBobbing);

and always must be

MinimumRealPreferredHeight >= RealPreferredHeight

Reasoning: otherwise this class would "want camera to fall down" (because we will always be higher than RealPreferredHeight) but your OnMoveAllowed would not allow it (because Radius would not allow it).

This method will make sure that this condition holds by eventually adjusting (making larger) PreferredHeight. Note that for Radius = 0.0 this will always leave PreferredHeight as it is.

Properties

Public property PreferGravityUpForRotations: boolean read FPreferGravityUpForRotations write FPreferGravityUpForRotations default true;

If PreferGravityUpForRotations or PreferGravityUpForMoving then various operations are done with respect to GravityUp, otherwise they are done with respect to current Camera.Up.

With PreferGravityUpForRotations, this affects rotations: horizontal rotations (Input_LeftRotate and Input_RightRotate) and rotations caused by MouseLook. Also vertical rotations are bounded by MinAngleFromGravityUp when PreferGravityUpForRotations.

Note that you can change it freely at runtime, and when you set PreferGravityUpForRotations from False to True then in nearest Update the Camera.Up will be gradually fixed, so that Camera.Direction and Camera.Up and GravityUp are on the same plane. Also Camera.Direction may be adjusted to honour MinAngleFromGravityUp.

With PreferGravityUpForMoving, this affects moving: horizontal moving (forward, backward, strafe), and vertical moving (Input_Jump and Input_Crouch when Gravity is False). E.g. when PreferGravityUpForMoving then forward/backward keys are tied to horizontal plane defined by GravityUp. When not PreferGravityUpForMoving then forward/backward try to move you just in the Camera.Direction. Which is usually more handy when e.g. simulating flying.

  • When there is no "natural" up-or-down feeling in the scene, e.g. outer space environment without any gravity, then you may set PreferGravityUpForRotations as False and you should leave PreferGravityUpForMoving and Gravity to False.

  • With PreferGravityUpForRotations the "feeling" of GravityUp is stronger. Raising/bowing the head doesn't mess with "the general sense that there's some vertical axis independent of my movement, that doesn't change, and affects how I move".

    Without PreferGravityUpForRotations, we quickly start to do rotations in an awkward way — once you do some vertical rotation, you changed Camera.Up, and next horizontal rotation will be done versus new Camera.Up.

    If your GravityUp is good, then you generally should leave PreferGravityUpForRotations to True. Unless you really want the player to feel movements as "awkward", e.g. when you want to simulate this "outer space without any gravity" feeling.

  • If your GravityUp is good, then you generally should set PreferGravityUpForMoving just like Gravity.

    E.g. when the player is flying / swimming etc. he will probably prefer PreferGravityUpForMoving = False, because this way he will not have to press Input_Jump and Input_Crouch. Simply pressing Input_Forward and Input_Backward and doing rotations will be enough to move freely in 3D space.

    When gravity works, PreferGravityUpForMoving = True is better, otherwise player would unnecessarily try to jump when looking up.

Public property PreferGravityUpForMoving: boolean read FPreferGravityUpForMoving write FPreferGravityUpForMoving default true;

This item has no description.

Public property MinAngleFromGravityUp: Single read FMinAngleFromGravityUp write FMinAngleFromGravityUp default DefaultMinAngleFromGravityUp;

This sets the minimal angle (in radians) between GravityUp and Camera.Direction, and also between -GravityUp and Camera.Direction. This way vertical rotations (like Input_UpRotate, Input_DownRotate) are "bounded" to not allow player to do something strange, i.e. bow your head too much and raise your head too much.

This is used only when PreferGravityUpForRotations is True and when it's <> 0.0.

This must be always between 0 and Pi/2. Value of Pi/2 will effectively disallow vertical rotations (although you should rather do this in a "cleaner way" by calling MakeClear on Input_UpRotate and Input_DownRotate).

Public property FallSpeedStart: Single read FFallSpeedStart write FFallSpeedStart default DefaultFallSpeedStart;

Initial speed of falling down. Of course this is used only when Gravity is true.

Note that while falling down, the camera will actually fall with greater and greated speed (this adds more realism to the gravity effect...). Note that this is always relative to Camera.Direction length. Camera.Direction determines moving speed — and so it determines also falling speed. The default DefaultFallSpeedStart is chosen to be something sensible, to usually get nice effect of falling.

You can change it at any time, but note that if you change this while Falling is True, then you will not change the "current falling down speed". You will change only the falling down speed used the next time.

Public property FallSpeedIncrease: Single read FFallSpeedIncrease write FFallSpeedIncrease default DefaultFallSpeedIncrease;

When falling down, the speed increases. Set this to 1.0 to fall down with constant speed (taken from FallSpeedStart).

Public property Falling: boolean read FFalling write FFalling;

Are we currently falling down because of gravity.

Public property FallingEffect: boolean read FFallingEffect write FFallingEffect default true;

Make a nice dizzying camera effect when falling down. This adds temporary camera rotations simulating that you rotate randomly and helplessly when falling down.

Of course this is meaningfull only when Gravity works.

Note that changing it from True to False doesn't immediately "cancel out" this effect if it's currently in progress. It only prevents this effect from starting again.

Public property GrowSpeed: Single read FGrowSpeed write FGrowSpeed default DefaultGrowSpeed;

When Gravity works and camera height above the ground is less than PreferredHeight, then we try to "grow", i.e. camera position increases along the GravityUp so that camera height above the ground is closer to PreferredHeight. This property (together with length of Camera.Direction, that always determines every moving speed) determines the speed of this growth.

Public property JumpMaxHeight: Single read FJumpMaxHeight write FJumpMaxHeight default DefaultJumpMaxHeight;

How high can you jump ? The max jump distance is calculated as JumpMaxHeight * PreferredHeight, see MaxJumpDistance.

Public property IsJumping: boolean read FIsJumping;

We are in the middle of a "jump" move right now.

Public property JumpHorizontalSpeedMultiply: Single read FJumpHorizontalSpeedMultiply write FJumpHorizontalSpeedMultiply default DefaultJumpHorizontalSpeedMultiply;

Scales the speed of horizontal moving during jump.

Public property JumpTime: Single read FJumpTime write FJumpTime default DefaultJumpTime;

How fast do you jump up. This is the time, in seconds, in takes to reach MaxJumpDistance height when jumping.

Public property IsCrouching: boolean read FIsCrouching;

Is player crouching right now.

Public property FallingOnTheGround: boolean read FFallingOnTheGround;

True when the effect caused by FallOnTheGround is stil in motion.

Public property IsOnTheGround: boolean read FIsOnTheGround;

This is True when gravity works (that is Gravity is True), and player is standing stable on the ground. This is set in every Update.

You can use this e.g. to make some effects when player is on some special ground (standing or walking), e.g. hurt player when he's standing on some toxical ground.

See also
IsWalkingOnTheGround
This is True when gravity works (that is Gravity is True), and player is standing stable on the ground, and player is moving horizontally.
Public property IsWalkingOnTheGround: boolean read FIsWalkingOnTheGround;

This is True when gravity works (that is Gravity is True), and player is standing stable on the ground, and player is moving horizontally. In other words, this is like "IsOnTheGround and (s)he's walking". This is set in every Update.

The intention is that you can use this to make some "footsteps" sound for the player.

Public property IsAbove: boolean read FIsAbove;

Last known information about whether camera is over the ground.

These are updated continuously only when Gravity is True.

We do not (and, currently, cannot) track here if AboveGround pointer will be eventually released (which may happen if you release your 3D scene, or rebuild scene causing octree rebuild). This is not a problem for navigation class, since we do not use this pointer for anything. But if you use this pointer, then you may want to take care to eventually set it to Nil when your octree or such is released.

AboveHeight is in world coordinates (not camera coordinates).

Public property AboveHeight: Single read FAboveHeight;

This item has no description.

Public property AboveGround: PTriangle read FAboveGround write FAboveGround;

This item has no description.

Public property Input_Forward: TInputShortcut read FInput_Forward;

This item has no description.

Public property Input_Backward: TInputShortcut read FInput_Backward;

This item has no description.

Public property Input_LeftRotate: TInputShortcut read FInput_LeftRotate;

This item has no description.

Public property Input_RightRotate: TInputShortcut read FInput_RightRotate;

This item has no description.

Public property Input_LeftRot: TInputShortcut read FInput_LeftRotate; deprecated 'use Input_LeftRotate';

Warning: this symbol is deprecated: use Input_LeftRotate

This item has no description.

Public property Input_RightRot: TInputShortcut read FInput_RightRotate; deprecated 'use Input_RightRotate';

Warning: this symbol is deprecated: use Input_RightRotate

This item has no description.

Public property Input_LeftStrafe: TInputShortcut read FInput_LeftStrafe;

This item has no description.

Public property Input_RightStrafe: TInputShortcut read FInput_RightStrafe;

This item has no description.

Public property Input_UpRotate: TInputShortcut read FInput_UpRotate;

This item has no description.

Public property Input_DownRotate: TInputShortcut read FInput_DownRotate;

This item has no description.

Public property Input_IncreasePreferredHeight: TInputShortcut read FInput_IncreasePreferredHeight;

This item has no description.

Public property Input_DecreasePreferredHeight: TInputShortcut read FInput_DecreasePreferredHeight;

This item has no description.

Public property Input_GravityUp: TInputShortcut read FInput_GravityUp;

This item has no description.

Public property Input_Run: TInputShortcut read FInput_Run;

This item has no description.

Public property Input_MoveSpeedInc: TInputShortcut read FInput_MoveSpeedInc;

Change the MoveSpeed.

Public property Input_MoveSpeedDec: TInputShortcut read FInput_MoveSpeedDec;

This item has no description.

Public property Input_Jump: TInputShortcut read FInput_Jump;

Jumping and crouching (when Gravity = True) or flying up / down (when Gravity = False).

Public property Input_Crouch: TInputShortcut read FInput_Crouch;

This item has no description.

Public property MoveForward: boolean read FMoveForward write FMoveForward;

Move forward, just like Input_Forward would be pressed.

Public property MoveBackward: boolean read FMoveBackward write FMoveBackward;

Move backward, just like Input_Backward would be pressed.

Public property AllowSlowerRotations: boolean read FAllowSlowerRotations write FAllowSlowerRotations default true;

If True then all rotation keys (Input_RightRotate, Input_LeftRotate, Input_UpRotate, Input_DownRotate) will work 10x slower when Ctrl modified is pressed.

Public property CheckModsDown: boolean read FCheckModsDown write FCheckModsDown default true;

Do we check what key modifiers are pressed and do something differently based on it?

If True then all keys work only when no modifiers or only shift are pressed. Additionally when Ctrl is pressed (and AllowSlowerRotations) then rotation keys work 10x slower. Also Increase/DecreasePreferredHeight work only when Ctrl pressed. Other keys with other modifiers don't work. We allow shift, because to press character "+" on non-numpad keyboard (useful on laptops, where numpad is difficult) you probably need to press shift.

If False then all keys work as usual, no matter what modifiers are pressed. And rotation keys never work 10x slower (AllowSlowerRotations is ignored), also Increase/DecreasePreferredHeight are ignored.

Public property RotationHorizontalPivot: Single read FRotationHorizontalPivot write FRotationHorizontalPivot default 0; deprecated 'use TCastleThirdPersonNavigation for real 3rd-person navigation';

Warning: this symbol is deprecated: use TCastleThirdPersonNavigation for real 3rd-person navigation

Horizontal rotation can rotate around a vector that is RotationHorizontalPivot units forward before the camera. This is a poor-mans way to implement some 3rd camera game. Note that when non-zero this may (for now) move the camera without actually checking OnMoveAllowed.

Public property HeadBobbing: Single read FHeadBobbing write FHeadBobbing default DefaultHeadBobbing;

We may make a "head bobbing" effect, by moving the camera a bit up and down.

This property mutiplied by PreferredHeight says how much head bobbing can move you along GravityUp. Set this to 0 to disable head bobbing. This must always be < 1.0. For sensible effects, this should be rather close to 0.0, for example 0.02.

This is meaningfull only when TCastleWalkNavigation.Gravity works.

Public property HeadBobbingTime: Single read FHeadBobbingTime write FHeadBobbingTime default DefaultHeadBobbingTime;

Controls head bobbing frequency. In the time of HeadBobbingTime seconds, we do full head bobbing sequence (camera swing up, then down again).

Note that if you do a footsteps sound in your game (see stPlayerFootstepsDefault or TMaterialProperty.FootstepsSound) then you will want this property to match your footsteps sound length, things feel and sound natural then. Also, often it sounds better to record two footsteps inside a single sound file, in which case the footstep sound length should be twice as long as this property. For example, record 2 steps inside a 1-second long footstep sound, and set this property to 0.5 a second (which is a default in fact).

Public property ClimbHeight: Single read FClimbHeight write FClimbHeight;

The tallest height that you can climb only used when TCastleWalkNavigation.Gravity is True. This is checked in each single horizontal move when TCastleWalkNavigation.Gravity works. Must be >= 0. Value 0 means there is no limit (and makes a small speedup).

This is reliable to prevent user from climbing stairs and such, when vertical walls are really vertical (not just steep-almost-vertical).

It's not 100% reliable to prevent player from climbing steep hills. That's because, depending on how often an event processing occurs, you actually climb using less or more steps. So even a very steep hill can be always climbed on a computer with very fast speed, because with large FPS you effectively climb it using a lot of very small steps (assuming that FPS limit is not enabled, that is CastleWindow.TCastleApplication.LimitFPS or CastleControl.LimitFPS is zero).

Remember that user can still try jumping to climb on high obstactes. See TCastleWalkNavigation.JumpMaxHeight for a way to control jumping.

For a 100% reliable way to prevent user from reaching some point, that does not rely on specific navigation settings, you should build actual walls in 3D (invisible walls can be created by Collision.proxy in VRML/X3D).

Published property MouseLook;

This item has no description. Showing description inherited from TCastleMouseLookNavigation.MouseLook.

Use mouse look to navigate (rotate the camera).

This also makes mouse cursor of Container hidden, and forces mouse position to the middle of the window (to avoid the situation when mouse movement is blocked by screen borders).

Setting this property at design-time (in CGE editor) does not activate the mouse look in CGE editor. It only controls the mouse look once the application is running.

Published property MouseLookHorizontalSensitivity;

This item has no description. Showing description inherited from TCastleMouseLookNavigation.MouseLookHorizontalSensitivity.

Mouse look sensitivity, if MouseLook is working. These properties specify how much angle change is produced by moving mouse by 1 pixel.

Published property MouseLookVerticalSensitivity;

This item has no description.

Published property InvertVerticalMouseLook;

This item has no description. Showing description inherited from TCastleMouseLookNavigation.InvertVerticalMouseLook.

If this is True and MouseLook works, then the meaning of vertical mouse movement is inverted: when user moves mouse up, he looks down. Some players are more comfortable with such configuration.

Published property RotationHorizontalSpeed: Single read FRotationHorizontalSpeed write FRotationHorizontalSpeed default DefaultRotationHorizontalSpeed;

Rotation keys speed, in radians per second.

Published property RotationVerticalSpeed: Single read FRotationVerticalSpeed write FRotationVerticalSpeed default DefaultRotationVerticalSpeed;

This item has no description.

Published property MoveHorizontalSpeed: Single read FMoveHorizontalSpeed write FMoveHorizontalSpeed default 1.0;

Moving speeds. MoveHorizontalSpeed is only for horizontal movement, MoveVerticalSpeed is only for vertical, and MoveSpeed simply affects both types of movement. Effectively, we always scale the speed of movement by either MoveHorizontalSpeed * MoveSpeed or MoveVerticalSpeed * MoveSpeed.

We move by distance MoveSpeed * MoveHorizontalSpeed (or MoveVerticalSpeed) during one second. So if you leave MoveHorizontalSpeed = MoveVerticalSpeed = 1 (as default), MoveSpeed expresses the speed in nice units / per second.

Default values for all these speed properties is 1.0, so you simply move by 1 unit per second.

Published property MoveVerticalSpeed: Single read FMoveVerticalSpeed write FMoveVerticalSpeed default 1.0;

This item has no description.

Published property MoveSpeed: Single read FMoveSpeed write FMoveSpeed default 1.0;

This item has no description.

Published property MoveSpeedMin: Single read FMoveSpeedMin write FMoveSpeedMin default DefaultMoveSpeedMin;

Minimum and maximum values for possible MoveSpeed that user can make, using Input_MoveSpeedInc, Input_MoveSpeedInc. Note that code can still set MoveSpeed to any value, however small or large, these limits only apply to user changing speed by Input_MoveSpeedInc, Input_MoveSpeedInc.

Published property MoveSpeedMax: Single read FMoveSpeedMax write FMoveSpeedMax default DefaultMoveSpeedMax;

This item has no description.

Published property MouseDraggingHorizontalRotationSpeed: Single read FMouseDraggingHorizontalRotationSpeed write FMouseDraggingHorizontalRotationSpeed default DefaultMouseDraggingHorizontalRotationSpeed;

Speed (radians per pixel delta) of rotations by mouse dragging. Relevant only if niMouseDragging in Input and MouseDragMode is mdRotate or mdWalkRotate. Separate for horizontal and vertical, this way you can e.g. limit (or disable) vertical rotations, useful for games where you mostly look horizontally and accidentally looking up/down is more confusing than useful.

Published property MouseDraggingVerticalRotationSpeed: Single read FMouseDraggingVerticalRotationSpeed write FMouseDraggingVerticalRotationSpeed default DefaultMouseDraggingVerticalRotationSpeed;

This item has no description.

Published property MouseDraggingMoveSpeed: Single read FMouseDraggingMoveSpeed write FMouseDraggingMoveSpeed default DefaultMouseDraggingMoveSpeed;

Moving speed when mouse dragging. Relevant only when (MouseDragMode is mdWalkRotate) and (niMouseDragging in UsingInput).

Published property MouseDragMode: TMouseDragMode read FMouseDragMode write FMouseDragMode default mdWalkRotate;

What mouse dragging does. Used only when niMouseDragging in Input.

Published property Gravity: boolean read FGravity write FGravity default true;

This unlocks a couple of features and automatic behaviors related to gravity. Gravity always drags the camera down to -GravityUp.

Summary of things done by gravity:

While there are many properties allowing you to control gravity behavior, most of them have initial values that should be sensible in all cases. The most important property you need to set yourself is PreferredHeight. Everything else should basically work auto-magically.

Note that Gravity setting is independent from PreferGravityUpForRotations or PreferGravityUpForMoving settings — PreferGravityUpXxx say how the player controls work, Gravity says what happens to player due to ... well, due to gravity.

Published property PreferredHeight: Single read FPreferredHeight write FPreferredHeight default DefaultPreferredHeight;

Height above the ground, only used when TCastleWalkNavigation.Gravity is True. The Camera.Translation tries to stay PreferredHeight above the ground. Temporarily it may still be lower (e.g. player can shortly "duck" when he falls from high).

This must always be >= 0. You should set this to something greater than zero to get sensible behavior of some things related to TCastleWalkNavigation.Gravity.

See CorrectPreferredHeight for important property of PreferredHeight that you should keep.

Published property CrouchHeight: Single read FCrouchHeight write FCrouchHeight default DefaultCrouchHeight;

Preferred height when crouching. This is always mutiplied to PreferredHeight. This should always be <= 1 (CrouchHeight = 1 effectively disables crouching, although it's better to do this by calling MakeClear on Input_Crouch).

Published property Radius;

This item has no description. Showing description inherited from TCastleNavigation.Radius.

The radius of a sphere around the camera that makes collisions with the world.

  • Collision detection routines use this.

  • It determines the projection near plane (that must be slightly smaller than this radius), see also TCastleCamera.ProjectionNear.

  • Walk navigation uses this for automatically correcting PreferredHeight, otherwise weird things could happen if your avatar height is too small compared to the camera radius. See CorrectPreferredHeight.

    Especially useful if you let user change PreferredHeight at runtime by Input_IncreasePreferredHeight, Input_DecreasePreferredHeight.


Generated by PasDoc 0.16.0-snapshot.