Created
November 28, 2025 18:32
-
-
Save w0wca7a/2b1208cc014329b20011b7f8e1b0d885 to your computer and use it in GitHub Desktop.
Camera controller for GameControllers in Stride based on DirectInput
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| using System; | |
| using Stride.Core.Mathematics; | |
| using Stride.Engine; | |
| using Stride.Input; | |
| public class BasicCameraGameController : SyncScript | |
| { | |
| private const float MaximumPitch = MathUtil.PiOverTwo * 0.99f; | |
| private Vector3 upVector; | |
| private Vector3 translation; | |
| private float yaw; | |
| private float pitch; | |
| public float SpeedFactor { get; set; } = 50.0f; | |
| public float MovementSensitive { get; set; } = 4f; | |
| public float RotationSensitive { get; set; } = 4f; | |
| public Buttons Down { get; set; } = Buttons.LeftThumb; | |
| public Buttons Up { get; set; } = Buttons.RightThumb; | |
| public Buttons Force { get; set; } = Buttons.LeftShoulder; | |
| public override void Start() | |
| { | |
| base.Start(); | |
| upVector = Vector3.UnitY; | |
| } | |
| public override void Update() | |
| { | |
| ProcessInput(); | |
| UpdateTransform(); | |
| } | |
| private void ProcessInput() | |
| { | |
| float deltaTime = (float)Game.UpdateTime.Elapsed.TotalSeconds; | |
| translation = Vector3.Zero; | |
| yaw = 0f; | |
| pitch = 0f; | |
| { | |
| float speed = 1f * deltaTime; | |
| Vector3 dir = Vector3.Zero; | |
| if (Input.HasGameController) | |
| { | |
| var gameController = Input.GameControllers[0]; | |
| var dpad = gameController.GetDPad(0); | |
| switch (dpad) | |
| { | |
| //up | |
| case GamePadButton.PadUp: | |
| dir.Z += 50 * speed; | |
| break; | |
| // right | |
| case GamePadButton.PadRight: | |
| dir.X += 50 * speed; | |
| break; | |
| // down | |
| case GamePadButton.PadDown: | |
| dir.Z -= 50 * speed; | |
| break; | |
| //left | |
| case GamePadButton.PadLeft: | |
| dir.X -= 50 * speed; | |
| break; | |
| //up-right | |
| case (GamePadButton.PadUp | GamePadButton.PadRight): | |
| dir.Z += 50 * speed; | |
| dir.X += 50 * speed; | |
| break; | |
| // right-down | |
| case (GamePadButton.PadRight | GamePadButton.PadDown): | |
| dir.X += 50 * speed; | |
| dir.Z -= 50 * speed; | |
| break; | |
| // left-down | |
| case (GamePadButton.PadDown | GamePadButton.PadLeft): | |
| dir.Z -= 50 * speed; | |
| dir.X -= 50 * speed; | |
| break; | |
| // left-up | |
| case (GamePadButton.PadLeft | GamePadButton.PadUp): | |
| dir.X -= 50 * speed; | |
| dir.Z += 50 * speed; | |
| break; | |
| } | |
| dir.Z += -gameController.GetAxis(1); | |
| dir.X += gameController.GetAxis(0); | |
| if (gameController.IsButtonDown((int)Down)) | |
| { | |
| dir.Y -= 50 * speed; | |
| } | |
| if (gameController.IsButtonDown((int)Up)) | |
| { | |
| dir.Y += 50 * speed; | |
| } | |
| if (gameController.IsButtonDown((int)Force)) | |
| { | |
| speed *= SpeedFactor; | |
| } | |
| } | |
| translation += dir * speed * MovementSensitive; | |
| } | |
| { | |
| float speed = 1f * deltaTime; | |
| Vector2 rotation = Vector2.Zero; | |
| if (Input.HasGameController) | |
| { | |
| var gameController = Input.GameControllers[0]; | |
| rotation.X += -gameController.GetAxis(3); | |
| rotation.Y += -gameController.GetAxis(2); | |
| } | |
| rotation *= speed * RotationSensitive / 5; | |
| pitch += rotation.X; | |
| yaw += rotation.Y; | |
| } | |
| } | |
| private void UpdateTransform() | |
| { | |
| var rotation = Matrix.RotationQuaternion(Entity.Transform.Rotation); | |
| var right = Vector3.Cross(rotation.Forward, upVector); | |
| var up = Vector3.Cross(right, rotation.Forward); | |
| right.Normalize(); | |
| up.Normalize(); | |
| var currentPitch = MathUtil.PiOverTwo - MathF.Acos(Vector3.Dot(rotation.Forward, upVector)); | |
| pitch = MathUtil.Clamp(currentPitch + pitch, -MaximumPitch, MaximumPitch) - currentPitch; | |
| Vector3 finalTranslation = translation; | |
| finalTranslation.Z = -finalTranslation.Z; | |
| finalTranslation = Vector3.TransformCoordinate(finalTranslation, rotation); | |
| Entity.Transform.Position += finalTranslation; | |
| Entity.Transform.Rotation *= Quaternion.RotationAxis(right, pitch) * Quaternion.RotationAxis(upVector, yaw); | |
| } | |
| public enum Buttons | |
| { | |
| X = 0, | |
| A = 1, | |
| B = 2, | |
| Y = 3, | |
| LeftShoulder = 4, | |
| RightShoulder = 5, | |
| LeftStick = 6, | |
| RightStick = 7, | |
| Back = 8, | |
| Start = 9, | |
| LeftThumb = 10, | |
| RightThumb = 11 | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment