Skip to content

Instantly share code, notes, and snippets.

@w0wca7a
Created November 28, 2025 18:32
Show Gist options
  • Select an option

  • Save w0wca7a/2b1208cc014329b20011b7f8e1b0d885 to your computer and use it in GitHub Desktop.

Select an option

Save w0wca7a/2b1208cc014329b20011b7f8e1b0d885 to your computer and use it in GitHub Desktop.
Camera controller for GameControllers in Stride based on DirectInput
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