Table of Contents

Raycasting and Camera Focus

In this tutorial, we will learn how to use raycasting to detect entities in a 3D scene and adjust the camera to focus on them. This technique is useful for games or simulations where you need to interact with objects using the mouse and smoothly transition the camera's focus based on those interactions.

What You'll Learn

  • How to create 3D entities and assign materials to them.
  • How to use raycasting to detect objects in a 3D scene.
  • How to use the camera to smoothly look at the target entity.

Code Walkthrough

using Stride.CommunityToolkit.Bullet;
using Stride.CommunityToolkit.Engine;
using Stride.CommunityToolkit.Games;
using Stride.CommunityToolkit.Physics;
using Stride.CommunityToolkit.Rendering.ProceduralModels;
using Stride.Core.Mathematics;
using Stride.Engine;
using Stride.Games;
using Stride.Physics;

Entity? target = null;
CameraComponent? camera = null;
Simulation? simulation = null;

using var game = new Game();

game.Run(start: Start, update: Update);

void Start(Scene scene)
{
    // Set up a base 3D scene with default lighting and camera
    game.SetupBase3DScene();

    // Add a gizmo to help visualize the ground plane and axis directions
    game.AddGroundGizmo(showAxisName: true);

    // Create a cube entity with a violet material and position it in the scene
    var cube = game.Create3DPrimitive(PrimitiveModelType.Cube, new()
    {
        Material = game.CreateMaterial(Color.Violet),
    });

    // Set the position of the cube
    cube.Transform.Position = new Vector3(0, 8, -3);

    // Add cube to the scene
    cube.Scene = scene;

    // Create a sphere entity with a wheat-colored material
    var entity = game.Create3DPrimitive(PrimitiveModelType.Sphere, new()
    {
        Material = game.CreateMaterial(Color.Wheat),
    });

    // Set the position of the sphere
    entity.Transform.Position = new Vector3(-4, 8, 0);

    // Add sphere to the scene
    entity.Scene = scene;

    // Retrieve the camera and the physics simulation from the scene
    camera = scene.GetCamera();
    simulation = game.SceneSystem.SceneInstance.GetProcessor<PhysicsProcessor>()?.Simulation;
}

// Update method called every frame to handle game logic
void Update(Scene scene, GameTime gameTime)
{
    // Ensure that the camera and simulation are initialized
    if (simulation == null || camera is null) return;

    // Check if the left mouse button is pressed
    if (game.Input.IsMouseButtonPressed(Stride.Input.MouseButton.Left))
    {
        // Cast a ray from the mouse position into the world
        var ray = camera.ScreenToWorldRaySegment(game.Input.MousePosition);

        // Perform raycasting in the simulation to detect any entities
        var hitResult = simulation.Raycast(ray);

        if (hitResult.Succeeded)
        {
            // If the ray hits an entity, set it as the camera's target
            target = hitResult.Collider.Entity;
        }
    }

    // If a target entity is set, make the camera smoothly look at it
    if (target != null)
    {
        camera.Entity.Transform.LookAt(target.Transform, game.DeltaTime() * 3.0f);
    }
}

Code Walkthrough

  • Game Setup: In the Start() method, we set up a basic 3D scene with lighting and a camera using the SetupBase3DScene() helper method. We then create two 3D entities, a cube and a sphere, and position them in the scene with different materials.

  • Raycasting with Mouse Input: In the Update() method, we check if the left mouse button is pressed. If pressed, a ray is cast from the mouse position into the 3D world using ScreenToWorldRaySegment(). This ray is used to check for collisions with 3D entities in the scene via raycasting.

  • Camera Focus: If the ray successfully hits an entity, that entity becomes the target. The camera then uses the LookAt() method to smoothly focus on the target entity, giving the player a clear view of the object they clicked on.

Running the Code

When you run this code, the game will display a 3D scene with a cube and a sphere. By clicking on either object with the mouse, the camera will smoothly rotate to focus on the clicked object. The left mouse button controls the focus.

Summary

This example demonstrates how to use raycasting to detect entities in a scene based on mouse input and how to adjust the camera to focus on those entities. This technique is useful for games that require interactive environments, object selection, or camera-based interactions.

Feel free to extend this concept by adding more entities, adjusting the camera's behavior, or experimenting with different easing functions for camera movement.