Skip to content

Commit

Permalink
feat: Updated example controllers
Browse files Browse the repository at this point in the history
RuntimeData struct for inspector folding
  • Loading branch information
MrGadget1024 committed Sep 30, 2024
1 parent 53d8812 commit 70351d9
Show file tree
Hide file tree
Showing 6 changed files with 552 additions and 338 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public struct OptionsKeys
public KeyCode ToggleUI;
}

public enum GroundState : byte { Jumping, Falling, Grounded }
public enum GroundState : byte { Grounded, Jumping, Falling }

[Serializable]
public struct MoveKeys
Expand Down Expand Up @@ -145,46 +145,123 @@ public enum ControlOptions : byte
[Tooltip("Roll acceleration in degrees per second squared")]
public float rollAcceleration = 3f;

[Header("Diagnostics")]
[ReadOnly, SerializeField]
GroundState groundState = GroundState.Grounded;
// Runtime data in a struct so it can be folded up in inspector
[Serializable]
public struct RuntimeData
{
[ReadOnly, SerializeField, Range(-1f, 1f)] float _horizontal;
[ReadOnly, SerializeField, Range(-1f, 1f)] float _vertical;
[ReadOnly, SerializeField, Range(-300f, 300f)] float _turnSpeed;
[ReadOnly, SerializeField, Range(-180f, 180f)] float _pitchAngle;
[ReadOnly, SerializeField, Range(-180f, 180f)] float _pitchSpeed;
[ReadOnly, SerializeField, Range(-180f, 180f)] float _rollAngle;
[ReadOnly, SerializeField, Range(-180f, 180f)] float _rollSpeed;
[ReadOnly, SerializeField, Range(-1.5f, 1.5f)] float _animVelocity;
[ReadOnly, SerializeField, Range(-1.5f, 1.5f)] float _animRotation;
[ReadOnly, SerializeField, Range(-1f, 1f)] float _mouseInputX;
[ReadOnly, SerializeField, Range(0, 30f)] float _mouseSensitivity;
[ReadOnly, SerializeField] GroundState _groundState;
[ReadOnly, SerializeField] Vector3 _direction;
[ReadOnly, SerializeField] Vector3Int _velocity;
[ReadOnly, SerializeField] GameObject _controllerUI;

#region Properties

public float horizontal
{
get => _horizontal;
internal set => _horizontal = value;
}

[ReadOnly, SerializeField, Range(-1f, 1f)]
float horizontal;
[ReadOnly, SerializeField, Range(-1f, 1f)]
float vertical;
public float vertical
{
get => _vertical;
internal set => _vertical = value;
}

[ReadOnly, SerializeField, Range(-1f, 1f)]
float mouseInputX;
[ReadOnly, SerializeField, Range(0, 30f)]
float mouseSensitivity;
[ReadOnly, SerializeField, Range(-300f, 300f)]
float turnSpeed;
public float turnSpeed
{
get => _turnSpeed;
internal set => _turnSpeed = value;
}

[ReadOnly, SerializeField, Range(-180f, 180f)]
float pitchAngle;
[ReadOnly, SerializeField, Range(-180f, 180f)]
float pitchSpeed;
public float pitchAngle
{
get => _pitchAngle;
internal set => _pitchAngle = value;
}

[ReadOnly, SerializeField, Range(-180f, 180f)]
float rollAngle;
[ReadOnly, SerializeField, Range(-180f, 180f)]
float rollSpeed;
public float pitchSpeed
{
get => _pitchSpeed;
internal set => _pitchSpeed = value;
}

[ReadOnly, SerializeField, Range(-1.5f, 1.5f)]
float animVelocity;
public float rollAngle
{
get => _rollAngle;
internal set => _rollAngle = value;
}

[ReadOnly, SerializeField, Range(-1.5f, 1.5f)]
float animRotation;
public float rollSpeed
{
get => _rollSpeed;
internal set => _rollSpeed = value;
}

[ReadOnly, SerializeField]
Vector3 direction;
public float animVelocity
{
get => _animVelocity;
internal set => _animVelocity = value;
}

[ReadOnly, SerializeField]
Vector3Int velocity;
public float animRotation
{
get => _animRotation;
internal set => _animRotation = value;
}

[ReadOnly, SerializeField]
GameObject controllerUI;
public float mouseInputX
{
get => _mouseInputX;
internal set => _mouseInputX = value;
}

public float mouseSensitivity
{
get => _mouseSensitivity;
internal set => _mouseSensitivity = value;
}

public GroundState groundState
{
get => _groundState;
internal set => _groundState = value;
}

public Vector3 direction
{
get => _direction;
internal set => _direction = value;
}

public Vector3Int velocity
{
get => _velocity;
internal set => _velocity = value;
}

public GameObject controllerUI
{
get => _controllerUI;
internal set => _controllerUI = value;
}

#endregion
}

