First person camera
This C# Intermediate tutorial covers the implementation of first person camera.
Explanation
You learn about mouse movement and how to convert that into a 3d rotation. We set up camera angle limits and finally we apply movement to a first person character controller.
Camera controller
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
using Stride.Core.Mathematics;
using Stride.Engine;
using Stride.Input;
using Stride.Physics;
namespace CSharpIntermediate.Code
{
public class FirstPersonCamera : SyncScript
{
public float MouseSpeed = 0.6f;
public float MaxLookUpAngle = -50;
public float MaxLookDownAngle = 50;
public bool InvertMouseY = false;
private Entity firstPersonCameraPivot;
private Vector3 camRotation;
private bool isActive = false;
private Vector2 maxCameraAnglesRadians;
private CharacterComponent character;
public override void Start()
{
firstPersonCameraPivot = Entity.FindChild("CameraPivot");
// Convert the Max camera angles from Degress to Radions
maxCameraAnglesRadians = new Vector2(MathUtil.DegreesToRadians(MaxLookUpAngle), MathUtil.DegreesToRadians(MaxLookDownAngle));
// Store the initial camera rotation
camRotation = Entity.Transform.RotationEulerXYZ;
// Set the mouse to the middle of the screen
Input.MousePosition = new Vector2(0.5f, 0.5f);
isActive = true;
Game.IsMouseVisible = false;
character = Entity.Get<CharacterComponent>();
}
public override void Update()
{
if (Input.IsKeyPressed(Keys.Escape))
{
isActive = !isActive;
Game.IsMouseVisible = !isActive;
Input.UnlockMousePosition();
}
if (isActive)
{
Input.LockMousePosition();
var mouseMovement = Input.MouseDelta * MouseSpeed;
// Update camera rotation values
camRotation.Y += -mouseMovement.X;
camRotation.X += InvertMouseY ? -mouseMovement.Y : mouseMovement.Y;
camRotation.X = MathUtil.Clamp(camRotation.X, maxCameraAnglesRadians.X, maxCameraAnglesRadians.Y);
// Apply Y rotation to character entity
character.Orientation = Quaternion.RotationY(camRotation.Y);
// Entity.Transform.Rotation = Quaternion.RotationY(camRotation.Y);
// Apply X camera rotation to the existing camera rotations
firstPersonCameraPivot.Transform.Rotation = Quaternion.RotationX(camRotation.X);
}
}
}
}
Character movement
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
using Stride.Core.Mathematics;
using Stride.Engine;
using Stride.Input;
using Stride.Physics;
namespace CSharpIntermediate.Code
{
public class CharacterMovement : SyncScript
{
public Vector3 MovementMultiplier = new Vector3(3, 0, 4);
private CharacterComponent character;
public override void Start()
{
character = Entity.Get<CharacterComponent>();
}
public override void Update()
{
var velocity = new Vector3();
if (Input.IsKeyDown(Keys.W))
{
velocity.Z++;
}
if (Input.IsKeyDown(Keys.S))
{
velocity.Z--;
}
if (Input.IsKeyDown(Keys.A))
{
velocity.X++;
}
if (Input.IsKeyDown(Keys.D))
{
velocity.X--;
}
velocity.Normalize();
velocity *= MovementMultiplier;
velocity = Vector3.Transform(velocity, Entity.Transform.Rotation);
character.SetVelocity(velocity);
}
}
}