-
Notifications
You must be signed in to change notification settings - Fork 24
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #158 from VaclavElias/feat-01-adding-extensions
feat: New projects, tutorials, and extensive extension methods to enhance functionality and documentation
- Loading branch information
Showing
38 changed files
with
5,431 additions
and
34 deletions.
There are no files selected for viewing
This file contains 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
This file contains 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
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
# Using Easing Functions: Animating Position and Material Color | ||
|
||
**Easing functions** are used in animations to create smooth transitions between values over a specified time. In this tutorial, we'll explore how to use easing functions not only to move a 3D object but also to interpolate its material color. This will allow us to create animations that blend both movement and visual effects. | ||
|
||
## What You'll Learn | ||
- How to create a 3D primitive (cube). | ||
- How to implement easing functions for smooth transitions in animations. | ||
- How to animate the movement of a 3D object using easing functions. | ||
- How to interpolate and change the material color of a 3D object dynamically. | ||
|
||
## Code Walkthrough | ||
|
||
[!code-csharp[Easing demo](../../../examples/snippets/Easing_Example01/Program.cs)] | ||
|
||
## Code Breakdown | ||
|
||
- **Position Animation:** The `MathUtilEx.Interpolate` method is used with a quintic easing function to smoothly transition the sphere's position from its start to its end position. | ||
- **Material Color Animation:** The same interpolation approach is applied to change the color of the sphere’s material. A **linear easing function** is used to gradually change the color from white to a randomly generated color. | ||
- **Resetting the Animation:** The animation is reset each time the spacebar is pressed, allowing the movement and color transition to start over. | ||
|
||
## Running the Code | ||
|
||
When you run the code, you'll see a 3D sphere smoothly moving from the starting position (8 units above the ground) to the bottom (2 units above the ground) over a duration of 2 seconds. At the same time, the sphere’s material color will gradually change from white to a randomly generated color. You can press the **spacebar** to reset the animation and see the sphere rise back to the top while its color returns to white. | ||
|
||
## Summary | ||
|
||
In this tutorial, you learned how to animate both the position and material color of a 3D object using easing functions. This technique allows you to create smooth and visually appealing transitions, which are essential for creating polished game experiences. |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
# 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 | ||
|
||
[!code-csharp[Pick and Aim](../../../examples/snippets/Physics_Example001/Program.cs)] | ||
|
||
## 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. |
This file contains 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
This file contains 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
14 changes: 14 additions & 0 deletions
14
examples/snippets/Easing_Example01/Easing_Example01.csproj
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<OutputType>Exe</OutputType> | ||
<TargetFramework>net8.0</TargetFramework> | ||
<ImplicitUsings>enable</ImplicitUsings> | ||
<Nullable>enable</Nullable> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\..\..\src\Stride.CommunityToolkit.Windows\Stride.CommunityToolkit.Windows.csproj" /> | ||
</ItemGroup> | ||
|
||
</Project> |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
using Stride.CommunityToolkit.Engine; | ||
using Stride.CommunityToolkit.Mathematics; | ||
using Stride.CommunityToolkit.Rendering.ProceduralModels; | ||
using Stride.Core.Mathematics; | ||
using Stride.Engine; | ||
using Stride.Games; | ||
using Stride.Input; | ||
using Stride.Rendering.Materials; | ||
|
||
// Time elapsed since the start of the animation | ||
var elapsed = TimeSpan.Zero; | ||
|
||
// Duration of the animation (2 seconds) | ||
var duration = TimeSpan.FromSeconds(2); | ||
|
||
// Target position (where the object will ease to) | ||
var bottom = new Vector3(0, 2, 0); | ||
|
||
// Starting position of the object | ||
var startPosition = new Vector3(0, 8, 0); | ||
|
||
// 3D entity to be animated | ||
var entity = new Entity(); | ||
|
||
// Color to interpolate to, initilized to white | ||
Color color = Color.White; | ||
|
||
// Initialize a new game instance | ||
using var game = new Game(); | ||
|
||
// Run the game, specifying both the Start and Update methods | ||
game.Run(start: Start, update: Update); | ||
|
||
// Setup and initialize the scene | ||
void Start(Scene scene) | ||
{ | ||
// Set up a base 3D scene with default lighting and camera | ||
game.SetupBase3DScene(); | ||
|
||
// Create a 3D sphere primitive and assign the material to it | ||
entity = game.Create3DPrimitive(PrimitiveModelType.Sphere, new() | ||
{ | ||
Material = game.CreateMaterial(Color.White) | ||
}); | ||
|
||
// Add the sphere entity to the root scene | ||
entity.Scene = scene; | ||
|
||
var random = new Random(); | ||
|
||
// Generate a random color to interpolate to | ||
color = random.NextColor(); | ||
} | ||
|
||
// Update the scene every frame (for animations and input handling) | ||
void Update(Scene scene, GameTime time) | ||
{ | ||
// Calculate the progress of the animation as a ratio between 0 and 1 | ||
var progress = (float)(elapsed.TotalSeconds / duration.TotalSeconds); | ||
|
||
if (progress > 1.0f) | ||
{ | ||
progress = 1.0f; | ||
} | ||
|
||
// Interpolate the position of the object using a quintic easing function | ||
var position = MathUtilEx.Interpolate(startPosition, bottom, progress, EasingFunction.QuinticEaseOut); | ||
|
||
Console.WriteLine(position); | ||
|
||
// Apply the new position to the entity | ||
entity.Transform.Position = position; | ||
|
||
// Interpolate the color using a linear easing function | ||
var diffuse = MathUtilEx.Interpolate(Color.White, color, progress, EasingFunction.Linear); | ||
|
||
// Apply the interpolated color to the material | ||
entity.Get<ModelComponent>().SetMaterialParameter(MaterialKeys.DiffuseValue, diffuse); | ||
|
||
// Update the elapsed time with the time since the last frame | ||
elapsed += time.Elapsed; | ||
|
||
// Reset the animation when the spacebar is pressed | ||
if (game.Input.IsKeyPressed(Keys.Space)) | ||
{ | ||
elapsed = TimeSpan.Zero; | ||
} | ||
} |
14 changes: 14 additions & 0 deletions
14
examples/snippets/Physics_Example001/Physics_Example001.csproj
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<OutputType>Exe</OutputType> | ||
<TargetFramework>net8.0</TargetFramework> | ||
<ImplicitUsings>enable</ImplicitUsings> | ||
<Nullable>enable</Nullable> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\..\..\src\Stride.CommunityToolkit.Windows\Stride.CommunityToolkit.Windows.csproj" /> | ||
</ItemGroup> | ||
|
||
</Project> |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
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); | ||
} | ||
} |
This file contains 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
Oops, something went wrong.