[Header("Diagnostics")]
public RuntimeData runtimeData;

#region Network Setup

Expand Down Expand Up @@ -235,8 +312,7 @@ public override void OnStartAuthority()
{
// Calculate DPI-aware sensitivity
float dpiScale = (Screen.dpi > 0) ? (Screen.dpi / BASE_DPI) : 1f;
mouseSensitivity = turnAcceleration * dpiScale;
//Debug.Log($"Screen DPI: {Screen.dpi}, DPI Scale: {dpiScale}, Adjusted Turn Acceleration: {turnAccelerationDPI}");
runtimeData.mouseSensitivity = turnAcceleration * dpiScale;

SetCursor(controlOptions.HasFlag(ControlOptions.MouseSteer));

Expand All @@ -262,22 +338,22 @@ public override void OnStopAuthority()
public override void OnStartLocalPlayer()
{
if (ControllerUIPrefab != null)
controllerUI = Instantiate(ControllerUIPrefab);
runtimeData.controllerUI = Instantiate(ControllerUIPrefab);

if (controllerUI != null)
if (runtimeData.controllerUI != null)
{
if (controllerUI.TryGetComponent(out FlyerControllerUI canvasControlPanel))
if (runtimeData.controllerUI.TryGetComponent(out FlyerControllerUI canvasControlPanel))
canvasControlPanel.Refresh(moveKeys, flightKeys, optionsKeys);

controllerUI.SetActive(controlOptions.HasFlag(ControlOptions.ShowUI));
runtimeData.controllerUI.SetActive(controlOptions.HasFlag(ControlOptions.ShowUI));
}
}

public override void OnStopLocalPlayer()
{
if (controllerUI != null)
Destroy(controllerUI);
controllerUI = null;
if (runtimeData.controllerUI != null)
Destroy(runtimeData.controllerUI);
runtimeData.controllerUI = null;
}

#endregion
Expand Down Expand Up @@ -306,12 +382,12 @@ void Update()

// Reset ground state
if (characterController.isGrounded)
groundState = GroundState.Grounded;
else if (groundState != GroundState.Jumping)
groundState = GroundState.Falling;
runtimeData.groundState = GroundState.Grounded;
else if (runtimeData.groundState != GroundState.Jumping)
runtimeData.groundState = GroundState.Falling;

// Diagnostic velocity...FloorToInt for display purposes
velocity = Vector3Int.FloorToInt(characterController.velocity);
runtimeData.velocity = Vector3Int.FloorToInt(characterController.velocity);
}

void SetCursor(bool locked)
Expand All @@ -335,8 +411,8 @@ void HandleOptions()
{
controlOptions ^= ControlOptions.ShowUI;

if (controllerUI != null)
controllerUI.SetActive(controlOptions.HasFlag(ControlOptions.ShowUI));
if (runtimeData.controllerUI != null)
runtimeData.controllerUI.SetActive(controlOptions.HasFlag(ControlOptions.ShowUI));
}

if (flightKeys.AutoLevel != KeyCode.None && Input.GetKeyUp(flightKeys.AutoLevel))
Expand All @@ -354,28 +430,28 @@ void HandleTurning(float deltaTime)
if (moveKeys.TurnRight != KeyCode.None && Input.GetKey(moveKeys.TurnRight))
targetTurnSpeed += maxTurnSpeed;

turnSpeed = Mathf.MoveTowards(turnSpeed, targetTurnSpeed, turnAcceleration * maxTurnSpeed * deltaTime);
transform.Rotate(0f, turnSpeed * deltaTime, 0f);
runtimeData.turnSpeed = Mathf.MoveTowards(runtimeData.turnSpeed, targetTurnSpeed, turnAcceleration * maxTurnSpeed * deltaTime);
transform.Rotate(0f, runtimeData.turnSpeed * deltaTime, 0f);
}

void HandleMouseSteer(float deltaTime)
{
// Accumulate mouse input over time
mouseInputX += Input.GetAxisRaw("Mouse X") * mouseSensitivity;
runtimeData.mouseInputX += Input.GetAxisRaw("Mouse X") * runtimeData.mouseSensitivity;

// Clamp the accumulator to simulate key press behavior
mouseInputX = Mathf.Clamp(mouseInputX, -1f, 1f);
runtimeData.mouseInputX = Mathf.Clamp(runtimeData.mouseInputX, -1f, 1f);

// Calculate target turn speed
float targetTurnSpeed = mouseInputX * maxTurnSpeed;
float targetTurnSpeed = runtimeData.mouseInputX * maxTurnSpeed;

// Use the same acceleration logic as HandleTurning
turnSpeed = Mathf.MoveTowards(turnSpeed, targetTurnSpeed, mouseSensitivity * maxTurnSpeed * deltaTime);
runtimeData.turnSpeed = Mathf.MoveTowards(runtimeData.turnSpeed, targetTurnSpeed, runtimeData.mouseSensitivity * maxTurnSpeed * deltaTime);

// Apply rotation
transform.Rotate(0f, turnSpeed * deltaTime, 0f);
transform.Rotate(0f, runtimeData.turnSpeed * deltaTime, 0f);

mouseInputX = Mathf.MoveTowards(mouseInputX, 0f, mouseSensitivity * deltaTime);
runtimeData.mouseInputX = Mathf.MoveTowards(runtimeData.mouseInputX, 0f, runtimeData.mouseSensitivity * deltaTime);
}

void HandlePitch(float deltaTime)
Expand All @@ -396,15 +472,15 @@ void HandlePitch(float deltaTime)
inputDetected = true;
}

pitchSpeed = Mathf.MoveTowards(pitchSpeed, targetPitchSpeed, pitchAcceleration * maxPitchSpeed * deltaTime);
runtimeData.pitchSpeed = Mathf.MoveTowards(runtimeData.pitchSpeed, targetPitchSpeed, pitchAcceleration * maxPitchSpeed * deltaTime);

// Apply pitch rotation
pitchAngle += pitchSpeed * deltaTime;
pitchAngle = Mathf.Clamp(pitchAngle, -maxPitchUpAngle, maxPitchDownAngle);
runtimeData.pitchAngle += runtimeData.pitchSpeed * deltaTime;
runtimeData.pitchAngle = Mathf.Clamp(runtimeData.pitchAngle, -maxPitchUpAngle, maxPitchDownAngle);

// Return to zero when no input
if (!inputDetected && controlOptions.HasFlag(ControlOptions.AutoLevel))
pitchAngle = Mathf.MoveTowards(pitchAngle, 0f, maxPitchSpeed * deltaTime);
runtimeData.pitchAngle = Mathf.MoveTowards(runtimeData.pitchAngle, 0f, maxPitchSpeed * deltaTime);

ApplyRotation();
}
Expand All @@ -427,15 +503,15 @@ void HandleRoll(float deltaTime)
inputDetected = true;
}

rollSpeed = Mathf.MoveTowards(rollSpeed, targetRollSpeed, rollAcceleration * maxRollSpeed * deltaTime);
runtimeData.rollSpeed = Mathf.MoveTowards(runtimeData.rollSpeed, targetRollSpeed, rollAcceleration * maxRollSpeed * deltaTime);

// Apply roll rotation
rollAngle += rollSpeed * deltaTime;
rollAngle = Mathf.Clamp(rollAngle, -maxRollAngle, maxRollAngle);
runtimeData.rollAngle += runtimeData.rollSpeed * deltaTime;
runtimeData.rollAngle = Mathf.Clamp(runtimeData.rollAngle, -maxRollAngle, maxRollAngle);

// Return to zero when no input
if (!inputDetected && controlOptions.HasFlag(ControlOptions.AutoLevel))
rollAngle = Mathf.MoveTowards(rollAngle, 0f, maxRollSpeed * deltaTime);
runtimeData.rollAngle = Mathf.MoveTowards(runtimeData.rollAngle, 0f, maxRollSpeed * deltaTime);

ApplyRotation();
}
Expand All @@ -446,7 +522,7 @@ void ApplyRotation()
float currentYaw = transform.localRotation.eulerAngles.y;

// Apply all rotations
transform.localRotation = Quaternion.Euler(pitchAngle, currentYaw, rollAngle);
transform.localRotation = Quaternion.Euler(runtimeData.pitchAngle, currentYaw, runtimeData.rollAngle);
}

void HandleMove(float deltaTime)
Expand All @@ -464,39 +540,36 @@ void HandleMove(float deltaTime)
if (targetMoveX == 0f)
{
if (!controlOptions.HasFlag(ControlOptions.AutoRun))
horizontal = Mathf.MoveTowards(horizontal, targetMoveX, inputGravity * deltaTime);
runtimeData.horizontal = Mathf.MoveTowards(runtimeData.horizontal, targetMoveX, inputGravity * deltaTime);
}
else
horizontal = Mathf.MoveTowards(horizontal, targetMoveX, inputSensitivity * deltaTime);
runtimeData.horizontal = Mathf.MoveTowards(runtimeData.horizontal, targetMoveX, inputSensitivity * deltaTime);

if (targetMoveZ == 0f)
{
if (!controlOptions.HasFlag(ControlOptions.AutoRun))
vertical = Mathf.MoveTowards(vertical, targetMoveZ, inputGravity * deltaTime);
runtimeData.vertical = Mathf.MoveTowards(runtimeData.vertical, targetMoveZ, inputGravity * deltaTime);
}
else
vertical = Mathf.MoveTowards(vertical, targetMoveZ, inputSensitivity * deltaTime);
runtimeData.vertical = Mathf.MoveTowards(runtimeData.vertical, targetMoveZ, inputSensitivity * deltaTime);
}

void ApplyMove(float deltaTime)
{
// Create initial direction vector without jumpSpeed (y-axis).
direction = new Vector3(horizontal, 0f, vertical);
runtimeData.direction = new Vector3(runtimeData.horizontal, 0f, runtimeData.vertical);

// Clamp so diagonal strafing isn't a speed advantage.
direction = Vector3.ClampMagnitude(direction, 1f);
runtimeData.direction = Vector3.ClampMagnitude(runtimeData.direction, 1f);

// Transforms direction from local space to world space.
direction = transform.TransformDirection(direction);
runtimeData.direction = transform.TransformDirection(runtimeData.direction);

// Multiply for desired ground speed.
direction *= maxMoveSpeed;

//// Add jumpSpeed to direction as last step.
//direction.y = jumpSpeed;
runtimeData.direction *= maxMoveSpeed;

// Finally move the character.
characterController.Move(direction * deltaTime);
characterController.Move(runtimeData.direction * deltaTime);
}
}
}
Loading

0 comments on commit 70351d9

Please sign in to comment.