diff --git a/samples/Audio/SimpleAudio/SimpleAudio.Game/SimpleAudio.Game.csproj b/samples/Audio/SimpleAudio/SimpleAudio.Game/SimpleAudio.Game.csproj
index 84ccd03ced..b0e9775095 100644
--- a/samples/Audio/SimpleAudio/SimpleAudio.Game/SimpleAudio.Game.csproj
+++ b/samples/Audio/SimpleAudio/SimpleAudio.Game/SimpleAudio.Game.csproj
@@ -2,6 +2,8 @@
net8.0
SimpleAudio
+ enable
+ latest
diff --git a/samples/Audio/SimpleAudio/SimpleAudio.Game/SoundScript.cs b/samples/Audio/SimpleAudio/SimpleAudio.Game/SoundScript.cs
index 7ff46f7cd6..647e1809c3 100644
--- a/samples/Audio/SimpleAudio/SimpleAudio.Game/SoundScript.cs
+++ b/samples/Audio/SimpleAudio/SimpleAudio.Game/SoundScript.cs
@@ -1,95 +1,92 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
-using System.Linq;
-using System.Threading.Tasks;
+
+using Stride.Audio;
using Stride.Core;
using Stride.Core.Mathematics;
-using Stride.Audio;
using Stride.Engine;
using Stride.Input;
using Stride.UI;
using Stride.UI.Controls;
-using Stride.UI.Panels;
-namespace SimpleAudio
+namespace SimpleAudio;
+
+///
+/// The main script in charge of the sound.
+///
+public class SoundScript : AsyncScript
{
///
- /// The main script in charge of the sound.
+ /// The page containing the UI elements
///
- public class SoundScript : AsyncScript
+ public UIPage Page {get; set; }
+
+ public Sound SoundMusic;
+ private SoundInstance music;
+ public Sound SoundEffect;
+ private SoundInstance effect;
+
+ [DataMember(Mask = LiveScriptingMask)] // keep the value when reloading the script (live-scripting)
+ private float originalPositionX;
+
+ [DataMember(Mask = LiveScriptingMask)] // keep the value when reloading the script (live-scripting)
+ private float fontColor;
+
+ public override async Task Execute()
{
- ///
- /// The page containing the UI elements
- ///
- public UIPage Page {get; set; }
+ var imgLeft = Page?.RootElement.FindVisualChildOfType("LeftWave");
+ var imgRight = Page?.RootElement.FindVisualChildOfType("RightWave");
- public Sound SoundMusic;
- private SoundInstance music;
- public Sound SoundEffect;
- private SoundInstance effect;
+ music = SoundMusic.CreateInstance();
+ effect = SoundEffect.CreateInstance();
- [DataMember(Mask = LiveScriptingMask)] // keep the value when reloading the script (live-scripting)
- private float originalPositionX;
+ if (!IsLiveReloading)
+ {
+ // start ambient music
+ music.IsLooping = true;
+ music.Play();
- [DataMember(Mask = LiveScriptingMask)] // keep the value when reloading the script (live-scripting)
- private float fontColor;
+ fontColor = 0;
+ originalPositionX = (imgRight != null) ? imgRight.GetCanvasRelativePosition().X : 0.65f;
+ }
- public override async Task Execute()
+ while (Game.IsRunning)
{
- var imgLeft = Page?.RootElement.FindVisualChildOfType("LeftWave");
- var imgRight = Page?.RootElement.FindVisualChildOfType("RightWave");
-
- music = SoundMusic.CreateInstance();
- effect = SoundEffect.CreateInstance();
-
- if (!IsLiveReloading)
+ if (Input.PointerEvents.Any(item => item.EventType == PointerEventType.Pressed)) // New click
{
- // start ambient music
- music.IsLooping = true;
- music.Play();
+ if (imgLeft != null && imgRight != null)
+ {
+ // reset wave position
+ imgLeft.SetCanvasRelativePosition(new Vector3(1 - originalPositionX, 0.5f, 0));
+ imgLeft.Opacity = 0;
+
+ imgRight.SetCanvasRelativePosition(new Vector3(originalPositionX, 0.5f, 0));
+ imgRight.Opacity = 0;
+ }
+
+ // reset transparency
+ fontColor = 1;
- fontColor = 0;
- originalPositionX = (imgRight != null) ? imgRight.GetCanvasRelativePosition().X : 0.65f;
+ // play the sound effect on each touch on the screen
+ effect.Stop();
+ effect.Play();
}
-
- while (Game.IsRunning)
+ else
{
- if (Input.PointerEvents.Any(item => item.EventType == PointerEventType.Pressed)) // New click
+ if (imgLeft != null && imgRight != null)
{
- if (imgLeft != null && imgRight != null)
- {
- // reset wave position
- imgLeft.SetCanvasRelativePosition(new Vector3(1 - originalPositionX, 0.5f, 0));
- imgLeft.Opacity = 0;
+ imgLeft.SetCanvasRelativePosition(imgLeft.GetCanvasRelativePosition() - new Vector3(0.0025f, 0, 0));
+ imgRight.SetCanvasRelativePosition(imgRight.GetCanvasRelativePosition() + new Vector3(0.0025f, 0, 0));
- imgRight.SetCanvasRelativePosition(new Vector3(originalPositionX, 0.5f, 0));
- imgRight.Opacity = 0;
- }
-
- // reset transparency
- fontColor = 1;
-
- // play the sound effect on each touch on the screen
- effect.Stop();
- effect.Play();
+ // changing font transparency
+ fontColor = 0.93f * fontColor;
+ imgLeft.Opacity = fontColor;
+ imgRight.Opacity = fontColor;
}
- else
- {
- if (imgLeft != null && imgRight != null)
- {
- imgLeft.SetCanvasRelativePosition(imgLeft.GetCanvasRelativePosition() - new Vector3(0.0025f, 0, 0));
- imgRight.SetCanvasRelativePosition(imgRight.GetCanvasRelativePosition() + new Vector3(0.0025f, 0, 0));
-
- // changing font transparency
- fontColor = 0.93f * fontColor;
- imgLeft.Opacity = fontColor;
- imgRight.Opacity = fontColor;
- }
- }
-
- // wait for next frame
- await Script.NextFrame();
}
+
+ // wait for next frame
+ await Script.NextFrame();
}
}
}
diff --git a/samples/Audio/SimpleAudio/SimpleAudio.Windows/SimpleAudio.Windows.csproj b/samples/Audio/SimpleAudio/SimpleAudio.Windows/SimpleAudio.Windows.csproj
index 2de591ec21..bee403944c 100644
--- a/samples/Audio/SimpleAudio/SimpleAudio.Windows/SimpleAudio.Windows.csproj
+++ b/samples/Audio/SimpleAudio/SimpleAudio.Windows/SimpleAudio.Windows.csproj
@@ -7,6 +7,8 @@
..\Bin\Windows\$(Configuration)\
false
STRIDE_PLATFORM_DESKTOP
+ enable
+ latest
$(MSBuildThisFileDirectory)..\SimpleAudio.sdpkg
diff --git a/samples/Games/JumpyJet/JumpyJet.Game/BackgroundScript.cs b/samples/Games/JumpyJet/JumpyJet.Game/BackgroundScript.cs
index 24aa1919a5..022d342e2b 100644
--- a/samples/Games/JumpyJet/JumpyJet.Game/BackgroundScript.cs
+++ b/samples/Games/JumpyJet/JumpyJet.Game/BackgroundScript.cs
@@ -4,29 +4,27 @@
using System.Threading.Tasks;
using Stride.Engine;
using Stride.Engine.Events;
-using Stride.Physics;
using Stride.Rendering.Compositing;
-namespace JumpyJet
+namespace JumpyJet;
+
+public class BackgroundScript : AsyncScript
{
- public class BackgroundScript : AsyncScript
+ private readonly EventReceiver gameOverListener = new(GameGlobals.GameOverEventKey);
+ private readonly EventReceiver gameResetListener = new(GameGlobals.GameResetEventKey);
+
+ public override async Task Execute()
{
- private EventReceiver gameOverListener = new EventReceiver(GameGlobals.GameOverEventKey);
- private EventReceiver gameResetListener = new EventReceiver(GameGlobals.GameResetEventKey);
+ // Find our JumpyJetRenderer to start/stop parallax background
+ var renderer = (JumpyJetRenderer)((SceneCameraRenderer)SceneSystem.GraphicsCompositor.Game).Child;
- public override async Task Execute()
+ while (Game.IsRunning)
{
- // Find our JumpyJetRenderer to start/stop parallax background
- var renderer = (JumpyJetRenderer)((SceneCameraRenderer)SceneSystem.GraphicsCompositor.Game).Child;
-
- while (Game.IsRunning)
- {
- await gameOverListener.ReceiveAsync();
- renderer.StopScrolling();
+ await gameOverListener.ReceiveAsync();
+ renderer.StopScrolling();
- await gameResetListener.ReceiveAsync();
- renderer.StartScrolling();
- }
+ await gameResetListener.ReceiveAsync();
+ renderer.StartScrolling();
}
}
}
diff --git a/samples/Games/JumpyJet/JumpyJet.Game/BackgroundSection.cs b/samples/Games/JumpyJet/JumpyJet.Game/BackgroundSection.cs
index 17098f582a..225b475c36 100644
--- a/samples/Games/JumpyJet/JumpyJet.Game/BackgroundSection.cs
+++ b/samples/Games/JumpyJet/JumpyJet.Game/BackgroundSection.cs
@@ -1,117 +1,117 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
+
using Stride.Core.Mathematics;
using Stride.Graphics;
-namespace JumpyJet
+namespace JumpyJet;
+
+///
+/// A section of the parallax background.
+///
+public class BackgroundSection
{
- ///
- /// A section of the parallax background.
- ///
- public class BackgroundSection
+ private readonly float depth;
+ private readonly Int2 screenResolution;
+ private readonly Vector2 screenCenter;
+
+ // Texture
+ private Texture texture;
+ private RectangleF textureRegion;
+
+ // First quad parameters
+ private readonly Vector2 firstQuadPos;
+ private Vector2 firstQuadOrigin;
+ private RectangleF firstQuadRegion;
+
+ // Second quad parameters
+ private Vector2 secondQuadPos;
+ private Vector2 secondQuadOrigin;
+ private RectangleF secondQuadRegion;
+
+ public bool IsUpdating { get; set; }
+ public bool IsRunning { get; protected set; }
+ public bool IsVisible { get; protected set; }
+ public float ScrollPos { get; protected set; }
+ public float ScrollWidth { get; protected set; }
+ public float ScrollSpeed { get; protected set; }
+
+ public BackgroundSection(Sprite backgroundSprite, Vector3 screenVirtualResolution, float scrollSpeed, float depth, Vector2 startPos = default)
{
- private readonly float depth;
- private readonly Int2 screenResolution;
- private readonly Vector2 screenCenter;
-
- // Texture
- private Texture texture;
- private RectangleF textureRegion;
-
- // First quad parameters
- private readonly Vector2 firstQuadPos;
- private Vector2 firstQuadOrigin;
- private RectangleF firstQuadRegion;
-
- // Second quad parameters
- private Vector2 secondQuadPos;
- private Vector2 secondQuadOrigin;
- private RectangleF secondQuadRegion;
-
- public bool IsUpdating { get; set; }
- public bool IsRunning { get; protected set; }
- public bool IsVisible { get; protected set; }
- public float ScrollPos { get; protected set; }
- public float ScrollWidth { get; protected set; }
- public float ScrollSpeed { get; protected set; }
-
- public BackgroundSection(Sprite backgroundSprite, Vector3 screenVirtualResolution, float scrollSpeed, float depth, Vector2 startPos = default(Vector2))
- {
- screenResolution = new Int2((int)screenVirtualResolution.X, (int)screenVirtualResolution.Y);
- screenCenter = new Vector2(screenVirtualResolution.X / 2, screenVirtualResolution.Y / 2);
+ screenResolution = new Int2((int)screenVirtualResolution.X, (int)screenVirtualResolution.Y);
+ screenCenter = new Vector2(screenVirtualResolution.X / 2, screenVirtualResolution.Y / 2);
- this.depth = depth;
- firstQuadPos = startPos;
- secondQuadPos = startPos;
+ this.depth = depth;
+ firstQuadPos = startPos;
+ secondQuadPos = startPos;
- ScrollSpeed = scrollSpeed;
- ScrollPos = 0;
+ ScrollSpeed = scrollSpeed;
+ ScrollPos = 0;
- CreateBackground(backgroundSprite.Texture, backgroundSprite.Region);
+ CreateBackground(backgroundSprite.Texture, backgroundSprite.Region);
- IsUpdating = true;
- }
+ IsUpdating = true;
+ }
- public void DrawSprite(float elapsedTime, SpriteBatch spriteBatch)
+ public void DrawSprite(float elapsedTime, SpriteBatch spriteBatch)
+ {
+ if (IsUpdating)
{
- if (IsUpdating)
- {
- // Update Scroll position
- if (ScrollPos >= textureRegion.Width)
- ScrollPos = 0;
+ // Update Scroll position
+ if (ScrollPos >= textureRegion.Width)
+ ScrollPos = 0;
- ScrollPos += elapsedTime * ScrollSpeed;
+ ScrollPos += elapsedTime * ScrollSpeed;
- UpdateSpriteQuads();
- }
+ UpdateSpriteQuads();
+ }
- // DrawParallax the first quad
- spriteBatch.Draw(texture, firstQuadPos + screenCenter, firstQuadRegion, Color.White, 0f, firstQuadOrigin, 1f, SpriteEffects.None, ImageOrientation.AsIs, depth);
+ // DrawParallax the first quad
+ spriteBatch.Draw(texture, firstQuadPos + screenCenter, firstQuadRegion, Color.White, 0f, firstQuadOrigin, 1f, SpriteEffects.None, ImageOrientation.AsIs, depth);
- if (secondQuadRegion.Width > 0)
- {
- // DrawParallax the second quad
- spriteBatch.Draw(texture, secondQuadPos + screenCenter, secondQuadRegion, Color.White, 0f, secondQuadOrigin, 1f, SpriteEffects.None, ImageOrientation.AsIs, depth);
- }
+ if (secondQuadRegion.Width > 0)
+ {
+ // DrawParallax the second quad
+ spriteBatch.Draw(texture, secondQuadPos + screenCenter, secondQuadRegion, Color.White, 0f, secondQuadOrigin, 1f, SpriteEffects.None, ImageOrientation.AsIs, depth);
}
+ }
- private void CreateBackground(Texture bgTexture, RectangleF texReg)
- {
- texture = bgTexture;
- textureRegion = texReg;
+ private void CreateBackground(Texture bgTexture, RectangleF texReg)
+ {
+ texture = bgTexture;
+ textureRegion = texReg;
- // Set offset to rectangle
- firstQuadRegion.X = textureRegion.X;
- firstQuadRegion.Y = textureRegion.Y;
+ // Set offset to rectangle
+ firstQuadRegion.X = textureRegion.X;
+ firstQuadRegion.Y = textureRegion.Y;
- firstQuadRegion.Width = (textureRegion.Width > screenResolution.X) ? screenResolution.X : textureRegion.Width;
- firstQuadRegion.Height = (textureRegion.Height > screenResolution.Y) ? screenResolution.Y : textureRegion.Height;
+ firstQuadRegion.Width = (textureRegion.Width > screenResolution.X) ? screenResolution.X : textureRegion.Width;
+ firstQuadRegion.Height = (textureRegion.Height > screenResolution.Y) ? screenResolution.Y : textureRegion.Height;
- // Centering the content
- firstQuadOrigin.X = 0.5f * firstQuadRegion.Width;
- firstQuadOrigin.Y = 0.5f * firstQuadRegion.Height;
+ // Centering the content
+ firstQuadOrigin.X = 0.5f * firstQuadRegion.Width;
+ firstQuadOrigin.Y = 0.5f * firstQuadRegion.Height;
- // Copy data from first quad to second one
- secondQuadRegion = firstQuadRegion;
- secondQuadOrigin = firstQuadOrigin;
- }
+ // Copy data from first quad to second one
+ secondQuadRegion = firstQuadRegion;
+ secondQuadOrigin = firstQuadOrigin;
+ }
- private void UpdateSpriteQuads()
- {
- // Update first Quad
- var firstQuadNewWidth = textureRegion.Width - ScrollPos;
- firstQuadRegion.Width = firstQuadNewWidth;
- // Update X position of the first Quad
- firstQuadRegion.X = ScrollPos;
-
- // Update second Quad
- // Calculate new X position and width of the second quad
- var secondQuadNewWidth = (ScrollPos + screenResolution.X) - textureRegion.Width;
- var secondQuadNewXPosition = (screenResolution.X - secondQuadNewWidth) / 2;
-
- secondQuadRegion.Width = secondQuadNewWidth;
- secondQuadPos.X = secondQuadNewXPosition;
- secondQuadOrigin.X = secondQuadNewWidth / 2f;
- }
+ private void UpdateSpriteQuads()
+ {
+ // Update first Quad
+ var firstQuadNewWidth = textureRegion.Width - ScrollPos;
+ firstQuadRegion.Width = firstQuadNewWidth;
+ // Update X position of the first Quad
+ firstQuadRegion.X = ScrollPos;
+
+ // Update second Quad
+ // Calculate new X position and width of the second quad
+ var secondQuadNewWidth = (ScrollPos + screenResolution.X) - textureRegion.Width;
+ var secondQuadNewXPosition = (screenResolution.X - secondQuadNewWidth) / 2;
+
+ secondQuadRegion.Width = secondQuadNewWidth;
+ secondQuadPos.X = secondQuadNewXPosition;
+ secondQuadOrigin.X = secondQuadNewWidth / 2f;
}
}
diff --git a/samples/Games/JumpyJet/JumpyJet.Game/CharacterScript.cs b/samples/Games/JumpyJet/JumpyJet.Game/CharacterScript.cs
index 9a93043225..3c6e72f985 100644
--- a/samples/Games/JumpyJet/JumpyJet.Game/CharacterScript.cs
+++ b/samples/Games/JumpyJet/JumpyJet.Game/CharacterScript.cs
@@ -1,5 +1,6 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
+
using System;
using System.Linq;
using System.Threading.Tasks;
@@ -10,163 +11,160 @@
using Stride.Physics;
using Stride.Rendering.Sprites;
-namespace JumpyJet
+namespace JumpyJet;
+
+///
+/// CharacterScript is controlled by a user.
+/// The control is as follow, tapping a screen/clicking a mouse will make the agent jump up.
+///
+public class CharacterScript : AsyncScript
{
- ///
- /// CharacterScript is controlled by a user.
- /// The control is as follow, tapping a screen/clicking a mouse will make the agent jump up.
- ///
- public class CharacterScript : AsyncScript
- {
- private EventReceiver gameResetListener = new EventReceiver(GameGlobals.GameResetEventKey);
- private EventReceiver gameStartedListener = new EventReceiver(GameGlobals.GameStartedEventKey);
+ private readonly EventReceiver gameResetListener = new(GameGlobals.GameResetEventKey);
+ private readonly EventReceiver gameStartedListener = new(GameGlobals.GameStartedEventKey);
- private static readonly Vector3 Gravity = new Vector3(0, -17, 0);
- private static readonly Vector3 StartPos = new Vector3(-1, 0, 0);
- private static readonly Vector3 StartVelocity = new Vector3(0, 7, 0);
+ private static readonly Vector3 Gravity = new(0, -17, 0);
+ private static readonly Vector3 StartPos = new(-1, 0, 0);
+ private static readonly Vector3 StartVelocity = new(0, 7, 0);
- private const float TopLimit = (568 - 200) * GameGlobals.GamePixelToUnitScale;
- private const float NormalVelocityY = 6.5f;
- private const float VelocityAboveTopLimit = 2f;
- private const int FlyingSpriteFrameIndex = 1;
- private const int FallingSpriteFrameIndex = 0;
+ private const float TopLimit = (568 - 200) * GameGlobals.GamePixelToUnitScale;
+ private const float NormalVelocityY = 6.5f;
+ private const float VelocityAboveTopLimit = 2f;
+ private const int FlyingSpriteFrameIndex = 1;
+ private const int FallingSpriteFrameIndex = 0;
- private Vector3 position;
- private Vector3 rotation;
+ private Vector3 position;
+ private Vector3 rotation;
- private bool isRunning;
- private Vector3 velocity;
+ private bool isRunning;
+ private Vector3 velocity;
- public void Start()
- {
- position = StartPos;
- velocity = StartVelocity;
+ public void Start()
+ {
+ position = StartPos;
+ velocity = StartVelocity;
- Reset();
+ Reset();
- Script.AddTask(CountPassedPipes);
- Script.AddTask(DetectGameOver);
- }
+ Script.AddTask(CountPassedPipes);
+ Script.AddTask(DetectGameOver);
+ }
- ///
- /// Reset CharacterScript parameters: position, velocity and set state.
- ///
- public void Reset()
- {
- position.Y = 0;
- rotation.Z = 0f;
- UpdateTransformation();
+ ///
+ /// Reset CharacterScript parameters: position, velocity and set state.
+ ///
+ public void Reset()
+ {
+ position.Y = 0;
+ rotation.Z = 0f;
+ UpdateTransformation();
- velocity = StartVelocity;
- isRunning = false;
+ velocity = StartVelocity;
+ isRunning = false;
- var provider = Entity.Get().SpriteProvider as SpriteFromSheet;
- if (provider != null)
- provider.CurrentFrame = FallingSpriteFrameIndex;
- }
+ if (Entity.Get().SpriteProvider is SpriteFromSheet provider)
+ provider.CurrentFrame = FallingSpriteFrameIndex;
+ }
- ///
- /// Update the agent according to its states: {Idle, Alive, Die}
- ///
- public async Task CountPassedPipes()
- {
- var physicsComponent = Entity.Components.Get();
+ ///
+ /// Update the agent according to its states: {Idle, Alive, Die}
+ ///
+ public async Task CountPassedPipes()
+ {
+ var physicsComponent = Entity.Components.Get();
- while (Game.IsRunning)
- {
- var collision = await physicsComponent.NewCollision();
+ while (Game.IsRunning)
+ {
+ var collision = await physicsComponent.NewCollision();
- if (collision.ColliderA.CollisionGroup == CollisionFilterGroups.CustomFilter1 || // use collision group 1 to distinguish pipe passed trigger from other colliders.
- collision.ColliderB.CollisionGroup == CollisionFilterGroups.CustomFilter1)
- GameGlobals.PipePassedEventKey.Broadcast();
- }
+ if (collision.ColliderA.CollisionGroup == CollisionFilterGroups.CustomFilter1 || // use collision group 1 to distinguish pipe passed trigger from other colliders.
+ collision.ColliderB.CollisionGroup == CollisionFilterGroups.CustomFilter1)
+ GameGlobals.PipePassedEventKey.Broadcast();
}
+ }
- ///
- /// Update the agent according to its states: {Idle, Alive, Die}
- ///
- public async Task DetectGameOver()
+ ///
+ /// Update the agent according to its states: {Idle, Alive, Die}
+ ///
+ public async Task DetectGameOver()
+ {
+ var physicsComponent = Entity.Components.Get();
+
+ while (Game.IsRunning)
{
- var physicsComponent = Entity.Components.Get();
+ await Script.NextFrame();
- while (Game.IsRunning)
+ // detect collisions with the pipes
+ var collision = await physicsComponent.NewCollision();
+ if (collision.ColliderA.CollisionGroup == CollisionFilterGroups.DefaultFilter &&
+ collision.ColliderB.CollisionGroup == CollisionFilterGroups.DefaultFilter)
{
- await Script.NextFrame();
-
- // detect collisions with the pipes
- var collision = await physicsComponent.NewCollision();
- if (collision.ColliderA.CollisionGroup == CollisionFilterGroups.DefaultFilter &&
- collision.ColliderB.CollisionGroup == CollisionFilterGroups.DefaultFilter)
- {
- isRunning = false;
- GameGlobals.GameOverEventKey.Broadcast();
- }
+ isRunning = false;
+ GameGlobals.GameOverEventKey.Broadcast();
}
}
+ }
- ///
- /// Update the agent according to its states: {Idle, Alive, Die}
- ///
- public override async Task Execute()
- {
- Start();
+ ///
+ /// Update the agent according to its states: {Idle, Alive, Die}
+ ///
+ public override async Task Execute()
+ {
+ Start();
- while (Game.IsRunning)
- {
- await Script.NextFrame();
+ while (Game.IsRunning)
+ {
+ await Script.NextFrame();
- if (gameResetListener.TryReceive())
- Reset();
+ if (gameResetListener.TryReceive())
+ Reset();
- if (gameStartedListener.TryReceive())
- isRunning = true;
+ if (gameStartedListener.TryReceive())
+ isRunning = true;
- if (!isRunning)
- continue;
+ if (!isRunning)
+ continue;
- var elapsedTime = (float)Game.UpdateTime.Elapsed.TotalSeconds;
+ var elapsedTime = (float)Game.UpdateTime.Elapsed.TotalSeconds;
- // apply impulse on the touch/space
- if (Input.IsKeyPressed(Keys.Space) || UserTappedScreen())
- velocity.Y = position.Y > TopLimit ? VelocityAboveTopLimit : NormalVelocityY;
+ // apply impulse on the touch/space
+ if (Input.IsKeyPressed(Keys.Space) || UserTappedScreen())
+ velocity.Y = position.Y > TopLimit ? VelocityAboveTopLimit : NormalVelocityY;
- // update position/velocity
- velocity += Gravity * elapsedTime;
- position += velocity * elapsedTime;
+ // update position/velocity
+ velocity += Gravity * elapsedTime;
+ position += velocity * elapsedTime;
- // update animation and rotation value
- UpdateAgentAnimation();
+ // update animation and rotation value
+ UpdateAgentAnimation();
- // update the position/rotation
- UpdateTransformation();
- }
+ // update the position/rotation
+ UpdateTransformation();
}
+ }
- private void UpdateTransformation()
- {
- Entity.Transform.Position = position;
- Entity.Transform.RotationEulerXYZ = rotation;
- }
+ private void UpdateTransformation()
+ {
+ Entity.Transform.Position = position;
+ Entity.Transform.RotationEulerXYZ = rotation;
+ }
- private bool UserTappedScreen()
- {
- return Input.PointerEvents.Any(pointerEvent => pointerEvent.EventType == PointerEventType.Pressed);
- }
+ private bool UserTappedScreen()
+ {
+ return Input.PointerEvents.Any(pointerEvent => pointerEvent.EventType == PointerEventType.Pressed);
+ }
- private void UpdateAgentAnimation()
- {
- var isFalling = velocity.Y < 0;
- var rotationSign = isFalling ? -1 : 1;
-
- // Set falling sprite frame
- var provider = Entity.Get().SpriteProvider as SpriteFromSheet;
- if (provider != null)
- provider.CurrentFrame = isFalling ? FallingSpriteFrameIndex : FlyingSpriteFrameIndex;
-
- // Rotate a sprite
- rotation.Z += rotationSign * MathUtil.Pi * 0.01f;
- if (rotationSign * rotation.Z > Math.PI / 10f)
- rotation.Z = rotationSign * MathUtil.Pi / 10f;
- }
+ private void UpdateAgentAnimation()
+ {
+ var isFalling = velocity.Y < 0;
+ var rotationSign = isFalling ? -1 : 1;
+
+ // Set falling sprite frame
+ if (Entity.Get().SpriteProvider is SpriteFromSheet provider)
+ provider.CurrentFrame = isFalling ? FallingSpriteFrameIndex : FlyingSpriteFrameIndex;
+
+ // Rotate a sprite
+ rotation.Z += rotationSign * MathUtil.Pi * 0.01f;
+ if (rotationSign * rotation.Z > Math.PI / 10f)
+ rotation.Z = rotationSign * MathUtil.Pi / 10f;
}
}
diff --git a/samples/Games/JumpyJet/JumpyJet.Game/GameGlobals.cs b/samples/Games/JumpyJet/JumpyJet.Game/GameGlobals.cs
index 1982544a03..0db4fc344b 100644
--- a/samples/Games/JumpyJet/JumpyJet.Game/GameGlobals.cs
+++ b/samples/Games/JumpyJet/JumpyJet.Game/GameGlobals.cs
@@ -3,16 +3,15 @@
using Stride.Engine.Events;
-namespace JumpyJet
+namespace JumpyJet;
+
+static class GameGlobals
{
- static class GameGlobals
- {
- public static EventKey GameOverEventKey = new EventKey("Global", "Game Over");
- public static EventKey GameStartedEventKey = new EventKey("Global", "Game Started");
- public static EventKey GameResetEventKey = new EventKey("Global", "Game Reset");
- public static EventKey PipePassedEventKey = new EventKey("Global", "Pipe Passed");
+ public static EventKey GameOverEventKey = new("Global", "Game Over");
+ public static EventKey GameStartedEventKey = new("Global", "Game Started");
+ public static EventKey GameResetEventKey = new("Global", "Game Reset");
+ public static EventKey PipePassedEventKey = new("Global", "Pipe Passed");
- public const float GameSpeed = 2.90f;
- public const float GamePixelToUnitScale = 0.01f;
- }
+ public const float GameSpeed = 2.90f;
+ public const float GamePixelToUnitScale = 0.01f;
}
diff --git a/samples/Games/JumpyJet/JumpyJet.Game/JumpyJetRenderer.cs b/samples/Games/JumpyJet/JumpyJet.Game/JumpyJetRenderer.cs
index 33f5a49b80..4f9cbb80ea 100644
--- a/samples/Games/JumpyJet/JumpyJet.Game/JumpyJetRenderer.cs
+++ b/samples/Games/JumpyJet/JumpyJet.Game/JumpyJetRenderer.cs
@@ -7,113 +7,112 @@
using Stride.Rendering;
using Stride.Rendering.Compositing;
-namespace JumpyJet
+namespace JumpyJet;
+
+public class JumpyJetRenderer : SceneRendererBase
{
- public class JumpyJetRenderer : SceneRendererBase
- {
- // Entities' depth
- private const int Pal0Depth = 0;
- private const int Pal1Depth = 1;
- private const int Pal2Depth = 2;
- private const int Pal3Depth = 3;
+ // Entities' depth
+ private const int Pal0Depth = 0;
+ private const int Pal1Depth = 1;
+ private const int Pal2Depth = 2;
+ private const int Pal3Depth = 3;
- private SpriteBatch spriteBatch;
+ private SpriteBatch spriteBatch;
- private readonly List backgroundParallax = new List();
+ private readonly List backgroundParallax = [];
- public SpriteSheet ParallaxBackgrounds;
+ public SpriteSheet ParallaxBackgrounds;
- ///
- /// The main render stage for opaque geometry.
- ///
- public RenderStage OpaqueRenderStage { get; set; }
+ ///
+ /// The main render stage for opaque geometry.
+ ///
+ public RenderStage OpaqueRenderStage { get; set; }
- ///
- /// The transparent render stage for transparent geometry.
- ///
- public RenderStage TransparentRenderStage { get; set; }
+ ///
+ /// The transparent render stage for transparent geometry.
+ ///
+ public RenderStage TransparentRenderStage { get; set; }
- public void StartScrolling()
- {
- EnableAllParallaxesUpdate(true);
- }
+ public void StartScrolling()
+ {
+ EnableAllParallaxesUpdate(true);
+ }
- public void StopScrolling()
- {
- EnableAllParallaxesUpdate(false);
- }
+ public void StopScrolling()
+ {
+ EnableAllParallaxesUpdate(false);
+ }
- private void EnableAllParallaxesUpdate(bool isEnable)
+ private void EnableAllParallaxesUpdate(bool isEnable)
+ {
+ foreach (var pallarax in backgroundParallax)
{
- foreach (var pallarax in backgroundParallax)
- {
- pallarax.IsUpdating = isEnable;
- }
+ pallarax.IsUpdating = isEnable;
}
+ }
- protected override void InitializeCore()
- {
- base.InitializeCore();
+ protected override void InitializeCore()
+ {
+ base.InitializeCore();
- var virtualResolution = new Vector3(GraphicsDevice.Presenter.BackBuffer.Width, GraphicsDevice.Presenter.BackBuffer.Height, 20f);
+ var virtualResolution = new Vector3(GraphicsDevice.Presenter.BackBuffer.Width, GraphicsDevice.Presenter.BackBuffer.Height, 20f);
- // Create Parallax Background
- backgroundParallax.Add(new BackgroundSection(ParallaxBackgrounds.Sprites[0], virtualResolution, 100 * GameGlobals.GameSpeed / 4f, Pal0Depth));
- backgroundParallax.Add(new BackgroundSection(ParallaxBackgrounds.Sprites[1], virtualResolution, 100 * GameGlobals.GameSpeed / 3f, Pal1Depth));
- backgroundParallax.Add(new BackgroundSection(ParallaxBackgrounds.Sprites[2], virtualResolution, 100 * GameGlobals.GameSpeed / 1.5f, Pal2Depth));
+ // Create Parallax Background
+ backgroundParallax.Add(new BackgroundSection(ParallaxBackgrounds.Sprites[0], virtualResolution, 100 * GameGlobals.GameSpeed / 4f, Pal0Depth));
+ backgroundParallax.Add(new BackgroundSection(ParallaxBackgrounds.Sprites[1], virtualResolution, 100 * GameGlobals.GameSpeed / 3f, Pal1Depth));
+ backgroundParallax.Add(new BackgroundSection(ParallaxBackgrounds.Sprites[2], virtualResolution, 100 * GameGlobals.GameSpeed / 1.5f, Pal2Depth));
- // For pal3Sprite: Ground, move it downward so that its bottom edge is at the bottom screen.
- var screenHeight = virtualResolution.Y;
- var pal3Height = ParallaxBackgrounds.Sprites[3].SizeInPixels.Y;
- backgroundParallax.Add(new BackgroundSection(ParallaxBackgrounds.Sprites[3], virtualResolution, 100 * GameGlobals.GameSpeed, Pal3Depth, Vector2.UnitY * (screenHeight - pal3Height) / 2));
+ // For pal3Sprite: Ground, move it downward so that its bottom edge is at the bottom screen.
+ var screenHeight = virtualResolution.Y;
+ var pal3Height = ParallaxBackgrounds.Sprites[3].SizeInPixels.Y;
+ backgroundParallax.Add(new BackgroundSection(ParallaxBackgrounds.Sprites[3], virtualResolution, 100 * GameGlobals.GameSpeed, Pal3Depth, Vector2.UnitY * (screenHeight - pal3Height) / 2));
- // allocate the sprite batch in charge of drawing the backgrounds.
- spriteBatch = new SpriteBatch(GraphicsDevice) { VirtualResolution = virtualResolution };
- }
+ // allocate the sprite batch in charge of drawing the backgrounds.
+ spriteBatch = new SpriteBatch(GraphicsDevice) { VirtualResolution = virtualResolution };
+ }
- protected override void CollectCore(RenderContext context)
+ protected override void CollectCore(RenderContext context)
+ {
+ // Setup pixel formats for RenderStage
+ using (context.SaveRenderOutputAndRestore())
{
- // Setup pixel formats for RenderStage
- using (context.SaveRenderOutputAndRestore())
+ // Fill RenderStage formats and register render stages to main view
+ if (OpaqueRenderStage != null)
+ {
+ context.RenderView.RenderStages.Add(OpaqueRenderStage);
+ OpaqueRenderStage.Output = context.RenderOutput;
+ }
+ if (TransparentRenderStage != null)
{
- // Fill RenderStage formats and register render stages to main view
- if (OpaqueRenderStage != null)
- {
- context.RenderView.RenderStages.Add(OpaqueRenderStage);
- OpaqueRenderStage.Output = context.RenderOutput;
- }
- if (TransparentRenderStage != null)
- {
- context.RenderView.RenderStages.Add(TransparentRenderStage);
- TransparentRenderStage.Output = context.RenderOutput;
- }
+ context.RenderView.RenderStages.Add(TransparentRenderStage);
+ TransparentRenderStage.Output = context.RenderOutput;
}
}
+ }
- protected override void DrawCore(RenderContext context, RenderDrawContext drawContext)
- {
- var renderSystem = context.RenderSystem;
+ protected override void DrawCore(RenderContext context, RenderDrawContext drawContext)
+ {
+ var renderSystem = context.RenderSystem;
- // Clear
- drawContext.CommandList.Clear(drawContext.CommandList.DepthStencilBuffer, DepthStencilClearOptions.DepthBuffer);
+ // Clear
+ drawContext.CommandList.Clear(drawContext.CommandList.DepthStencilBuffer, DepthStencilClearOptions.DepthBuffer);
- // Draw parallax background
- spriteBatch.Begin(drawContext.GraphicsContext);
+ // Draw parallax background
+ spriteBatch.Begin(drawContext.GraphicsContext);
- float elapsedTime = (float)context.Time.Elapsed.TotalSeconds;
- foreach (var pallaraxBackground in backgroundParallax)
- pallaraxBackground.DrawSprite(elapsedTime, spriteBatch);
+ float elapsedTime = (float)context.Time.Elapsed.TotalSeconds;
+ foreach (var pallaraxBackground in backgroundParallax)
+ pallaraxBackground.DrawSprite(elapsedTime, spriteBatch);
- spriteBatch.End();
+ spriteBatch.End();
- // Draw [main view | main stage]
- if (OpaqueRenderStage != null)
- renderSystem.Draw(drawContext, context.RenderView, OpaqueRenderStage);
+ // Draw [main view | main stage]
+ if (OpaqueRenderStage != null)
+ renderSystem.Draw(drawContext, context.RenderView, OpaqueRenderStage);
- // Draw [main view | transparent stage]
- if (TransparentRenderStage != null)
- renderSystem.Draw(drawContext, context.RenderView, TransparentRenderStage);
- }
+ // Draw [main view | transparent stage]
+ if (TransparentRenderStage != null)
+ renderSystem.Draw(drawContext, context.RenderView, TransparentRenderStage);
}
}
diff --git a/samples/Games/JumpyJet/JumpyJet.Game/PipesScript.cs b/samples/Games/JumpyJet/JumpyJet.Game/PipesScript.cs
index 2371ba1734..0fd9b98566 100644
--- a/samples/Games/JumpyJet/JumpyJet.Game/PipesScript.cs
+++ b/samples/Games/JumpyJet/JumpyJet.Game/PipesScript.cs
@@ -1,5 +1,6 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
+
using System;
using System.Collections.Generic;
using Stride.Core.Mathematics;
@@ -7,104 +8,103 @@
using Stride.Engine;
using Stride.Engine.Events;
-namespace JumpyJet
-{
- ///
- /// The script in charge of creating and updating the pipes.
- ///
- public class PipesScript : SyncScript
- {
- private const float GapBetweenPipe = 4f;
- private const float StartPipePosition = 4f;
+namespace JumpyJet;
- private EventReceiver gameOverListener = new EventReceiver(GameGlobals.GameOverEventKey);
- private EventReceiver gameResetListener = new EventReceiver(GameGlobals.GameResetEventKey);
- private EventReceiver gameStartedListener = new EventReceiver(GameGlobals.GameStartedEventKey);
+///
+/// The script in charge of creating and updating the pipes.
+///
+public class PipesScript : SyncScript
+{
+ private const float GapBetweenPipe = 4f;
+ private const float StartPipePosition = 4f;
- private readonly List pipeSets = new List();
+ private readonly EventReceiver gameOverListener = new(GameGlobals.GameOverEventKey);
+ private readonly EventReceiver gameResetListener = new(GameGlobals.GameResetEventKey);
+ private readonly EventReceiver gameStartedListener = new(GameGlobals.GameStartedEventKey);
- private bool isScrolling;
+ private readonly List pipeSets = [];
- private readonly Random random = new Random();
+ private bool isScrolling;
- private float sceneWidth;
+ private readonly Random random = new();
- // The width of pipe prefab
- private float pipeOvervaluedWidth = 1f;
+ private float sceneWidth;
- public UrlReference PipePrefabUrl { get; set; }
+ // The width of pipe prefab
+ private readonly float pipeOvervaluedWidth = 1f;
- public override void Start()
- {
- var pipeSetPrefab = Content.Load(PipePrefabUrl);
+ public UrlReference PipePrefabUrl { get; set; }
- // Create PipeSets
- sceneWidth = GameGlobals.GamePixelToUnitScale * GraphicsDevice.Presenter.BackBuffer.Width;
- var numberOfPipes = (int)Math.Ceiling((sceneWidth + 2 * pipeOvervaluedWidth) / GapBetweenPipe);
- for (int i = 0; i < numberOfPipes; i++)
- {
- var pipeSet = pipeSetPrefab.Instantiate()[0];
- pipeSets.Add(pipeSet);
- Entity.AddChild(pipeSet);
- }
+ public override void Start()
+ {
+ var pipeSetPrefab = Content.Load(PipePrefabUrl);
- // Reset the position of the PipeSets
- Reset();
+ // Create PipeSets
+ sceneWidth = GameGlobals.GamePixelToUnitScale * GraphicsDevice.Presenter.BackBuffer.Width;
+ var numberOfPipes = (int)Math.Ceiling((sceneWidth + 2 * pipeOvervaluedWidth) / GapBetweenPipe);
+ for (int i = 0; i < numberOfPipes; i++)
+ {
+ var pipeSet = pipeSetPrefab.Instantiate()[0];
+ pipeSets.Add(pipeSet);
+ Entity.AddChild(pipeSet);
}
- public override void Update()
- {
- if (gameOverListener.TryReceive())
- isScrolling = false;
+ // Reset the position of the PipeSets
+ Reset();
+ }
- if (gameStartedListener.TryReceive())
- isScrolling = true;
+ public override void Update()
+ {
+ if (gameOverListener.TryReceive())
+ isScrolling = false;
- if (gameResetListener.TryReceive())
- Reset();
+ if (gameStartedListener.TryReceive())
+ isScrolling = true;
- if (!isScrolling)
- return;
+ if (gameResetListener.TryReceive())
+ Reset();
- var elapsedTime = (float)Game.UpdateTime.Elapsed.TotalSeconds;
+ if (!isScrolling)
+ return;
- for (int i = 0; i < pipeSets.Count; i++)
- {
- var pipeSetTransform = pipeSets[i].Transform;
+ var elapsedTime = (float)Game.UpdateTime.Elapsed.TotalSeconds;
- // update the position of the pipe
- pipeSetTransform.Position -= new Vector3(elapsedTime * GameGlobals.GameSpeed, 0, 0);
+ for (int i = 0; i < pipeSets.Count; i++)
+ {
+ var pipeSetTransform = pipeSets[i].Transform;
+
+ // update the position of the pipe
+ pipeSetTransform.Position -= new Vector3(elapsedTime * GameGlobals.GameSpeed, 0, 0);
- // move the pipe to the end of screen if not visible anymore
- if (pipeSetTransform.Position.X + pipeOvervaluedWidth / 2 < -sceneWidth / 2)
- {
+ // move the pipe to the end of screen if not visible anymore
+ if (pipeSetTransform.Position.X + pipeOvervaluedWidth / 2 < -sceneWidth / 2)
+ {
- // When a pipe is determined to be reset,
- // get its next position by adding an offset to the position
- // of a pipe which index is before itself.
- var prevPipeSetIndex = (i - 1 + pipeSets.Count) % pipeSets.Count;
+ // When a pipe is determined to be reset,
+ // get its next position by adding an offset to the position
+ // of a pipe which index is before itself.
+ var prevPipeSetIndex = (i - 1 + pipeSets.Count) % pipeSets.Count;
- var nextPosX = pipeSets[prevPipeSetIndex].Transform.Position.X + GapBetweenPipe;
- pipeSetTransform.Position = new Vector3(nextPosX, GetPipeRandomYPosition(), 0);
- }
+ var nextPosX = pipeSets[prevPipeSetIndex].Transform.Position.X + GapBetweenPipe;
+ pipeSetTransform.Position = new Vector3(nextPosX, GetPipeRandomYPosition(), 0);
}
}
+ }
- private float GetPipeRandomYPosition()
- {
- return GameGlobals.GamePixelToUnitScale * random.Next(50, 225);
- }
+ private float GetPipeRandomYPosition()
+ {
+ return GameGlobals.GamePixelToUnitScale * random.Next(50, 225);
+ }
- private void Reset()
- {
- for (var i = 0; i < pipeSets.Count; ++i)
- pipeSets[i].Transform.Position = new Vector3(StartPipePosition + i * GapBetweenPipe, GetPipeRandomYPosition(), 0);
- }
+ private void Reset()
+ {
+ for (var i = 0; i < pipeSets.Count; ++i)
+ pipeSets[i].Transform.Position = new Vector3(StartPipePosition + i * GapBetweenPipe, GetPipeRandomYPosition(), 0);
+ }
- public override void Cancel()
- {
- // remove all the children pipes.
- Entity.Transform.Children.Clear();
- }
+ public override void Cancel()
+ {
+ // remove all the children pipes.
+ Entity.Transform.Children.Clear();
}
}
diff --git a/samples/Games/JumpyJet/JumpyJet.Game/UIScript.cs b/samples/Games/JumpyJet/JumpyJet.Game/UIScript.cs
index 8a14ba777f..cdd8b962fb 100644
--- a/samples/Games/JumpyJet/JumpyJet.Game/UIScript.cs
+++ b/samples/Games/JumpyJet/JumpyJet.Game/UIScript.cs
@@ -1,5 +1,6 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
+
using Stride.Core;
using Stride.Core.Mathematics;
using Stride.Engine;
@@ -10,213 +11,212 @@
using Stride.UI.Controls;
using Stride.UI.Panels;
-namespace JumpyJet
+namespace JumpyJet;
+
+///
+/// UIScript manages UIElements using in the game.
+/// At one time UI.RootElement is one of each root which corresponding to each state of the game.
+///
+/// It provides a ButtonClickedEvent Action that could be subscribed by its user.
+/// This action provides the name of Button element that is clicked,
+/// which is one of {startButton, MenuBotton and RestartButton}
+///
+public class UIScript : SyncScript
{
- ///
- /// UIScript manages UIElements using in the game.
- /// At one time UI.RootElement is one of each root which corresponding to each state of the game.
- ///
- /// It provides a ButtonClickedEvent Action that could be subscribed by its user.
- /// This action provides the name of Button element that is clicked,
- /// which is one of {startButton, MenuBotton and RestartButton}
- ///
- public class UIScript : SyncScript
- {
- private EventReceiver gameOverListener = new EventReceiver(GameGlobals.GameOverEventKey);
- private EventReceiver pipePassedListener = new EventReceiver(GameGlobals.PipePassedEventKey);
+ private readonly EventReceiver gameOverListener = new(GameGlobals.GameOverEventKey);
+ private readonly EventReceiver pipePassedListener = new(GameGlobals.PipePassedEventKey);
- public SpriteFont Font;
- public SpriteSheet UIImages;
+ public SpriteFont Font;
+ public SpriteSheet UIImages;
- private ModalElement mainMenuRoot;
- private Canvas gameRoot;
- private ModalElement gameOverRoot;
+ private ModalElement mainMenuRoot;
+ private Canvas gameRoot;
+ private ModalElement gameOverRoot;
- private TextBlock scoreTextBlock;
- private ISpriteProvider buttonImage;
+ private TextBlock scoreTextBlock;
+ private ISpriteProvider buttonImage;
- private int currentScore = 0;
+ private int currentScore;
- ///
- /// Load resource and construct ui components
- ///
- public override void Start()
- {
- // Load resources shared by different UI screens
- buttonImage = SpriteFromSheet.Create(UIImages, "button");
-
- // Load and create specific UI screens.
- CreateMainMenuUI();
- CreateGameUI();
- CreateGameOverUI();
-
- // set the default screen to main screen
- StartMainMenuMode();
- }
+ ///
+ /// Load resource and construct ui components
+ ///
+ public override void Start()
+ {
+ // Load resources shared by different UI screens
+ buttonImage = SpriteFromSheet.Create(UIImages, "button");
- public override void Update()
- {
- // Increase the score if a new pipe has been passed
- if (pipePassedListener.TryReceive())
- ++currentScore;
+ // Load and create specific UI screens.
+ CreateMainMenuUI();
+ CreateGameUI();
+ CreateGameOverUI();
- // move to game over UI
- if (gameOverListener.TryReceive())
- {
- currentScore = 0;
- Entity.Get().Page = new UIPage { RootElement = gameOverRoot };
- }
+ // set the default screen to main screen
+ StartMainMenuMode();
+ }
- // Update the current score
- scoreTextBlock.Text = "Score : {0,2}".ToFormat(currentScore);
- }
+ public override void Update()
+ {
+ // Increase the score if a new pipe has been passed
+ if (pipePassedListener.TryReceive())
+ ++currentScore;
- ///
- /// Change UI mode to main menu
- ///
- public void StartMainMenuMode()
- {
- Entity.Get().Page = new UIPage { RootElement = mainMenuRoot };
- }
- ///
- /// Change UI mode to game mode
- ///
- public void StartGameMode()
+ // move to game over UI
+ if (gameOverListener.TryReceive())
{
- Entity.Get().Page = new UIPage { RootElement = gameRoot };
+ currentScore = 0;
+ Entity.Get().Page = new UIPage { RootElement = gameOverRoot };
}
- private void CreateMainMenuUI()
- {
- var strideLogo = new ImageElement { Source = SpriteFromSheet.Create(UIImages, "sd_logo") };
-
- strideLogo.SetCanvasPinOrigin(new Vector3(0.5f, 0.5f, 1f));
- strideLogo.SetCanvasRelativeSize(new Vector3(0.75f, 0.5f, 1f));
- strideLogo.SetCanvasRelativePosition(new Vector3(0.5f, 0.3f, 1f));
+ // Update the current score
+ scoreTextBlock.Text = "Score : {0,2}".ToFormat(currentScore);
+ }
- var startButton = new Button
- {
- Content = new TextBlock
- {
- Font = Font,
- Text = "Touch to Start",
- TextColor = Color.Black,
- HorizontalAlignment = HorizontalAlignment.Center,
- VerticalAlignment = VerticalAlignment.Center
- },
- NotPressedImage = buttonImage,
- PressedImage = buttonImage,
- MouseOverImage = buttonImage,
- Padding = new Thickness(77, 30, 25, 30),
- MinimumWidth = 250f,
- };
-
- startButton.SetCanvasPinOrigin(new Vector3(0.5f, 0.5f, 1f));
- startButton.SetCanvasRelativePosition(new Vector3(0.5f, 0.7f, 0f));
- startButton.Click += (sender, args) =>
- {
- GameGlobals.GameStartedEventKey.Broadcast();
- StartGameMode();
- };
+ ///
+ /// Change UI mode to main menu
+ ///
+ public void StartMainMenuMode()
+ {
+ Entity.Get().Page = new UIPage { RootElement = mainMenuRoot };
+ }
+ ///
+ /// Change UI mode to game mode
+ ///
+ public void StartGameMode()
+ {
+ Entity.Get().Page = new UIPage { RootElement = gameRoot };
+ }
- var mainMenuCanvas = new Canvas();
- mainMenuCanvas.Children.Add(strideLogo);
- mainMenuCanvas.Children.Add(startButton);
+ private void CreateMainMenuUI()
+ {
+ var strideLogo = new ImageElement { Source = SpriteFromSheet.Create(UIImages, "sd_logo") };
- mainMenuRoot = new ModalElement
- {
- HorizontalAlignment = HorizontalAlignment.Stretch,
- VerticalAlignment = VerticalAlignment.Stretch,
- Content = mainMenuCanvas
- };
- }
+ strideLogo.SetCanvasPinOrigin(new Vector3(0.5f, 0.5f, 1f));
+ strideLogo.SetCanvasRelativeSize(new Vector3(0.75f, 0.5f, 1f));
+ strideLogo.SetCanvasRelativePosition(new Vector3(0.5f, 0.3f, 1f));
- private void CreateGameUI()
+ var startButton = new Button
{
- scoreTextBlock = new TextBlock
+ Content = new TextBlock
{
Font = Font,
+ Text = "Touch to Start",
TextColor = Color.Black,
+ HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Center
- };
- scoreTextBlock.SetCanvasPinOrigin(new Vector3(0.5f, 0.5f, 1f));
- scoreTextBlock.SetCanvasRelativePosition(new Vector3(0.2f, 0.05f, 0f));
+ },
+ NotPressedImage = buttonImage,
+ PressedImage = buttonImage,
+ MouseOverImage = buttonImage,
+ Padding = new Thickness(77, 30, 25, 30),
+ MinimumWidth = 250f,
+ };
+
+ startButton.SetCanvasPinOrigin(new Vector3(0.5f, 0.5f, 1f));
+ startButton.SetCanvasRelativePosition(new Vector3(0.5f, 0.7f, 0f));
+ startButton.Click += (sender, args) =>
+ {
+ GameGlobals.GameStartedEventKey.Broadcast();
+ StartGameMode();
+ };
- var scoreBoard = new ContentDecorator
- {
- BackgroundImage = SpriteFromSheet.Create(UIImages, "score_bg"),
- Content = scoreTextBlock,
- Padding = new Thickness(60, 31, 25, 35),
- MinimumWidth = 190f // Set the minimum width of score button so that it wont modify when the content (text) changes, and less than minimum.
- };
-
- gameRoot = new Canvas();
- gameRoot.Children.Add(scoreBoard);
- }
+ var mainMenuCanvas = new Canvas();
+ mainMenuCanvas.Children.Add(strideLogo);
+ mainMenuCanvas.Children.Add(startButton);
- private void CreateGameOverUI()
+ mainMenuRoot = new ModalElement
{
- var menuButton = new Button
- {
- Content = new TextBlock
- {
- Font = Font,
- Text = "Menu",
- TextColor = Color.Black,
- HorizontalAlignment = HorizontalAlignment.Center,
- VerticalAlignment = VerticalAlignment.Center
- },
- PressedImage = buttonImage,
- NotPressedImage = buttonImage,
- MouseOverImage = buttonImage,
- Padding = new Thickness(77, 30, 25, 30),
- MinimumWidth = 190f,
- };
-
- menuButton.SetCanvasPinOrigin(new Vector3(0.5f, 0.5f, 1f));
- menuButton.SetCanvasRelativePosition(new Vector3(0.70f, 0.7f, 0f));
- menuButton.Click += (sender, args) =>
- {
- GameGlobals.GameResetEventKey.Broadcast();
- StartMainMenuMode();
- };
+ HorizontalAlignment = HorizontalAlignment.Stretch,
+ VerticalAlignment = VerticalAlignment.Stretch,
+ Content = mainMenuCanvas
+ };
+ }
+
+ private void CreateGameUI()
+ {
+ scoreTextBlock = new TextBlock
+ {
+ Font = Font,
+ TextColor = Color.Black,
+ VerticalAlignment = VerticalAlignment.Center
+ };
+ scoreTextBlock.SetCanvasPinOrigin(new Vector3(0.5f, 0.5f, 1f));
+ scoreTextBlock.SetCanvasRelativePosition(new Vector3(0.2f, 0.05f, 0f));
+
+ var scoreBoard = new ContentDecorator
+ {
+ BackgroundImage = SpriteFromSheet.Create(UIImages, "score_bg"),
+ Content = scoreTextBlock,
+ Padding = new Thickness(60, 31, 25, 35),
+ MinimumWidth = 190f // Set the minimum width of score button so that it wont modify when the content (text) changes, and less than minimum.
+ };
+
+ gameRoot = new Canvas();
+ gameRoot.Children.Add(scoreBoard);
+ }
- var retryButton = new Button
+ private void CreateGameOverUI()
+ {
+ var menuButton = new Button
+ {
+ Content = new TextBlock
{
- Content = new TextBlock
- {
- Font = Font,
- Text = "Retry",
- TextColor = Color.Black,
- HorizontalAlignment = HorizontalAlignment.Center,
- VerticalAlignment = VerticalAlignment.Center
- },
- Padding = new Thickness(74, 30, 25, 30),
- MinimumWidth = 190f,
- PressedImage = buttonImage,
- MouseOverImage = buttonImage,
- NotPressedImage = buttonImage
- };
-
- retryButton.SetCanvasPinOrigin(new Vector3(0.5f, 0.5f, 1f));
- retryButton.SetCanvasRelativePosition(new Vector3(0.3f, 0.7f, 0f));
- retryButton.Click += (sender, args) =>
+ Font = Font,
+ Text = "Menu",
+ TextColor = Color.Black,
+ HorizontalAlignment = HorizontalAlignment.Center,
+ VerticalAlignment = VerticalAlignment.Center
+ },
+ PressedImage = buttonImage,
+ NotPressedImage = buttonImage,
+ MouseOverImage = buttonImage,
+ Padding = new Thickness(77, 30, 25, 30),
+ MinimumWidth = 190f,
+ };
+
+ menuButton.SetCanvasPinOrigin(new Vector3(0.5f, 0.5f, 1f));
+ menuButton.SetCanvasRelativePosition(new Vector3(0.70f, 0.7f, 0f));
+ menuButton.Click += (sender, args) =>
+ {
+ GameGlobals.GameResetEventKey.Broadcast();
+ StartMainMenuMode();
+ };
+
+ var retryButton = new Button
+ {
+ Content = new TextBlock
{
- GameGlobals.GameResetEventKey.Broadcast();
- GameGlobals.GameStartedEventKey.Broadcast();
- StartGameMode();
- };
+ Font = Font,
+ Text = "Retry",
+ TextColor = Color.Black,
+ HorizontalAlignment = HorizontalAlignment.Center,
+ VerticalAlignment = VerticalAlignment.Center
+ },
+ Padding = new Thickness(74, 30, 25, 30),
+ MinimumWidth = 190f,
+ PressedImage = buttonImage,
+ MouseOverImage = buttonImage,
+ NotPressedImage = buttonImage
+ };
+
+ retryButton.SetCanvasPinOrigin(new Vector3(0.5f, 0.5f, 1f));
+ retryButton.SetCanvasRelativePosition(new Vector3(0.3f, 0.7f, 0f));
+ retryButton.Click += (sender, args) =>
+ {
+ GameGlobals.GameResetEventKey.Broadcast();
+ GameGlobals.GameStartedEventKey.Broadcast();
+ StartGameMode();
+ };
- var gameOverCanvas = new Canvas();
- gameOverCanvas.Children.Add(menuButton);
- gameOverCanvas.Children.Add(retryButton);
+ var gameOverCanvas = new Canvas();
+ gameOverCanvas.Children.Add(menuButton);
+ gameOverCanvas.Children.Add(retryButton);
- gameOverRoot = new ModalElement
- {
- HorizontalAlignment = HorizontalAlignment.Stretch,
- VerticalAlignment = VerticalAlignment.Stretch,
- Content = gameOverCanvas
- };
- }
+ gameOverRoot = new ModalElement
+ {
+ HorizontalAlignment = HorizontalAlignment.Stretch,
+ VerticalAlignment = VerticalAlignment.Stretch,
+ Content = gameOverCanvas
+ };
}
}
diff --git a/samples/Games/SpaceEscape/SpaceEscape.Game/Background/BackgroundInfo.cs b/samples/Games/SpaceEscape/SpaceEscape.Game/Background/BackgroundInfo.cs
index 5912485d9d..ad693a1bb1 100644
--- a/samples/Games/SpaceEscape/SpaceEscape.Game/Background/BackgroundInfo.cs
+++ b/samples/Games/SpaceEscape/SpaceEscape.Game/Background/BackgroundInfo.cs
@@ -1,18 +1,12 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
-using System.Collections.Generic;
+
using Stride.Engine;
-namespace SpaceEscape.Background
-{
- public class BackgroundInfo : ScriptComponent
- {
- public BackgroundInfo()
- {
- Holes = new List();
- }
+namespace SpaceEscape.Background;
- public int MaxNbObstacles { get; set; }
- public List Holes { get; private set; }
- }
+public class BackgroundInfo : ScriptComponent
+{
+ public int MaxNbObstacles { get; set; }
+ public List Holes { get; private set; } = [];
}
diff --git a/samples/Games/SpaceEscape/SpaceEscape.Game/Background/BackgroundScript.cs b/samples/Games/SpaceEscape/SpaceEscape.Game/Background/BackgroundScript.cs
index 9f1c6e9b60..5f8e202d97 100644
--- a/samples/Games/SpaceEscape/SpaceEscape.Game/Background/BackgroundScript.cs
+++ b/samples/Games/SpaceEscape/SpaceEscape.Game/Background/BackgroundScript.cs
@@ -1,249 +1,244 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
-using System;
-using System.Collections.Generic;
+using SpaceEscape.Effects;
using Stride.Core.Mathematics;
-using Stride.Rendering;
using Stride.Engine;
-using SpaceEscape.Effects;
-using System.Linq;
-using Stride.Core.Extensions;
+using Stride.Rendering;
+
+namespace SpaceEscape.Background;
-namespace SpaceEscape.Background
+///
+/// BackgroundScript controls background section in the game.
+///
+public class BackgroundScript : SyncScript
{
- ///
- /// BackgroundScript controls background section in the game.
- ///
- public class BackgroundScript : SyncScript
- {
- public event Action DistanceUpdated;
+ public event Action DistanceUpdated;
- private const float GameSpeed = 30f;
- private const float RemoveBlockPosition = -16f;
- private const float AddBlockPosition = 280f;
- private const int NumberOfStartBlock = 5;
+ private const float GameSpeed = 30f;
+ private const float RemoveBlockPosition = -16f;
+ private const float AddBlockPosition = 280f;
+ private const int NumberOfStartBlock = 5;
- public Scene LevelBlocks;
- public Model SkyplaneModel; // Cache to scroll its UV region.
+ public Scene LevelBlocks;
+ public Model SkyplaneModel; // Cache to scroll its UV region.
- internal static readonly Random Random = new Random();
- private readonly List levelBlocks = new List();
- private LevelGenerator levelGenerator;
- private float runningDistance; // Store how far the player progressed in m.
+ internal static readonly Random Random = new();
+ private readonly List levelBlocks = [];
+ private LevelGenerator levelGenerator;
+ private float runningDistance; // Store how far the player progressed in m.
- private static readonly Vector3 SkyPlanePosition = new Vector3(0, -10f, 340f);
- private Vector4 skyplaneUVRegion = new Vector4(0f, 0f, 1f, 1f);
- private bool isScrolling;
- private Entity skyplaneEntity;
+ private static readonly Vector3 SkyPlanePosition = new(0, -10f, 340f);
+ private Vector4 skyplaneUVRegion = new(0f, 0f, 1f, 1f);
+ private bool isScrolling;
+ private Entity skyplaneEntity;
- private float RunningDistance
+ private float RunningDistance
+ {
+ get{ return runningDistance; }
+ set
{
- get{ return runningDistance; }
- set
- {
- runningDistance = value;
- if (DistanceUpdated != null)
- DistanceUpdated(runningDistance);
- }
+ runningDistance = value;
+ if (DistanceUpdated != null)
+ DistanceUpdated(runningDistance);
}
+ }
- public override void Start()
- {
- var levelBlockEntity = LevelBlocks.Entities.First(x => x.Name == "LevelBlocks");
- levelGenerator = levelBlockEntity.Get();
+ public override void Start()
+ {
+ var levelBlockEntity = LevelBlocks.Entities.First(x => x.Name == "LevelBlocks");
+ levelGenerator = levelBlockEntity.Get();
- RunningDistance = 0f;
+ RunningDistance = 0f;
- // Load SkyPlane
- skyplaneEntity = new Entity { new ModelComponent(SkyplaneModel) };
+ // Load SkyPlane
+ skyplaneEntity = new Entity { new ModelComponent(SkyplaneModel) };
- skyplaneEntity.Transform.Position= SkyPlanePosition;
- SkyplaneModel.Meshes[0].Parameters.Set(GameParameters.EnableBend, false);
- SkyplaneModel.Meshes[0].Parameters.Set(GameParameters.EnableOnflyTextureUVChange, true);
+ skyplaneEntity.Transform.Position= SkyPlanePosition;
+ SkyplaneModel.Meshes[0].Parameters.Set(GameParameters.EnableBend, false);
+ SkyplaneModel.Meshes[0].Parameters.Set(GameParameters.EnableOnflyTextureUVChange, true);
- // Add skyPlane with LevelBlocks to EntitySystem
- SceneSystem.SceneInstance.RootScene.Entities.Add(skyplaneEntity);
- CreateStartLevelBlocks();
- }
+ // Add skyPlane with LevelBlocks to EntitySystem
+ SceneSystem.SceneInstance.RootScene.Entities.Add(skyplaneEntity);
+ CreateStartLevelBlocks();
+ }
+
+ public override void Cancel()
+ {
+ Entity.Transform.Children.Clear();
+ SceneSystem.SceneInstance.RootScene.Entities.Remove(skyplaneEntity);
+ }
+
+ public override void Update()
+ {
+ if (!isScrolling)
+ return;
- public override void Cancel()
+ var elapsedTime = (float)Game.UpdateTime.Elapsed.TotalSeconds;
+
+ // Check if needed to remove the first block
+ var firstBlock = levelBlocks[0];
+ if (firstBlock.PositionZ + firstBlock.Length * 0.5f < RemoveBlockPosition)
{
- Entity.Transform.Children.Clear();
- SceneSystem.SceneInstance.RootScene.Entities.Remove(skyplaneEntity);
+ RemoveLevelBlock(firstBlock);
}
- public override void Update()
+ // Check if needed to add new levelblock
+ var lastBlock = levelBlocks[^1];
+ if (lastBlock.PositionZ - lastBlock.Length * 0.5f < AddBlockPosition)
{
- if (!isScrolling)
- return;
-
- var elapsedTime = (float)Game.UpdateTime.Elapsed.TotalSeconds;
-
- // Check if needed to remove the first block
- var firstBlock = levelBlocks[0];
- if (firstBlock.PositionZ + firstBlock.Length * 0.5f < RemoveBlockPosition)
- {
- RemoveLevelBlock(firstBlock);
- }
+ AddLevelBlock(levelGenerator.RandomCreateLevelBlock());
+ }
- // Check if needed to add new levelblock
- var lastBlock = levelBlocks[levelBlocks.Count - 1];
- if (lastBlock.PositionZ - lastBlock.Length * 0.5f < AddBlockPosition)
- {
- AddLevelBlock(levelGenerator.RandomCreateLevelBlock());
- }
+ // Move levelblocks
+ foreach (var levelBlock in levelBlocks)
+ {
+ var moveDist = GameSpeed * elapsedTime;
+ levelBlock.PositionZ -= moveDist;
+ RunningDistance += moveDist / 100f;
+ }
- // Move levelblocks
- foreach (var levelBlock in levelBlocks)
- {
- var moveDist = GameSpeed * elapsedTime;
- levelBlock.PositionZ -= moveDist;
- RunningDistance += moveDist / 100f;
- }
+ if (skyplaneUVRegion.X < -1f)
+ // Reset scrolling position of Skyplane's UV
+ skyplaneUVRegion.X = 0f;
- if (skyplaneUVRegion.X < -1f)
- // Reset scrolling position of Skyplane's UV
- skyplaneUVRegion.X = 0f;
+ // Move Scroll position by an offset every frame.
+ skyplaneUVRegion.X -= 0.0005f;
- // Move Scroll position by an offset every frame.
- skyplaneUVRegion.X -= 0.0005f;
+ // Update Parameters of the shader
+ SkyplaneModel.Meshes[0].Parameters.Set(TransformationTextureUVKeys.TextureRegion, skyplaneUVRegion);
+ }
- // Update Parameters of the shader
- SkyplaneModel.Meshes[0].Parameters.Set(TransformationTextureUVKeys.TextureRegion, skyplaneUVRegion);
- }
+ public void Reset()
+ {
+ RunningDistance = 0f;
+ isScrolling = false;
- public void Reset()
+ for (var i = levelBlocks.Count - 1; i >= 0; i--)
{
- RunningDistance = 0f;
- isScrolling = false;
+ var levelBlock = levelBlocks[i];
- for (var i = levelBlocks.Count - 1; i >= 0; i--)
- {
- var levelBlock = levelBlocks[i];
-
- Entity.RemoveChild(levelBlock.RootEntity);
- levelBlocks.RemoveAt(i);
- }
-
- CreateStartLevelBlocks();
+ Entity.RemoveChild(levelBlock.RootEntity);
+ levelBlocks.RemoveAt(i);
}
- public bool DetectCollisions(ref BoundingBox agentBB)
+ CreateStartLevelBlocks();
+ }
+
+ public bool DetectCollisions(ref BoundingBox agentBB)
+ {
+ foreach (var levelBlock in levelBlocks)
{
- foreach (var levelBlock in levelBlocks)
+ foreach (var obst in levelBlock.CollidableObstacles)
{
- foreach (var obst in levelBlock.CollidableObstacles)
- {
- if (DetectCollision(ref agentBB, obst))
- return true;
- }
+ if (DetectCollision(ref agentBB, obst))
+ return true;
}
-
- return false;
}
- private static bool DetectCollision(ref BoundingBox agentBB,
- Obstacle obst)
- {
- var objTrans = obst.Entity.Transform;
- objTrans.UpdateWorldMatrix();
-
- var objWorldPos = objTrans.WorldMatrix.TranslationVector;
+ return false;
+ }
- foreach (var boundingBox in obst.BoundingBoxes)
- {
- var minVec = objWorldPos + boundingBox.Minimum;
- var maxVec = objWorldPos + boundingBox.Maximum;
- var testBB = new BoundingBox(minVec, maxVec);
+ private static bool DetectCollision(ref BoundingBox agentBB,
+ Obstacle obst)
+ {
+ var objTrans = obst.Entity.Transform;
+ objTrans.UpdateWorldMatrix();
- if (CollisionHelper.BoxContainsBox(ref testBB, ref agentBB) != ContainmentType.Disjoint)
- return true;
- }
- return false;
- }
+ var objWorldPos = objTrans.WorldMatrix.TranslationVector;
- ///
- /// Starts the scrolling of the background
- ///
- public void StartScrolling()
+ foreach (var boundingBox in obst.BoundingBoxes)
{
- isScrolling = true;
- }
+ var minVec = objWorldPos + boundingBox.Minimum;
+ var maxVec = objWorldPos + boundingBox.Maximum;
+ var testBB = new BoundingBox(minVec, maxVec);
- ///
- /// Stops the scrolling of the background
- ///
- public void StopScrolling()
- {
- isScrolling = false;
+ if (CollisionHelper.BoxContainsBox(ref testBB, ref agentBB) != ContainmentType.Disjoint)
+ return true;
}
+ return false;
+ }
- public bool DetectHoles(ref Vector3 agentWorldPos, out float height)
- {
- height = 0f;
+ ///
+ /// Starts the scrolling of the background
+ ///
+ public void StartScrolling()
+ {
+ isScrolling = true;
+ }
+
+ ///
+ /// Stops the scrolling of the background
+ ///
+ public void StopScrolling()
+ {
+ isScrolling = false;
+ }
- foreach (var levelBlock in levelBlocks)
+ public bool DetectHoles(ref Vector3 agentWorldPos, out float height)
+ {
+ height = 0f;
+
+ foreach (var levelBlock in levelBlocks)
+ {
+ levelBlock.RootEntity.Transform.UpdateWorldMatrix();
+ var worldPosZ = levelBlock.RootEntity.Transform.Position.Z;
+ foreach (var hole in levelBlock.Holes)
{
- levelBlock.RootEntity.Transform.UpdateWorldMatrix();
- var worldPosZ = levelBlock.RootEntity.Transform.Position.Z;
- foreach (var hole in levelBlock.Holes)
- {
- if (DetectHole(ref agentWorldPos, out height, hole,
- worldPosZ))
- return true;
- }
+ if (DetectHole(ref agentWorldPos, out height, hole,
+ worldPosZ))
+ return true;
}
- return false;
}
+ return false;
+ }
- private static bool DetectHole(ref Vector3 agentWorldPos, out float height, Hole hole, float blockPosZ)
- {
- var testArea = hole.Area;
- testArea.Y += blockPosZ;
- height = hole.Height;
+ private static bool DetectHole(ref Vector3 agentWorldPos, out float height, Hole hole, float blockPosZ)
+ {
+ var testArea = hole.Area;
+ testArea.Y += blockPosZ;
+ height = hole.Height;
- var agentVec2Pos = new Vector2(-agentWorldPos.X, agentWorldPos.Z);
- return RectContains(ref testArea, ref agentVec2Pos);
- }
+ var agentVec2Pos = new Vector2(-agentWorldPos.X, agentWorldPos.Z);
+ return RectContains(ref testArea, ref agentVec2Pos);
+ }
- private void CreateStartLevelBlocks()
- {
- AddLevelBlock(levelGenerator.CreateSafeLevelBlock());
+ private void CreateStartLevelBlocks()
+ {
+ AddLevelBlock(levelGenerator.CreateSafeLevelBlock());
- for (var i = 0; i < NumberOfStartBlock; i++)
- AddLevelBlock(levelGenerator.RandomCreateLevelBlock());
- }
+ for (var i = 0; i < NumberOfStartBlock; i++)
+ AddLevelBlock(levelGenerator.RandomCreateLevelBlock());
+ }
- private void AddLevelBlock(Section newSection)
- {
- var count = levelBlocks.Count;
- levelBlocks.Add(newSection);
+ private void AddLevelBlock(Section newSection)
+ {
+ var count = levelBlocks.Count;
+ levelBlocks.Add(newSection);
- if (count == 0)
- {
- Entity.AddChild(newSection.RootEntity);
- return;
- }
+ if (count == 0)
+ {
+ Entity.AddChild(newSection.RootEntity);
+ return;
+ }
- var prevLatestBlock = levelBlocks[count - 1];
+ var prevLatestBlock = levelBlocks[count - 1];
- var originDist = 0.5f * (prevLatestBlock.Length + newSection.Length);
- newSection.PositionZ = prevLatestBlock.PositionZ + originDist;
+ var originDist = 0.5f * (prevLatestBlock.Length + newSection.Length);
+ newSection.PositionZ = prevLatestBlock.PositionZ + originDist;
- Entity.AddChild(newSection.RootEntity);
- }
+ Entity.AddChild(newSection.RootEntity);
+ }
- private void RemoveLevelBlock(Section firstBlock)
- {
- levelBlocks.Remove(firstBlock);
- Entity.RemoveChild(firstBlock.RootEntity);
- }
+ private void RemoveLevelBlock(Section firstBlock)
+ {
+ levelBlocks.Remove(firstBlock);
+ Entity.RemoveChild(firstBlock.RootEntity);
+ }
- private static bool RectContains(ref RectangleF rect, ref Vector2 agentPos)
- {
- return (rect.X <= agentPos.X) && (rect.X + rect.Width >= agentPos.X)
- && (rect.Y >= agentPos.Y) && (rect.Y - rect.Height <= agentPos.Y);
- }
+ private static bool RectContains(ref RectangleF rect, ref Vector2 agentPos)
+ {
+ return (rect.X <= agentPos.X) && (rect.X + rect.Width >= agentPos.X)
+ && (rect.Y >= agentPos.Y) && (rect.Y - rect.Height <= agentPos.Y);
}
}
diff --git a/samples/Games/SpaceEscape/SpaceEscape.Game/Background/Hole.cs b/samples/Games/SpaceEscape/SpaceEscape.Game/Background/Hole.cs
index 64b001fe61..097f65d70f 100644
--- a/samples/Games/SpaceEscape/SpaceEscape.Game/Background/Hole.cs
+++ b/samples/Games/SpaceEscape/SpaceEscape.Game/Background/Hole.cs
@@ -1,24 +1,24 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
+
using Stride.Core;
using Stride.Core.Mathematics;
-namespace SpaceEscape.Background
+namespace SpaceEscape.Background;
+
+///
+/// This class contains information needed to describe a hole in the background.
+///
+[DataContract("BackgroundElement")]
+public class Hole
{
///
- /// This class contains information needed to describe a hole in the background.
+ /// The area of the hole.
///
- [DataContract("BackgroundElement")]
- public class Hole
- {
- ///
- /// The area of the hole.
- ///
- public RectangleF Area { get; set; }
+ public RectangleF Area { get; set; }
- ///
- /// The height of the hole.
- ///
- public float Height { get; set; }
- }
+ ///
+ /// The height of the hole.
+ ///
+ public float Height { get; set; }
}
diff --git a/samples/Games/SpaceEscape/SpaceEscape.Game/Background/LevelGenerator.cs b/samples/Games/SpaceEscape/SpaceEscape.Game/Background/LevelGenerator.cs
index 7b9a7fa9ab..3915915755 100644
--- a/samples/Games/SpaceEscape/SpaceEscape.Game/Background/LevelGenerator.cs
+++ b/samples/Games/SpaceEscape/SpaceEscape.Game/Background/LevelGenerator.cs
@@ -1,126 +1,124 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
-using System.Linq;
+
using Stride.Core.Mathematics;
using Stride.Engine;
-namespace SpaceEscape.Background
-{
+namespace SpaceEscape.Background;
+
- public class LevelGenerator : ScriptComponent
+public class LevelGenerator : ScriptComponent
+{
+ public Entity Background_a00;
+ public Entity Background_b00;
+ public Entity Background_b01;
+ public Entity Background_b02;
+ public Entity Background_b03;
+ public Entity Background_b04;
+
+ public Entity Obstacle1;
+ public Entity Obstacle2;
+
+ ///
+ /// Randomly create pattern from defined Factory method of each one.
+ ///
+ ///
+ public Section RandomCreateLevelBlock()
{
- public Entity Background_a00;
- public Entity Background_b00;
- public Entity Background_b01;
- public Entity Background_b02;
- public Entity Background_b03;
- public Entity Background_b04;
-
- public Entity Obstacle1;
- public Entity Obstacle2;
-
- ///
- /// Randomly create pattern from defined Factory method of each one.
- ///
- ///
- public Section RandomCreateLevelBlock()
+ Entity backgroundEntity;
+ switch (BackgroundScript.Random.Next(6))
{
- Entity backgroundEntity;
- switch (BackgroundScript.Random.Next(6))
- {
- default:
- case 0: backgroundEntity = Background_a00; break;
- case 1: backgroundEntity = Background_b00; break;
- case 2: backgroundEntity = Background_b01; break;
- case 3: backgroundEntity = Background_b02; break;
- case 4: backgroundEntity = Background_b03; break;
- case 5: backgroundEntity = Background_b04; break;
- }
-
- return CreateLevelBlock(backgroundEntity.Clone());
+ default:
+ case 0: backgroundEntity = Background_a00; break;
+ case 1: backgroundEntity = Background_b00; break;
+ case 2: backgroundEntity = Background_b01; break;
+ case 3: backgroundEntity = Background_b02; break;
+ case 4: backgroundEntity = Background_b03; break;
+ case 5: backgroundEntity = Background_b04; break;
}
- public Section CreateSafeLevelBlock()
+ return CreateLevelBlock(backgroundEntity.Clone());
+ }
+
+ public Section CreateSafeLevelBlock()
+ {
+ return CreateLevelBlock(Background_a00.Clone(), 0);
+ }
+
+ ///
+ /// Randomly get Obstacle from available keys and return the clone.
+ ///
+ ///
+ private Entity CloneRandomObstacle(out bool useSubmeshesBoundingBoxes)
+ {
+ Entity obstacleEntity;
+ switch (BackgroundScript.Random.Next(2))
{
- return CreateLevelBlock(Background_a00.Clone(), 0);
+ default:
+ case 0: obstacleEntity = Obstacle1; break;
+ case 1: obstacleEntity = Obstacle2; break;
}
- ///
- /// Randomly get Obstacle from available keys and return the clone.
- ///
- ///
- private Entity CloneRandomObstacle(out bool useSubmeshesBoundingBoxes)
- {
- Entity obstacleEntity;
- switch (BackgroundScript.Random.Next(2))
- {
- default:
- case 0: obstacleEntity = Obstacle1; break;
- case 1: obstacleEntity = Obstacle2; break;
- }
+ useSubmeshesBoundingBoxes = obstacleEntity.Get().UseSubMeshBoundingBoxes;
+ obstacleEntity = obstacleEntity.Clone();
- useSubmeshesBoundingBoxes = obstacleEntity.Get().UseSubMeshBoundingBoxes;
- obstacleEntity = obstacleEntity.Clone();
+ // Reset position
+ obstacleEntity.Transform.Position = Vector3.Zero;
- // Reset position
- obstacleEntity.Transform.Position = Vector3.Zero;
+ return obstacleEntity;
+ }
- return obstacleEntity;
- }
+ ///
+ /// Factory method to create Section from a given BackgroundEntity
+ ///
+ ///
+ /// The maximum number of obstacle in the block level
+ ///
+ private Section CreateLevelBlock(Entity backgroundEnt, int? maxObstacleOverride = null)
+ {
+ // Reset position
+ backgroundEnt.Transform.Position = Vector3.Zero;
- ///
- /// Factory method to create Section from a given BackgroundEntity
- ///
- ///
- /// The maximum number of obstacle in the block level
- ///
- private Section CreateLevelBlock(Entity backgroundEnt, int? maxObstacleOverride = null)
- {
- // Reset position
- backgroundEnt.Transform.Position = Vector3.Zero;
+ var levelBlock = new Section();
+ var backgroundInfo = backgroundEnt.Get();
+ levelBlock.AddBackgroundEntity(backgroundEnt).AddHoleRange(backgroundInfo.Holes);
- var levelBlock = new Section();
- var backgroundInfo = backgroundEnt.Get();
- levelBlock.AddBackgroundEntity(backgroundEnt).AddHoleRange(backgroundInfo.Holes);
+ var len = levelBlock.Length;
+ RandomAddObstacles(levelBlock, len, maxObstacleOverride ?? backgroundInfo.MaxNbObstacles);
- var len = levelBlock.Length;
- RandomAddObstacles(levelBlock, len, maxObstacleOverride ?? backgroundInfo.MaxNbObstacles);
+ return levelBlock;
+ }
- return levelBlock;
- }
+ ///
+ /// Randomly add obstacles to the given level block, while
+ /// the number of obstacles to be added is from nbObst.
+ ///
+ ///
+ ///
+ ///
+ private void RandomAddObstacles(Section section, float patternLen, int nbObst)
+ {
+ var halfPatternLen = patternLen / 2f;
- ///
- /// Randomly add obstacles to the given level block, while
- /// the number of obstacles to be added is from nbObst.
- ///
- ///
- ///
- ///
- private void RandomAddObstacles(Section section, float patternLen, int nbObst)
+ for (var i = 0; i < nbObst; i++)
{
- var halfPatternLen = patternLen / 2f;
-
- for (var i = 0; i < nbObst; i++)
- {
- // Random val in {0.0-1.0}
- var randVal = BackgroundScript.Random.NextDouble();
+ // Random val in {0.0-1.0}
+ var randVal = BackgroundScript.Random.NextDouble();
- // Calculate position in Z axis by:
- // changing the value in uniform space (randVal) to world space.
- // the value is substracted with halfPatternLen because the origin (0) is at the center of the block.
- var posZ = patternLen * (float)((i + randVal) / nbObst) - halfPatternLen;
+ // Calculate position in Z axis by:
+ // changing the value in uniform space (randVal) to world space.
+ // the value is substracted with halfPatternLen because the origin (0) is at the center of the block.
+ var posZ = patternLen * (float)((i + randVal) / nbObst) - halfPatternLen;
- // Random lane, and get the world position in X axis.
- var lane = BackgroundScript.Random.Next(3);
- var posX = (1 - lane) * 5f;
+ // Random lane, and get the world position in X axis.
+ var lane = BackgroundScript.Random.Next(3);
+ var posX = (1 - lane) * 5f;
- // Randomly get the obstacle, and set the position of this obstacle.
- bool useSubBoundingBoxes;
- var obsEnt = CloneRandomObstacle(out useSubBoundingBoxes);
- obsEnt.Transform.Position = new Vector3(posX, 0, posZ);
+ // Randomly get the obstacle, and set the position of this obstacle.
+ var obsEnt = CloneRandomObstacle(out var useSubBoundingBoxes);
+ obsEnt.Transform.Position = new Vector3(posX, 0, posZ);
- section.AddObstacleEntity(obsEnt, useSubBoundingBoxes);
- }
+ section.AddObstacleEntity(obsEnt, useSubBoundingBoxes);
}
}
}
diff --git a/samples/Games/SpaceEscape/SpaceEscape.Game/Background/Obstacle.cs b/samples/Games/SpaceEscape/SpaceEscape.Game/Background/Obstacle.cs
index 2abbc1a333..8af966878a 100644
--- a/samples/Games/SpaceEscape/SpaceEscape.Game/Background/Obstacle.cs
+++ b/samples/Games/SpaceEscape/SpaceEscape.Game/Background/Obstacle.cs
@@ -1,24 +1,23 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
-using System.Collections.Generic;
+
using Stride.Core.Mathematics;
using Stride.Engine;
-namespace SpaceEscape.Background
+namespace SpaceEscape.Background;
+
+///
+/// The class contains information needed to describe a collidable object.
+///
+public class Obstacle
{
///
- /// The class contains information needed to describe a collidable object.
+ /// The list of bounding boxes used to determine the collision with the obstacle.
///
- public class Obstacle
- {
- ///
- /// The list of bounding boxes used to determine the collision with the obstacle.
- ///
- public List BoundingBoxes = new List();
+ public List BoundingBoxes = [];
- ///
- /// The entity representing the collidable object.
- ///
- public Entity Entity { get; set; }
- }
+ ///
+ /// The entity representing the collidable object.
+ ///
+ public Entity Entity { get; set; }
}
diff --git a/samples/Games/SpaceEscape/SpaceEscape.Game/Background/ObstacleInfo.cs b/samples/Games/SpaceEscape/SpaceEscape.Game/Background/ObstacleInfo.cs
index 1826b6b939..ef6da6752a 100644
--- a/samples/Games/SpaceEscape/SpaceEscape.Game/Background/ObstacleInfo.cs
+++ b/samples/Games/SpaceEscape/SpaceEscape.Game/Background/ObstacleInfo.cs
@@ -1,11 +1,11 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
+
using Stride.Engine;
-namespace SpaceEscape.Background
+namespace SpaceEscape.Background;
+
+public class ObstacleInfo : ScriptComponent
{
- public class ObstacleInfo : ScriptComponent
- {
- public bool UseSubMeshBoundingBoxes;
- }
+ public bool UseSubMeshBoundingBoxes;
}
diff --git a/samples/Games/SpaceEscape/SpaceEscape.Game/Background/Section.cs b/samples/Games/SpaceEscape/SpaceEscape.Game/Background/Section.cs
index c7129761a9..57904fd39c 100644
--- a/samples/Games/SpaceEscape/SpaceEscape.Game/Background/Section.cs
+++ b/samples/Games/SpaceEscape/SpaceEscape.Game/Background/Section.cs
@@ -1,130 +1,129 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
-using System.Collections.Generic;
+
using Stride.Core.Mathematics;
using Stride.Engine;
-namespace SpaceEscape.Background
+namespace SpaceEscape.Background;
+
+///
+/// Represents a section of the background which contains other game objects.
+///
+public class Section
{
///
- /// Represents a section of the background which contains other game objects.
+ /// Gets the length of the level block
+ ///
+ public float Length { get; private set; }
+
+ ///
+ /// Gets the root entity of the level block
+ ///
+ public Entity RootEntity { get; }
+
+ ///
+ /// Gets the list collidable obstacles of the level block
+ ///
+ public List CollidableObstacles { get; }
+
+ ///
+ /// Gets the list of holes of the level block
///
- public class Section
+ public List Holes { get; }
+
+ ///
+ /// Create a new empty level block.
+ ///
+ public Section()
{
- ///
- /// Gets the length of the level block
- ///
- public float Length { get; private set; }
-
- ///
- /// Gets the root entity of the level block
- ///
- public Entity RootEntity { get; private set; }
-
- ///
- /// Gets the list collidable obstacles of the level block
- ///
- public List CollidableObstacles { get; private set; }
-
- ///
- /// Gets the list of holes of the level block
- ///
- public List Holes { get; private set; }
-
- ///
- /// Create a new empty level block.
- ///
- public Section()
- {
- RootEntity = new Entity();
- CollidableObstacles = new List();
- Holes = new List();
- }
+ RootEntity = new Entity();
+ CollidableObstacles = [];
+ Holes = [];
+ }
- ///
- /// Gets the distance in the Oz axis of the level block to the origin.
- ///
- public float PositionZ
- {
- get { return RootEntity.Transform.Position.Z; }
- set { RootEntity.Transform.Position.Z = value; }
- }
+ ///
+ /// Gets the distance in the Oz axis of the level block to the origin.
+ ///
+ public float PositionZ
+ {
+ get { return RootEntity.Transform.Position.Z; }
+ set { RootEntity.Transform.Position.Z = value; }
+ }
- public Section AddBackgroundEntity(Entity backgroundEntity)
- {
- // Attach it in ModelEntity
- RootEntity.AddChild(backgroundEntity);
+ public Section AddBackgroundEntity(Entity backgroundEntity)
+ {
+ // Attach it in ModelEntity
+ RootEntity.AddChild(backgroundEntity);
- // Get length via its bounding box
- var modelComponent = backgroundEntity.Get().Model;
- var boundingBox = modelComponent.BoundingBox;
+ // Get length via its bounding box
+ var modelComponent = backgroundEntity.Get().Model;
+ var boundingBox = modelComponent.BoundingBox;
- Length += boundingBox.Maximum.Z - boundingBox.Minimum.Z;
+ Length += boundingBox.Maximum.Z - boundingBox.Minimum.Z;
- return this;
- }
+ return this;
+ }
- ///
- /// Chaining method for adding an obstacle to this Section.
- /// It initializes bounding boxes and stores in Collidable Obstacles.
- ///
- /// The entity containing the obstacle
- /// true to use the bounding boxes of the sub-meshes
- ///
- public Section AddObstacleEntity(Entity obstacleEntity, bool useSubBoundingBoxes)
- {
- // Attach it in ModelEntity
- RootEntity.AddChild(obstacleEntity);
+ ///
+ /// Chaining method for adding an obstacle to this Section.
+ /// It initializes bounding boxes and stores in Collidable Obstacles.
+ ///
+ /// The entity containing the obstacle
+ /// true to use the bounding boxes of the sub-meshes
+ ///
+ public Section AddObstacleEntity(Entity obstacleEntity, bool useSubBoundingBoxes)
+ {
+ // Attach it in ModelEntity
+ RootEntity.AddChild(obstacleEntity);
- // Get and add bb to CollidableObstacles
- var modelComponent = obstacleEntity.Get();
+ // Get and add bb to CollidableObstacles
+ var modelComponent = obstacleEntity.Get();
- var collidableObstacle = new Obstacle { Entity = obstacleEntity };
+ var collidableObstacle = new Obstacle { Entity = obstacleEntity };
- if (useSubBoundingBoxes)
+ if (useSubBoundingBoxes)
+ {
+ // Use bounding boxes from parts of the obstacle.
+ foreach (var mesh in modelComponent.Model.Meshes)
{
- // Use bounding boxes from parts of the obstacle.
- foreach (var mesh in modelComponent.Model.Meshes)
+ var boundingBox = mesh.BoundingBox;
+ var nodeIndex = mesh.NodeIndex;
+ while (nodeIndex >= 0)
{
- var boundingBox = mesh.BoundingBox;
- var nodeIndex = mesh.NodeIndex;
- while (nodeIndex >= 0)
- {
- var node = modelComponent.Model.Skeleton.Nodes[nodeIndex];
- var transform = node.Transform;
- var matrix = Matrix.Transformation(Vector3.Zero, Quaternion.Identity, transform.Scale, Vector3.Zero, transform.Rotation, transform.Position);
+ var node = modelComponent.Model.Skeleton.Nodes[nodeIndex];
+ var transform = node.Transform;
+ var matrix = Matrix.Transformation(Vector3.Zero, Quaternion.Identity, transform.Scale, Vector3.Zero, transform.Rotation, transform.Position);
- Vector3.TransformNormal(ref boundingBox.Minimum, ref matrix, out boundingBox.Minimum);
- Vector3.TransformNormal(ref boundingBox.Maximum, ref matrix, out boundingBox.Maximum);
+ Vector3.TransformNormal(ref boundingBox.Minimum, ref matrix, out boundingBox.Minimum);
+ Vector3.TransformNormal(ref boundingBox.Maximum, ref matrix, out boundingBox.Maximum);
- nodeIndex = node.ParentIndex;
- }
-
- collidableObstacle.BoundingBoxes.Add(boundingBox);
+ nodeIndex = node.ParentIndex;
}
+
+ collidableObstacle.BoundingBoxes.Add(boundingBox);
}
- else
- {
- // Use bounding box of the whole model
- collidableObstacle.BoundingBoxes.Add(modelComponent.Model.BoundingBox);
- }
+ }
+ else
+ {
+ // Use bounding box of the whole model
+ collidableObstacle.BoundingBoxes.Add(modelComponent.Model.BoundingBox);
+ }
- CollidableObstacles.Add(collidableObstacle);
+ CollidableObstacles.Add(collidableObstacle);
- return this;
- }
+ return this;
+ }
- ///
- /// Add list of Holes to this Section.
- ///
- ///
- ///
- public Section AddHoleRange(List holes)
- {
- if(holes != null)
- Holes.AddRange(holes);
+ ///
+ /// Add list of Holes to this Section.
+ ///
+ ///
+ ///
+ public Section AddHoleRange(List holes)
+ {
+ if(holes != null)
+ Holes.AddRange(holes);
- return this;
- }
+ return this;
}
}
diff --git a/samples/Games/SpaceEscape/SpaceEscape.Game/CharacterScript.cs b/samples/Games/SpaceEscape/SpaceEscape.Game/CharacterScript.cs
index 4ffc5adfb8..c7658ce248 100644
--- a/samples/Games/SpaceEscape/SpaceEscape.Game/CharacterScript.cs
+++ b/samples/Games/SpaceEscape/SpaceEscape.Game/CharacterScript.cs
@@ -1,425 +1,420 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
-using System;
-using System.Collections.Generic;
-using System.Threading.Tasks;
+using Stride.Animations;
using Stride.Core.Mathematics;
using Stride.Engine;
-using Stride.Animations;
using Stride.Input;
-namespace SpaceEscape
+namespace SpaceEscape;
+
+///
+/// CharacterScript is the main character that is controllable by a user.
+/// It could change lane to left and right, and slide.
+///
+public class CharacterScript : AsyncScript
{
///
- /// CharacterScript is the main character that is controllable by a user.
- /// It could change lane to left and right, and slide.
+ /// The sprite component containing the shadow of the vessel.
///
- public class CharacterScript : AsyncScript
+ public SpriteComponent CharacterShadow;
+
+ private enum AgentState
{
- ///
- /// The sprite component containing the shadow of the vessel.
- ///
- public SpriteComponent CharacterShadow;
+ Run,
+ ChangeLaneLeft,
+ ChangeLaneRight,
+ Slide,
+ Die,
+ }
- private enum AgentState
- {
- Run,
- ChangeLaneLeft,
- ChangeLaneRight,
- Slide,
- Die,
- }
+ private enum InputState
+ {
+ None,
+ Left,
+ Right,
+ Down,
+ }
- private enum InputState
- {
- None,
- Left,
- Right,
- Down,
- }
+ private enum AgentAnimationKeys
+ {
+ Active,
+ DodgeLeft,
+ DodgeRight,
+ Slide,
+ Crash,
+ }
- private enum AgentAnimationKeys
- {
- Active,
- DodgeLeft,
- DodgeRight,
- Slide,
- Crash,
- }
+ private enum BoundingBoxKeys
+ {
+ Normal,
+ Slide,
+ }
+
+ private const int LeftLane = 0;
+ private const int MiddleLane = 1;
+ private const int RightLane = 2;
+ private const float LaneLength = 5f;
+ private float laneHeight;
- private enum BoundingBoxKeys
+ public int CurLane { get; private set; }
+ private BoundingBox activeBoundingBox;
+ private AgentState State
+ {
+ get { return state; }
+ set
{
- Normal,
- Slide,
+ state = value;
+ OnEnter(state);
}
+ }
- private const int LeftLane = 0;
- private const int MiddleLane = 1;
- private const int RightLane = 2;
- private const float LaneLength = 5f;
- private float laneHeight;
+ private bool shouldProcessInput;
+ private bool started;
+ private AgentState state; // Current state of the agent
+ private PlayingAnimation playingAnimation; // Current active animation
+ private float startChangeLanePosX; // Position of X before changing lane
+ private float targetChangeLanePosX; // Position of X after changning lane
+ private readonly Dictionary boundingBoxes = new();
+
+ public bool IsDead { get { return State == AgentState.Die; } }
+
+ public void Start()
+ {
+ // Configure Gestures for controlling the agent
+ if (!IsLiveReloading) // Live scripting: add the gesture only once (on first load).
+ Input.Gestures.Add(new GestureConfigDrag(GestureShape.Free) { MinimumDragDistance = 0.02f, RequiredNumberOfFingers = 1 });
- public int CurLane { get; private set; }
- private BoundingBox activeBoundingBox;
- private AgentState State
- {
- get { return state; }
- set
- {
- state = value;
- OnEnter(state);
- }
- }
+ // Setup Normal pose BoundingBox with that of obtained by ModelComponent.
+ boundingBoxes[BoundingBoxKeys.Normal] = Entity.Get().Model.BoundingBox;
+
+ // Create a slide pose BoundingBox by substracting it with a threshold for making the box, smaller in Y axis.
+ var modelMinBB = boundingBoxes[BoundingBoxKeys.Normal].Minimum;
+ var modelMaxBB = boundingBoxes[BoundingBoxKeys.Normal].Maximum;
+ boundingBoxes[BoundingBoxKeys.Slide] = new BoundingBox(modelMinBB, new Vector3(modelMaxBB.X, modelMaxBB.Y - 0.7f, modelMaxBB.Z));
+
+ started = true;
+ }
+
+ ///
+ /// Script Function which awaits each frame and update the CharacterScript.
+ ///
+ ///
+ public override async Task Execute()
+ {
+ Start();
+
+ laneHeight = Entity.Transform.Position.Y;
- private bool shouldProcessInput;
- private bool started;
- private AgentState state; // Current state of the agent
- private PlayingAnimation playingAnimation; // Current active animation
- private float startChangeLanePosX; // Position of X before changing lane
- private float targetChangeLanePosX; // Position of X after changning lane
- private readonly Dictionary boundingBoxes = new Dictionary();
-
- public bool IsDead { get { return State == AgentState.Die; } }
-
- public void Start()
+ Reset();
+
+ while (Game.IsRunning)
{
- // Configure Gestures for controlling the agent
- if (!IsLiveReloading) // Live scripting: add the gesture only once (on first load).
- Input.Gestures.Add(new GestureConfigDrag(GestureShape.Free) { MinimumDragDistance = 0.02f, RequiredNumberOfFingers = 1 });
+ await Script.NextFrame();
+
+ // Get input state from gesture, if none check from the keyboard.
+ var inputState = GetInputFromGesture();
- // Setup Normal pose BoundingBox with that of obtained by ModelComponent.
- boundingBoxes[BoundingBoxKeys.Normal] = Entity.Get().Model.BoundingBox;
+ if (inputState == InputState.None)
+ inputState = GetInputFromKeyboard();
- // Create a slide pose BoundingBox by substracting it with a threshold for making the box, smaller in Y axis.
- var modelMinBB = boundingBoxes[BoundingBoxKeys.Normal].Minimum;
- var modelMaxBB = boundingBoxes[BoundingBoxKeys.Normal].Maximum;
- boundingBoxes[BoundingBoxKeys.Slide] = new BoundingBox(modelMinBB, new Vector3(modelMaxBB.X, modelMaxBB.Y - 0.7f, modelMaxBB.Z));
+ // Process obtained input in this frame
+ ProcessInput(inputState);
- started = true;
+ // Update the agent
+ UpdateState();
}
+ }
- ///
- /// Script Function which awaits each frame and update the CharacterScript.
- ///
- ///
- public override async Task Execute()
- {
- Start();
+ ///
+ /// Activate the character.
+ ///
+ public void Activate()
+ {
+ shouldProcessInput = true;
+ }
- laneHeight = Entity.Transform.Position.Y;
+ ///
+ /// Reset internal state of the agent.
+ ///
+ public void Reset()
+ {
+ if (!started)
+ return;
+ shouldProcessInput = false;
+ State = AgentState.Run;
+ CurLane = MiddleLane;
+ SetShadowTransparency(1);
+ Entity.Transform.Position.Y = laneHeight;
+ Entity.Transform.Position.X = GetXPosition(CurLane);
+ }
- Reset();
+ ///
+ /// Invoke from its user to indicate that the agent has died.
+ ///
+ public void OnDied(float floorHeight)
+ {
+ State = AgentState.Die;
+ Entity.Transform.Position.Y = floorHeight;
+ SetShadowTransparency(0);
+ }
- while (Game.IsRunning)
- {
- await Script.NextFrame();
+ ///
+ /// Calculate and returns the current bounding box of the character
+ ///
+ /// The bounding box
+ public BoundingBox CalculateCurrentBoundingBox()
+ {
+ var agentWorldPosition = Entity.Transform.Position;
- // Get input state from gesture, if none check from the keyboard.
- var inputState = GetInputFromGesture();
+ // Calculate the CharacterScript bounding box
+ var minVec = agentWorldPosition + activeBoundingBox.Minimum;
+ var maxVec = agentWorldPosition + activeBoundingBox.Maximum;
- if (inputState == InputState.None)
- inputState = GetInputFromKeyboard();
+ return new BoundingBox(minVec, maxVec);
+ }
- // Process obtained input in this frame
- ProcessInput(inputState);
+ private void SetShadowTransparency(float transparency)
+ {
+ CharacterShadow.Color = transparency*Color.White;
+ }
- // Update the agent
- UpdateState();
- }
+ ///
+ /// Retrieve input from the user by his/her keyboard, and transform to one of the agent's input state.
+ ///
+ ///
+ private InputState GetInputFromKeyboard()
+ {
+ if (Input.IsKeyPressed(Keys.Left))
+ {
+ return InputState.Left;
}
-
- ///
- /// Activate the character.
- ///
- public void Activate()
+ if (Input.IsKeyPressed(Keys.Right))
{
- shouldProcessInput = true;
+ return InputState.Right;
}
-
- ///
- /// Reset internal state of the agent.
- ///
- public void Reset()
+ if (Input.IsKeyPressed(Keys.Down))
{
- if (!started)
- return;
- shouldProcessInput = false;
- State = AgentState.Run;
- CurLane = MiddleLane;
- SetShadowTransparency(1);
- Entity.Transform.Position.Y = laneHeight;
- Entity.Transform.Position.X = GetXPosition(CurLane);
+ return InputState.Down;
}
+ return InputState.None;
+ }
- ///
- /// Invoke from its user to indicate that the agent has died.
- ///
- public void OnDied(float floorHeight)
+ ///
+ /// Retrieve input from the user by Drag gesture, and determine the input state by
+ /// calculating the direction of drag by ProcessInputFromDragGesture().
+ ///
+ ///
+ private InputState GetInputFromGesture()
+ {
+ // Gesture recognition
+ foreach (var gestureEvent in Input.GestureEvents)
{
- State = AgentState.Die;
- Entity.Transform.Position.Y = floorHeight;
- SetShadowTransparency(0);
+ // Select only Drag gesture with Began state.
+ if (gestureEvent.Type == GestureType.Drag && gestureEvent.State == GestureState.Began)
+ // From Draw gesture, determine the InputState from direction of the swipe.
+ return ProcessInputFromDragGesture((GestureEventDrag)gestureEvent);
}
- ///
- /// Calculate and returns the current bounding box of the character
- ///
- /// The bounding box
- public BoundingBox CalculateCurrentBoundingBox()
- {
- var agentWorldPosition = Entity.Transform.Position;
+ return InputState.None;
+ }
- // Calculate the CharacterScript bounding box
- var minVec = agentWorldPosition + activeBoundingBox.Minimum;
- var maxVec = agentWorldPosition + activeBoundingBox.Maximum;
+ ///
+ /// Process gestureEvent to determine the input state.
+ ///
+ ///
+ ///
+ private InputState ProcessInputFromDragGesture(GestureEventDrag gestureEvent)
+ {
+ // Get drag vector and multiply by the screenRatio of the screen, also flip y (-screenRatio).
+ var screenRatio = (float)GraphicsDevice.Presenter.BackBuffer.Height / GraphicsDevice.Presenter.BackBuffer.Width;
+ var dragVector = (gestureEvent.CurrentPosition - gestureEvent.StartPosition) * new Vector2(1f, -screenRatio);
+ var dragDirection = Vector2.Normalize(dragVector);
- return new BoundingBox(minVec, maxVec);
- }
+ Vector2 comparedAxis;
+ float xDeg;
+ float yDeg;
- private void SetShadowTransparency(float transparency)
+ // Head of dragDirection is in Quadrant 1.
+ if (dragDirection is { X: >= 0, Y: >= 0 })
{
- CharacterShadow.Color = transparency*Color.White;
- }
+ comparedAxis = Vector2.UnitX;
+ xDeg = FindAngleBetweenVector(ref dragDirection, ref comparedAxis);
+ comparedAxis = Vector2.UnitY;
+ yDeg = FindAngleBetweenVector(ref dragDirection, ref comparedAxis);
- ///
- /// Retrieve input from the user by his/her keyboard, and transform to one of the agent's input state.
- ///
- ///
- private InputState GetInputFromKeyboard()
- {
- if (Input.IsKeyPressed(Keys.Left))
- {
- return InputState.Left;
- }
- if (Input.IsKeyPressed(Keys.Right))
- {
- return InputState.Right;
- }
- if (Input.IsKeyPressed(Keys.Down))
- {
- return InputState.Down;
- }
- return InputState.None;
+ return xDeg <= yDeg ? InputState.Right : InputState.None;
}
- ///
- /// Retrieve input from the user by Drag gesture, and determine the input state by
- /// calculating the direction of drag by ProcessInputFromDragGesture().
- ///
- ///
- private InputState GetInputFromGesture()
+ // Head of dragDirection is in Quadrant 2.
+ if (dragDirection is { X: <= 0, Y: >= 0 })
{
- // Gesture recognition
- foreach (var gestureEvent in Input.GestureEvents)
- {
- // Select only Drag gesture with Began state.
- if (gestureEvent.Type == GestureType.Drag && gestureEvent.State == GestureState.Began)
- // From Draw gesture, determine the InputState from direction of the swipe.
- return ProcessInputFromDragGesture((GestureEventDrag)gestureEvent);
- }
-
- return InputState.None;
+ comparedAxis = -Vector2.UnitX;
+ xDeg = FindAngleBetweenVector(ref dragDirection, ref comparedAxis);
+ comparedAxis = Vector2.UnitY;
+ yDeg = FindAngleBetweenVector(ref dragDirection, ref comparedAxis);
+
+ return xDeg <= yDeg ? InputState.Left : InputState.None;
}
- ///
- /// Process gestureEvent to determine the input state.
- ///
- ///
- ///
- private InputState ProcessInputFromDragGesture(GestureEventDrag gestureEvent)
+ // Head of dragDirection is in Quadrant 3, check if the input is left or down.
+ if (dragDirection is { X: <= 0, Y: <= 0 })
{
- // Get drag vector and multiply by the screenRatio of the screen, also flip y (-screenRatio).
- var screenRatio = (float)GraphicsDevice.Presenter.BackBuffer.Height / GraphicsDevice.Presenter.BackBuffer.Width;
- var dragVector = (gestureEvent.CurrentPosition - gestureEvent.StartPosition) * new Vector2(1f, -screenRatio);
- var dragDirection = Vector2.Normalize(dragVector);
-
- Vector2 comparedAxis;
- float xDeg;
- float yDeg;
-
- // Head of dragDirection is in Quadrant 1.
- if (dragDirection.X >= 0 && dragDirection.Y >= 0)
- {
- comparedAxis = Vector2.UnitX;
- xDeg = FindAngleBetweenVector(ref dragDirection, ref comparedAxis);
- comparedAxis = Vector2.UnitY;
- yDeg = FindAngleBetweenVector(ref dragDirection, ref comparedAxis);
-
- return xDeg <= yDeg ? InputState.Right : InputState.None;
- }
-
- // Head of dragDirection is in Quadrant 2.
- if (dragDirection.X <= 0 && dragDirection.Y >= 0)
- {
- comparedAxis = -Vector2.UnitX;
- xDeg = FindAngleBetweenVector(ref dragDirection, ref comparedAxis);
- comparedAxis = Vector2.UnitY;
- yDeg = FindAngleBetweenVector(ref dragDirection, ref comparedAxis);
-
- return xDeg <= yDeg ? InputState.Left : InputState.None;
- }
-
- // Head of dragDirection is in Quadrant 3, check if the input is left or down.
- if (dragDirection.X <= 0 && dragDirection.Y <= 0)
- {
- comparedAxis = -Vector2.UnitX;
- xDeg = FindAngleBetweenVector(ref dragDirection, ref comparedAxis);
- comparedAxis = -Vector2.UnitY;
- yDeg = FindAngleBetweenVector(ref dragDirection, ref comparedAxis);
-
- return xDeg <= yDeg ? InputState.Left : InputState.Down;
- }
-
- // Head of dragDirection is in Quadrant 4, check if the input is right or down.
- comparedAxis = Vector2.UnitX;
+ comparedAxis = -Vector2.UnitX;
xDeg = FindAngleBetweenVector(ref dragDirection, ref comparedAxis);
comparedAxis = -Vector2.UnitY;
yDeg = FindAngleBetweenVector(ref dragDirection, ref comparedAxis);
- return xDeg <= yDeg ? InputState.Right : InputState.Down;
+ return xDeg <= yDeg ? InputState.Left : InputState.Down;
}
- private static float FindAngleBetweenVector(ref Vector2 v1, ref Vector2 v2)
+ // Head of dragDirection is in Quadrant 4, check if the input is right or down.
+ comparedAxis = Vector2.UnitX;
+ xDeg = FindAngleBetweenVector(ref dragDirection, ref comparedAxis);
+ comparedAxis = -Vector2.UnitY;
+ yDeg = FindAngleBetweenVector(ref dragDirection, ref comparedAxis);
+
+ return xDeg <= yDeg ? InputState.Right : InputState.Down;
+ }
+
+ private static float FindAngleBetweenVector(ref Vector2 v1, ref Vector2 v2)
+ {
+ Vector2.Dot(ref v1, ref v2, out var dotProd);
+ return (float)Math.Acos(dotProd);
+ }
+
+ ///
+ /// Process user's input, according to the current state.
+ /// It might change state of the agent.
+ ///
+ ///
+ private void ProcessInput(InputState currentInputState)
+ {
+ if (!shouldProcessInput)
+ return;
+
+ switch (currentInputState)
{
- float dotProd;
- Vector2.Dot(ref v1, ref v2, out dotProd);
- return (float)Math.Acos(dotProd);
+ case InputState.Left:
+ if (CurLane != LeftLane && State is AgentState.Run or AgentState.Slide)
+ State = AgentState.ChangeLaneLeft;
+ break;
+ case InputState.Right:
+ if (CurLane != RightLane && State is AgentState.Run or AgentState.Slide)
+ State = AgentState.ChangeLaneRight;
+ break;
+ case InputState.Down:
+ if (State == AgentState.Run)
+ State = AgentState.Slide;
+ break;
}
+ }
- ///
- /// Process user's input, according to the current state.
- /// It might change state of the agent.
- ///
- ///
- private void ProcessInput(InputState currentInputState)
+ ///
+ /// Invoke upon enter each state. It sets initial behaviour of the CharacterScript for that state.
+ ///
+ ///
+ private void OnEnter(AgentState agentState)
+ {
+ activeBoundingBox = (agentState == AgentState.Slide)
+ ? boundingBoxes[BoundingBoxKeys.Slide] :
+ boundingBoxes[BoundingBoxKeys.Normal];
+
+ switch (agentState)
{
- if (!shouldProcessInput)
- return;
-
- switch (currentInputState)
- {
- case InputState.Left:
- if (CurLane != LeftLane && (State == AgentState.Run|| State == AgentState.Slide))
- State = AgentState.ChangeLaneLeft;
- break;
- case InputState.Right:
- if (CurLane != RightLane && (State == AgentState.Run || State == AgentState.Slide))
- State = AgentState.ChangeLaneRight;
- break;
- case InputState.Down:
- if (State == AgentState.Run)
- State = AgentState.Slide;
- break;
- }
+ case AgentState.Run:
+ PlayAnimation(AgentAnimationKeys.Active);
+ break;
+ case AgentState.ChangeLaneLeft:
+ OnEnterChangeLane(true);
+ break;
+ case AgentState.ChangeLaneRight:
+ OnEnterChangeLane(false);
+ break;
+ case AgentState.Slide:
+ PlayAnimation(AgentAnimationKeys.Slide);
+ break;
+ case AgentState.Die:
+ PlayAnimation(AgentAnimationKeys.Crash);
+ break;
+ default:
+ throw new ArgumentOutOfRangeException(nameof(agentState));
}
+ }
- ///
- /// Invoke upon enter each state. It sets initial behaviour of the CharacterScript for that state.
- ///
- ///
- private void OnEnter(AgentState agentState)
+ ///
+ /// Upon Enter ChangeLane state, cache the start X position, and determine X position that will arrive for interpolation.
+ /// And play animation accordingly.
+ ///
+ ///
+ private void OnEnterChangeLane(bool isChangeLaneLeft)
+ {
+ if (isChangeLaneLeft)
{
- activeBoundingBox = (agentState == AgentState.Slide)
- ? boundingBoxes[BoundingBoxKeys.Slide] :
- boundingBoxes[BoundingBoxKeys.Normal];
-
- switch (agentState)
- {
- case AgentState.Run:
- PlayAnimation(AgentAnimationKeys.Active);
- break;
- case AgentState.ChangeLaneLeft:
- OnEnterChangeLane(true);
- break;
- case AgentState.ChangeLaneRight:
- OnEnterChangeLane(false);
- break;
- case AgentState.Slide:
- PlayAnimation(AgentAnimationKeys.Slide);
- break;
- case AgentState.Die:
- PlayAnimation(AgentAnimationKeys.Crash);
- break;
- default:
- throw new ArgumentOutOfRangeException("agentState");
- }
+ startChangeLanePosX = GetXPosition(CurLane--);
+ PlayAnimation(AgentAnimationKeys.DodgeLeft);
}
-
- ///
- /// Upon Enter ChangeLane state, cache the start X position, and determine X position that will arrive for interpolation.
- /// And play animation accordingly.
- ///
- ///
- private void OnEnterChangeLane(bool isChangeLaneLeft)
+ else
{
- if (isChangeLaneLeft)
- {
- startChangeLanePosX = GetXPosition(CurLane--);
- PlayAnimation(AgentAnimationKeys.DodgeLeft);
- }
- else
- {
- startChangeLanePosX = GetXPosition(CurLane++);
- PlayAnimation(AgentAnimationKeys.DodgeRight);
- }
-
- targetChangeLanePosX = GetXPosition(CurLane);
+ startChangeLanePosX = GetXPosition(CurLane++);
+ PlayAnimation(AgentAnimationKeys.DodgeRight);
}
- ///
- /// UpdateState updates the agent according to its state.
- ///
- private void UpdateState()
+ targetChangeLanePosX = GetXPosition(CurLane);
+ }
+
+ ///
+ /// UpdateState updates the agent according to its state.
+ ///
+ private void UpdateState()
+ {
+ switch (State)
{
- switch (State)
- {
- case AgentState.ChangeLaneLeft:
- case AgentState.ChangeLaneRight:
- UpdateChangeLane();
- break;
- case AgentState.Slide:
- if (playingAnimation.CurrentTime.TotalSeconds >= playingAnimation.Clip.Duration.TotalSeconds)
- State = AgentState.Run;
- break;
- }
+ case AgentState.ChangeLaneLeft:
+ case AgentState.ChangeLaneRight:
+ UpdateChangeLane();
+ break;
+ case AgentState.Slide:
+ if (playingAnimation.CurrentTime.TotalSeconds >= playingAnimation.Clip.Duration.TotalSeconds)
+ State = AgentState.Run;
+ break;
}
- ///
- /// In ChangeLane state, the agent's X position is determined by Linear interpolation of the current animation process.
- ///
- private void UpdateChangeLane()
- {
- var t = (float)(playingAnimation.CurrentTime.TotalSeconds / playingAnimation.Clip.Duration.TotalSeconds);
+ }
+ ///
+ /// In ChangeLane state, the agent's X position is determined by Linear interpolation of the current animation process.
+ ///
+ private void UpdateChangeLane()
+ {
+ var t = (float)(playingAnimation.CurrentTime.TotalSeconds / playingAnimation.Clip.Duration.TotalSeconds);
- // Interpolate new X position in World coordinate.
- var newPosX = MathUtil.Lerp(startChangeLanePosX, targetChangeLanePosX, t);
- Entity.Transform.Position.X = newPosX;
+ // Interpolate new X position in World coordinate.
+ var newPosX = MathUtil.Lerp(startChangeLanePosX, targetChangeLanePosX, t);
+ Entity.Transform.Position.X = newPosX;
- // Animation ends, changing state.
- if (t >= 1.0f)
- State = AgentState.Run;
- }
+ // Animation ends, changing state.
+ if (t >= 1.0f)
+ State = AgentState.Run;
+ }
- ///
- /// Helper function for playing animation given AgentAnimationKey.
- ///
- ///
- private void PlayAnimation(AgentAnimationKeys key)
- {
- var animationComponent = Entity.Get();
-
- animationComponent.Play(key.ToString());
- playingAnimation = animationComponent.PlayingAnimations[0];
- }
+ ///
+ /// Helper function for playing animation given AgentAnimationKey.
+ ///
+ ///
+ private void PlayAnimation(AgentAnimationKeys key)
+ {
+ var animationComponent = Entity.Get();
+
+ animationComponent.Play(key.ToString());
+ playingAnimation = animationComponent.PlayingAnimations[0];
+ }
- ///
- /// Returns world position in X axis for the giving lane index.
- ///
- ///
- ///
- private static float GetXPosition(int lane)
- {
- return (1 - lane) * LaneLength;
- }
+ ///
+ /// Returns world position in X axis for the giving lane index.
+ ///
+ ///
+ ///
+ private static float GetXPosition(int lane)
+ {
+ return (1 - lane) * LaneLength;
}
}
diff --git a/samples/Games/SpaceEscape/SpaceEscape.Game/Effects/CustomFogEffect.sdsl.cs b/samples/Games/SpaceEscape/SpaceEscape.Game/Effects/CustomFogEffect.sdsl.cs
index dacdbdaad0..7cab7e81fa 100644
--- a/samples/Games/SpaceEscape/SpaceEscape.Game/Effects/CustomFogEffect.sdsl.cs
+++ b/samples/Games/SpaceEscape/SpaceEscape.Game/Effects/CustomFogEffect.sdsl.cs
@@ -1,4 +1,4 @@
-//
+//
// Do not edit this file yourself!
//
// This code was generated by Stride Shader Mixin Code Generator.
@@ -14,14 +14,13 @@
using Stride.Core.Mathematics;
using Buffer = Stride.Graphics.Buffer;
-namespace Stride.Rendering
+namespace Stride.Rendering;
+
+public static partial class CustomFogEffectKeys
{
- public static partial class CustomFogEffectKeys
- {
- public static readonly ValueParameterKey FogColor = ParameterKeys.NewValue(new Color4(1,1,1,1));
- public static readonly ValueParameterKey fogNearPlaneZ = ParameterKeys.NewValue(80.0f);
- public static readonly ValueParameterKey fogFarPlaneZ = ParameterKeys.NewValue(250.0f);
- public static readonly ValueParameterKey fogNearPlaneY = ParameterKeys.NewValue(0.0f);
- public static readonly ValueParameterKey fogFarPlaneY = ParameterKeys.NewValue(120.0f);
- }
+ public static readonly ValueParameterKey FogColor = ParameterKeys.NewValue(new Color4(1,1,1,1));
+ public static readonly ValueParameterKey fogNearPlaneZ = ParameterKeys.NewValue(80.0f);
+ public static readonly ValueParameterKey fogFarPlaneZ = ParameterKeys.NewValue(250.0f);
+ public static readonly ValueParameterKey fogNearPlaneY = ParameterKeys.NewValue(0.0f);
+ public static readonly ValueParameterKey fogFarPlaneY = ParameterKeys.NewValue(120.0f);
}
diff --git a/samples/Games/SpaceEscape/SpaceEscape.Game/Effects/SpaceEscapeEffectMain.sdfx.cs b/samples/Games/SpaceEscape/SpaceEscape.Game/Effects/SpaceEscapeEffectMain.sdfx.cs
index e27e736cc5..4f902e22ba 100644
--- a/samples/Games/SpaceEscape/SpaceEscape.Game/Effects/SpaceEscapeEffectMain.sdfx.cs
+++ b/samples/Games/SpaceEscape/SpaceEscape.Game/Effects/SpaceEscapeEffectMain.sdfx.cs
@@ -1,4 +1,4 @@
-//
+//
// Do not edit this file yourself!
//
// This code was generated by Stride Shader Mixin Code Generator.
@@ -14,35 +14,34 @@
using Stride.Core.Mathematics;
using Buffer = Stride.Graphics.Buffer;
-namespace SpaceEscape.Effects
+namespace SpaceEscape.Effects;
+
+[DataContract]public partial class GameParameters : ShaderMixinParameters
{
- [DataContract]public partial class GameParameters : ShaderMixinParameters
- {
- public static readonly PermutationParameterKey EnableFog = ParameterKeys.NewPermutation(true);
- public static readonly PermutationParameterKey EnableBend = ParameterKeys.NewPermutation(true);
- public static readonly PermutationParameterKey EnableOnflyTextureUVChange = ParameterKeys.NewPermutation(false);
- };
- internal static partial class ShaderMixins
+ public static readonly PermutationParameterKey EnableFog = ParameterKeys.NewPermutation(true);
+ public static readonly PermutationParameterKey EnableBend = ParameterKeys.NewPermutation(true);
+ public static readonly PermutationParameterKey EnableOnflyTextureUVChange = ParameterKeys.NewPermutation(false);
+};
+internal static partial class ShaderMixins
+{
+ internal partial class SpaceEscapeEffectMain : IShaderMixinBuilder
{
- internal partial class SpaceEscapeEffectMain : IShaderMixinBuilder
+ public void Generate(ShaderMixinSource mixin, ShaderMixinContext context)
{
- public void Generate(ShaderMixinSource mixin, ShaderMixinContext context)
- {
- context.Mixin(mixin, "StrideForwardShadingEffect");
- if (context.GetParam(GameParameters.EnableOnflyTextureUVChange))
- context.Mixin(mixin, "TransformationTextureUV");
- if (context.GetParam(GameParameters.EnableBend))
- context.Mixin(mixin, "TransformationBendWorld");
- if (context.GetParam(GameParameters.EnableFog))
- context.Mixin(mixin, "CustomFogEffect");
- }
+ context.Mixin(mixin, "StrideForwardShadingEffect");
+ if (context.GetParam(GameParameters.EnableOnflyTextureUVChange))
+ context.Mixin(mixin, "TransformationTextureUV");
+ if (context.GetParam(GameParameters.EnableBend))
+ context.Mixin(mixin, "TransformationBendWorld");
+ if (context.GetParam(GameParameters.EnableFog))
+ context.Mixin(mixin, "CustomFogEffect");
+ }
- [ModuleInitializer]
- internal static void __Initialize__()
+ [ModuleInitializer]
+ internal static void __Initialize__()
- {
- ShaderMixinManager.Register("SpaceEscapeEffectMain", new SpaceEscapeEffectMain());
- }
+ {
+ ShaderMixinManager.Register("SpaceEscapeEffectMain", new SpaceEscapeEffectMain());
}
}
}
diff --git a/samples/Games/SpaceEscape/SpaceEscape.Game/Effects/TransformationBendWorld.sdsl.cs b/samples/Games/SpaceEscape/SpaceEscape.Game/Effects/TransformationBendWorld.sdsl.cs
index a101da0495..6841833ad1 100644
--- a/samples/Games/SpaceEscape/SpaceEscape.Game/Effects/TransformationBendWorld.sdsl.cs
+++ b/samples/Games/SpaceEscape/SpaceEscape.Game/Effects/TransformationBendWorld.sdsl.cs
@@ -1,4 +1,4 @@
-//
+//
// Do not edit this file yourself!
//
// This code was generated by Stride Shader Mixin Code Generator.
@@ -14,11 +14,10 @@
using Stride.Core.Mathematics;
using Buffer = Stride.Graphics.Buffer;
-namespace Stride.Rendering
+namespace Stride.Rendering;
+
+public static partial class TransformationBendWorldKeys
{
- public static partial class TransformationBendWorldKeys
- {
- public static readonly ValueParameterKey DeformFactorX = ParameterKeys.NewValue(-0.001f);
- public static readonly ValueParameterKey DeformFactorY = ParameterKeys.NewValue(-0.0006f);
- }
+ public static readonly ValueParameterKey DeformFactorX = ParameterKeys.NewValue(-0.001f);
+ public static readonly ValueParameterKey DeformFactorY = ParameterKeys.NewValue(-0.0006f);
}
diff --git a/samples/Games/SpaceEscape/SpaceEscape.Game/Effects/TransformationTextureUV.sdsl.cs b/samples/Games/SpaceEscape/SpaceEscape.Game/Effects/TransformationTextureUV.sdsl.cs
index 8a174442f7..c5cea0d1a6 100644
--- a/samples/Games/SpaceEscape/SpaceEscape.Game/Effects/TransformationTextureUV.sdsl.cs
+++ b/samples/Games/SpaceEscape/SpaceEscape.Game/Effects/TransformationTextureUV.sdsl.cs
@@ -1,4 +1,4 @@
-//
+//
// Do not edit this file yourself!
//
// This code was generated by Stride Shader Mixin Code Generator.
@@ -14,10 +14,9 @@
using Stride.Core.Mathematics;
using Buffer = Stride.Graphics.Buffer;
-namespace Stride.Rendering
+namespace Stride.Rendering;
+
+public static partial class TransformationTextureUVKeys
{
- public static partial class TransformationTextureUVKeys
- {
- public static readonly ValueParameterKey TextureRegion = ParameterKeys.NewValue(new Vector4(0,0,1,1));
- }
+ public static readonly ValueParameterKey TextureRegion = ParameterKeys.NewValue(new Vector4(0,0,1,1));
}
diff --git a/samples/Games/SpaceEscape/SpaceEscape.Game/GameScript.cs b/samples/Games/SpaceEscape/SpaceEscape.Game/GameScript.cs
index 08711f9690..1621ce875c 100644
--- a/samples/Games/SpaceEscape/SpaceEscape.Game/GameScript.cs
+++ b/samples/Games/SpaceEscape/SpaceEscape.Game/GameScript.cs
@@ -1,131 +1,126 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
-using System;
-using Stride.Core.Mathematics;
-using Stride.Engine;
-using Stride.Rendering;
using SpaceEscape.Background;
+using Stride.Engine;
-namespace SpaceEscape
+namespace SpaceEscape;
+
+///
+/// GameScript manages all entities in the game: Camera, CharacterScript, BackgroundScript and Obstacles.
+///
+public class GameScript : SyncScript
{
///
- /// GameScript manages all entities in the game: Camera, CharacterScript, BackgroundScript and Obstacles.
+ /// The reference to the character script
+ ///
+ public CharacterScript CharacterScript;
+
+ ///
+ /// The reference to the background script
+ ///
+ public BackgroundScript BackgroundScript;
+
+ ///
+ /// The reference to the UI script
+ ///
+ public UIScript UIScript;
+
+ public override void Start()
+ {
+ // Enable visual of mouse in the game
+ Game.Window.IsMouseVisible = true;
+
+ // Update the distance displayed in the UI
+ BackgroundScript.DistanceUpdated += SetDistanceInUI;
+
+ // set behavior of UI button
+ UIScript.StartButton.Click += StartGame;
+ UIScript.RetryButton.Click += RestartGame;
+ UIScript.MenuButton.Click += GoToMenu;
+
+ GoToMenu(this, EventArgs.Empty);
+ }
+
+ ///
+ /// Script update loop that detect collision between CharacterScript an obstacles,
+ /// and detect if the CharacterScript falls to any hole.
+ ///
+ ///
+ public override void Update()
+ {
+ if (CharacterScript.IsDead)
+ return;
+
+ var agentBoundingBox = CharacterScript.CalculateCurrentBoundingBox();
+
+ // Detect collision between agents and real-world obstacles.
+ if (BackgroundScript.DetectCollisions(ref agentBoundingBox))
+ KillAgent(0);
+
+ // Detect if the CharacterScript falls into a hole
+ if (BackgroundScript.DetectHoles(ref CharacterScript.Entity.Transform.Position, out var floorHeight))
+ KillAgent(floorHeight);
+ }
+
+ public override void Cancel()
+ {
+ BackgroundScript.DistanceUpdated -= SetDistanceInUI;
+
+ UIScript.StartButton.Click -= StartGame;
+ UIScript.RetryButton.Click -= RestartGame;
+ UIScript.MenuButton.Click -= GoToMenu;
+ }
+
+ private void SetDistanceInUI(float curDist)
+ {
+ UIScript.SetDistance((int)curDist);
+ }
+
+ ///
+ /// Kills the player.
+ ///
+ private void KillAgent(float height)
+ {
+ CharacterScript.OnDied(height);
+ UIScript.StartGameOverMode();
+ BackgroundScript.StopScrolling();
+ }
+
+ ///
+ /// Reset game's entities: CharacterScript and LevelBlocks.
+ ///
+ private void ResetGame()
+ {
+ CharacterScript.Reset();
+ BackgroundScript.Reset();
+ }
+
+ ///
+ /// Restart playing
+ ///
+ private void RestartGame(object sender, EventArgs args)
+ {
+ ResetGame();
+ StartGame(sender, args);
+ }
+
+ ///
+ /// Start playing
+ ///
+ private void StartGame(object sender, EventArgs args)
+ {
+ UIScript.StartPlayMode();
+ BackgroundScript.StartScrolling();
+ CharacterScript.Activate();
+ }
+
+ ///
+ /// Go to the menu screen
///
- public class GameScript : SyncScript
+ private void GoToMenu(object sender, EventArgs args)
{
- ///
- /// The reference to the character script
- ///
- public CharacterScript CharacterScript;
-
- ///
- /// The reference to the background script
- ///
- public BackgroundScript BackgroundScript;
-
- ///
- /// The reference to the UI script
- ///
- public UIScript UIScript;
-
- public override void Start()
- {
- // Enable visual of mouse in the game
- Game.Window.IsMouseVisible = true;
-
- // Update the distance displayed in the UI
- BackgroundScript.DistanceUpdated += SetDistanceInUI;
-
- // set behavior of UI button
- UIScript.StartButton.Click += StartGame;
- UIScript.RetryButton.Click += RestartGame;
- UIScript.MenuButton.Click += GoToMenu;
-
- GoToMenu(this, EventArgs.Empty);
- }
-
- ///
- /// Script update loop that detect collision between CharacterScript an obstacles,
- /// and detect if the CharacterScript falls to any hole.
- ///
- ///
- public override void Update()
- {
- if (CharacterScript.IsDead)
- return;
-
- float floorHeight;
- var agentBoundingBox = CharacterScript.CalculateCurrentBoundingBox();
-
- // Detect collision between agents and real-world obstacles.
- if (BackgroundScript.DetectCollisions(ref agentBoundingBox))
- KillAgent(0);
-
- // Detect if the CharacterScript falls into a hole
- if (BackgroundScript.DetectHoles(ref CharacterScript.Entity.Transform.Position, out floorHeight))
- KillAgent(floorHeight);
- }
-
- public override void Cancel()
- {
- BackgroundScript.DistanceUpdated -= SetDistanceInUI;
-
- UIScript.StartButton.Click -= StartGame;
- UIScript.RetryButton.Click -= RestartGame;
- UIScript.MenuButton.Click -= GoToMenu;
- }
-
- private void SetDistanceInUI(float curDist)
- {
- UIScript.SetDistance((int)curDist);
- }
-
- ///
- /// Kills the player.
- ///
- private void KillAgent(float height)
- {
- CharacterScript.OnDied(height);
- UIScript.StartGameOverMode();
- BackgroundScript.StopScrolling();
- }
-
- ///
- /// Reset game's entities: CharacterScript and LevelBlocks.
- ///
- private void ResetGame()
- {
- CharacterScript.Reset();
- BackgroundScript.Reset();
- }
-
- ///
- /// Restart playing
- ///
- private void RestartGame(object sender, EventArgs args)
- {
- ResetGame();
- StartGame(sender, args);
- }
-
- ///
- /// Start playing
- ///
- private void StartGame(object sender, EventArgs args)
- {
- UIScript.StartPlayMode();
- BackgroundScript.StartScrolling();
- CharacterScript.Activate();
- }
-
- ///
- /// Go to the menu screen
- ///
- private void GoToMenu(object sender, EventArgs args)
- {
- UIScript.StartMainMenuMode();
- ResetGame();
- }
+ UIScript.StartMainMenuMode();
+ ResetGame();
}
}
diff --git a/samples/Games/SpaceEscape/SpaceEscape.Game/PlayIdleAnimationScript.cs b/samples/Games/SpaceEscape/SpaceEscape.Game/PlayIdleAnimationScript.cs
index 00b7bcb11d..8a72059a80 100644
--- a/samples/Games/SpaceEscape/SpaceEscape.Game/PlayIdleAnimationScript.cs
+++ b/samples/Games/SpaceEscape/SpaceEscape.Game/PlayIdleAnimationScript.cs
@@ -1,21 +1,21 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
+
using Stride.Engine;
-namespace SpaceEscape
+namespace SpaceEscape;
+
+///
+/// Plays the idle animation of the entity if any
+///
+public class PlayAnimationScript : StartupScript
{
- ///
- /// Plays the idle animation of the entity if any
- ///
- public class PlayAnimationScript : StartupScript
- {
- public string AnimationName;
+ public string AnimationName;
- public override void Start()
- {
- var animation = Entity.Get();
- if (animation != null)
- animation.Play(AnimationName);
- }
+ public override void Start()
+ {
+ var animation = Entity.Get();
+ if (animation != null)
+ animation.Play(AnimationName);
}
}
diff --git a/samples/Games/SpaceEscape/SpaceEscape.Game/Rendering/BendFogRenderFeature.cs b/samples/Games/SpaceEscape/SpaceEscape.Game/Rendering/BendFogRenderFeature.cs
index ad84250825..6785786e4b 100644
--- a/samples/Games/SpaceEscape/SpaceEscape.Game/Rendering/BendFogRenderFeature.cs
+++ b/samples/Games/SpaceEscape/SpaceEscape.Game/Rendering/BendFogRenderFeature.cs
@@ -1,125 +1,118 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+
+using SpaceEscape.Effects;
using Stride.Core.Mathematics;
-using Stride.Graphics;
using Stride.Rendering;
-using Stride.Rendering.Materials;
-using SpaceEscape.Effects;
-namespace SpaceEscape.Rendering
+namespace SpaceEscape.Rendering;
+
+///
+/// Custom render feature, that uploads constants needed by the SpaceEscapeEffectMain effect
+///
+public class BendFogRenderFeature : SubRenderFeature
{
- ///
- /// Custom render feature, that uploads constants needed by the SpaceEscapeEffectMain effect
- ///
- public class BendFogRenderFeature : SubRenderFeature
- {
- private StaticObjectPropertyKey renderEffectKey;
+ private StaticObjectPropertyKey renderEffectKey;
- private ConstantBufferOffsetReference fog;
- private ConstantBufferOffsetReference bend;
- private ConstantBufferOffsetReference uvChange;
+ private ConstantBufferOffsetReference fog;
+ private ConstantBufferOffsetReference bend;
+ private ConstantBufferOffsetReference uvChange;
- // Constant buffer layout for CustomFogEffect
- private struct PerDrawFog
- {
- public Color4 FogColor;
+ // Constant buffer layout for CustomFogEffect
+ private struct PerDrawFog
+ {
+ public Color4 FogColor;
- public float fogNearPlaneZ;
- public float fogFarPlaneZ;
+ public float fogNearPlaneZ;
+ public float fogFarPlaneZ;
- public float fogNearPlaneY;
- public float fogFarPlaneY;
- }
+ public float fogNearPlaneY;
+ public float fogFarPlaneY;
+ }
- ///
- protected override void InitializeCore()
- {
- base.InitializeCore();
+ ///
+ protected override void InitializeCore()
+ {
+ base.InitializeCore();
- renderEffectKey = ((RootEffectRenderFeature)RootRenderFeature).RenderEffectKey;
+ renderEffectKey = ((RootEffectRenderFeature)RootRenderFeature).RenderEffectKey;
- fog = ((RootEffectRenderFeature)RootRenderFeature).CreateDrawCBufferOffsetSlot(CustomFogEffectKeys.FogColor.Name);
- bend = ((RootEffectRenderFeature)RootRenderFeature).CreateDrawCBufferOffsetSlot(TransformationBendWorldKeys.DeformFactorX.Name);
- uvChange = ((RootEffectRenderFeature)RootRenderFeature).CreateDrawCBufferOffsetSlot(TransformationTextureUVKeys.TextureRegion.Name);
- }
+ fog = ((RootEffectRenderFeature)RootRenderFeature).CreateDrawCBufferOffsetSlot(CustomFogEffectKeys.FogColor.Name);
+ bend = ((RootEffectRenderFeature)RootRenderFeature).CreateDrawCBufferOffsetSlot(TransformationBendWorldKeys.DeformFactorX.Name);
+ uvChange = ((RootEffectRenderFeature)RootRenderFeature).CreateDrawCBufferOffsetSlot(TransformationTextureUVKeys.TextureRegion.Name);
+ }
+
+ ///
+ public override void PrepareEffectPermutations(RenderDrawContext context)
+ {
+ var renderEffects = RootRenderFeature.RenderData.GetData(renderEffectKey);
+ int effectSlotCount = ((RootEffectRenderFeature)RootRenderFeature).EffectPermutationSlotCount;
- ///
- public override void PrepareEffectPermutations(RenderDrawContext context)
+ foreach (var renderObject in RootRenderFeature.RenderObjects)
{
- var renderEffects = RootRenderFeature.RenderData.GetData(renderEffectKey);
- int effectSlotCount = ((RootEffectRenderFeature)RootRenderFeature).EffectPermutationSlotCount;
+ var staticObjectNode = renderObject.StaticObjectNode;
+ var renderMesh = (RenderMesh)renderObject;
- foreach (var renderObject in RootRenderFeature.RenderObjects)
+ for (int i = 0; i < effectSlotCount; ++i)
{
- var staticObjectNode = renderObject.StaticObjectNode;
- var renderMesh = (RenderMesh)renderObject;
+ var staticEffectObjectNode = staticObjectNode * effectSlotCount + i;
+ var renderEffect = renderEffects[staticEffectObjectNode];
- for (int i = 0; i < effectSlotCount; ++i)
- {
- var staticEffectObjectNode = staticObjectNode * effectSlotCount + i;
- var renderEffect = renderEffects[staticEffectObjectNode];
-
- // Skip effects not used during this frame
- if (renderEffect == null || !renderEffect.IsUsedDuringThisFrame(RenderSystem))
- continue;
-
- // Generate shader permuatations
- renderEffect.EffectValidator.ValidateParameter(GameParameters.EnableBend, renderMesh.Mesh.Parameters.Get(GameParameters.EnableBend));
- renderEffect.EffectValidator.ValidateParameter(GameParameters.EnableFog, renderMesh.Mesh.Parameters.Get(GameParameters.EnableFog));
- renderEffect.EffectValidator.ValidateParameter(GameParameters.EnableOnflyTextureUVChange, renderMesh.Mesh.Parameters.Get(GameParameters.EnableOnflyTextureUVChange));
- }
+ // Skip effects not used during this frame
+ if (renderEffect == null || !renderEffect.IsUsedDuringThisFrame(RenderSystem))
+ continue;
+
+ // Generate shader permuatations
+ renderEffect.EffectValidator.ValidateParameter(GameParameters.EnableBend, renderMesh.Mesh.Parameters.Get(GameParameters.EnableBend));
+ renderEffect.EffectValidator.ValidateParameter(GameParameters.EnableFog, renderMesh.Mesh.Parameters.Get(GameParameters.EnableFog));
+ renderEffect.EffectValidator.ValidateParameter(GameParameters.EnableOnflyTextureUVChange, renderMesh.Mesh.Parameters.Get(GameParameters.EnableOnflyTextureUVChange));
}
}
+ }
- ///
- public override unsafe void Prepare(RenderDrawContext context)
+ ///
+ public override unsafe void Prepare(RenderDrawContext context)
+ {
+ foreach (var renderNode in ((RootEffectRenderFeature)RootRenderFeature).RenderNodes)
{
- foreach (var renderNode in ((RootEffectRenderFeature)RootRenderFeature).RenderNodes)
- {
- var perDrawLayout = renderNode.RenderEffect.Reflection.PerDrawLayout;
- if (perDrawLayout == null)
- continue;
+ var perDrawLayout = renderNode.RenderEffect.Reflection.PerDrawLayout;
+ if (perDrawLayout == null)
+ continue;
- var mappedCB = renderNode.Resources.ConstantBuffer.Data;
- var renderMesh = (RenderMesh)renderNode.RenderObject;
- var parameters = renderMesh.Mesh.Parameters;
+ var mappedCB = renderNode.Resources.ConstantBuffer.Data;
+ var renderMesh = (RenderMesh)renderNode.RenderObject;
+ var parameters = renderMesh.Mesh.Parameters;
- // Upload fog parameters
- var fogOffset = perDrawLayout.GetConstantBufferOffset(fog);
- if (fogOffset != -1)
- {
- var perDraw = (PerDrawFog*)((byte*)mappedCB + fogOffset);
- *perDraw = new PerDrawFog
- {
- FogColor = Color.FromAbgr(0xFF7D02FF),
- fogNearPlaneZ = 80.0f,
- fogFarPlaneZ = 250.0f,
- fogNearPlaneY = 0.0f,
- fogFarPlaneY = 120.0f
- };
- }
-
- // Upload world bending parameters
- var bendOffset = perDrawLayout.GetConstantBufferOffset(bend);
- if (bendOffset != -1)
- {
- var perDraw = (float*)((byte*)mappedCB + bendOffset);
- *perDraw++ = parameters.Get(TransformationBendWorldKeys.DeformFactorX);
- *perDraw = parameters.Get(TransformationBendWorldKeys.DeformFactorX);
- }
-
- // Updload uv change parameters
- var uvChangeOffset = perDrawLayout.GetConstantBufferOffset(uvChange);
- if (uvChangeOffset != -1)
+ // Upload fog parameters
+ var fogOffset = perDrawLayout.GetConstantBufferOffset(fog);
+ if (fogOffset != -1)
+ {
+ var perDraw = (PerDrawFog*)((byte*)mappedCB + fogOffset);
+ *perDraw = new PerDrawFog
{
- var perDraw = (Vector4*)((byte*)mappedCB + uvChangeOffset);
- *perDraw = parameters.Get(TransformationTextureUVKeys.TextureRegion);
- }
+ FogColor = Color.FromAbgr(0xFF7D02FF),
+ fogNearPlaneZ = 80.0f,
+ fogFarPlaneZ = 250.0f,
+ fogNearPlaneY = 0.0f,
+ fogFarPlaneY = 120.0f
+ };
+ }
+
+ // Upload world bending parameters
+ var bendOffset = perDrawLayout.GetConstantBufferOffset(bend);
+ if (bendOffset != -1)
+ {
+ var perDraw = (float*)((byte*)mappedCB + bendOffset);
+ *perDraw++ = parameters.Get(TransformationBendWorldKeys.DeformFactorX);
+ *perDraw = parameters.Get(TransformationBendWorldKeys.DeformFactorX);
+ }
+
+ // Updload uv change parameters
+ var uvChangeOffset = perDrawLayout.GetConstantBufferOffset(uvChange);
+ if (uvChangeOffset != -1)
+ {
+ var perDraw = (Vector4*)((byte*)mappedCB + uvChangeOffset);
+ *perDraw = parameters.Get(TransformationTextureUVKeys.TextureRegion);
}
}
}
diff --git a/samples/Games/SpaceEscape/SpaceEscape.Game/SpaceEscape.Game.csproj b/samples/Games/SpaceEscape/SpaceEscape.Game/SpaceEscape.Game.csproj
index c4fdb3c021..3f8120c249 100644
--- a/samples/Games/SpaceEscape/SpaceEscape.Game/SpaceEscape.Game.csproj
+++ b/samples/Games/SpaceEscape/SpaceEscape.Game/SpaceEscape.Game.csproj
@@ -3,6 +3,8 @@
net8.0
SpaceEscape
true
+ enable
+ latest
diff --git a/samples/Games/SpaceEscape/SpaceEscape.Game/UIScript.cs b/samples/Games/SpaceEscape/SpaceEscape.Game/UIScript.cs
index 73a35f5d0f..f5c716862c 100644
--- a/samples/Games/SpaceEscape/SpaceEscape.Game/UIScript.cs
+++ b/samples/Games/SpaceEscape/SpaceEscape.Game/UIScript.cs
@@ -1,5 +1,6 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
+
using Stride.Core;
using Stride.Core.Mathematics;
using Stride.Engine;
@@ -9,174 +10,173 @@
using Stride.UI.Controls;
using Stride.UI.Panels;
-namespace SpaceEscape
+namespace SpaceEscape;
+
+///
+/// UIScript manages UIElements using in the game.
+/// At one time UI.RootElement is one of each root which corresponding to each state of the game.
+///
+/// It provides a ButtonClickedEvent Action that could be subscribed by its user.
+/// This action provides the name of Button element that is clicked,
+/// which is one of {StartButton, MenuBotton and RestartButton}
+///
+public class UIScript : StartupScript
{
+ internal Button StartButton { get; private set; }
+ internal Button MenuButton { get; private set; }
+ internal Button RetryButton { get; private set; }
+
+ public SpriteFont Font;
+ public SpriteSheet UIImages;
+
+ private ModalElement mainMenuRoot;
+ private Canvas gameRoot;
+ private ModalElement gameOverRoot;
+
+ private TextBlock distanceTextBlock;
+ private ISpriteProvider buttonImage;
+
///
- /// UIScript manages UIElements using in the game.
- /// At one time UI.RootElement is one of each root which corresponding to each state of the game.
- ///
- /// It provides a ButtonClickedEvent Action that could be subscribed by its user.
- /// This action provides the name of Button element that is clicked,
- /// which is one of {StartButton, MenuBotton and RestartButton}
+ /// Load resource and construct ui components
///
- public class UIScript : StartupScript
+ public override void Start()
{
- internal Button StartButton { get; private set; }
- internal Button MenuButton { get; private set; }
- internal Button RetryButton { get; private set; }
-
- public SpriteFont Font;
- public SpriteSheet UIImages;
+ base.Start();
+
+ // Load resources shared by different UI screens
+ buttonImage = SpriteFromSheet.Create(UIImages, "button");
+
+ // Load and create specific UI screens.
+ CreateMainMenuUI();
+ CreateGameUI();
+ CreateGameOverUI();
+ }
- private ModalElement mainMenuRoot;
- private Canvas gameRoot;
- private ModalElement gameOverRoot;
+ private void CreateMainMenuUI()
+ {
+ var strideLogo = new ImageElement { Source = SpriteFromSheet.Create(UIImages, "sd_logo") };
- private TextBlock distanceTextBlock;
- private ISpriteProvider buttonImage;
+ strideLogo.SetCanvasPinOrigin(new Vector3(0.5f, 0.5f, 1f));
+ strideLogo.SetCanvasRelativeSize(new Vector3(0.8f, 0.5f, 1f));
+ strideLogo.SetCanvasRelativePosition(new Vector3(0.5f, 0.3f, 1f));
- ///
- /// Load resource and construct ui components
- ///
- public override void Start()
- {
- base.Start();
-
- // Load resources shared by different UI screens
- buttonImage = SpriteFromSheet.Create(UIImages, "button");
-
- // Load and create specific UI screens.
- CreateMainMenuUI();
- CreateGameUI();
- CreateGameOverUI();
- }
-
- private void CreateMainMenuUI()
- {
- var strideLogo = new ImageElement { Source = SpriteFromSheet.Create(UIImages, "sd_logo") };
-
- strideLogo.SetCanvasPinOrigin(new Vector3(0.5f, 0.5f, 1f));
- strideLogo.SetCanvasRelativeSize(new Vector3(0.8f, 0.5f, 1f));
- strideLogo.SetCanvasRelativePosition(new Vector3(0.5f, 0.3f, 1f));
-
- StartButton = new Button
- {
- Content = new TextBlock { Font = Font, Text = "Touch to Start", TextColor = Color.Black,
- HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Center},
- NotPressedImage = buttonImage,
- PressedImage = buttonImage,
- MouseOverImage = buttonImage,
- Padding = new Thickness(80, 27, 25, 35),
- MinimumWidth = 250f,
- };
-
- StartButton.SetCanvasPinOrigin(new Vector3(0.5f, 0.5f, 1f));
- StartButton.SetCanvasRelativePosition(new Vector3(0.5f, 0.8f, 0f));
-
- var mainMenuCanvas = new Canvas();
- mainMenuCanvas.Children.Add(strideLogo);
- mainMenuCanvas.Children.Add(StartButton);
-
- mainMenuRoot = new ModalElement
- {
- HorizontalAlignment = HorizontalAlignment.Stretch,
- VerticalAlignment = VerticalAlignment.Stretch,
- Content = mainMenuCanvas
- };
- }
-
- private void CreateGameUI()
+ StartButton = new Button
{
- distanceTextBlock = new TextBlock { Font = Font, TextColor = Color.Gold, VerticalAlignment = VerticalAlignment.Center };
- distanceTextBlock.SetCanvasPinOrigin(new Vector3(0.5f, 0.5f, 1f));
- distanceTextBlock.SetCanvasRelativePosition(new Vector3(0.2f, 0.05f, 0f));
-
- var scoreBoard = new ContentDecorator
- {
- BackgroundImage = SpriteFromSheet.Create(UIImages, "distance_bg"),
- Content = distanceTextBlock,
- Padding = new Thickness(60, 31, 25, 35),
- MinimumWidth = 290f // Set the minimum width of score button so that it wont modify when the content (text) changes, and less than minimum.
- };
-
- gameRoot = new Canvas();
- gameRoot.Children.Add(scoreBoard);
- }
-
- private void CreateGameOverUI()
+ Content = new TextBlock { Font = Font, Text = "Touch to Start", TextColor = Color.Black,
+ HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Center},
+ NotPressedImage = buttonImage,
+ PressedImage = buttonImage,
+ MouseOverImage = buttonImage,
+ Padding = new Thickness(80, 27, 25, 35),
+ MinimumWidth = 250f,
+ };
+
+ StartButton.SetCanvasPinOrigin(new Vector3(0.5f, 0.5f, 1f));
+ StartButton.SetCanvasRelativePosition(new Vector3(0.5f, 0.8f, 0f));
+
+ var mainMenuCanvas = new Canvas();
+ mainMenuCanvas.Children.Add(strideLogo);
+ mainMenuCanvas.Children.Add(StartButton);
+
+ mainMenuRoot = new ModalElement
{
- MenuButton = new Button
- {
- Content = new TextBlock { Font = Font, Text = "Menu", TextColor = Color.Black,
- HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Center},
- PressedImage = buttonImage,
- NotPressedImage = buttonImage,
- MouseOverImage = buttonImage,
- Padding = new Thickness(77, 29, 25, 35),
- MinimumWidth = 190f,
- };
-
- MenuButton.SetCanvasPinOrigin(new Vector3(0.5f, 0.5f, 1f));
- MenuButton.SetCanvasRelativePosition(new Vector3(0.70f, 0.7f, 0f));
-
- RetryButton = new Button
- {
- Content = new TextBlock { Font = Font, Text = "Retry", TextColor = Color.Black,
- HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Center},
- Padding = new Thickness(74, 29, 25, 35),
- MinimumWidth = 190f,
- PressedImage = buttonImage,
- MouseOverImage = buttonImage,
- NotPressedImage = buttonImage
- };
-
- RetryButton.SetCanvasPinOrigin(new Vector3(0.5f, 0.5f, 1f));
- RetryButton.SetCanvasRelativePosition(new Vector3(0.3f, 0.7f, 0f));
-
- var gameOverCanvas = new Canvas();
- gameOverCanvas.Children.Add(MenuButton);
- gameOverCanvas.Children.Add(RetryButton);
-
- gameOverRoot = new ModalElement
- {
- HorizontalAlignment = HorizontalAlignment.Stretch,
- VerticalAlignment = VerticalAlignment.Stretch,
- Content = gameOverCanvas,
- MinimumWidth = 200f,
- };
- }
-
- ///
- /// Change UI mode to main menu
- ///
- public void StartMainMenuMode()
- {
- Entity.Get().Page = new UIPage { RootElement = mainMenuRoot };
- }
+ HorizontalAlignment = HorizontalAlignment.Stretch,
+ VerticalAlignment = VerticalAlignment.Stretch,
+ Content = mainMenuCanvas
+ };
+ }
- ///
- /// Change UI mode to game
- ///
- public void StartPlayMode()
+ private void CreateGameUI()
+ {
+ distanceTextBlock = new TextBlock { Font = Font, TextColor = Color.Gold, VerticalAlignment = VerticalAlignment.Center };
+ distanceTextBlock.SetCanvasPinOrigin(new Vector3(0.5f, 0.5f, 1f));
+ distanceTextBlock.SetCanvasRelativePosition(new Vector3(0.2f, 0.05f, 0f));
+
+ var scoreBoard = new ContentDecorator
{
- Entity.Get().Page = new UIPage { RootElement = gameRoot };
- }
+ BackgroundImage = SpriteFromSheet.Create(UIImages, "distance_bg"),
+ Content = distanceTextBlock,
+ Padding = new Thickness(60, 31, 25, 35),
+ MinimumWidth = 290f // Set the minimum width of score button so that it wont modify when the content (text) changes, and less than minimum.
+ };
+
+ gameRoot = new Canvas();
+ gameRoot.Children.Add(scoreBoard);
+ }
- ///
- /// Change ui mode to game over
- ///
- public void StartGameOverMode()
+ private void CreateGameOverUI()
+ {
+ MenuButton = new Button
+ {
+ Content = new TextBlock { Font = Font, Text = "Menu", TextColor = Color.Black,
+ HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Center},
+ PressedImage = buttonImage,
+ NotPressedImage = buttonImage,
+ MouseOverImage = buttonImage,
+ Padding = new Thickness(77, 29, 25, 35),
+ MinimumWidth = 190f,
+ };
+
+ MenuButton.SetCanvasPinOrigin(new Vector3(0.5f, 0.5f, 1f));
+ MenuButton.SetCanvasRelativePosition(new Vector3(0.70f, 0.7f, 0f));
+
+ RetryButton = new Button
{
- Entity.Get().Page = new UIPage { RootElement = gameOverRoot };
- }
-
- ///
- /// A function to update UI distance element.
- ///
- ///
- public void SetDistance(int distance)
+ Content = new TextBlock { Font = Font, Text = "Retry", TextColor = Color.Black,
+ HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Center},
+ Padding = new Thickness(74, 29, 25, 35),
+ MinimumWidth = 190f,
+ PressedImage = buttonImage,
+ MouseOverImage = buttonImage,
+ NotPressedImage = buttonImage
+ };
+
+ RetryButton.SetCanvasPinOrigin(new Vector3(0.5f, 0.5f, 1f));
+ RetryButton.SetCanvasRelativePosition(new Vector3(0.3f, 0.7f, 0f));
+
+ var gameOverCanvas = new Canvas();
+ gameOverCanvas.Children.Add(MenuButton);
+ gameOverCanvas.Children.Add(RetryButton);
+
+ gameOverRoot = new ModalElement
{
- distanceTextBlock.Text = "Distance : {0,6}".ToFormat(distance);
- }
+ HorizontalAlignment = HorizontalAlignment.Stretch,
+ VerticalAlignment = VerticalAlignment.Stretch,
+ Content = gameOverCanvas,
+ MinimumWidth = 200f,
+ };
+ }
+
+ ///
+ /// Change UI mode to main menu
+ ///
+ public void StartMainMenuMode()
+ {
+ Entity.Get().Page = new UIPage { RootElement = mainMenuRoot };
+ }
+
+ ///
+ /// Change UI mode to game
+ ///
+ public void StartPlayMode()
+ {
+ Entity.Get().Page = new UIPage { RootElement = gameRoot };
+ }
+
+ ///
+ /// Change ui mode to game over
+ ///
+ public void StartGameOverMode()
+ {
+ Entity.Get().Page = new UIPage { RootElement = gameOverRoot };
+ }
+
+ ///
+ /// A function to update UI distance element.
+ ///
+ ///
+ public void SetDistance(int distance)
+ {
+ distanceTextBlock.Text = "Distance : {0,6}".ToFormat(distance);
}
}
diff --git a/samples/Games/SpaceEscape/SpaceEscape.Windows/SpaceEscape.Windows.csproj b/samples/Games/SpaceEscape/SpaceEscape.Windows/SpaceEscape.Windows.csproj
index b9819ff48e..685b994001 100644
--- a/samples/Games/SpaceEscape/SpaceEscape.Windows/SpaceEscape.Windows.csproj
+++ b/samples/Games/SpaceEscape/SpaceEscape.Windows/SpaceEscape.Windows.csproj
@@ -7,6 +7,8 @@
..\Bin\Windows\$(Configuration)\
false
STRIDE_PLATFORM_DESKTOP
+ enable
+ latest
$(MSBuildThisFileDirectory)..\SpaceEscape.sdpkg
diff --git a/samples/Graphics/AnimatedModel/AnimatedModel.Game/AnimatedModel.Game.csproj b/samples/Graphics/AnimatedModel/AnimatedModel.Game/AnimatedModel.Game.csproj
index a145f87cf8..8f4e1416a7 100644
--- a/samples/Graphics/AnimatedModel/AnimatedModel.Game/AnimatedModel.Game.csproj
+++ b/samples/Graphics/AnimatedModel/AnimatedModel.Game/AnimatedModel.Game.csproj
@@ -2,6 +2,8 @@
net8.0
AnimatedModel
+ enable
+ latest
diff --git a/samples/Graphics/AnimatedModel/AnimatedModel.Game/AnimationScript.cs b/samples/Graphics/AnimatedModel/AnimatedModel.Game/AnimationScript.cs
index de4be2098b..6c73e9f3fa 100644
--- a/samples/Graphics/AnimatedModel/AnimatedModel.Game/AnimationScript.cs
+++ b/samples/Graphics/AnimatedModel/AnimatedModel.Game/AnimationScript.cs
@@ -1,93 +1,92 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
-using System;
-using Stride.Core.Mathematics;
+
using Stride.Animations;
+using Stride.Core.Mathematics;
using Stride.Engine;
using Stride.Rendering.Colors;
using Stride.Rendering.Lights;
-namespace AnimatedModel
+namespace AnimatedModel;
+
+public class AnimationScript : StartupScript
{
- public class AnimationScript : StartupScript
+ public override void Start()
{
- public override void Start()
- {
- // Create an AnimationClip. Make sure to properly set it's duration.
- var animationClip = new AnimationClip { Duration = TimeSpan.FromSeconds(1) };
+ // Create an AnimationClip. Make sure to properly set it's duration.
+ var animationClip = new AnimationClip { Duration = TimeSpan.FromSeconds(1) };
- // Add some curves, specifying the path to the properties to animate.
- // - Components can be index using a special syntax to their key.
- // - Properties can be qualified with a type name in parenthesis
- // - If a type is not serializable, it's fully qualified name must be used
- var colorLightBaseName = typeof(ColorLightBase).AssemblyQualifiedName;
- var colorRgbProviderName = typeof(ColorRgbProvider).AssemblyQualifiedName;
+ // Add some curves, specifying the path to the properties to animate.
+ // - Components can be index using a special syntax to their key.
+ // - Properties can be qualified with a type name in parenthesis
+ // - If a type is not serializable, it's fully qualified name must be used
+ var colorLightBaseName = typeof(ColorLightBase).AssemblyQualifiedName;
+ var colorRgbProviderName = typeof(ColorRgbProvider).AssemblyQualifiedName;
- animationClip.AddCurve("[TransformComponent.Key].Rotation", CreateLightRotationCurve());
- animationClip.AddCurve(string.Format("[LightComponent.Key].Type.({0})Color.({1})Value", colorLightBaseName, colorRgbProviderName), CreateLightColorCurve());
+ animationClip.AddCurve("[TransformComponent.Key].Rotation", CreateLightRotationCurve());
+ animationClip.AddCurve($"[LightComponent.Key].Type.({colorLightBaseName})Color.({colorRgbProviderName})Value", CreateLightColorCurve());
- // Optional: Pack all animation channels into an optimized interleaved format
- animationClip.Optimize();
+ // Optional: Pack all animation channels into an optimized interleaved format
+ animationClip.Optimize();
- // Add an AnimationComponent to the current entity and register our custom clip
- const string animationName = "MyCustomAnimation";
- var animationComponent = Entity.GetOrCreate();
- animationComponent.Animations.Add(animationName, animationClip);
+ // Add an AnimationComponent to the current entity and register our custom clip
+ const string animationName = "MyCustomAnimation";
+ var animationComponent = Entity.GetOrCreate();
+ animationComponent.Animations.Add(animationName, animationClip);
- // Start playing the animation right away and keep repeating it
- var playingAnimation = animationComponent.Play(animationName);
- playingAnimation.RepeatMode = AnimationRepeatMode.LoopInfinite;
- playingAnimation.TimeFactor = 0.1f; // slow down
- playingAnimation.CurrentTime = TimeSpan.FromSeconds(0.6f); // start at different time
- }
+ // Start playing the animation right away and keep repeating it
+ var playingAnimation = animationComponent.Play(animationName);
+ playingAnimation.RepeatMode = AnimationRepeatMode.LoopInfinite;
+ playingAnimation.TimeFactor = 0.1f; // slow down
+ playingAnimation.CurrentTime = TimeSpan.FromSeconds(0.6f); // start at different time
+ }
- private AnimationCurve CreateLightColorCurve()
+ private static AnimationCurve CreateLightColorCurve()
+ {
+ return new AnimationCurve
{
- return new AnimationCurve
+ InterpolationType = AnimationCurveInterpolationType.Cubic,
+ KeyFrames =
{
- InterpolationType = AnimationCurveInterpolationType.Cubic,
- KeyFrames =
- {
- CreateKeyFrame(0.00f, new Vector3(1, 0.45f, 0 * 0.7f)), // Dawn
- CreateKeyFrame(0.05f, new Vector3(1, 0.15f, 0) * 0.3f),
+ CreateKeyFrame(0.00f, new Vector3(1, 0.45f, 0 * 0.7f)), // Dawn
+ CreateKeyFrame(0.05f, new Vector3(1, 0.15f, 0) * 0.3f),
- CreateKeyFrame(0.10f, new Vector3(0)),
- CreateKeyFrame(0.25f, new Vector3(0)), // Midnight
- CreateKeyFrame(0.40f, new Vector3(0)),
+ CreateKeyFrame(0.10f, new Vector3(0)),
+ CreateKeyFrame(0.25f, new Vector3(0)), // Midnight
+ CreateKeyFrame(0.40f, new Vector3(0)),
- CreateKeyFrame(0.45f, new Vector3(1, 0.15f, 0) * 0.3f),
- CreateKeyFrame(0.50f, new Vector3(1, 0.45f, 0) * 0.7f), // Dusk
- CreateKeyFrame(0.55f, new Vector3(1, 0.65f, 0)),
+ CreateKeyFrame(0.45f, new Vector3(1, 0.15f, 0) * 0.3f),
+ CreateKeyFrame(0.50f, new Vector3(1, 0.45f, 0) * 0.7f), // Dusk
+ CreateKeyFrame(0.55f, new Vector3(1, 0.65f, 0)),
- CreateKeyFrame(0.60f, new Vector3(1, 1, 1)),
- CreateKeyFrame(0.75f, new Vector3(1, 1, 1)), // Noon
- CreateKeyFrame(0.90f, new Vector3(1, 1, 1)),
+ CreateKeyFrame(0.60f, new Vector3(1, 1, 1)),
+ CreateKeyFrame(0.75f, new Vector3(1, 1, 1)), // Noon
+ CreateKeyFrame(0.90f, new Vector3(1, 1, 1)),
- CreateKeyFrame(0.95f, new Vector3(1, 0.65f, 0)),
- CreateKeyFrame(1.00f, new Vector3(1, 0.35f, 0)), // Dawn
- }
- };
- }
+ CreateKeyFrame(0.95f, new Vector3(1, 0.65f, 0)),
+ CreateKeyFrame(1.00f, new Vector3(1, 0.35f, 0)), // Dawn
+ }
+ };
+ }
- private AnimationCurve CreateLightRotationCurve()
+ private static AnimationCurve CreateLightRotationCurve()
+ {
+ return new AnimationCurve
{
- return new AnimationCurve
+ InterpolationType = AnimationCurveInterpolationType.Linear,
+ KeyFrames =
{
- InterpolationType = AnimationCurveInterpolationType.Linear,
- KeyFrames =
- {
- CreateKeyFrame(0.00f, Quaternion.RotationX(0)),
- CreateKeyFrame(0.25f, Quaternion.RotationX(MathUtil.PiOverTwo)),
- CreateKeyFrame(0.50f, Quaternion.RotationX(MathUtil.Pi)),
- CreateKeyFrame(0.75f, Quaternion.RotationX(-MathUtil.PiOverTwo)),
- CreateKeyFrame(1.00f, Quaternion.RotationX(MathUtil.TwoPi))
- }
- };
- }
-
- private static KeyFrameData CreateKeyFrame(float keyTime, T value)
- {
- return new KeyFrameData((CompressedTimeSpan)TimeSpan.FromSeconds(keyTime), value);
- }
+ CreateKeyFrame(0.00f, Quaternion.RotationX(0)),
+ CreateKeyFrame(0.25f, Quaternion.RotationX(MathUtil.PiOverTwo)),
+ CreateKeyFrame(0.50f, Quaternion.RotationX(MathUtil.Pi)),
+ CreateKeyFrame(0.75f, Quaternion.RotationX(-MathUtil.PiOverTwo)),
+ CreateKeyFrame(1.00f, Quaternion.RotationX(MathUtil.TwoPi))
+ }
+ };
}
+
+ private static KeyFrameData CreateKeyFrame(float keyTime, T value)
+ {
+ return new KeyFrameData((CompressedTimeSpan)TimeSpan.FromSeconds(keyTime), value);
+ }
}
diff --git a/samples/Graphics/AnimatedModel/AnimatedModel.Game/RenderTextureSceneRenderer.cs b/samples/Graphics/AnimatedModel/AnimatedModel.Game/RenderTextureSceneRenderer.cs
index 2b122c5fa2..112879e7bc 100644
--- a/samples/Graphics/AnimatedModel/AnimatedModel.Game/RenderTextureSceneRenderer.cs
+++ b/samples/Graphics/AnimatedModel/AnimatedModel.Game/RenderTextureSceneRenderer.cs
@@ -1,46 +1,46 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
+
using Stride.Graphics;
using Stride.Rendering;
using Stride.Rendering.Compositing;
-namespace AnimatedModel
+namespace AnimatedModel;
+
+public class RenderTextureSceneRenderer : SceneRendererBase
{
- public class RenderTextureSceneRenderer : SceneRendererBase
- {
- public Texture RenderTexture { get; set; }
+ public Texture RenderTexture { get; set; }
- public ISceneRenderer Child { get; set; }
+ public ISceneRenderer Child { get; set; }
- protected override void CollectCore(RenderContext context)
- {
- base.CollectCore(context);
+ protected override void CollectCore(RenderContext context)
+ {
+ base.CollectCore(context);
- if (RenderTexture == null)
- return;
+ if (RenderTexture == null)
+ return;
- using (context.SaveRenderOutputAndRestore())
- using (context.SaveViewportAndRestore())
- {
- context.RenderOutput.RenderTargetFormat0 = RenderTexture.ViewFormat;
- context.ViewportState.Viewport0 = new Viewport(0, 0, RenderTexture.ViewWidth, RenderTexture.ViewHeight);
+ using (context.SaveRenderOutputAndRestore())
+ using (context.SaveViewportAndRestore())
+ {
+ context.RenderOutput.RenderTargetFormat0 = RenderTexture.ViewFormat;
+ context.ViewportState.Viewport0 = new Viewport(0, 0, RenderTexture.ViewWidth, RenderTexture.ViewHeight);
- Child?.Collect(context);
- }
+ Child?.Collect(context);
}
+ }
- protected override void DrawCore(RenderContext context, RenderDrawContext drawContext)
- {
- if (RenderTexture == null)
- return;
+ protected override void DrawCore(RenderContext context, RenderDrawContext drawContext)
+ {
+ if (RenderTexture == null)
+ return;
- using (drawContext.PushRenderTargetsAndRestore())
- {
- var depthBuffer = PushScopedResource(context.Allocator.GetTemporaryTexture2D(RenderTexture.ViewWidth, RenderTexture.ViewHeight, drawContext.CommandList.DepthStencilBuffer.ViewFormat, TextureFlags.DepthStencil));
- drawContext.CommandList.SetRenderTargetAndViewport(depthBuffer, RenderTexture);
+ using (drawContext.PushRenderTargetsAndRestore())
+ {
+ var depthBuffer = PushScopedResource(context.Allocator.GetTemporaryTexture2D(RenderTexture.ViewWidth, RenderTexture.ViewHeight, drawContext.CommandList.DepthStencilBuffer.ViewFormat, TextureFlags.DepthStencil));
+ drawContext.CommandList.SetRenderTargetAndViewport(depthBuffer, RenderTexture);
- Child?.Draw(drawContext);
- }
+ Child?.Draw(drawContext);
}
}
}
diff --git a/samples/Graphics/AnimatedModel/AnimatedModel.Game/RotateEntity.cs b/samples/Graphics/AnimatedModel/AnimatedModel.Game/RotateEntity.cs
index 58f5143a5d..7fd9dd3e1b 100644
--- a/samples/Graphics/AnimatedModel/AnimatedModel.Game/RotateEntity.cs
+++ b/samples/Graphics/AnimatedModel/AnimatedModel.Game/RotateEntity.cs
@@ -1,32 +1,30 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
-using System.Linq;
-using System.Threading.Tasks;
+
using Stride.Core.Mathematics;
using Stride.Engine;
-namespace AnimatedModel
+namespace AnimatedModel;
+
+///
+/// Rotate the entity when user slide its finger on the screen.
+///
+public class RotateEntity : AsyncScript
{
- ///
- /// Rotate the entity when user slide its finger on the screen.
- ///
- public class RotateEntity : AsyncScript
+ public override async Task Execute()
{
- public override async Task Execute()
- {
- var rotationSpeed = 0f;
+ var rotationSpeed = 0f;
- while (Game.IsRunning)
- {
- await Script.NextFrame();
+ while (Game.IsRunning)
+ {
+ await Script.NextFrame();
- if (Input.PointerEvents.Any())
- rotationSpeed = 200f * Input.PointerEvents.Sum(x => x.DeltaPosition.X);
+ if (Input.PointerEvents.Any())
+ rotationSpeed = 200f * Input.PointerEvents.Sum(x => x.DeltaPosition.X);
- rotationSpeed *= 0.93f;
- var elapsedTime = (float) Game.UpdateTime.Elapsed.TotalSeconds;
- Entity.Transform.Rotation *= Quaternion.RotationY(rotationSpeed * elapsedTime);
- }
+ rotationSpeed *= 0.93f;
+ var elapsedTime = (float) Game.UpdateTime.Elapsed.TotalSeconds;
+ Entity.Transform.Rotation *= Quaternion.RotationY(rotationSpeed * elapsedTime);
}
}
}
diff --git a/samples/Graphics/AnimatedModel/AnimatedModel.Game/UIScript.cs b/samples/Graphics/AnimatedModel/AnimatedModel.Game/UIScript.cs
index 0a85e78dfd..13b21e32fe 100644
--- a/samples/Graphics/AnimatedModel/AnimatedModel.Game/UIScript.cs
+++ b/samples/Graphics/AnimatedModel/AnimatedModel.Game/UIScript.cs
@@ -1,35 +1,33 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
-using System;
+
using Stride.Engine;
using Stride.Graphics;
using Stride.UI;
using Stride.UI.Controls;
-using Stride.UI.Panels;
-namespace AnimatedModel
+namespace AnimatedModel;
+
+public class UIScript : StartupScript
{
- public class UIScript : StartupScript
- {
- public Entity Knight;
+ public Entity Knight;
- public SpriteFont Font;
+ public SpriteFont Font;
- public override void Start()
- {
- base.Start();
+ public override void Start()
+ {
+ base.Start();
- // Bind the buttons
- var page = Entity.Get().Page;
+ // Bind the buttons
+ var page = Entity.Get().Page;
- var btnIdle = page.RootElement.FindVisualChildOfType
$(MSBuildThisFileDirectory)..\AnimatedModel.sdpkg
diff --git a/samples/Graphics/CustomEffect/CustomEffect.Game/CustomEffect.Game.csproj b/samples/Graphics/CustomEffect/CustomEffect.Game/CustomEffect.Game.csproj
index 76d64e5b23..25fb8c5d66 100644
--- a/samples/Graphics/CustomEffect/CustomEffect.Game/CustomEffect.Game.csproj
+++ b/samples/Graphics/CustomEffect/CustomEffect.Game/CustomEffect.Game.csproj
@@ -2,6 +2,8 @@
net8.0
CustomEffect
+ enable
+ latest
diff --git a/samples/Graphics/CustomEffect/CustomEffect.Game/CustomEffectRenderer.cs b/samples/Graphics/CustomEffect/CustomEffect.Game/CustomEffectRenderer.cs
index 1a09f7f1b5..2ba20ef113 100644
--- a/samples/Graphics/CustomEffect/CustomEffect.Game/CustomEffectRenderer.cs
+++ b/samples/Graphics/CustomEffect/CustomEffect.Game/CustomEffectRenderer.cs
@@ -1,69 +1,67 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// 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.Graphics;
using Stride.Rendering;
using Stride.Rendering.Compositing;
-using Stride.Graphics;
-using System;
-namespace CustomEffect
+namespace CustomEffect;
+
+///
+/// The renderer in charge of drawing the custom effect.
+///
+public class CustomEffectRenderer : SceneRendererBase
{
- ///
- /// The renderer in charge of drawing the custom effect.
- ///
- public class CustomEffectRenderer : SceneRendererBase
- {
- private Effect customEffect;
- private SpriteBatch spriteBatch;
- private EffectInstance customEffectInstance;
- private DelegateSceneRenderer renderer;
- private SamplerState samplerState;
+ private Effect customEffect;
+ private SpriteBatch spriteBatch;
+ private EffectInstance customEffectInstance;
+ private DelegateSceneRenderer renderer;
+ private SamplerState samplerState;
- public Texture Background;
- public Texture Logo;
+ public Texture Background;
+ public Texture Logo;
- protected override void InitializeCore()
- {
- base.InitializeCore();
+ protected override void InitializeCore()
+ {
+ base.InitializeCore();
- customEffect = EffectSystem.LoadEffect("Effect").WaitForResult();
- customEffectInstance = new EffectInstance(customEffect);
+ customEffect = EffectSystem.LoadEffect("Effect").WaitForResult();
+ customEffectInstance = new EffectInstance(customEffect);
- spriteBatch = new SpriteBatch(GraphicsDevice) { VirtualResolution = new Vector3(1) };
+ spriteBatch = new SpriteBatch(GraphicsDevice) { VirtualResolution = new Vector3(1) };
- // set fixed parameters once
- customEffectInstance.Parameters.Set(TexturingKeys.Sampler, samplerState);
- customEffectInstance.Parameters.Set(EffectKeys.Center, new Vector2(0.5f, 0.5f));
- customEffectInstance.Parameters.Set(EffectKeys.Frequency, 40);
- customEffectInstance.Parameters.Set(EffectKeys.Spread, 0.5f);
- customEffectInstance.Parameters.Set(EffectKeys.Amplitude, 0.015f);
- customEffectInstance.Parameters.Set(EffectKeys.InvAspectRatio, GraphicsDevice.Presenter.BackBuffer.Height / (float)GraphicsDevice.Presenter.BackBuffer.Width);
+ // set fixed parameters once
+ customEffectInstance.Parameters.Set(TexturingKeys.Sampler, samplerState);
+ customEffectInstance.Parameters.Set(EffectKeys.Center, new Vector2(0.5f, 0.5f));
+ customEffectInstance.Parameters.Set(EffectKeys.Frequency, 40);
+ customEffectInstance.Parameters.Set(EffectKeys.Spread, 0.5f);
+ customEffectInstance.Parameters.Set(EffectKeys.Amplitude, 0.015f);
+ customEffectInstance.Parameters.Set(EffectKeys.InvAspectRatio, GraphicsDevice.Presenter.BackBuffer.Height / (float)GraphicsDevice.Presenter.BackBuffer.Width);
- // NOTE: Linear-Wrap sampling is not available for non-square non-power-of-two textures on opengl es 2.0
- samplerState = SamplerState.New(GraphicsDevice, new SamplerStateDescription(TextureFilter.Linear, TextureAddressMode.Clamp));
- }
+ // NOTE: Linear-Wrap sampling is not available for non-square non-power-of-two textures on opengl es 2.0
+ samplerState = SamplerState.New(GraphicsDevice, new SamplerStateDescription(TextureFilter.Linear, TextureAddressMode.Clamp));
+ }
- protected override void DrawCore(RenderContext context, RenderDrawContext drawContext)
- {
- // Clear
- drawContext.CommandList.Clear(drawContext.CommandList.RenderTarget, Color.Green);
- drawContext.CommandList.Clear(drawContext.CommandList.DepthStencilBuffer, DepthStencilClearOptions.DepthBuffer);
+ protected override void DrawCore(RenderContext context, RenderDrawContext drawContext)
+ {
+ // Clear
+ drawContext.CommandList.Clear(drawContext.CommandList.RenderTarget, Color.Green);
+ drawContext.CommandList.Clear(drawContext.CommandList.DepthStencilBuffer, DepthStencilClearOptions.DepthBuffer);
- customEffectInstance.Parameters.Set(EffectKeys.Phase, -3 * (float)context.Time.Total.TotalSeconds);
+ customEffectInstance.Parameters.Set(EffectKeys.Phase, -3 * (float)context.Time.Total.TotalSeconds);
- spriteBatch.Begin(drawContext.GraphicsContext, blendState: BlendStates.NonPremultiplied, depthStencilState: DepthStencilStates.None, effect: customEffectInstance);
+ spriteBatch.Begin(drawContext.GraphicsContext, blendState: BlendStates.NonPremultiplied, depthStencilState: DepthStencilStates.None, effect: customEffectInstance);
- // Draw background
- var target = drawContext.CommandList.RenderTarget;
- var imageBufferMinRatio = Math.Min(Background.ViewWidth / (float)target.ViewWidth, Background.ViewHeight / (float)target.ViewHeight);
- var sourceSize = new Vector2(target.ViewWidth * imageBufferMinRatio, target.ViewHeight * imageBufferMinRatio);
- var source = new RectangleF((Background.ViewWidth - sourceSize.X) / 2, (Background.ViewHeight - sourceSize.Y) / 2, sourceSize.X, sourceSize.Y);
- spriteBatch.Draw(Background, new RectangleF(0, 0, 1, 1), source, Color.White, 0, Vector2.Zero);
+ // Draw background
+ var target = drawContext.CommandList.RenderTarget;
+ var imageBufferMinRatio = Math.Min(Background.ViewWidth / (float)target.ViewWidth, Background.ViewHeight / (float)target.ViewHeight);
+ var sourceSize = new Vector2(target.ViewWidth * imageBufferMinRatio, target.ViewHeight * imageBufferMinRatio);
+ var source = new RectangleF((Background.ViewWidth - sourceSize.X) / 2, (Background.ViewHeight - sourceSize.Y) / 2, sourceSize.X, sourceSize.Y);
+ spriteBatch.Draw(Background, new RectangleF(0, 0, 1, 1), source, Color.White, 0, Vector2.Zero);
- spriteBatch.Draw(Logo, new RectangleF(0, 0, 1, 1), Color.White);
- spriteBatch.End();
- }
+ spriteBatch.Draw(Logo, new RectangleF(0, 0, 1, 1), Color.White);
+ spriteBatch.End();
}
}
diff --git a/samples/Graphics/CustomEffect/CustomEffect.Game/Effects/Effect.sdsl.cs b/samples/Graphics/CustomEffect/CustomEffect.Game/Effects/Effect.sdsl.cs
index 356722c0d5..9539bb5b72 100644
--- a/samples/Graphics/CustomEffect/CustomEffect.Game/Effects/Effect.sdsl.cs
+++ b/samples/Graphics/CustomEffect/CustomEffect.Game/Effects/Effect.sdsl.cs
@@ -14,15 +14,14 @@
using Stride.Core.Mathematics;
using Buffer = Stride.Graphics.Buffer;
-namespace Stride.Rendering
+namespace Stride.Rendering;
+
+public static partial class EffectKeys
{
- public static partial class EffectKeys
- {
- public static readonly ValueParameterKey Center = ParameterKeys.NewValue();
- public static readonly ValueParameterKey Frequency = ParameterKeys.NewValue();
- public static readonly ValueParameterKey Phase = ParameterKeys.NewValue();
- public static readonly ValueParameterKey Spread = ParameterKeys.NewValue();
- public static readonly ValueParameterKey Amplitude = ParameterKeys.NewValue();
- public static readonly ValueParameterKey InvAspectRatio = ParameterKeys.NewValue();
- }
+ public static readonly ValueParameterKey Center = ParameterKeys.NewValue();
+ public static readonly ValueParameterKey Frequency = ParameterKeys.NewValue();
+ public static readonly ValueParameterKey Phase = ParameterKeys.NewValue();
+ public static readonly ValueParameterKey Spread = ParameterKeys.NewValue();
+ public static readonly ValueParameterKey Amplitude = ParameterKeys.NewValue();
+ public static readonly ValueParameterKey InvAspectRatio = ParameterKeys.NewValue();
}
diff --git a/samples/Graphics/CustomEffect/CustomEffect.Windows/CustomEffect.Windows.csproj b/samples/Graphics/CustomEffect/CustomEffect.Windows/CustomEffect.Windows.csproj
index 50671aea6e..4c375022f6 100644
--- a/samples/Graphics/CustomEffect/CustomEffect.Windows/CustomEffect.Windows.csproj
+++ b/samples/Graphics/CustomEffect/CustomEffect.Windows/CustomEffect.Windows.csproj
@@ -7,6 +7,8 @@
..\Bin\Windows\$(Configuration)\
false
STRIDE_PLATFORM_DESKTOP
+ enable
+ latest
$(MSBuildThisFileDirectory)..\CustomEffect.sdpkg
diff --git a/samples/Graphics/MaterialShader/MaterialShader.Game/MaterialShader.Game.csproj b/samples/Graphics/MaterialShader/MaterialShader.Game/MaterialShader.Game.csproj
index c5347bba75..0efd5b2d37 100644
--- a/samples/Graphics/MaterialShader/MaterialShader.Game/MaterialShader.Game.csproj
+++ b/samples/Graphics/MaterialShader/MaterialShader.Game/MaterialShader.Game.csproj
@@ -2,6 +2,8 @@
net8.0
MaterialShader
+ enable
+ latest
diff --git a/samples/Graphics/MaterialShader/MaterialShader.Windows/MaterialShader.Windows.csproj b/samples/Graphics/MaterialShader/MaterialShader.Windows/MaterialShader.Windows.csproj
index 83b897b5fe..4a11630cc9 100644
--- a/samples/Graphics/MaterialShader/MaterialShader.Windows/MaterialShader.Windows.csproj
+++ b/samples/Graphics/MaterialShader/MaterialShader.Windows/MaterialShader.Windows.csproj
@@ -7,6 +7,8 @@
..\Bin\Windows\$(Configuration)\
false
STRIDE_PLATFORM_DESKTOP
+ enable
+ latest
$(MSBuildThisFileDirectory)..\MaterialShader.sdpkg
diff --git a/samples/Graphics/SpriteFonts/SpriteFonts.Game/FontRenderer.cs b/samples/Graphics/SpriteFonts/SpriteFonts.Game/FontRenderer.cs
index b4643ce023..7d298b26f9 100644
--- a/samples/Graphics/SpriteFonts/SpriteFonts.Game/FontRenderer.cs
+++ b/samples/Graphics/SpriteFonts/SpriteFonts.Game/FontRenderer.cs
@@ -1,437 +1,438 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
-using System;
-using System.Collections.Generic;
-using System.Linq;
+
using Stride.Core;
using Stride.Core.Mathematics;
-using Stride.Engine;
-using Stride.Rendering;
-using Stride.Rendering.Compositing;
using Stride.Graphics;
using Stride.Input;
+using Stride.Rendering;
+using Stride.Rendering.Compositing;
-namespace SpriteFonts
+namespace SpriteFonts;
+
+///
+/// This sample shows how to easily manipulate font in several different ways for rendering using SpriteBatch.
+/// The features of font described in here includes:
+/// 1. Static font
+/// 2. Dynamic font with different size
+/// 3. Font styles {Bold, Italic}
+/// 4. Alias modes {Aliased, Anti-aliased, Clear}
+/// 5. Different languages supported
+/// 6. Three alignment modes {Left, Center, Right}
+/// 7. Animated text
+///
+public class FontRenderer : SceneRendererBase
{
- ///
- /// This sample shows how to easily manipulate font in several different ways for rendering using SpriteBatch.
- /// The features of font described in here includes:
- /// 1. Static font
- /// 2. Dynamic font with different size
- /// 3. Font styles {Bold, Italic}
- /// 4. Alias modes {Aliased, Anti-aliased, Clear}
- /// 5. Different languages supported
- /// 6. Three alignment modes {Left, Center, Right}
- /// 7. Animated text
- ///
- public class FontRenderer : SceneRendererBase
+ // Time to display text groups where the first index corresponding to introduction text, and the rest corresponding to text groups
+ private static readonly float[] TimeToDisplayTextGroups =
+ [
+ 3f /*Intro*/, 5f /*Static*/, 5f /*Dynamic*/, 4f /*Style*/, 5f /*Alias*/,
+ 5f /*Language*/, 5f /*Alignment*/, 10f /*Animated*/
+ ];
+
+ private readonly List screenRenderers = [];
+
+ private const float FadeInDuration = 1f;
+ private const float FadeOutDuration = 1f;
+
+ private const float DynamicFontContentSize = 50;
+
+ private const string RefenceText =
+ """
+ In the first centuries of typesetting,
+ quotations were distinguished merely by
+ indicating the speaker, and this can still
+ be seen in some editions of the Bible.
+ During the Renaissance, quotations
+ were distinguished by setting in a typeface
+ contrasting with the main body text
+ (often Italic type with roman,
+ or the other way round).
+ Block quotations were set this way
+ at full size and full measure
+ """;
+
+ private Vector2 centerVirtualPosition;
+ private Vector2 screenSize;
+ private SpriteBatch spriteBatch;
+
+ public Texture Background;
+
+ public SpriteFont StaticFont;
+ public SpriteFont DynamicFont;
+ public SpriteFont BoldFont;
+ public SpriteFont ItalicFont;
+ public SpriteFont AliasedFont;
+ public SpriteFont AntialiasedFont;
+ public SpriteFont ClearTypeFont;
+ public SpriteFont JapaneseFont;
+ public SpriteFont TimesNewRoman;
+ public SpriteFont HeaderFont;
+
+ private Vector2 animatedFontPosition;
+ private float animatedFontScale;
+ private float animatedFontRotation;
+ private float animatedFontAlpha;
+ private bool isPlaying = true;
+ private int currentScreenIndex;
+ private float currentTime;
+
+ private readonly Vector2 headerPosition = new(0.5f, 0.25f);
+ private readonly Vector2 contentPosition = new(0.5f, 0.4f);
+
+ private readonly Color strideColor = new(0xFF3008da);
+
+ private readonly Vector2 virtualResolution = new(1920, 1080);
+
+ private InputManager input;
+
+ protected override void InitializeCore()
{
- // Time to display text groups where the first index corresponding to introduction text, and the rest corresponding to text groups
- private static readonly float[] TimeToDisplayTextGroups = { 3f /*Intro*/, 5f /*Static*/, 5f /*Dynamic*/, 4f /*Style*/, 5f /*Alias*/,
- 5f /*Language*/, 5f /*Alignment*/, 10f /*Animated*/};
-
- private readonly List screenRenderers = new List();
-
- private const float FadeInDuration = 1f;
- private const float FadeOutDuration = 1f;
-
- private const float DynamicFontContentSize = 50;
-
- private const string RefenceText = @"
-In the first centuries of typesetting,
-quotations were distinguished merely by
-indicating the speaker, and this can still
-be seen in some editions of the Bible.
-During the Renaissance, quotations
-were distinguished by setting in a typeface
-contrasting with the main body text
-(often Italic type with roman,
-or the other way round).
-Block quotations were set this way
-at full size and full measure";
-
- private Vector2 centerVirtualPosition;
- private Vector2 screenSize;
- private SpriteBatch spriteBatch;
-
- public Texture Background;
-
- public SpriteFont StaticFont;
- public SpriteFont DynamicFont;
- public SpriteFont BoldFont;
- public SpriteFont ItalicFont;
- public SpriteFont AliasedFont;
- public SpriteFont AntialiasedFont;
- public SpriteFont ClearTypeFont;
- public SpriteFont JapaneseFont;
- public SpriteFont TimesNewRoman;
- public SpriteFont HeaderFont;
-
- private Vector2 animatedFontPosition;
- private float animatedFontScale;
- private float animatedFontRotation;
- private float animatedFontAlpha;
- private bool isPlaying = true;
- private int currentScreenIndex;
- private float currentTime;
+ base.InitializeCore();
- private readonly Vector2 headerPosition = new Vector2(0.5f, 0.25f);
- private readonly Vector2 contentPosition = new Vector2(0.5f, 0.4f);
+ input = Context.Services.GetSafeServiceAs();
- private readonly Color strideColor = new Color(0xFF3008da);
+ // Create the SpriteBatch used to render them
+ spriteBatch = new SpriteBatch(GraphicsDevice) { VirtualResolution = new Vector3(virtualResolution, 1000) };
- private Vector2 virtualResolution = new Vector2(1920, 1080);
+ centerVirtualPosition = new Vector2(virtualResolution.X * 0.5f, virtualResolution.Y * 0.5f);
+ screenSize = new Vector2(GraphicsDevice.Presenter.BackBuffer.Width, GraphicsDevice.Presenter.BackBuffer.Height);
- private InputManager input;
+ screenRenderers.Add(DrawIntroductionCategory);
+ screenRenderers.Add(DrawStaticCategory);
+ screenRenderers.Add(DrawDynamicCategory);
+ screenRenderers.Add(DrawStyleCategory);
+ screenRenderers.Add(DrawAliasCategory);
+ screenRenderers.Add(DrawLanguageCategory);
+ screenRenderers.Add(DrawAlignmentCategory);
+ screenRenderers.Add(DrawAnimationCategory);
+ }
- protected override void InitializeCore()
- {
- base.InitializeCore();
+ protected override void DrawCore(RenderContext context, RenderDrawContext drawContext)
+ {
+ // Clear
+ drawContext.CommandList.Clear(drawContext.CommandList.RenderTarget, Color.Green);
+ drawContext.CommandList.Clear(drawContext.CommandList.DepthStencilBuffer, DepthStencilClearOptions.DepthBuffer);
- input = Context.Services.GetSafeServiceAs();
+ UpdateAnimatedFontParameters();
+ UpdateInput();
+ UpdateCurrentScreenIndex();
- // Create the SpriteBatch used to render them
- spriteBatch = new SpriteBatch(GraphicsDevice) { VirtualResolution = new Vector3(virtualResolution, 1000) };
+ if (isPlaying)
+ currentTime += (float)context.Time.Elapsed.TotalSeconds;
- centerVirtualPosition = new Vector2(virtualResolution.X * 0.5f, virtualResolution.Y * 0.5f);
- screenSize = new Vector2(GraphicsDevice.Presenter.BackBuffer.Width, GraphicsDevice.Presenter.BackBuffer.Height);
+ spriteBatch.Begin(drawContext.GraphicsContext);
+
+ // Draw background
+ var target = drawContext.CommandList.RenderTarget;
+ var imageBufferMinRatio = Math.Min(Background.ViewWidth / (float)target.ViewWidth, Background.ViewHeight / (float)target.ViewHeight);
+ var sourceSize = new Vector2(target.ViewWidth * imageBufferMinRatio, target.ViewHeight * imageBufferMinRatio);
+ var source = new RectangleF((Background.ViewWidth - sourceSize.X) / 2, (Background.ViewHeight - sourceSize.Y) / 2, sourceSize.X, sourceSize.Y);
+ spriteBatch.Draw(Background, new RectangleF(0, 0, virtualResolution.X, virtualResolution.Y), source, Color.White, 0, Vector2.Zero);
+
+ screenRenderers[currentScreenIndex]();
+ spriteBatch.End();
+ }
- screenRenderers.Add(DrawIntroductionCategory);
- screenRenderers.Add(DrawStaticCategory);
- screenRenderers.Add(DrawDynamicCategory);
- screenRenderers.Add(DrawStyleCategory);
- screenRenderers.Add(DrawAliasCategory);
- screenRenderers.Add(DrawLanguageCategory);
- screenRenderers.Add(DrawAlignmentCategory);
- screenRenderers.Add(DrawAnimationCategory);
- }
+ #region Draw Methods
- protected override void DrawCore(RenderContext context, RenderDrawContext drawContext)
- {
- // Clear
- drawContext.CommandList.Clear(drawContext.CommandList.RenderTarget, Color.Green);
- drawContext.CommandList.Clear(drawContext.CommandList.DepthStencilBuffer, DepthStencilClearOptions.DepthBuffer);
-
- UpdateAnimatedFontParameters();
- UpdateInput();
- UpdateCurrentScreenIndex();
-
- if (isPlaying)
- currentTime += (float)context.Time.Elapsed.TotalSeconds;
-
- spriteBatch.Begin(drawContext.GraphicsContext);
-
- // Draw background
- var target = drawContext.CommandList.RenderTarget;
- var imageBufferMinRatio = Math.Min(Background.ViewWidth / (float)target.ViewWidth, Background.ViewHeight / (float)target.ViewHeight);
- var sourceSize = new Vector2(target.ViewWidth * imageBufferMinRatio, target.ViewHeight * imageBufferMinRatio);
- var source = new RectangleF((Background.ViewWidth - sourceSize.X) / 2, (Background.ViewHeight - sourceSize.Y) / 2, sourceSize.X, sourceSize.Y);
- spriteBatch.Draw(Background, new RectangleF(0, 0, virtualResolution.X, virtualResolution.Y), source, Color.White, 0, Vector2.Zero);
-
- screenRenderers[currentScreenIndex]();
- spriteBatch.End();
- }
+ private void DrawHeader(string headerPart1, string headerPart2, string headerPart3)
+ {
+ const float headerSize = 70;
- #region Draw Methods
+ var position = GetVirtualPosition(headerPosition);
- private void DrawHeader(string headerPart1, string headerPart2, string headerPart3)
- {
- const float headerSize = 70;
+ // Find the X position offset for the first part of text
+ position -= spriteBatch.MeasureString(HeaderFont, headerPart1 + headerPart2 + headerPart3, headerSize, screenSize) * 0.5f;
- var position = GetVirtualPosition(headerPosition);
+ // Draw each part separately because we need to have a different color in the 2nd part
+ spriteBatch.DrawString(HeaderFont, headerPart1, headerSize, position, Color.White * GetInterpolatedAlpha());
- // Find the X position offset for the first part of text
- position -= spriteBatch.MeasureString(HeaderFont, headerPart1 + headerPart2 + headerPart3, headerSize, screenSize) * 0.5f;
+ position.X += spriteBatch.MeasureString(HeaderFont, headerPart1, headerSize, screenSize).X;
- // Draw each part separately because we need to have a different color in the 2nd part
- spriteBatch.DrawString(HeaderFont, headerPart1, headerSize, position, Color.White * GetInterpolatedAlpha());
+ spriteBatch.DrawString(HeaderFont, headerPart2, headerSize, position, strideColor * GetInterpolatedAlpha());
- position.X += spriteBatch.MeasureString(HeaderFont, headerPart1, headerSize, screenSize).X;
+ position.X += spriteBatch.MeasureString(HeaderFont, headerPart2, headerSize, screenSize).X;
- spriteBatch.DrawString(HeaderFont, headerPart2, headerSize, position, strideColor * GetInterpolatedAlpha());
+ spriteBatch.DrawString(HeaderFont, headerPart3, headerSize, position, Color.White * GetInterpolatedAlpha());
+ }
- position.X += spriteBatch.MeasureString(HeaderFont, headerPart2, headerSize, screenSize).X;
+ ///
+ /// Draw "Introduction" text group.
+ /// Render Stride SpriteFont sample introduction page.
+ ///
+ private void DrawIntroductionCategory()
+ {
+ // Draw Create {cross-platform} {game} {in C#} in three pieces separately
+ const float textSize = 80;
+ const string textPart1 = "Create cross-platform";
+ const string textPart2 = " games ";
+ const string textPart3 = "in C#";
- spriteBatch.DrawString(HeaderFont, headerPart3, headerSize, position, Color.White * GetInterpolatedAlpha());
- }
+ var position = GetVirtualPosition(0.5f, 0.5f);
- ///
- /// Draw "Introduction" text group.
- /// Render Stride SpriteFont sample introduction page.
- ///
- private void DrawIntroductionCategory()
- {
- // Draw Create {cross-platform} {game} {in C#} in three pieces separately
- const float textSize = 80;
- const string textPart1 = "Create cross-platform";
- const string textPart2 = " games ";
- const string textPart3 = "in C#";
+ // Find the X position offset for the first part of text
+ position -= spriteBatch.MeasureString(DynamicFont, textPart1 + textPart2 + textPart3, textSize, screenSize) * 0.5f;
- var position = GetVirtualPosition(0.5f, 0.5f);
+ // Draw each part separately because we need to have a different color in the 2nd part
+ spriteBatch.DrawString(DynamicFont, textPart1, textSize, position, Color.White * GetInterpolatedAlpha());
- // Find the X position offset for the first part of text
- position -= spriteBatch.MeasureString(DynamicFont, textPart1 + textPart2 + textPart3, textSize, screenSize) * 0.5f;
+ position.X += spriteBatch.MeasureString(DynamicFont, textPart1, textSize, screenSize).X;
- // Draw each part separately because we need to have a different color in the 2nd part
- spriteBatch.DrawString(DynamicFont, textPart1, textSize, position, Color.White * GetInterpolatedAlpha());
+ spriteBatch.DrawString(DynamicFont, textPart2, textSize, position, strideColor * GetInterpolatedAlpha());
- position.X += spriteBatch.MeasureString(DynamicFont, textPart1, textSize, screenSize).X;
+ position.X += spriteBatch.MeasureString(DynamicFont, textPart2, textSize, screenSize).X;
- spriteBatch.DrawString(DynamicFont, textPart2, textSize, position, strideColor * GetInterpolatedAlpha());
+ spriteBatch.DrawString(DynamicFont, textPart3, textSize, position, Color.White * GetInterpolatedAlpha());
+ }
- position.X += spriteBatch.MeasureString(DynamicFont, textPart2, textSize, screenSize).X;
+ ///
+ /// Draw "Static" text group.
+ /// Render text created in compiling-time which could not change in run-time.
+ ///
+ private void DrawStaticCategory()
+ {
+ DrawHeader("Compile-time rendered ", "static", " fonts");
- spriteBatch.DrawString(DynamicFont, textPart3, textSize, position, Color.White * GetInterpolatedAlpha());
- }
+ var position = GetVirtualPosition(contentPosition);
- ///
- /// Draw "Static" text group.
- /// Render text created in compiling-time which could not change in run-time.
- ///
- private void DrawStaticCategory()
- {
- DrawHeader("Compile-time rendered ", "static", " fonts");
+ const string text = "Embeds only required characters into the database\n" +
+ "Does not require any rendering time at execution\n" +
+ "Cannot adjust their size to the virtual resolution\n" +
+ "Cannot modify their size at run-time";
- var position = GetVirtualPosition(contentPosition);
+ position.X -= spriteBatch.MeasureString(StaticFont, text, screenSize).X / 2;
- var text = "Embeds only required characters into the database\n" +
- "Does not require any rendering time at execution\n" +
- "Cannot adjust their size to the virtual resolution\n" +
- "Cannot modify their size at run-time";
+ spriteBatch.DrawString(StaticFont, text, position, Color.White * GetInterpolatedAlpha());
+ }
- position.X -= spriteBatch.MeasureString(StaticFont, text, screenSize).X / 2;
+ ///
+ /// Draw "Dynamic" text group.
+ /// Display text created dynamically in different sizes.
+ ///
+ private void DrawDynamicCategory()
+ {
+ DrawHeader("Run-time rendered ", "dynamic", " fonts");
- spriteBatch.DrawString(StaticFont, text, position, Color.White * GetInterpolatedAlpha());
- }
+ var text = "Embeds all characters of the font into the database\n" +
+ "Is rendered at execution time and requires some time for rendering\n" +
+ "Can adjust their size to the virtual resolution\n";
- ///
- /// Draw "Dynamic" text group.
- /// Display text created dynamically in different sizes.
- ///
- private void DrawDynamicCategory()
- {
- DrawHeader("Run-time rendered ", "dynamic", " fonts");
+ var position = GetVirtualPosition(contentPosition);
+ var firstTextSize = spriteBatch.MeasureString(DynamicFont, text, DynamicFontContentSize, screenSize);
- var text = "Embeds all characters of the font into the database\n" +
- "Is rendered at execution time and requires some time for rendering\n" +
- "Can adjust their size to the virtual resolution\n";
+ position.X -= firstTextSize.X / 2;
- var position = GetVirtualPosition(contentPosition);
- var firstTextSize = spriteBatch.MeasureString(DynamicFont, text, DynamicFontContentSize, screenSize);
+ spriteBatch.DrawString(DynamicFont, text, DynamicFontContentSize, position, Color.White * GetInterpolatedAlpha());
- position.X -= firstTextSize.X / 2;
+ text = "Can modify their size at execution time";
- spriteBatch.DrawString(DynamicFont, text, DynamicFontContentSize, position, Color.White * GetInterpolatedAlpha());
+ position.Y += firstTextSize.Y;
+ spriteBatch.DrawString(DynamicFont, text, 80, position, Color.White * GetInterpolatedAlpha());
+ }
- text = "Can modify their size at execution time";
+ ///
+ /// Draw "Style" text group.
+ /// Illustrate possible styles of font that can be rendered in compile-time {Italic, Bold}
+ ///
+ private void DrawStyleCategory()
+ {
+ DrawHeader("Support common font ", "styles", "");
- position.Y += firstTextSize.Y;
- spriteBatch.DrawString(DynamicFont, text, 80, position, Color.White * GetInterpolatedAlpha());
- }
+ var position = GetVirtualPosition(contentPosition);
- ///
- /// Draw "Style" text group.
- /// Illustrate possible styles of font that can be rendered in compile-time {Italic, Bold}
- ///
- private void DrawStyleCategory()
- {
- DrawHeader("Support common font ", "styles", "");
+ var text = "None - This is a sample sentence.";
+ var firstTextSize = spriteBatch.MeasureString(DynamicFont, text, DynamicFontContentSize, screenSize);
+ position.X -= firstTextSize.X / 2;
+ spriteBatch.DrawString(DynamicFont, text, DynamicFontContentSize, position, Color.White * GetInterpolatedAlpha());
- var position = GetVirtualPosition(contentPosition);
+ text = "Italic - This is a sample sentence.";
+ position.Y += firstTextSize.Y;
+ spriteBatch.DrawString(ItalicFont, text, DynamicFontContentSize, position, Color.White * GetInterpolatedAlpha());
- var text = "None - This is a sample sentence.";
- var firstTextSize = spriteBatch.MeasureString(DynamicFont, text, DynamicFontContentSize, screenSize);
- position.X -= firstTextSize.X / 2;
- spriteBatch.DrawString(DynamicFont, text, DynamicFontContentSize, position, Color.White * GetInterpolatedAlpha());
+ text = "Bold - This is a sample sentence.";
+ position.Y += spriteBatch.MeasureString(ItalicFont, text, DynamicFontContentSize, screenSize).Y;
+ spriteBatch.DrawString(BoldFont, text, DynamicFontContentSize, position, Color.White * GetInterpolatedAlpha());
+ }
- text = "Italic - This is a sample sentence.";
- position.Y += firstTextSize.Y;
- spriteBatch.DrawString(ItalicFont, text, DynamicFontContentSize, position, Color.White * GetInterpolatedAlpha());
+ ///
+ /// Draw "Alias" text group.
+ /// Display all three possible alias modes {Aliased, Anti-aliased, Clear type}.
+ ///
+ private void DrawAliasCategory()
+ {
+ DrawHeader("Support common ", "anti-aliasing", " modes");
- text = "Bold - This is a sample sentence.";
- position.Y += spriteBatch.MeasureString(ItalicFont, text, DynamicFontContentSize, screenSize).Y;
- spriteBatch.DrawString(BoldFont, text, DynamicFontContentSize, position, Color.White * GetInterpolatedAlpha());
- }
+ var position = GetVirtualPosition(contentPosition);
- ///
- /// Draw "Alias" text group.
- /// Display all three possible alias modes {Aliased, Anti-aliased, Clear type}.
- ///
- private void DrawAliasCategory()
- {
- DrawHeader("Support common ", "anti-aliasing", " modes");
+ var text = "Aliased - This is a sample sentence.";
+ var firstTextSize = spriteBatch.MeasureString(AliasedFont, text, DynamicFontContentSize, screenSize);
+ position.X -= firstTextSize.X / 2;
+ spriteBatch.DrawString(AliasedFont, text, position, Color.White * GetInterpolatedAlpha());
- var position = GetVirtualPosition(contentPosition);
+ position.Y += firstTextSize.Y;
+ text = "Anti-aliased - This is a sample sentence.";
+ spriteBatch.DrawString(AntialiasedFont, text, position, Color.White * GetInterpolatedAlpha());
- var text = "Aliased - This is a sample sentence.";
- var firstTextSize = spriteBatch.MeasureString(AliasedFont, text, DynamicFontContentSize, screenSize);
- position.X -= firstTextSize.X / 2;
- spriteBatch.DrawString(AliasedFont, text, position, Color.White * GetInterpolatedAlpha());
+ position.Y += spriteBatch.MeasureString(AntialiasedFont, text, screenSize).Y;
+ text = "Clear-type - This is a sample sentence.";
+ spriteBatch.DrawString(ClearTypeFont, text, position, Color.White * GetInterpolatedAlpha());
+ }
- position.Y += firstTextSize.Y;
- text = "Anti-aliased - This is a sample sentence.";
- spriteBatch.DrawString(AntialiasedFont, text, position, Color.White * GetInterpolatedAlpha());
+ ///
+ /// Draw "Language" text group.
+ /// Show Japanese dynamic font, by rendering a japanese paragraph.
+ /// Other pictogram alphabets are supported as well.
+ ///
+ private void DrawLanguageCategory()
+ {
+ DrawHeader("Support ", "pictogram-based", " fonts");
- position.Y += spriteBatch.MeasureString(AntialiasedFont, text, screenSize).Y;
- text = "Clear-type - This is a sample sentence.";
- spriteBatch.DrawString(ClearTypeFont, text, position, Color.White * GetInterpolatedAlpha());
- }
+ const int sizeIncreament = 15;
+ const float scale = 0.8f;
+ var position = GetVirtualPosition(contentPosition);
+ const string text = "Japanese dynamic sprite font\nあいうえおかきくけこ 天竜の\nアイウエオカキクケコ 幅八町の\n一二三四五六七八九十 梅雨濁り";
- ///
- /// Draw "Language" text group.
- /// Show Japanese dynamic font, by rendering a japanese paragraph.
- /// Other pictogram alphabets are supported as well.
- ///
- private void DrawLanguageCategory()
- {
- DrawHeader("Support ", "pictogram-based", " fonts");
+ position.X -= spriteBatch.MeasureString(JapaneseFont, text, scale * (DynamicFontContentSize + sizeIncreament), screenSize).X / 2;
+ spriteBatch.DrawString(JapaneseFont, text, scale * (DynamicFontContentSize + sizeIncreament), position, Color.White * GetInterpolatedAlpha());
+ }
- var sizeIncreament = 15;
- var scale = 0.8f;
- var position = GetVirtualPosition(contentPosition);
- var text = "Japanese dynamic sprite font\nあいうえおかきくけこ 天竜の\nアイウエオカキクケコ 幅八町の\n一二三四五六七八九十 梅雨濁り";
+ ///
+ /// Draw "Alignment" text group.
+ /// Display three paragraphs showing possible alignments {Left, Center, Right}
+ ///
+ private void DrawAlignmentCategory()
+ {
+ DrawHeader("Support standard ", "text alignment", " modes");
- position.X -= spriteBatch.MeasureString(JapaneseFont, text, scale * (DynamicFontContentSize + sizeIncreament), screenSize).X / 2;
- spriteBatch.DrawString(JapaneseFont, text, scale * (DynamicFontContentSize + sizeIncreament), position, Color.White * GetInterpolatedAlpha());
- }
+ var position = GetVirtualPosition(contentPosition);
- ///
- /// Draw "Alignment" text group.
- /// Display three paragraphs showing possible alignments {Left, Center, Right}
- ///
- private void DrawAlignmentCategory()
- {
- DrawHeader("Support standard ", "text alignment", " modes");
+ // Draw content
+ position.X = virtualResolution.X * 0.03f;
+ var text = "LEFT-ALIGNED TEXT\n" + RefenceText;
- var position = GetVirtualPosition(contentPosition);
+ const int textSize = 28;
- // Draw content
- position.X = virtualResolution.X * 0.03f;
- var text = "LEFT-ALIGNED TEXT\n" + RefenceText;
+ spriteBatch.DrawString(TimesNewRoman, text, textSize, position, Color.White * GetInterpolatedAlpha());
- var textSize = 28;
+ position.X = centerVirtualPosition.X - 0.5f * spriteBatch.MeasureString(TimesNewRoman, text, textSize, screenSize).X;
+ text = "CENTERED TEXT\n" + RefenceText;
- spriteBatch.DrawString(TimesNewRoman, text, textSize, position, Color.White * GetInterpolatedAlpha());
+ spriteBatch.DrawString(TimesNewRoman, text, textSize, position, Color.White * GetInterpolatedAlpha(), TextAlignment.Center);
- position.X = centerVirtualPosition.X - 0.5f * spriteBatch.MeasureString(TimesNewRoman, text, textSize, screenSize).X;
- text = "CENTERED TEXT\n" + RefenceText;
+ position.X = virtualResolution.X - spriteBatch.MeasureString(TimesNewRoman, text, textSize, screenSize).X - virtualResolution.X * 0.03f;
+ text = "RIGHT-ALIGNED TEXT\n" + RefenceText;
- spriteBatch.DrawString(TimesNewRoman, text, textSize, position, Color.White * GetInterpolatedAlpha(), TextAlignment.Center);
+ spriteBatch.DrawString(TimesNewRoman, text, textSize, position, Color.White * GetInterpolatedAlpha(), TextAlignment.Right);
+ }
- position.X = virtualResolution.X - spriteBatch.MeasureString(TimesNewRoman, text, textSize, screenSize).X - virtualResolution.X * 0.03f;
- text = "RIGHT-ALIGNED TEXT\n" + RefenceText;
+ ///
+ /// Draw "Animation" text group.
+ /// Illustrate an animate text.
+ ///
+ private void DrawAnimationCategory()
+ {
+ DrawHeader("Easily ", "animate", " your texts!");
- spriteBatch.DrawString(TimesNewRoman, text, textSize, position, Color.White * GetInterpolatedAlpha(), TextAlignment.Right);
- }
+ // Draw content
+ const string text = "Stride Engine";
- ///
- /// Draw "Animation" text group.
- /// Illustrate an animate text.
- ///
- private void DrawAnimationCategory()
- {
- DrawHeader("Easily ", "animate", " your texts!");
+ spriteBatch.DrawString(DynamicFont, text, DynamicFontContentSize, animatedFontPosition, animatedFontAlpha * Color.White * GetInterpolatedAlpha(), animatedFontRotation,
+ 0.5f * spriteBatch.MeasureString(DynamicFont, text, DynamicFontContentSize, screenSize), animatedFontScale * Vector2.One, SpriteEffects.None, 0f, TextAlignment.Left);
+ }
- // Draw content
- var text = "Stride Engine";
+ #endregion Draw methods
- spriteBatch.DrawString(DynamicFont, text, DynamicFontContentSize, animatedFontPosition, animatedFontAlpha * Color.White * GetInterpolatedAlpha(), animatedFontRotation,
- 0.5f * spriteBatch.MeasureString(DynamicFont, text, DynamicFontContentSize, screenSize), animatedFontScale * Vector2.One, SpriteEffects.None, 0f, TextAlignment.Left);
+ ///
+ /// Check if there is any input command.
+ /// Input commands are for controlling: 1. Text group advancing, 2. Previous/Next text group selection.
+ ///
+ ///
+ private void UpdateInput()
+ {
+ // Toggle play/not play
+ if (input.IsKeyPressed(Keys.Space) || input.PointerEvents.Any(pointerEvent => pointerEvent.EventType == PointerEventType.Pressed))
+ {
+ isPlaying = !isPlaying;
}
-
- #endregion Draw methods
-
- ///
- /// Check if there is any input command.
- /// Input commands are for controlling: 1. Text group advancing, 2. Previous/Next text group selection.
- ///
- ///
- private void UpdateInput()
+ else if (input.IsKeyPressed(Keys.Left) || input.IsKeyPressed(Keys.Right))
{
- // Toggle play/not play
- if (input.IsKeyPressed(Keys.Space) || input.PointerEvents.Any(pointerEvent => pointerEvent.EventType == PointerEventType.Pressed))
- {
- isPlaying = !isPlaying;
- }
- else if (input.IsKeyPressed(Keys.Left) || input.IsKeyPressed(Keys.Right))
- {
- currentTime = 0;
- currentScreenIndex = (currentScreenIndex + (input.IsKeyPressed(Keys.Left) ? -1 : +1) + screenRenderers.Count) % screenRenderers.Count;
- }
+ currentTime = 0;
+ currentScreenIndex = (currentScreenIndex + (input.IsKeyPressed(Keys.Left) ? -1 : +1) + screenRenderers.Count) % screenRenderers.Count;
}
+ }
- private void UpdateCurrentScreenIndex()
- {
- var upperBound = TimeToDisplayTextGroups[currentScreenIndex];
+ private void UpdateCurrentScreenIndex()
+ {
+ var upperBound = TimeToDisplayTextGroups[currentScreenIndex];
- if (currentTime > upperBound)
- {
- currentTime = 0;
- currentScreenIndex = (currentScreenIndex + 1) % screenRenderers.Count;
- }
+ if (currentTime > upperBound)
+ {
+ currentTime = 0;
+ currentScreenIndex = (currentScreenIndex + 1) % screenRenderers.Count;
}
+ }
- ///
- /// Update the main font parameters according to sample state.
- ///
- ///
- private void UpdateAnimatedFontParameters()
- {
- if (!isPlaying)
- return;
+ ///
+ /// Update the main font parameters according to sample state.
+ ///
+ ///
+ private void UpdateAnimatedFontParameters()
+ {
+ if (!isPlaying)
+ return;
- animatedFontAlpha = GetVaryingValue(1.6f * currentTime);
- animatedFontRotation = 2f * currentTime * (float)Math.PI;
- animatedFontPosition = GetVirtualPosition(0.5f, 0.65f) + 160 * new Vector2(1.5f * (float)Math.Cos(1.5f * currentTime), (float)Math.Sin(1.5f * currentTime));
- animatedFontScale = 0.9f + 0.2f * GetVaryingValue(2.5f * currentTime);
- }
+ animatedFontAlpha = GetVaryingValue(1.6f * currentTime);
+ animatedFontRotation = 2f * currentTime * (float)Math.PI;
+ animatedFontPosition = GetVirtualPosition(0.5f, 0.65f) + 160 * new Vector2(1.5f * (float)Math.Cos(1.5f * currentTime), (float)Math.Sin(1.5f * currentTime));
+ animatedFontScale = 0.9f + 0.2f * GetVaryingValue(2.5f * currentTime);
+ }
- ///
- /// Return interpolated value for alpha channel of a text that controls opacity.
- /// Value, that is outside the bound, would not invisible.
- ///
- ///
- private float GetInterpolatedAlpha()
- {
- var upperBound = TimeToDisplayTextGroups[currentScreenIndex];
+ ///
+ /// Return interpolated value for alpha channel of a text that controls opacity.
+ /// Value, that is outside the bound, would not invisible.
+ ///
+ ///
+ private float GetInterpolatedAlpha()
+ {
+ var upperBound = TimeToDisplayTextGroups[currentScreenIndex];
- if (currentTime < FadeInDuration)
- return currentTime / FadeInDuration;
+ if (currentTime < FadeInDuration)
+ return currentTime / FadeInDuration;
- if (currentTime < upperBound - FadeOutDuration)
- return 1f;
+ if (currentTime < upperBound - FadeOutDuration)
+ return 1f;
- return Math.Max(upperBound - currentTime, 0) / FadeOutDuration;
- }
+ return Math.Max(upperBound - currentTime, 0) / FadeOutDuration;
+ }
- ///
- /// Return position in virtual resolution coordinate by given relative position [0, 1]
- ///
- ///
- ///
- ///
- private Vector2 GetVirtualPosition(float relativePositionX, float relativePositionY)
- {
- return GetVirtualPosition(new Vector2(relativePositionX, relativePositionY));
- }
+ ///
+ /// Return position in virtual resolution coordinate by given relative position [0, 1]
+ ///
+ ///
+ ///
+ ///
+ private Vector2 GetVirtualPosition(float relativePositionX, float relativePositionY)
+ {
+ return GetVirtualPosition(new Vector2(relativePositionX, relativePositionY));
+ }
- ///
- /// Return position in virtual resolution coordinate by given relative position [0, 1]
- ///
- ///
- private Vector2 GetVirtualPosition(Vector2 relativePosition)
- {
- return new Vector2(virtualResolution.X * relativePosition.X, virtualResolution.Y * relativePosition.Y);
- }
+ ///
+ /// Return position in virtual resolution coordinate by given relative position [0, 1]
+ ///
+ ///
+ private Vector2 GetVirtualPosition(Vector2 relativePosition)
+ {
+ return new Vector2(virtualResolution.X * relativePosition.X, virtualResolution.Y * relativePosition.Y);
+ }
- ///
- /// Get a varying value between [0,1] depending on the time
- ///
- /// the current time
- /// the varying value
- private static float GetVaryingValue(float time)
- {
- return (float)Math.Cos(time) * 0.5f + 0.5f;
- }
+ ///
+ /// Get a varying value between [0,1] depending on the time
+ ///
+ /// the current time
+ /// the varying value
+ private static float GetVaryingValue(float time)
+ {
+ return (float)Math.Cos(time) * 0.5f + 0.5f;
}
}
diff --git a/samples/Graphics/SpriteFonts/SpriteFonts.Game/SpriteFonts.Game.csproj b/samples/Graphics/SpriteFonts/SpriteFonts.Game/SpriteFonts.Game.csproj
index 6cf2ca4ab9..084e6095c5 100644
--- a/samples/Graphics/SpriteFonts/SpriteFonts.Game/SpriteFonts.Game.csproj
+++ b/samples/Graphics/SpriteFonts/SpriteFonts.Game/SpriteFonts.Game.csproj
@@ -2,6 +2,8 @@
net8.0
SpriteFonts
+ enable
+ latest
diff --git a/samples/Graphics/SpriteFonts/SpriteFonts.Windows/SpriteFonts.Windows.csproj b/samples/Graphics/SpriteFonts/SpriteFonts.Windows/SpriteFonts.Windows.csproj
index de60f19338..1d7e34430c 100644
--- a/samples/Graphics/SpriteFonts/SpriteFonts.Windows/SpriteFonts.Windows.csproj
+++ b/samples/Graphics/SpriteFonts/SpriteFonts.Windows/SpriteFonts.Windows.csproj
@@ -7,6 +7,8 @@
..\Bin\Windows\$(Configuration)\
false
STRIDE_PLATFORM_DESKTOP
+ enable
+ latest
$(MSBuildThisFileDirectory)..\SpriteFonts.sdpkg
diff --git a/samples/Graphics/SpriteStudioDemo/SpriteStudioDemo.Game/BeamScript.cs b/samples/Graphics/SpriteStudioDemo/SpriteStudioDemo.Game/BeamScript.cs
index 4febdda0e8..aa2b617d2d 100644
--- a/samples/Graphics/SpriteStudioDemo/SpriteStudioDemo.Game/BeamScript.cs
+++ b/samples/Graphics/SpriteStudioDemo/SpriteStudioDemo.Game/BeamScript.cs
@@ -1,34 +1,32 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
-using System.Threading.Tasks;
+
using Stride.Engine;
-using Stride.Physics;
-namespace SpriteStudioDemo
+namespace SpriteStudioDemo;
+
+public class BeamScript : AsyncScript
{
- public class BeamScript : AsyncScript
- {
- private const float maxWidthX = 8f + 2f;
- private const float minWidthX = -8f - 2f;
+ private const float maxWidthX = 8f + 2f;
+ private const float minWidthX = -8f - 2f;
- private bool dead;
+ private bool dead;
- public void Die()
- {
- dead = true;
- }
+ public void Die()
+ {
+ dead = true;
+ }
- public override async Task Execute()
+ public override async Task Execute()
+ {
+ while(Game.IsRunning)
{
- while(Game.IsRunning)
- {
- await Script.NextFrame();
+ await Script.NextFrame();
- if ((Entity.Transform.Position.X <= minWidthX) || (Entity.Transform.Position.X >= maxWidthX) || dead)
- {
- SceneSystem.SceneInstance.RootScene.Entities.Remove(Entity);
- return;
- }
+ if ((Entity.Transform.Position.X <= minWidthX) || (Entity.Transform.Position.X >= maxWidthX) || dead)
+ {
+ SceneSystem.SceneInstance.RootScene.Entities.Remove(Entity);
+ return;
}
}
}
diff --git a/samples/Graphics/SpriteStudioDemo/SpriteStudioDemo.Game/EnemyCollisionScript.cs b/samples/Graphics/SpriteStudioDemo/SpriteStudioDemo.Game/EnemyCollisionScript.cs
index 52dfe8d811..8ffc06dba8 100644
--- a/samples/Graphics/SpriteStudioDemo/SpriteStudioDemo.Game/EnemyCollisionScript.cs
+++ b/samples/Graphics/SpriteStudioDemo/SpriteStudioDemo.Game/EnemyCollisionScript.cs
@@ -1,38 +1,33 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
+
using Stride.Engine;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
using Stride.Physics;
-namespace SpriteStudioDemo
+namespace SpriteStudioDemo;
+
+public class EnemyCollisionScript : AsyncScript
{
- public class EnemyCollisionScript : AsyncScript
+ public override async Task Execute()
{
- public override async Task Execute()
+ var rigidbodyElement = Entity.Get();
+ var enemyScript = Entity.Get();
+
+ while (Game.IsRunning)
{
- var rigidbodyElement = Entity.Get();
- var enemyScript = Entity.Get();
+ var collision = await rigidbodyElement.NewCollision();
- while (Game.IsRunning)
+ if (collision.ColliderA.Entity.Name == "bullet" && !rigidbodyElement.IsTrigger) //if we are trigger we should ignore the bullet
{
- var collision = await rigidbodyElement.NewCollision();
-
- if (collision.ColliderA.Entity.Name == "bullet" && !rigidbodyElement.IsTrigger) //if we are trigger we should ignore the bullet
- {
- var script = collision.ColliderA.Entity.Get();
- script.Die();
- enemyScript.Explode();
- }
- else if (collision.ColliderB.Entity.Name == "bullet" && !rigidbodyElement.IsTrigger)
- {
- var script = collision.ColliderB.Entity.Get();
- script.Die();
- enemyScript.Explode();
- }
+ var script = collision.ColliderA.Entity.Get();
+ script.Die();
+ enemyScript.Explode();
+ }
+ else if (collision.ColliderB.Entity.Name == "bullet" && !rigidbodyElement.IsTrigger)
+ {
+ var script = collision.ColliderB.Entity.Get();
+ script.Die();
+ enemyScript.Explode();
}
}
}
diff --git a/samples/Graphics/SpriteStudioDemo/SpriteStudioDemo.Game/EnemyScript.cs b/samples/Graphics/SpriteStudioDemo/SpriteStudioDemo.Game/EnemyScript.cs
index 52970bd676..63d51bf873 100644
--- a/samples/Graphics/SpriteStudioDemo/SpriteStudioDemo.Game/EnemyScript.cs
+++ b/samples/Graphics/SpriteStudioDemo/SpriteStudioDemo.Game/EnemyScript.cs
@@ -1,111 +1,109 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
+
+using System.Diagnostics;
+using Stride.Animations;
using Stride.Core.Mathematics;
using Stride.Engine;
using Stride.Physics;
-using System;
-using System.Threading.Tasks;
-using Stride.Animations;
-using System.Diagnostics;
-namespace SpriteStudioDemo
-{
- public class EnemyScript : AsyncScript
- {
- private const float enemyInitPositionY = 20;
-
- // enemy position
- private const float gameWidthX = 16f; // from -8f to 8f
- private const float gameWidthHalfX = gameWidthX / 2f;
+namespace SpriteStudioDemo;
- private const float enemyLifeBase = 3.0f;
- private float enemyLife = 3.0f;
+public class EnemyScript : AsyncScript
+{
+ private const float enemyInitPositionY = 20;
- private RigidbodyComponent rigidbodyElement;
- private AnimationComponent animationComponent;
+ // enemy position
+ private const float gameWidthX = 16f; // from -8f to 8f
+ private const float gameWidthHalfX = gameWidthX / 2f;
- PlayingAnimation playingAnimation;
+ private const float enemyLifeBase = 3.0f;
+ private float enemyLife = 3.0f;
- // random
- private static readonly int seed = Environment.TickCount;
- private static readonly Random enemyRandomLocal = new Random(seed);
+ private RigidbodyComponent rigidbodyElement;
+ private AnimationComponent animationComponent;
- private async Task Reset()
- {
- rigidbodyElement.IsKinematic = true; //sto motion and set kinematic (listen to our transform changes)
- rigidbodyElement.IsTrigger = true; //set as ghost (bullets will go thru)
+ PlayingAnimation playingAnimation;
- Entity.Transform.Position.Y = enemyInitPositionY;
+ // random
+ private static readonly int seed = Environment.TickCount;
+ private static readonly Random enemyRandomLocal = new(seed);
- var random = enemyRandomLocal;
- // Appearance position
- Entity.Transform.Position.X = (((float)(random.NextDouble())) * gameWidthX) - gameWidthHalfX;
- // Waiting time
- enemyLife = enemyLifeBase + (enemyLifeBase * (float)random.NextDouble());
+ private async Task Reset()
+ {
+ rigidbodyElement.IsKinematic = true; //sto motion and set kinematic (listen to our transform changes)
+ rigidbodyElement.IsTrigger = true; //set as ghost (bullets will go thru)
- Entity.Transform.UpdateWorldMatrix();
- rigidbodyElement.UpdatePhysicsTransformation();
+ Entity.Transform.Position.Y = enemyInitPositionY;
- if (playingAnimation == null || playingAnimation.Name != "Wait")
- {
- playingAnimation = animationComponent.Play("Wait");
- }
+ var random = enemyRandomLocal;
+ // Appearance position
+ Entity.Transform.Position.X = (((float)(random.NextDouble())) * gameWidthX) - gameWidthHalfX;
+ // Waiting time
+ enemyLife = enemyLifeBase + (enemyLifeBase * (float)random.NextDouble());
- await Script.NextFrame();
+ Entity.Transform.UpdateWorldMatrix();
+ rigidbodyElement.UpdatePhysicsTransformation();
- rigidbodyElement.IsKinematic = false;
- rigidbodyElement.IsTrigger = false;
- rigidbodyElement.Activate();
+ if (playingAnimation is not { Name: "Wait" })
+ {
+ playingAnimation = animationComponent.Play("Wait");
}
- Task exploding;
+ await Script.NextFrame();
- public void Explode()
- {
- rigidbodyElement.IsKinematic = true;
- rigidbodyElement.IsTrigger = true;
-
- if (playingAnimation == null || playingAnimation.Name != "Dead")
- {
- playingAnimation = animationComponent.Play("Dead");
- }
+ rigidbodyElement.IsKinematic = false;
+ rigidbodyElement.IsTrigger = false;
+ rigidbodyElement.Activate();
+ }
- exploding = WaitMs(1500);
- }
+ Task exploding;
- readonly Stopwatch _watch = Stopwatch.StartNew();
+ public void Explode()
+ {
+ rigidbodyElement.IsKinematic = true;
+ rigidbodyElement.IsTrigger = true;
- public async Task WaitMs(int ms)
+ if (playingAnimation is not { Name: "Dead" })
{
- var start = _watch.ElapsedMilliseconds;
- while (_watch.ElapsedMilliseconds < start + ms)
- {
- await Script.NextFrame();
- }
+ playingAnimation = animationComponent.Play("Dead");
}
- public override async Task Execute()
+ exploding = WaitMs(1500);
+ }
+
+ readonly Stopwatch _watch = Stopwatch.StartNew();
+
+ public async Task WaitMs(int ms)
+ {
+ var start = _watch.ElapsedMilliseconds;
+ while (_watch.ElapsedMilliseconds < start + ms)
{
- animationComponent = Entity.Get();
+ await Script.NextFrame();
+ }
+ }
- rigidbodyElement = Entity.Get();
- rigidbodyElement.LinearFactor = new Vector3(0, 1, 0); //allow only Y motion
- rigidbodyElement.AngularFactor = new Vector3(0, 0, 0); //allow no rotation
+ public override async Task Execute()
+ {
+ animationComponent = Entity.Get();
- await Reset();
+ rigidbodyElement = Entity.Get();
+ rigidbodyElement.LinearFactor = new Vector3(0, 1, 0); //allow only Y motion
+ rigidbodyElement.AngularFactor = new Vector3(0, 0, 0); //allow no rotation
- while (Game.IsRunning)
- {
- await WaitMs((int)(enemyLife * 1000));
+ await Reset();
- if (exploding != null)
- {
- await exploding;
- exploding = null;
- }
+ while (Game.IsRunning)
+ {
+ await WaitMs((int)(enemyLife * 1000));
- await Reset();
+ if (exploding != null)
+ {
+ await exploding;
+ exploding = null;
}
+
+ await Reset();
}
}
}
diff --git a/samples/Graphics/SpriteStudioDemo/SpriteStudioDemo.Game/GuiScript.cs b/samples/Graphics/SpriteStudioDemo/SpriteStudioDemo.Game/GuiScript.cs
index 778bdc504a..e1a07872c2 100644
--- a/samples/Graphics/SpriteStudioDemo/SpriteStudioDemo.Game/GuiScript.cs
+++ b/samples/Graphics/SpriteStudioDemo/SpriteStudioDemo.Game/GuiScript.cs
@@ -1,5 +1,6 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// 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.Graphics;
@@ -7,29 +8,28 @@
using Stride.UI.Controls;
using Stride.UI.Panels;
-namespace SpriteStudioDemo
+namespace SpriteStudioDemo;
+
+///
+/// The GUI script
+///
+public class GuiScript : StartupScript
{
- ///
- /// The GUI script
- ///
- public class GuiScript : StartupScript
- {
public SpriteFont Font { get; set; }
- public override void Start()
+ public override void Start()
+ {
+ var font = Font;
+ var textBlock = new TextBlock
{
- var font = Font;
- var textBlock = new TextBlock
- {
- Font = font,
- TextSize = 18,
- TextColor = Color.Gold,
- Text = "Shoot : Touch in a vertical section where the Agent resides\n" +
- "Move : Touch in the screen on the corresponding side of the Agent",
- };
- textBlock.SetCanvasRelativePosition(new Vector3(0.008f, 0.9f, 0));
+ Font = font,
+ TextSize = 18,
+ TextColor = Color.Gold,
+ Text = "Shoot : Touch in a vertical section where the Agent resides\n" +
+ "Move : Touch in the screen on the corresponding side of the Agent",
+ };
+ textBlock.SetCanvasRelativePosition(new Vector3(0.008f, 0.9f, 0));
- Entity.Get().Page = new UIPage { RootElement = new Canvas { Children = { textBlock } } };
- }
+ Entity.Get().Page = new UIPage { RootElement = new Canvas { Children = { textBlock } } };
}
}
diff --git a/samples/Graphics/SpriteStudioDemo/SpriteStudioDemo.Game/PlayerScript.cs b/samples/Graphics/SpriteStudioDemo/SpriteStudioDemo.Game/PlayerScript.cs
index 0322c1b091..de13e0eed0 100644
--- a/samples/Graphics/SpriteStudioDemo/SpriteStudioDemo.Game/PlayerScript.cs
+++ b/samples/Graphics/SpriteStudioDemo/SpriteStudioDemo.Game/PlayerScript.cs
@@ -1,236 +1,232 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
-using System;
+
+using Stride.Animations;
using Stride.Core;
using Stride.Core.Mathematics;
-using Stride.Animations;
using Stride.Engine;
using Stride.Graphics;
using Stride.Input;
using Stride.Physics;
using Stride.Rendering.Sprites;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading.Tasks;
-namespace SpriteStudioDemo
+namespace SpriteStudioDemo;
+
+public class PlayerScript : AsyncScript
{
- public class PlayerScript : AsyncScript
+ private enum AgentAnimation
{
- private enum AgentAnimation
- {
- Run,
- Idle,
- Shoot
- }
+ Run,
+ Idle,
+ Shoot
+ }
- // InputState represents all command inputs from a user
- private enum InputState
- {
- None,
- RunLeft,
- RunRight,
- Shoot,
- }
+ // InputState represents all command inputs from a user
+ private enum InputState
+ {
+ None,
+ RunLeft,
+ RunRight,
+ Shoot,
+ }
+
+ // TODO centralize
+ private const float gameWidthX = 16f; // from -8f to 8f
- // TODO centralize
- private const float gameWidthX = 16f; // from -8f to 8f
+ private const float gameWidthHalfX = gameWidthX / 2f;
- private const float gameWidthHalfX = gameWidthX / 2f;
+ private const int AgentMoveDistance = 10; // virtual resolution unit/second
+ private const float AgentShootDelay = 0.3f; // second
- private const int AgentMoveDistance = 10; // virtual resolution unit/second
- private const float AgentShootDelay = 0.3f; // second
+ private static readonly Dictionary AnimationFps = new() { { AgentAnimation.Run, 12 }, { AgentAnimation.Idle, 7 }, { AgentAnimation.Shoot, 15 } };
- private static readonly Dictionary AnimationFps = new Dictionary { { AgentAnimation.Run, 12 }, { AgentAnimation.Idle, 7 }, { AgentAnimation.Shoot, 15 } };
+ private SpriteComponent agentSpriteComponent;
+ private SpriteSheet spriteSheet;
- private SpriteComponent agentSpriteComponent;
- private SpriteSheet spriteSheet;
+ // Touch input state
+ private PointerEvent pointerState;
- // Touch input state
- private PointerEvent pointerState;
+ private bool isPointerDown; // Cache state if a user is current touching the screen.
- private bool isPointerDown; // Cache state if a user is current touching the screen.
+ [DataMember(Mask = LiveScriptingMask)] // keep the value when reloading the script (live-scripting)
+ private bool isAgentFacingRight;
- [DataMember(Mask = LiveScriptingMask)] // keep the value when reloading the script (live-scripting)
- private bool isAgentFacingRight;
+ [DataMember(Mask = LiveScriptingMask)] // keep the value when reloading the script (live-scripting)
+ private float shootDelayCounter;
- [DataMember(Mask = LiveScriptingMask)] // keep the value when reloading the script (live-scripting)
- private float shootDelayCounter;
+ [DataMember(Mask = LiveScriptingMask)] // keep the value when reloading the script (live-scripting)
+ private AgentAnimation currentAgentAnimation;
- [DataMember(Mask = LiveScriptingMask)] // keep the value when reloading the script (live-scripting)
- private AgentAnimation currentAgentAnimation;
+ private AgentAnimation CurrentAgentAnimation { get; set; }
- private AgentAnimation CurrentAgentAnimation { get; set; }
-
- public SpriteSheet BulletSheet { get; set; }
-
- public PhysicsColliderShape BulletColliderShape { get; set; }
+ public SpriteSheet BulletSheet { get; set; }
- public override async Task Execute()
+ public PhysicsColliderShape BulletColliderShape { get; set; }
+
+ public override async Task Execute()
+ {
+ spriteSheet = BulletSheet;
+ agentSpriteComponent = Entity.Get();
+ var animComponent = Entity.Get();
+ PlayingAnimation playingAnimation = null;
+
+ // Calculate offset of the bullet from the Agent if he is facing left and right side // TODO improve this
+ var bulletOffset = new Vector3(1.3f, 1.65f, 0f);
+
+ // Initialize game entities
+ if (!IsLiveReloading)
{
- spriteSheet = BulletSheet;
- agentSpriteComponent = Entity.Get();
- var animComponent = Entity.Get();
- PlayingAnimation playingAnimation = null;
+ shootDelayCounter = 0f;
+ isAgentFacingRight = true;
+ currentAgentAnimation = AgentAnimation.Idle;
+ }
+ CurrentAgentAnimation = currentAgentAnimation;
- // Calculate offset of the bullet from the Agent if he is facing left and right side // TODO improve this
- var bulletOffset = new Vector3(1.3f, 1.65f, 0f);
+ var normalScaleX = Entity.Transform.Scale.X;
- // Initialize game entities
- if (!IsLiveReloading)
- {
- shootDelayCounter = 0f;
- isAgentFacingRight = true;
- currentAgentAnimation = AgentAnimation.Idle;
- }
- CurrentAgentAnimation = currentAgentAnimation;
+ var bulletCS = BulletColliderShape;
+
+ Task animTask = null;
- var normalScaleX = Entity.Transform.Scale.X;
+ while (Game.IsRunning)
+ {
+ await Script.NextFrame();
- var bulletCS = BulletColliderShape;
+ var inputState = GetKeyboardInputState();
- Task animTask = null;
+ if (inputState == InputState.None)
+ inputState = GetPointerInputState();
- while (Game.IsRunning)
+ if (inputState is InputState.RunLeft or InputState.RunRight)
{
- await Script.NextFrame();
+ // Update Agent's position
+ var dt = (float)Game.UpdateTime.Elapsed.TotalSeconds;
+
+ Entity.Transform.Position.X += ((inputState == InputState.RunRight) ? AgentMoveDistance : -AgentMoveDistance) * dt;
+
+ if (Entity.Transform.Position.X < -gameWidthHalfX)
+ Entity.Transform.Position.X = -gameWidthHalfX;
+
+ if (Entity.Transform.Position.X > gameWidthHalfX)
+ Entity.Transform.Position.X = gameWidthHalfX;
- var inputState = GetKeyboardInputState();
+ isAgentFacingRight = inputState == InputState.RunRight;
- if (inputState == InputState.None)
- inputState = GetPointerInputState();
+ // If agent face left, flip the sprite
+ Entity.Transform.Scale.X = isAgentFacingRight ? normalScaleX : -normalScaleX;
- if (inputState == InputState.RunLeft || inputState == InputState.RunRight)
+ // Update the sprite animation and state
+ CurrentAgentAnimation = AgentAnimation.Run;
+ if (playingAnimation is not { Name: "Run" })
{
- // Update Agent's position
- var dt = (float)Game.UpdateTime.Elapsed.TotalSeconds;
+ playingAnimation = animComponent.Play("Run");
+ }
+ }
+ else if (inputState == InputState.Shoot)
+ {
+ if (animTask is { IsCompleted: false }) continue;
+ if (animTask is { IsCompleted: true }) playingAnimation = null;
- Entity.Transform.Position.X += ((inputState == InputState.RunRight) ? AgentMoveDistance : -AgentMoveDistance) * dt;
+ animTask = null;
- if (Entity.Transform.Position.X < -gameWidthHalfX)
- Entity.Transform.Position.X = -gameWidthHalfX;
+ var rb = new RigidbodyComponent { CanCollideWith = CollisionFilterGroupFlags.CustomFilter1, CollisionGroup = CollisionFilterGroups.DefaultFilter };
+ rb.ColliderShapes.Add(new ColliderShapeAssetDesc { Shape = bulletCS });
- if (Entity.Transform.Position.X > gameWidthHalfX)
- Entity.Transform.Position.X = gameWidthHalfX;
+ // Spawns a new bullet
+ var bullet = new Entity
+ {
+ new SpriteComponent { SpriteProvider = SpriteFromSheet.Create(spriteSheet, "bullet") },
+ rb,
+ new BeamScript()
+ };
+ bullet.Name = "bullet";
- isAgentFacingRight = inputState == InputState.RunRight;
+ bullet.Transform.Position = (isAgentFacingRight) ? Entity.Transform.Position + bulletOffset : Entity.Transform.Position + (bulletOffset * new Vector3(-1, 1, 1));
+ bullet.Transform.UpdateWorldMatrix();
- // If agent face left, flip the sprite
- Entity.Transform.Scale.X = isAgentFacingRight ? normalScaleX : -normalScaleX;
+ SceneSystem.SceneInstance.RootScene.Entities.Add(bullet);
- // Update the sprite animation and state
- CurrentAgentAnimation = AgentAnimation.Run;
- if (playingAnimation == null || playingAnimation.Name != "Run")
- {
- playingAnimation = animComponent.Play("Run");
- }
- }
- else if (inputState == InputState.Shoot)
+ rb.LinearFactor = new Vector3(1, 0, 0);
+ rb.AngularFactor = new Vector3(0, 0, 0);
+ rb.ApplyImpulse(isAgentFacingRight ? new Vector3(25, 0, 0) : new Vector3(-25, 0, 0));
+
+ // Start animation for shooting
+ CurrentAgentAnimation = AgentAnimation.Shoot;
+ if (playingAnimation is not { Name: "Attack" })
{
- if(animTask != null && !animTask.IsCompleted) continue;
- if (animTask != null && animTask.IsCompleted) playingAnimation = null;
-
- animTask = null;
-
- var rb = new RigidbodyComponent { CanCollideWith = CollisionFilterGroupFlags.CustomFilter1, CollisionGroup = CollisionFilterGroups.DefaultFilter };
- rb.ColliderShapes.Add(new ColliderShapeAssetDesc { Shape = bulletCS });
-
- // Spawns a new bullet
- var bullet = new Entity
- {
- new SpriteComponent { SpriteProvider = SpriteFromSheet.Create(spriteSheet, "bullet") },
- rb,
- new BeamScript()
- };
- bullet.Name = "bullet";
-
- bullet.Transform.Position = (isAgentFacingRight) ? Entity.Transform.Position + bulletOffset : Entity.Transform.Position + (bulletOffset * new Vector3(-1, 1, 1));
- bullet.Transform.UpdateWorldMatrix();
-
- SceneSystem.SceneInstance.RootScene.Entities.Add(bullet);
-
- rb.LinearFactor = new Vector3(1, 0, 0);
- rb.AngularFactor = new Vector3(0, 0, 0);
- rb.ApplyImpulse(isAgentFacingRight ? new Vector3(25, 0, 0) : new Vector3(-25, 0, 0));
-
- // Start animation for shooting
- CurrentAgentAnimation = AgentAnimation.Shoot;
- if (playingAnimation == null || playingAnimation.Name != "Attack")
- {
- playingAnimation = animComponent.Play("Attack");
- animTask = animComponent.Ended(playingAnimation);
- }
+ playingAnimation = animComponent.Play("Attack");
+ animTask = animComponent.Ended(playingAnimation);
}
- else
+ }
+ else
+ {
+ CurrentAgentAnimation = AgentAnimation.Idle;
+ if (playingAnimation is not { Name: "Stance" })
{
- CurrentAgentAnimation = AgentAnimation.Idle;
- if (playingAnimation == null || playingAnimation.Name != "Stance")
- {
- playingAnimation = animComponent.Play("Stance");
- }
+ playingAnimation = animComponent.Play("Stance");
}
}
}
+ }
- ///
- /// Determine input from a user from a keyboard.
- /// Left and Right arrow for running to left and right direction, Space for shooting.
- ///
- ///
- private InputState GetKeyboardInputState()
- {
- if (Input.IsKeyDown(Keys.Right))
- return InputState.RunRight;
- if (Input.IsKeyDown(Keys.Left))
- return InputState.RunLeft;
+ ///
+ /// Determine input from a user from a keyboard.
+ /// Left and Right arrow for running to left and right direction, Space for shooting.
+ ///
+ ///
+ private InputState GetKeyboardInputState()
+ {
+ if (Input.IsKeyDown(Keys.Right))
+ return InputState.RunRight;
+ if (Input.IsKeyDown(Keys.Left))
+ return InputState.RunLeft;
- return Input.IsKeyDown(Keys.Space) ? InputState.Shoot : InputState.None;
- }
+ return Input.IsKeyDown(Keys.Space) ? InputState.Shoot : InputState.None;
+ }
- ///
- /// Determine input from a user from Pointer (Touch/Mouse).
- /// It analyses the input from a user, and transform it to InputState using in the game, which is then returned.
- ///
- ///
- private InputState GetPointerInputState()
+ ///
+ /// Determine input from a user from Pointer (Touch/Mouse).
+ /// It analyses the input from a user, and transform it to InputState using in the game, which is then returned.
+ ///
+ ///
+ private InputState GetPointerInputState()
+ {
+ // Get new state of Pointer (Touch input)
+ if (Input.PointerEvents.Any())
{
- // Get new state of Pointer (Touch input)
- if (Input.PointerEvents.Any())
- {
- var lastPointer = Input.PointerEvents.Last();
- if (lastPointer.EventType == PointerEventType.Pressed)
- isPointerDown = true;
- else if (lastPointer.EventType == PointerEventType.Released)
- isPointerDown = false;
- pointerState = lastPointer;
- }
+ var lastPointer = Input.PointerEvents.Last();
+ if (lastPointer.EventType == PointerEventType.Pressed)
+ isPointerDown = true;
+ else if (lastPointer.EventType == PointerEventType.Released)
+ isPointerDown = false;
+ pointerState = lastPointer;
+ }
- // If a user does not touch the screen, there is not input
- if (!isPointerDown)
- {
- return InputState.None;
- }
-
- // Transform pointer's position from normorlize coordinate to virtual resolution coordinate
- var resolution = new Vector2(GraphicsDevice.Presenter.BackBuffer.Width, GraphicsDevice.Presenter.BackBuffer.Height);
- var virtualCoordinatePointerPositionA = resolution.X * (pointerState.Position.X + 0.05f);
- var virtualCoordinatePointerPositionB = resolution.X * (pointerState.Position.X - 0.05f);
-
- var virtualX = VirtualCoordToPixel(Entity.Transform.Position.X);
-
- // Check if the touch position is in the x-axis region of the agent's sprite; if so, input is shoot
- if (virtualX <= virtualCoordinatePointerPositionA && virtualCoordinatePointerPositionB <= virtualX)
- {
- return InputState.Shoot;
- }
-
- // Check if a pointer falls left or right of the screen, which would correspond to Run to the left or right respectively
- return ((pointerState.Position.X) <= virtualX / resolution.X) ? InputState.RunLeft : InputState.RunRight;
+ // If a user does not touch the screen, there is not input
+ if (!isPointerDown)
+ {
+ return InputState.None;
}
- private float VirtualCoordToPixel(float virtualCoord)
+ // Transform pointer's position from normorlize coordinate to virtual resolution coordinate
+ var resolution = new Vector2(GraphicsDevice.Presenter.BackBuffer.Width, GraphicsDevice.Presenter.BackBuffer.Height);
+ var virtualCoordinatePointerPositionA = resolution.X * (pointerState.Position.X + 0.05f);
+ var virtualCoordinatePointerPositionB = resolution.X * (pointerState.Position.X - 0.05f);
+
+ var virtualX = VirtualCoordToPixel(Entity.Transform.Position.X);
+
+ // Check if the touch position is in the x-axis region of the agent's sprite; if so, input is shoot
+ if (virtualX <= virtualCoordinatePointerPositionA && virtualCoordinatePointerPositionB <= virtualX)
{
- return (virtualCoord + (gameWidthHalfX)) / gameWidthX * GraphicsDevice.Presenter.BackBuffer.Width;
+ return InputState.Shoot;
}
+
+ // Check if a pointer falls left or right of the screen, which would correspond to Run to the left or right respectively
+ return ((pointerState.Position.X) <= virtualX / resolution.X) ? InputState.RunLeft : InputState.RunRight;
+ }
+
+ private float VirtualCoordToPixel(float virtualCoord)
+ {
+ return (virtualCoord + (gameWidthHalfX)) / gameWidthX * GraphicsDevice.Presenter.BackBuffer.Width;
}
}
diff --git a/samples/Graphics/SpriteStudioDemo/SpriteStudioDemo.Game/SpriteStudioDemo.Game.csproj b/samples/Graphics/SpriteStudioDemo/SpriteStudioDemo.Game/SpriteStudioDemo.Game.csproj
index d0ec3408f4..3fb20c3d8e 100644
--- a/samples/Graphics/SpriteStudioDemo/SpriteStudioDemo.Game/SpriteStudioDemo.Game.csproj
+++ b/samples/Graphics/SpriteStudioDemo/SpriteStudioDemo.Game/SpriteStudioDemo.Game.csproj
@@ -2,6 +2,8 @@
net8.0
SpriteStudioDemo
+ enable
+ latest
diff --git a/samples/Graphics/SpriteStudioDemo/SpriteStudioDemo.Windows/SpriteStudioDemo.Windows.csproj b/samples/Graphics/SpriteStudioDemo/SpriteStudioDemo.Windows/SpriteStudioDemo.Windows.csproj
index e5af06c354..26e6cb24cd 100644
--- a/samples/Graphics/SpriteStudioDemo/SpriteStudioDemo.Windows/SpriteStudioDemo.Windows.csproj
+++ b/samples/Graphics/SpriteStudioDemo/SpriteStudioDemo.Windows/SpriteStudioDemo.Windows.csproj
@@ -7,6 +7,8 @@
..\Bin\Windows\$(Configuration)\
false
STRIDE_PLATFORM_DESKTOP
+ enable
+ latest
$(MSBuildThisFileDirectory)..\SpriteStudioDemo.sdpkg
diff --git a/samples/Input/GravitySensor/GravitySensor.Game/BallScript.cs b/samples/Input/GravitySensor/GravitySensor.Game/BallScript.cs
index b0c169cad3..7c859ecc8a 100644
--- a/samples/Input/GravitySensor/GravitySensor.Game/BallScript.cs
+++ b/samples/Input/GravitySensor/GravitySensor.Game/BallScript.cs
@@ -1,16 +1,16 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
+
using Stride.Animations;
using Stride.Engine;
-namespace GravitySensor
+namespace GravitySensor;
+
+public class BallScript : StartupScript
{
- public class BallScript : StartupScript
+ public override void Start()
{
- public override void Start()
- {
- var sprite = Entity.Get();
- SpriteAnimation.Play(sprite, 0, sprite.SpriteProvider.SpritesCount - 1, AnimationRepeatMode.LoopInfinite, 2);
- }
+ var sprite = Entity.Get();
+ SpriteAnimation.Play(sprite, 0, sprite.SpriteProvider.SpritesCount - 1, AnimationRepeatMode.LoopInfinite, 2);
}
}
diff --git a/samples/Input/GravitySensor/GravitySensor.Game/BounceScript.cs b/samples/Input/GravitySensor/GravitySensor.Game/BounceScript.cs
index 4d9430a669..8da62b1c8a 100644
--- a/samples/Input/GravitySensor/GravitySensor.Game/BounceScript.cs
+++ b/samples/Input/GravitySensor/GravitySensor.Game/BounceScript.cs
@@ -1,20 +1,20 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
+
using Stride.Engine;
-namespace GravitySensor
+namespace GravitySensor;
+
+///
+/// This script will set the restitution of each rigidbody element to 1.0f to allow the entity to bounce
+///
+public class BounceScript : StartupScript
{
- ///
- /// This script will set the restitution of each rigidbody element to 1.0f to allow the entity to bounce
- ///
- public class BounceScript : StartupScript
+ public override void Start()
{
- public override void Start()
+ foreach (var physicsElement in Entity.GetAll())
{
- foreach (var physicsElement in Entity.GetAll())
- {
- physicsElement.Restitution = 0.9f;
- }
+ physicsElement.Restitution = 0.9f;
}
}
}
diff --git a/samples/Input/GravitySensor/GravitySensor.Game/GravityScript.cs b/samples/Input/GravitySensor/GravitySensor.Game/GravityScript.cs
index c0c86adc7e..2557ed73ae 100644
--- a/samples/Input/GravitySensor/GravitySensor.Game/GravityScript.cs
+++ b/samples/Input/GravitySensor/GravitySensor.Game/GravityScript.cs
@@ -1,58 +1,58 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
+
using Stride.Core.Mathematics;
-using Stride.Input;
using Stride.Engine;
+using Stride.Input;
using Stride.Physics;
-namespace GravitySensor
+namespace GravitySensor;
+
+///
+/// This script will handle keyboard inputs and set the scene gravity according to those inputs
+///
+public class GravityScript : SyncScript
{
- ///
- /// This script will handle keyboard inputs and set the scene gravity according to those inputs
- ///
- public class GravityScript : SyncScript
+ private Simulation simulation;
+
+ public override void Start()
{
- private Simulation simulation;
+ simulation = this.GetSimulation();
+ simulation.Gravity = new Vector3(0, 0, 0);
- public override void Start()
- {
- simulation = this.GetSimulation();
- simulation.Gravity = new Vector3(0, 0, 0);
+ if (Input.Gravity != null) // enables the orientation sensor.
+ Input.Gravity.IsEnabled = true;
+ }
+
+ public override void Update()
+ {
+ // no keys down and default gravity
+ var gravity = new Vector3(0, 0, 0);
- if (Input.Gravity != null) // enables the orientation sensor.
- Input.Gravity.IsEnabled = true;
+ // Get the gravity vector from the sensor
+ if (Input.Gravity?.IsEnabled ?? false)
+ {
+ var originalVector = Input.Gravity.Vector;
+ gravity = new Vector3(originalVector.Z, originalVector.X, -originalVector.Y); // this rotation includes: (1) rotation of the scene (up = Z axis), (2) rotation of the display (Landscape)
}
- public override void Update()
+ if (Input.IsKeyDown(Keys.Up))
+ {
+ gravity += new Vector3(0, 10, 0.0f);
+ }
+ if (Input.IsKeyDown(Keys.Left))
+ {
+ gravity += new Vector3(-10, 0, 0.0f);
+ }
+ if (Input.IsKeyDown(Keys.Down))
+ {
+ gravity += new Vector3(0, -10, 0.0f);
+ }
+ if (Input.IsKeyDown(Keys.Right))
{
- // no keys down and default gravity
- var gravity = new Vector3(0, 0, 0);
-
- // Get the gravity vector from the sensor
- if (Input.Gravity?.IsEnabled ?? false)
- {
- var originalVector = Input.Gravity.Vector;
- gravity = new Vector3(originalVector.Z, originalVector.X, -originalVector.Y); // this rotation includes: (1) rotation of the scene (up = Z axis), (2) rotation of the display (Landscape)
- }
-
- if (Input.IsKeyDown(Keys.Up))
- {
- gravity += new Vector3(0, 10, 0.0f);
- }
- if (Input.IsKeyDown(Keys.Left))
- {
- gravity += new Vector3(-10, 0, 0.0f);
- }
- if (Input.IsKeyDown(Keys.Down))
- {
- gravity += new Vector3(0, -10, 0.0f);
- }
- if (Input.IsKeyDown(Keys.Right))
- {
- gravity += new Vector3(10, 0, 0.0f);
- }
-
- simulation.Gravity = gravity;
+ gravity += new Vector3(10, 0, 0.0f);
}
+
+ simulation.Gravity = gravity;
}
}
diff --git a/samples/Input/GravitySensor/GravitySensor.Game/GravitySensor.Game.csproj b/samples/Input/GravitySensor/GravitySensor.Game/GravitySensor.Game.csproj
index 4b42c7fef9..51d069cc1a 100644
--- a/samples/Input/GravitySensor/GravitySensor.Game/GravitySensor.Game.csproj
+++ b/samples/Input/GravitySensor/GravitySensor.Game/GravitySensor.Game.csproj
@@ -2,6 +2,8 @@
net8.0
GravitySensor
+ enable
+ latest
diff --git a/samples/Input/GravitySensor/GravitySensor.Game/GuiScript.cs b/samples/Input/GravitySensor/GravitySensor.Game/GuiScript.cs
index 349a70352f..af435c1561 100644
--- a/samples/Input/GravitySensor/GravitySensor.Game/GuiScript.cs
+++ b/samples/Input/GravitySensor/GravitySensor.Game/GuiScript.cs
@@ -1,6 +1,6 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
-using System.Threading.Tasks;
+
using Stride.Core.Mathematics;
using Stride.Engine;
using Stride.Graphics;
@@ -9,42 +9,41 @@
using Stride.UI.Controls;
using Stride.UI.Panels;
-namespace GravitySensor
+namespace GravitySensor;
+
+public class GuiScript : AsyncScript
{
- public class GuiScript : AsyncScript
+ public SpriteFont Font;
+
+ public override async Task Execute()
{
- public SpriteFont Font;
+ if (Input.Gravity != null) // do not display any message when orientation sensor is available
+ return;
+
+ if (IsLiveReloading)
+ return;
- public override async Task Execute()
+ var textBlock = new TextBlock
{
- if (Input.Gravity != null) // do not display any message when orientation sensor is available
- return;
-
- if (IsLiveReloading)
- return;
-
- var textBlock = new TextBlock
- {
- Text = "Use arrows to play with gravity!",
- Font = Font,
- TextColor = Color.White,
- TextSize = 40
- };
- textBlock.SetCanvasPinOrigin(new Vector3(0.5f, 0.5f, 0));
- textBlock.SetCanvasRelativePosition(new Vector3(0.5f, 0.75f, 0f));
- Entity.Get().Page = new UIPage { RootElement = new Canvas { Children = { textBlock } } };
-
- while (Game.IsRunning)
- {
- await Script.NextFrame();
-
- if (!Input.IsKeyPressed(Keys.Left) && !Input.IsKeyPressed(Keys.Right) && !Input.IsKeyPressed(Keys.Up) &&
- !Input.IsKeyPressed(Keys.Down))
- continue;
-
- Entity.Get().Page = null;
- return;
- }
+ Text = "Use arrows to play with gravity!",
+ Font = Font,
+ TextColor = Color.White,
+ TextSize = 40
+ };
+ textBlock.SetCanvasPinOrigin(new Vector3(0.5f, 0.5f, 0));
+ textBlock.SetCanvasRelativePosition(new Vector3(0.5f, 0.75f, 0f));
+ Entity.Get().Page = new UIPage { RootElement = new Canvas { Children = { textBlock } } };
+
+ while (Game.IsRunning)
+ {
+ await Script.NextFrame();
+
+ if (!Input.IsKeyPressed(Keys.Left) && !Input.IsKeyPressed(Keys.Right) && !Input.IsKeyPressed(Keys.Up) &&
+ !Input.IsKeyPressed(Keys.Down))
+ continue;
+
+ Entity.Get().Page = null;
+ return;
}
}
}
diff --git a/samples/Input/GravitySensor/GravitySensor.Game/NoSleepScript.cs b/samples/Input/GravitySensor/GravitySensor.Game/NoSleepScript.cs
index be8baa69de..72025e3c47 100644
--- a/samples/Input/GravitySensor/GravitySensor.Game/NoSleepScript.cs
+++ b/samples/Input/GravitySensor/GravitySensor.Game/NoSleepScript.cs
@@ -1,27 +1,26 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
-using System.Threading.Tasks;
+
using Stride.Engine;
using Stride.Physics;
-namespace GravitySensor
+namespace GravitySensor;
+
+///
+/// This script will make sure that all the physics elements of this entity will never be set to sleep status
+/// The physics engine will sometimes set colliders to sleep state to reduce processor usage when there is no motion happening
+/// Those colliders will wake up if an external (an other collider hitting us) collision happens, but in this case we need to prevent this behavior totally,
+/// as there will be no external collision once the motion is 0.
+///
+public class NoSleepScript : AsyncScript
{
- ///
- /// This script will make sure that all the physics elements of this entity will never be set to sleep status
- /// The physics engine will sometimes set colliders to sleep state to reduce processor usage when there is no motion happening
- /// Those colliders will wake up if an external (an other collider hitting us) collision happens, but in this case we need to prevent this behavior totally,
- /// as there will be no external collision once the motion is 0.
- ///
- public class NoSleepScript : AsyncScript
+ public override Task Execute()
{
- public override Task Execute()
+ foreach (var physicsElement in Entity.GetAll())
{
- foreach (var physicsElement in Entity.GetAll())
- {
- physicsElement.CanSleep = false;
- }
-
- return Task.FromResult(0);
+ physicsElement.CanSleep = false;
}
+
+ return Task.FromResult(0);
}
}
diff --git a/samples/Input/GravitySensor/GravitySensor.Windows/GravitySensor.Windows.csproj b/samples/Input/GravitySensor/GravitySensor.Windows/GravitySensor.Windows.csproj
index af060a650b..d6c11be2ae 100644
--- a/samples/Input/GravitySensor/GravitySensor.Windows/GravitySensor.Windows.csproj
+++ b/samples/Input/GravitySensor/GravitySensor.Windows/GravitySensor.Windows.csproj
@@ -7,6 +7,8 @@
..\Bin\Windows\$(Configuration)\
false
STRIDE_PLATFORM_DESKTOP
+ enable
+ latest
$(MSBuildThisFileDirectory)..\GravitySensor.sdpkg
diff --git a/samples/Input/TouchInputs/TouchInputs.Game/TouchInputs.Game.csproj b/samples/Input/TouchInputs/TouchInputs.Game/TouchInputs.Game.csproj
index 18372b0eab..a252f32031 100644
--- a/samples/Input/TouchInputs/TouchInputs.Game/TouchInputs.Game.csproj
+++ b/samples/Input/TouchInputs/TouchInputs.Game/TouchInputs.Game.csproj
@@ -2,6 +2,8 @@
net8.0
TouchInputs
+ enable
+ latest
diff --git a/samples/Input/TouchInputs/TouchInputs.Game/TouchInputsRenderer.cs b/samples/Input/TouchInputs/TouchInputs.Game/TouchInputsRenderer.cs
index 7667d4306e..b97dd81c5c 100644
--- a/samples/Input/TouchInputs/TouchInputs.Game/TouchInputsRenderer.cs
+++ b/samples/Input/TouchInputs/TouchInputs.Game/TouchInputsRenderer.cs
@@ -1,50 +1,47 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
-using System;
-using System.Collections.Generic;
+
using Stride.Core.Mathematics;
using Stride.Engine;
+using Stride.Graphics;
using Stride.Rendering;
using Stride.Rendering.Compositing;
-using Stride.Graphics;
-using Stride.Input;
-namespace TouchInputs
+namespace TouchInputs;
+
+public class TouchInputsRenderer : SceneRendererBase
{
- public class TouchInputsRenderer : SceneRendererBase
+ private SpriteBatch spriteBatch;
+
+ private readonly Vector2 virtualResolution = new(1920, 1080);
+
+ public Texture Background;
+
+ protected override void InitializeCore()
+ {
+ base.InitializeCore();
+
+ // create the SpriteBatch used to render them
+ spriteBatch = new SpriteBatch(GraphicsDevice) { VirtualResolution = new Vector3(virtualResolution, 1000) };
+ }
+
+ protected override void DrawCore(RenderContext context, RenderDrawContext drawContext)
{
- private SpriteBatch spriteBatch;
-
- private Vector2 virtualResolution = new Vector2(1920, 1080);
-
- public Texture Background;
-
- protected override void InitializeCore()
- {
- base.InitializeCore();
-
- // create the SpriteBatch used to render them
- spriteBatch = new SpriteBatch(GraphicsDevice) { VirtualResolution = new Vector3(virtualResolution, 1000) };
- }
-
- protected override void DrawCore(RenderContext context, RenderDrawContext drawContext)
- {
- // Clear
- drawContext.CommandList.Clear(drawContext.CommandList.RenderTarget, Color.Green);
- drawContext.CommandList.Clear(drawContext.CommandList.DepthStencilBuffer, DepthStencilClearOptions.DepthBuffer);
-
- // Draw background
- spriteBatch.Begin(drawContext.GraphicsContext);
- var target = drawContext.CommandList.RenderTarget;
- var imageBufferMinRatio = Math.Min(Background.ViewWidth / (float)target.ViewWidth, Background.ViewHeight / (float)target.ViewHeight);
- var sourceSize = new Vector2(target.ViewWidth * imageBufferMinRatio, target.ViewHeight * imageBufferMinRatio);
- var source = new RectangleF((Background.ViewWidth - sourceSize.X) / 2, (Background.ViewHeight - sourceSize.Y) / 2, sourceSize.X, sourceSize.Y);
- spriteBatch.Draw(Background, new RectangleF(0, 0, virtualResolution.X, virtualResolution.Y), source, Color.White, 0, Vector2.Zero);
- spriteBatch.End();
-
- // Draw touch inputs
- var entity = SceneInstance.GetCurrent(context).RootScene.Entities[0]; // Note: there's only one entity in our scene
- entity.Get().Render(drawContext, spriteBatch);
- }
+ // Clear
+ drawContext.CommandList.Clear(drawContext.CommandList.RenderTarget, Color.Green);
+ drawContext.CommandList.Clear(drawContext.CommandList.DepthStencilBuffer, DepthStencilClearOptions.DepthBuffer);
+
+ // Draw background
+ spriteBatch.Begin(drawContext.GraphicsContext);
+ var target = drawContext.CommandList.RenderTarget;
+ var imageBufferMinRatio = Math.Min(Background.ViewWidth / (float)target.ViewWidth, Background.ViewHeight / (float)target.ViewHeight);
+ var sourceSize = new Vector2(target.ViewWidth * imageBufferMinRatio, target.ViewHeight * imageBufferMinRatio);
+ var source = new RectangleF((Background.ViewWidth - sourceSize.X) / 2, (Background.ViewHeight - sourceSize.Y) / 2, sourceSize.X, sourceSize.Y);
+ spriteBatch.Draw(Background, new RectangleF(0, 0, virtualResolution.X, virtualResolution.Y), source, Color.White, 0, Vector2.Zero);
+ spriteBatch.End();
+
+ // Draw touch inputs
+ var entity = SceneInstance.GetCurrent(context).RootScene.Entities[0]; // Note: there's only one entity in our scene
+ entity.Get().Render(drawContext, spriteBatch);
}
}
diff --git a/samples/Input/TouchInputs/TouchInputs.Game/TouchInputsScript.cs b/samples/Input/TouchInputs/TouchInputs.Game/TouchInputsScript.cs
index 318aa1ead9..5e2aa91d29 100644
--- a/samples/Input/TouchInputs/TouchInputs.Game/TouchInputsScript.cs
+++ b/samples/Input/TouchInputs/TouchInputs.Game/TouchInputsScript.cs
@@ -1,270 +1,267 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
-using System;
-using System.Collections.Generic;
+
using Stride.Core.Mathematics;
using Stride.Engine;
-using Stride.Rendering;
-using Stride.Rendering.Compositing;
using Stride.Graphics;
using Stride.Input;
+using Stride.Rendering;
+
+namespace TouchInputs;
-namespace TouchInputs
+public class TouchInputsScript : SyncScript
{
- public class TouchInputsScript : SyncScript
- {
- private const float TextSpaceY = 3;
- private const float TextSubSectionOffsetX = 15;
- private const string KeyboardSessionString = "Keyboard :";
+ private const float TextSpaceY = 3;
+ private const float TextSubSectionOffsetX = 15;
+ private const string KeyboardSessionString = "Keyboard :";
- public SpriteFont Font;
- public Texture RoundTexture;
+ public SpriteFont Font;
+ public Texture RoundTexture;
- private Vector2 roundTextureSize;
+ private Vector2 roundTextureSize;
- private readonly Color fontColor = Color.WhiteSmoke;
+ private readonly Color fontColor = Color.WhiteSmoke;
- private float textHeight;
- private readonly Vector2 textLeftTopCorner = new Vector2(5, 5);
+ private float textHeight;
+ private readonly Vector2 textLeftTopCorner = new(5, 5);
- // keyboard
- private string keyEvents;
- private string keyDown;
+ // keyboard
+ private string keyEvents;
+ private string keyDown;
- // mouse
- private Vector2 mousePosition;
- private string mouseButtonPressed;
- private string mouseButtonDown;
- private string mouseButtonReleased;
+ // mouse
+ private Vector2 mousePosition;
+ private string mouseButtonPressed;
+ private string mouseButtonDown;
+ private string mouseButtonReleased;
- private readonly Color mouseColor = Color.DarkGray;
+ private readonly Color mouseColor = Color.DarkGray;
- // pointers
- private readonly Queue> pointerPressed = new Queue>();
- private readonly Queue> pointerMoved = new Queue>();
- private readonly Queue> pointerReleased = new Queue>();
+ // pointers
+ private readonly Queue> pointerPressed = [];
+ private readonly Queue> pointerMoved = [];
+ private readonly Queue> pointerReleased = [];
- private readonly TimeSpan displayPointerDuration = TimeSpan.FromSeconds(1.5f);
+ private readonly TimeSpan displayPointerDuration = TimeSpan.FromSeconds(1.5f);
- // Gestures
- private string dragEvent;
- private string flickEvent;
- private string longPressEvent;
- private string compositeEvent;
- private string tapEvent;
+ // Gestures
+ private string dragEvent;
+ private string flickEvent;
+ private string longPressEvent;
+ private string compositeEvent;
+ private string tapEvent;
- private Tuple lastFlickEvent = new Tuple(null, TimeSpan.Zero);
- private Tuple lastLongPressEvent = new Tuple(null, TimeSpan.Zero);
- private Tuple lastTapEvent = new Tuple(null, TimeSpan.Zero);
+ private Tuple lastFlickEvent = new(null, TimeSpan.Zero);
+ private Tuple lastLongPressEvent = new(null, TimeSpan.Zero);
+ private Tuple lastTapEvent = new(null, TimeSpan.Zero);
- // GamePads
- private string gamePadText;
+ // GamePads
+ private string gamePadText;
- private readonly TimeSpan displayGestureDuration = TimeSpan.FromSeconds(1f);
+ private readonly TimeSpan displayGestureDuration = TimeSpan.FromSeconds(1f);
- public override void Start()
- {
- // initialize parameters
- textHeight = Font.MeasureString(KeyboardSessionString).Y;
- roundTextureSize = new Vector2(RoundTexture.Width, RoundTexture.Height);
+ public override void Start()
+ {
+ // initialize parameters
+ textHeight = Font.MeasureString(KeyboardSessionString).Y;
+ roundTextureSize = new Vector2(RoundTexture.Width, RoundTexture.Height);
- // activate the gesture recognitions
- if (!IsLiveReloading) // Live Scripting: do it only on first launch
- {
- Input.Gestures.Add(new GestureConfigDrag());
- Input.Gestures.Add(new GestureConfigFlick());
- Input.Gestures.Add(new GestureConfigLongPress());
- Input.Gestures.Add(new GestureConfigComposite());
- Input.Gestures.Add(new GestureConfigTap());
- }
+ // activate the gesture recognitions
+ if (!IsLiveReloading) // Live Scripting: do it only on first launch
+ {
+ Input.Gestures.Add(new GestureConfigDrag());
+ Input.Gestures.Add(new GestureConfigFlick());
+ Input.Gestures.Add(new GestureConfigLongPress());
+ Input.Gestures.Add(new GestureConfigComposite());
+ Input.Gestures.Add(new GestureConfigTap());
}
+ }
- public override void Update()
+ public override void Update()
+ {
+ var currentTime = Game.DrawTime.Total;
+
+ keyDown = "";
+ keyEvents = "";
+ mouseButtonPressed = "";
+ mouseButtonDown = "";
+ mouseButtonReleased = "";
+ dragEvent = "";
+ flickEvent = "";
+ longPressEvent = "";
+ compositeEvent = "";
+ tapEvent = "";
+ gamePadText = "";
+
+ // Keyboard
+ if (Input.HasKeyboard)
{
- var currentTime = Game.DrawTime.Total;
-
- keyDown = "";
- keyEvents = "";
- mouseButtonPressed = "";
- mouseButtonDown = "";
- mouseButtonReleased = "";
- dragEvent = "";
- flickEvent = "";
- longPressEvent = "";
- compositeEvent = "";
- tapEvent = "";
- gamePadText = "";
-
- // Keyboard
- if (Input.HasKeyboard)
- {
- foreach (var keyEvent in Input.KeyEvents)
- keyEvents += keyEvent + ", ";
+ foreach (var keyEvent in Input.KeyEvents)
+ keyEvents += keyEvent + ", ";
- foreach (var key in Input.DownKeys)
- keyDown += key + ", ";
- }
-
- // Mouse
- if (Input.HasMouse)
- {
- mousePosition = Input.MousePosition;
- for (int i = 0; i <= (int)MouseButton.Extended2; i++)
- {
- var button = (MouseButton)i;
- if (Input.IsMouseButtonPressed(button))
- mouseButtonPressed += button + ", ";
- if (Input.IsMouseButtonDown(button))
- mouseButtonDown += button + ", ";
- if (Input.IsMouseButtonReleased(button))
- mouseButtonReleased += button + ", ";
- }
- }
+ foreach (var key in Input.DownKeys)
+ keyDown += key + ", ";
+ }
- // Pointers
- if (Input.HasPointer)
+ // Mouse
+ if (Input.HasMouse)
+ {
+ mousePosition = Input.MousePosition;
+ for (int i = 0; i <= (int)MouseButton.Extended2; i++)
{
- foreach (var pointerEvent in Input.PointerEvents)
- {
- switch (pointerEvent.EventType)
- {
- case PointerEventType.Pressed:
- pointerPressed.Enqueue(Tuple.Create(pointerEvent.Position, currentTime));
- break;
- case PointerEventType.Moved:
- pointerMoved.Enqueue(Tuple.Create(pointerEvent.Position, currentTime));
- break;
- case PointerEventType.Released:
- pointerReleased.Enqueue(Tuple.Create(pointerEvent.Position, currentTime));
- break;
- case PointerEventType.Canceled:
- break;
- default:
- throw new ArgumentOutOfRangeException();
- }
- }
-
- // remove too old pointer events
- RemoveOldPointerEventInfo(pointerPressed);
- RemoveOldPointerEventInfo(pointerMoved);
- RemoveOldPointerEventInfo(pointerReleased);
+ var button = (MouseButton)i;
+ if (Input.IsMouseButtonPressed(button))
+ mouseButtonPressed += button + ", ";
+ if (Input.IsMouseButtonDown(button))
+ mouseButtonDown += button + ", ";
+ if (Input.IsMouseButtonReleased(button))
+ mouseButtonReleased += button + ", ";
}
+ }
- // Gestures
- foreach (var gestureEvent in Input.GestureEvents)
+ // Pointers
+ if (Input.HasPointer)
+ {
+ foreach (var pointerEvent in Input.PointerEvents)
{
- switch (gestureEvent.Type)
+ switch (pointerEvent.EventType)
{
- case GestureType.Drag:
- var dragGestureEvent = (GestureEventDrag)gestureEvent;
- dragEvent = "Translation = " + dragGestureEvent.TotalTranslation;
+ case PointerEventType.Pressed:
+ pointerPressed.Enqueue(Tuple.Create(pointerEvent.Position, currentTime));
break;
- case GestureType.Flick:
- lastFlickEvent = Tuple.Create(gestureEvent, currentTime);
+ case PointerEventType.Moved:
+ pointerMoved.Enqueue(Tuple.Create(pointerEvent.Position, currentTime));
break;
- case GestureType.LongPress:
- lastLongPressEvent = Tuple.Create(gestureEvent, currentTime);
+ case PointerEventType.Released:
+ pointerReleased.Enqueue(Tuple.Create(pointerEvent.Position, currentTime));
break;
- case GestureType.Composite:
- var compositeGestureEvent = (GestureEventComposite)gestureEvent;
- compositeEvent = "Rotation = " + compositeGestureEvent.TotalRotation + " - Scale = " + compositeGestureEvent.TotalScale + " - Translation = " + compositeGestureEvent.TotalTranslation;
- break;
- case GestureType.Tap:
- lastTapEvent = Tuple.Create(gestureEvent, currentTime);
+ case PointerEventType.Canceled:
break;
default:
throw new ArgumentOutOfRangeException();
}
}
- if (Input.HasGamePad)
- {
- for (int i = 0; i < Input.GamePadCount; i++)
- {
- var gamePadState = Input.GetGamePadByIndex(i);
- gamePadText += "\n[" + i + "] " + gamePadState;
- }
- }
+ // remove too old pointer events
+ RemoveOldPointerEventInfo(pointerPressed);
+ RemoveOldPointerEventInfo(pointerMoved);
+ RemoveOldPointerEventInfo(pointerReleased);
+ }
- if (currentTime - lastFlickEvent.Item2 < displayGestureDuration && lastFlickEvent.Item1 != null)
- {
- var flickGestureEvent = (GestureEventFlick)lastFlickEvent.Item1;
- flickEvent = " Start Position = " + flickGestureEvent.StartPosition + " - Speed = " + flickGestureEvent.AverageSpeed;
- }
- if (currentTime - lastLongPressEvent.Item2 < displayGestureDuration && lastLongPressEvent.Item1 != null)
+ // Gestures
+ foreach (var gestureEvent in Input.GestureEvents)
+ {
+ switch (gestureEvent.Type)
{
- var longPressGestureEvent = (GestureEventLongPress)lastLongPressEvent.Item1;
- longPressEvent = " Position = " + longPressGestureEvent.Position;
+ case GestureType.Drag:
+ var dragGestureEvent = (GestureEventDrag)gestureEvent;
+ dragEvent = "Translation = " + dragGestureEvent.TotalTranslation;
+ break;
+ case GestureType.Flick:
+ lastFlickEvent = Tuple.Create(gestureEvent, currentTime);
+ break;
+ case GestureType.LongPress:
+ lastLongPressEvent = Tuple.Create(gestureEvent, currentTime);
+ break;
+ case GestureType.Composite:
+ var compositeGestureEvent = (GestureEventComposite)gestureEvent;
+ compositeEvent = "Rotation = " + compositeGestureEvent.TotalRotation + " - Scale = " + compositeGestureEvent.TotalScale + " - Translation = " + compositeGestureEvent.TotalTranslation;
+ break;
+ case GestureType.Tap:
+ lastTapEvent = Tuple.Create(gestureEvent, currentTime);
+ break;
+ default:
+ throw new ArgumentOutOfRangeException();
}
- if (currentTime - lastTapEvent.Item2 < displayGestureDuration && lastTapEvent.Item1 != null)
+ }
+
+ if (Input.HasGamePad)
+ {
+ for (int i = 0; i < Input.GamePadCount; i++)
{
- var tapGestureEvent = (GestureEventTap)lastTapEvent.Item1;
- tapEvent = " Position = " + tapGestureEvent.TapPosition + " - number of taps = " + tapGestureEvent.NumberOfTaps;
+ var gamePadState = Input.GetGamePadByIndex(i);
+ gamePadText += "\n[" + i + "] " + gamePadState;
}
}
- public void Render(RenderDrawContext context, SpriteBatch spriteBatch)
+ if (currentTime - lastFlickEvent.Item2 < displayGestureDuration && lastFlickEvent.Item1 != null)
{
- var screenSize = spriteBatch.VirtualResolution.Value;
-
- // depth test off mode
- spriteBatch.Begin(context.GraphicsContext, depthStencilState: DepthStencilStates.None);
-
- // render the keyboard key states
- spriteBatch.DrawString(Font, KeyboardSessionString, textLeftTopCorner, fontColor);
- spriteBatch.DrawString(Font, "Key pressed/released: " + keyEvents, textLeftTopCorner + new Vector2(TextSubSectionOffsetX, 1 * (textHeight + TextSpaceY)), fontColor);
- spriteBatch.DrawString(Font, "Key down: " + keyDown, textLeftTopCorner + new Vector2(TextSubSectionOffsetX, 2 * (textHeight + TextSpaceY)), fontColor);
-
- // render the mouse key states
- spriteBatch.DrawString(Font, "Mouse :", textLeftTopCorner + new Vector2(0, 4 * (textHeight + TextSpaceY)), fontColor);
- spriteBatch.DrawString(Font, "Mouse position: " + mousePosition, textLeftTopCorner + new Vector2(TextSubSectionOffsetX, 5 * (textHeight + TextSpaceY)), fontColor);
- spriteBatch.DrawString(Font, "Mouse button pressed: " + mouseButtonPressed, textLeftTopCorner + new Vector2(TextSubSectionOffsetX, 6 * (textHeight + TextSpaceY)), fontColor);
- spriteBatch.DrawString(Font, "Mouse button down: " + mouseButtonDown, textLeftTopCorner + new Vector2(TextSubSectionOffsetX, 7 * (textHeight + TextSpaceY)), fontColor);
- spriteBatch.DrawString(Font, "Mouse button released: " + mouseButtonReleased, textLeftTopCorner + new Vector2(TextSubSectionOffsetX, 8 * (textHeight + TextSpaceY)), fontColor);
-
- var mouseScreenPosition = new Vector2(mousePosition.X * screenSize.X, mousePosition.Y * screenSize.Y);
- spriteBatch.Draw(RoundTexture, mouseScreenPosition, mouseColor, 0, roundTextureSize / 2, 0.1f);
-
- // render the pointer states
- foreach (var tuple in pointerPressed)
- DrawPointers(spriteBatch, tuple, 1.5f, Color.Blue);
- foreach (var tuple in pointerMoved)
- DrawPointers(spriteBatch, tuple, 1f, Color.Green);
- foreach (var tuple in pointerReleased)
- DrawPointers(spriteBatch, tuple, 2f, Color.Red);
-
- // render the gesture states
- spriteBatch.DrawString(Font, "Gestures :", textLeftTopCorner + new Vector2(0, 10 * (textHeight + TextSpaceY)), fontColor);
- spriteBatch.DrawString(Font, "Drag: " + dragEvent, textLeftTopCorner + new Vector2(TextSubSectionOffsetX, 11 * (textHeight + TextSpaceY)), fontColor);
- spriteBatch.DrawString(Font, "Flick: " + flickEvent, textLeftTopCorner + new Vector2(TextSubSectionOffsetX, 12 * (textHeight + TextSpaceY)), fontColor);
- spriteBatch.DrawString(Font, "LongPress: " + longPressEvent, textLeftTopCorner + new Vector2(TextSubSectionOffsetX, 13 * (textHeight + TextSpaceY)), fontColor);
- spriteBatch.DrawString(Font, "Composite: " + compositeEvent, textLeftTopCorner + new Vector2(TextSubSectionOffsetX, 14 * (textHeight + TextSpaceY)), fontColor);
- spriteBatch.DrawString(Font, "Tap: " + tapEvent, textLeftTopCorner + new Vector2(TextSubSectionOffsetX, 15 * (textHeight + TextSpaceY)), fontColor);
-
- spriteBatch.DrawString(Font, "GamePads: " + gamePadText, textLeftTopCorner + new Vector2(TextSubSectionOffsetX, 17 * (textHeight + TextSpaceY)), fontColor);
- spriteBatch.End();
+ var flickGestureEvent = (GestureEventFlick)lastFlickEvent.Item1;
+ flickEvent = " Start Position = " + flickGestureEvent.StartPosition + " - Speed = " + flickGestureEvent.AverageSpeed;
}
- private void DrawPointers(SpriteBatch spriteBatch, Tuple tuple, float baseScale, Color baseColor)
+ if (currentTime - lastLongPressEvent.Item2 < displayGestureDuration && lastLongPressEvent.Item1 != null)
{
- var screenSize = spriteBatch.VirtualResolution.Value;
- var position = tuple.Item1;
- var duration = Game.DrawTime.Total - tuple.Item2;
-
- var scale = (float)(0.2f * (1f - duration.TotalSeconds / displayPointerDuration.TotalSeconds));
- var pointerScreenPosition = new Vector2(position.X * screenSize.X, position.Y * screenSize.Y);
-
- spriteBatch.Draw(RoundTexture, pointerScreenPosition, baseColor, 0, roundTextureSize / 2, scale * baseScale);
+ var longPressGestureEvent = (GestureEventLongPress)lastLongPressEvent.Item1;
+ longPressEvent = " Position = " + longPressGestureEvent.Position;
}
-
- ///
- /// Utility function to remove old pointer event from the queues
- ///
- /// the pointers event position and triggered time.
- private void RemoveOldPointerEventInfo(Queue> tuples)
+ if (currentTime - lastTapEvent.Item2 < displayGestureDuration && lastTapEvent.Item1 != null)
{
- while (tuples.Count > 0 && Game.UpdateTime.Total - tuples.Peek().Item2 > displayPointerDuration)
- tuples.Dequeue();
+ var tapGestureEvent = (GestureEventTap)lastTapEvent.Item1;
+ tapEvent = " Position = " + tapGestureEvent.TapPosition + " - number of taps = " + tapGestureEvent.NumberOfTaps;
}
+ }
+ public void Render(RenderDrawContext context, SpriteBatch spriteBatch)
+ {
+ var screenSize = spriteBatch.VirtualResolution.Value;
+
+ // depth test off mode
+ spriteBatch.Begin(context.GraphicsContext, depthStencilState: DepthStencilStates.None);
+
+ // render the keyboard key states
+ spriteBatch.DrawString(Font, KeyboardSessionString, textLeftTopCorner, fontColor);
+ spriteBatch.DrawString(Font, "Key pressed/released: " + keyEvents, textLeftTopCorner + new Vector2(TextSubSectionOffsetX, 1 * (textHeight + TextSpaceY)), fontColor);
+ spriteBatch.DrawString(Font, "Key down: " + keyDown, textLeftTopCorner + new Vector2(TextSubSectionOffsetX, 2 * (textHeight + TextSpaceY)), fontColor);
+
+ // render the mouse key states
+ spriteBatch.DrawString(Font, "Mouse :", textLeftTopCorner + new Vector2(0, 4 * (textHeight + TextSpaceY)), fontColor);
+ spriteBatch.DrawString(Font, "Mouse position: " + mousePosition, textLeftTopCorner + new Vector2(TextSubSectionOffsetX, 5 * (textHeight + TextSpaceY)), fontColor);
+ spriteBatch.DrawString(Font, "Mouse button pressed: " + mouseButtonPressed, textLeftTopCorner + new Vector2(TextSubSectionOffsetX, 6 * (textHeight + TextSpaceY)), fontColor);
+ spriteBatch.DrawString(Font, "Mouse button down: " + mouseButtonDown, textLeftTopCorner + new Vector2(TextSubSectionOffsetX, 7 * (textHeight + TextSpaceY)), fontColor);
+ spriteBatch.DrawString(Font, "Mouse button released: " + mouseButtonReleased, textLeftTopCorner + new Vector2(TextSubSectionOffsetX, 8 * (textHeight + TextSpaceY)), fontColor);
+
+ var mouseScreenPosition = new Vector2(mousePosition.X * screenSize.X, mousePosition.Y * screenSize.Y);
+ spriteBatch.Draw(RoundTexture, mouseScreenPosition, mouseColor, 0, roundTextureSize / 2, 0.1f);
+
+ // render the pointer states
+ foreach (var tuple in pointerPressed)
+ DrawPointers(spriteBatch, tuple, 1.5f, Color.Blue);
+ foreach (var tuple in pointerMoved)
+ DrawPointers(spriteBatch, tuple, 1f, Color.Green);
+ foreach (var tuple in pointerReleased)
+ DrawPointers(spriteBatch, tuple, 2f, Color.Red);
+
+ // render the gesture states
+ spriteBatch.DrawString(Font, "Gestures :", textLeftTopCorner + new Vector2(0, 10 * (textHeight + TextSpaceY)), fontColor);
+ spriteBatch.DrawString(Font, "Drag: " + dragEvent, textLeftTopCorner + new Vector2(TextSubSectionOffsetX, 11 * (textHeight + TextSpaceY)), fontColor);
+ spriteBatch.DrawString(Font, "Flick: " + flickEvent, textLeftTopCorner + new Vector2(TextSubSectionOffsetX, 12 * (textHeight + TextSpaceY)), fontColor);
+ spriteBatch.DrawString(Font, "LongPress: " + longPressEvent, textLeftTopCorner + new Vector2(TextSubSectionOffsetX, 13 * (textHeight + TextSpaceY)), fontColor);
+ spriteBatch.DrawString(Font, "Composite: " + compositeEvent, textLeftTopCorner + new Vector2(TextSubSectionOffsetX, 14 * (textHeight + TextSpaceY)), fontColor);
+ spriteBatch.DrawString(Font, "Tap: " + tapEvent, textLeftTopCorner + new Vector2(TextSubSectionOffsetX, 15 * (textHeight + TextSpaceY)), fontColor);
+
+ spriteBatch.DrawString(Font, "GamePads: " + gamePadText, textLeftTopCorner + new Vector2(TextSubSectionOffsetX, 17 * (textHeight + TextSpaceY)), fontColor);
+ spriteBatch.End();
}
+ private void DrawPointers(SpriteBatch spriteBatch, Tuple tuple, float baseScale, Color baseColor)
+ {
+ var screenSize = spriteBatch.VirtualResolution.Value;
+ var position = tuple.Item1;
+ var duration = Game.DrawTime.Total - tuple.Item2;
+
+ var scale = (float)(0.2f * (1f - duration.TotalSeconds / displayPointerDuration.TotalSeconds));
+ var pointerScreenPosition = new Vector2(position.X * screenSize.X, position.Y * screenSize.Y);
+
+ spriteBatch.Draw(RoundTexture, pointerScreenPosition, baseColor, 0, roundTextureSize / 2, scale * baseScale);
+ }
+
+ ///
+ /// Utility function to remove old pointer event from the queues
+ ///
+ /// the pointers event position and triggered time.
+ private void RemoveOldPointerEventInfo(Queue> tuples)
+ {
+ while (tuples.Count > 0 && Game.UpdateTime.Total - tuples.Peek().Item2 > displayPointerDuration)
+ tuples.Dequeue();
+ }
+
}
diff --git a/samples/Input/TouchInputs/TouchInputs.Windows/TouchInputs.Windows.csproj b/samples/Input/TouchInputs/TouchInputs.Windows/TouchInputs.Windows.csproj
index 5e55005cfa..a3c0b8448f 100644
--- a/samples/Input/TouchInputs/TouchInputs.Windows/TouchInputs.Windows.csproj
+++ b/samples/Input/TouchInputs/TouchInputs.Windows/TouchInputs.Windows.csproj
@@ -7,6 +7,8 @@
..\Bin\Windows\$(Configuration)\
false
STRIDE_PLATFORM_DESKTOP
+ enable
+ latest
$(MSBuildThisFileDirectory)..\TouchInputs.sdpkg
diff --git a/samples/Particles/ParticlesSample/ParticlesSample.Game/AnimationStart.cs b/samples/Particles/ParticlesSample/ParticlesSample.Game/AnimationStart.cs
index e8d8810a50..21f8739735 100644
--- a/samples/Particles/ParticlesSample/ParticlesSample.Game/AnimationStart.cs
+++ b/samples/Particles/ParticlesSample/ParticlesSample.Game/AnimationStart.cs
@@ -1,61 +1,54 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Stride.Core;
-using Stride.Core.Mathematics;
+
using Stride.Animations;
-using Stride.Input;
+using Stride.Core;
using Stride.Engine;
-namespace ParticlesSample
+namespace ParticlesSample;
+
+[DataContract]
+public class PlayAnimation
+{
+ public AnimationClip Clip;
+ public AnimationBlendOperation BlendOperation = AnimationBlendOperation.LinearBlend;
+ public double StartTime = 0;
+}
+
+///
+/// Script which starts a few playing animations on a target and halts
+///
+public class AnimationStart : StartupScript
{
- [DataContract]
- public class PlayAnimation
- {
- public AnimationClip Clip;
- public AnimationBlendOperation BlendOperation = AnimationBlendOperation.LinearBlend;
- public double StartTime = 0;
- }
-
///
- /// Script which starts a few playing animations on a target and halts
+ /// If null, will target the same entity it is attached to.
///
- public class AnimationStart : StartupScript
- {
- ///
- /// If null, will target the same entity it is attached to.
- ///
- public AnimationComponent Target { get; set; }
+ public AnimationComponent Target { get; set; }
- ///
- /// Al list of animations to be loaded when the script starts
- ///
- public readonly List Animations = new List();
+ ///
+ /// Al list of animations to be loaded when the script starts
+ ///
+ public readonly List Animations = [];
- public override void Start()
- {
- var animComponent = Target ?? Entity.Get();
-
- if (animComponent != null)
- PlayAnimations(animComponent);
+ public override void Start()
+ {
+ var animComponent = Target ?? Entity.Get();
+
+ if (animComponent != null)
+ PlayAnimations(animComponent);
- // Destroy this script since it's no longer needed
- Entity.Remove(this);
- }
+ // Destroy this script since it's no longer needed
+ Entity.Remove(this);
+ }
- private void PlayAnimations(AnimationComponent animComponent)
+ private void PlayAnimations(AnimationComponent animComponent)
+ {
+ foreach (var anim in Animations)
{
- foreach (var anim in Animations)
- {
- if (anim.Clip != null)
- animComponent.Add(anim.Clip, anim.StartTime, anim.BlendOperation);
- }
-
- Animations.Clear();
+ if (anim.Clip != null)
+ animComponent.Add(anim.Clip, anim.StartTime, anim.BlendOperation);
}
+
+ Animations.Clear();
}
}
diff --git a/samples/Particles/ParticlesSample/ParticlesSample.Game/CameraOrbitScript.cs b/samples/Particles/ParticlesSample/ParticlesSample.Game/CameraOrbitScript.cs
index 8bec53afe8..2231010432 100644
--- a/samples/Particles/ParticlesSample/ParticlesSample.Game/CameraOrbitScript.cs
+++ b/samples/Particles/ParticlesSample/ParticlesSample.Game/CameraOrbitScript.cs
@@ -1,98 +1,94 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
-using System;
-using System.Linq;
-using System.Threading.Tasks;
-using Stride.Engine;
-using Stride.Input;
+
using Stride.Core.Mathematics;
+using Stride.Engine;
-namespace ParticlesSample
+namespace ParticlesSample;
+
+///
+/// Script that update the position of the camera.
+///
+public class CameraOrbitScript : AsyncScript
{
- ///
- /// Script that update the position of the camera.
- ///
- public class CameraOrbitScript : AsyncScript
- {
- private readonly Vector3 lookAtPosition = new Vector3(0, 0, 0);
- private float lookAtAngle = 90f;
- private float lookAtAngleY = 10f;
- private const float lookFromDistance = 8f;
- private const float MinimumCameraHeight = 0f;
- private const float MaximumCameraHeight = 50f;
- private const float AbsoluteMaxSpeedX = 5f;
- private const float AbsoluteMaxSpeedY = 2f;
- private const float Friction = 0.9f;
- private const float Frametime = 1 / 60.0f;
- private float timeToProcess;
- private float movingSpeedX;
- private float movingSpeedY;
- private bool userIsTouchingScreen;
+ private readonly Vector3 lookAtPosition = new(0, 0, 0);
+ private float lookAtAngle = 90f;
+ private float lookAtAngleY = 10f;
+ private const float lookFromDistance = 8f;
+ private const float MinimumCameraHeight = 0f;
+ private const float MaximumCameraHeight = 50f;
+ private const float AbsoluteMaxSpeedX = 5f;
+ private const float AbsoluteMaxSpeedY = 2f;
+ private const float Friction = 0.9f;
+ private const float Frametime = 1 / 60.0f;
+ private float timeToProcess;
+ private float movingSpeedX;
+ private float movingSpeedY;
+ private bool userIsTouchingScreen;
- public override async Task Execute()
+ public override async Task Execute()
+ {
+ while (Game.IsRunning)
{
- while (Game.IsRunning)
- {
- var elapsedTime = (float)Game.UpdateTime.Elapsed.TotalSeconds;
- timeToProcess = Math.Max(timeToProcess + elapsedTime, 1.0f);
+ var elapsedTime = (float)Game.UpdateTime.Elapsed.TotalSeconds;
+ timeToProcess = Math.Max(timeToProcess + elapsedTime, 1.0f);
- // determine if the user is currently touching the screen.
- if (Input.PointerEvents.Count > 0)
- userIsTouchingScreen = Input.Pointer.DownPointers.Any(x=>x.IsDown);
+ // determine if the user is currently touching the screen.
+ if (Input.PointerEvents.Count > 0)
+ userIsTouchingScreen = Input.Pointer.DownPointers.Any(x=>x.IsDown);
- // calculate the current speed of the camera
- if (userIsTouchingScreen)
+ // calculate the current speed of the camera
+ if (userIsTouchingScreen)
+ {
+ movingSpeedX += -AbsoluteMaxSpeedX * Input.PointerEvents.Sum(x => x.DeltaPosition.X);
+ if (Math.Abs(movingSpeedX) > AbsoluteMaxSpeedX)
{
- movingSpeedX += -AbsoluteMaxSpeedX * Input.PointerEvents.Sum(x => x.DeltaPosition.X);
- if (Math.Abs(movingSpeedX) > AbsoluteMaxSpeedX)
- {
- movingSpeedX = AbsoluteMaxSpeedX * Math.Sign(movingSpeedX);
- }
+ movingSpeedX = AbsoluteMaxSpeedX * Math.Sign(movingSpeedX);
+ }
- movingSpeedY += AbsoluteMaxSpeedY * Input.PointerEvents.Sum(y => y.DeltaPosition.Y);
- if (Math.Abs(movingSpeedY) > AbsoluteMaxSpeedY)
- {
- movingSpeedY = AbsoluteMaxSpeedY * Math.Sign(movingSpeedY);
- }
+ movingSpeedY += AbsoluteMaxSpeedY * Input.PointerEvents.Sum(y => y.DeltaPosition.Y);
+ if (Math.Abs(movingSpeedY) > AbsoluteMaxSpeedY)
+ {
+ movingSpeedY = AbsoluteMaxSpeedY * Math.Sign(movingSpeedY);
+ }
- timeToProcess = timeToProcess % Frametime;
- UpdatePosition(movingSpeedX * 2, movingSpeedY * 2);
- }
- else
+ timeToProcess %= Frametime;
+ UpdatePosition(movingSpeedX * 2, movingSpeedY * 2);
+ }
+ else
+ {
+ while (timeToProcess >= Frametime)
{
- while (timeToProcess >= Frametime)
- {
- timeToProcess -= Frametime;
- var previousSpeedX = movingSpeedX;
- movingSpeedX = (float)(movingSpeedX * Math.Pow(Friction, Frametime));
- var previousSpeedY = movingSpeedY;
- movingSpeedY = (float)(movingSpeedY * Math.Pow(Friction, Frametime));
- UpdatePosition(previousSpeedX + movingSpeedX, previousSpeedY + movingSpeedY);
- }
+ timeToProcess -= Frametime;
+ var previousSpeedX = movingSpeedX;
+ movingSpeedX = (float)(movingSpeedX * Math.Pow(Friction, Frametime));
+ var previousSpeedY = movingSpeedY;
+ movingSpeedY = (float)(movingSpeedY * Math.Pow(Friction, Frametime));
+ UpdatePosition(previousSpeedX + movingSpeedX, previousSpeedY + movingSpeedY);
}
-
- // wait until next frame
- await Script.NextFrame();
}
+
+ // wait until next frame
+ await Script.NextFrame();
}
+ }
- private void UpdatePosition(float speedX, float speedY)
- {
- lookAtAngle = lookAtAngle + (speedX) * 7.5f * Frametime;
- lookAtAngleY = lookAtAngleY + (speedY) * 1.5f * Frametime;
- lookAtAngleY = MathUtil.Clamp(lookAtAngleY, MinimumCameraHeight, MaximumCameraHeight);
+ private void UpdatePosition(float speedX, float speedY)
+ {
+ lookAtAngle += (speedX) * 7.5f * Frametime;
+ lookAtAngleY += (speedY) * 1.5f * Frametime;
+ lookAtAngleY = MathUtil.Clamp(lookAtAngleY, MinimumCameraHeight, MaximumCameraHeight);
- var maxDistance = lookFromDistance*(1 + (float) Math.Sin(MathUtil.DegreesToRadians(lookAtAngleY)));
+ var maxDistance = lookFromDistance*(1 + (float) Math.Sin(MathUtil.DegreesToRadians(lookAtAngleY)));
- var distance = maxDistance * (float)Math.Cos(MathUtil.DegreesToRadians(lookAtAngleY));
- Entity.Transform.Position.X = (float)Math.Sin(MathUtil.DegreesToRadians(lookAtAngle)) * distance;
- Entity.Transform.Position.Z = (float)Math.Cos(MathUtil.DegreesToRadians(lookAtAngle)) * distance;
- Entity.Transform.Position.Y = maxDistance*(float) Math.Sin(MathUtil.DegreesToRadians(lookAtAngleY));
- Entity.Transform.Position += lookAtPosition;
+ var distance = maxDistance * (float)Math.Cos(MathUtil.DegreesToRadians(lookAtAngleY));
+ Entity.Transform.Position.X = (float)Math.Sin(MathUtil.DegreesToRadians(lookAtAngle)) * distance;
+ Entity.Transform.Position.Z = (float)Math.Cos(MathUtil.DegreesToRadians(lookAtAngle)) * distance;
+ Entity.Transform.Position.Y = maxDistance*(float) Math.Sin(MathUtil.DegreesToRadians(lookAtAngleY));
+ Entity.Transform.Position += lookAtPosition;
- Entity.Transform.Rotation = Quaternion.RotationAxis(new Vector3(1, 0, 0), MathUtil.DegreesToRadians(-lookAtAngleY)) *
- Quaternion.RotationAxis(new Vector3(0, 1, 0), MathUtil.DegreesToRadians(lookAtAngle));
- }
+ Entity.Transform.Rotation = Quaternion.RotationAxis(new Vector3(1, 0, 0), MathUtil.DegreesToRadians(-lookAtAngleY)) *
+ Quaternion.RotationAxis(new Vector3(0, 1, 0), MathUtil.DegreesToRadians(lookAtAngle));
}
}
diff --git a/samples/Particles/ParticlesSample/ParticlesSample.Game/Effects/ParticleCustomEffect.sdfx.cs b/samples/Particles/ParticlesSample/ParticlesSample.Game/Effects/ParticleCustomEffect.sdfx.cs
index 1c23837570..65cd26bc7a 100644
--- a/samples/Particles/ParticlesSample/ParticlesSample.Game/Effects/ParticleCustomEffect.sdfx.cs
+++ b/samples/Particles/ParticlesSample/ParticlesSample.Game/Effects/ParticleCustomEffect.sdfx.cs
@@ -1,4 +1,4 @@
-//
+//
// Do not edit this file yourself!
//
// This code was generated by Stride Shader Mixin Code Generator.
@@ -6,54 +6,48 @@
// and re-save the associated .sdfx.
//
-using System;
using Stride.Core;
-using Stride.Rendering;
-using Stride.Graphics;
using Stride.Shaders;
-using Stride.Core.Mathematics;
-using Buffer = Stride.Graphics.Buffer;
-namespace Stride.Rendering
+namespace Stride.Rendering;
+
+internal static partial class ShaderMixins
{
- internal static partial class ShaderMixins
+ internal partial class ParticleCustomEffect : IShaderMixinBuilder
{
- internal partial class ParticleCustomEffect : IShaderMixinBuilder
+ public void Generate(ShaderMixinSource mixin, ShaderMixinContext context)
{
- public void Generate(ShaderMixinSource mixin, ShaderMixinContext context)
+ context.Mixin(mixin, "ParticleBaseEffect");
+ context.Mixin(mixin, "ParticleCustomShader");
+ if (context.GetParam(ParticleCustomShaderKeys.BaseColor) != null)
{
- context.Mixin(mixin, "ParticleBaseEffect");
- context.Mixin(mixin, "ParticleCustomShader");
- if (context.GetParam(ParticleCustomShaderKeys.BaseColor) != null)
- {
- {
- var __mixinToCompose__ = context.GetParam(ParticleCustomShaderKeys.BaseColor);
- var __subMixin = new ShaderMixinSource();
- context.PushComposition(mixin, "baseColor", __subMixin);
- context.Mixin(__subMixin, __mixinToCompose__);
- context.PopComposition();
- }
- }
- if (context.GetParam(ParticleCustomShaderKeys.BaseIntensity) != null)
{
+ var __mixinToCompose__ = context.GetParam(ParticleCustomShaderKeys.BaseColor);
+ var __subMixin = new ShaderMixinSource();
+ context.PushComposition(mixin, "baseColor", __subMixin);
+ context.Mixin(__subMixin, __mixinToCompose__);
+ context.PopComposition();
+ }
+ }
+ if (context.GetParam(ParticleCustomShaderKeys.BaseIntensity) != null)
+ {
- {
- var __mixinToCompose__ = context.GetParam(ParticleCustomShaderKeys.BaseIntensity);
- var __subMixin = new ShaderMixinSource();
- context.PushComposition(mixin, "baseIntensity", __subMixin);
- context.Mixin(__subMixin, __mixinToCompose__);
- context.PopComposition();
- }
+ {
+ var __mixinToCompose__ = context.GetParam(ParticleCustomShaderKeys.BaseIntensity);
+ var __subMixin = new ShaderMixinSource();
+ context.PushComposition(mixin, "baseIntensity", __subMixin);
+ context.Mixin(__subMixin, __mixinToCompose__);
+ context.PopComposition();
}
}
+ }
- [ModuleInitializer]
- internal static void __Initialize__()
+ [ModuleInitializer]
+ internal static void __Initialize__()
- {
- ShaderMixinManager.Register("ParticleCustomEffect", new ParticleCustomEffect());
- }
+ {
+ ShaderMixinManager.Register("ParticleCustomEffect", new ParticleCustomEffect());
}
}
}
diff --git a/samples/Particles/ParticlesSample/ParticlesSample.Game/GameProfiler.cs b/samples/Particles/ParticlesSample/ParticlesSample.Game/GameProfiler.cs
index 095513c687..88540dec19 100644
--- a/samples/Particles/ParticlesSample/ParticlesSample.Game/GameProfiler.cs
+++ b/samples/Particles/ParticlesSample/ParticlesSample.Game/GameProfiler.cs
@@ -1,141 +1,137 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
-using System;
-using System.Threading.Tasks;
using Stride.Core.Mathematics;
-using Stride.Core.Diagnostics;
-using Stride.Input;
using Stride.Engine;
+using Stride.Input;
using Stride.Profiling;
-namespace ParticlesSample
+namespace ParticlesSample;
+
+public class GameProfiler : AsyncScript
{
- public class GameProfiler : AsyncScript
+ ///
+ /// Enables or disable the game profiling
+ ///
+ public bool Enabled;
+
+ ///
+ /// The color of the text displayed during profiling
+ ///
+ public Color TextColor { get; set; } = Color.LightGreen;
+
+ ///
+ /// The time between two refreshes of the profiling information in milliseconds.
+ ///
+ public double RefreshTime { get; set; } = 500;
+
+ ///
+ /// Gets or set the sorting mode of the profiling entries
+ ///
+ public GameProfilingSorting SortingMode { get; set; } = GameProfilingSorting.ByTime;
+
+ ///
+ /// Gets or sets the type of the profiling to display: CPU or GPU
+ ///
+ public GameProfilingResults FilteringMode { get; set; } = GameProfilingResults.Fps;
+
+ ///
+ /// Gets or sets the current profiling result page to display.
+ ///
+ public uint ResultPage { get; set; } = 1;
+
+ public override async Task Execute()
{
- ///
- /// Enables or disable the game profiling
- ///
- public bool Enabled;
-
- ///
- /// The color of the text displayed during profiling
- ///
- public Color TextColor { get; set; } = Color.LightGreen;
-
- ///
- /// The time between two refreshes of the profiling information in milliseconds.
- ///
- public double RefreshTime { get; set; } = 500;
-
- ///
- /// Gets or set the sorting mode of the profiling entries
- ///
- public GameProfilingSorting SortingMode { get; set; } = GameProfilingSorting.ByTime;
-
- ///
- /// Gets or sets the type of the profiling to display: CPU or GPU
- ///
- public GameProfilingResults FilteringMode { get; set; } = GameProfilingResults.Fps;
-
- ///
- /// Gets or sets the current profiling result page to display.
- ///
- public uint ResultPage { get; set; } = 1;
-
- public override async Task Execute()
+ if (Enabled)
+ GameProfiler.EnableProfiling();
+
+ while (Game.IsRunning)
{
- if (Enabled)
- GameProfiler.EnableProfiling();
+ GameProfiler.TextColor = TextColor;
+ GameProfiler.RefreshTime = RefreshTime;
+ GameProfiler.SortingMode = SortingMode;
+ GameProfiler.FilteringMode = FilteringMode;
+ GameProfiler.CurrentResultPage = ResultPage;
+ ResultPage = GameProfiler.CurrentResultPage;
- while (Game.IsRunning)
+ if (Input.IsKeyDown(Keys.LeftShift) && Input.IsKeyDown(Keys.LeftCtrl) && Input.IsKeyReleased(Keys.P))
{
- GameProfiler.TextColor = TextColor;
- GameProfiler.RefreshTime = RefreshTime;
- GameProfiler.SortingMode = SortingMode;
- GameProfiler.FilteringMode = FilteringMode;
- GameProfiler.CurrentResultPage = ResultPage;
- ResultPage = GameProfiler.CurrentResultPage;
-
- if (Input.IsKeyDown(Keys.LeftShift) && Input.IsKeyDown(Keys.LeftCtrl) && Input.IsKeyReleased(Keys.P))
+ if (Enabled)
{
- if (Enabled)
- {
- GameProfiler.DisableProfiling();
- Enabled = false;
- }
- else
- {
- GameProfiler.EnableProfiling();
- Enabled = true;
- }
+ GameProfiler.DisableProfiling();
+ Enabled = false;
}
+ else
+ {
+ GameProfiler.EnableProfiling();
+ Enabled = true;
+ }
+ }
- if (Enabled)
+ if (Enabled)
+ {
+ // update the filtering mode
+ if (Input.IsKeyPressed(Keys.F1))
{
- // update the filtering mode
- if (Input.IsKeyPressed(Keys.F1))
- {
- FilteringMode = GameProfilingResults.Fps;
- }
- else if (Input.IsKeyPressed(Keys.F2))
- {
- FilteringMode = GameProfilingResults.CpuEvents;
- }
- else if (Input.IsKeyPressed(Keys.F3))
- {
- FilteringMode = GameProfilingResults.GpuEvents;
- }
-
- // update the sorting mode
- if (Input.IsKeyPressed(Keys.F4))
- {
- SortingMode = (GameProfilingSorting)(((int)SortingMode+1) % Enum.GetValues(typeof(GameProfilingSorting)).Length);
- }
-
- // update the refreshing speed
- if (Input.IsKeyPressed(Keys.Subtract) || Input.IsKeyPressed(Keys.OemMinus))
- {
- RefreshTime = Math.Min(RefreshTime * 2, 10000);
- }
- else if (Input.IsKeyPressed(Keys.Add) || Input.IsKeyPressed(Keys.OemPlus))
- {
- RefreshTime = Math.Max(RefreshTime / 2, 100);
- }
-
- // update the result page
- if (Input.IsKeyPressed(Keys.D1))
- {
- ResultPage = 1;
- }
- else if (Input.IsKeyPressed(Keys.D2))
- {
- ResultPage = 2;
- }
- else if (Input.IsKeyPressed(Keys.D3))
- {
- ResultPage = 3;
- }
- else if (Input.IsKeyPressed(Keys.D4))
- {
- ResultPage = 4;
- }
- else if (Input.IsKeyPressed(Keys.D5))
- {
- ResultPage = 5;
- }
- if (Input.IsKeyPressed(Keys.F3))
- {
- ResultPage = Math.Max(1, --ResultPage);
- }
- else if (Input.IsKeyPressed(Keys.F4))
- {
- ++ResultPage;
- }
+ FilteringMode = GameProfilingResults.Fps;
+ }
+ else if (Input.IsKeyPressed(Keys.F2))
+ {
+ FilteringMode = GameProfilingResults.CpuEvents;
+ }
+ else if (Input.IsKeyPressed(Keys.F3))
+ {
+ FilteringMode = GameProfilingResults.GpuEvents;
}
- await Script.NextFrame();
+ // update the sorting mode
+ if (Input.IsKeyPressed(Keys.F4))
+ {
+ SortingMode = (GameProfilingSorting)(((int)SortingMode+1) % Enum.GetValues(typeof(GameProfilingSorting)).Length);
+ }
+
+ // update the refreshing speed
+ if (Input.IsKeyPressed(Keys.Subtract) || Input.IsKeyPressed(Keys.OemMinus))
+ {
+ RefreshTime = Math.Min(RefreshTime * 2, 10000);
+ }
+ else if (Input.IsKeyPressed(Keys.Add) || Input.IsKeyPressed(Keys.OemPlus))
+ {
+ RefreshTime = Math.Max(RefreshTime / 2, 100);
+ }
+
+ // update the result page
+ if (Input.IsKeyPressed(Keys.D1))
+ {
+ ResultPage = 1;
+ }
+ else if (Input.IsKeyPressed(Keys.D2))
+ {
+ ResultPage = 2;
+ }
+ else if (Input.IsKeyPressed(Keys.D3))
+ {
+ ResultPage = 3;
+ }
+ else if (Input.IsKeyPressed(Keys.D4))
+ {
+ ResultPage = 4;
+ }
+ else if (Input.IsKeyPressed(Keys.D5))
+ {
+ ResultPage = 5;
+ }
+ if (Input.IsKeyPressed(Keys.F3))
+ {
+ ResultPage = Math.Max(1, --ResultPage);
+ }
+ else if (Input.IsKeyPressed(Keys.F4))
+ {
+ ++ResultPage;
+ }
}
+
+ await Script.NextFrame();
}
}
}
\ No newline at end of file
diff --git a/samples/Particles/ParticlesSample/ParticlesSample.Game/LaserOrientationScript.cs b/samples/Particles/ParticlesSample/ParticlesSample.Game/LaserOrientationScript.cs
index fd242ee300..418ec1526a 100644
--- a/samples/Particles/ParticlesSample/ParticlesSample.Game/LaserOrientationScript.cs
+++ b/samples/Particles/ParticlesSample/ParticlesSample.Game/LaserOrientationScript.cs
@@ -1,79 +1,67 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
-using System;
-using System.Linq;
-using System.Threading.Tasks;
+
using Stride.Core;
-using Stride.Engine;
-using Stride.Input;
using Stride.Core.Mathematics;
+using Stride.Engine;
-namespace ParticlesSample
+namespace ParticlesSample;
+
+///
+/// Script that update the position of the camera.
+///
+public class LaserOrientationScript : AsyncScript
{
- ///
- /// Script that update the position of the camera.
- ///
- public class LaserOrientationScript : AsyncScript
- {
- public TransformComponent Target;
+ public TransformComponent Target;
- [Display("Do not scale")]
- public bool doNotScale = false;
+ [Display("Do not scale")]
+ public bool doNotScale = false;
- [Display("Scale Only Z")]
- public bool scaleOnlyZ = true;
+ [Display("Scale Only Z")]
+ public bool scaleOnlyZ = true;
- private Vector3 targetPosition = new Vector3(0, 0, 0);
+ private Vector3 targetPosition = new(0, 0, 0);
- // We could expose this if we need to change it
- private Vector3 upVector = new Vector3(0, 1, 0);
+ // We could expose this if we need to change it
+ private Vector3 upVector = new(0, 1, 0);
- public override async Task Execute()
+ public override async Task Execute()
+ {
+ while (true)
{
- while (true)
- {
- targetPosition = Target != null ? Target.WorldMatrix.TranslationVector : new Vector3(0, 0, 0);
- UpdateRotation();
-
- // wait until next frame
- await Script.NextFrame();
- }
- }
+ targetPosition = Target != null ? Target.WorldMatrix.TranslationVector : new Vector3(0, 0, 0);
+ UpdateRotation();
- private void UpdateRotation()
- {
- var eyePosition = Entity.Transform.WorldMatrix.TranslationVector;
+ // wait until next frame
+ await Script.NextFrame();
+ }
+ }
- Vector3 xaxis, yaxis, zaxis;
- Vector3.Subtract(ref eyePosition, ref targetPosition, out zaxis);
- var laserLength = zaxis.Length();
- zaxis.Normalize();
- Vector3.Cross(ref upVector, ref zaxis, out xaxis); xaxis.Normalize();
- Vector3.Cross(ref zaxis, ref xaxis, out yaxis);
+ private void UpdateRotation()
+ {
+ var eyePosition = Entity.Transform.WorldMatrix.TranslationVector;
- var result = Matrix.Identity;
- result.M11 = xaxis.X; result.M12 = xaxis.Y; result.M13 = xaxis.Z;
- result.M21 = yaxis.X; result.M22 = yaxis.Y; result.M23 = yaxis.Z;
- result.M31 = zaxis.X; result.M32 = zaxis.Y; result.M33 = zaxis.Z;
+ Vector3.Subtract(ref eyePosition, ref targetPosition, out var zaxis);
+ var laserLength = zaxis.Length();
+ zaxis.Normalize();
+ Vector3.Cross(ref upVector, ref zaxis, out var xaxis); xaxis.Normalize();
+ Vector3.Cross(ref zaxis, ref xaxis, out var yaxis);
- var rotation = Quaternion.Identity;
+ var result = Matrix.Identity;
+ result.M11 = xaxis.X; result.M12 = xaxis.Y; result.M13 = xaxis.Z;
+ result.M21 = yaxis.X; result.M22 = yaxis.Y; result.M23 = yaxis.Z;
+ result.M31 = zaxis.X; result.M32 = zaxis.Y; result.M33 = zaxis.Z;
- Quaternion.RotationMatrix(ref result, out rotation);
+ Quaternion.RotationMatrix(ref result, out var rotation);
- Entity.Transform.Rotation = rotation;
+ Entity.Transform.Rotation = rotation;
- if (doNotScale)
- return;
+ if (doNotScale)
+ return;
- if (scaleOnlyZ)
- {
- Entity.Transform.Scale = new Vector3(Entity.Transform.Scale.X, Entity.Transform.Scale.Y, laserLength);
- }
- else
- {
- Entity.Transform.Scale = new Vector3(laserLength, laserLength, laserLength);
- }
- }
+ Entity.Transform.Scale = scaleOnlyZ
+ ? new Vector3(Entity.Transform.Scale.X, Entity.Transform.Scale.Y, laserLength)
+ : new Vector3(laserLength, laserLength, laserLength);
}
}
diff --git a/samples/Particles/ParticlesSample/ParticlesSample.Game/Materials/ParticleCustomMaterial.cs b/samples/Particles/ParticlesSample/ParticlesSample.Game/Materials/ParticleCustomMaterial.cs
index f26063899d..ec1949cb55 100644
--- a/samples/Particles/ParticlesSample/ParticlesSample.Game/Materials/ParticleCustomMaterial.cs
+++ b/samples/Particles/ParticlesSample/ParticlesSample.Game/Materials/ParticleCustomMaterial.cs
@@ -1,191 +1,173 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
-using System;
-using System.Text.RegularExpressions;
using Stride.Core;
using Stride.Core.Mathematics;
using Stride.Graphics;
+using Stride.Particles.Materials;
using Stride.Particles.Sorters;
using Stride.Particles.VertexLayouts;
using Stride.Rendering;
using Stride.Rendering.Materials;
using Stride.Rendering.Materials.ComputeColors;
using Stride.Shaders;
-using Stride.Particles.Materials;
-namespace ParticlesSample.Materials
+namespace ParticlesSample.Materials;
+
+[DataContract("ParticleCustomMaterial")]
+[Display("ParticleCustomMaterial")]
+public class ParticleCustomMaterial : ParticleMaterialSimple
{
- [DataContract("ParticleCustomMaterial")]
- [Display("ParticleCustomMaterial")]
- public class ParticleCustomMaterial : ParticleMaterialSimple
+ private ShaderSource shaderBaseColor;
+ private ShaderSource shaderBaseScalar;
+
+ [DataMemberIgnore]
+ public override string EffectName { get; protected set; } = "ParticleCustomEffect";
+
+ ///
+ /// allows several channels to be blended together, including textures, vertex streams and fixed values.
+ ///
+ ///
+ /// Emissive component ignores light and defines a fixed color this particle should use (emit) when rendered.
+ ///
+ [DataMember(100)]
+ [Display("Emissive")]
+ public IComputeColor ComputeColor { get; set; } = new ComputeTextureColor();
+
+ ///
+ /// defines how the base coordinates of the particle shape should be modified for texture scrolling, animation, etc.
+ ///
+ ///
+ /// If left blank, the texture coordinates will be the original ones from the shape builder, usually (0, 0, 1, 1). Or you can define a custom texture coordinate builder which modifies the original coordinates for the sprite.
+ ///
+ [DataMember(200)]
+ [Display("TexCoord0")]
+ public UVBuilder UVBuilder0;
+ private readonly AttributeDescription texCoord0 = new("TEXCOORD");
+
+ ///
+ /// allows several channels to be blended together, including textures, vertex streams and fixed values.
+ ///
+ ///
+ /// Alpha component which defines how opaque (1) or transparent (0) the color will be
+ ///
+ [DataMember(300)]
+ [Display("Alpha")]
+ public IComputeScalar ComputeScalar { get; set; } = new ComputeTextureScalar();
+
+ ///
+ /// defines how the base coordinates of the particle shape should be modified for texture scrolling, animation, etc.
+ ///
+ ///
+ /// If left blank, the texture coordinates will be the original ones from the shape builder, usually (0, 0, 1, 1). Or you can define a custom texture coordinate builder which modifies the original coordinates for the sprite.
+ ///
+ [DataMember(400)]
+ [Display("TexCoord1")]
+ public UVBuilder UVBuilder1;
+ private readonly AttributeDescription texCoord1 = new("TEXCOORD1");
+
+ protected override void InitializeCore(RenderContext context)
{
- private ShaderSource shaderBaseColor;
- private ShaderSource shaderBaseScalar;
-
- [DataMemberIgnore]
- public override string EffectName
- {
- get { return effectName; }
- protected set { effectName = value; }
- }
- private string effectName = "ParticleCustomEffect";
-
- ///
- /// allows several channels to be blended together, including textures, vertex streams and fixed values.
- ///
- ///
- /// Emissive component ignores light and defines a fixed color this particle should use (emit) when rendered.
- ///
- [DataMember(100)]
- [Display("Emissive")]
- public IComputeColor ComputeColor
- {
- get { return computeColor; }
- set { computeColor = value; }
- }
- private IComputeColor computeColor = new ComputeTextureColor();
-
- ///
- /// defines how the base coordinates of the particle shape should be modified for texture scrolling, animation, etc.
- ///
- ///
- /// If left blank, the texture coordinates will be the original ones from the shape builder, usually (0, 0, 1, 1). Or you can define a custom texture coordinate builder which modifies the original coordinates for the sprite.
- ///
- [DataMember(200)]
- [Display("TexCoord0")]
- public UVBuilder UVBuilder0;
- private readonly AttributeDescription texCoord0 = new AttributeDescription("TEXCOORD");
-
- ///
- /// allows several channels to be blended together, including textures, vertex streams and fixed values.
- ///
- ///
- /// Alpha component which defines how opaque (1) or transparent (0) the color will be
- ///
- [DataMember(300)]
- [Display("Alpha")]
- public IComputeScalar ComputeScalar
- {
- get { return computeScalar; }
- set { computeScalar = value; }
- }
- private IComputeScalar computeScalar = new ComputeTextureScalar();
-
- ///
- /// defines how the base coordinates of the particle shape should be modified for texture scrolling, animation, etc.
- ///
- ///
- /// If left blank, the texture coordinates will be the original ones from the shape builder, usually (0, 0, 1, 1). Or you can define a custom texture coordinate builder which modifies the original coordinates for the sprite.
- ///
- [DataMember(400)]
- [Display("TexCoord1")]
- public UVBuilder UVBuilder1;
- private readonly AttributeDescription texCoord1 = new AttributeDescription("TEXCOORD1");
-
- protected override void InitializeCore(RenderContext context)
- {
- base.InitializeCore(context);
+ base.InitializeCore(context);
- UpdateShaders(context.GraphicsDevice);
- }
+ UpdateShaders(context.GraphicsDevice);
+ }
- ///
- public override void Setup(RenderContext context)
- {
- base.Setup(context);
+ ///
+ public override void Setup(RenderContext context)
+ {
+ base.Setup(context);
- UpdateShaders(context.GraphicsDevice);
- }
+ UpdateShaders(context.GraphicsDevice);
+ }
- public override void ValidateEffect(RenderContext context, ref EffectValidator effectValidator)
- {
- effectValidator.ValidateParameter(ParticleCustomShaderKeys.BaseColor, shaderBaseColor);
- effectValidator.ValidateParameter(ParticleCustomShaderKeys.BaseIntensity, shaderBaseScalar);
- }
+ public override void ValidateEffect(RenderContext context, ref EffectValidator effectValidator)
+ {
+ effectValidator.ValidateParameter(ParticleCustomShaderKeys.BaseColor, shaderBaseColor);
+ effectValidator.ValidateParameter(ParticleCustomShaderKeys.BaseIntensity, shaderBaseScalar);
+ }
- private void UpdateShaders(GraphicsDevice graphicsDevice)
+ private void UpdateShaders(GraphicsDevice graphicsDevice)
+ {
+ if (ComputeColor != null && ComputeScalar != null)
{
- if (ComputeColor != null && ComputeScalar != null)
+ var shaderGeneratorContext = new ShaderGeneratorContext(graphicsDevice)
{
- var shaderGeneratorContext = new ShaderGeneratorContext(graphicsDevice)
- {
- Parameters = Parameters,
- ColorSpace = graphicsDevice.ColorSpace
- };
-
- // Don't forget to set the proper color space!
- shaderGeneratorContext.ColorSpace = graphicsDevice.ColorSpace;
-
- var newShaderBaseColor = ComputeColor.GenerateShaderSource(shaderGeneratorContext, new MaterialComputeColorKeys(ParticleCustomShaderKeys.EmissiveMap, ParticleCustomShaderKeys.EmissiveValue, Color.White));
- var newShaderBaseScalar = ComputeScalar.GenerateShaderSource(shaderGeneratorContext, new MaterialComputeColorKeys(ParticleCustomShaderKeys.IntensityMap, ParticleCustomShaderKeys.IntensityValue, Color.White));
-
- // Check if shader code has changed
- if (!newShaderBaseColor.Equals(shaderBaseColor) || !newShaderBaseScalar.Equals(shaderBaseScalar))
- {
- shaderBaseColor = newShaderBaseColor;
- shaderBaseScalar = newShaderBaseScalar;
- Parameters.Set(ParticleCustomShaderKeys.BaseColor, shaderBaseColor);
- Parameters.Set(ParticleCustomShaderKeys.BaseIntensity, shaderBaseScalar);
-
- // TODO: Is this necessary?
- HasVertexLayoutChanged = true;
- }
- }
- }
+ Parameters = Parameters,
+ ColorSpace = graphicsDevice.ColorSpace
+ };
- public override void UpdateVertexBuilder(ParticleVertexBuilder vertexBuilder)
- {
- base.UpdateVertexBuilder(vertexBuilder);
+ // Don't forget to set the proper color space!
+ shaderGeneratorContext.ColorSpace = graphicsDevice.ColorSpace;
- var code = shaderBaseColor != null ? shaderBaseColor.ToString() : null;
+ var newShaderBaseColor = ComputeColor.GenerateShaderSource(shaderGeneratorContext, new MaterialComputeColorKeys(ParticleCustomShaderKeys.EmissiveMap, ParticleCustomShaderKeys.EmissiveValue, Color.White));
+ var newShaderBaseScalar = ComputeScalar.GenerateShaderSource(shaderGeneratorContext, new MaterialComputeColorKeys(ParticleCustomShaderKeys.IntensityMap, ParticleCustomShaderKeys.IntensityValue, Color.White));
- if (code != null && code.Contains("COLOR0"))
+ // Check if shader code has changed
+ if (!newShaderBaseColor.Equals(shaderBaseColor) || !newShaderBaseScalar.Equals(shaderBaseScalar))
{
- vertexBuilder.AddVertexElement(ParticleVertexElements.Color);
+ shaderBaseColor = newShaderBaseColor;
+ shaderBaseScalar = newShaderBaseScalar;
+ Parameters.Set(ParticleCustomShaderKeys.BaseColor, shaderBaseColor);
+ Parameters.Set(ParticleCustomShaderKeys.BaseIntensity, shaderBaseScalar);
+
+ // TODO: Is this necessary?
+ HasVertexLayoutChanged = true;
}
+ }
+ }
- // There are two UV builders, building texCoord0 and texCoord1
- // Which set is referenced can be set by the user in the IComputeColor tree
- vertexBuilder.AddVertexElement(ParticleVertexElements.TexCoord[0]);
+ public override void UpdateVertexBuilder(ParticleVertexBuilder vertexBuilder)
+ {
+ base.UpdateVertexBuilder(vertexBuilder);
- vertexBuilder.AddVertexElement(ParticleVertexElements.TexCoord[1]);
- }
+ var code = shaderBaseColor?.ToString();
- public override unsafe void PatchVertexBuffer(ref ParticleBufferState bufferState, Vector3 invViewX, Vector3 invViewY, ref ParticleList sorter)
+ if (code != null && code.Contains("COLOR0"))
{
- // If you want, you can integrate the base builder here and not call it. It should result in slight speed up
- base.PatchVertexBuffer(ref bufferState, invViewX, invViewY, ref sorter);
+ vertexBuilder.AddVertexElement(ParticleVertexElements.Color);
+ }
- // Update the non-default coordinates first, because they update off the default ones
- if (UVBuilder1 != null) UVBuilder1.BuildUVCoordinates(ref bufferState, ref sorter, texCoord1);
+ // There are two UV builders, building texCoord0 and texCoord1
+ // Which set is referenced can be set by the user in the IComputeColor tree
+ vertexBuilder.AddVertexElement(ParticleVertexElements.TexCoord[0]);
- // Update the default coordinates last
- if (UVBuilder0 != null) UVBuilder0.BuildUVCoordinates(ref bufferState, ref sorter, texCoord0);
+ vertexBuilder.AddVertexElement(ParticleVertexElements.TexCoord[1]);
+ }
- // If the particles have color field, the base class should have already passed the information
- if (HasColorField)
- return;
+ public override unsafe void PatchVertexBuffer(ref ParticleBufferState bufferState, Vector3 invViewX, Vector3 invViewY, ref ParticleList sorter)
+ {
+ // If you want, you can integrate the base builder here and not call it. It should result in slight speed up
+ base.PatchVertexBuffer(ref bufferState, invViewX, invViewY, ref sorter);
- // If there is no color stream we don't need to fill anything
- var colAttribute = bufferState.GetAccessor(VertexAttributes.Color);
- if (colAttribute.Size <= 0)
- return;
+ // Update the non-default coordinates first, because they update off the default ones
+ if (UVBuilder1 != null) UVBuilder1.BuildUVCoordinates(ref bufferState, ref sorter, texCoord1);
- // Since the particles don't have their own color field, set the default color to white
- var color = 0xFFFFFFFF;
+ // Update the default coordinates last
+ if (UVBuilder0 != null) UVBuilder0.BuildUVCoordinates(ref bufferState, ref sorter, texCoord0);
- bufferState.StartOver();
- foreach (var particle in sorter)
- {
- bufferState.SetAttributePerParticle(colAttribute, (IntPtr)(&color));
+ // If the particles have color field, the base class should have already passed the information
+ if (HasColorField)
+ return;
- bufferState.NextParticle();
- }
+ // If there is no color stream we don't need to fill anything
+ var colAttribute = bufferState.GetAccessor(VertexAttributes.Color);
+ if (colAttribute.Size <= 0)
+ return;
- bufferState.StartOver();
+ // Since the particles don't have their own color field, set the default color to white
+ var color = 0xFFFFFFFF;
+
+ bufferState.StartOver();
+ foreach (var particle in sorter)
+ {
+ bufferState.SetAttributePerParticle(colAttribute, (IntPtr)(&color));
+
+ bufferState.NextParticle();
}
+ bufferState.StartOver();
}
+
}
diff --git a/samples/Particles/ParticlesSample/ParticlesSample.Game/Materials/ParticleCustomShaderKeys.cs b/samples/Particles/ParticlesSample/ParticlesSample.Game/Materials/ParticleCustomShaderKeys.cs
index a63b18bea7..14ff5318a4 100644
--- a/samples/Particles/ParticlesSample/ParticlesSample.Game/Materials/ParticleCustomShaderKeys.cs
+++ b/samples/Particles/ParticlesSample/ParticlesSample.Game/Materials/ParticleCustomShaderKeys.cs
@@ -6,16 +6,15 @@
using Stride.Shaders;
//namespace Stride.Rendering
-namespace Stride.Rendering
+namespace Stride.Rendering;
+
+public partial class ParticleCustomShaderKeys
{
- public partial class ParticleCustomShaderKeys
- {
- public static readonly PermutationParameterKey BaseColor = ParameterKeys.NewPermutation();
- public static readonly ObjectParameterKey EmissiveMap = ParameterKeys.NewObject();
- public static readonly ValueParameterKey EmissiveValue = ParameterKeys.NewValue();
+ public static readonly PermutationParameterKey BaseColor = ParameterKeys.NewPermutation();
+ public static readonly ObjectParameterKey EmissiveMap = ParameterKeys.NewObject();
+ public static readonly ValueParameterKey EmissiveValue = ParameterKeys.NewValue();
- public static readonly PermutationParameterKey BaseIntensity = ParameterKeys.NewPermutation();
- public static readonly ObjectParameterKey IntensityMap = ParameterKeys.NewObject();
- public static readonly ValueParameterKey IntensityValue = ParameterKeys.NewValue();
- }
+ public static readonly PermutationParameterKey BaseIntensity = ParameterKeys.NewPermutation();
+ public static readonly ObjectParameterKey IntensityMap = ParameterKeys.NewObject();
+ public static readonly ValueParameterKey IntensityValue = ParameterKeys.NewValue();
}
diff --git a/samples/Particles/ParticlesSample/ParticlesSample.Game/NextSceneScript.cs b/samples/Particles/ParticlesSample/ParticlesSample.Game/NextSceneScript.cs
index bd1d4d1ba6..68fc23bc55 100644
--- a/samples/Particles/ParticlesSample/ParticlesSample.Game/NextSceneScript.cs
+++ b/samples/Particles/ParticlesSample/ParticlesSample.Game/NextSceneScript.cs
@@ -1,5 +1,6 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// 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.Graphics;
@@ -7,70 +8,69 @@
using Stride.UI.Controls;
using Stride.UI.Panels;
-namespace ParticlesSample
+namespace ParticlesSample;
+
+public class NextSceneScript : SyncScript
{
- public class NextSceneScript : SyncScript
- {
- public Scene Next;
+ public Scene Next;
- public Scene Previous;
+ public Scene Previous;
- public SpriteFont Font;
+ public SpriteFont Font;
- public override void Start()
- {
- SetupUI();
- }
+ public override void Start()
+ {
+ SetupUI();
+ }
- public override void Update() { }
+ public override void Update() { }
- private void SetupUI()
- {
- var uiComponent = Entity.Get();
- if (uiComponent == null)
- return;
+ private void SetupUI()
+ {
+ var uiComponent = Entity.Get();
+ if (uiComponent == null)
+ return;
- // Create the UI
- Entity.Get().Page = new UIPage
+ // Create the UI
+ Entity.Get().Page = new UIPage
+ {
+ RootElement = new Grid
{
- RootElement = new Grid
+ Children =
+ {
+ CreateButton("<<", 72, 0, Previous),
+ CreateButton(">>", 72, 2, Next)
+ },
+
+ ColumnDefinitions =
{
- Children =
- {
- CreateButton("<<", 72, 0, Previous),
- CreateButton(">>", 72, 2, Next)
- },
-
- ColumnDefinitions =
- {
- new StripDefinition(StripType.Auto, 10),
- new StripDefinition(StripType.Star, 80),
- new StripDefinition(StripType.Auto, 10),
+ new StripDefinition(StripType.Auto, 10),
+ new StripDefinition(StripType.Star, 80),
+ new StripDefinition(StripType.Auto, 10),
- }
}
- };
- }
+ }
+ };
+ }
- private Button CreateButton(string text, int textSize, int columnId, Scene targetScene)
+ private Button CreateButton(string text, int textSize, int columnId, Scene targetScene)
+ {
+ var button = new Button
{
- var button = new Button
- {
- Name = text,
- HorizontalAlignment = HorizontalAlignment.Center,
- Content = new TextBlock { Text = text, Font = Font, TextSize = textSize, TextColor = new Color(200, 200, 200, 255), VerticalAlignment = VerticalAlignment.Center },
- BackgroundColor = new Color(new Vector4(0.2f, 0.2f, 0.2f, 0.2f)),
- };
+ Name = text,
+ HorizontalAlignment = HorizontalAlignment.Center,
+ Content = new TextBlock { Text = text, Font = Font, TextSize = textSize, TextColor = new Color(200, 200, 200, 255), VerticalAlignment = VerticalAlignment.Center },
+ BackgroundColor = new Color(new Vector4(0.2f, 0.2f, 0.2f, 0.2f)),
+ };
- button.SetGridColumn(columnId);
+ button.SetGridColumn(columnId);
- button.Click += (sender, args) =>
- {
- SceneSystem.SceneInstance.RootScene = targetScene;
- Cancel();
- };
+ button.Click += (sender, args) =>
+ {
+ SceneSystem.SceneInstance.RootScene = targetScene;
+ Cancel();
+ };
- return button;
- }
+ return button;
}
}
diff --git a/samples/Particles/ParticlesSample/ParticlesSample.Game/Particles/CustomParticleFields.cs b/samples/Particles/ParticlesSample/ParticlesSample.Game/Particles/CustomParticleFields.cs
index 449739c439..69f322457d 100644
--- a/samples/Particles/ParticlesSample/ParticlesSample.Game/Particles/CustomParticleFields.cs
+++ b/samples/Particles/ParticlesSample/ParticlesSample.Game/Particles/CustomParticleFields.cs
@@ -4,13 +4,12 @@
using Stride.Core.Mathematics;
using Stride.Particles;
-namespace ParticlesSample.Particles
+namespace ParticlesSample.Particles;
+
+public static class CustomParticleFields
{
- public static class CustomParticleFields
- {
- ///
- /// Custom field for our particle, which defines non-uniform dimensions in 2D space
- ///
- public static readonly ParticleFieldDescription RectangleXY = new ParticleFieldDescription("RectangleXY", new Vector2(1, 1));
- }
+ ///
+ /// Custom field for our particle, which defines non-uniform dimensions in 2D space
+ ///
+ public static readonly ParticleFieldDescription RectangleXY = new("RectangleXY", new Vector2(1, 1));
}
diff --git a/samples/Particles/ParticlesSample/ParticlesSample.Game/Particles/Initializers/CustomParticleInitializer.cs b/samples/Particles/ParticlesSample/ParticlesSample.Game/Particles/Initializers/CustomParticleInitializer.cs
index 525f8a5f04..7e2081c9cc 100644
--- a/samples/Particles/ParticlesSample/ParticlesSample.Game/Particles/Initializers/CustomParticleInitializer.cs
+++ b/samples/Particles/ParticlesSample/ParticlesSample.Game/Particles/Initializers/CustomParticleInitializer.cs
@@ -1,7 +1,6 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
-using System;
using System.ComponentModel;
using Stride.Core;
using Stride.Core.Annotations;
@@ -10,106 +9,105 @@
using Stride.Particles.DebugDraw;
using Stride.Particles.Initializers;
-namespace ParticlesSample.Particles.Initializers
+namespace ParticlesSample.Particles.Initializers;
+
+[DataContract("CustomParticleInitializer")]
+[Display("Custom Cone Initializer")]
+public class CustomParticleInitializer : ParticleInitializer
{
- [DataContract("CustomParticleInitializer")]
- [Display("Custom Cone Initializer")]
- public class CustomParticleInitializer : ParticleInitializer
- {
- [DataMember(100)]
- [DataMemberRange(0, 120, 1, 5, 2)]
- [Display("Arc")]
- public float Angle = 20f;
+ [DataMember(100)]
+ [DataMemberRange(0, 120, 1, 5, 2)]
+ [Display("Arc")]
+ public float Angle = 20f;
- [DataMember(200)]
- [Display("Velocity")]
- public float Strength = 1f;
+ [DataMember(200)]
+ [Display("Velocity")]
+ public float Strength = 1f;
- public CustomParticleInitializer()
- {
- DebugDraw = false;
- RequiredFields.Add(ParticleFields.Position);
- RequiredFields.Add(ParticleFields.Velocity);
- RequiredFields.Add(ParticleFields.RandomSeed);
- }
+ public CustomParticleInitializer()
+ {
+ DebugDraw = false;
+ RequiredFields.Add(ParticleFields.Position);
+ RequiredFields.Add(ParticleFields.Velocity);
+ RequiredFields.Add(ParticleFields.RandomSeed);
+ }
- public override unsafe void Initialize(ParticlePool pool, int startIdx, int endIdx, int maxCapacity)
- {
- if (!pool.FieldExists(ParticleFields.Position) || !pool.FieldExists(ParticleFields.Velocity) || !pool.FieldExists(ParticleFields.RandomSeed))
- return;
+ public override unsafe void Initialize(ParticlePool pool, int startIdx, int endIdx, int maxCapacity)
+ {
+ if (!pool.FieldExists(ParticleFields.Position) || !pool.FieldExists(ParticleFields.Velocity) || !pool.FieldExists(ParticleFields.RandomSeed))
+ return;
- var posField = pool.GetField(ParticleFields.Position);
- var velField = pool.GetField(ParticleFields.Velocity);
- var rndField = pool.GetField(ParticleFields.RandomSeed);
+ var posField = pool.GetField(ParticleFields.Position);
+ var velField = pool.GetField(ParticleFields.Velocity);
+ var rndField = pool.GetField(ParticleFields.RandomSeed);
- var range = (float)(Angle * Math.PI / 180f);
- var magnitude = WorldScale.X;
+ var range = (float)(Angle * Math.PI / 180f);
+ var magnitude = WorldScale.X;
- var i = startIdx;
- while (i != endIdx)
- {
- var particle = pool.FromIndex(i);
- var randSeed = particle.Get(rndField);
+ var i = startIdx;
+ while (i != endIdx)
+ {
+ var particle = pool.FromIndex(i);
+ var randSeed = particle.Get(rndField);
- var x = (randSeed.GetFloat(RandomOffset.Offset2A + SeedOffset) - 0.5f) * range;
- var z = (randSeed.GetFloat(RandomOffset.Offset2B + SeedOffset) - 0.5f) * range;
+ var x = (randSeed.GetFloat(RandomOffset.Offset2A + SeedOffset) - 0.5f) * range;
+ var z = (randSeed.GetFloat(RandomOffset.Offset2B + SeedOffset) - 0.5f) * range;
- var u = (randSeed.GetFloat(RandomOffset.Offset2A + SeedOffset) - 0.5f) * range;
- var v = (randSeed.GetFloat(RandomOffset.Offset2B + SeedOffset) - 0.5f) * Math.PI;
+ var u = (randSeed.GetFloat(RandomOffset.Offset2A + SeedOffset) - 0.5f) * range;
+ var v = (randSeed.GetFloat(RandomOffset.Offset2B + SeedOffset) - 0.5f) * Math.PI;
- // var particleRandPos = new Vector3(x, 1, z);
+ // var particleRandPos = new Vector3(x, 1, z);
- var xz = (float)Math.Sin(u);
- var particleRandPos = new Vector3((float)Math.Cos(v) * xz, (float)Math.Sqrt(1 - u * u), (float)Math.Sin(v) * xz);
- particleRandPos.Normalize();
+ var xz = (float)Math.Sin(u);
+ var particleRandPos = new Vector3((float)Math.Cos(v) * xz, (float)Math.Sqrt(1 - u * u), (float)Math.Sin(v) * xz);
+ particleRandPos.Normalize();
- particleRandPos *= magnitude;
- WorldRotation.Rotate(ref particleRandPos);
+ particleRandPos *= magnitude;
+ WorldRotation.Rotate(ref particleRandPos);
- (*((Vector3*)particle[posField])) = particleRandPos + WorldPosition;
+ (*((Vector3*)particle[posField])) = particleRandPos + WorldPosition;
- (*((Vector3*)particle[velField])) = particleRandPos * Strength;
+ (*((Vector3*)particle[velField])) = particleRandPos * Strength;
- i = (i + 1) % maxCapacity;
- }
+ i = (i + 1) % maxCapacity;
}
+ }
- [DataMember(8)]
- [Display("Seed offset")]
- public UInt32 SeedOffset { get; set; }
-
- ///
- /// Should this Particle Module's bounds be displayed as a debug draw
- ///
- ///
- /// Display the Particle Module's bounds as a wireframe debug shape.
- ///
- [DataMember(-1)]
- [DefaultValue(false)]
- public bool DebugDraw { get; set; }
-
- public override bool TryGetDebugDrawShape(out DebugDrawShape debugDrawShape, out Vector3 translation, out Quaternion rotation, out Vector3 scale)
- {
- if (!DebugDraw)
- return base.TryGetDebugDrawShape(out debugDrawShape, out translation, out rotation, out scale);
+ [DataMember(8)]
+ [Display("Seed offset")]
+ public UInt32 SeedOffset { get; set; }
+
+ ///
+ /// Should this Particle Module's bounds be displayed as a debug draw
+ ///
+ ///
+ /// Display the Particle Module's bounds as a wireframe debug shape.
+ ///
+ [DataMember(-1)]
+ [DefaultValue(false)]
+ public bool DebugDraw { get; set; }
+
+ public override bool TryGetDebugDrawShape(out DebugDrawShape debugDrawShape, out Vector3 translation, out Quaternion rotation, out Vector3 scale)
+ {
+ if (!DebugDraw)
+ return base.TryGetDebugDrawShape(out debugDrawShape, out translation, out rotation, out scale);
- debugDrawShape = DebugDrawShape.Cone;
+ debugDrawShape = DebugDrawShape.Cone;
- rotation = WorldRotation;
+ rotation = WorldRotation;
- scale = new Vector3(1, -1, 1);
- translation = new Vector3(0, Strength + 1, 0);
+ scale = new Vector3(1, -1, 1);
+ translation = new Vector3(0, Strength + 1, 0);
- var radiusToStrength = (float)Math.Tan((Angle * Math.PI / 180f)) * (Strength + 1);
- var coneScale = new Vector3(radiusToStrength, Strength + 1, radiusToStrength);
+ var radiusToStrength = (float)Math.Tan((Angle * Math.PI / 180f)) * (Strength + 1);
+ var coneScale = new Vector3(radiusToStrength, Strength + 1, radiusToStrength);
- scale *= WorldScale * coneScale;
- rotation.Rotate(ref translation);
- translation += WorldPosition;
+ scale *= WorldScale * coneScale;
+ rotation.Rotate(ref translation);
+ translation += WorldPosition;
- return true;
- }
+ return true;
}
}
diff --git a/samples/Particles/ParticlesSample/ParticlesSample.Game/Particles/ShapeBuilders/CustomParticleShape.cs b/samples/Particles/ParticlesSample/ParticlesSample.Game/Particles/ShapeBuilders/CustomParticleShape.cs
index 44dde90ef8..8cc3306fc7 100644
--- a/samples/Particles/ParticlesSample/ParticlesSample.Game/Particles/ShapeBuilders/CustomParticleShape.cs
+++ b/samples/Particles/ParticlesSample/ParticlesSample.Game/Particles/ShapeBuilders/CustomParticleShape.cs
@@ -1,141 +1,133 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
-using System;
using Stride.Core;
using Stride.Core.Mathematics;
using Stride.Particles;
+using Stride.Particles.ShapeBuilders;
using Stride.Particles.Sorters;
using Stride.Particles.VertexLayouts;
-using Stride.Particles.ShapeBuilders;
-namespace ParticlesSample.Particles.ShapeBuilders
+namespace ParticlesSample.Particles.ShapeBuilders;
+
+[DataContract("CustomParticleShape")]
+[Display("CustomShape")]
+public class CustomParticleShape : ShapeBuilder
{
- [DataContract("CustomParticleShape")]
- [Display("CustomShape")]
- public class CustomParticleShape : ShapeBuilder
+ [DataMember(100)]
+ public bool FixYAxis = false;
+
+ // One particle requires 1 quad = 4 vertices (6 indices)
+ public override int QuadsPerParticle { get; protected set; } = 1;
+
+ ///
+ public override unsafe int BuildVertexBuffer(ref ParticleBufferState bufferState, Vector3 invViewX, Vector3 invViewY,
+ ref Vector3 spaceTranslation, ref Quaternion spaceRotation, float spaceScale, ref ParticleList sorter, ref Matrix viewProj)
{
- [DataMember(100)]
- public bool FixYAxis = false;
+ // Step 1 - get all required fields to build the particle shapes. Some fields may not exist if no initializer or updater operates on them
+ // In that case we just decide on a default value for that field and skip the update
- private int quadsPerParticle = 1;
+ var positionField = sorter.GetField(ParticleFields.Position);
+ if (!positionField.IsValid())
+ return 0; // We can't display the particles without position. All other fields are optional
- // One particle requires 1 quad = 4 vertices (6 indices)
- public override int QuadsPerParticle
- {
- get { return quadsPerParticle; }
- protected set { quadsPerParticle = value; }
- }
+ var sizeField = sorter.GetField(ParticleFields.Size);
+ var angleField = sorter.GetField(ParticleFields.Angle);
+ var hasAngle = angleField.IsValid();
+
+ var rectField = sorter.GetField(CustomParticleFields.RectangleXY);
+ var isRectangle = rectField.IsValid();
+
+ // In case of Local space particles they are simulated in local emitter space, but drawn in world space
+ // If the draw space is identity (i.e. simulation space = draw space) skip transforming the particle's location later
+ var trsIdentity = (spaceScale == 1f);
+ trsIdentity = trsIdentity && (spaceTranslation.Equals(new Vector3(0, 0, 0)));
+ trsIdentity = trsIdentity && (spaceRotation.Equals(new Quaternion(0, 0, 0, 1)));
- ///
- public override unsafe int BuildVertexBuffer(ref ParticleBufferState bufferState, Vector3 invViewX, Vector3 invViewY,
- ref Vector3 spaceTranslation, ref Quaternion spaceRotation, float spaceScale, ref ParticleList sorter, ref Matrix viewProj)
+ // Custom feature - fix the Y axis to always point up in world space rather than screen space
+ if (FixYAxis)
{
- // Step 1 - get all required fields to build the particle shapes. Some fields may not exist if no initializer or updater operates on them
- // In that case we just decide on a default value for that field and skip the update
+ invViewY = new Vector3(0, 1, 0);
+ invViewX.Y = 0;
+ invViewX.Normalize();
+ }
- var positionField = sorter.GetField(ParticleFields.Position);
- if (!positionField.IsValid())
- return 0; // We can't display the particles without position. All other fields are optional
+ var renderedParticles = 0;
- var sizeField = sorter.GetField(ParticleFields.Size);
- var angleField = sorter.GetField(ParticleFields.Angle);
- var hasAngle = angleField.IsValid();
+ var posAttribute = bufferState.GetAccessor(VertexAttributes.Position);
+ var texAttribute = bufferState.GetAccessor(bufferState.DefaultTexCoords);
- var rectField = sorter.GetField(CustomParticleFields.RectangleXY);
- var isRectangle = rectField.IsValid();
+ foreach (var particle in sorter)
+ {
+ var centralPos = particle.Get(positionField);
- // In case of Local space particles they are simulated in local emitter space, but drawn in world space
- // If the draw space is identity (i.e. simulation space = draw space) skip transforming the particle's location later
- var trsIdentity = (spaceScale == 1f);
- trsIdentity = trsIdentity && (spaceTranslation.Equals(new Vector3(0, 0, 0)));
- trsIdentity = trsIdentity && (spaceRotation.Equals(new Quaternion(0, 0, 0, 1)));
+ var particleSize = sizeField.IsValid() ? particle.Get(sizeField) : 1f;
- // Custom feature - fix the Y axis to always point up in world space rather than screen space
- if (FixYAxis)
+ if (!trsIdentity)
{
- invViewY = new Vector3(0, 1, 0);
- invViewX.Y = 0;
- invViewX.Normalize();
+ spaceRotation.Rotate(ref centralPos);
+ centralPos = centralPos * spaceScale + spaceTranslation;
+ particleSize *= spaceScale;
}
- var renderedParticles = 0;
+ var unitX = invViewX * particleSize;
+ var unitY = invViewY * particleSize;
+ if (isRectangle)
+ {
+ var rectSize = particle.Get(rectField);
- var posAttribute = bufferState.GetAccessor(VertexAttributes.Position);
- var texAttribute = bufferState.GetAccessor(bufferState.DefaultTexCoords);
+ unitX *= rectSize.X;
+ unitY *= rectSize.Y;
+ }
- foreach (var particle in sorter)
+ // Particle rotation. Positive value means clockwise rotation.
+ if (hasAngle)
{
- var centralPos = particle.Get(positionField);
-
- var particleSize = sizeField.IsValid() ? particle.Get(sizeField) : 1f;
-
- if (!trsIdentity)
- {
- spaceRotation.Rotate(ref centralPos);
- centralPos = centralPos * spaceScale + spaceTranslation;
- particleSize *= spaceScale;
- }
-
- var unitX = invViewX * particleSize;
- var unitY = invViewY * particleSize;
- if (isRectangle)
- {
- var rectSize = particle.Get(rectField);
-
- unitX *= rectSize.X;
- unitY *= rectSize.Y;
- }
-
- // Particle rotation. Positive value means clockwise rotation.
- if (hasAngle)
- {
- var rotationAngle = particle.Get(angleField);
- var cosA = (float)Math.Cos(rotationAngle);
- var sinA = (float)Math.Sin(rotationAngle);
- var tempX = unitX * cosA - unitY * sinA;
- unitY = unitY * cosA + unitX * sinA;
- unitX = tempX;
- }
-
-
- var particlePos = centralPos - unitX + unitY;
- var uvCoord = new Vector2(0, 0);
- // 0f 0f
- bufferState.SetAttribute(posAttribute, (IntPtr)(&particlePos));
- bufferState.SetAttribute(texAttribute, (IntPtr)(&uvCoord));
- bufferState.NextVertex();
-
-
- // 1f 0f
- particlePos += unitX * 2;
- uvCoord.X = 1;
- bufferState.SetAttribute(posAttribute, (IntPtr)(&particlePos));
- bufferState.SetAttribute(texAttribute, (IntPtr)(&uvCoord));
- bufferState.NextVertex();
-
-
- // 1f 1f
- particlePos -= unitY * 2;
- uvCoord.Y = 1;
- bufferState.SetAttribute(posAttribute, (IntPtr)(&particlePos));
- bufferState.SetAttribute(texAttribute, (IntPtr)(&uvCoord));
- bufferState.NextVertex();
-
-
- // 0f 1f
- particlePos -= unitX * 2;
- uvCoord.X = 0;
- bufferState.SetAttribute(posAttribute, (IntPtr)(&particlePos));
- bufferState.SetAttribute(texAttribute, (IntPtr)(&uvCoord));
- bufferState.NextVertex();
-
- renderedParticles++;
+ var rotationAngle = particle.Get(angleField);
+ var cosA = (float)Math.Cos(rotationAngle);
+ var sinA = (float)Math.Sin(rotationAngle);
+ var tempX = unitX * cosA - unitY * sinA;
+ unitY = unitY * cosA + unitX * sinA;
+ unitX = tempX;
}
- // Return the number of updated vertices
- var vtxPerShape = 4 * QuadsPerParticle;
- return renderedParticles * vtxPerShape;
+
+ var particlePos = centralPos - unitX + unitY;
+ var uvCoord = new Vector2(0, 0);
+ // 0f 0f
+ bufferState.SetAttribute(posAttribute, (IntPtr)(&particlePos));
+ bufferState.SetAttribute(texAttribute, (IntPtr)(&uvCoord));
+ bufferState.NextVertex();
+
+
+ // 1f 0f
+ particlePos += unitX * 2;
+ uvCoord.X = 1;
+ bufferState.SetAttribute(posAttribute, (IntPtr)(&particlePos));
+ bufferState.SetAttribute(texAttribute, (IntPtr)(&uvCoord));
+ bufferState.NextVertex();
+
+
+ // 1f 1f
+ particlePos -= unitY * 2;
+ uvCoord.Y = 1;
+ bufferState.SetAttribute(posAttribute, (IntPtr)(&particlePos));
+ bufferState.SetAttribute(texAttribute, (IntPtr)(&uvCoord));
+ bufferState.NextVertex();
+
+
+ // 0f 1f
+ particlePos -= unitX * 2;
+ uvCoord.X = 0;
+ bufferState.SetAttribute(posAttribute, (IntPtr)(&particlePos));
+ bufferState.SetAttribute(texAttribute, (IntPtr)(&uvCoord));
+ bufferState.NextVertex();
+
+ renderedParticles++;
}
+
+ // Return the number of updated vertices
+ var vtxPerShape = 4 * QuadsPerParticle;
+ return renderedParticles * vtxPerShape;
}
}
diff --git a/samples/Particles/ParticlesSample/ParticlesSample.Game/Particles/Spawners/CustomParticleSpawner.cs b/samples/Particles/ParticlesSample/ParticlesSample.Game/Particles/Spawners/CustomParticleSpawner.cs
index 39eae8295d..661e456258 100644
--- a/samples/Particles/ParticlesSample/ParticlesSample.Game/Particles/Spawners/CustomParticleSpawner.cs
+++ b/samples/Particles/ParticlesSample/ParticlesSample.Game/Particles/Spawners/CustomParticleSpawner.cs
@@ -1,103 +1,93 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
-using System;
using Stride.Core;
using Stride.Particles;
using Stride.Particles.Spawners;
-namespace SimpleCustomParticles.Particles.Spawners
+namespace SimpleCustomParticles.Particles.Spawners;
+
+///
+/// A custom implementation for the .
+/// This spawner continuously spawns 100 particles per second and burst spawns 50 particles in a single frame with one second delays
+///
+[DataContract("CustomParticleSpawner")] // Used for serialization, a good practice is to have the data contract have the same name as the class
+[Display("CustomParticleSpawner")]
+public sealed class CustomParticleSpawner : ParticleSpawner
{
///
- /// A custom implementation for the .
- /// This spawner continuously spawns 100 particles per second and burst spawns 50 particles in a single frame with one second delays
+ /// Carry over the real part
///
- [DataContract("CustomParticleSpawner")] // Used for serialization, a good practice is to have the data contract have the same name as the class
- [Display("CustomParticleSpawner")]
- public sealed class CustomParticleSpawner : ParticleSpawner
+ [DataMemberIgnore]
+ private float carryOver; // Private members do not appear on the Property Grid
+
+ [DataMemberIgnore]
+ private float spawnCount = 100f; // Private members do not appear on the Property Grid
+
+ [DataMember(100)] // When data is serialized, this attribute decides its priority
+ [Display("Number of particles")] // This is the name which will be displayed on the Property Grid
+ public float SpawnCount
{
- ///
- /// Carry over the real part
- ///
- [DataMemberIgnore]
- private float carryOver; // Private members do not appear on the Property Grid
-
- [DataMemberIgnore]
- private float spawnCount; // Private members do not appear on the Property Grid
-
- [DataMember(100)] // When data is serialized, this attribute decides its priority
- [Display("Number of particles")] // This is the name which will be displayed on the Property Grid
- public float SpawnCount
+ get { return spawnCount; }
+ set
{
- get { return spawnCount; }
- set
- {
- // Notify the emitter that the rate has changed and the total maximum number of particles might need to change too
- MarkAsDirty();
- spawnCount = value;
- }
+ // Notify the emitter that the rate has changed and the total maximum number of particles might need to change too
+ MarkAsDirty();
+ spawnCount = value;
}
+ }
- [DataMemberIgnore]
- private float burstTimer; // Private members do not appear on the Property Grid
+ [DataMemberIgnore]
+ private float burstTimer; // Private members do not appear on the Property Grid
- [DataMemberIgnore]
- private float burstCount; // Private members do not appear on the Property Grid
+ [DataMemberIgnore]
+ private float burstCount = 50f; // Private members do not appear on the Property Grid
- [DataMember(200)] // When data is serialized, this attribute decides its priority
- [Display("Burst particles")] // This is the name which will be displayed on the Property Grid
- public float BurstCount
- {
- get { return burstCount; }
- set
- {
- // Notify the emitter that the rate has changed and the total maximum number of particles might need to change too
- MarkAsDirty();
- burstCount = value;
- }
- }
-
- public CustomParticleSpawner()
+ [DataMember(200)] // When data is serialized, this attribute decides its priority
+ [Display("Burst particles")] // This is the name which will be displayed on the Property Grid
+ public float BurstCount
+ {
+ get { return burstCount; }
+ set
{
- spawnCount = 100f;
- burstCount = 50f;
- carryOver = 0;
- burstTimer = 0;
+ // Notify the emitter that the rate has changed and the total maximum number of particles might need to change too
+ MarkAsDirty();
+ burstCount = value;
}
+ }
- ///
- public override int GetMaxParticlesPerSecond()
- {
- return (int)Math.Ceiling(SpawnCount) + (int)Math.Ceiling(BurstCount);
- }
+ ///
+ public override int GetMaxParticlesPerSecond()
+ {
+ return (int)Math.Ceiling(SpawnCount) + (int)Math.Ceiling(BurstCount);
+ }
- ///
- public override void SpawnNew(float dt, ParticleEmitter emitter)
- {
- // State is handled by the base class. Generally you only want to spawn particle when in active state
- var spawnerState = GetUpdatedState(dt, emitter);
- if (spawnerState != SpawnerState.Active)
- return;
+ ///
+ public override void SpawnNew(float dt, ParticleEmitter emitter)
+ {
+ // State is handled by the base class. Generally you only want to spawn particle when in active state
+ var spawnerState = GetUpdatedState(dt, emitter);
+ if (spawnerState != SpawnerState.Active)
+ return;
- // Calculate particles per second
- var toSpawn = spawnCount * dt + carryOver;
- var integerPart = (int)Math.Floor(toSpawn);
- carryOver = toSpawn - integerPart;
+ // Calculate particles per second
+ var toSpawn = spawnCount * dt + carryOver;
+ var integerPart = (int)Math.Floor(toSpawn);
+ carryOver = toSpawn - integerPart;
- // Calculate burst particles
- burstTimer -= dt;
- if (burstTimer < 0)
- {
- burstTimer += 1f;
- integerPart += (int)Math.Floor(BurstCount);
- }
+ // Calculate burst particles
+ burstTimer -= dt;
+ if (burstTimer < 0)
+ {
+ burstTimer += 1f;
+ integerPart += (int)Math.Floor(BurstCount);
+ }
- // Lastly, tell the emitter how many new particles do we want to spawn this frame
- emitter.EmitParticles(integerPart);
- }
+ // Lastly, tell the emitter how many new particles do we want to spawn this frame
+ emitter.EmitParticles(integerPart);
}
}
diff --git a/samples/Particles/ParticlesSample/ParticlesSample.Game/Particles/Updaters/CustomParticleUpdater.cs b/samples/Particles/ParticlesSample/ParticlesSample.Game/Particles/Updaters/CustomParticleUpdater.cs
index 2aae299202..cfefe7efce 100644
--- a/samples/Particles/ParticlesSample/ParticlesSample.Game/Particles/Updaters/CustomParticleUpdater.cs
+++ b/samples/Particles/ParticlesSample/ParticlesSample.Game/Particles/Updaters/CustomParticleUpdater.cs
@@ -1,133 +1,131 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
-using System;
using Stride.Core;
using Stride.Core.Mathematics;
using Stride.Particles;
using Stride.Particles.Modules;
-namespace ParticlesSample.Particles.Updaters
+namespace ParticlesSample.Particles.Updaters;
+
+public enum AnimatedCurveEnum
{
- public enum AnimatedCurveEnum
- {
- [Display("Cos(time)")]
- CosCos,
+ [Display("Cos(time)")]
+ CosCos,
- [Display("Sin(time)")]
- SinSin,
+ [Display("Sin(time)")]
+ SinSin,
- [Display("Cos/Sin")]
- CosSin,
+ [Display("Cos/Sin")]
+ CosSin,
- [Display("Sin/Cos")]
- SinCos,
+ [Display("Sin/Cos")]
+ SinCos,
+}
+
+[DataContract("CustomParticleUpdater")] // Used for serialization, a good practice is to have the data contract have the same name as the class
+[Display("CustomUpdater")]
+public class CustomParticleUpdater : ParticleUpdater
+{
+ // By making this updater a post-updater we can ensure it will be called for both newly spawned and old particles (1 frame or older)
+ [DataMemberIgnore]
+ public override bool IsPostUpdater
+ {
+ get { return true; }
}
- [DataContract("CustomParticleUpdater")] // Used for serialization, a good practice is to have the data contract have the same name as the class
- [Display("CustomUpdater")]
- public class CustomParticleUpdater : ParticleUpdater
+ ///
+ /// We use a simple matechematical function to calculate the rectangle's dimensions based on the particle's lifetime
+ ///
+ [DataMember(10)]
+ public AnimatedCurveEnum Curve;
+
+ public CustomParticleUpdater()
{
- // By making this updater a post-updater we can ensure it will be called for both newly spawned and old particles (1 frame or older)
- [DataMemberIgnore]
- public override bool IsPostUpdater
- {
- get { return true; }
- }
+ // This is going to be our "input" field
+ RequiredFields.Add(ParticleFields.Life);
- ///
- /// We use a simple matechematical function to calculate the rectangle's dimensions based on the particle's lifetime
- ///
- [DataMember(10)]
- public AnimatedCurveEnum Curve;
+ // This is the field we want to update
+ // It is not part of the basic fields - we created it just for this updater
+ RequiredFields.Add(CustomParticleFields.RectangleXY);
+ }
- public CustomParticleUpdater()
- {
- // This is going to be our "input" field
- RequiredFields.Add(ParticleFields.Life);
+ ///
+ /// The Update(...) step is called every frame for the particle pool, containing all particles
+ /// Since this is a post-updater the Update(...) step is called *after* new particles have spawned for this frame
+ /// Regular updaters are invoked *before* spawning new particles and avoid updating the particles on the frame they spawn
+ ///
+ public override void Update(float dt, ParticlePool pool)
+ {
+ // Make sure the fields we require exist, otherwise trying to access them will result in an invalid memory
+ // The particle pool can check if the accessor is valid on each access, but that would be very inefficient so it skips the check
+ if (!pool.FieldExists(ParticleFields.Life) || !pool.FieldExists(CustomParticleFields.RectangleXY))
+ return;
- // This is the field we want to update
- // It is not part of the basic fields - we created it just for this updater
- RequiredFields.Add(CustomParticleFields.RectangleXY);
- }
+ var lifeField = pool.GetField(ParticleFields.Life);
+ var rectField = pool.GetField(CustomParticleFields.RectangleXY);
- ///
- /// The Update(...) step is called every frame for the particle pool, containing all particles
- /// Since this is a post-updater the Update(...) step is called *after* new particles have spawned for this frame
- /// Regular updaters are invoked *before* spawning new particles and avoid updating the particles on the frame they spawn
- ///
- public override void Update(float dt, ParticlePool pool)
+ // Instead of switching for each particle, we switch only once and then batch-update the particles to improve performance
+ switch (Curve)
{
- // Make sure the fields we require exist, otherwise trying to access them will result in an invalid memory
- // The particle pool can check if the accessor is valid on each access, but that would be very inefficient so it skips the check
- if (!pool.FieldExists(ParticleFields.Life) || !pool.FieldExists(CustomParticleFields.RectangleXY))
- return;
-
- var lifeField = pool.GetField(ParticleFields.Life);
- var rectField = pool.GetField(CustomParticleFields.RectangleXY);
-
- // Instead of switching for each particle, we switch only once and then batch-update the particles to improve performance
- switch (Curve)
- {
- // X and Y sides both depend on cos(time)
- case AnimatedCurveEnum.CosCos:
+ // X and Y sides both depend on cos(time)
+ case AnimatedCurveEnum.CosCos:
+ {
+ foreach (var particle in pool)
{
- foreach (var particle in pool)
- {
- // Get the particle's remaining life. It's normalized between 0 and 1
- var lifePi = particle.Get(lifeField) * MathUtil.Pi;
-
- // Set the rectangle as a simple function over time
- particle.Set(rectField, new Vector2((float)Math.Cos(lifePi), (float)Math.Cos(lifePi)));
- }
+ // Get the particle's remaining life. It's normalized between 0 and 1
+ var lifePi = particle.Get(lifeField) * MathUtil.Pi;
+
+ // Set the rectangle as a simple function over time
+ particle.Set(rectField, new Vector2((float)Math.Cos(lifePi), (float)Math.Cos(lifePi)));
}
- break;
+ }
+ break;
- // X and Y sides both depend on sin(time)
- case AnimatedCurveEnum.SinSin:
+ // X and Y sides both depend on sin(time)
+ case AnimatedCurveEnum.SinSin:
+ {
+ foreach (var particle in pool)
{
- foreach (var particle in pool)
- {
- // Get the particle's remaining life. It's normalized between 0 and 1
- var lifePi = particle.Get(lifeField) * MathUtil.Pi;
-
- // Set the rectangle as a simple function over time
- particle.Set(rectField, new Vector2((float)Math.Sin(lifePi), (float)Math.Sin(lifePi)));
- }
+ // Get the particle's remaining life. It's normalized between 0 and 1
+ var lifePi = particle.Get(lifeField) * MathUtil.Pi;
+
+ // Set the rectangle as a simple function over time
+ particle.Set(rectField, new Vector2((float)Math.Sin(lifePi), (float)Math.Sin(lifePi)));
}
- break;
+ }
+ break;
- // X and Y sides depend on cos(time) and sin(time)
- case AnimatedCurveEnum.CosSin:
+ // X and Y sides depend on cos(time) and sin(time)
+ case AnimatedCurveEnum.CosSin:
+ {
+ foreach (var particle in pool)
{
- foreach (var particle in pool)
- {
- // Get the particle's remaining life. It's normalized between 0 and 1
- var lifePi = particle.Get(lifeField) * MathUtil.Pi;
-
- // Set the rectangle as a simple function over time
- particle.Set(rectField, new Vector2((float)Math.Cos(lifePi), (float)Math.Sin(lifePi)));
- }
+ // Get the particle's remaining life. It's normalized between 0 and 1
+ var lifePi = particle.Get(lifeField) * MathUtil.Pi;
+
+ // Set the rectangle as a simple function over time
+ particle.Set(rectField, new Vector2((float)Math.Cos(lifePi), (float)Math.Sin(lifePi)));
}
- break;
+ }
+ break;
- // X and Y sides depend on sin(time) and cos(time)
- case AnimatedCurveEnum.SinCos:
+ // X and Y sides depend on sin(time) and cos(time)
+ case AnimatedCurveEnum.SinCos:
+ {
+ foreach (var particle in pool)
{
- foreach (var particle in pool)
- {
- // Get the particle's remaining life. It's normalized between 0 and 1
- var lifePi = particle.Get(lifeField) * MathUtil.Pi;
-
- // Set the rectangle as a simple function over time
- particle.Set(rectField, new Vector2((float)Math.Sin(lifePi), (float)Math.Cos(lifePi)));
- }
+ // Get the particle's remaining life. It's normalized between 0 and 1
+ var lifePi = particle.Get(lifeField) * MathUtil.Pi;
+
+ // Set the rectangle as a simple function over time
+ particle.Set(rectField, new Vector2((float)Math.Sin(lifePi), (float)Math.Cos(lifePi)));
}
- break;
- }
+ }
+ break;
}
}
}
diff --git a/samples/Particles/ParticlesSample/ParticlesSample.Game/ParticlesSample.Game.csproj b/samples/Particles/ParticlesSample/ParticlesSample.Game/ParticlesSample.Game.csproj
index a3b3465546..d351cd649d 100644
--- a/samples/Particles/ParticlesSample/ParticlesSample.Game/ParticlesSample.Game.csproj
+++ b/samples/Particles/ParticlesSample/ParticlesSample.Game/ParticlesSample.Game.csproj
@@ -3,6 +3,8 @@
net8.0
ParticlesSample
true
+ enable
+ latest
diff --git a/samples/Particles/ParticlesSample/ParticlesSample.Game/PrefabInstance.cs b/samples/Particles/ParticlesSample/ParticlesSample.Game/PrefabInstance.cs
index fae389fbae..c0e7ccb96a 100644
--- a/samples/Particles/ParticlesSample/ParticlesSample.Game/PrefabInstance.cs
+++ b/samples/Particles/ParticlesSample/ParticlesSample.Game/PrefabInstance.cs
@@ -1,141 +1,132 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
-using System;
-using System.Threading.Tasks;
using Stride.Core;
-using Stride.Input;
using Stride.Engine;
-namespace ParticlesSample
+namespace ParticlesSample;
+
+///
+/// A script which spawns a timed instance from a source prefab.
+///
+public class PrefabInstance : AsyncScript
{
///
- /// A script which spawns a timed instance from a source prefab.
+ /// Source to the prefab, selectable by the user
///
- public class PrefabInstance : AsyncScript
- {
- ///
- /// Source to the prefab, selectable by the user
- ///
- [DataMember(10)]
- [Display("Source")]
- public Prefab SourcePrefab;
-
- ///
- /// Should the prefab follow the entity's transform component on change or not
- ///
- [DataMember(20)]
- [Display("Following")]
- public bool Following
- {
- get { return following; }
- set { following = value; }
- }
- private bool following = true;
+ [DataMember(10)]
+ [Display("Source")]
+ public Prefab SourcePrefab;
+
+ ///
+ /// Should the prefab follow the entity's transform component on change or not
+ ///
+ [DataMember(20)]
+ [Display("Following")]
+ public bool Following { get; set; } = true;
- ///
- /// How long before the prefab instance is deleted, selectable by the user
- ///
- [DataMember(30)]
- [Display("Timeout")]
- public float InstanceTimeout = 3f;
+ ///
+ /// How long before the prefab instance is deleted, selectable by the user
+ ///
+ [DataMember(30)]
+ [Display("Timeout")]
+ public float InstanceTimeout = 3f;
- [DataMember(40)]
- [Display("Trigger Time")]
- public float TimeDelay { get; set; }
+ [DataMember(40)]
+ [Display("Trigger Time")]
+ public float TimeDelay { get; set; }
- [DataMember(50)]
- [Display("Animation")]
- public AnimationComponent Animation { get; set; }
+ [DataMember(50)]
+ [Display("Animation")]
+ public AnimationComponent Animation { get; set; }
- private bool canTrigger = true;
- private double lastTime = 0;
+ private bool canTrigger = true;
+ private double lastTime;
- public override async Task Execute()
+ public override async Task Execute()
+ {
+ while (Game.IsRunning)
{
- while (Game.IsRunning)
- {
- await Script.NextFrame();
+ await Script.NextFrame();
- if (IsTriggered())
- {
- SpawnInstance();
- }
+ if (IsTriggered())
+ {
+ SpawnInstance();
}
}
+ }
- protected bool IsTriggered()
- {
- var time = Animation?.PlayingAnimations[0].CurrentTime.TotalSeconds ?? 0;
+ protected bool IsTriggered()
+ {
+ var time = Animation?.PlayingAnimations[0].CurrentTime.TotalSeconds ?? 0;
- if (time < lastTime)
- canTrigger = true;
+ if (time < lastTime)
+ canTrigger = true;
- var isTriggered = (canTrigger && TimeDelay <= time);
+ var isTriggered = (canTrigger && TimeDelay <= time);
- lastTime = time;
- if (isTriggered)
- canTrigger = false;
+ lastTime = time;
+ if (isTriggered)
+ canTrigger = false;
- return isTriggered;
- }
+ return isTriggered;
+ }
+
+ ///
+ /// Will add a cloned entity from the prefab to the scene, wait for the specified time and delete it
+ ///
+ protected void SpawnInstance()
+ {
+ if (SourcePrefab == null)
+ return;
- ///
- /// Will add a cloned entity from the prefab to the scene, wait for the specified time and delete it
- ///
- protected void SpawnInstance()
+ Func spawnTask = async () =>
{
- if (SourcePrefab == null)
- return;
+ // Clone
+ var spawnedEntities = SourcePrefab.Instantiate();
- Func spawnTask = async () =>
+ // Add
+ foreach (var prefabEntity in spawnedEntities)
{
- // Clone
- var spawnedEntities = SourcePrefab.Instantiate();
-
- // Add
- foreach (var prefabEntity in spawnedEntities)
+ if (Following)
{
- if (Following)
- {
- Entity.AddChild(prefabEntity);
- }
- else
- {
- prefabEntity.Transform.UpdateLocalMatrix();
- var worldMatrix = prefabEntity.Transform.LocalMatrix * Entity.Transform.WorldMatrix;
- worldMatrix.Decompose(out prefabEntity.Transform.Scale, out prefabEntity.Transform.Rotation, out prefabEntity.Transform.Position);
-
- SceneSystem.SceneInstance.RootScene.Entities.Add(prefabEntity);
- }
+ Entity.AddChild(prefabEntity);
}
-
- // Countdown
- var secondsCountdown = InstanceTimeout;
- while (secondsCountdown > 0f)
+ else
{
- await Script.NextFrame();
- secondsCountdown -= (float)Game.UpdateTime.Elapsed.TotalSeconds;
+ prefabEntity.Transform.UpdateLocalMatrix();
+ var worldMatrix = prefabEntity.Transform.LocalMatrix * Entity.Transform.WorldMatrix;
+ worldMatrix.Decompose(out prefabEntity.Transform.Scale, out prefabEntity.Transform.Rotation, out prefabEntity.Transform.Position);
+
+ SceneSystem.SceneInstance.RootScene.Entities.Add(prefabEntity);
}
+ }
- // Remove
- foreach (var clonedEntity in spawnedEntities)
+ // Countdown
+ var secondsCountdown = InstanceTimeout;
+ while (secondsCountdown > 0f)
+ {
+ await Script.NextFrame();
+ secondsCountdown -= (float)Game.UpdateTime.Elapsed.TotalSeconds;
+ }
+
+ // Remove
+ foreach (var clonedEntity in spawnedEntities)
+ {
+ if (Following)
{
- if (Following)
- {
- Entity.RemoveChild(clonedEntity);
- }
- else
- {
- SceneSystem.SceneInstance.RootScene.Entities.Remove(clonedEntity);
- }
+ Entity.RemoveChild(clonedEntity);
}
+ else
+ {
+ SceneSystem.SceneInstance.RootScene.Entities.Remove(clonedEntity);
+ }
+ }
- // Cleanup
- spawnedEntities.Clear();
- };
+ // Cleanup
+ spawnedEntities.Clear();
+ };
- Script.AddTask(spawnTask);
- }
+ Script.AddTask(spawnTask);
}
}
diff --git a/samples/Particles/ParticlesSample/ParticlesSample.Game/RotateEntity.cs b/samples/Particles/ParticlesSample/ParticlesSample.Game/RotateEntity.cs
index fe460ef026..42008735ec 100644
--- a/samples/Particles/ParticlesSample/ParticlesSample.Game/RotateEntity.cs
+++ b/samples/Particles/ParticlesSample/ParticlesSample.Game/RotateEntity.cs
@@ -1,32 +1,30 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
-using System.Linq;
-using System.Threading.Tasks;
+
using Stride.Core.Mathematics;
using Stride.Engine;
-namespace ParticlesSample
+namespace ParticlesSample;
+
+///
+/// Rotate the entity when user slide its finger on the screen.
+///
+public class RotateEntity : AsyncScript
{
- ///
- /// Rotate the entity when user slide its finger on the screen.
- ///
- public class RotateEntity : AsyncScript
+ public override async Task Execute()
{
- public override async Task Execute()
- {
- var rotationSpeed = 0f;
+ var rotationSpeed = 0f;
- while (Game.IsRunning)
- {
- await Script.NextFrame();
+ while (Game.IsRunning)
+ {
+ await Script.NextFrame();
- if (Input.PointerEvents.Any())
- rotationSpeed = 200f * Input.PointerEvents.Sum(x => x.DeltaPosition.X);
+ if (Input.PointerEvents.Any())
+ rotationSpeed = 200f * Input.PointerEvents.Sum(x => x.DeltaPosition.X);
- rotationSpeed *= 0.93f;
- var elapsedTime = (float)Game.UpdateTime.Elapsed.TotalSeconds;
- Entity.Transform.Rotation *= Quaternion.RotationY(rotationSpeed * elapsedTime);
- }
+ rotationSpeed *= 0.93f;
+ var elapsedTime = (float)Game.UpdateTime.Elapsed.TotalSeconds;
+ Entity.Transform.Rotation *= Quaternion.RotationY(rotationSpeed * elapsedTime);
}
}
}
diff --git a/samples/Particles/ParticlesSample/ParticlesSample.Game/RotationScript.cs b/samples/Particles/ParticlesSample/ParticlesSample.Game/RotationScript.cs
index 8c9e8a1c32..5e4ced6287 100644
--- a/samples/Particles/ParticlesSample/ParticlesSample.Game/RotationScript.cs
+++ b/samples/Particles/ParticlesSample/ParticlesSample.Game/RotationScript.cs
@@ -1,59 +1,58 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
-using System;
-using Stride.Core.Mathematics;
+
using Stride.Animations;
+using Stride.Core.Mathematics;
using Stride.Engine;
-namespace ParticlesSample
+namespace ParticlesSample;
+
+public class RotationScript : StartupScript
{
- public class RotationScript : StartupScript
- {
- public float TimeFactor = 1f;
+ public float TimeFactor = 1f;
- public override void Start()
- {
- // Create an AnimationClip. Make sure to properly set it's duration.
- var animationClip = new AnimationClip { Duration = TimeSpan.FromSeconds(1) };
+ public override void Start()
+ {
+ // Create an AnimationClip. Make sure to properly set it's duration.
+ var animationClip = new AnimationClip { Duration = TimeSpan.FromSeconds(1) };
- animationClip.AddCurve("[TransformComponent.Key].Rotation", CreateLightRotationCurve());
+ animationClip.AddCurve("[TransformComponent.Key].Rotation", CreateLightRotationCurve());
- // Optional: Pack all animation channels into an optimized interleaved format
- animationClip.Optimize();
+ // Optional: Pack all animation channels into an optimized interleaved format
+ animationClip.Optimize();
- // Add an AnimationComponent to the current entity and register our custom clip
- const string animationName = "MyCustomAnimation";
- var animationComponent = Entity.GetOrCreate();
- animationComponent.Animations.Clear();
- animationComponent.Animations.Add(animationName, animationClip);
+ // Add an AnimationComponent to the current entity and register our custom clip
+ const string animationName = "MyCustomAnimation";
+ var animationComponent = Entity.GetOrCreate();
+ animationComponent.Animations.Clear();
+ animationComponent.Animations.Add(animationName, animationClip);
- // Start playing the animation right away and keep repeating it
- var playingAnimation = animationComponent.Play(animationName);
- playingAnimation.RepeatMode = AnimationRepeatMode.LoopInfinite;
- playingAnimation.TimeFactor = TimeFactor;
- playingAnimation.CurrentTime = TimeSpan.FromSeconds(0.6f); // start at different time
- }
+ // Start playing the animation right away and keep repeating it
+ var playingAnimation = animationComponent.Play(animationName);
+ playingAnimation.RepeatMode = AnimationRepeatMode.LoopInfinite;
+ playingAnimation.TimeFactor = TimeFactor;
+ playingAnimation.CurrentTime = TimeSpan.FromSeconds(0.6f); // start at different time
+ }
- private AnimationCurve CreateLightRotationCurve()
+ private static AnimationCurve CreateLightRotationCurve()
+ {
+ return new AnimationCurve
{
- return new AnimationCurve
+ InterpolationType = AnimationCurveInterpolationType.Linear,
+ KeyFrames =
{
- InterpolationType = AnimationCurveInterpolationType.Linear,
- KeyFrames =
- {
- CreateKeyFrame(0.00f, Quaternion.RotationX(0)),
- CreateKeyFrame(0.25f, Quaternion.RotationX(MathUtil.PiOverTwo)),
- CreateKeyFrame(0.50f, Quaternion.RotationX(MathUtil.Pi)),
- CreateKeyFrame(0.75f, Quaternion.RotationX(-MathUtil.PiOverTwo)),
- CreateKeyFrame(1.00f, Quaternion.RotationX(MathUtil.TwoPi))
- }
- };
- }
-
- private static KeyFrameData CreateKeyFrame(float keyTime, T value)
- {
- return new KeyFrameData((CompressedTimeSpan)TimeSpan.FromSeconds(keyTime), value);
- }
+ CreateKeyFrame(0.00f, Quaternion.RotationX(0)),
+ CreateKeyFrame(0.25f, Quaternion.RotationX(MathUtil.PiOverTwo)),
+ CreateKeyFrame(0.50f, Quaternion.RotationX(MathUtil.Pi)),
+ CreateKeyFrame(0.75f, Quaternion.RotationX(-MathUtil.PiOverTwo)),
+ CreateKeyFrame(1.00f, Quaternion.RotationX(MathUtil.TwoPi))
+ }
+ };
+ }
+
+ private static KeyFrameData CreateKeyFrame(float keyTime, T value)
+ {
+ return new KeyFrameData((CompressedTimeSpan)TimeSpan.FromSeconds(keyTime), value);
}
}
diff --git a/samples/Particles/ParticlesSample/ParticlesSample.Game/UIScript.cs b/samples/Particles/ParticlesSample/ParticlesSample.Game/UIScript.cs
index c16654a941..20a8ddb30a 100644
--- a/samples/Particles/ParticlesSample/ParticlesSample.Game/UIScript.cs
+++ b/samples/Particles/ParticlesSample/ParticlesSample.Game/UIScript.cs
@@ -1,55 +1,54 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
-using System;
+
using Stride.Engine;
using Stride.Graphics;
using Stride.UI;
using Stride.UI.Controls;
using Stride.UI.Panels;
-namespace ParticlesSample
+namespace ParticlesSample;
+
+public class UIScript : StartupScript
{
- public class UIScript : StartupScript
- {
- public Entity Knight;
+ public Entity Knight;
- public SpriteFont Font;
+ public SpriteFont Font;
+
+ public override void Start()
+ {
+ base.Start();
- public override void Start()
+ // Setup the UI
+ Entity.Get().Page.RootElement = new StackPanel
{
- base.Start();
+ Orientation = Orientation.Vertical,
+ HorizontalAlignment = HorizontalAlignment.Right,
+ Margin = new Thickness(0, 10, 20, 0),
+ Children = { CreateButton("Idle"), CreateButton("Run") }
+ };
- // Setup the UI
- Entity.Get().Page.RootElement = new StackPanel
- {
- Orientation = Orientation.Vertical,
- HorizontalAlignment = HorizontalAlignment.Right,
- Margin = new Thickness(0, 10, 20, 0),
- Children = { CreateButton("Idle"), CreateButton("Run") }
- };
-
- // Set the default animation
- Knight.Get().Play("Run");
- }
-
- ///
- /// Create a button and link the click action to the corresponding animation.
- ///
- private Button CreateButton(string animationName)
+ // Set the default animation
+ Knight.Get().Play("Run");
+ }
+
+ ///
+ /// Create a button and link the click action to the corresponding animation.
+ ///
+ private Button CreateButton(string animationName)
+ {
+ var idleButton = new Button
{
- var idleButton = new Button
+ Content = new TextBlock
{
- Content = new TextBlock
- {
- Text = "Play " + animationName,
- Font = Font,
- },
- Padding = new Thickness(10, 10, 10, 10),
- Margin = new Thickness(0, 0, 0, 10),
- };
- idleButton.Click += (s, e) => Knight.Get().Crossfade(animationName, TimeSpan.FromSeconds(0.1));
-
- return idleButton;
- }
+ Text = "Play " + animationName,
+ Font = Font,
+ },
+ Padding = new Thickness(10, 10, 10, 10),
+ Margin = new Thickness(0, 0, 0, 10),
+ };
+ idleButton.Click += (s, e) => Knight.Get().Crossfade(animationName, TimeSpan.FromSeconds(0.1));
+
+ return idleButton;
}
}
diff --git a/samples/Particles/ParticlesSample/ParticlesSample.Windows/ParticlesSample.Windows.csproj b/samples/Particles/ParticlesSample/ParticlesSample.Windows/ParticlesSample.Windows.csproj
index 89bda55a5b..cd159a740f 100644
--- a/samples/Particles/ParticlesSample/ParticlesSample.Windows/ParticlesSample.Windows.csproj
+++ b/samples/Particles/ParticlesSample/ParticlesSample.Windows/ParticlesSample.Windows.csproj
@@ -7,6 +7,8 @@
..\Bin\Windows\$(Configuration)\
false
STRIDE_PLATFORM_DESKTOP
+ enable
+ latest
$(MSBuildThisFileDirectory)..\ParticlesSample.sdpkg
diff --git a/samples/Physics/PhysicsSample/PhysicsSample.Game/AutoResetRigidBody.cs b/samples/Physics/PhysicsSample/PhysicsSample.Game/AutoResetRigidBody.cs
index 3ff743d84d..d930091896 100644
--- a/samples/Physics/PhysicsSample/PhysicsSample.Game/AutoResetRigidBody.cs
+++ b/samples/Physics/PhysicsSample/PhysicsSample.Game/AutoResetRigidBody.cs
@@ -1,54 +1,53 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
-using System.Threading.Tasks;
+
using Stride.Core.Mathematics;
using Stride.Engine;
using Stride.Engine.Events;
using Stride.Physics;
-namespace PhysicsSample
+namespace PhysicsSample;
+
+public class AutoResetRigidbody : AsyncScript
{
- public class AutoResetRigidbody : AsyncScript
- {
- private Vector3 startLocation;
- private Quaternion startRotation;
+ private Vector3 startLocation;
+ private Quaternion startRotation;
- public Entity TriggerEntity;
+ public Entity TriggerEntity;
- public override async Task Execute()
- {
- startLocation = Entity.Transform.Position;
- startRotation = Entity.Transform.Rotation;
+ public override async Task Execute()
+ {
+ startLocation = Entity.Transform.Position;
+ startRotation = Entity.Transform.Rotation;
- //grab a reference to the falling sphere's rigidbody
- var rigidBody = Entity.Get();
+ //grab a reference to the falling sphere's rigidbody
+ var rigidBody = Entity.Get();
- var triggerKey = TriggerEntity.Get().TriggerEvent;
- var receiver = new EventReceiver(triggerKey);
+ var triggerKey = TriggerEntity.Get().TriggerEvent;
+ var receiver = new EventReceiver(triggerKey);
- while (!CancellationToken.IsCancellationRequested)
- {
- var state = await receiver.ReceiveAsync();
+ while (!CancellationToken.IsCancellationRequested)
+ {
+ var state = await receiver.ReceiveAsync();
if (CancellationToken.IsCancellationRequested)
- return;
+ return;
- if (state)
- {
- //switch to dynamic and awake the rigid body
- rigidBody.RigidBodyType = RigidBodyTypes.Dynamic;
- rigidBody.Activate(true); //need to awake to object
- }
- else
- {
- //when out revert to kinematic and old starting position
- rigidBody.RigidBodyType = RigidBodyTypes.Kinematic;
- //reset position
- Entity.Transform.Position = startLocation;
- Entity.Transform.Rotation = startRotation;
- Entity.Transform.UpdateWorldMatrix();
- Entity.Get().UpdatePhysicsTransformation();
- }
+ if (state)
+ {
+ //switch to dynamic and awake the rigid body
+ rigidBody.RigidBodyType = RigidBodyTypes.Dynamic;
+ rigidBody.Activate(true); //need to awake to object
+ }
+ else
+ {
+ //when out revert to kinematic and old starting position
+ rigidBody.RigidBodyType = RigidBodyTypes.Kinematic;
+ //reset position
+ Entity.Transform.Position = startLocation;
+ Entity.Transform.Rotation = startRotation;
+ Entity.Transform.UpdateWorldMatrix();
+ Entity.Get().UpdatePhysicsTransformation();
}
}
}
diff --git a/samples/Physics/PhysicsSample/PhysicsSample.Game/CharacterScript.cs b/samples/Physics/PhysicsSample/PhysicsSample.Game/CharacterScript.cs
index fee001ad2d..b9b6a97db8 100644
--- a/samples/Physics/PhysicsSample/PhysicsSample.Game/CharacterScript.cs
+++ b/samples/Physics/PhysicsSample/PhysicsSample.Game/CharacterScript.cs
@@ -1,224 +1,222 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
-using System;
-using System.Linq;
+
+using Stride.Animations;
using Stride.Core;
using Stride.Core.Mathematics;
-using Stride.Animations;
using Stride.Engine;
using Stride.Input;
using Stride.Physics;
using Stride.Rendering.Sprites;
-namespace PhysicsSample
+namespace PhysicsSample;
+
+///
+/// This script will interface the Physics character controller of the entity to move the character around
+/// Will also animate the sprite of the entity, between run and idle.
+///
+public class CharacterScript : SyncScript
{
- ///
- /// This script will interface the Physics character controller of the entity to move the character around
- /// Will also animate the sprite of the entity, between run and idle.
- ///
- public class CharacterScript : SyncScript
+ [Flags]
+ enum PlayerState
{
- [Flags]
- enum PlayerState
- {
- Idle = 0x0,
- Run = 0x1,
- Jump = 0x2
- }
+ Idle = 0x0,
+ Run = 0x1,
+ Jump = 0x2
+ }
- private const float speed = 0.075f;
+ private const float speed = 0.075f;
- private CharacterComponent playerController;
- private SpriteComponent playerSprite;
+ private CharacterComponent playerController;
+ private SpriteComponent playerSprite;
- [DataMember(Mask = LiveScriptingMask)] // keep the value when reloading the script (live-scripting)
- private bool movingToTarget;
+ [DataMember(Mask = LiveScriptingMask)] // keep the value when reloading the script (live-scripting)
+ private bool movingToTarget;
- [DataMember(Mask = LiveScriptingMask)] // keep the value when reloading the script (live-scripting)
- private PlayerState oldState = PlayerState.Idle;
+ [DataMember(Mask = LiveScriptingMask)] // keep the value when reloading the script (live-scripting)
+ private PlayerState oldState = PlayerState.Idle;
- [DataMember(Mask = LiveScriptingMask)] // keep the value when reloading the script (live-scripting)
- private Vector3 oldDirection = Vector3.Zero;
+ [DataMember(Mask = LiveScriptingMask)] // keep the value when reloading the script (live-scripting)
+ private Vector3 oldDirection = Vector3.Zero;
- [DataMember(Mask = LiveScriptingMask)] // keep the value when reloading the script (live-scripting)
- private Vector3 autoPilotTarget = Vector3.Zero;
+ [DataMember(Mask = LiveScriptingMask)] // keep the value when reloading the script (live-scripting)
+ private Vector3 autoPilotTarget = Vector3.Zero;
- void PlayIdle()
- {
- var sheet = ((SpriteFromSheet)playerSprite.SpriteProvider).Sheet;
- SpriteAnimation.Play(playerSprite, sheet.FindImageIndex("idle0"), sheet.FindImageIndex("idle4"), AnimationRepeatMode.LoopInfinite, 7);
- }
+ void PlayIdle()
+ {
+ var sheet = ((SpriteFromSheet)playerSprite.SpriteProvider).Sheet;
+ SpriteAnimation.Play(playerSprite, sheet.FindImageIndex("idle0"), sheet.FindImageIndex("idle4"), AnimationRepeatMode.LoopInfinite, 7);
+ }
- void PlayRun()
- {
- var sheet = ((SpriteFromSheet)playerSprite.SpriteProvider).Sheet;
- SpriteAnimation.Play(playerSprite, sheet.FindImageIndex("run0"), sheet.FindImageIndex("run4"), AnimationRepeatMode.LoopInfinite, 12);
- }
+ void PlayRun()
+ {
+ var sheet = ((SpriteFromSheet)playerSprite.SpriteProvider).Sheet;
+ SpriteAnimation.Play(playerSprite, sheet.FindImageIndex("run0"), sheet.FindImageIndex("run4"), AnimationRepeatMode.LoopInfinite, 12);
+ }
- public override void Start()
- {
- playerSprite = Entity.Get();
- playerController = Entity.Get();
+ public override void Start()
+ {
+ playerSprite = Entity.Get();
+ playerController = Entity.Get();
- //Please remember that in the GameStudio element the parameter Step Height is extremely important, it not set properly it will cause the entity to snap fast to the ground
- playerController.JumpSpeed = 5.0f;
- playerController.Gravity = new Vector3(0.0f, -10.0f, 0.0f);
- playerController.FallSpeed = 10.0f;
- playerController.ProcessCollisions = true;
+ //Please remember that in the GameStudio element the parameter Step Height is extremely important, it not set properly it will cause the entity to snap fast to the ground
+ playerController.JumpSpeed = 5.0f;
+ playerController.Gravity = new Vector3(0.0f, -10.0f, 0.0f);
+ playerController.FallSpeed = 10.0f;
+ playerController.ProcessCollisions = true;
- if (!IsLiveReloading)
+ if (!IsLiveReloading)
+ {
+ Script.AddTask(async () =>
{
- Script.AddTask(async () =>
+ while (Game.IsRunning)
{
- while (Game.IsRunning)
+ var collision = await playerController.NewCollision();
+ // Stop if we collide from side
+ foreach (var contact in collision.Contacts)
{
- var collision = await playerController.NewCollision();
- // Stop if we collide from side
- foreach (var contact in collision.Contacts)
+ if (contact.Normal.X is < -0.5f or > 0.5f)
{
- if (contact.Normal.X < -0.5f || contact.Normal.X > 0.5f)
- {
- movingToTarget = false;
- break;
- }
+ movingToTarget = false;
+ break;
}
}
- });
- PlayIdle();
- }
+ }
+ });
+ PlayIdle();
}
+ }
+
+ public override void Update()
+ {
+ var playerState = PlayerState.Idle;
+ var playerDirection = Vector3.Zero;
+
+ // -- Keyboard Inputs
- public override void Update()
+ // Space bar = jump
+ if (Input.IsKeyDown(Keys.Space))
{
- var playerState = PlayerState.Idle;
- var playerDirection = Vector3.Zero;
+ playerState |= PlayerState.Jump;
+ }
- // -- Keyboard Inputs
+ // Left - right = run
+ if (Input.IsKeyDown(Keys.Right))
+ {
+ movingToTarget = false;
+ playerState |= PlayerState.Run;
+ playerDirection = Vector3.UnitX * speed;
+ }
+ else if (Input.IsKeyDown(Keys.Left))
+ {
+ movingToTarget = false;
+ playerState |= PlayerState.Run;
+ playerDirection = -Vector3.UnitX * speed;
+ }
- // Space bar = jump
- if (Input.IsKeyDown(Keys.Space))
+ // -- Pointer (mouse/touch)
+ foreach (var pointerEvent in Input.PointerEvents.Where(pointerEvent => pointerEvent.EventType == PointerEventType.Pressed))
+ {
+ if (!movingToTarget)
{
- playerState |= PlayerState.Jump;
- }
+ var screenX = (pointerEvent.Position.X - 0.5f) * 2.0f;
+ screenX *= 8.75f;
- // Left - right = run
- if (Input.IsKeyDown(Keys.Right))
- {
- movingToTarget = false;
- playerState |= PlayerState.Run;
- playerDirection = Vector3.UnitX * speed;
+ autoPilotTarget = new Vector3(screenX, 0, 0);
+
+ movingToTarget = true;
}
- else if (Input.IsKeyDown(Keys.Left))
+ else
{
- movingToTarget = false;
- playerState |= PlayerState.Run;
- playerDirection = -Vector3.UnitX * speed;
+ playerState |= PlayerState.Jump;
}
+ }
- // -- Pointer (mouse/touch)
- foreach (var pointerEvent in Input.PointerEvents.Where(pointerEvent => pointerEvent.EventType == PointerEventType.Pressed))
- {
- if (!movingToTarget)
- {
- var screenX = (pointerEvent.Position.X - 0.5f) * 2.0f;
- screenX *= 8.75f;
-
- autoPilotTarget = new Vector3(screenX, 0, 0);
-
- movingToTarget = true;
- }
- else
- {
- playerState |= PlayerState.Jump;
- }
- }
+ // -- Logic
- // -- Logic
+ // are we autopiloting?
+ if (movingToTarget)
+ {
+ var direction = autoPilotTarget - Entity.Transform.Position;
+ direction.Y = 0;
- // are we autopiloting?
- if (movingToTarget)
+ //should we stop?
+ var length = direction.Length();
+ if (length < speed)
{
- var direction = autoPilotTarget - Entity.Transform.Position;
- direction.Y = 0;
-
- //should we stop?
- var length = direction.Length();
- if (length < speed)
- {
- movingToTarget = false;
+ movingToTarget = false;
- playerDirection = Vector3.Zero;
+ playerDirection = Vector3.Zero;
- playerState = PlayerState.Idle;
- }
- else
- {
- direction.Normalize();
+ playerState = PlayerState.Idle;
+ }
+ else
+ {
+ direction.Normalize();
- playerDirection = (direction.X > 0 ? Vector3.UnitX : -Vector3.UnitX) * speed;
+ playerDirection = (direction.X > 0 ? Vector3.UnitX : -Vector3.UnitX) * speed;
- playerState |= PlayerState.Run;
- }
+ playerState |= PlayerState.Run;
}
+ }
- // did we start jumping?
- if (playerState.HasFlag(PlayerState.Jump) && !oldState.HasFlag(PlayerState.Jump))
- {
- playerController.Jump();
- }
+ // did we start jumping?
+ if (playerState.HasFlag(PlayerState.Jump) && !oldState.HasFlag(PlayerState.Jump))
+ {
+ playerController.Jump();
+ }
- // did we just land?
- if (oldState.HasFlag(PlayerState.Jump))
+ // did we just land?
+ if (oldState.HasFlag(PlayerState.Jump))
+ {
+ if (!playerController.IsGrounded)
{
- if (!playerController.IsGrounded)
+ //force set jump flag
+ if (!playerState.HasFlag(PlayerState.Jump))
{
- //force set jump flag
- if (!playerState.HasFlag(PlayerState.Jump))
- {
- playerState |= PlayerState.Jump;
- // Mantain motion
- playerDirection = oldDirection;
- }
+ playerState |= PlayerState.Jump;
+ // Mantain motion
+ playerDirection = oldDirection;
}
- else if (playerController.IsGrounded)
+ }
+ else if (playerController.IsGrounded)
+ {
+ //force clear jump flag
+ if (playerState.HasFlag(PlayerState.Jump))
{
- //force clear jump flag
- if (playerState.HasFlag(PlayerState.Jump))
- {
- playerState ^= PlayerState.Jump;
- }
+ playerState ^= PlayerState.Jump;
}
}
+ }
- // did we start running?
- if (playerState.HasFlag(PlayerState.Run) && !oldState.HasFlag(PlayerState.Run))
- {
- PlayRun();
- }
- // did we stop running?
- else if (!playerState.HasFlag(PlayerState.Run) && oldState.HasFlag(PlayerState.Run))
- {
- PlayIdle();
- }
+ // did we start running?
+ if (playerState.HasFlag(PlayerState.Run) && !oldState.HasFlag(PlayerState.Run))
+ {
+ PlayRun();
+ }
+ // did we stop running?
+ else if (!playerState.HasFlag(PlayerState.Run) && oldState.HasFlag(PlayerState.Run))
+ {
+ PlayIdle();
+ }
- // movement logic
- if (oldDirection != playerDirection)
- {
- playerController.Move(playerDirection);
+ // movement logic
+ if (oldDirection != playerDirection)
+ {
+ playerController.Move(playerDirection);
- if (playerState.HasFlag(PlayerState.Run))
+ if (playerState.HasFlag(PlayerState.Run))
+ {
+ if ((playerDirection.X > 0 && Entity.Transform.Scale.X < 0) ||
+ (playerDirection.X < 0 && Entity.Transform.Scale.X > 0))
{
- if ((playerDirection.X > 0 && Entity.Transform.Scale.X < 0) ||
- (playerDirection.X < 0 && Entity.Transform.Scale.X > 0))
- {
- Entity.Transform.Scale.X *= -1.0f;
- }
+ Entity.Transform.Scale.X *= -1.0f;
}
}
-
- // Store current state for next frame
- oldState = playerState;
- oldDirection = playerDirection;
}
+
+ // Store current state for next frame
+ oldState = playerState;
+ oldDirection = playerDirection;
}
}
diff --git a/samples/Physics/PhysicsSample/PhysicsSample.Game/DemoScript.cs b/samples/Physics/PhysicsSample/PhysicsSample.Game/DemoScript.cs
index 7fd91850b9..f891b7f12a 100644
--- a/samples/Physics/PhysicsSample/PhysicsSample.Game/DemoScript.cs
+++ b/samples/Physics/PhysicsSample/PhysicsSample.Game/DemoScript.cs
@@ -1,7 +1,6 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
-using System;
-using System.Collections.Generic;
+
using Stride.Core.Mathematics;
using Stride.Engine;
using Stride.Graphics;
@@ -9,257 +8,255 @@
using Stride.UI;
using Stride.UI.Controls;
using Stride.UI.Panels;
-using System.Threading.Tasks;
-namespace PhysicsSample12
+namespace PhysicsSample12;
+
+public class DemoScript : StartupScript
{
- public class DemoScript : StartupScript
- {
- private Simulation simulation;
+ private Simulation simulation;
- public Entity cube;
- public Entity sphere;
+ public Entity cube;
+ public Entity sphere;
- public SpriteFont Font;
+ public SpriteFont Font;
- private Constraint currentConstraint;
- private readonly List PhysicsSampleList = new List();
- private int constraintIndex;
+ private Constraint currentConstraint;
+ private readonly List PhysicsSampleList = [];
+ private int constraintIndex;
- private RigidbodyComponent cubeRigidBody;
- private RigidbodyComponent sphereRigidBody;
+ private RigidbodyComponent cubeRigidBody;
+ private RigidbodyComponent sphereRigidBody;
- private TextBlock constraintNameBlock;
+ private TextBlock constraintNameBlock;
- public override void Start()
- {
- simulation = this.GetSimulation();
- simulation.Gravity = new Vector3(0, -9, 0);
+ public override void Start()
+ {
+ simulation = this.GetSimulation();
+ simulation.Gravity = new Vector3(0, -9, 0);
- cubeRigidBody = cube.Get();
- cubeRigidBody.CanSleep = false;
- sphereRigidBody = sphere.Get();
- sphereRigidBody.CanSleep = false;
+ cubeRigidBody = cube.Get();
+ cubeRigidBody.CanSleep = false;
+ sphereRigidBody = sphere.Get();
+ sphereRigidBody.CanSleep = false;
- // Create the UI
- constraintNameBlock = new TextBlock
- {
- Font = Font,
- TextSize = 55,
- TextColor = Color.White,
- };
- constraintNameBlock.SetCanvasPinOrigin(new Vector3(0.5f, 0.5f, 0));
- constraintNameBlock.SetCanvasRelativePosition(new Vector3(0.5f, 0.83f, 0));
-
- Entity.Get().Page = new UIPage
+ // Create the UI
+ constraintNameBlock = new TextBlock
+ {
+ Font = Font,
+ TextSize = 55,
+ TextColor = Color.White,
+ };
+ constraintNameBlock.SetCanvasPinOrigin(new Vector3(0.5f, 0.5f, 0));
+ constraintNameBlock.SetCanvasRelativePosition(new Vector3(0.5f, 0.83f, 0));
+
+ Entity.Get().Page = new UIPage
+ {
+ RootElement = new Canvas
{
- RootElement = new Canvas
+ Children =
{
- Children =
- {
- constraintNameBlock,
- CreateButton("Next", Font, 1),
- CreateButton("Previous", Font, -1)
- }
+ constraintNameBlock,
+ CreateButton("Next", Font, 1),
+ CreateButton("Previous", Font, -1)
}
- };
-
- // Create and initialize constraint
- PhysicsSampleList.Add(CreatePoint2PointConstraint);
- PhysicsSampleList.Add(CreateHingeConstraint);
- PhysicsSampleList.Add(CreateGearConstraint);
- PhysicsSampleList.Add(CreateSliderConstraint);
- PhysicsSampleList.Add(CreateConeTwistConstraint);
- PhysicsSampleList.Add(CreateGeneric6DoFConstraint);
-
- RemoveConstraint();
- PhysicsSampleList[constraintIndex]();
-
- //Add a script for the slider constraint, to apply an impulse on collision
- cubeRigidBody.ProcessCollisions = true;
- Script.AddTask(async () =>
+ }
+ };
+
+ // Create and initialize constraint
+ PhysicsSampleList.Add(CreatePoint2PointConstraint);
+ PhysicsSampleList.Add(CreateHingeConstraint);
+ PhysicsSampleList.Add(CreateGearConstraint);
+ PhysicsSampleList.Add(CreateSliderConstraint);
+ PhysicsSampleList.Add(CreateConeTwistConstraint);
+ PhysicsSampleList.Add(CreateGeneric6DoFConstraint);
+
+ RemoveConstraint();
+ PhysicsSampleList[constraintIndex]();
+
+ //Add a script for the slider constraint, to apply an impulse on collision
+ cubeRigidBody.ProcessCollisions = true;
+ Script.AddTask(async () =>
+ {
+ while (Game.IsRunning)
{
- while (Game.IsRunning)
- {
- var collision = await cubeRigidBody.NewCollision();
- if (!(currentConstraint is SliderConstraint)) continue;
- if (collision.ColliderA != sphereRigidBody && collision.ColliderB != sphereRigidBody) continue;
- sphereRigidBody.LinearVelocity = Vector3.Zero; //clear any existing velocity
- sphereRigidBody.ApplyImpulse(new Vector3(-25, 0, 0)); //fire impulse
- }
- });
- }
+ var collision = await cubeRigidBody.NewCollision();
+ if (currentConstraint is not SliderConstraint) continue;
+ if (collision.ColliderA != sphereRigidBody && collision.ColliderB != sphereRigidBody) continue;
+ sphereRigidBody.LinearVelocity = Vector3.Zero; //clear any existing velocity
+ sphereRigidBody.ApplyImpulse(new Vector3(-25, 0, 0)); //fire impulse
+ }
+ });
+ }
- void CreatePoint2PointConstraint()
- {
- cubeRigidBody.LinearFactor = Vector3.Zero;
- cubeRigidBody.AngularFactor = Vector3.Zero;
- sphereRigidBody.LinearFactor = new Vector3(1, 1, 1);
- sphereRigidBody.AngularFactor = new Vector3(1, 1, 1);
-
- currentConstraint = Simulation.CreateConstraint(ConstraintTypes.Point2Point, cubeRigidBody, sphereRigidBody,
- Matrix.Identity, Matrix.Translation(new Vector3(4, 0, 0)));
- simulation.AddConstraint(currentConstraint);
- constraintNameBlock.Text = "Point to Point";
-
- //there are no limits so the sphere will orbit once we apply this
- sphereRigidBody.ApplyImpulse(new Vector3(0, 0, 18));
- }
+ void CreatePoint2PointConstraint()
+ {
+ cubeRigidBody.LinearFactor = Vector3.Zero;
+ cubeRigidBody.AngularFactor = Vector3.Zero;
+ sphereRigidBody.LinearFactor = new Vector3(1, 1, 1);
+ sphereRigidBody.AngularFactor = new Vector3(1, 1, 1);
+
+ currentConstraint = Simulation.CreateConstraint(ConstraintTypes.Point2Point, cubeRigidBody, sphereRigidBody,
+ Matrix.Identity, Matrix.Translation(new Vector3(4, 0, 0)));
+ simulation.AddConstraint(currentConstraint);
+ constraintNameBlock.Text = "Point to Point";
+
+ //there are no limits so the sphere will orbit once we apply this
+ sphereRigidBody.ApplyImpulse(new Vector3(0, 0, 18));
+ }
- void CreateHingeConstraint()
- {
- cubeRigidBody.LinearFactor = Vector3.Zero;
- cubeRigidBody.AngularFactor = Vector3.Zero;
- sphereRigidBody.LinearFactor = new Vector3(1, 1, 1);
- sphereRigidBody.AngularFactor = new Vector3(1, 1, 1);
-
- currentConstraint = Simulation.CreateConstraint(ConstraintTypes.Hinge, cubeRigidBody, sphereRigidBody,
- Matrix.Identity, Matrix.Translation(new Vector3(4, 0, 0)));
- simulation.AddConstraint(currentConstraint);
- constraintNameBlock.Text = "Hinge";
-
- //applying this impulse will show the hinge limits stopping it
- sphereRigidBody.ApplyImpulse(new Vector3(0, 0, 18));
- }
+ void CreateHingeConstraint()
+ {
+ cubeRigidBody.LinearFactor = Vector3.Zero;
+ cubeRigidBody.AngularFactor = Vector3.Zero;
+ sphereRigidBody.LinearFactor = new Vector3(1, 1, 1);
+ sphereRigidBody.AngularFactor = new Vector3(1, 1, 1);
+
+ currentConstraint = Simulation.CreateConstraint(ConstraintTypes.Hinge, cubeRigidBody, sphereRigidBody,
+ Matrix.Identity, Matrix.Translation(new Vector3(4, 0, 0)));
+ simulation.AddConstraint(currentConstraint);
+ constraintNameBlock.Text = "Hinge";
+
+ //applying this impulse will show the hinge limits stopping it
+ sphereRigidBody.ApplyImpulse(new Vector3(0, 0, 18));
+ }
- void CreateGearConstraint()
- {
- cubeRigidBody.LinearFactor = Vector3.Zero;
- cubeRigidBody.AngularFactor = new Vector3(1, 1, 1);
- sphereRigidBody.LinearFactor = Vector3.Zero;
- sphereRigidBody.AngularFactor = new Vector3(1, 1, 1);
+ void CreateGearConstraint()
+ {
+ cubeRigidBody.LinearFactor = Vector3.Zero;
+ cubeRigidBody.AngularFactor = new Vector3(1, 1, 1);
+ sphereRigidBody.LinearFactor = Vector3.Zero;
+ sphereRigidBody.AngularFactor = new Vector3(1, 1, 1);
- currentConstraint = Simulation.CreateConstraint(ConstraintTypes.Gear, sphereRigidBody, cubeRigidBody,
- Matrix.Translation(new Vector3(1, 0, 0)), Matrix.Translation(new Vector3(1, 0, 0)));
- simulation.AddConstraint(currentConstraint);
- constraintNameBlock.Text = "Gear";
+ currentConstraint = Simulation.CreateConstraint(ConstraintTypes.Gear, sphereRigidBody, cubeRigidBody,
+ Matrix.Translation(new Vector3(1, 0, 0)), Matrix.Translation(new Vector3(1, 0, 0)));
+ simulation.AddConstraint(currentConstraint);
+ constraintNameBlock.Text = "Gear";
- var gear = (GearConstraint)currentConstraint;
- gear.Ratio = 0.5f;
+ var gear = (GearConstraint)currentConstraint;
+ gear.Ratio = 0.5f;
- //this force will start a motion in the sphere which gets propagated into the cube
- sphereRigidBody.AngularVelocity = new Vector3(25, 0, 0);
- }
+ //this force will start a motion in the sphere which gets propagated into the cube
+ sphereRigidBody.AngularVelocity = new Vector3(25, 0, 0);
+ }
- void CreateSliderConstraint()
- {
- cubeRigidBody.LinearFactor = Vector3.Zero;
- cubeRigidBody.AngularFactor = Vector3.Zero;
- sphereRigidBody.LinearFactor = new Vector3(1, 1, 1);
- sphereRigidBody.AngularFactor = new Vector3(1, 1, 1);
-
- currentConstraint = Simulation.CreateConstraint(ConstraintTypes.Slider, cubeRigidBody, sphereRigidBody, Matrix.Identity, Matrix.Identity, true);
- simulation.AddConstraint(currentConstraint);
- constraintNameBlock.Text = "Slider";
-
- var slider = (SliderConstraint)currentConstraint;
- slider.LowerLinearLimit = -4;
- slider.UpperLinearLimit = 0;
- //avoid strange movements
- slider.LowerAngularLimit = (float)-Math.PI / 3.0f;
- slider.UpperAngularLimit = (float)Math.PI / 3.0f;
-
- //applying this impulse will let the sphere reach the lower linear limit and afterwards will be dragged back towards the cube
- sphereRigidBody.ApplyImpulse(new Vector3(-25, 0, 0));
- }
+ void CreateSliderConstraint()
+ {
+ cubeRigidBody.LinearFactor = Vector3.Zero;
+ cubeRigidBody.AngularFactor = Vector3.Zero;
+ sphereRigidBody.LinearFactor = new Vector3(1, 1, 1);
+ sphereRigidBody.AngularFactor = new Vector3(1, 1, 1);
+
+ currentConstraint = Simulation.CreateConstraint(ConstraintTypes.Slider, cubeRigidBody, sphereRigidBody, Matrix.Identity, Matrix.Identity, true);
+ simulation.AddConstraint(currentConstraint);
+ constraintNameBlock.Text = "Slider";
+
+ var slider = (SliderConstraint)currentConstraint;
+ slider.LowerLinearLimit = -4;
+ slider.UpperLinearLimit = 0;
+ //avoid strange movements
+ slider.LowerAngularLimit = (float)-Math.PI / 3.0f;
+ slider.UpperAngularLimit = (float)Math.PI / 3.0f;
+
+ //applying this impulse will let the sphere reach the lower linear limit and afterwards will be dragged back towards the cube
+ sphereRigidBody.ApplyImpulse(new Vector3(-25, 0, 0));
+ }
- void CreateConeTwistConstraint()
- {
- cubeRigidBody.LinearFactor = Vector3.Zero;
- cubeRigidBody.AngularFactor = Vector3.Zero;
- sphereRigidBody.LinearFactor = new Vector3(1, 1, 1);
- sphereRigidBody.AngularFactor = new Vector3(1, 1, 1);
+ void CreateConeTwistConstraint()
+ {
+ cubeRigidBody.LinearFactor = Vector3.Zero;
+ cubeRigidBody.AngularFactor = Vector3.Zero;
+ sphereRigidBody.LinearFactor = new Vector3(1, 1, 1);
+ sphereRigidBody.AngularFactor = new Vector3(1, 1, 1);
- currentConstraint = Simulation.CreateConstraint(ConstraintTypes.ConeTwist, cubeRigidBody, sphereRigidBody,
- Matrix.Identity, Matrix.Translation(new Vector3(4, 0, 0)));
- simulation.AddConstraint(currentConstraint);
- constraintNameBlock.Text = "Cone Twist";
+ currentConstraint = Simulation.CreateConstraint(ConstraintTypes.ConeTwist, cubeRigidBody, sphereRigidBody,
+ Matrix.Identity, Matrix.Translation(new Vector3(4, 0, 0)));
+ simulation.AddConstraint(currentConstraint);
+ constraintNameBlock.Text = "Cone Twist";
- var coneTwist = (ConeTwistConstraint)currentConstraint;
- coneTwist.SetLimit(0.5f, 0.5f, 0.5f);
+ var coneTwist = (ConeTwistConstraint)currentConstraint;
+ coneTwist.SetLimit(0.5f, 0.5f, 0.5f);
- //applying this impulse will show the cone limits
- sphereRigidBody.ApplyImpulse(new Vector3(0, 0, 18));
- }
+ //applying this impulse will show the cone limits
+ sphereRigidBody.ApplyImpulse(new Vector3(0, 0, 18));
+ }
- void CreateGeneric6DoFConstraint()
- {
- cubeRigidBody.LinearFactor = Vector3.Zero;
- cubeRigidBody.AngularFactor = Vector3.Zero;
- sphereRigidBody.LinearFactor = new Vector3(1, 1, 1);
- sphereRigidBody.AngularFactor = new Vector3(1, 1, 1);
+ void CreateGeneric6DoFConstraint()
+ {
+ cubeRigidBody.LinearFactor = Vector3.Zero;
+ cubeRigidBody.AngularFactor = Vector3.Zero;
+ sphereRigidBody.LinearFactor = new Vector3(1, 1, 1);
+ sphereRigidBody.AngularFactor = new Vector3(1, 1, 1);
- currentConstraint = Simulation.CreateConstraint(ConstraintTypes.Generic6DoF, cubeRigidBody, sphereRigidBody,
- Matrix.Identity, Matrix.Translation(new Vector3(4, 0, 0)));
- simulation.AddConstraint(currentConstraint);
- constraintNameBlock.Text = "Generic 6D of Freedom";
+ currentConstraint = Simulation.CreateConstraint(ConstraintTypes.Generic6DoF, cubeRigidBody, sphereRigidBody,
+ Matrix.Identity, Matrix.Translation(new Vector3(4, 0, 0)));
+ simulation.AddConstraint(currentConstraint);
+ constraintNameBlock.Text = "Generic 6D of Freedom";
- sphereRigidBody.ApplyImpulse(new Vector3(0, 0, 18));
- }
+ sphereRigidBody.ApplyImpulse(new Vector3(0, 0, 18));
+ }
- private void RemoveConstraint()
+ private void RemoveConstraint()
+ {
+ //Remove and dispose the current constraint
+ if (currentConstraint != null)
{
- //Remove and dispose the current constraint
- if (currentConstraint != null)
- {
- simulation.RemoveConstraint(currentConstraint);
- currentConstraint.Dispose();
+ simulation.RemoveConstraint(currentConstraint);
+ currentConstraint.Dispose();
currentConstraint = null;
- }
+ }
- //Stop motion and reset the rigid bodies
- cubeRigidBody.PhysicsWorldTransform = Matrix.Translation(new Vector3(2, 0, -9)) *
- Matrix.RotationQuaternion(new Quaternion(0, 0, 0, 1));
+ //Stop motion and reset the rigid bodies
+ cubeRigidBody.PhysicsWorldTransform = Matrix.Translation(new Vector3(2, 0, -9)) *
+ Matrix.RotationQuaternion(new Quaternion(0, 0, 0, 1));
- cubeRigidBody.AngularVelocity = Vector3.Zero;
- cubeRigidBody.LinearVelocity = Vector3.Zero;
+ cubeRigidBody.AngularVelocity = Vector3.Zero;
+ cubeRigidBody.LinearVelocity = Vector3.Zero;
- sphereRigidBody.PhysicsWorldTransform = Matrix.Translation(new Vector3(-2, 0, -9)) *
- Matrix.RotationQuaternion(new Quaternion(0, 0, 0, 1));
+ sphereRigidBody.PhysicsWorldTransform = Matrix.Translation(new Vector3(-2, 0, -9)) *
+ Matrix.RotationQuaternion(new Quaternion(0, 0, 0, 1));
- sphereRigidBody.AngularVelocity = Vector3.Zero;
- sphereRigidBody.LinearVelocity = Vector3.Zero;
- }
+ sphereRigidBody.AngularVelocity = Vector3.Zero;
+ sphereRigidBody.LinearVelocity = Vector3.Zero;
+ }
- private void ChangeConstraint(int offset)
- {
- RemoveConstraint();
+ private void ChangeConstraint(int offset)
+ {
+ RemoveConstraint();
- // calculate constraint index
- constraintIndex = (constraintIndex + offset + PhysicsSampleList.Count) % PhysicsSampleList.Count;
+ // calculate constraint index
+ constraintIndex = (constraintIndex + offset + PhysicsSampleList.Count) % PhysicsSampleList.Count;
- PhysicsSampleList[constraintIndex]();
- }
+ PhysicsSampleList[constraintIndex]();
+ }
- private Button CreateButton(string text, SpriteFont font, int offset)
+ private Button CreateButton(string text, SpriteFont font, int offset)
+ {
+ var button = new Button
{
- var button = new Button
- {
- Name = text,
- Padding = Thickness.UniformRectangle(15),
- HorizontalAlignment = HorizontalAlignment.Left,
- Content = new TextBlock { Text = text, Font = font, TextSize = 35, TextColor = new Color(200, 200, 200, 255) },
- BackgroundColor = new Color(new Vector4(0.2f, 0.2f, 0.2f, 0.2f)),
- };
-
- button.Click += (sender, args) =>
+ Name = text,
+ Padding = Thickness.UniformRectangle(15),
+ HorizontalAlignment = HorizontalAlignment.Left,
+ Content = new TextBlock { Text = text, Font = font, TextSize = 35, TextColor = new Color(200, 200, 200, 255) },
+ BackgroundColor = new Color(new Vector4(0.2f, 0.2f, 0.2f, 0.2f)),
+ };
+
+ button.Click += (sender, args) =>
+ {
+ Script.AddTask(() =>
{
- Script.AddTask(() =>
- {
- ChangeConstraint(offset);
- return Task.CompletedTask;
- });
- };
+ ChangeConstraint(offset);
+ return Task.CompletedTask;
+ });
+ };
- button.SetCanvasPinOrigin(new Vector3(offset > 0 ? 1 : 0, 0.5f, 0));
- button.SetCanvasRelativePosition(new Vector3(offset > 0 ? 0.87f : 0.13f, 0.93f, 0));
+ button.SetCanvasPinOrigin(new Vector3(offset > 0 ? 1 : 0, 0.5f, 0));
+ button.SetCanvasRelativePosition(new Vector3(offset > 0 ? 0.87f : 0.13f, 0.93f, 0));
- return button;
- }
+ return button;
+ }
- public override void Cancel()
- {
- RemoveConstraint();
- }
+ public override void Cancel()
+ {
+ RemoveConstraint();
}
}
diff --git a/samples/Physics/PhysicsSample/PhysicsSample.Game/EnemyScript.cs b/samples/Physics/PhysicsSample/PhysicsSample.Game/EnemyScript.cs
index 13a0e68823..188a530ffd 100644
--- a/samples/Physics/PhysicsSample/PhysicsSample.Game/EnemyScript.cs
+++ b/samples/Physics/PhysicsSample/PhysicsSample.Game/EnemyScript.cs
@@ -1,21 +1,21 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
+
using Stride.Animations;
using Stride.Engine;
using Stride.Rendering.Sprites;
-namespace PhysicsSample
+namespace PhysicsSample;
+
+///
+/// This simple script will start the sprite idle animation
+///
+public class EnemyScript : StartupScript
{
- ///
- /// This simple script will start the sprite idle animation
- ///
- public class EnemyScript : StartupScript
+ public override void Start()
{
- public override void Start()
- {
- var spriteComponent = Entity.Get();
- var sheet = ((SpriteFromSheet)spriteComponent.SpriteProvider).Sheet;
- SpriteAnimation.Play(spriteComponent, sheet.FindImageIndex("active0"), sheet.FindImageIndex("active1"), AnimationRepeatMode.LoopInfinite, 2);
- }
+ var spriteComponent = Entity.Get();
+ var sheet = ((SpriteFromSheet)spriteComponent.SpriteProvider).Sheet;
+ SpriteAnimation.Play(spriteComponent, sheet.FindImageIndex("active0"), sheet.FindImageIndex("active1"), AnimationRepeatMode.LoopInfinite, 2);
}
}
diff --git a/samples/Physics/PhysicsSample/PhysicsSample.Game/GuiScript.cs b/samples/Physics/PhysicsSample/PhysicsSample.Game/GuiScript.cs
index f32d97fe46..23803d8ec9 100644
--- a/samples/Physics/PhysicsSample/PhysicsSample.Game/GuiScript.cs
+++ b/samples/Physics/PhysicsSample/PhysicsSample.Game/GuiScript.cs
@@ -1,5 +1,6 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// 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.Graphics;
@@ -7,30 +8,29 @@
using Stride.UI.Controls;
using Stride.UI.Panels;
-namespace PhysicsSample
+namespace PhysicsSample;
+
+///
+/// The script in charge of displaying the UI
+///
+public class GuiScript : StartupScript
{
- ///
- /// The script in charge of displaying the UI
- ///
- public class GuiScript : StartupScript
+ public SpriteFont Font;
+
+ public override void Start()
{
- public SpriteFont Font;
+ base.Start();
- public override void Start()
+ var textBlock = new TextBlock
{
- base.Start();
-
- var textBlock = new TextBlock
- {
- Text = "Shoot the cubes!",
- Font = Font,
- TextColor = Color.White,
- TextSize = 60
- };
- textBlock.SetCanvasPinOrigin(new Vector3(0.5f, 0.5f, 0));
- textBlock.SetCanvasRelativePosition(new Vector3(0.5f, 0.9f, 0f));
+ Text = "Shoot the cubes!",
+ Font = Font,
+ TextColor = Color.White,
+ TextSize = 60
+ };
+ textBlock.SetCanvasPinOrigin(new Vector3(0.5f, 0.5f, 0));
+ textBlock.SetCanvasRelativePosition(new Vector3(0.5f, 0.9f, 0f));
- Entity.Get().Page = new UIPage { RootElement = new Canvas { Children = { textBlock } } };
- }
+ Entity.Get().Page = new UIPage { RootElement = new Canvas { Children = { textBlock } } };
}
}
diff --git a/samples/Physics/PhysicsSample/PhysicsSample.Game/ImpulseOnSpaceScript.cs b/samples/Physics/PhysicsSample/PhysicsSample.Game/ImpulseOnSpaceScript.cs
index a8fd513e81..51a5716756 100644
--- a/samples/Physics/PhysicsSample/PhysicsSample.Game/ImpulseOnSpaceScript.cs
+++ b/samples/Physics/PhysicsSample/PhysicsSample.Game/ImpulseOnSpaceScript.cs
@@ -1,26 +1,26 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
+
using Stride.Core.Mathematics;
-using Stride.Input;
using Stride.Engine;
+using Stride.Input;
using Stride.Physics;
-namespace PhysicsSample
+namespace PhysicsSample;
+
+///
+/// Apply an impulse on the entity when pressing key 'Space'
+///
+public class ImpulseOnSpaceScript : SyncScript
{
- ///
- /// Apply an impulse on the entity when pressing key 'Space'
- ///
- public class ImpulseOnSpaceScript : SyncScript
+ public override void Update()
{
- public override void Update()
+ if (Input.IsKeyDown(Keys.Space))
{
- if (Input.IsKeyDown(Keys.Space))
- {
- var rigidBody = Entity.Get();
+ var rigidBody = Entity.Get();
- rigidBody.Activate();
- rigidBody.ApplyImpulse(new Vector3(0, 1, 0));
- }
+ rigidBody.Activate();
+ rigidBody.ApplyImpulse(new Vector3(0, 1, 0));
}
}
}
diff --git a/samples/Physics/PhysicsSample/PhysicsSample.Game/NextSceneScript.cs b/samples/Physics/PhysicsSample/PhysicsSample.Game/NextSceneScript.cs
index 19cb24f1c8..207130c0a2 100644
--- a/samples/Physics/PhysicsSample/PhysicsSample.Game/NextSceneScript.cs
+++ b/samples/Physics/PhysicsSample/PhysicsSample.Game/NextSceneScript.cs
@@ -1,5 +1,6 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// 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.Graphics;
@@ -7,78 +8,77 @@
using Stride.UI.Controls;
using Stride.UI.Panels;
-namespace PhysicsSample
+namespace PhysicsSample;
+
+public class NextSceneScript : SyncScript
{
- public class NextSceneScript : SyncScript
- {
- private Scene targetScene;
+ private Scene targetScene;
- public Scene NextScene;
+ public Scene NextScene;
- public Scene PreviousScene;
+ public Scene PreviousScene;
- public SpriteFont Font;
+ public SpriteFont Font;
- public override void Start()
- {
- SetupUI();
- }
+ public override void Start()
+ {
+ SetupUI();
+ }
- public override void Update()
+ public override void Update()
+ {
+ if (targetScene != null)
{
- if (targetScene != null)
- {
- SceneSystem.SceneInstance.RootScene = targetScene;
- targetScene = null;
- }
+ SceneSystem.SceneInstance.RootScene = targetScene;
+ targetScene = null;
}
+ }
- private void SetupUI()
- {
- var uiComponent = Entity.Get();
- if (uiComponent == null)
- return;
+ private void SetupUI()
+ {
+ var uiComponent = Entity.Get();
+ if (uiComponent == null)
+ return;
- // Create the UI
- Entity.Get().Page = new UIPage
+ // Create the UI
+ Entity.Get().Page = new UIPage
+ {
+ RootElement = new Grid
{
- RootElement = new Grid
+ Children =
+ {
+ CreateButton("<<", 72, 0, PreviousScene),
+ CreateButton(">>", 72, 2, NextScene)
+ },
+
+ ColumnDefinitions =
{
- Children =
- {
- CreateButton("<<", 72, 0, PreviousScene),
- CreateButton(">>", 72, 2, NextScene)
- },
-
- ColumnDefinitions =
- {
- new StripDefinition(StripType.Auto, 10),
- new StripDefinition(StripType.Star, 80),
- new StripDefinition(StripType.Auto, 10),
-
- }
+ new StripDefinition(StripType.Auto, 10),
+ new StripDefinition(StripType.Star, 80),
+ new StripDefinition(StripType.Auto, 10),
+
}
- };
- }
+ }
+ };
+ }
- private Button CreateButton(string text, int textSize, int columnId, Scene newTargetScene)
+ private Button CreateButton(string text, int textSize, int columnId, Scene newTargetScene)
+ {
+ var button = new Button
{
- var button = new Button
- {
- Name = text,
- HorizontalAlignment = HorizontalAlignment.Center,
- Content = new TextBlock { Text = text, Font = Font, TextSize = textSize, TextColor = new Color(200, 200, 200, 255), VerticalAlignment = VerticalAlignment.Center },
- BackgroundColor = new Color(new Vector4(0.2f, 0.2f, 0.2f, 0.2f)),
- };
+ Name = text,
+ HorizontalAlignment = HorizontalAlignment.Center,
+ Content = new TextBlock { Text = text, Font = Font, TextSize = textSize, TextColor = new Color(200, 200, 200, 255), VerticalAlignment = VerticalAlignment.Center },
+ BackgroundColor = new Color(new Vector4(0.2f, 0.2f, 0.2f, 0.2f)),
+ };
- button.SetGridColumn(columnId);
+ button.SetGridColumn(columnId);
- button.Click += (sender, args) =>
- {
- targetScene = newTargetScene;
- };
+ button.Click += (sender, args) =>
+ {
+ targetScene = newTargetScene;
+ };
- return button;
- }
+ return button;
}
}
diff --git a/samples/Physics/PhysicsSample/PhysicsSample.Game/PhysicsSample.Game.csproj b/samples/Physics/PhysicsSample/PhysicsSample.Game/PhysicsSample.Game.csproj
index dde154743a..aed4b3a858 100644
--- a/samples/Physics/PhysicsSample/PhysicsSample.Game/PhysicsSample.Game.csproj
+++ b/samples/Physics/PhysicsSample/PhysicsSample.Game/PhysicsSample.Game.csproj
@@ -2,6 +2,8 @@
net8.0
PhysicsSample
+ enable
+ latest
diff --git a/samples/Physics/PhysicsSample/PhysicsSample.Game/Player.cs b/samples/Physics/PhysicsSample/PhysicsSample.Game/Player.cs
index 670276dbe7..7af100d6a5 100644
--- a/samples/Physics/PhysicsSample/PhysicsSample.Game/Player.cs
+++ b/samples/Physics/PhysicsSample/PhysicsSample.Game/Player.cs
@@ -1,73 +1,72 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
-using System.Linq;
+
using Stride.Core.Mathematics;
using Stride.Engine;
using Stride.Input;
using Stride.Physics;
-namespace PhysicsSample
+namespace PhysicsSample;
+
+public class Player : SyncScript
{
- public class Player : SyncScript
- {
- private const float speed = 0.25f;
- private CharacterComponent character;
+ private const float speed = 0.25f;
+ private CharacterComponent character;
- public override void Start()
+ public override void Start()
+ {
+ character = Entity.Get();
+ character.Gravity = new Vector3(0.0f, -10.0f, 0.0f);
+ var rigidBodyComponent = Entity.Get();
+ if (rigidBodyComponent != null)
{
- character = Entity.Get();
- character.Gravity = new Vector3(0.0f, -10.0f, 0.0f);
- var rigidBodyComponent = Entity.Get();
- if (rigidBodyComponent != null)
- {
- rigidBodyComponent.CanSleep = false;
- }
+ rigidBodyComponent.CanSleep = false;
}
+ }
+
+ private Vector3 pointerVector;
- private Vector3 pointerVector;
+ public override void Update()
+ {
+ var move = new Vector3();
- public override void Update()
+ if (Input.IsKeyDown(Keys.A) || Input.IsKeyDown(Keys.Left))
+ {
+ move = -Vector3.UnitX;
+ }
+ if (Input.IsKeyDown(Keys.D) || Input.IsKeyDown(Keys.Right))
{
- var move = new Vector3();
+ move = Vector3.UnitX;
+ }
- if (Input.IsKeyDown(Keys.A) || Input.IsKeyDown(Keys.Left))
- {
- move = -Vector3.UnitX;
- }
- if (Input.IsKeyDown(Keys.D) || Input.IsKeyDown(Keys.Right))
+ foreach(var evt in Input.PointerEvents)
+ {
+ switch (evt.EventType)
{
- move = Vector3.UnitX;
- }
-
- foreach(var evt in Input.PointerEvents)
- {
- switch (evt.EventType)
- {
- case PointerEventType.Pressed:
- if (evt.Position.X < 0.5)
- {
- pointerVector = -Vector3.UnitX;
- }
- else
- {
- pointerVector = Vector3.UnitX;
- }
- break;
- case PointerEventType.Released:
- case PointerEventType.Canceled:
- pointerVector = Vector3.Zero;
- break;
- }
+ case PointerEventType.Pressed:
+ if (evt.Position.X < 0.5)
+ {
+ pointerVector = -Vector3.UnitX;
+ }
+ else
+ {
+ pointerVector = Vector3.UnitX;
+ }
+ break;
+ case PointerEventType.Released:
+ case PointerEventType.Canceled:
+ pointerVector = Vector3.Zero;
+ break;
}
+ }
- if (pointerVector != Vector3.Zero)
- {
- move = pointerVector;
- }
+ if (pointerVector != Vector3.Zero)
+ {
+ move = pointerVector;
+ }
- move *= speed;
+ move *= speed;
- character.Move(move);
- }
+ character.Move(move);
}
}
diff --git a/samples/Physics/PhysicsSample/PhysicsSample.Game/RaycastingScript.cs b/samples/Physics/PhysicsSample/PhysicsSample.Game/RaycastingScript.cs
index 97bf728b39..243bc3fb5c 100644
--- a/samples/Physics/PhysicsSample/PhysicsSample.Game/RaycastingScript.cs
+++ b/samples/Physics/PhysicsSample/PhysicsSample.Game/RaycastingScript.cs
@@ -1,63 +1,61 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
-using System.Linq;
+
using Stride.Core.Mathematics;
using Stride.Engine;
using Stride.Graphics;
using Stride.Input;
using Stride.Physics;
-namespace PhysicsSample
+namespace PhysicsSample;
+
+public class RaycastingScript : SyncScript
{
- public class RaycastingScript : SyncScript
+ private Simulation simulation;
+ private CameraComponent camera;
+
+ public override void Start()
{
- private Simulation simulation;
- private CameraComponent camera;
+ camera = Entity.Get();
+ simulation = this.GetSimulation();
+ }
- public override void Start()
+ public override void Update()
+ {
+ foreach (var pointerEvent in Input.PointerEvents.Where(x => x.EventType == PointerEventType.Pressed))
{
- camera = Entity.Get();
- simulation = this.GetSimulation();
+ Raycast(pointerEvent.Position);
}
+ }
- public override void Update()
- {
- foreach (var pointerEvent in Input.PointerEvents.Where(x => x.EventType == PointerEventType.Pressed))
- {
- Raycast(pointerEvent.Position);
- }
- }
+ private void Raycast(Vector2 screenPos)
+ {
+ var backBuffer = GraphicsDevice.Presenter.BackBuffer;
+ screenPos.X *= backBuffer.Width;
+ screenPos.Y *= backBuffer.Height;
- private void Raycast(Vector2 screenPos)
- {
- var backBuffer = GraphicsDevice.Presenter.BackBuffer;
- screenPos.X *= backBuffer.Width;
- screenPos.Y *= backBuffer.Height;
-
- var viewport = new Viewport(0, 0, backBuffer.Width, backBuffer.Height);
-
- var unprojectedNear =
- viewport.Unproject(
- new Vector3(screenPos, 0.0f),
- camera.ProjectionMatrix,
- camera.ViewMatrix,
- Matrix.Identity);
-
- var unprojectedFar =
- viewport.Unproject(
- new Vector3(screenPos, 1.0f),
- camera.ProjectionMatrix,
- camera.ViewMatrix,
- Matrix.Identity);
-
- var result = simulation.Raycast(unprojectedNear, unprojectedFar);
- if (!result.Succeeded || result.Collider == null) return;
-
- var rigidBody = result.Collider as RigidbodyComponent;
- if (rigidBody == null) return;
-
- rigidBody.Activate();
- rigidBody.ApplyImpulse(new Vector3(0, 5, 0));
- }
+ var viewport = new Viewport(0, 0, backBuffer.Width, backBuffer.Height);
+
+ var unprojectedNear =
+ viewport.Unproject(
+ new Vector3(screenPos, 0.0f),
+ camera.ProjectionMatrix,
+ camera.ViewMatrix,
+ Matrix.Identity);
+
+ var unprojectedFar =
+ viewport.Unproject(
+ new Vector3(screenPos, 1.0f),
+ camera.ProjectionMatrix,
+ camera.ViewMatrix,
+ Matrix.Identity);
+
+ var result = simulation.Raycast(unprojectedNear, unprojectedFar);
+ if (!result.Succeeded || result.Collider == null) return;
+
+ if (result.Collider is not RigidbodyComponent rigidBody) return;
+
+ rigidBody.Activate();
+ rigidBody.ApplyImpulse(new Vector3(0, 5, 0));
}
}
diff --git a/samples/Physics/PhysicsSample/PhysicsSample.Game/Trigger.cs b/samples/Physics/PhysicsSample/PhysicsSample.Game/Trigger.cs
index f1606e9bad..06b4d22329 100644
--- a/samples/Physics/PhysicsSample/PhysicsSample.Game/Trigger.cs
+++ b/samples/Physics/PhysicsSample/PhysicsSample.Game/Trigger.cs
@@ -1,52 +1,50 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
-using System;
-using Stride.Engine;
-using Stride.Physics;
-using System.Threading.Tasks;
+
using Stride.Core;
+using Stride.Engine;
using Stride.Engine.Events;
+using Stride.Physics;
-namespace PhysicsSample
+namespace PhysicsSample;
+
+public class Trigger : AsyncScript
{
- public class Trigger : AsyncScript
+ [DataMemberIgnore]
+ public EventKey TriggerEvent = new();
+
+ public override async Task Execute()
{
- [DataMemberIgnore]
- public EventKey TriggerEvent = new EventKey();
+ var trigger = Entity.Get();
+ trigger.ProcessCollisions = true;
- public override async Task Execute()
+ while (Game.IsRunning)
{
- var trigger = Entity.Get();
- trigger.ProcessCollisions = true;
+ // Wait for the next collision event
+ var firstCollision = await trigger.NewCollision();
- while (Game.IsRunning)
- {
- // Wait for the next collision event
- var firstCollision = await trigger.NewCollision();
+ // Filter collisions based on collision groups
+ var filterAhitB = ((int)firstCollision.ColliderA.CanCollideWith) & ((int)firstCollision.ColliderB.CollisionGroup);
+ var filterBhitA = ((int)firstCollision.ColliderB.CanCollideWith) & ((int)firstCollision.ColliderA.CollisionGroup);
+ if (filterAhitB == 0 || filterBhitA == 0)
+ continue;
- // Filter collisions based on collision groups
- var filterAhitB = ((int)firstCollision.ColliderA.CanCollideWith) & ((int)firstCollision.ColliderB.CollisionGroup);
- var filterBhitA = ((int)firstCollision.ColliderB.CanCollideWith) & ((int)firstCollision.ColliderA.CollisionGroup);
- if (filterAhitB == 0 || filterBhitA == 0)
- continue;
+ // Broadcast the collision start event
+ TriggerEvent.Broadcast(true);
- // Broadcast the collision start event
- TriggerEvent.Broadcast(true);
-
- // Wait for the collision to end and broadcast that event
- Func collisionEndTask = async () =>
+ // Wait for the collision to end and broadcast that event
+ Func collisionEndTask = async () =>
+ {
+ Collision collision;
+ do
{
- Collision collision;
- do
- {
- collision = await trigger.CollisionEnded();
- } while (collision != firstCollision);
+ collision = await trigger.CollisionEnded();
+ } while (collision != firstCollision);
- TriggerEvent.Broadcast(false);
- };
+ TriggerEvent.Broadcast(false);
+ };
- Script.AddTask(collisionEndTask);
- }
+ Script.AddTask(collisionEndTask);
}
}
}
diff --git a/samples/Physics/PhysicsSample/PhysicsSample.Windows/PhysicsSample.Windows.csproj b/samples/Physics/PhysicsSample/PhysicsSample.Windows/PhysicsSample.Windows.csproj
index 7905e35bd1..eeeb4e5110 100644
--- a/samples/Physics/PhysicsSample/PhysicsSample.Windows/PhysicsSample.Windows.csproj
+++ b/samples/Physics/PhysicsSample/PhysicsSample.Windows/PhysicsSample.Windows.csproj
@@ -7,6 +7,8 @@
..\Bin\Windows\$(Configuration)\
false
STRIDE_PLATFORM_DESKTOP
+ enable
+ latest
$(MSBuildThisFileDirectory)..\PhysicsSample.sdpkg
diff --git a/samples/Templates/FirstPersonShooter/FirstPersonShooter/FirstPersonShooter.Game/Core/InputManagerExtensions.cs b/samples/Templates/FirstPersonShooter/FirstPersonShooter/FirstPersonShooter.Game/Core/InputManagerExtensions.cs
index 8db925415c..89199863dc 100644
--- a/samples/Templates/FirstPersonShooter/FirstPersonShooter/FirstPersonShooter.Game/Core/InputManagerExtensions.cs
+++ b/samples/Templates/FirstPersonShooter/FirstPersonShooter/FirstPersonShooter.Game/Core/InputManagerExtensions.cs
@@ -1,133 +1,116 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
+
using Stride.Core.Mathematics;
using Stride.Input;
-namespace FirstPersonShooter.Core
+namespace FirstPersonShooter.Core;
+
+public static class InputManagerExtensions
{
- public static class InputManagerExtensions
+ public static bool IsGamePadButtonDown(this InputManager input, GamePadButton button, int index)
{
- public static bool IsGamePadButtonDown(this InputManager input, GamePadButton button, int index)
- {
- var gamepad = input.GetGamePadByIndex(index);
- if (gamepad == null)
- return false;
-
- return (gamepad.State.Buttons & button) == button;
- }
-
- public static bool IsGamePadButtonDownAny(this InputManager input, GamePadButton button)
- {
- foreach(var gamepad in input.GamePads)
- {
- if ((gamepad.State.Buttons & button) == button)
- return true;
- }
+ var gamepad = input.GetGamePadByIndex(index);
+ if (gamepad == null)
return false;
- }
- public static Vector2 GetLeftThumb(this InputManager input, int index)
- {
- var gamepad = input.GetGamePadByIndex(index);
- if (gamepad == null)
- return Vector2.Zero;
+ return (gamepad.State.Buttons & button) == button;
+ }
- return gamepad.State.LeftThumb;
- }
+ public static bool IsGamePadButtonDownAny(this InputManager input, GamePadButton button)
+ {
+ return input.GamePads.Any(gamepad => (gamepad.State.Buttons & button) == button);
+ }
+
+ public static Vector2 GetLeftThumb(this InputManager input, int index)
+ {
+ var gamepad = input.GetGamePadByIndex(index);
+ return gamepad == null ? Vector2.Zero : gamepad.State.LeftThumb;
+ }
- public static Vector2 GetLeftThumbAny(this InputManager input, float deadZone)
+ public static Vector2 GetLeftThumbAny(this InputManager input, float deadZone)
+ {
+ int totalCount = 0;
+ Vector2 totalMovement = Vector2.Zero;
+ foreach (var gamepad in input.GamePads)
{
- int totalCount = 0;
- Vector2 totalMovement = Vector2.Zero;
- foreach (var gamepad in input.GamePads)
+ var leftVector = gamepad.State.LeftThumb;
+ if (leftVector.Length() >= deadZone)
{
- var leftVector = gamepad.State.LeftThumb;
- if (leftVector.Length() >= deadZone)
- {
- totalCount++;
- totalMovement += leftVector;
- }
+ totalCount++;
+ totalMovement += leftVector;
}
-
- return (totalCount > 1) ? (totalMovement / totalCount) : totalMovement;
}
- public static Vector2 GetRightThumb(this InputManager input, int index)
- {
- var gamepad = input.GetGamePadByIndex(index);
- if (gamepad == null)
- return Vector2.Zero;
+ return (totalCount > 1) ? (totalMovement / totalCount) : totalMovement;
+ }
- return gamepad.State.RightThumb;
- }
+ public static Vector2 GetRightThumb(this InputManager input, int index)
+ {
+ var gamepad = input.GetGamePadByIndex(index);
+ return gamepad == null ? Vector2.Zero : gamepad.State.RightThumb;
+ }
- public static Vector2 GetRightThumbAny(this InputManager input, float deadZone)
+ public static Vector2 GetRightThumbAny(this InputManager input, float deadZone)
+ {
+ int totalCount = 0;
+ Vector2 totalMovement = Vector2.Zero;
+ foreach (var gamepad in input.GamePads)
{
- int totalCount = 0;
- Vector2 totalMovement = Vector2.Zero;
- foreach (var gamepad in input.GamePads)
+ var rightVector = gamepad.State.RightThumb;
+ if (rightVector.Length() >= deadZone)
{
- var rightVector = gamepad.State.RightThumb;
- if (rightVector.Length() >= deadZone)
- {
- totalCount++;
- totalMovement += rightVector;
- }
+ totalCount++;
+ totalMovement += rightVector;
}
-
- return (totalCount > 1) ? (totalMovement / totalCount) : totalMovement;
}
- public static float GetLeftTrigger(this InputManager input, int index)
- {
- var gamepad = input.GetGamePadByIndex(index);
- if (gamepad == null)
- return 0.0f;
+ return (totalCount > 1) ? (totalMovement / totalCount) : totalMovement;
+ }
- return gamepad.State.LeftTrigger;
- }
+ public static float GetLeftTrigger(this InputManager input, int index)
+ {
+ var gamepad = input.GetGamePadByIndex(index);
+ return gamepad == null ? 0.0f : gamepad.State.LeftTrigger;
+ }
- public static float GetLeftTriggerAny(this InputManager input, float deadZone)
+ public static float GetLeftTriggerAny(this InputManager input, float deadZone)
+ {
+ int totalCount = 0;
+ float totalInput = 0;
+ foreach (var gamepad in input.GamePads)
{
- int totalCount = 0;
- float totalInput = 0;
- foreach (var gamepad in input.GamePads)
+ float triggerValue = gamepad.State.LeftTrigger;
+ if (triggerValue >= deadZone)
{
- float triggerValue = gamepad.State.LeftTrigger;
- if (triggerValue >= deadZone)
- {
- totalCount++;
- totalInput += triggerValue;
- }
+ totalCount++;
+ totalInput += triggerValue;
}
-
- return (totalCount > 1) ? (totalInput / totalCount) : totalInput;
}
- public static float GetRightTrigger(this InputManager input, int index)
- {
- var gamepad = input.GetGamePadByIndex(index);
- if (gamepad == null)
- return 0.0f;
+ return (totalCount > 1) ? (totalInput / totalCount) : totalInput;
+ }
- return gamepad.State.RightTrigger;
- }
+ public static float GetRightTrigger(this InputManager input, int index)
+ {
+ var gamepad = input.GetGamePadByIndex(index);
+ return gamepad == null ? 0.0f : gamepad.State.RightTrigger;
+ }
- public static float GetRightTriggerAny(this InputManager input, float deadZone)
+ public static float GetRightTriggerAny(this InputManager input, float deadZone)
+ {
+ int totalCount = 0;
+ float totalInput = 0;
+ foreach (var gamepad in input.GamePads)
{
- int totalCount = 0;
- float totalInput = 0;
- foreach (var gamepad in input.GamePads)
+ float triggerValue = gamepad.State.RightTrigger;
+ if (triggerValue >= deadZone)
{
- float triggerValue = gamepad.State.RightTrigger;
- if (triggerValue >= deadZone)
- {
- totalCount++;
- totalInput += triggerValue;
- }
+ totalCount++;
+ totalInput += triggerValue;
}
-
- return (totalCount > 1) ? (totalInput / totalCount) : totalInput;
}
+
+ return (totalCount > 1) ? (totalInput / totalCount) : totalInput;
}
}
diff --git a/samples/Templates/FirstPersonShooter/FirstPersonShooter/FirstPersonShooter.Game/Core/Utils.cs b/samples/Templates/FirstPersonShooter/FirstPersonShooter/FirstPersonShooter.Game/Core/Utils.cs
index 856324ebca..7ca31d8527 100644
--- a/samples/Templates/FirstPersonShooter/FirstPersonShooter/FirstPersonShooter.Game/Core/Utils.cs
+++ b/samples/Templates/FirstPersonShooter/FirstPersonShooter/FirstPersonShooter.Game/Core/Utils.cs
@@ -1,24 +1,24 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
+
using Stride.Core.Mathematics;
using Stride.Engine;
-namespace FirstPersonShooter.Core
+namespace FirstPersonShooter.Core;
+
+public static class Utils
{
- public static class Utils
+ public static Vector3 LogicDirectionToWorldDirection(Vector2 logicDirection, CameraComponent camera, Vector3 upVector)
{
- public static Vector3 LogicDirectionToWorldDirection(Vector2 logicDirection, CameraComponent camera, Vector3 upVector)
- {
- camera.Update();
- var inverseView = Matrix.Invert(camera.ViewMatrix);
+ camera.Update();
+ var inverseView = Matrix.Invert(camera.ViewMatrix);
- var forward = Vector3.Cross(upVector, inverseView.Right);
- forward.Normalize();
+ var forward = Vector3.Cross(upVector, inverseView.Right);
+ forward.Normalize();
- var right = Vector3.Cross(forward, upVector);
- var worldDirection = forward * logicDirection.Y + right * logicDirection.X;
- worldDirection.Normalize();
- return worldDirection;
- }
+ var right = Vector3.Cross(forward, upVector);
+ var worldDirection = forward * logicDirection.Y + right * logicDirection.X;
+ worldDirection.Normalize();
+ return worldDirection;
}
}
diff --git a/samples/Templates/FirstPersonShooter/FirstPersonShooter/FirstPersonShooter.Game/EffectController.cs b/samples/Templates/FirstPersonShooter/FirstPersonShooter/FirstPersonShooter.Game/EffectController.cs
index 2ea9106dcd..354361db83 100644
--- a/samples/Templates/FirstPersonShooter/FirstPersonShooter/FirstPersonShooter.Game/EffectController.cs
+++ b/samples/Templates/FirstPersonShooter/FirstPersonShooter/FirstPersonShooter.Game/EffectController.cs
@@ -1,40 +1,37 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
-using System;
-using System.Threading.Tasks;
+
using FirstPersonShooter.Player;
using Stride.Core.Mathematics;
using Stride.Engine.Events;
using Stride.Physics;
-namespace FirstPersonShooter
-{
- ///
- /// Will spawn some visual effects when the gun shoots
- ///
- public class EffectController : TriggerScript
- {
- private readonly EventReceiver weaponFiredEvent = new EventReceiver(WeaponScript.WeaponFired);
+namespace FirstPersonShooter;
+
+///
+/// Will spawn some visual effects when the gun shoots
+///
+public class EffectController : TriggerScript
+{
+ private readonly EventReceiver weaponFiredEvent = new(WeaponScript.WeaponFired);
- public override async Task Execute()
+ public override async Task Execute()
+ {
+ while (Game.IsRunning)
{
- while (Game.IsRunning)
- {
- var target = await weaponFiredEvent.ReceiveAsync();
+ var target = await weaponFiredEvent.ReceiveAsync();
- if (target.DidFire)
- SpawnEvent("MuzzleFlash", Entity, Matrix.Identity);
+ if (target.DidFire)
+ SpawnEvent("MuzzleFlash", Entity, Matrix.Identity);
- if (target.DidHit)
- SpawnEvent("BulletImpact", null, Matrix.RotationQuaternion(Quaternion.BetweenDirections(Vector3.UnitY, target.HitResult.Normal)) * Matrix.Translation(target.HitResult.Point));
+ if (target.DidHit)
+ SpawnEvent("BulletImpact", null, Matrix.RotationQuaternion(Quaternion.BetweenDirections(Vector3.UnitY, target.HitResult.Normal)) * Matrix.Translation(target.HitResult.Point));
- var rigidBody = target.HitResult.Collider as RigidbodyComponent;
- if (rigidBody != null)
- {
- var rand = new Random();
- SpawnEvent("DamagedTrail", rigidBody.Entity, Matrix.Translation(new Vector3((float)rand.NextDouble() - 0.5f, (float)rand.NextDouble() - 0.5f, (float)rand.NextDouble() - 0.5f)));
- }
+ if (target.HitResult.Collider is RigidbodyComponent rigidBody)
+ {
+ var rand = new Random();
+ SpawnEvent("DamagedTrail", rigidBody.Entity, Matrix.Translation(new Vector3((float)rand.NextDouble() - 0.5f, (float)rand.NextDouble() - 0.5f, (float)rand.NextDouble() - 0.5f)));
}
- }
- }
+ }
+ }
}
diff --git a/samples/Templates/FirstPersonShooter/FirstPersonShooter/FirstPersonShooter.Game/FirstPersonShooter.Game.csproj b/samples/Templates/FirstPersonShooter/FirstPersonShooter/FirstPersonShooter.Game/FirstPersonShooter.Game.csproj
index c4defbbe00..b462f2bdc0 100644
--- a/samples/Templates/FirstPersonShooter/FirstPersonShooter/FirstPersonShooter.Game/FirstPersonShooter.Game.csproj
+++ b/samples/Templates/FirstPersonShooter/FirstPersonShooter/FirstPersonShooter.Game/FirstPersonShooter.Game.csproj
@@ -2,6 +2,8 @@
net8.0
FirstPersonShooter
+ enable
+ latest
diff --git a/samples/Templates/FirstPersonShooter/FirstPersonShooter/FirstPersonShooter.Game/FpsCamera.cs b/samples/Templates/FirstPersonShooter/FirstPersonShooter/FirstPersonShooter.Game/FpsCamera.cs
index 900107f98a..6f45c330f7 100644
--- a/samples/Templates/FirstPersonShooter/FirstPersonShooter/FirstPersonShooter.Game/FpsCamera.cs
+++ b/samples/Templates/FirstPersonShooter/FirstPersonShooter/FirstPersonShooter.Game/FpsCamera.cs
@@ -1,105 +1,102 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
+
+using FirstPersonShooter.Player;
using Stride.Core.Mathematics;
using Stride.Engine;
-using System;
-using System.Threading.Tasks;
-using FirstPersonShooter.Player;
using Stride.Engine.Events;
-namespace FirstPersonShooter
+namespace FirstPersonShooter;
+
+///
+/// The default script for the scene editor camera.
+///
+public class FpsCamera : AsyncScript
{
///
- /// The default script for the scene editor camera.
+ /// Gets the camera component used to visualized the scene.
+ ///
+ private CameraComponent Component => Entity?.Get();
+
+ ///
+ /// Gets or sets the rotation speed of the camera (in radian/screen units)
+ ///
+ public float RotationSpeed { get; set; } = 2.355f;
+
+ ///
+ /// Gets or sets the Yaw rotation of the camera.
///
- public class FpsCamera : AsyncScript
+ private float Yaw { get; set; }
+
+ ///
+ /// Gets or sets the Pitch rotation of the camera.
+ ///
+ private float Pitch { get; set; }
+
+ ///
+ /// Check to invert the horizontal camera movement
+ ///
+ public bool InvertX { get; set; } = false;
+
+ ///
+ /// Check to invert the vertical camera movement
+ ///
+ public bool InvertY { get; set; } = false;
+
+ private readonly EventReceiver cameraDirectionEvent = new(PlayerInput.CameraDirectionEventKey);
+
+ public override async Task Execute()
{
- ///
- /// Gets the camera component used to visualized the scene.
- ///
- private CameraComponent Component => Entity?.Get();
-
- ///
- /// Gets or sets the rotation speed of the camera (in radian/screen units)
- ///
- public float RotationSpeed { get; set; } = 2.355f;
-
- ///
- /// Gets or sets the Yaw rotation of the camera.
- ///
- private float Yaw { get; set; }
-
- ///
- /// Gets or sets the Pitch rotation of the camera.
- ///
- private float Pitch { get; set; }
-
- ///
- /// Check to invert the horizontal camera movement
- ///
- public bool InvertX { get; set; } = false;
-
- ///
- /// Check to invert the vertical camera movement
- ///
- public bool InvertY { get; set; } = false;
-
- private readonly EventReceiver cameraDirectionEvent = new EventReceiver(PlayerInput.CameraDirectionEventKey);
-
- public override async Task Execute()
- {
- Reset();
+ Reset();
- while (true)
- {
- UpdateCamera();
+ while (true)
+ {
+ UpdateCamera();
- await Script.NextFrame();
- }
+ await Script.NextFrame();
}
+ }
- public void Reset()
- {
- Yaw =
- (float)
- Math.Asin(2 * Entity.Transform.Rotation.X * Entity.Transform.Rotation.Y +
- 2 * Entity.Transform.Rotation.Z * Entity.Transform.Rotation.W);
+ public void Reset()
+ {
+ Yaw =
+ (float)
+ Math.Asin(2 * Entity.Transform.Rotation.X * Entity.Transform.Rotation.Y +
+ 2 * Entity.Transform.Rotation.Z * Entity.Transform.Rotation.W);
+
+ Pitch =
+ (float)
+ Math.Atan2(
+ 2 * Entity.Transform.Rotation.X * Entity.Transform.Rotation.W -
+ 2 * Entity.Transform.Rotation.Y * Entity.Transform.Rotation.Z,
+ 1 - 2 * Entity.Transform.Rotation.X * Entity.Transform.Rotation.X -
+ 2 * Entity.Transform.Rotation.Z * Entity.Transform.Rotation.Z);
+ }
+
+ ///
+ /// Update the camera parameters.
+ ///
+ protected virtual void UpdateCamera()
+ {
+ // Camera movement from player input
+ cameraDirectionEvent.TryReceive(out var cameraMovement);
+
+ if (InvertY) cameraMovement.Y *= -1;
+ if (InvertX) cameraMovement.X *= -1;
- Pitch =
- (float)
- Math.Atan2(
- 2 * Entity.Transform.Rotation.X * Entity.Transform.Rotation.W -
- 2 * Entity.Transform.Rotation.Y * Entity.Transform.Rotation.Z,
- 1 - 2 * Entity.Transform.Rotation.X * Entity.Transform.Rotation.X -
- 2 * Entity.Transform.Rotation.Z * Entity.Transform.Rotation.Z);
- }
+ Yaw -= cameraMovement.X * RotationSpeed;
+ Pitch = MathUtil.Clamp(Pitch + cameraMovement.Y * RotationSpeed, -MathUtil.PiOverTwo, MathUtil.PiOverTwo);
- ///
- /// Update the camera parameters.
- ///
- protected virtual void UpdateCamera()
- {
- // Camera movement from player input
- Vector2 cameraMovement;
- cameraDirectionEvent.TryReceive(out cameraMovement);
-
- if (InvertY) cameraMovement.Y *= -1;
- if (InvertX) cameraMovement.X *= -1;
-
- Yaw -= cameraMovement.X * RotationSpeed;
- Pitch = MathUtil.Clamp(Pitch + cameraMovement.Y * RotationSpeed, -MathUtil.PiOverTwo, MathUtil.PiOverTwo);
-
- // Update the camera view matrix
- UpdateViewMatrix();
- }
+ // Update the camera view matrix
+ UpdateViewMatrix();
+ }
- private void UpdateViewMatrix()
- {
- var camera = Component;
- if (camera == null) return;
- var rotation = Quaternion.RotationYawPitchRoll(Yaw, Pitch, 0);
+ private void UpdateViewMatrix()
+ {
+ var camera = Component;
+ if (camera == null) return;
+ var rotation = Quaternion.RotationYawPitchRoll(Yaw, Pitch, 0);
- Entity.Transform.Rotation = rotation;
- }
+ Entity.Transform.Rotation = rotation;
}
}
diff --git a/samples/Templates/FirstPersonShooter/FirstPersonShooter/FirstPersonShooter.Game/Player/AnimationController.cs b/samples/Templates/FirstPersonShooter/FirstPersonShooter/FirstPersonShooter.Game/Player/AnimationController.cs
index 80e8bdf0b7..71848f1f7e 100644
--- a/samples/Templates/FirstPersonShooter/FirstPersonShooter/FirstPersonShooter.Game/Player/AnimationController.cs
+++ b/samples/Templates/FirstPersonShooter/FirstPersonShooter/FirstPersonShooter.Game/Player/AnimationController.cs
@@ -1,184 +1,182 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
-using System;
+
+using Stride.Animations;
using Stride.Core;
using Stride.Core.Collections;
-using Stride.Animations;
using Stride.Engine;
using Stride.Engine.Events;
-namespace FirstPersonShooter.Player
+namespace FirstPersonShooter.Player;
+
+public class AnimationController : SyncScript, IBlendTreeBuilder
{
- public class AnimationController : SyncScript, IBlendTreeBuilder
- {
- private readonly EventReceiver weaponFiredEvent = new EventReceiver(WeaponScript.WeaponFired);
+ private readonly EventReceiver weaponFiredEvent = new(WeaponScript.WeaponFired);
- private readonly EventReceiver isReloadingEvent = new EventReceiver(WeaponScript.IsReloading);
+ private readonly EventReceiver isReloadingEvent = new(WeaponScript.IsReloading);
- private readonly EventReceiver runSpeedEvent = new EventReceiver(PlayerController.RunSpeedEventKey);
+ private readonly EventReceiver runSpeedEvent = new(PlayerController.RunSpeedEventKey);
- private float runSpeed = 0;
+ private float runSpeed;
- private AnimationState defaultState = AnimationState.Idle;
+ private AnimationState defaultState = AnimationState.Idle;
- [Display("Animation Component")]
- public AnimationComponent AnimationComponent { get; set; }
+ [Display("Animation Component")]
+ public AnimationComponent AnimationComponent { get; set; }
- [Display("Idle")]
- public AnimationClip AnimationIdle { get; set; }
+ [Display("Idle")]
+ public AnimationClip AnimationIdle { get; set; }
- [Display("Walk")]
- public AnimationClip AnimationWalk { get; set; }
+ [Display("Walk")]
+ public AnimationClip AnimationWalk { get; set; }
- [Display("Shoot")]
- public AnimationClip AnimationShoot { get; set; }
+ [Display("Shoot")]
+ public AnimationClip AnimationShoot { get; set; }
- [Display("Reload")]
- public AnimationClip AnimationReload { get; set; }
+ [Display("Reload")]
+ public AnimationClip AnimationReload { get; set; }
- [Display("Time Scale")]
- public double TimeFactor { get; set; } = 1;
+ [Display("Time Scale")]
+ public double TimeFactor { get; set; } = 1;
- private AnimationClipEvaluator animEvaluatorIdle;
- private AnimationClipEvaluator animEvaluatorWalk;
- private AnimationClipEvaluator animEvaluatorShoot;
- private AnimationClipEvaluator animEvaluatorReload;
- private double currentTime = 0;
+ private AnimationClipEvaluator animEvaluatorIdle;
+ private AnimationClipEvaluator animEvaluatorWalk;
+ private AnimationClipEvaluator animEvaluatorShoot;
+ private AnimationClipEvaluator animEvaluatorReload;
+ private double currentTime;
- private AnimationState state = AnimationState.Idle;
+ private AnimationState state = AnimationState.Idle;
- private AnimationClipEvaluator currentEvaluator;
- private AnimationClip currentClip;
+ private AnimationClipEvaluator currentEvaluator;
+ private AnimationClip currentClip;
- public override void Start()
- {
- base.Start();
+ public override void Start()
+ {
+ base.Start();
- if (AnimationComponent == null)
- throw new InvalidOperationException("The animation component is not set");
+ if (AnimationComponent == null)
+ throw new InvalidOperationException("The animation component is not set");
- if (AnimationIdle == null)
- throw new InvalidOperationException("Idle animation is not set");
+ if (AnimationIdle == null)
+ throw new InvalidOperationException("Idle animation is not set");
- if (AnimationWalk == null)
- throw new InvalidOperationException("Walking animation is not set");
+ if (AnimationWalk == null)
+ throw new InvalidOperationException("Walking animation is not set");
- if (AnimationShoot == null)
- throw new InvalidOperationException("Shooting animation is not set");
+ if (AnimationShoot == null)
+ throw new InvalidOperationException("Shooting animation is not set");
- if (AnimationReload == null)
- throw new InvalidOperationException("Reloading animation is not set");
+ if (AnimationReload == null)
+ throw new InvalidOperationException("Reloading animation is not set");
- // By setting a custom blend tree builder we can override the default behavior of the animation system
- // Instead, BuildBlendTree(FastList blendStack) will be called each frame
- AnimationComponent.BlendTreeBuilder = this;
+ // By setting a custom blend tree builder we can override the default behavior of the animation system
+ // Instead, BuildBlendTree(FastList blendStack) will be called each frame
+ AnimationComponent.BlendTreeBuilder = this;
- animEvaluatorIdle = AnimationComponent.Blender.CreateEvaluator(AnimationIdle);
- animEvaluatorWalk = AnimationComponent.Blender.CreateEvaluator(AnimationWalk);
- animEvaluatorShoot = AnimationComponent.Blender.CreateEvaluator(AnimationShoot);
- animEvaluatorReload = AnimationComponent.Blender.CreateEvaluator(AnimationReload);
+ animEvaluatorIdle = AnimationComponent.Blender.CreateEvaluator(AnimationIdle);
+ animEvaluatorWalk = AnimationComponent.Blender.CreateEvaluator(AnimationWalk);
+ animEvaluatorShoot = AnimationComponent.Blender.CreateEvaluator(AnimationShoot);
+ animEvaluatorReload = AnimationComponent.Blender.CreateEvaluator(AnimationReload);
- currentEvaluator = animEvaluatorIdle;
- currentClip = AnimationIdle;
- }
+ currentEvaluator = animEvaluatorIdle;
+ currentClip = AnimationIdle;
+ }
- public override void Cancel()
+ public override void Cancel()
+ {
+ AnimationComponent.Blender.ReleaseEvaluator(animEvaluatorIdle);
+ AnimationComponent.Blender.ReleaseEvaluator(animEvaluatorWalk);
+ AnimationComponent.Blender.ReleaseEvaluator(animEvaluatorShoot);
+ AnimationComponent.Blender.ReleaseEvaluator(animEvaluatorReload);
+ }
+
+ private void SwitchToDefaultState()
+ {
+ currentTime = (state == defaultState) ? currentTime : 0;
+ state = defaultState;
+
+ if (state == AnimationState.Idle)
{
- AnimationComponent.Blender.ReleaseEvaluator(animEvaluatorIdle);
- AnimationComponent.Blender.ReleaseEvaluator(animEvaluatorWalk);
- AnimationComponent.Blender.ReleaseEvaluator(animEvaluatorShoot);
- AnimationComponent.Blender.ReleaseEvaluator(animEvaluatorReload);
+ currentClip = AnimationIdle;
+ currentEvaluator = animEvaluatorIdle;
}
-
- private void SwitchToDefaultState()
+ else
{
- currentTime = (state == defaultState) ? currentTime : 0;
- state = defaultState;
-
- if (state == AnimationState.Idle)
- {
- currentClip = AnimationIdle;
- currentEvaluator = animEvaluatorIdle;
- }
- else
- {
- currentClip = AnimationWalk;
- currentEvaluator = animEvaluatorWalk;
- }
+ currentClip = AnimationWalk;
+ currentEvaluator = animEvaluatorWalk;
}
+ }
- public override void Update()
- {
- runSpeedEvent.TryReceive(out runSpeed);
- defaultState = (runSpeed > 0.15f) ? AnimationState.Walking : AnimationState.Idle;
+ public override void Update()
+ {
+ runSpeedEvent.TryReceive(out runSpeed);
+ defaultState = (runSpeed > 0.15f) ? AnimationState.Walking : AnimationState.Idle;
- WeaponFiredResult weaponResult;
- var didFire = weaponFiredEvent.TryReceive(out weaponResult);
+ WeaponFiredResult weaponResult;
+ var didFire = weaponFiredEvent.TryReceive(out weaponResult);
- bool isReloading;
- var didReload = isReloadingEvent.TryReceive(out isReloading);
- isReloading |= didReload;
+ var didReload = isReloadingEvent.TryReceive(out var isReloading);
+ isReloading |= didReload;
- // Update current animation
- var currentTicks = TimeSpan.FromTicks((long)(currentTime * currentClip.Duration.Ticks));
- var updatedTicks = currentTicks.Ticks + (long)(Game.DrawTime.Elapsed.Ticks * TimeFactor);
+ // Update current animation
+ var currentTicks = TimeSpan.FromTicks((long)(currentTime * currentClip.Duration.Ticks));
+ var updatedTicks = currentTicks.Ticks + (long)(Game.DrawTime.Elapsed.Ticks * TimeFactor);
- var currentClipFinished = (updatedTicks >= currentClip.Duration.Ticks);
+ var currentClipFinished = (updatedTicks >= currentClip.Duration.Ticks);
- currentTicks = TimeSpan.FromTicks(updatedTicks % currentClip.Duration.Ticks);
- currentTime = ((double)currentTicks.Ticks / (double)currentClip.Duration.Ticks);
+ currentTicks = TimeSpan.FromTicks(updatedTicks % currentClip.Duration.Ticks);
+ currentTime = (currentTicks.Ticks / (double)currentClip.Duration.Ticks);
- // State change if necessary
- if (isReloading)
- {
- if (state != AnimationState.Reloading)
- {
- currentTime = 0;
- state = AnimationState.Reloading;
- currentClip = AnimationReload;
- currentEvaluator = animEvaluatorReload;
- }
- }
- else
- if (didFire)
- {
- if (state != AnimationState.Shooting)
- {
- currentTime = 0;
- state = AnimationState.Shooting;
- currentClip = AnimationShoot;
- currentEvaluator = animEvaluatorShoot;
- }
- }
- else
- if (currentClipFinished)
+ // State change if necessary
+ if (isReloading)
+ {
+ if (state != AnimationState.Reloading)
{
- SwitchToDefaultState();
+ currentTime = 0;
+ state = AnimationState.Reloading;
+ currentClip = AnimationReload;
+ currentEvaluator = animEvaluatorReload;
}
- else
- if ((state == AnimationState.Idle || state == AnimationState.Walking) && state != defaultState)
+ }
+ else
+ if (didFire)
+ {
+ if (state != AnimationState.Shooting)
{
- SwitchToDefaultState();
+ currentTime = 0;
+ state = AnimationState.Shooting;
+ currentClip = AnimationShoot;
+ currentEvaluator = animEvaluatorShoot;
}
}
-
- ///
- /// BuildBlendTree is called every frame from the animation system when the needs to be evaluated
- /// It overrides the default behavior of the by setting a custom blend tree
- ///
- /// The stack of animation operations to be blended
- public void BuildBlendTree(FastList blendStack)
+ else
+ if (currentClipFinished)
{
- blendStack.Add(AnimationOperation.NewPush(currentEvaluator, TimeSpan.FromTicks((long)(currentTime * currentClip.Duration.Ticks))));
+ SwitchToDefaultState();
}
-
- enum AnimationState
+ else
+ if (state is AnimationState.Idle or AnimationState.Walking && state != defaultState)
{
- Idle,
- Walking,
- Shooting,
- Reloading,
+ SwitchToDefaultState();
}
}
+
+ ///
+ /// BuildBlendTree is called every frame from the animation system when the needs to be evaluated
+ /// It overrides the default behavior of the by setting a custom blend tree
+ ///
+ /// The stack of animation operations to be blended
+ public void BuildBlendTree(FastList blendStack)
+ {
+ blendStack.Add(AnimationOperation.NewPush(currentEvaluator, TimeSpan.FromTicks((long)(currentTime * currentClip.Duration.Ticks))));
+ }
+
+ enum AnimationState
+ {
+ Idle,
+ Walking,
+ Shooting,
+ Reloading,
+ }
}
diff --git a/samples/Templates/FirstPersonShooter/FirstPersonShooter/FirstPersonShooter.Game/Player/PlayerController.cs b/samples/Templates/FirstPersonShooter/FirstPersonShooter/FirstPersonShooter.Game/Player/PlayerController.cs
index e1be2575c6..eb80ac4e20 100644
--- a/samples/Templates/FirstPersonShooter/FirstPersonShooter/FirstPersonShooter.Game/Player/PlayerController.cs
+++ b/samples/Templates/FirstPersonShooter/FirstPersonShooter/FirstPersonShooter.Game/Player/PlayerController.cs
@@ -1,56 +1,54 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
-using System;
+
using Stride.Core;
using Stride.Core.Mathematics;
using Stride.Engine;
using Stride.Engine.Events;
using Stride.Physics;
-namespace FirstPersonShooter.Player
+namespace FirstPersonShooter.Player;
+
+public class PlayerController : SyncScript
{
- public class PlayerController : SyncScript
+ [Display("Run Speed")]
+ public float MaxRunSpeed { get; set; } = 5;
+
+ public static readonly EventKey RunSpeedEventKey = new();
+
+ // This component is the physics representation of a controllable character
+ private CharacterComponent character;
+
+ private readonly EventReceiver moveDirectionEvent = new(PlayerInput.MoveDirectionEventKey);
+
+ ///
+ /// Called when the script is first initialized
+ ///
+ public override void Start()
+ {
+ base.Start();
+
+ // Will search for an CharacterComponent within the same entity as this script
+ character = Entity.Get();
+ if (character == null) throw new ArgumentException("Please add a CharacterComponent to the entity containing PlayerController!");
+ }
+
+ ///
+ /// Called on every frame update
+ ///
+ public override void Update()
{
- [Display("Run Speed")]
- public float MaxRunSpeed { get; set; } = 5;
-
- public static readonly EventKey RunSpeedEventKey = new EventKey();
-
- // This component is the physics representation of a controllable character
- private CharacterComponent character;
-
- private readonly EventReceiver moveDirectionEvent = new EventReceiver(PlayerInput.MoveDirectionEventKey);
-
- ///
- /// Called when the script is first initialized
- ///
- public override void Start()
- {
- base.Start();
-
- // Will search for an CharacterComponent within the same entity as this script
- character = Entity.Get();
- if (character == null) throw new ArgumentException("Please add a CharacterComponent to the entity containing PlayerController!");
- }
-
- ///
- /// Called on every frame update
- ///
- public override void Update()
- {
- Move();
- }
-
- private void Move()
- {
- // Character speed
- Vector3 moveDirection = Vector3.Zero;
- moveDirectionEvent.TryReceive(out moveDirection);
-
- character.SetVelocity(moveDirection * MaxRunSpeed);
-
- // Broadcast normalized speed
- RunSpeedEventKey.Broadcast(moveDirection.Length());
- }
+ Move();
+ }
+
+ private void Move()
+ {
+ // Character speed
+ moveDirectionEvent.TryReceive(out var moveDirection);
+
+ character.SetVelocity(moveDirection * MaxRunSpeed);
+
+ // Broadcast normalized speed
+ RunSpeedEventKey.Broadcast(moveDirection.Length());
}
}
diff --git a/samples/Templates/FirstPersonShooter/FirstPersonShooter/FirstPersonShooter.Game/Player/PlayerInput.cs b/samples/Templates/FirstPersonShooter/FirstPersonShooter/FirstPersonShooter.Game/Player/PlayerInput.cs
index 711b943ce6..eea8c06596 100644
--- a/samples/Templates/FirstPersonShooter/FirstPersonShooter/FirstPersonShooter.Game/Player/PlayerInput.cs
+++ b/samples/Templates/FirstPersonShooter/FirstPersonShooter/FirstPersonShooter.Game/Player/PlayerInput.cs
@@ -1,145 +1,138 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
-using System.Collections.Generic;
-using System.Linq;
+
+using FirstPersonShooter.Core;
using Stride.Core.Mathematics;
using Stride.Engine;
using Stride.Engine.Events;
using Stride.Input;
-using FirstPersonShooter.Core;
-namespace FirstPersonShooter.Player
+namespace FirstPersonShooter.Player;
+
+public class PlayerInput : SyncScript
{
- public class PlayerInput : SyncScript
- {
- ///
- /// Raised every frame with the intended direction of movement from the player.
- ///
- public static readonly EventKey MoveDirectionEventKey = new EventKey(); // This can be made non-static and require specific binding to the scripts instead
+ ///
+ /// Raised every frame with the intended direction of movement from the player.
+ ///
+ public static readonly EventKey MoveDirectionEventKey = new(); // This can be made non-static and require specific binding to the scripts instead
- public static readonly EventKey CameraDirectionEventKey = new EventKey(); // This can be made non-static and require specific binding to the scripts instead
+ public static readonly EventKey CameraDirectionEventKey = new(); // This can be made non-static and require specific binding to the scripts instead
- public static readonly EventKey ShootEventKey = new EventKey(); // This can be made non-static and require specific binding to the scripts instead
+ public static readonly EventKey ShootEventKey = new(); // This can be made non-static and require specific binding to the scripts instead
- public static readonly EventKey ReloadEventKey = new EventKey(); // This can be made non-static and require specific binding to the scripts instead
+ public static readonly EventKey ReloadEventKey = new(); // This can be made non-static and require specific binding to the scripts instead
- public float DeadZone { get; set; } = 0.25f;
+ public float DeadZone { get; set; } = 0.25f;
- public CameraComponent Camera { get; set; }
+ public CameraComponent Camera { get; set; }
- ///
- /// Multiplies move movement by this amount to apply aim rotations
- ///
- public float MouseSensitivity { get; set; } = 100.0f;
+ ///
+ /// Multiplies move movement by this amount to apply aim rotations
+ ///
+ public float MouseSensitivity { get; set; } = 100.0f;
- public List KeysLeft { get; } = new List();
+ public List KeysLeft { get; } = [];
- public List KeysRight { get; } = new List();
+ public List KeysRight { get; } = [];
- public List KeysUp { get; } = new List();
+ public List KeysUp { get; } = [];
- public List KeysDown { get; } = new List();
+ public List KeysDown { get; } = [];
- public List KeysReload { get; } = new List();
+ public List KeysReload { get; } = [];
- public PlayerInput()
+ public PlayerInput()
+ {
+ // Fix single frame input lag
+ Priority = -1000;
+ }
+
+ public override void Update()
+ {
+ // Character movement
+ // The character movement can be controlled by a game controller or a keyboard
+ // The character receives input in 3D world space, so that it can be controlled by an AI script as well
+ // For this reason we map the 2D user input to a 3D movement using the current camera
{
- // Fix single frame input lag
- Priority = -1000;
+ // Game controller: left stick
+ var moveDirection = Input.GetLeftThumbAny(DeadZone);
+ var isDeadZoneLeft = moveDirection.Length() < DeadZone;
+ if (isDeadZoneLeft)
+ moveDirection = Vector2.Zero;
+ else
+ moveDirection.Normalize();
+
+ // Keyboard
+ if (KeysLeft.Any(key => Input.IsKeyDown(key)))
+ moveDirection += -Vector2.UnitX;
+ if (KeysRight.Any(key => Input.IsKeyDown(key)))
+ moveDirection += +Vector2.UnitX;
+ if (KeysUp.Any(key => Input.IsKeyDown(key)))
+ moveDirection += +Vector2.UnitY;
+ if (KeysDown.Any(key => Input.IsKeyDown(key)))
+ moveDirection += -Vector2.UnitY;
+
+ // Broadcast the movement vector as a world-space Vector3 to allow characters to be controlled
+ var worldSpeed = (Camera != null)
+ ? Utils.LogicDirectionToWorldDirection(moveDirection, Camera, Vector3.UnitY)
+ : new Vector3(moveDirection.X, 0, moveDirection.Y); // If we don't have the correct camera attached we can send the directions anyway, but they probably won't match
+
+ MoveDirectionEventKey.Broadcast(worldSpeed);
}
- public override void Update()
+ // Camera rotation
+ // Camera rotation is ALWAYS in camera space, so we don't need to account for View or Projection matrices
{
- // Character movement
- // The character movement can be controlled by a game controller or a keyboard
- // The character receives input in 3D world space, so that it can be controlled by an AI script as well
- // For this reason we map the 2D user input to a 3D movement using the current camera
+ // Game controller: right stick
+ var cameraDirection = Input.GetRightThumbAny(DeadZone);
+ var isDeadZoneRight = cameraDirection.Length() < DeadZone;
+ if (isDeadZoneRight)
+ cameraDirection = Vector2.Zero;
+ else
+ cameraDirection.Normalize();
+
+ // Contrary to a mouse, driving camera rotation from a stick must be scaled by delta time.
+ // The amount of camera rotation with a stick is constant over time based on the tilt of the stick,
+ // Whereas mouse driven rotation is already constrained by time, it is driven by the difference in position from last *time* to this *time*.
+ cameraDirection *= (float)this.Game.UpdateTime.Elapsed.TotalSeconds;
+
+ // Mouse-based camera rotation.
+ // Only enabled after you click the screen to lock your cursor, pressing escape will cancel it.
+ if (Input.IsMouseButtonDown(MouseButton.Left))
{
- // Game controller: left stick
- var moveDirection = Input.GetLeftThumbAny(DeadZone);
- var isDeadZoneLeft = moveDirection.Length() < DeadZone;
- if (isDeadZoneLeft)
- moveDirection = Vector2.Zero;
- else
- moveDirection.Normalize();
-
- // Keyboard
- if (KeysLeft.Any(key => Input.IsKeyDown(key)))
- moveDirection += -Vector2.UnitX;
- if (KeysRight.Any(key => Input.IsKeyDown(key)))
- moveDirection += +Vector2.UnitX;
- if (KeysUp.Any(key => Input.IsKeyDown(key)))
- moveDirection += +Vector2.UnitY;
- if (KeysDown.Any(key => Input.IsKeyDown(key)))
- moveDirection += -Vector2.UnitY;
-
- // Broadcast the movement vector as a world-space Vector3 to allow characters to be controlled
- var worldSpeed = (Camera != null)
- ? Utils.LogicDirectionToWorldDirection(moveDirection, Camera, Vector3.UnitY)
- : new Vector3(moveDirection.X, 0, moveDirection.Y); // If we don't have the correct camera attached we can send the directions anyway, but they probably won't match
-
- MoveDirectionEventKey.Broadcast(worldSpeed);
+ Input.LockMousePosition(true);
+ Game.IsMouseVisible = false;
}
-
- // Camera rotation
- // Camera rotation is ALWAYS in camera space, so we don't need to account for View or Projection matrices
+ if (Input.IsKeyPressed(Keys.Escape))
{
- // Game controller: right stick
- var cameraDirection = Input.GetRightThumbAny(DeadZone);
- var isDeadZoneRight = cameraDirection.Length() < DeadZone;
- if (isDeadZoneRight)
- cameraDirection = Vector2.Zero;
- else
- cameraDirection.Normalize();
-
- // Contrary to a mouse, driving camera rotation from a stick must be scaled by delta time.
- // The amount of camera rotation with a stick is constant over time based on the tilt of the stick,
- // Whereas mouse driven rotation is already constrained by time, it is driven by the difference in position from last *time* to this *time*.
- cameraDirection *= (float)this.Game.UpdateTime.Elapsed.TotalSeconds;
-
- // Mouse-based camera rotation.
- // Only enabled after you click the screen to lock your cursor, pressing escape will cancel it.
- if (Input.IsMouseButtonDown(MouseButton.Left))
- {
- Input.LockMousePosition(true);
- Game.IsMouseVisible = false;
- }
- if (Input.IsKeyPressed(Keys.Escape))
- {
- Input.UnlockMousePosition();
- Game.IsMouseVisible = true;
- }
- if (Input.IsMousePositionLocked)
- {
- cameraDirection += new Vector2(Input.MouseDelta.X, -Input.MouseDelta.Y) * MouseSensitivity;
- }
-
- // Broadcast the camera direction directly, as a screen-space Vector2
- CameraDirectionEventKey.Broadcast(cameraDirection);
+ Input.UnlockMousePosition();
+ Game.IsMouseVisible = true;
}
-
+ if (Input.IsMousePositionLocked)
{
- // Controller: Right trigger
- // Mouse: Left button, Tap events
- var didShoot = Input.GetRightTriggerAny(0.2f) > 0.2f; // This will allow for continuous shooting
+ cameraDirection += new Vector2(Input.MouseDelta.X, -Input.MouseDelta.Y) * MouseSensitivity;
+ }
- if (Input.PointerEvents.Any(x => x.EventType == PointerEventType.Pressed))
- didShoot = true;
-
- if (Input.HasMouse && Input.IsMouseButtonDown(MouseButton.Left)) // This will allow for continuous shooting
- didShoot = true;
+ // Broadcast the camera direction directly, as a screen-space Vector2
+ CameraDirectionEventKey.Broadcast(cameraDirection);
+ }
- ShootEventKey.Broadcast(didShoot);
- }
+ {
+ // Controller: Right trigger
+ // Mouse: Left button, Tap events
+ var didShoot = Input.GetRightTriggerAny(0.2f) > 0.2f
+ || Input.PointerEvents.Any(x => x.EventType == PointerEventType.Pressed)
+ || Input.HasMouse && Input.IsMouseButtonDown(MouseButton.Left); // This will allow for continuous shooting
- {
- // Reload weapon
- var isReloading = Input.IsGamePadButtonDownAny(GamePadButton.X);
- if (KeysReload.Any(key => Input.IsKeyDown(key)))
- isReloading = true;
+ ShootEventKey.Broadcast(didShoot);
+ }
- ReloadEventKey.Broadcast(isReloading);
- }
+ {
+ // Reload weapon
+ var isReloading = Input.IsGamePadButtonDownAny(GamePadButton.X)
+ || KeysReload.Any(key => Input.IsKeyDown(key));
+
+ ReloadEventKey.Broadcast(isReloading);
}
}
}
diff --git a/samples/Templates/FirstPersonShooter/FirstPersonShooter/FirstPersonShooter.Game/Player/WeaponScript.cs b/samples/Templates/FirstPersonShooter/FirstPersonShooter/FirstPersonShooter.Game/Player/WeaponScript.cs
index 7b3b8e10ee..411a8f7c9b 100644
--- a/samples/Templates/FirstPersonShooter/FirstPersonShooter/FirstPersonShooter.Game/Player/WeaponScript.cs
+++ b/samples/Templates/FirstPersonShooter/FirstPersonShooter/FirstPersonShooter.Game/Player/WeaponScript.cs
@@ -1,123 +1,117 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
-using System;
-using System.Threading.Tasks;
+
using Stride.Core.Mathematics;
using Stride.Engine;
using Stride.Engine.Events;
using Stride.Physics;
using Stride.Rendering.Sprites;
-namespace FirstPersonShooter.Player
+namespace FirstPersonShooter.Player;
+
+public struct WeaponFiredResult
{
- public struct WeaponFiredResult
- {
- public bool DidFire;
- public bool DidHit;
- public HitResult HitResult;
- }
+ public bool DidFire;
+ public bool DidHit;
+ public HitResult HitResult;
+}
- public class WeaponScript : SyncScript
- {
- public static readonly EventKey WeaponFired = new EventKey();
+public class WeaponScript : SyncScript
+{
+ public static readonly EventKey WeaponFired = new();
- public static readonly EventKey IsReloading = new EventKey();
+ public static readonly EventKey IsReloading = new();
- private readonly EventReceiver shootEvent = new EventReceiver(PlayerInput.ShootEventKey);
+ private readonly EventReceiver shootEvent = new(PlayerInput.ShootEventKey);
- private readonly EventReceiver reloadEvent = new EventReceiver(PlayerInput.ReloadEventKey);
+ private readonly EventReceiver reloadEvent = new(PlayerInput.ReloadEventKey);
- public float MaxShootDistance { get; set; } = 100f;
+ public float MaxShootDistance { get; set; } = 100f;
- public float ShootImpulse { get; set; } = 5f;
+ public float ShootImpulse { get; set; } = 5f;
- public float Cooldown { get; set; } = 0.3f;
- private float cooldownRemaining = 0;
+ public float Cooldown { get; set; } = 0.3f;
+ private float cooldownRemaining;
- public float ReloadCooldown { get; set; } = 2.0f;
+ public float ReloadCooldown { get; set; } = 2.0f;
- public SpriteComponent RemainingBullets { get; set; }
- private int remainingBullets = 0;
+ public SpriteComponent RemainingBullets { get; set; }
+ private int remainingBullets;
- private void UpdateBulletsLED()
- {
- var spriteSheet = RemainingBullets?.SpriteProvider as SpriteFromSheet;
- if (spriteSheet != null)
- spriteSheet.CurrentFrame = remainingBullets;
- }
+ private void UpdateBulletsLED()
+ {
+ if (RemainingBullets?.SpriteProvider is SpriteFromSheet spriteSheet)
+ spriteSheet.CurrentFrame = remainingBullets;
+ }
- private void ReloadWeapon()
+ private void ReloadWeapon()
+ {
+ IsReloading.Broadcast(true);
+ Func reloadTask = async () =>
{
- IsReloading.Broadcast(true);
- Func reloadTask = async () =>
+ // Countdown
+ var secondsCountdown = cooldownRemaining = ReloadCooldown;
+ while (secondsCountdown > 0f)
{
- // Countdown
- var secondsCountdown = cooldownRemaining = ReloadCooldown;
- while (secondsCountdown > 0f)
- {
- await Script.NextFrame();
- secondsCountdown -= (float) Game.UpdateTime.Elapsed.TotalSeconds;
- }
-
- remainingBullets = 9;
- UpdateBulletsLED();
- };
-
- Script.AddTask(reloadTask);
- }
+ await Script.NextFrame();
+ secondsCountdown -= (float) Game.UpdateTime.Elapsed.TotalSeconds;
+ }
- ///
- /// Called on every frame update
- ///
- public override void Update()
- {
- bool didShoot;
- shootEvent.TryReceive(out didShoot);
+ remainingBullets = 9;
+ UpdateBulletsLED();
+ };
- bool didReload;
- reloadEvent.TryReceive(out didReload);
+ Script.AddTask(reloadTask);
+ }
- cooldownRemaining = (cooldownRemaining > 0) ? (cooldownRemaining - (float)this.Game.UpdateTime.Elapsed.TotalSeconds) : 0f;
- if (cooldownRemaining > 0)
- return; // Can't shoot yet
+ ///
+ /// Called on every frame update
+ ///
+ public override void Update()
+ {
+ shootEvent.TryReceive(out var didShoot);
- if ((remainingBullets == 0 && didShoot) || (remainingBullets < 9 && didReload))
- {
- ReloadWeapon();
- return;
- }
+ reloadEvent.TryReceive(out var didReload);
- if (!didShoot)
- return;
+ cooldownRemaining = (cooldownRemaining > 0) ? (cooldownRemaining - (float)this.Game.UpdateTime.Elapsed.TotalSeconds) : 0f;
+ if (cooldownRemaining > 0)
+ return; // Can't shoot yet
- remainingBullets--;
- UpdateBulletsLED();
+ if ((remainingBullets == 0 && didShoot) || (remainingBullets < 9 && didReload))
+ {
+ ReloadWeapon();
+ return;
+ }
+
+ if (!didShoot)
+ return;
- cooldownRemaining = Cooldown;
+ remainingBullets--;
+ UpdateBulletsLED();
- var raycastStart = Entity.Transform.WorldMatrix.TranslationVector;
- var forward = Entity.Transform.WorldMatrix.Forward;
- var raycastEnd = raycastStart + forward * MaxShootDistance;
+ cooldownRemaining = Cooldown;
- var result = this.GetSimulation().Raycast(raycastStart, raycastEnd);
+ var raycastStart = Entity.Transform.WorldMatrix.TranslationVector;
+ var forward = Entity.Transform.WorldMatrix.Forward;
+ var raycastEnd = raycastStart + forward * MaxShootDistance;
- var weaponFired = new WeaponFiredResult {HitResult = result, DidFire = true, DidHit = false };
+ var result = this.GetSimulation().Raycast(raycastStart, raycastEnd);
- if (result.Succeeded && result.Collider != null)
+ var weaponFired = new WeaponFiredResult {HitResult = result, DidFire = true, DidHit = false };
+
+ if (result is { Succeeded: true, Collider: not null })
+ {
+ weaponFired.DidHit = true;
+
+ if (result.Collider is RigidbodyComponent rigidBody)
{
- weaponFired.DidHit = true;
-
- var rigidBody = result.Collider as RigidbodyComponent;
- if (rigidBody != null)
- {
- rigidBody.Activate();
- rigidBody.ApplyImpulse(forward * ShootImpulse);
- rigidBody.ApplyTorqueImpulse(forward * ShootImpulse + new Vector3(0, 1, 0));
- }
+ rigidBody.Activate();
+ rigidBody.ApplyImpulse(forward * ShootImpulse);
+ rigidBody.ApplyTorqueImpulse(forward * ShootImpulse + new Vector3(0, 1, 0));
}
-
- // Broadcast the fire event
- WeaponFired.Broadcast( weaponFired );
}
+
+ // Broadcast the fire event
+ WeaponFired.Broadcast( weaponFired );
}
}
diff --git a/samples/Templates/FirstPersonShooter/FirstPersonShooter/FirstPersonShooter.Game/Trigger/TriggerEvent.cs b/samples/Templates/FirstPersonShooter/FirstPersonShooter/FirstPersonShooter.Game/Trigger/TriggerEvent.cs
index d9dcf8358d..43e46f602e 100644
--- a/samples/Templates/FirstPersonShooter/FirstPersonShooter/FirstPersonShooter.Game/Trigger/TriggerEvent.cs
+++ b/samples/Templates/FirstPersonShooter/FirstPersonShooter/FirstPersonShooter.Game/Trigger/TriggerEvent.cs
@@ -1,53 +1,53 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
+
using Stride.Core;
using Stride.Core.Annotations;
using Stride.Core.Mathematics;
using Stride.Engine;
-namespace FirstPersonShooter.Trigger
+namespace FirstPersonShooter.Trigger;
+
+[DataContract("TriggerEvent")]
+public class TriggerEvent
{
- [DataContract("TriggerEvent")]
- public class TriggerEvent
- {
- [DataMember(10)]
- [Display("Name")]
- [InlineProperty]
- public string Name { get; set; }
+ [DataMember(10)]
+ [Display("Name")]
+ [InlineProperty]
+ public string Name { get; set; }
- [DataMember(20)]
- [Display("Source")]
- public Prefab SourcePrefab { get; set; }
+ [DataMember(20)]
+ [Display("Source")]
+ public Prefab SourcePrefab { get; set; }
- [DataMember(30)]
- public bool FollowEntity { get; set; }
+ [DataMember(30)]
+ public bool FollowEntity { get; set; }
- [DataMember(40)]
- [Display("Duration")]
- public float Duration { get; set; } = 3f;
+ [DataMember(40)]
+ [Display("Duration")]
+ public float Duration { get; set; } = 3f;
- [DataMemberIgnore]
- public Matrix LocalMatrix = Matrix.Identity;
+ [DataMemberIgnore]
+ public Matrix LocalMatrix = Matrix.Identity;
- [DataMember(110)]
- [Display("Local translation")]
- public Vector3 Position { get { return translation; } set { translation = value; UpdateMatrix(); } }
+ [DataMember(110)]
+ [Display("Local translation")]
+ public Vector3 Position { get { return translation; } set { translation = value; UpdateMatrix(); } }
- [DataMember(120)]
- [Display("Local rotation")]
- public Quaternion Rotation { get { return rotation; } set { rotation = value; UpdateMatrix(); } }
+ [DataMember(120)]
+ [Display("Local rotation")]
+ public Quaternion Rotation { get { return rotation; } set { rotation = value; UpdateMatrix(); } }
- [DataMember(130)]
- [Display("Local scale")]
- public Vector3 Scale { get { return scaling; } set { scaling = value; UpdateMatrix(); } }
+ [DataMember(130)]
+ [Display("Local scale")]
+ public Vector3 Scale { get { return scaling; } set { scaling = value; UpdateMatrix(); } }
- private Vector3 translation = Vector3.Zero;
- private Vector3 scaling = Vector3.One;
- private Quaternion rotation = Quaternion.Identity;
+ private Vector3 translation = Vector3.Zero;
+ private Vector3 scaling = Vector3.One;
+ private Quaternion rotation = Quaternion.Identity;
- private void UpdateMatrix()
- {
- Matrix.Transformation(ref scaling, ref rotation, ref translation, out LocalMatrix);
- }
+ private void UpdateMatrix()
+ {
+ Matrix.Transformation(ref scaling, ref rotation, ref translation, out LocalMatrix);
}
}
diff --git a/samples/Templates/FirstPersonShooter/FirstPersonShooter/FirstPersonShooter.Game/Trigger/TriggerGroup.cs b/samples/Templates/FirstPersonShooter/FirstPersonShooter/FirstPersonShooter.Game/Trigger/TriggerGroup.cs
index a99f61f0b8..ec97f5bc10 100644
--- a/samples/Templates/FirstPersonShooter/FirstPersonShooter/FirstPersonShooter.Game/Trigger/TriggerGroup.cs
+++ b/samples/Templates/FirstPersonShooter/FirstPersonShooter/FirstPersonShooter.Game/Trigger/TriggerGroup.cs
@@ -1,32 +1,30 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
-using System;
-using System.Collections.Generic;
+
using Stride.Core;
-namespace FirstPersonShooter.Trigger
+namespace FirstPersonShooter.Trigger;
+
+[DataContract("TriggerGroup")]
+public class TriggerGroup
{
- [DataContract("TriggerGroup")]
- public class TriggerGroup
- {
- [DataMember(10)]
- [Display("Name")]
- public string Name { get; set; } = "NewTriggerGroup";
+ [DataMember(10)]
+ [Display("Name")]
+ public string Name { get; set; } = "NewTriggerGroup";
- [DataMember(20)]
- [Display("Events")]
- public List TriggerEvents { get; } = new List();
+ [DataMember(20)]
+ [Display("Events")]
+ public List TriggerEvents { get; } = [];
- public TriggerEvent Find(string name) => Find(x => x.Name.Equals(name));
+ public TriggerEvent Find(string name) => Find(x => x.Name.Equals(name));
- public List FindAll(Predicate match)
- {
- return TriggerEvents.FindAll(match);
- }
+ public List FindAll(Predicate match)
+ {
+ return TriggerEvents.FindAll(match);
+ }
- public TriggerEvent Find(Predicate match)
- {
- return TriggerEvents.Find(match);
- }
+ public TriggerEvent Find(Predicate match)
+ {
+ return TriggerEvents.Find(match);
}
}
diff --git a/samples/Templates/FirstPersonShooter/FirstPersonShooter/FirstPersonShooter.Game/Trigger/TriggerGroupException.cs b/samples/Templates/FirstPersonShooter/FirstPersonShooter/FirstPersonShooter.Game/Trigger/TriggerGroupException.cs
index fbac47f317..33006eeff7 100644
--- a/samples/Templates/FirstPersonShooter/FirstPersonShooter/FirstPersonShooter.Game/Trigger/TriggerGroupException.cs
+++ b/samples/Templates/FirstPersonShooter/FirstPersonShooter/FirstPersonShooter.Game/Trigger/TriggerGroupException.cs
@@ -1,11 +1,9 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
-using System;
-namespace FirstPersonShooter.Trigger
+namespace FirstPersonShooter.Trigger;
+
+public class TriggerGroupException : Exception
{
- public class TriggerGroupException : Exception
- {
- public TriggerGroupException(string ex) : base(ex) { }
- }
+ public TriggerGroupException(string ex) : base(ex) { }
}
diff --git a/samples/Templates/FirstPersonShooter/FirstPersonShooter/FirstPersonShooter.Game/Trigger/TriggerScript.cs b/samples/Templates/FirstPersonShooter/FirstPersonShooter/FirstPersonShooter.Game/Trigger/TriggerScript.cs
index ee6bd968ab..a57ce0d72c 100644
--- a/samples/Templates/FirstPersonShooter/FirstPersonShooter/FirstPersonShooter.Game/Trigger/TriggerScript.cs
+++ b/samples/Templates/FirstPersonShooter/FirstPersonShooter/FirstPersonShooter.Game/Trigger/TriggerScript.cs
@@ -1,85 +1,83 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
-using System;
-using System.Threading.Tasks;
+
using FirstPersonShooter.Trigger;
using Stride.Core;
using Stride.Core.Mathematics;
using Stride.Engine;
-namespace FirstPersonShooter
+namespace FirstPersonShooter;
+
+///
+/// A script which spawns a timed instance from a source prefab.
+///
+public abstract class TriggerScript : AsyncScript
{
- ///
- /// A script which spawns a timed instance from a source prefab.
- ///
- public abstract class TriggerScript : AsyncScript
+ [DataMember(10)]
+ [Display("TriggerGroup")]
+ public TriggerGroup TriggerGroup { get; set; } = new();
+
+ protected void SpawnEvent(string eventName, Entity attachEntity, Matrix transformMatrix)
{
- [DataMember(10)]
- [Display("TriggerGroup")]
- public TriggerGroup TriggerGroup { get; set; } = new TriggerGroup();
+ var TriggerEvent = TriggerGroup.Find(eventName);
+ if (TriggerEvent == null)
+ throw new TriggerGroupException($"Trigger event {eventName} was not found!");
- protected void SpawnEvent(string eventName, Entity attachEntity, Matrix transformMatrix)
- {
- var TriggerEvent = TriggerGroup.Find(eventName);
- if (TriggerEvent == null)
- throw new TriggerGroupException($"Trigger event {eventName} was not found!");
+ SpawnInstance(TriggerEvent.SourcePrefab, attachEntity, TriggerEvent.Duration, TriggerEvent.LocalMatrix * transformMatrix);
+ }
- SpawnInstance(TriggerEvent.SourcePrefab, attachEntity, TriggerEvent.Duration, TriggerEvent.LocalMatrix * transformMatrix);
- }
+ protected void SpawnInstance(Prefab source, Entity attachEntity, float timeout, Matrix localMatrix)
+ {
+ if (source == null)
+ return;
- protected void SpawnInstance(Prefab source, Entity attachEntity, float timeout, Matrix localMatrix)
+ Func spawnTask = async () =>
{
- if (source == null)
- return;
+ // Clone
+ var spawnedEntities = source.Instantiate();
- Func spawnTask = async () =>
+ // Add
+ foreach (var prefabEntity in spawnedEntities)
{
- // Clone
- var spawnedEntities = source.Instantiate();
+ prefabEntity.Transform.UpdateLocalMatrix();
+ var entityMatrix = prefabEntity.Transform.LocalMatrix * localMatrix;
+ entityMatrix.Decompose(out prefabEntity.Transform.Scale, out prefabEntity.Transform.Rotation, out prefabEntity.Transform.Position);
- // Add
- foreach (var prefabEntity in spawnedEntities)
+ if (attachEntity != null)
{
- prefabEntity.Transform.UpdateLocalMatrix();
- var entityMatrix = prefabEntity.Transform.LocalMatrix * localMatrix;
- entityMatrix.Decompose(out prefabEntity.Transform.Scale, out prefabEntity.Transform.Rotation, out prefabEntity.Transform.Position);
-
- if (attachEntity != null)
- {
- attachEntity.AddChild(prefabEntity);
- }
- else
- {
- SceneSystem.SceneInstance.RootScene.Entities.Add(prefabEntity);
- }
+ attachEntity.AddChild(prefabEntity);
}
-
- // Countdown
- var secondsCountdown = timeout;
- while (secondsCountdown > 0f)
+ else
{
- await Script.NextFrame();
- secondsCountdown -= (float)Game.UpdateTime.Elapsed.TotalSeconds;
+ SceneSystem.SceneInstance.RootScene.Entities.Add(prefabEntity);
}
+ }
+
+ // Countdown
+ var secondsCountdown = timeout;
+ while (secondsCountdown > 0f)
+ {
+ await Script.NextFrame();
+ secondsCountdown -= (float)Game.UpdateTime.Elapsed.TotalSeconds;
+ }
- // Remove
- foreach (var clonedEntity in spawnedEntities)
+ // Remove
+ foreach (var clonedEntity in spawnedEntities)
+ {
+ if (attachEntity != null)
+ {
+ attachEntity.RemoveChild(clonedEntity);
+ }
+ else
{
- if (attachEntity != null)
- {
- attachEntity.RemoveChild(clonedEntity);
- }
- else
- {
- SceneSystem.SceneInstance.RootScene.Entities.Remove(clonedEntity);
- }
+ SceneSystem.SceneInstance.RootScene.Entities.Remove(clonedEntity);
}
+ }
- // Cleanup
- spawnedEntities.Clear();
- };
+ // Cleanup
+ spawnedEntities.Clear();
+ };
- Script.AddTask(spawnTask);
- }
+ Script.AddTask(spawnTask);
}
}
diff --git a/samples/Templates/FirstPersonShooter/FirstPersonShooter/FirstPersonShooter.Windows/FirstPersonShooter.Windows.csproj b/samples/Templates/FirstPersonShooter/FirstPersonShooter/FirstPersonShooter.Windows/FirstPersonShooter.Windows.csproj
index 0642bec585..866d120f32 100644
--- a/samples/Templates/FirstPersonShooter/FirstPersonShooter/FirstPersonShooter.Windows/FirstPersonShooter.Windows.csproj
+++ b/samples/Templates/FirstPersonShooter/FirstPersonShooter/FirstPersonShooter.Windows/FirstPersonShooter.Windows.csproj
@@ -7,6 +7,8 @@
..\Bin\Windows\$(Configuration)\
false
STRIDE_PLATFORM_DESKTOP
+ enable
+ latest
$(MSBuildThisFileDirectory)..\FirstPersonShooter.sdpkg
diff --git a/samples/Templates/FirstPersonShooter/FirstPersonShooter/FirstPersonShooter.Windows/Resources/GameIcon.ico b/samples/Templates/FirstPersonShooter/FirstPersonShooter/FirstPersonShooter.Windows/Resources/GameIcon.ico
new file mode 100644
index 0000000000..371291c924
Binary files /dev/null and b/samples/Templates/FirstPersonShooter/FirstPersonShooter/FirstPersonShooter.Windows/Resources/GameIcon.ico differ
diff --git a/samples/Templates/ThirdPersonPlatformer/ThirdPersonPlatformer/ThirdPersonPlatformer.Game/BasicCameraController.cs b/samples/Templates/ThirdPersonPlatformer/ThirdPersonPlatformer/ThirdPersonPlatformer.Game/BasicCameraController.cs
index d27a23eb48..00f94360f3 100644
--- a/samples/Templates/ThirdPersonPlatformer/ThirdPersonPlatformer/ThirdPersonPlatformer.Game/BasicCameraController.cs
+++ b/samples/Templates/ThirdPersonPlatformer/ThirdPersonPlatformer/ThirdPersonPlatformer.Game/BasicCameraController.cs
@@ -1,188 +1,187 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
-using System;
+
using Stride.Core;
using Stride.Core.Mathematics;
using Stride.Engine;
using Stride.Input;
-namespace ThirdPersonPlatformer
+namespace ThirdPersonPlatformer;
+
+///
+/// A script that allows to move and rotate an entity through keyboard, mouse and touch input to provide basic camera navigation.
+///
+///
+/// The entity can be moved using W, A, S, D, Q and E, arrow keys or dragging/scaling using multi-touch.
+/// Rotation is achieved using the Numpad, the mouse while holding the right mouse button, or dragging using single-touch.
+///
+public class BasicCameraController : SyncScript
{
- ///
- /// A script that allows to move and rotate an entity through keyboard, mouse and touch input to provide basic camera navigation.
- ///
- ///
- /// The entity can be moved using W, A, S, D, Q and E, arrow keys or dragging/scaling using multi-touch.
- /// Rotation is achieved using the Numpad, the mouse while holding the right mouse button, or dragging using single-touch.
- ///
- public class BasicCameraController : SyncScript
- {
- private const float MaximumPitch = MathUtil.PiOverTwo * 0.99f;
+ private const float MaximumPitch = MathUtil.PiOverTwo * 0.99f;
- private Vector3 upVector;
- private Vector3 translation;
- private float yaw;
- private float pitch;
+ private Vector3 upVector;
+ private Vector3 translation;
+ private float yaw;
+ private float pitch;
- public Vector3 KeyboardMovementSpeed { get; set; } = new Vector3(5.0f);
+ public Vector3 KeyboardMovementSpeed { get; set; } = new(5.0f);
- public Vector3 TouchMovementSpeed { get; set; } = new Vector3(40, 40, 20);
+ public Vector3 TouchMovementSpeed { get; set; } = new(40, 40, 20);
- public float SpeedFactor { get; set; } = 5.0f;
+ public float SpeedFactor { get; set; } = 5.0f;
- public Vector2 KeyboardRotationSpeed { get; set; } = new Vector2(3.0f);
+ public Vector2 KeyboardRotationSpeed { get; set; } = new(3.0f);
- public Vector2 MouseRotationSpeed { get; set; } = new Vector2(90.0f, 60.0f);
+ public Vector2 MouseRotationSpeed { get; set; } = new(90.0f, 60.0f);
- public Vector2 TouchRotationSpeed { get; set; } = new Vector2(60.0f, 40.0f);
+ public Vector2 TouchRotationSpeed { get; set; } = new(60.0f, 40.0f);
- public override void Start()
- {
- base.Start();
+ public override void Start()
+ {
+ base.Start();
- // Default up-direction
- upVector = Vector3.UnitY;
+ // Default up-direction
+ upVector = Vector3.UnitY;
- // Configure touch input
- if (!Platform.IsWindowsDesktop)
- {
- Input.Gestures.Add(new GestureConfigDrag());
- Input.Gestures.Add(new GestureConfigComposite());
- }
+ // Configure touch input
+ if (!Platform.IsWindowsDesktop)
+ {
+ Input.Gestures.Add(new GestureConfigDrag());
+ Input.Gestures.Add(new GestureConfigComposite());
}
+ }
- public override void Update()
+ public override void Update()
+ {
+ ProcessInput();
+ UpdateTransform();
+ }
+
+ private void ProcessInput()
+ {
+ translation = Vector3.Zero;
+ yaw = 0;
+ pitch = 0;
+
+ // Move with keyboard
+ if (Input.IsKeyDown(Keys.W) || Input.IsKeyDown(Keys.Up))
{
- ProcessInput();
- UpdateTransform();
+ translation.Z = -KeyboardMovementSpeed.Z;
}
-
- private void ProcessInput()
+ else if (Input.IsKeyDown(Keys.S) || Input.IsKeyDown(Keys.Down))
{
- translation = Vector3.Zero;
- yaw = 0;
- pitch = 0;
-
- // Move with keyboard
- if (Input.IsKeyDown(Keys.W) || Input.IsKeyDown(Keys.Up))
- {
- translation.Z = -KeyboardMovementSpeed.Z;
- }
- else if (Input.IsKeyDown(Keys.S) || Input.IsKeyDown(Keys.Down))
- {
- translation.Z = KeyboardMovementSpeed.Z;
- }
+ translation.Z = KeyboardMovementSpeed.Z;
+ }
- if (Input.IsKeyDown(Keys.A) || Input.IsKeyDown(Keys.Left))
- {
- translation.X = -KeyboardMovementSpeed.X;
- }
- else if (Input.IsKeyDown(Keys.D) || Input.IsKeyDown(Keys.Right))
- {
- translation.X = KeyboardMovementSpeed.X;
- }
+ if (Input.IsKeyDown(Keys.A) || Input.IsKeyDown(Keys.Left))
+ {
+ translation.X = -KeyboardMovementSpeed.X;
+ }
+ else if (Input.IsKeyDown(Keys.D) || Input.IsKeyDown(Keys.Right))
+ {
+ translation.X = KeyboardMovementSpeed.X;
+ }
- if (Input.IsKeyDown(Keys.Q))
- {
- translation.Y = -KeyboardMovementSpeed.Y;
- }
- else if (Input.IsKeyDown(Keys.E))
- {
- translation.Y = KeyboardMovementSpeed.Y;
- }
+ if (Input.IsKeyDown(Keys.Q))
+ {
+ translation.Y = -KeyboardMovementSpeed.Y;
+ }
+ else if (Input.IsKeyDown(Keys.E))
+ {
+ translation.Y = KeyboardMovementSpeed.Y;
+ }
- // Alternative translation speed
- if (Input.IsKeyDown(Keys.LeftShift) || Input.IsKeyDown(Keys.RightShift))
- {
- translation *= SpeedFactor;
- }
+ // Alternative translation speed
+ if (Input.IsKeyDown(Keys.LeftShift) || Input.IsKeyDown(Keys.RightShift))
+ {
+ translation *= SpeedFactor;
+ }
- // Rotate with keyboard
- if (Input.IsKeyDown(Keys.NumPad2))
- {
- pitch = KeyboardRotationSpeed.X;
- }
- else if (Input.IsKeyDown(Keys.NumPad8))
- {
- pitch = -KeyboardRotationSpeed.X;
- }
+ // Rotate with keyboard
+ if (Input.IsKeyDown(Keys.NumPad2))
+ {
+ pitch = KeyboardRotationSpeed.X;
+ }
+ else if (Input.IsKeyDown(Keys.NumPad8))
+ {
+ pitch = -KeyboardRotationSpeed.X;
+ }
- if (Input.IsKeyDown(Keys.NumPad4))
- {
- yaw = KeyboardRotationSpeed.Y;
- }
- else if (Input.IsKeyDown(Keys.NumPad6))
- {
- yaw = -KeyboardRotationSpeed.Y;
- }
+ if (Input.IsKeyDown(Keys.NumPad4))
+ {
+ yaw = KeyboardRotationSpeed.Y;
+ }
+ else if (Input.IsKeyDown(Keys.NumPad6))
+ {
+ yaw = -KeyboardRotationSpeed.Y;
+ }
- // Rotate with mouse
- if (Input.IsMouseButtonDown(MouseButton.Right))
- {
- Input.LockMousePosition();
- Game.IsMouseVisible = false;
+ // Rotate with mouse
+ if (Input.IsMouseButtonDown(MouseButton.Right))
+ {
+ Input.LockMousePosition();
+ Game.IsMouseVisible = false;
- yaw = -Input.MouseDelta.X * MouseRotationSpeed.X;
- pitch = -Input.MouseDelta.Y * MouseRotationSpeed.Y;
- }
- else
- {
- Input.UnlockMousePosition();
- Game.IsMouseVisible = true;
- }
+ yaw = -Input.MouseDelta.X * MouseRotationSpeed.X;
+ pitch = -Input.MouseDelta.Y * MouseRotationSpeed.Y;
+ }
+ else
+ {
+ Input.UnlockMousePosition();
+ Game.IsMouseVisible = true;
+ }
- // Handle gestures
- foreach (var gestureEvent in Input.GestureEvents)
+ // Handle gestures
+ foreach (var gestureEvent in Input.GestureEvents)
+ {
+ switch (gestureEvent.Type)
{
- switch (gestureEvent.Type)
- {
- // Rotate by dragging
- case GestureType.Drag:
- var drag = (GestureEventDrag)gestureEvent;
- var dragDistance = drag.DeltaTranslation;
- yaw = -dragDistance.X * TouchRotationSpeed.X;
- pitch = -dragDistance.Y * TouchRotationSpeed.Y;
- break;
-
- // Move along z-axis by scaling and in xy-plane by multi-touch dragging
- case GestureType.Composite:
- var composite = (GestureEventComposite)gestureEvent;
- translation.X = -composite.DeltaTranslation.X * TouchMovementSpeed.X;
- translation.Y = -composite.DeltaTranslation.Y * TouchMovementSpeed.Y;
- translation.Z = -(float)Math.Log(composite.DeltaScale + 1) * TouchMovementSpeed.Z;
- break;
- }
+ // Rotate by dragging
+ case GestureType.Drag:
+ var drag = (GestureEventDrag)gestureEvent;
+ var dragDistance = drag.DeltaTranslation;
+ yaw = -dragDistance.X * TouchRotationSpeed.X;
+ pitch = -dragDistance.Y * TouchRotationSpeed.Y;
+ break;
+
+ // Move along z-axis by scaling and in xy-plane by multi-touch dragging
+ case GestureType.Composite:
+ var composite = (GestureEventComposite)gestureEvent;
+ translation.X = -composite.DeltaTranslation.X * TouchMovementSpeed.X;
+ translation.Y = -composite.DeltaTranslation.Y * TouchMovementSpeed.Y;
+ translation.Z = -(float)Math.Log(composite.DeltaScale + 1) * TouchMovementSpeed.Z;
+ break;
}
}
+ }
- private void UpdateTransform()
- {
- var elapsedTime = (float)Game.UpdateTime.Elapsed.TotalSeconds;
+ private void UpdateTransform()
+ {
+ var elapsedTime = (float)Game.UpdateTime.Elapsed.TotalSeconds;
- translation *= elapsedTime;
- yaw *= elapsedTime;
- pitch *= elapsedTime;
+ translation *= elapsedTime;
+ yaw *= elapsedTime;
+ pitch *= elapsedTime;
- // Get the local coordinate system
- var rotation = Matrix.RotationQuaternion(Entity.Transform.Rotation);
+ // Get the local coordinate system
+ var rotation = Matrix.RotationQuaternion(Entity.Transform.Rotation);
- // Enforce the global up-vector by adjusting the local x-axis
- var right = Vector3.Cross(rotation.Forward, upVector);
- var up = Vector3.Cross(right, rotation.Forward);
+ // Enforce the global up-vector by adjusting the local x-axis
+ var right = Vector3.Cross(rotation.Forward, upVector);
+ var up = Vector3.Cross(right, rotation.Forward);
- // Stabilize
- right.Normalize();
- up.Normalize();
+ // Stabilize
+ right.Normalize();
+ up.Normalize();
- // Adjust pitch. Prevent it from exceeding up and down facing. Stabilize edge cases.
- var currentPitch = MathUtil.PiOverTwo - (float)Math.Acos(Vector3.Dot(rotation.Forward, upVector));
- pitch = MathUtil.Clamp(currentPitch + pitch, -MaximumPitch, MaximumPitch) - currentPitch;
+ // Adjust pitch. Prevent it from exceeding up and down facing. Stabilize edge cases.
+ var currentPitch = MathUtil.PiOverTwo - (float)Math.Acos(Vector3.Dot(rotation.Forward, upVector));
+ pitch = MathUtil.Clamp(currentPitch + pitch, -MaximumPitch, MaximumPitch) - currentPitch;
- // Move in local coordinates
- Entity.Transform.Position += Vector3.TransformCoordinate(translation, rotation);
+ // Move in local coordinates
+ Entity.Transform.Position += Vector3.TransformCoordinate(translation, rotation);
- // Yaw around global up-vector, pitch and roll in local space
- Entity.Transform.Rotation *= Quaternion.RotationAxis(right, pitch) * Quaternion.RotationAxis(upVector, yaw);
- }
+ // Yaw around global up-vector, pitch and roll in local space
+ Entity.Transform.Rotation *= Quaternion.RotationAxis(right, pitch) * Quaternion.RotationAxis(upVector, yaw);
}
}
diff --git a/samples/Templates/ThirdPersonPlatformer/ThirdPersonPlatformer/ThirdPersonPlatformer.Game/Camera/ThirdPersonCamera.cs b/samples/Templates/ThirdPersonPlatformer/ThirdPersonPlatformer/ThirdPersonPlatformer.Game/Camera/ThirdPersonCamera.cs
index a6a9851d85..0ea7c4083f 100644
--- a/samples/Templates/ThirdPersonPlatformer/ThirdPersonPlatformer/ThirdPersonPlatformer.Game/Camera/ThirdPersonCamera.cs
+++ b/samples/Templates/ThirdPersonPlatformer/ThirdPersonPlatformer/ThirdPersonPlatformer.Game/Camera/ThirdPersonCamera.cs
@@ -1,158 +1,155 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
-using System;
-using System.Collections.Generic;
+
using Stride.Core.Mathematics;
using Stride.Engine;
using Stride.Engine.Events;
using Stride.Physics;
using ThirdPersonPlatformer.Player;
-namespace ThirdPersonPlatformer.Camera
+namespace ThirdPersonPlatformer.Camera;
+
+public class ThirdPersonCamera : SyncScript
{
- public class ThirdPersonCamera : SyncScript
+ ///
+ /// Starting camera distance from the target
+ ///
+ public float DefaultDistance { get; set; } = 6f;
+
+ ///
+ /// Minimum camera distance from the target
+ ///
+ public float MinimumDistance { get; set; } = 0.4f;
+
+ ///
+ /// Cone radius for the collision cone used to hold the camera
+ ///
+ public float ConeRadius { get; set; } = 1.25f;
+
+ ///
+ /// Check to invert the horizontal camera movement
+ ///
+ public bool InvertX { get; set; } = false;
+
+ ///
+ /// Minimum camera distance from the target
+ ///
+ public float MinVerticalAngle { get; set; } = -20f;
+
+ ///
+ /// Maximum camera distance from the target
+ ///
+ public float MaxVerticalAngle { get; set; } = 70f;
+
+ ///
+ /// Check to invert the vertical camera movement
+ ///
+ public bool InvertY { get; set; } = false;
+
+ ///
+ /// Maximum rotation speed for the camera around the target in degrees per second
+ ///
+ public float RotationSpeed { get; set; } = 360f;
+
+ ///
+ /// Maximum rotation speed for the camera around the target in degrees per second
+ ///
+ public float VerticalSpeed { get; set; } = 65f;
+
+ private Vector3 cameraRotationXYZ = new(-20, 45, 0);
+ private Vector3 targetRotationXYZ = new(-20, 45, 0);
+ private readonly EventReceiver cameraDirectionEvent = new(PlayerInput.CameraDirectionEventKey);
+ private List resultsOutput;
+ private ConeColliderShape coneShape;
+
+ ///
+ /// Raycast between the camera and its target. The script assumes the camera is a child entity of its target.
+ ///
+ private void UpdateCameraRaycast()
{
- ///
- /// Starting camera distance from the target
- ///
- public float DefaultDistance { get; set; } = 6f;
-
- ///
- /// Minimum camera distance from the target
- ///
- public float MinimumDistance { get; set; } = 0.4f;
-
- ///
- /// Cone radius for the collision cone used to hold the camera
- ///
- public float ConeRadius { get; set; } = 1.25f;
-
- ///
- /// Check to invert the horizontal camera movement
- ///
- public bool InvertX { get; set; } = false;
-
- ///
- /// Minimum camera distance from the target
- ///
- public float MinVerticalAngle { get; set; } = -20f;
-
- ///
- /// Maximum camera distance from the target
- ///
- public float MaxVerticalAngle { get; set; } = 70f;
-
- ///
- /// Check to invert the vertical camera movement
- ///
- public bool InvertY { get; set; } = false;
-
- ///
- /// Maximum rotation speed for the camera around the target in degrees per second
- ///
- public float RotationSpeed { get; set; } = 360f;
-
- ///
- /// Maximum rotation speed for the camera around the target in degrees per second
- ///
- public float VerticalSpeed { get; set; } = 65f;
-
- private Vector3 cameraRotationXYZ = new Vector3(-20, 45, 0);
- private Vector3 targetRotationXYZ = new Vector3(-20, 45, 0);
- private readonly EventReceiver cameraDirectionEvent = new EventReceiver(PlayerInput.CameraDirectionEventKey);
- private List resultsOutput;
- private ConeColliderShape coneShape;
-
- ///
- /// Raycast between the camera and its target. The script assumes the camera is a child entity of its target.
- ///
- private void UpdateCameraRaycast()
- {
- var maxLength = DefaultDistance;
- var cameraVector = new Vector3(0, 0, DefaultDistance);
- Entity.GetParent().Transform.Rotation.Rotate(ref cameraVector);
+ var maxLength = DefaultDistance;
+ var cameraVector = new Vector3(0, 0, DefaultDistance);
+ Entity.GetParent().Transform.Rotation.Rotate(ref cameraVector);
- if (ConeRadius <= 0)
+ if (ConeRadius <= 0)
+ {
+ // If the cone radius
+ var raycastStart = Entity.GetParent().Transform.WorldMatrix.TranslationVector;
+ var hitResult = this.GetSimulation().Raycast(raycastStart, raycastStart + cameraVector);
+ if (hitResult.Succeeded)
{
- // If the cone radius
- var raycastStart = Entity.GetParent().Transform.WorldMatrix.TranslationVector;
- var hitResult = this.GetSimulation().Raycast(raycastStart, raycastStart + cameraVector);
- if (hitResult.Succeeded)
- {
- maxLength = Math.Min(DefaultDistance, (raycastStart - hitResult.Point).Length());
- }
+ maxLength = Math.Min(DefaultDistance, (raycastStart - hitResult.Point).Length());
}
- else
- {
- // If the cone radius is > 0 we will sweep an actual cone and see where it collides
- var fromMatrix = Matrix.Translation(0, 0, -DefaultDistance * 0.5f) *
- Entity.GetParent().Transform.WorldMatrix;
- var toMatrix = Matrix.Translation(0, 0, DefaultDistance * 0.5f) *
- Entity.GetParent().Transform.WorldMatrix;
+ }
+ else
+ {
+ // If the cone radius is > 0 we will sweep an actual cone and see where it collides
+ var fromMatrix = Matrix.Translation(0, 0, -DefaultDistance * 0.5f) *
+ Entity.GetParent().Transform.WorldMatrix;
+ var toMatrix = Matrix.Translation(0, 0, DefaultDistance * 0.5f) *
+ Entity.GetParent().Transform.WorldMatrix;
- resultsOutput.Clear();
- var cfg = CollisionFilterGroups.DefaultFilter;
- var cfgf = CollisionFilterGroupFlags.DefaultFilter; // Intentionally ignoring the CollisionFilterGroupFlags.StaticFilter; to avoid collision with poles
+ resultsOutput.Clear();
+ const CollisionFilterGroups cfg = CollisionFilterGroups.DefaultFilter;
+ const CollisionFilterGroupFlags cfgf = CollisionFilterGroupFlags.DefaultFilter; // Intentionally ignoring the CollisionFilterGroupFlags.StaticFilter; to avoid collision with poles
- this.GetSimulation().ShapeSweepPenetrating(coneShape, fromMatrix, toMatrix, resultsOutput, cfg, cfgf);
+ this.GetSimulation().ShapeSweepPenetrating(coneShape, fromMatrix, toMatrix, resultsOutput, cfg, cfgf);
- foreach (var result in resultsOutput)
+ foreach (var result in resultsOutput)
+ {
+ if (result.Succeeded)
{
- if (result.Succeeded)
- {
- var signedVector = result.Point - Entity.GetParent().Transform.WorldMatrix.TranslationVector;
- var signedDistance = Vector3.Dot(cameraVector, signedVector);
-
- var currentLength = DefaultDistance * result.HitFraction;
- if (signedDistance > 0 && currentLength < maxLength)
- maxLength = currentLength;
- }
+ var signedVector = result.Point - Entity.GetParent().Transform.WorldMatrix.TranslationVector;
+ var signedDistance = Vector3.Dot(cameraVector, signedVector);
+
+ var currentLength = DefaultDistance * result.HitFraction;
+ if (signedDistance > 0 && currentLength < maxLength)
+ maxLength = currentLength;
}
}
+ }
- if (maxLength < MinimumDistance)
- maxLength = MinimumDistance;
+ if (maxLength < MinimumDistance)
+ maxLength = MinimumDistance;
- Entity.Transform.Position.Z = maxLength;
- }
+ Entity.Transform.Position.Z = maxLength;
+ }
- ///
- /// Raycast between the camera and its target. The script assumes the camera is a child entity of its target.
- ///
- private void UpdateCameraOrientation()
- {
- // Camera movement from player input
- Vector2 cameraMovement;
- cameraDirectionEvent.TryReceive(out cameraMovement);
+ ///
+ /// Raycast between the camera and its target. The script assumes the camera is a child entity of its target.
+ ///
+ private void UpdateCameraOrientation()
+ {
+ // Camera movement from player input
+ cameraDirectionEvent.TryReceive(out var cameraMovement);
- if (InvertY) cameraMovement.Y *= -1;
- targetRotationXYZ.X += cameraMovement.Y * VerticalSpeed;
- targetRotationXYZ.X = Math.Max(targetRotationXYZ.X, -MaxVerticalAngle);
- targetRotationXYZ.X = Math.Min(targetRotationXYZ.X, -MinVerticalAngle);
+ if (InvertY) cameraMovement.Y *= -1;
+ targetRotationXYZ.X += cameraMovement.Y * VerticalSpeed;
+ targetRotationXYZ.X = Math.Max(targetRotationXYZ.X, -MaxVerticalAngle);
+ targetRotationXYZ.X = Math.Min(targetRotationXYZ.X, -MinVerticalAngle);
- if (InvertX) cameraMovement.X *= -1;
- targetRotationXYZ.Y -= cameraMovement.X * RotationSpeed;
+ if (InvertX) cameraMovement.X *= -1;
+ targetRotationXYZ.Y -= cameraMovement.X * RotationSpeed;
- // Very simple lerp to allow smoother transition of the camera towards its desired destination. You can change this behavior with a different one, better suited for your game.
- cameraRotationXYZ = Vector3.Lerp(cameraRotationXYZ, targetRotationXYZ, 0.25f);
- Entity.GetParent().Transform.RotationEulerXYZ = new Vector3(MathUtil.DegreesToRadians(cameraRotationXYZ.X), MathUtil.DegreesToRadians(cameraRotationXYZ.Y), 0);
- }
+ // Very simple lerp to allow smoother transition of the camera towards its desired destination. You can change this behavior with a different one, better suited for your game.
+ cameraRotationXYZ = Vector3.Lerp(cameraRotationXYZ, targetRotationXYZ, 0.25f);
+ Entity.GetParent().Transform.RotationEulerXYZ = new Vector3(MathUtil.DegreesToRadians(cameraRotationXYZ.X), MathUtil.DegreesToRadians(cameraRotationXYZ.Y), 0);
+ }
- public override void Update()
- {
- UpdateCameraRaycast();
+ public override void Update()
+ {
+ UpdateCameraRaycast();
- UpdateCameraOrientation();
- }
+ UpdateCameraOrientation();
+ }
- public override void Start()
- {
- base.Start();
+ public override void Start()
+ {
+ base.Start();
- coneShape = new ConeColliderShape(DefaultDistance, ConeRadius, ShapeOrientation.UpZ);
- resultsOutput = new List();
+ coneShape = new ConeColliderShape(DefaultDistance, ConeRadius, ShapeOrientation.UpZ);
+ resultsOutput = [];
- if (Entity.GetParent() == null) throw new ArgumentException("ThirdPersonCamera should be placed as a child entity of its target entity!");
- }
+ if (Entity.GetParent() == null) throw new ArgumentException("ThirdPersonCamera should be placed as a child entity of its target entity!");
}
}
diff --git a/samples/Templates/ThirdPersonPlatformer/ThirdPersonPlatformer/ThirdPersonPlatformer.Game/Core/InputManagerExtensions.cs b/samples/Templates/ThirdPersonPlatformer/ThirdPersonPlatformer/ThirdPersonPlatformer.Game/Core/InputManagerExtensions.cs
index 33656f39b0..1ec645ceb5 100644
--- a/samples/Templates/ThirdPersonPlatformer/ThirdPersonPlatformer/ThirdPersonPlatformer.Game/Core/InputManagerExtensions.cs
+++ b/samples/Templates/ThirdPersonPlatformer/ThirdPersonPlatformer/ThirdPersonPlatformer.Game/Core/InputManagerExtensions.cs
@@ -1,133 +1,116 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
+
using Stride.Core.Mathematics;
using Stride.Input;
-namespace ThirdPersonPlatformer.Core
+namespace ThirdPersonPlatformer.Core;
+
+public static class InputManagerExtensions
{
- public static class InputManagerExtensions
+ public static bool IsGamePadButtonDown(this InputManager input, GamePadButton button, int index)
{
- public static bool IsGamePadButtonDown(this InputManager input, GamePadButton button, int index)
- {
- var gamepad = input.GetGamePadByIndex(index);
- if (gamepad == null)
- return false;
-
- return (gamepad.State.Buttons & button) == button;
- }
-
- public static bool IsGamePadButtonDownAny(this InputManager input, GamePadButton button)
- {
- foreach (var gamepad in input.GamePads)
- {
- if ((gamepad.State.Buttons & button) == button)
- return true;
- }
+ var gamepad = input.GetGamePadByIndex(index);
+ if (gamepad == null)
return false;
- }
- public static Vector2 GetLeftThumb(this InputManager input, int index)
- {
- var gamepad = input.GetGamePadByIndex(index);
- if (gamepad == null)
- return Vector2.Zero;
+ return (gamepad.State.Buttons & button) == button;
+ }
- return gamepad.State.LeftThumb;
- }
+ public static bool IsGamePadButtonDownAny(this InputManager input, GamePadButton button)
+ {
+ return input.GamePads.Any(gamepad => (gamepad.State.Buttons & button) == button);
+ }
+
+ public static Vector2 GetLeftThumb(this InputManager input, int index)
+ {
+ var gamepad = input.GetGamePadByIndex(index);
+ return gamepad == null ? Vector2.Zero : gamepad.State.LeftThumb;
+ }
- public static Vector2 GetLeftThumbAny(this InputManager input, float deadZone)
+ public static Vector2 GetLeftThumbAny(this InputManager input, float deadZone)
+ {
+ int totalCount = 0;
+ Vector2 totalMovement = Vector2.Zero;
+ foreach (var gamepad in input.GamePads)
{
- int totalCount = 0;
- Vector2 totalMovement = Vector2.Zero;
- foreach (var gamepad in input.GamePads)
+ var leftVector = gamepad.State.LeftThumb;
+ if (leftVector.Length() >= deadZone)
{
- var leftVector = gamepad.State.LeftThumb;
- if (leftVector.Length() >= deadZone)
- {
- totalCount++;
- totalMovement += leftVector;
- }
+ totalCount++;
+ totalMovement += leftVector;
}
-
- return (totalCount > 1) ? (totalMovement / totalCount) : totalMovement;
}
- public static Vector2 GetRightThumb(this InputManager input, int index)
- {
- var gamepad = input.GetGamePadByIndex(index);
- if (gamepad == null)
- return Vector2.Zero;
+ return (totalCount > 1) ? (totalMovement / totalCount) : totalMovement;
+ }
- return gamepad.State.RightThumb;
- }
+ public static Vector2 GetRightThumb(this InputManager input, int index)
+ {
+ var gamepad = input.GetGamePadByIndex(index);
+ return gamepad == null ? Vector2.Zero : gamepad.State.RightThumb;
+ }
- public static Vector2 GetRightThumbAny(this InputManager input, float deadZone)
+ public static Vector2 GetRightThumbAny(this InputManager input, float deadZone)
+ {
+ int totalCount = 0;
+ Vector2 totalMovement = Vector2.Zero;
+ foreach (var gamepad in input.GamePads)
{
- int totalCount = 0;
- Vector2 totalMovement = Vector2.Zero;
- foreach (var gamepad in input.GamePads)
+ var rightVector = gamepad.State.RightThumb;
+ if (rightVector.Length() >= deadZone)
{
- var rightVector = gamepad.State.RightThumb;
- if (rightVector.Length() >= deadZone)
- {
- totalCount++;
- totalMovement += rightVector;
- }
+ totalCount++;
+ totalMovement += rightVector;
}
-
- return (totalCount > 1) ? (totalMovement / totalCount) : totalMovement;
}
- public static float GetLeftTrigger(this InputManager input, int index)
- {
- var gamepad = input.GetGamePadByIndex(index);
- if (gamepad == null)
- return 0.0f;
+ return (totalCount > 1) ? (totalMovement / totalCount) : totalMovement;
+ }
- return gamepad.State.LeftTrigger;
- }
+ public static float GetLeftTrigger(this InputManager input, int index)
+ {
+ var gamepad = input.GetGamePadByIndex(index);
+ return gamepad == null ? 0.0f : gamepad.State.LeftTrigger;
+ }
- public static float GetLeftTriggerAny(this InputManager input, float deadZone)
+ public static float GetLeftTriggerAny(this InputManager input, float deadZone)
+ {
+ int totalCount = 0;
+ float totalInput = 0;
+ foreach (var gamepad in input.GamePads)
{
- int totalCount = 0;
- float totalInput = 0;
- foreach (var gamepad in input.GamePads)
+ float triggerValue = gamepad.State.LeftTrigger;
+ if (triggerValue >= deadZone)
{
- float triggerValue = gamepad.State.LeftTrigger;
- if (triggerValue >= deadZone)
- {
- totalCount++;
- totalInput += triggerValue;
- }
+ totalCount++;
+ totalInput += triggerValue;
}
-
- return (totalCount > 1) ? (totalInput / totalCount) : totalInput;
}
- public static float GetRightTrigger(this InputManager input, int index)
- {
- var gamepad = input.GetGamePadByIndex(index);
- if (gamepad == null)
- return 0.0f;
+ return (totalCount > 1) ? (totalInput / totalCount) : totalInput;
+ }
- return gamepad.State.RightTrigger;
- }
+ public static float GetRightTrigger(this InputManager input, int index)
+ {
+ var gamepad = input.GetGamePadByIndex(index);
+ return gamepad == null ? 0.0f : gamepad.State.RightTrigger;
+ }
- public static float GetRightTriggerAny(this InputManager input, float deadZone)
+ public static float GetRightTriggerAny(this InputManager input, float deadZone)
+ {
+ int totalCount = 0;
+ float totalInput = 0;
+ foreach (var gamepad in input.GamePads)
{
- int totalCount = 0;
- float totalInput = 0;
- foreach (var gamepad in input.GamePads)
+ float triggerValue = gamepad.State.RightTrigger;
+ if (triggerValue >= deadZone)
{
- float triggerValue = gamepad.State.RightTrigger;
- if (triggerValue >= deadZone)
- {
- totalCount++;
- totalInput += triggerValue;
- }
+ totalCount++;
+ totalInput += triggerValue;
}
-
- return (totalCount > 1) ? (totalInput / totalCount) : totalInput;
}
+
+ return (totalCount > 1) ? (totalInput / totalCount) : totalInput;
}
}
diff --git a/samples/Templates/ThirdPersonPlatformer/ThirdPersonPlatformer/ThirdPersonPlatformer.Game/Core/Utils.cs b/samples/Templates/ThirdPersonPlatformer/ThirdPersonPlatformer/ThirdPersonPlatformer.Game/Core/Utils.cs
index 44e482380e..5180ac5f0e 100644
--- a/samples/Templates/ThirdPersonPlatformer/ThirdPersonPlatformer/ThirdPersonPlatformer.Game/Core/Utils.cs
+++ b/samples/Templates/ThirdPersonPlatformer/ThirdPersonPlatformer/ThirdPersonPlatformer.Game/Core/Utils.cs
@@ -1,24 +1,24 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
+
using Stride.Core.Mathematics;
using Stride.Engine;
-namespace ThirdPersonPlatformer.Core
+namespace ThirdPersonPlatformer.Core;
+
+public static class Utils
{
- public static class Utils
+ public static Vector3 LogicDirectionToWorldDirection(Vector2 logicDirection, CameraComponent camera, Vector3 upVector)
{
- public static Vector3 LogicDirectionToWorldDirection(Vector2 logicDirection, CameraComponent camera, Vector3 upVector)
- {
- camera.Update();
- var inverseView = Matrix.Invert(camera.ViewMatrix);
+ camera.Update();
+ var inverseView = Matrix.Invert(camera.ViewMatrix);
- var forward = Vector3.Cross(upVector, inverseView.Right);
- forward.Normalize();
+ var forward = Vector3.Cross(upVector, inverseView.Right);
+ forward.Normalize();
- var right = Vector3.Cross(forward, upVector);
- var worldDirection = forward * logicDirection.Y + right * logicDirection.X;
- worldDirection.Normalize();
- return worldDirection;
- }
+ var right = Vector3.Cross(forward, upVector);
+ var worldDirection = forward * logicDirection.Y + right * logicDirection.X;
+ worldDirection.Normalize();
+ return worldDirection;
}
}
diff --git a/samples/Templates/ThirdPersonPlatformer/ThirdPersonPlatformer/ThirdPersonPlatformer.Game/Player/AnimationController.cs b/samples/Templates/ThirdPersonPlatformer/ThirdPersonPlatformer/ThirdPersonPlatformer.Game/Player/AnimationController.cs
index bcde0c585d..9075f3dabe 100644
--- a/samples/Templates/ThirdPersonPlatformer/ThirdPersonPlatformer/ThirdPersonPlatformer.Game/Player/AnimationController.cs
+++ b/samples/Templates/ThirdPersonPlatformer/ThirdPersonPlatformer/ThirdPersonPlatformer.Game/Player/AnimationController.cs
@@ -1,279 +1,276 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
-using System;
+
+using Stride.Animations;
using Stride.Core;
using Stride.Core.Annotations;
using Stride.Core.Collections;
using Stride.Core.Mathematics;
-using Stride.Animations;
using Stride.Engine;
using Stride.Engine.Events;
-namespace ThirdPersonPlatformer.Player
+namespace ThirdPersonPlatformer.Player;
+
+public class AnimationController : SyncScript, IBlendTreeBuilder
{
- public class AnimationController : SyncScript, IBlendTreeBuilder
- {
- [Display("Animation Component")]
- public AnimationComponent AnimationComponent { get; set; }
+ [Display("Animation Component")]
+ public AnimationComponent AnimationComponent { get; set; }
- [Display("Idle")]
- public AnimationClip AnimationIdle { get; set; }
+ [Display("Idle")]
+ public AnimationClip AnimationIdle { get; set; }
- [Display("Walk")]
- public AnimationClip AnimationWalk { get; set; }
+ [Display("Walk")]
+ public AnimationClip AnimationWalk { get; set; }
- [Display("Run")]
- public AnimationClip AnimationRun { get; set; }
+ [Display("Run")]
+ public AnimationClip AnimationRun { get; set; }
- [Display("Jump")]
- public AnimationClip AnimationJumpStart { get; set; }
+ [Display("Jump")]
+ public AnimationClip AnimationJumpStart { get; set; }
- [Display("Airborne")]
- public AnimationClip AnimationJumpMid { get; set; }
+ [Display("Airborne")]
+ public AnimationClip AnimationJumpMid { get; set; }
- [Display("Landing")]
- public AnimationClip AnimationJumpEnd { get; set; }
+ [Display("Landing")]
+ public AnimationClip AnimationJumpEnd { get; set; }
- [DataMemberRange(0, 1, 0.01, 0.1, 3)]
- [Display("Walk Threshold")]
- public float WalkThreshold { get; set; } = 0.25f;
+ [DataMemberRange(0, 1, 0.01, 0.1, 3)]
+ [Display("Walk Threshold")]
+ public float WalkThreshold { get; set; } = 0.25f;
- [Display("Time Scale")]
- public double TimeFactor { get; set; } = 1;
+ [Display("Time Scale")]
+ public double TimeFactor { get; set; } = 1;
- private AnimationClipEvaluator animEvaluatorIdle;
- private AnimationClipEvaluator animEvaluatorWalk;
- private AnimationClipEvaluator animEvaluatorRun;
- private AnimationClipEvaluator animEvaluatorJumpStart;
- private AnimationClipEvaluator animEvaluatorJumpMid;
- private AnimationClipEvaluator animEvaluatorJumpEnd;
- private double currentTime = 0;
+ private AnimationClipEvaluator animEvaluatorIdle;
+ private AnimationClipEvaluator animEvaluatorWalk;
+ private AnimationClipEvaluator animEvaluatorRun;
+ private AnimationClipEvaluator animEvaluatorJumpStart;
+ private AnimationClipEvaluator animEvaluatorJumpMid;
+ private AnimationClipEvaluator animEvaluatorJumpEnd;
+ private double currentTime;
- // Idle-Walk-Run lerp
- private AnimationClipEvaluator animEvaluatorWalkLerp1;
- private AnimationClipEvaluator animEvaluatorWalkLerp2;
- private AnimationClip animationClipWalkLerp1;
- private AnimationClip animationClipWalkLerp2;
- private float walkLerpFactor = 0.5f;
+ // Idle-Walk-Run lerp
+ private AnimationClipEvaluator animEvaluatorWalkLerp1;
+ private AnimationClipEvaluator animEvaluatorWalkLerp2;
+ private AnimationClip animationClipWalkLerp1;
+ private AnimationClip animationClipWalkLerp2;
+ private float walkLerpFactor = 0.5f;
- // Internal state
- private bool isGrounded = false;
- private AnimationState state = AnimationState.Airborne;
- private readonly EventReceiver runSpeedEvent = new EventReceiver(PlayerController.RunSpeedEventKey);
- private readonly EventReceiver isGroundedEvent = new EventReceiver(PlayerController.IsGroundedEventKey);
+ // Internal state
+ private bool isGrounded;
+ private AnimationState state = AnimationState.Airborne;
+ private readonly EventReceiver runSpeedEvent = new(PlayerController.RunSpeedEventKey);
+ private readonly EventReceiver isGroundedEvent = new(PlayerController.IsGroundedEventKey);
- float runSpeed;
+ float runSpeed;
- public override void Start()
- {
- base.Start();
+ public override void Start()
+ {
+ base.Start();
- if (AnimationComponent == null)
- throw new InvalidOperationException("The animation component is not set");
+ if (AnimationComponent == null)
+ throw new InvalidOperationException("The animation component is not set");
- if (AnimationIdle == null)
- throw new InvalidOperationException("Idle animation is not set");
+ if (AnimationIdle == null)
+ throw new InvalidOperationException("Idle animation is not set");
- if (AnimationWalk == null)
- throw new InvalidOperationException("Walking animation is not set");
+ if (AnimationWalk == null)
+ throw new InvalidOperationException("Walking animation is not set");
- if (AnimationRun == null)
- throw new InvalidOperationException("Running animation is not set");
+ if (AnimationRun == null)
+ throw new InvalidOperationException("Running animation is not set");
- if (AnimationJumpStart == null)
- throw new InvalidOperationException("Jumping animation is not set");
+ if (AnimationJumpStart == null)
+ throw new InvalidOperationException("Jumping animation is not set");
- if (AnimationJumpMid == null)
- throw new InvalidOperationException("Airborne animation is not set");
+ if (AnimationJumpMid == null)
+ throw new InvalidOperationException("Airborne animation is not set");
- if (AnimationJumpEnd == null)
- throw new InvalidOperationException("Landing animation is not set");
+ if (AnimationJumpEnd == null)
+ throw new InvalidOperationException("Landing animation is not set");
- // By setting a custom blend tree builder we can override the default behavior of the animation system
- // Instead, BuildBlendTree(FastList blendStack) will be called each frame
- AnimationComponent.BlendTreeBuilder = this;
+ // By setting a custom blend tree builder we can override the default behavior of the animation system
+ // Instead, BuildBlendTree(FastList blendStack) will be called each frame
+ AnimationComponent.BlendTreeBuilder = this;
- animEvaluatorIdle = AnimationComponent.Blender.CreateEvaluator(AnimationIdle);
- animEvaluatorWalk = AnimationComponent.Blender.CreateEvaluator(AnimationWalk);
- animEvaluatorRun = AnimationComponent.Blender.CreateEvaluator(AnimationRun);
- animEvaluatorJumpStart = AnimationComponent.Blender.CreateEvaluator(AnimationJumpStart);
- animEvaluatorJumpMid = AnimationComponent.Blender.CreateEvaluator(AnimationJumpMid);
- animEvaluatorJumpEnd = AnimationComponent.Blender.CreateEvaluator(AnimationJumpEnd);
+ animEvaluatorIdle = AnimationComponent.Blender.CreateEvaluator(AnimationIdle);
+ animEvaluatorWalk = AnimationComponent.Blender.CreateEvaluator(AnimationWalk);
+ animEvaluatorRun = AnimationComponent.Blender.CreateEvaluator(AnimationRun);
+ animEvaluatorJumpStart = AnimationComponent.Blender.CreateEvaluator(AnimationJumpStart);
+ animEvaluatorJumpMid = AnimationComponent.Blender.CreateEvaluator(AnimationJumpMid);
+ animEvaluatorJumpEnd = AnimationComponent.Blender.CreateEvaluator(AnimationJumpEnd);
- // Initial walk lerp
- walkLerpFactor = 0;
+ // Initial walk lerp
+ walkLerpFactor = 0;
+ animEvaluatorWalkLerp1 = animEvaluatorIdle;
+ animEvaluatorWalkLerp2 = animEvaluatorWalk;
+ animationClipWalkLerp1 = AnimationIdle;
+ animationClipWalkLerp2 = AnimationWalk;
+ }
+
+ public override void Cancel()
+ {
+ AnimationComponent.Blender.ReleaseEvaluator(animEvaluatorIdle);
+ AnimationComponent.Blender.ReleaseEvaluator(animEvaluatorWalk);
+ AnimationComponent.Blender.ReleaseEvaluator(animEvaluatorRun);
+ AnimationComponent.Blender.ReleaseEvaluator(animEvaluatorJumpStart);
+ AnimationComponent.Blender.ReleaseEvaluator(animEvaluatorJumpMid);
+ AnimationComponent.Blender.ReleaseEvaluator(animEvaluatorJumpEnd);
+ }
+
+ private void UpdateWalking()
+ {
+ if (runSpeed < WalkThreshold)
+ {
+ walkLerpFactor = runSpeed / WalkThreshold;
+ walkLerpFactor = (float)Math.Sqrt(walkLerpFactor); // Idle-Walk blend looks really werid, so skew the factor towards walking
animEvaluatorWalkLerp1 = animEvaluatorIdle;
animEvaluatorWalkLerp2 = animEvaluatorWalk;
animationClipWalkLerp1 = AnimationIdle;
animationClipWalkLerp2 = AnimationWalk;
}
-
- public override void Cancel()
+ else
{
- AnimationComponent.Blender.ReleaseEvaluator(animEvaluatorIdle);
- AnimationComponent.Blender.ReleaseEvaluator(animEvaluatorWalk);
- AnimationComponent.Blender.ReleaseEvaluator(animEvaluatorRun);
- AnimationComponent.Blender.ReleaseEvaluator(animEvaluatorJumpStart);
- AnimationComponent.Blender.ReleaseEvaluator(animEvaluatorJumpMid);
- AnimationComponent.Blender.ReleaseEvaluator(animEvaluatorJumpEnd);
+ walkLerpFactor = (runSpeed - WalkThreshold) / (1.0f - WalkThreshold);
+ animEvaluatorWalkLerp1 = animEvaluatorWalk;
+ animEvaluatorWalkLerp2 = animEvaluatorRun;
+ animationClipWalkLerp1 = AnimationWalk;
+ animationClipWalkLerp2 = AnimationRun;
}
- private void UpdateWalking()
+ // Use DrawTime rather than UpdateTime
+ var time = Game.DrawTime;
+ // This update function will account for animation with different durations, keeping a current time relative to the blended maximum duration
+ long blendedMaxDuration =
+ (long)MathUtil.Lerp(animationClipWalkLerp1.Duration.Ticks, animationClipWalkLerp2.Duration.Ticks, walkLerpFactor);
+
+ var currentTicks = TimeSpan.FromTicks((long)(currentTime * blendedMaxDuration));
+
+ currentTicks = blendedMaxDuration == 0
+ ? TimeSpan.Zero
+ : TimeSpan.FromTicks((currentTicks.Ticks + (long)(time.Elapsed.Ticks * TimeFactor)) %
+ blendedMaxDuration);
+
+ currentTime = (currentTicks.Ticks / (double)blendedMaxDuration);
+ }
+
+ private void UpdateJumping()
+ {
+ const int speedFactor = 1;
+ var currentTicks = TimeSpan.FromTicks((long)(currentTime * AnimationJumpStart.Duration.Ticks));
+ var updatedTicks = currentTicks.Ticks + (long)(Game.DrawTime.Elapsed.Ticks * TimeFactor * speedFactor);
+
+ if (updatedTicks < AnimationJumpStart.Duration.Ticks)
{
- if (runSpeed < WalkThreshold)
- {
- walkLerpFactor = runSpeed / WalkThreshold;
- walkLerpFactor = (float)Math.Sqrt(walkLerpFactor); // Idle-Walk blend looks really werid, so skew the factor towards walking
- animEvaluatorWalkLerp1 = animEvaluatorIdle;
- animEvaluatorWalkLerp2 = animEvaluatorWalk;
- animationClipWalkLerp1 = AnimationIdle;
- animationClipWalkLerp2 = AnimationWalk;
- }
- else
- {
- walkLerpFactor = (runSpeed - WalkThreshold) / (1.0f - WalkThreshold);
- animEvaluatorWalkLerp1 = animEvaluatorWalk;
- animEvaluatorWalkLerp2 = animEvaluatorRun;
- animationClipWalkLerp1 = AnimationWalk;
- animationClipWalkLerp2 = AnimationRun;
- }
-
- // Use DrawTime rather than UpdateTime
- var time = Game.DrawTime;
- // This update function will account for animation with different durations, keeping a current time relative to the blended maximum duration
- long blendedMaxDuration = 0;
- blendedMaxDuration =
- (long)MathUtil.Lerp(animationClipWalkLerp1.Duration.Ticks, animationClipWalkLerp2.Duration.Ticks, walkLerpFactor);
-
- var currentTicks = TimeSpan.FromTicks((long)(currentTime * blendedMaxDuration));
-
- currentTicks = blendedMaxDuration == 0
- ? TimeSpan.Zero
- : TimeSpan.FromTicks((currentTicks.Ticks + (long)(time.Elapsed.Ticks * TimeFactor)) %
- blendedMaxDuration);
-
- currentTime = ((double)currentTicks.Ticks / (double)blendedMaxDuration);
+ currentTicks = TimeSpan.FromTicks(updatedTicks);
+ currentTime = (currentTicks.Ticks / (double)AnimationJumpStart.Duration.Ticks);
}
-
- private void UpdateJumping()
+ else
{
- var speedFactor = 1;
- var currentTicks = TimeSpan.FromTicks((long)(currentTime * AnimationJumpStart.Duration.Ticks));
- var updatedTicks = currentTicks.Ticks + (long)(Game.DrawTime.Elapsed.Ticks * TimeFactor * speedFactor);
-
- if (updatedTicks < AnimationJumpStart.Duration.Ticks)
- {
- currentTicks = TimeSpan.FromTicks(updatedTicks);
- currentTime = ((double)currentTicks.Ticks / (double)AnimationJumpStart.Duration.Ticks);
- }
- else
- {
- state = AnimationState.Airborne;
- currentTime = 0;
- UpdateAirborne();
- }
+ state = AnimationState.Airborne;
+ currentTime = 0;
+ UpdateAirborne();
}
+ }
+
+ private void UpdateAirborne()
+ {
+ // Use DrawTime rather than UpdateTime
+ var time = Game.DrawTime;
+ var currentTicks = TimeSpan.FromTicks((long)(currentTime * AnimationJumpMid.Duration.Ticks));
+ currentTicks = TimeSpan.FromTicks((currentTicks.Ticks + (long)(time.Elapsed.Ticks * TimeFactor)) %
+ AnimationJumpMid.Duration.Ticks);
+ currentTime = (currentTicks.Ticks / (double)AnimationJumpMid.Duration.Ticks);
+ }
+
+ private void UpdateLanding()
+ {
+ const int speedFactor = 1;
+ var currentTicks = TimeSpan.FromTicks((long)(currentTime * AnimationJumpEnd.Duration.Ticks));
+ var updatedTicks = currentTicks.Ticks + (long) (Game.DrawTime.Elapsed.Ticks * TimeFactor * speedFactor);
- private void UpdateAirborne()
+ if (updatedTicks < AnimationJumpEnd.Duration.Ticks)
{
- // Use DrawTime rather than UpdateTime
- var time = Game.DrawTime;
- var currentTicks = TimeSpan.FromTicks((long)(currentTime * AnimationJumpMid.Duration.Ticks));
- currentTicks = TimeSpan.FromTicks((currentTicks.Ticks + (long)(time.Elapsed.Ticks * TimeFactor)) %
- AnimationJumpMid.Duration.Ticks);
- currentTime = ((double)currentTicks.Ticks / (double)AnimationJumpMid.Duration.Ticks);
+ currentTicks = TimeSpan.FromTicks(updatedTicks);
+ currentTime = (currentTicks.Ticks / (double)AnimationJumpEnd.Duration.Ticks);
}
-
- private void UpdateLanding()
+ else
{
- var speedFactor = 1;
- var currentTicks = TimeSpan.FromTicks((long)(currentTime * AnimationJumpEnd.Duration.Ticks));
- var updatedTicks = currentTicks.Ticks + (long) (Game.DrawTime.Elapsed.Ticks * TimeFactor * speedFactor);
-
- if (updatedTicks < AnimationJumpEnd.Duration.Ticks)
- {
- currentTicks = TimeSpan.FromTicks(updatedTicks);
- currentTime = ((double)currentTicks.Ticks / (double)AnimationJumpEnd.Duration.Ticks);
- }
- else
- {
- state = AnimationState.Walking;
- currentTime = 0;
- UpdateWalking();
- }
+ state = AnimationState.Walking;
+ currentTime = 0;
+ UpdateWalking();
}
+ }
- public override void Update()
+ public override void Update()
+ {
+ // State control
+ runSpeedEvent.TryReceive(out runSpeed);
+ isGroundedEvent.TryReceive(out var isGroundedNewValue);
+ if (isGrounded != isGroundedNewValue)
{
- // State control
- runSpeedEvent.TryReceive(out runSpeed);
- bool isGroundedNewValue;
- isGroundedEvent.TryReceive(out isGroundedNewValue);
- if (isGrounded != isGroundedNewValue)
- {
- currentTime = 0;
- isGrounded = isGroundedNewValue;
- state = (isGrounded) ? AnimationState.Landing : AnimationState.Jumping;
- }
-
- switch (state)
- {
- case AnimationState.Walking: UpdateWalking(); break;
- case AnimationState.Jumping: UpdateJumping(); break;
- case AnimationState.Airborne: UpdateAirborne(); break;
- case AnimationState.Landing: UpdateLanding(); break;
- }
+ currentTime = 0;
+ isGrounded = isGroundedNewValue;
+ state = (isGrounded) ? AnimationState.Landing : AnimationState.Jumping;
}
- ///
- /// BuildBlendTree is called every frame from the animation system when the needs to be evaluated
- /// It overrides the default behavior of the by setting a custom blend tree
- ///
- /// The stack of animation operations to be blended
- public void BuildBlendTree(FastList blendStack)
+ switch (state)
{
- switch (state)
- {
- case AnimationState.Walking:
- {
- // Note! The tree is laid out as a stack and has to be flattened before returning it to the animation system!
- blendStack.Add(AnimationOperation.NewPush(animEvaluatorWalkLerp1,
- TimeSpan.FromTicks((long)(currentTime * animationClipWalkLerp1.Duration.Ticks))));
- blendStack.Add(AnimationOperation.NewPush(animEvaluatorWalkLerp2,
- TimeSpan.FromTicks((long)(currentTime * animationClipWalkLerp2.Duration.Ticks))));
- blendStack.Add(AnimationOperation.NewBlend(CoreAnimationOperation.Blend, walkLerpFactor));
- }
- break;
-
- case AnimationState.Jumping:
- {
- blendStack.Add(AnimationOperation.NewPush(animEvaluatorJumpStart,
- TimeSpan.FromTicks((long)(currentTime * AnimationJumpStart.Duration.Ticks))));
- }
- break;
-
- case AnimationState.Airborne:
- {
- blendStack.Add(AnimationOperation.NewPush(animEvaluatorJumpMid,
- TimeSpan.FromTicks((long)(currentTime * AnimationJumpMid.Duration.Ticks))));
- }
- break;
-
- case AnimationState.Landing:
- {
- blendStack.Add(AnimationOperation.NewPush(animEvaluatorJumpEnd,
- TimeSpan.FromTicks((long)(currentTime * AnimationJumpEnd.Duration.Ticks))));
- }
- break;
- }
+ case AnimationState.Walking: UpdateWalking(); break;
+ case AnimationState.Jumping: UpdateJumping(); break;
+ case AnimationState.Airborne: UpdateAirborne(); break;
+ case AnimationState.Landing: UpdateLanding(); break;
}
+ }
- enum AnimationState
+ ///
+ /// BuildBlendTree is called every frame from the animation system when the needs to be evaluated
+ /// It overrides the default behavior of the by setting a custom blend tree
+ ///
+ /// The stack of animation operations to be blended
+ public void BuildBlendTree(FastList blendStack)
+ {
+ switch (state)
{
- Walking,
- Jumping,
- Airborne,
- Landing,
+ case AnimationState.Walking:
+ {
+ // Note! The tree is laid out as a stack and has to be flattened before returning it to the animation system!
+ blendStack.Add(AnimationOperation.NewPush(animEvaluatorWalkLerp1,
+ TimeSpan.FromTicks((long)(currentTime * animationClipWalkLerp1.Duration.Ticks))));
+ blendStack.Add(AnimationOperation.NewPush(animEvaluatorWalkLerp2,
+ TimeSpan.FromTicks((long)(currentTime * animationClipWalkLerp2.Duration.Ticks))));
+ blendStack.Add(AnimationOperation.NewBlend(CoreAnimationOperation.Blend, walkLerpFactor));
+ }
+ break;
+
+ case AnimationState.Jumping:
+ {
+ blendStack.Add(AnimationOperation.NewPush(animEvaluatorJumpStart,
+ TimeSpan.FromTicks((long)(currentTime * AnimationJumpStart.Duration.Ticks))));
+ }
+ break;
+
+ case AnimationState.Airborne:
+ {
+ blendStack.Add(AnimationOperation.NewPush(animEvaluatorJumpMid,
+ TimeSpan.FromTicks((long)(currentTime * AnimationJumpMid.Duration.Ticks))));
+ }
+ break;
+
+ case AnimationState.Landing:
+ {
+ blendStack.Add(AnimationOperation.NewPush(animEvaluatorJumpEnd,
+ TimeSpan.FromTicks((long)(currentTime * AnimationJumpEnd.Duration.Ticks))));
+ }
+ break;
}
}
+
+ enum AnimationState
+ {
+ Walking,
+ Jumping,
+ Airborne,
+ Landing,
+ }
}
diff --git a/samples/Templates/ThirdPersonPlatformer/ThirdPersonPlatformer/ThirdPersonPlatformer.Game/Player/PlayerController.cs b/samples/Templates/ThirdPersonPlatformer/ThirdPersonPlatformer/ThirdPersonPlatformer.Game/Player/PlayerController.cs
index 498bfeeae2..2e3537785c 100644
--- a/samples/Templates/ThirdPersonPlatformer/ThirdPersonPlatformer/ThirdPersonPlatformer.Game/Player/PlayerController.cs
+++ b/samples/Templates/ThirdPersonPlatformer/ThirdPersonPlatformer/ThirdPersonPlatformer.Game/Player/PlayerController.cs
@@ -1,145 +1,142 @@
-// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
+// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
-using System;
+
using Stride.Core;
using Stride.Core.Mathematics;
using Stride.Engine;
using Stride.Engine.Events;
using Stride.Physics;
-namespace ThirdPersonPlatformer.Player
+namespace ThirdPersonPlatformer.Player;
+
+public class PlayerController : SyncScript
{
- public class PlayerController : SyncScript
- {
- [Display("Run Speed")]
- public float MaxRunSpeed { get; set; } = 10;
+ [Display("Run Speed")]
+ public float MaxRunSpeed { get; set; } = 10;
- public static readonly EventKey IsGroundedEventKey = new EventKey();
+ public static readonly EventKey IsGroundedEventKey = new();
- public static readonly EventKey RunSpeedEventKey = new EventKey();
+ public static readonly EventKey RunSpeedEventKey = new();
- // This component is the physics representation of a controllable character
- private CharacterComponent character;
- private Entity modelChildEntity;
+ // This component is the physics representation of a controllable character
+ private CharacterComponent character;
+ private Entity modelChildEntity;
- private float yawOrientation;
+ private float yawOrientation;
- private readonly EventReceiver moveDirectionEvent = new EventReceiver(PlayerInput.MoveDirectionEventKey);
+ private readonly EventReceiver moveDirectionEvent = new(PlayerInput.MoveDirectionEventKey);
- private readonly EventReceiver jumpEvent = new EventReceiver(PlayerInput.JumpEventKey);
+ private readonly EventReceiver jumpEvent = new(PlayerInput.JumpEventKey);
- ///
- /// Allow for some latency from the user input to make jumping appear more natural
- ///
- [Display("Jump Time Limit")]
- public float JumpReactionThreshold { get; set; } = 0.3f;
+ ///
+ /// Allow for some latency from the user input to make jumping appear more natural
+ ///
+ [Display("Jump Time Limit")]
+ public float JumpReactionThreshold { get; set; } = 0.3f;
- // When the character falls off a surface, allow for some reaction time
- private float jumpReactionRemaining;
+ // When the character falls off a surface, allow for some reaction time
+ private float jumpReactionRemaining;
- // Allow some inertia to the movement
- private Vector3 moveDirection = Vector3.Zero;
+ // Allow some inertia to the movement
+ private Vector3 moveDirection = Vector3.Zero;
- ///
- /// Called when the script is first initialized
- ///
- public override void Start()
- {
- base.Start();
+ ///
+ /// Called when the script is first initialized
+ ///
+ public override void Start()
+ {
+ base.Start();
- jumpReactionRemaining = JumpReactionThreshold;
+ jumpReactionRemaining = JumpReactionThreshold;
- // Will search for an CharacterComponent within the same entity as this script
- character = Entity.Get();
- if (character == null) throw new ArgumentException("Please add a CharacterComponent to the entity containing PlayerController!");
+ // Will search for an CharacterComponent within the same entity as this script
+ character = Entity.Get();
+ if (character == null) throw new ArgumentException("Please add a CharacterComponent to the entity containing PlayerController!");
- modelChildEntity = Entity.GetChild(0);
- }
+ modelChildEntity = Entity.GetChild(0);
+ }
- ///
- /// Called on every frame update
- ///
- public override void Update()
- {
- // var dt = Game.UpdateTime.Elapsed.Milliseconds * 0.001;
- Move(MaxRunSpeed);
+ ///
+ /// Called on every frame update
+ ///
+ public override void Update()
+ {
+ // var dt = Game.UpdateTime.Elapsed.Milliseconds * 0.001;
+ Move(MaxRunSpeed);
- Jump();
- }
+ Jump();
+ }
- ///
- /// Jump makes the character jump and also accounts for the player's reaction time, making jumping feel more natural by
- /// allowing jumps within some limit of the last time the character was on the ground
- ///
- private void Jump()
- {
- var dt = this.GetSimulation().FixedTimeStep;
+ ///
+ /// Jump makes the character jump and also accounts for the player's reaction time, making jumping feel more natural by
+ /// allowing jumps within some limit of the last time the character was on the ground
+ ///
+ private void Jump()
+ {
+ var dt = this.GetSimulation().FixedTimeStep;
- // Check if conditions allow the character to jump
- if (JumpReactionThreshold <= 0)
- {
- // No reaction threshold. The character can only jump if grounded
- if (!character.IsGrounded)
- {
- IsGroundedEventKey.Broadcast(false);
- return;
- }
- }
- else
+ // Check if conditions allow the character to jump
+ if (JumpReactionThreshold <= 0)
+ {
+ // No reaction threshold. The character can only jump if grounded
+ if (!character.IsGrounded)
{
- // If there is still enough time left for jumping allow the character to jump even when not grounded
- if (jumpReactionRemaining > 0)
- jumpReactionRemaining -= dt;
-
- // If the character on the ground reset the jumping reaction time
- if (character.IsGrounded)
- jumpReactionRemaining = JumpReactionThreshold;
-
- // If there is no more reaction time left don't allow the character to jump
- if (jumpReactionRemaining <= 0)
- {
- IsGroundedEventKey.Broadcast(character.IsGrounded);
- return;
- }
+ IsGroundedEventKey.Broadcast(false);
+ return;
}
+ }
+ else
+ {
+ // If there is still enough time left for jumping allow the character to jump even when not grounded
+ if (jumpReactionRemaining > 0)
+ jumpReactionRemaining -= dt;
+
+ // If the character on the ground reset the jumping reaction time
+ if (character.IsGrounded)
+ jumpReactionRemaining = JumpReactionThreshold;
- // If the player didn't press a jump button we don't need to jump
- bool didJump;
- jumpEvent.TryReceive(out didJump);
- if (!didJump)
+ // If there is no more reaction time left don't allow the character to jump
+ if (jumpReactionRemaining <= 0)
{
- IsGroundedEventKey.Broadcast(true);
+ IsGroundedEventKey.Broadcast(character.IsGrounded);
return;
}
-
- // Jump!!
- jumpReactionRemaining = 0;
- character.Jump();
-
- // Broadcast that the character is jumping!
- IsGroundedEventKey.Broadcast(false);
}
- private void Move(float speed)
+ // If the player didn't press a jump button we don't need to jump
+ jumpEvent.TryReceive(out var didJump);
+ if (!didJump)
{
- // Character speed
- Vector3 newMoveDirection;
- moveDirectionEvent.TryReceive(out newMoveDirection);
+ IsGroundedEventKey.Broadcast(true);
+ return;
+ }
- // Allow very simple inertia to the character to make animation transitions more fluid
- moveDirection = moveDirection*0.85f + newMoveDirection *0.15f;
+ // Jump!!
+ jumpReactionRemaining = 0;
+ character.Jump();
- character.SetVelocity(moveDirection * speed);
+ // Broadcast that the character is jumping!
+ IsGroundedEventKey.Broadcast(false);
+ }
- // Broadcast speed as per cent of the max speed
- RunSpeedEventKey.Broadcast(moveDirection.Length());
+ private void Move(float speed)
+ {
+ // Character speed
+ moveDirectionEvent.TryReceive(out var newMoveDirection);
- // Character orientation
- if (moveDirection.Length() > 0.001)
- {
- yawOrientation = MathUtil.RadiansToDegrees((float) Math.Atan2(-moveDirection.Z, moveDirection.X) + MathUtil.PiOverTwo);
- }
- modelChildEntity.Transform.Rotation = Quaternion.RotationYawPitchRoll(MathUtil.DegreesToRadians(yawOrientation), 0, 0);
+ // Allow very simple inertia to the character to make animation transitions more fluid
+ moveDirection = moveDirection*0.85f + newMoveDirection *0.15f;
+
+ character.SetVelocity(moveDirection * speed);
+
+ // Broadcast speed as per cent of the max speed
+ RunSpeedEventKey.Broadcast(moveDirection.Length());
+
+ // Character orientation
+ if (moveDirection.Length() > 0.001)
+ {
+ yawOrientation = MathUtil.RadiansToDegrees((float) Math.Atan2(-moveDirection.Z, moveDirection.X) + MathUtil.PiOverTwo);
}
+ modelChildEntity.Transform.Rotation = Quaternion.RotationYawPitchRoll(MathUtil.DegreesToRadians(yawOrientation), 0, 0);
}
}
diff --git a/samples/Templates/ThirdPersonPlatformer/ThirdPersonPlatformer/ThirdPersonPlatformer.Game/Player/PlayerInput.cs b/samples/Templates/ThirdPersonPlatformer/ThirdPersonPlatformer/ThirdPersonPlatformer.Game/Player/PlayerInput.cs
index 9b63a78de9..982148d509 100644
--- a/samples/Templates/ThirdPersonPlatformer/ThirdPersonPlatformer/ThirdPersonPlatformer.Game/Player/PlayerInput.cs
+++ b/samples/Templates/ThirdPersonPlatformer/ThirdPersonPlatformer/ThirdPersonPlatformer.Game/Player/PlayerInput.cs
@@ -1,140 +1,138 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
-using System.Collections.Generic;
-using System.Linq;
+
using Stride.Core.Mathematics;
using Stride.Engine;
using Stride.Engine.Events;
using Stride.Input;
using ThirdPersonPlatformer.Core;
-namespace ThirdPersonPlatformer.Player
+namespace ThirdPersonPlatformer.Player;
+
+public class PlayerInput : SyncScript
{
- public class PlayerInput : SyncScript
- {
- ///
- /// Raised every frame with the intended direction of movement from the player.
- ///
- // TODO Should not be static, but allow binding between player and controller
- public static readonly EventKey MoveDirectionEventKey = new EventKey();
+ ///
+ /// Raised every frame with the intended direction of movement from the player.
+ ///
+ // TODO Should not be static, but allow binding between player and controller
+ public static readonly EventKey MoveDirectionEventKey = new();
- public static readonly EventKey CameraDirectionEventKey = new EventKey();
+ public static readonly EventKey CameraDirectionEventKey = new();
- public static readonly EventKey JumpEventKey = new EventKey();
- private bool jumpButtonDown = false;
+ public static readonly EventKey JumpEventKey = new();
+ private bool jumpButtonDown;
- public float DeadZone { get; set; } = 0.25f;
+ public float DeadZone { get; set; } = 0.25f;
- public CameraComponent Camera { get; set; }
+ public CameraComponent Camera { get; set; }
- ///
- /// Multiplies move movement by this amount to apply aim rotations
- ///
- public float MouseSensitivity = 1f;
+ ///
+ /// Multiplies move movement by this amount to apply aim rotations
+ ///
+ public float MouseSensitivity = 1f;
- public List KeysLeft { get; } = new List();
+ public List KeysLeft { get; } = [];
- public List KeysRight { get; } = new List();
+ public List KeysRight { get; } = [];
- public List KeysUp { get; } = new List();
+ public List KeysUp { get; } = [];
- public List KeysDown { get; } = new List();
+ public List KeysDown { get; } = [];
- public List KeysJump { get; } = new List();
+ public List KeysJump { get; } = [];
- public override void Update()
+ public override void Update()
+ {
+ // Character movement: should be camera-aware
{
- // Character movement: should be camera-aware
+ // Left stick: movement
+ var moveDirection = Input.GetLeftThumbAny(DeadZone);
+
+ // Keyboard: movement
+ if (KeysLeft.Any(key => Input.IsKeyDown(key)))
+ moveDirection += -Vector2.UnitX;
+ if (KeysRight.Any(key => Input.IsKeyDown(key)))
+ moveDirection += +Vector2.UnitX;
+ if (KeysUp.Any(key => Input.IsKeyDown(key)))
+ moveDirection += +Vector2.UnitY;
+ if (KeysDown.Any(key => Input.IsKeyDown(key)))
+ moveDirection += -Vector2.UnitY;
+
+ // Broadcast the movement vector as a world-space Vector3 to allow characters to be controlled
+ var worldSpeed = (Camera != null)
+ ? Utils.LogicDirectionToWorldDirection(moveDirection, Camera, Vector3.UnitY)
+ : new Vector3(moveDirection.X, 0, moveDirection.Y);
+
+ // Adjust vector's magnitute - worldSpeed has been normalized
+ var moveLength = moveDirection.Length();
+ var isDeadZoneLeft = moveLength < DeadZone;
+ if (isDeadZoneLeft)
{
- // Left stick: movement
- var moveDirection = Input.GetLeftThumbAny(DeadZone);
-
- // Keyboard: movement
- if (KeysLeft.Any(key => Input.IsKeyDown(key)))
- moveDirection += -Vector2.UnitX;
- if (KeysRight.Any(key => Input.IsKeyDown(key)))
- moveDirection += +Vector2.UnitX;
- if (KeysUp.Any(key => Input.IsKeyDown(key)))
- moveDirection += +Vector2.UnitY;
- if (KeysDown.Any(key => Input.IsKeyDown(key)))
- moveDirection += -Vector2.UnitY;
-
- // Broadcast the movement vector as a world-space Vector3 to allow characters to be controlled
- var worldSpeed = (Camera != null)
- ? Utils.LogicDirectionToWorldDirection(moveDirection, Camera, Vector3.UnitY)
- : new Vector3(moveDirection.X, 0, moveDirection.Y);
-
- // Adjust vector's magnitute - worldSpeed has been normalized
- var moveLength = moveDirection.Length();
- var isDeadZoneLeft = moveLength < DeadZone;
- if (isDeadZoneLeft)
+ worldSpeed = Vector3.Zero;
+ }
+ else
+ {
+ if (moveLength > 1)
{
- worldSpeed = Vector3.Zero;
+ moveLength = 1;
}
else
{
- if (moveLength > 1)
- {
- moveLength = 1;
- }
- else
- {
- moveLength = (moveLength - DeadZone) / (1f - DeadZone);
- }
-
- worldSpeed *= moveLength;
+ moveLength = (moveLength - DeadZone) / (1f - DeadZone);
}
- MoveDirectionEventKey.Broadcast(worldSpeed);
+ worldSpeed *= moveLength;
}
- // Camera rotation: left-right rotates the camera horizontally while up-down controls its altitude
- {
- // Right stick: camera rotation
- var cameraDirection = Input.GetRightThumbAny(DeadZone);
- var isDeadZoneRight = cameraDirection.Length() < DeadZone;
- if (isDeadZoneRight)
- cameraDirection = Vector2.Zero;
- else
- cameraDirection.Normalize();
-
- // Contrary to a mouse, driving camera rotation from a stick must be scaled by delta time.
- // The amount of camera rotation with a stick is constant over time based on the tilt of the stick,
- // Whereas mouse driven rotation is already constrained by time, it is driven by the difference in position from last *time* to this *time*.
- cameraDirection *= (float)this.Game.UpdateTime.Elapsed.TotalSeconds;
-
- // Mouse-based camera rotation. Only enabled after you click the screen to lock your cursor, pressing escape cancels this
- if (Input.IsMouseButtonDown(MouseButton.Left))
- {
- Input.LockMousePosition(true);
- Game.IsMouseVisible = false;
- }
- if (Input.IsKeyPressed(Keys.Escape))
- {
- Input.UnlockMousePosition();
- Game.IsMouseVisible = true;
- }
- if (Input.IsMousePositionLocked)
- {
- cameraDirection += new Vector2(Input.MouseDelta.X, -Input.MouseDelta.Y)*MouseSensitivity;
- }
+ MoveDirectionEventKey.Broadcast(worldSpeed);
+ }
- // Broadcast the camera direction directly, as a screen-space Vector2
- CameraDirectionEventKey.Broadcast(cameraDirection);
+ // Camera rotation: left-right rotates the camera horizontally while up-down controls its altitude
+ {
+ // Right stick: camera rotation
+ var cameraDirection = Input.GetRightThumbAny(DeadZone);
+ var isDeadZoneRight = cameraDirection.Length() < DeadZone;
+ if (isDeadZoneRight)
+ cameraDirection = Vector2.Zero;
+ else
+ cameraDirection.Normalize();
+
+ // Contrary to a mouse, driving camera rotation from a stick must be scaled by delta time.
+ // The amount of camera rotation with a stick is constant over time based on the tilt of the stick,
+ // Whereas mouse driven rotation is already constrained by time, it is driven by the difference in position from last *time* to this *time*.
+ cameraDirection *= (float)this.Game.UpdateTime.Elapsed.TotalSeconds;
+
+ // Mouse-based camera rotation. Only enabled after you click the screen to lock your cursor, pressing escape cancels this
+ if (Input.IsMouseButtonDown(MouseButton.Left))
+ {
+ Input.LockMousePosition(true);
+ Game.IsMouseVisible = false;
}
-
- // Jumping: don't bother with jump restrictions here, just pass the button states
+ if (Input.IsKeyPressed(Keys.Escape))
+ {
+ Input.UnlockMousePosition();
+ Game.IsMouseVisible = true;
+ }
+ if (Input.IsMousePositionLocked)
{
- // Controller: jumping
- var isJumpDown = Input.IsGamePadButtonDownAny(GamePadButton.A);
- var didJump = (!jumpButtonDown && isJumpDown);
- jumpButtonDown = isJumpDown;
+ cameraDirection += new Vector2(Input.MouseDelta.X, -Input.MouseDelta.Y)*MouseSensitivity;
+ }
- // Keyboard: jumping
- didJump |= (KeysJump.Any(key => Input.IsKeyPressed(key)));
+ // Broadcast the camera direction directly, as a screen-space Vector2
+ CameraDirectionEventKey.Broadcast(cameraDirection);
+ }
- JumpEventKey.Broadcast(didJump);
- }
+ // Jumping: don't bother with jump restrictions here, just pass the button states
+ {
+ // Controller: jumping
+ var isJumpDown = Input.IsGamePadButtonDownAny(GamePadButton.A);
+ var didJump = (!jumpButtonDown && isJumpDown);
+ jumpButtonDown = isJumpDown;
+
+ // Keyboard: jumping
+ didJump |= (KeysJump.Any(key => Input.IsKeyPressed(key)));
+
+ JumpEventKey.Broadcast(didJump);
}
}
}
diff --git a/samples/Templates/ThirdPersonPlatformer/ThirdPersonPlatformer/ThirdPersonPlatformer.Game/ThirdPersonPlatformer.Game.csproj b/samples/Templates/ThirdPersonPlatformer/ThirdPersonPlatformer/ThirdPersonPlatformer.Game/ThirdPersonPlatformer.Game.csproj
index 5bff64deb4..db10c833f9 100644
--- a/samples/Templates/ThirdPersonPlatformer/ThirdPersonPlatformer/ThirdPersonPlatformer.Game/ThirdPersonPlatformer.Game.csproj
+++ b/samples/Templates/ThirdPersonPlatformer/ThirdPersonPlatformer/ThirdPersonPlatformer.Game/ThirdPersonPlatformer.Game.csproj
@@ -2,6 +2,8 @@
net8.0
ThirdPersonPlatformer
+ enable
+ latest
diff --git a/samples/Templates/ThirdPersonPlatformer/ThirdPersonPlatformer/ThirdPersonPlatformer.Windows/ThirdPersonPlatformer.Windows.csproj b/samples/Templates/ThirdPersonPlatformer/ThirdPersonPlatformer/ThirdPersonPlatformer.Windows/ThirdPersonPlatformer.Windows.csproj
index 56756b3e63..e2a747dc67 100644
--- a/samples/Templates/ThirdPersonPlatformer/ThirdPersonPlatformer/ThirdPersonPlatformer.Windows/ThirdPersonPlatformer.Windows.csproj
+++ b/samples/Templates/ThirdPersonPlatformer/ThirdPersonPlatformer/ThirdPersonPlatformer.Windows/ThirdPersonPlatformer.Windows.csproj
@@ -7,6 +7,8 @@
..\Bin\Windows\$(Configuration)\
false
STRIDE_PLATFORM_DESKTOP
+ enable
+ latest
$(MSBuildThisFileDirectory)..\ThirdPersonPlatformer.sdpkg
diff --git a/samples/Templates/TopDownRPG/TopDownRPG/TopDownRPG.Game/Core/ClickResult.cs b/samples/Templates/TopDownRPG/TopDownRPG/TopDownRPG.Game/Core/ClickResult.cs
index 40afd1fc39..8a88a07b07 100644
--- a/samples/Templates/TopDownRPG/TopDownRPG/TopDownRPG.Game/Core/ClickResult.cs
+++ b/samples/Templates/TopDownRPG/TopDownRPG/TopDownRPG.Game/Core/ClickResult.cs
@@ -1,52 +1,52 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// 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.Physics;
-namespace TopDownRPG.Core
+namespace TopDownRPG.Core;
+
+public enum ClickType
{
- public enum ClickType
- {
- ///
- /// The result didn't hit anything
- ///
- Empty,
-
- ///
- /// The result hit a ground object
- ///
- Ground,
-
- ///
- /// The result hit a treasure chest object
- ///
- LootCrate,
- }
+ ///
+ /// The result didn't hit anything
+ ///
+ Empty,
+
+ ///
+ /// The result hit a ground object
+ ///
+ Ground,
+
+ ///
+ /// The result hit a treasure chest object
+ ///
+ LootCrate,
+}
+
+///
+/// Result of the user clicking/tapping on the world
+///
+public struct ClickResult
+{
+ ///
+ /// The world-space position of the click, where the raycast hits the collision body
+ ///
+ public Vector3 WorldPosition;
+
+ ///
+ /// The Entity containing the collision body which was hit
+ ///
+ public Entity ClickedEntity;
+
+ ///
+ /// What kind of object did we hit
+ ///
+ public ClickType Type;
///
- /// Result of the user clicking/tapping on the world
+ /// The HitResult received from the physics simulation
///
- public struct ClickResult
- {
- ///
- /// The world-space position of the click, where the raycast hits the collision body
- ///
- public Vector3 WorldPosition;
-
- ///
- /// The Entity containing the collision body which was hit
- ///
- public Entity ClickedEntity;
-
- ///
- /// What kind of object did we hit
- ///
- public ClickType Type;
-
- ///
- /// The HitResult received from the physics simulation
- ///
- public HitResult HitResult;
- }
+ public HitResult HitResult;
}
diff --git a/samples/Templates/TopDownRPG/TopDownRPG/TopDownRPG.Game/Core/InputManagerExtensions.cs b/samples/Templates/TopDownRPG/TopDownRPG/TopDownRPG.Game/Core/InputManagerExtensions.cs
index 5995a6b5d8..88b57d6d04 100644
--- a/samples/Templates/TopDownRPG/TopDownRPG/TopDownRPG.Game/Core/InputManagerExtensions.cs
+++ b/samples/Templates/TopDownRPG/TopDownRPG/TopDownRPG.Game/Core/InputManagerExtensions.cs
@@ -1,38 +1,38 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
+
using Stride.Core.Mathematics;
using Stride.Input;
-namespace TopDownRPG.Core
+namespace TopDownRPG.Core;
+
+public static class InputManagerExtensions
{
- public static class InputManagerExtensions
+ public static bool IsGamePadButtonDown(this InputManager input, GamePadButton button, int index)
+ {
+ if (input.GamePadCount < index)
+ return false;
+
+ return (input.GetGamePadByIndex(index).State.Buttons & button) == button;
+ }
+
+ public static Vector2 GetLeftThumb(this InputManager input, int index)
+ {
+ return input.GamePadCount >= index ? input.GetGamePadByIndex(index).State.LeftThumb : Vector2.Zero;
+ }
+
+ public static Vector2 GetRightThumb(this InputManager input, int index)
+ {
+ return input.GamePadCount >= index ? input.GetGamePadByIndex(index).State.RightThumb : Vector2.Zero;
+ }
+
+ public static float GetLeftTrigger(this InputManager input, int index)
+ {
+ return input.GamePadCount >= index ? input.GetGamePadByIndex(index).State.LeftTrigger : 0.0f;
+ }
+
+ public static float GetRightTrigger(this InputManager input, int index)
{
- public static bool IsGamePadButtonDown(this InputManager input, GamePadButton button, int index)
- {
- if (input.GamePadCount < index)
- return false;
-
- return (input.GetGamePadByIndex(index).State.Buttons & button) == button;
- }
-
- public static Vector2 GetLeftThumb(this InputManager input, int index)
- {
- return input.GamePadCount >= index ? input.GetGamePadByIndex(index).State.LeftThumb : Vector2.Zero;
- }
-
- public static Vector2 GetRightThumb(this InputManager input, int index)
- {
- return input.GamePadCount >= index ? input.GetGamePadByIndex(index).State.RightThumb : Vector2.Zero;
- }
-
- public static float GetLeftTrigger(this InputManager input, int index)
- {
- return input.GamePadCount >= index ? input.GetGamePadByIndex(index).State.LeftTrigger : 0.0f;
- }
-
- public static float GetRightTrigger(this InputManager input, int index)
- {
- return input.GamePadCount >= index ? input.GetGamePadByIndex(index).State.RightTrigger : 0.0f;
- }
+ return input.GamePadCount >= index ? input.GetGamePadByIndex(index).State.RightTrigger : 0.0f;
}
}
diff --git a/samples/Templates/TopDownRPG/TopDownRPG/TopDownRPG.Game/Core/TaskExtension.cs b/samples/Templates/TopDownRPG/TopDownRPG/TopDownRPG.Game/Core/TaskExtension.cs
index 6a42a8de69..10268d74bc 100644
--- a/samples/Templates/TopDownRPG/TopDownRPG/TopDownRPG.Game/Core/TaskExtension.cs
+++ b/samples/Templates/TopDownRPG/TopDownRPG/TopDownRPG.Game/Core/TaskExtension.cs
@@ -1,23 +1,20 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
-using System;
-using System.Threading.Tasks;
-namespace TopDownRPG.Core
+namespace TopDownRPG.Core;
+
+public static class TaskExtension
{
- public static class TaskExtension
+ public static async Task InterruptedBy(this Task mainTask, Task interruptingTask, Action interruptionAction)
{
- public static async Task InterruptedBy(this Task mainTask, Task interruptingTask, Action interruptionAction)
+ var firstCompleted = await Task.WhenAny(mainTask, interruptingTask);
+ if (firstCompleted != mainTask)
{
- var firstCompleted = await Task.WhenAny(mainTask, interruptingTask);
- if (firstCompleted != mainTask)
- {
- // Interrupted, run action
- interruptionAction(firstCompleted);
- // And return a task that will never complete
- return await new TaskCompletionSource().Task;
- }
- return mainTask.Result;
+ // Interrupted, run action
+ interruptionAction(firstCompleted);
+ // And return a task that will never complete
+ return await new TaskCompletionSource().Task;
}
+ return mainTask.Result;
}
}
diff --git a/samples/Templates/TopDownRPG/TopDownRPG/TopDownRPG.Game/Core/Utils.cs b/samples/Templates/TopDownRPG/TopDownRPG/TopDownRPG.Game/Core/Utils.cs
index 43b1547953..188041a380 100644
--- a/samples/Templates/TopDownRPG/TopDownRPG/TopDownRPG.Game/Core/Utils.cs
+++ b/samples/Templates/TopDownRPG/TopDownRPG/TopDownRPG.Game/Core/Utils.cs
@@ -1,22 +1,55 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
-using System;
-using System.Threading.Tasks;
+
using Stride.Core.Collections;
using Stride.Core.Mathematics;
using Stride.Engine;
using Stride.Games;
using Stride.Physics;
-namespace TopDownRPG.Core
+namespace TopDownRPG.Core;
+
+public static class Utils
{
- public static class Utils
+ public static void SpawnPrefabModel(this ScriptComponent script, Prefab source, Entity attachEntity, Matrix localMatrix, Vector3 forceImpulse)
{
- public static void SpawnPrefabModel(this ScriptComponent script, Prefab source, Entity attachEntity, Matrix localMatrix, Vector3 forceImpulse)
+ if (source == null)
+ return;
+
+ // Clone
+ var spawnedEntities = source.Instantiate();
+
+ // Add
+ foreach (var prefabEntity in spawnedEntities)
{
- if (source == null)
- return;
+ prefabEntity.Transform.UpdateLocalMatrix();
+ var entityMatrix = prefabEntity.Transform.LocalMatrix * localMatrix;
+ entityMatrix.Decompose(out prefabEntity.Transform.Scale, out prefabEntity.Transform.Rotation, out prefabEntity.Transform.Position);
+
+ if (attachEntity != null)
+ {
+ attachEntity.AddChild(prefabEntity);
+ }
+ else
+ {
+ script.SceneSystem.SceneInstance.RootScene.Entities.Add(prefabEntity);
+ }
+ var physComp = prefabEntity.Get();
+ if (physComp != null)
+ {
+ physComp.ApplyImpulse(forceImpulse);
+ }
+ }
+ }
+
+ public static void SpawnPrefabInstance(this ScriptComponent script, Prefab source, Entity attachEntity, float timeout, Matrix localMatrix)
+ {
+ if (source == null)
+ return;
+
+ Func spawnTask = async () =>
+ {
// Clone
var spawnedEntities = source.Instantiate();
@@ -35,165 +68,129 @@ public static void SpawnPrefabModel(this ScriptComponent script, Prefab source,
{
script.SceneSystem.SceneInstance.RootScene.Entities.Add(prefabEntity);
}
-
- var physComp = prefabEntity.Get();
- if (physComp != null)
- {
- physComp.ApplyImpulse(forceImpulse);
- }
}
- }
- public static void SpawnPrefabInstance(this ScriptComponent script, Prefab source, Entity attachEntity, float timeout, Matrix localMatrix)
- {
- if (source == null)
- return;
-
- Func spawnTask = async () =>
+ // Countdown
+ var secondsCountdown = timeout;
+ while (secondsCountdown > 0f)
{
- // Clone
- var spawnedEntities = source.Instantiate();
-
- // Add
- foreach (var prefabEntity in spawnedEntities)
- {
- prefabEntity.Transform.UpdateLocalMatrix();
- var entityMatrix = prefabEntity.Transform.LocalMatrix * localMatrix;
- entityMatrix.Decompose(out prefabEntity.Transform.Scale, out prefabEntity.Transform.Rotation, out prefabEntity.Transform.Position);
-
- if (attachEntity != null)
- {
- attachEntity.AddChild(prefabEntity);
- }
- else
- {
- script.SceneSystem.SceneInstance.RootScene.Entities.Add(prefabEntity);
- }
- }
+ await script.Script.NextFrame();
+ secondsCountdown -= (float)script.Game.UpdateTime.Elapsed.TotalSeconds;
+ }
- // Countdown
- var secondsCountdown = timeout;
- while (secondsCountdown > 0f)
+ // Remove
+ foreach (var clonedEntity in spawnedEntities)
+ {
+ if (attachEntity != null)
{
- await script.Script.NextFrame();
- secondsCountdown -= (float)script.Game.UpdateTime.Elapsed.TotalSeconds;
+ attachEntity.RemoveChild(clonedEntity);
}
-
- // Remove
- foreach (var clonedEntity in spawnedEntities)
+ else
{
- if (attachEntity != null)
- {
- attachEntity.RemoveChild(clonedEntity);
- }
- else
- {
- script.SceneSystem.SceneInstance.RootScene.Entities.Remove(clonedEntity);
- }
+ script.SceneSystem.SceneInstance.RootScene.Entities.Remove(clonedEntity);
}
+ }
- // Cleanup
- spawnedEntities.Clear();
- };
+ // Cleanup
+ spawnedEntities.Clear();
+ };
- script.Script.AddTask(spawnTask);
- }
+ script.Script.AddTask(spawnTask);
+ }
- ///
- /// Removes an entity, together with its children, from the Game's scene graph
- ///
- /// The game instance containing the entity
- /// Entity to remove
- public static void RemoveEntity(this IGame game, Entity entity)
+ ///
+ /// Removes an entity, together with its children, from the Game's scene graph
+ ///
+ /// The game instance containing the entity
+ /// Entity to remove
+ public static void RemoveEntity(this IGame game, Entity entity)
+ {
+ var parent = entity.GetParent();
+ if (parent != null)
{
- var parent = entity.GetParent();
- if (parent != null)
- {
- parent.RemoveChild(entity);
- return;
- }
-
- ((Game)game).SceneSystem.SceneInstance.RootScene.Entities.Remove(entity);
+ parent.RemoveChild(entity);
+ return;
}
- public static async Task WaitTime(this IGame game, TimeSpan time)
+ ((Game)game).SceneSystem.SceneInstance.RootScene.Entities.Remove(entity);
+ }
+
+ public static async Task WaitTime(this IGame game, TimeSpan time)
+ {
+ var g = (Game)game;
+ var goal = game.UpdateTime.Total + time;
+ while (game.UpdateTime.Total < goal)
{
- var g = (Game)game;
- var goal = game.UpdateTime.Total + time;
- while (game.UpdateTime.Total < goal)
- {
- await g.Script.NextFrame();
- }
+ await g.Script.NextFrame();
}
+ }
- public static Vector3 LogicDirectionToWorldDirection(Vector2 logicDirection, CameraComponent camera, Vector3 upVector)
- {
- camera.Update();
- var inverseView = Matrix.Invert(camera.ViewMatrix);
+ public static Vector3 LogicDirectionToWorldDirection(Vector2 logicDirection, CameraComponent camera, Vector3 upVector)
+ {
+ camera.Update();
+ var inverseView = Matrix.Invert(camera.ViewMatrix);
- var forward = Vector3.Cross(upVector, inverseView.Right);
- forward.Normalize();
+ var forward = Vector3.Cross(upVector, inverseView.Right);
+ forward.Normalize();
- var right = Vector3.Cross(forward, upVector);
- var worldDirection = forward * logicDirection.Y + right * logicDirection.X;
- worldDirection.Normalize();
- return worldDirection;
- }
+ var right = Vector3.Cross(forward, upVector);
+ var worldDirection = forward * logicDirection.Y + right * logicDirection.X;
+ worldDirection.Normalize();
+ return worldDirection;
+ }
- public static bool ScreenPositionToWorldPositionRaycast(Vector2 screenPos, CameraComponent camera, Simulation simulation, out ClickResult clickResult)
- {
- Matrix invViewProj = Matrix.Invert(camera.ViewProjectionMatrix);
+ public static bool ScreenPositionToWorldPositionRaycast(Vector2 screenPos, CameraComponent camera, Simulation simulation, out ClickResult clickResult)
+ {
+ Matrix invViewProj = Matrix.Invert(camera.ViewProjectionMatrix);
- Vector3 sPos;
- sPos.X = screenPos.X * 2f - 1f;
- sPos.Y = 1f - screenPos.Y * 2f;
+ Vector3 sPos;
+ sPos.X = screenPos.X * 2f - 1f;
+ sPos.Y = 1f - screenPos.Y * 2f;
- sPos.Z = 0f;
- var vectorNear = Vector3.Transform(sPos, invViewProj);
- vectorNear /= vectorNear.W;
+ sPos.Z = 0f;
+ var vectorNear = Vector3.Transform(sPos, invViewProj);
+ vectorNear /= vectorNear.W;
- sPos.Z = 1f;
- var vectorFar = Vector3.Transform(sPos, invViewProj);
- vectorFar /= vectorFar.W;
+ sPos.Z = 1f;
+ var vectorFar = Vector3.Transform(sPos, invViewProj);
+ vectorFar /= vectorFar.W;
- clickResult.ClickedEntity = null;
- clickResult.WorldPosition = Vector3.Zero;
- clickResult.Type = ClickType.Empty;
- clickResult.HitResult = new HitResult();
+ clickResult.ClickedEntity = null;
+ clickResult.WorldPosition = Vector3.Zero;
+ clickResult.Type = ClickType.Empty;
+ clickResult.HitResult = new HitResult();
- var minDistance = float.PositiveInfinity;
+ var minDistance = float.PositiveInfinity;
+
+ var result = new FastList();
+ simulation.RaycastPenetrating(vectorNear.XYZ(), vectorFar.XYZ(), result, hitTriggers: true);
+ foreach (var hitResult in result)
+ {
+ ClickType type = ClickType.Empty;
- var result = new FastList();
- simulation.RaycastPenetrating(vectorNear.XYZ(), vectorFar.XYZ(), result, hitTriggers: true);
- foreach (var hitResult in result)
+ if (hitResult.Collider is StaticColliderComponent staticBody)
{
- ClickType type = ClickType.Empty;
-
- var staticBody = hitResult.Collider as StaticColliderComponent;
- if (staticBody != null)
- {
- if (staticBody.CollisionGroup == CollisionFilterGroups.CustomFilter1)
- type = ClickType.Ground;
+ if (staticBody.CollisionGroup == CollisionFilterGroups.CustomFilter1)
+ type = ClickType.Ground;
- if (staticBody.CollisionGroup == CollisionFilterGroups.CustomFilter2)
- type = ClickType.LootCrate;
+ if (staticBody.CollisionGroup == CollisionFilterGroups.CustomFilter2)
+ type = ClickType.LootCrate;
- if (type != ClickType.Empty)
+ if (type != ClickType.Empty)
+ {
+ var distance = (vectorNear.XYZ() - hitResult.Point).LengthSquared();
+ if (distance < minDistance)
{
- var distance = (vectorNear.XYZ() - hitResult.Point).LengthSquared();
- if (distance < minDistance)
- {
- minDistance = distance;
- clickResult.Type = type;
- clickResult.HitResult = hitResult;
- clickResult.WorldPosition = hitResult.Point;
- clickResult.ClickedEntity = hitResult.Collider.Entity;
- }
+ minDistance = distance;
+ clickResult.Type = type;
+ clickResult.HitResult = hitResult;
+ clickResult.WorldPosition = hitResult.Point;
+ clickResult.ClickedEntity = hitResult.Collider.Entity;
}
}
}
-
- return (clickResult.Type != ClickType.Empty);
}
+
+ return (clickResult.Type != ClickType.Empty);
}
}
diff --git a/samples/Templates/TopDownRPG/TopDownRPG/TopDownRPG.Game/Gameplay/CoinScript.cs b/samples/Templates/TopDownRPG/TopDownRPG/TopDownRPG.Game/Gameplay/CoinScript.cs
index 366162b3b6..af2792fb39 100644
--- a/samples/Templates/TopDownRPG/TopDownRPG/TopDownRPG.Game/Gameplay/CoinScript.cs
+++ b/samples/Templates/TopDownRPG/TopDownRPG/TopDownRPG.Game/Gameplay/CoinScript.cs
@@ -1,94 +1,92 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
-using System;
-using System.Threading.Tasks;
+
+using Stride.Audio;
using Stride.Core;
using Stride.Core.Mathematics;
-using Stride.Audio;
using Stride.Engine;
using Stride.Engine.Events;
using TopDownRPG.Core;
-namespace TopDownRPG.Gameplay
+namespace TopDownRPG.Gameplay;
+
+public class CoinScript : SyncScript
{
- public class CoinScript : SyncScript
- {
- public Prefab CoinGetEffect { get; set; }
+ public Prefab CoinGetEffect { get; set; }
- public Trigger Trigger { get; set; }
+ public Trigger Trigger { get; set; }
- [Display("Collect Coin")]
- public Sound SoundEffect { get; set; }
- private SoundInstance sfxInstance;
+ [Display("Collect Coin")]
+ public Sound SoundEffect { get; set; }
+ private SoundInstance sfxInstance;
- private EventReceiver triggeredEvent;
+ private EventReceiver triggeredEvent;
- private float spinSpeed = 1f;
+ private float spinSpeed = 1f;
- private bool activated = false;
+ private bool activated;
- private float animationTime = (float) (Math.PI * 3 / 2);
+ private float animationTime = (float) (Math.PI * 3 / 2);
- public override void Update()
+ public override void Update()
+ {
+ // Check if the coin has been collected
+ bool triggered;
+ if (!activated && (triggeredEvent?.TryReceive(out triggered) ?? false))
{
- // Check if the coin has been collected
- bool triggered;
- if (!activated && (triggeredEvent?.TryReceive(out triggered) ?? false))
- {
- CollisionStarted();
- }
-
- UpdateAnimation();
+ CollisionStarted();
}
- public void UpdateAnimation()
- {
- var dt = (float) Game.UpdateTime.Elapsed.TotalSeconds;
- Entity.Transform.Rotation *= Quaternion.RotationMatrix(Matrix.RotationY(spinSpeed * (float)(dt * Math.PI)));
+ UpdateAnimation();
+ }
- if (!activated)
- return;
+ public void UpdateAnimation()
+ {
+ var dt = (float) Game.UpdateTime.Elapsed.TotalSeconds;
+ Entity.Transform.Rotation *= Quaternion.RotationMatrix(Matrix.RotationY(spinSpeed * (float)(dt * Math.PI)));
- spinSpeed = Math.Min(10f, spinSpeed + dt * 15f);
+ if (!activated)
+ return;
- animationTime += dt * 5;
- var coinHeight = Math.Max(0, Math.Sin(animationTime));
- Entity.Transform.Position.Y = 1 + (float)coinHeight;
+ spinSpeed = Math.Min(10f, spinSpeed + dt * 15f);
- if (animationTime > Math.PI * 3)
- Entity.Transform.Scale = Vector3.Zero;
- }
+ animationTime += dt * 5;
+ var coinHeight = Math.Max(0, Math.Sin(animationTime));
+ Entity.Transform.Position.Y = 1 + (float)coinHeight;
- public override void Start()
- {
- base.Start();
+ if (animationTime > Math.PI * 3)
+ Entity.Transform.Scale = Vector3.Zero;
+ }
- triggeredEvent = (Trigger != null) ? new EventReceiver(Trigger.TriggerEvent) : null;
+ public override void Start()
+ {
+ base.Start();
- sfxInstance = SoundEffect?.CreateInstance();
- sfxInstance?.Stop();
- }
+ triggeredEvent = (Trigger != null) ? new EventReceiver(Trigger.TriggerEvent) : null;
- protected void CollisionStarted()
- {
- activated = true;
+ sfxInstance = SoundEffect?.CreateInstance();
+ sfxInstance?.Stop();
+ }
- // Play a sound effect
- sfxInstance?.Play();
+ protected void CollisionStarted()
+ {
+ activated = true;
- // Add a visual effect
- var effectMatrix = Matrix.Translation(Entity.Transform.WorldMatrix.TranslationVector);
- this.SpawnPrefabInstance(CoinGetEffect, null, 3, effectMatrix);
+ // Play a sound effect
+ sfxInstance?.Play();
- Func cleanupTask = async () =>
- {
- await Game.WaitTime(TimeSpan.FromMilliseconds(3000));
+ // Add a visual effect
+ var effectMatrix = Matrix.Translation(Entity.Transform.WorldMatrix.TranslationVector);
+ this.SpawnPrefabInstance(CoinGetEffect, null, 3, effectMatrix);
- Game.RemoveEntity(Entity);
- };
+ Func cleanupTask = async () =>
+ {
+ await Game.WaitTime(TimeSpan.FromMilliseconds(3000));
- Script.AddTask(cleanupTask);
- }
+ Game.RemoveEntity(Entity);
+ };
+ Script.AddTask(cleanupTask);
}
+
}
diff --git a/samples/Templates/TopDownRPG/TopDownRPG/TopDownRPG.Game/Gameplay/CrateScript.cs b/samples/Templates/TopDownRPG/TopDownRPG/TopDownRPG.Game/Gameplay/CrateScript.cs
index 84b1ed9e6b..eb32f20727 100644
--- a/samples/Templates/TopDownRPG/TopDownRPG/TopDownRPG.Game/Gameplay/CrateScript.cs
+++ b/samples/Templates/TopDownRPG/TopDownRPG/TopDownRPG.Game/Gameplay/CrateScript.cs
@@ -1,101 +1,99 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
-using System;
-using System.Threading.Tasks;
+
+using Stride.Audio;
using Stride.Core;
using Stride.Core.Mathematics;
-using Stride.Audio;
using Stride.Engine;
using Stride.Engine.Events;
using TopDownRPG.Core;
-namespace TopDownRPG.Gameplay
+namespace TopDownRPG.Gameplay;
+
+public class CrateScript : SyncScript
{
- public class CrateScript : SyncScript
- {
- public Prefab CoinGetEffect { get; set; }
+ public Prefab CoinGetEffect { get; set; }
- public Prefab CoinSpawnModel { get; set; }
+ public Prefab CoinSpawnModel { get; set; }
- [Display("Crate Breaking")]
- public Sound SoundEffect { get; set; }
- private SoundInstance sfxInstance;
+ [Display("Crate Breaking")]
+ public Sound SoundEffect { get; set; }
+ private SoundInstance sfxInstance;
- public Trigger Trigger { get; set; }
+ public Trigger Trigger { get; set; }
- private EventReceiver triggeredEvent;
+ private EventReceiver triggeredEvent;
- private bool activated = false;
+ private bool activated;
- private float animationTime = 0;
+ private float animationTime;
- public override void Update()
+ public override void Update()
+ {
+ // Check if the coin has been collected
+ bool triggered;
+ if (!activated && (triggeredEvent?.TryReceive(out triggered) ?? false))
{
- // Check if the coin has been collected
- bool triggered;
- if (!activated && (triggeredEvent?.TryReceive(out triggered) ?? false))
- {
- CollisionStarted();
- }
-
- UpdateAnimation();
+ CollisionStarted();
}
- public void UpdateAnimation()
- {
- if (!activated)
- return;
+ UpdateAnimation();
+ }
- var dt = (float)Game.UpdateTime.Elapsed.TotalSeconds;
+ public void UpdateAnimation()
+ {
+ if (!activated)
+ return;
- animationTime += dt * 8;
- var coinHeight = Math.Max(0, Math.Sin(animationTime));
- Entity.Transform.Position.Y = 1 + (float)coinHeight;
+ var dt = (float)Game.UpdateTime.Elapsed.TotalSeconds;
- var uniformScale = (float) Math.Max(0, Math.Min(1, (2 * Math.PI - animationTime) / Math.PI));
- Entity.Transform.Scale = new Vector3(uniformScale);
- }
+ animationTime += dt * 8;
+ var coinHeight = Math.Max(0, Math.Sin(animationTime));
+ Entity.Transform.Position.Y = 1 + (float)coinHeight;
+
+ var uniformScale = (float) Math.Max(0, Math.Min(1, (2 * Math.PI - animationTime) / Math.PI));
+ Entity.Transform.Scale = new Vector3(uniformScale);
+ }
+
+ public override void Start()
+ {
+ base.Start();
+
+ triggeredEvent = (Trigger != null) ? new EventReceiver(Trigger.TriggerEvent) : null;
+
+ sfxInstance = SoundEffect?.CreateInstance();
+ sfxInstance?.Stop();
+ }
- public override void Start()
+ protected void CollisionStarted()
+ {
+ activated = true;
+
+ // Add visual effect
+ var effectMatrix = Matrix.Translation(Entity.Transform.WorldMatrix.TranslationVector);
+ this.SpawnPrefabInstance(CoinGetEffect, null, 1.8f, effectMatrix);
+
+ Func cleanupTask = async () =>
{
- base.Start();
+ await Game.WaitTime(TimeSpan.FromMilliseconds(1500));
- triggeredEvent = (Trigger != null) ? new EventReceiver(Trigger.TriggerEvent) : null;
+ Game.RemoveEntity(Entity);
+ };
- sfxInstance = SoundEffect?.CreateInstance();
- sfxInstance?.Stop();
- }
+ Script.AddTask(cleanupTask);
+
+ // Play a sound effect
+ sfxInstance?.Play();
- protected void CollisionStarted()
+ // Spawn a collectible coin
+ // CoinSpawnModel
+ Random rand = new();
+ var numCoins = 3 + rand.Next(4);
+ for (int i = 0; i < numCoins; i++)
{
- activated = true;
-
- // Add visual effect
- var effectMatrix = Matrix.Translation(Entity.Transform.WorldMatrix.TranslationVector);
- this.SpawnPrefabInstance(CoinGetEffect, null, 1.8f, effectMatrix);
-
- Func cleanupTask = async () =>
- {
- await Game.WaitTime(TimeSpan.FromMilliseconds(1500));
-
- Game.RemoveEntity(Entity);
- };
-
- Script.AddTask(cleanupTask);
-
- // Play a sound effect
- sfxInstance?.Play();
-
- // Spawn a collectible coin
- // CoinSpawnModel
- Random rand = new Random();
- var numCoins = 3 + rand.Next(4);
- for (int i = 0; i < numCoins; i++)
- {
- var offsetVector = new Vector3((float)rand.NextDouble() - 0.5f, (float)rand.NextDouble(), (float)rand.NextDouble() - 0.5f);
- effectMatrix = Matrix.Scaling(0.7f + (float)rand.NextDouble() * 0.3f) * Matrix.Translation(Entity.Transform.WorldMatrix.TranslationVector + offsetVector * 2f);
- this.SpawnPrefabModel(CoinSpawnModel, null, effectMatrix, offsetVector * (3f + (float)rand.NextDouble() * 3f));
- }
+ var offsetVector = new Vector3((float)rand.NextDouble() - 0.5f, (float)rand.NextDouble(), (float)rand.NextDouble() - 0.5f);
+ effectMatrix = Matrix.Scaling(0.7f + (float)rand.NextDouble() * 0.3f) * Matrix.Translation(Entity.Transform.WorldMatrix.TranslationVector + offsetVector * 2f);
+ this.SpawnPrefabModel(CoinSpawnModel, null, effectMatrix, offsetVector * (3f + (float)rand.NextDouble() * 3f));
}
}
}
diff --git a/samples/Templates/TopDownRPG/TopDownRPG/TopDownRPG.Game/Gameplay/EnableDynamicNavigation.cs b/samples/Templates/TopDownRPG/TopDownRPG/TopDownRPG.Game/Gameplay/EnableDynamicNavigation.cs
index 5e019f12c8..63d212b545 100644
--- a/samples/Templates/TopDownRPG/TopDownRPG/TopDownRPG.Game/Gameplay/EnableDynamicNavigation.cs
+++ b/samples/Templates/TopDownRPG/TopDownRPG/TopDownRPG.Game/Gameplay/EnableDynamicNavigation.cs
@@ -2,43 +2,40 @@
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
using System.Collections.Specialized;
-using System.Linq;
using Stride.Core.Collections;
using Stride.Engine;
using Stride.Navigation;
-namespace Gameplay
+namespace Gameplay;
+
+public class EnableDynamicNavigation : StartupScript
{
- public class EnableDynamicNavigation : StartupScript
+ public override void Start()
{
- public override void Start()
- {
- var dynamicNavigationMeshSystem = Game.GameSystems.OfType().FirstOrDefault();
+ var dynamicNavigationMeshSystem = Game.GameSystems.OfType().FirstOrDefault();
- // Wait for the dynamic navigation to be registered
- if (dynamicNavigationMeshSystem == null)
- Game.GameSystems.CollectionChanged += GameSystemsOnCollectionChanged;
- else
- dynamicNavigationMeshSystem.Enabled = true;
- }
+ // Wait for the dynamic navigation to be registered
+ if (dynamicNavigationMeshSystem == null)
+ Game.GameSystems.CollectionChanged += GameSystemsOnCollectionChanged;
+ else
+ dynamicNavigationMeshSystem.Enabled = true;
+ }
- public override void Cancel()
- {
- Game.GameSystems.CollectionChanged -= GameSystemsOnCollectionChanged;
- }
+ public override void Cancel()
+ {
+ Game.GameSystems.CollectionChanged -= GameSystemsOnCollectionChanged;
+ }
- private void GameSystemsOnCollectionChanged(object sender, TrackingCollectionChangedEventArgs trackingCollectionChangedEventArgs)
+ private void GameSystemsOnCollectionChanged(object sender, TrackingCollectionChangedEventArgs trackingCollectionChangedEventArgs)
+ {
+ if (trackingCollectionChangedEventArgs.Action == NotifyCollectionChangedAction.Add)
{
- if (trackingCollectionChangedEventArgs.Action == NotifyCollectionChangedAction.Add)
+ if (trackingCollectionChangedEventArgs.Item is DynamicNavigationMeshSystem dynamicNavigationMeshSystem)
{
- var dynamicNavigationMeshSystem = trackingCollectionChangedEventArgs.Item as DynamicNavigationMeshSystem;
- if (dynamicNavigationMeshSystem != null)
- {
- dynamicNavigationMeshSystem.Enabled = true;
+ dynamicNavigationMeshSystem.Enabled = true;
- // No longer need to listen to changes
- Game.GameSystems.CollectionChanged -= GameSystemsOnCollectionChanged;
- }
+ // No longer need to listen to changes
+ Game.GameSystems.CollectionChanged -= GameSystemsOnCollectionChanged;
}
}
}
diff --git a/samples/Templates/TopDownRPG/TopDownRPG/TopDownRPG.Game/Gameplay/LootCoinScript.cs b/samples/Templates/TopDownRPG/TopDownRPG/TopDownRPG.Game/Gameplay/LootCoinScript.cs
index 9d3d164fdd..6b0081dbda 100644
--- a/samples/Templates/TopDownRPG/TopDownRPG/TopDownRPG.Game/Gameplay/LootCoinScript.cs
+++ b/samples/Templates/TopDownRPG/TopDownRPG/TopDownRPG.Game/Gameplay/LootCoinScript.cs
@@ -1,90 +1,88 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
-using System;
-using System.Threading.Tasks;
+
+using Stride.Audio;
using Stride.Core;
using Stride.Core.Mathematics;
-using Stride.Audio;
using Stride.Engine;
using Stride.Engine.Events;
using TopDownRPG.Core;
-namespace TopDownRPG.Gameplay
+namespace TopDownRPG.Gameplay;
+
+public class LootCoinScript : SyncScript
{
- public class LootCoinScript : SyncScript
- {
- public Prefab CoinGetEffect { get; set; }
+ public Prefab CoinGetEffect { get; set; }
- public Trigger Trigger { get; set; }
+ public Trigger Trigger { get; set; }
- [Display("Collect Coin")]
- public Sound SoundEffect { get; set; }
- private SoundInstance sfxInstance;
+ [Display("Collect Coin")]
+ public Sound SoundEffect { get; set; }
+ private SoundInstance sfxInstance;
- private EventReceiver triggeredEvent;
+ private EventReceiver triggeredEvent;
- private float spinSpeed = 1f;
+ private float spinSpeed = 1f;
- private bool activated = false;
+ private bool activated;
- private float animationTime = (float)(Math.PI * 3 / 2);
+ private float animationTime = (float)(Math.PI * 3 / 2);
- public override void Update()
+ public override void Update()
+ {
+ // Check if the coin has been collected
+ bool triggered;
+ if (!activated && (triggeredEvent?.TryReceive(out triggered) ?? false))
{
- // Check if the coin has been collected
- bool triggered;
- if (!activated && (triggeredEvent?.TryReceive(out triggered) ?? false))
- {
- CollisionStarted();
- }
-
- UpdateAnimation();
+ CollisionStarted();
}
- public void UpdateAnimation()
- {
- var dt = (float)Game.UpdateTime.Elapsed.TotalSeconds;
+ UpdateAnimation();
+ }
- if (!activated)
- return;
+ public void UpdateAnimation()
+ {
+ var dt = (float)Game.UpdateTime.Elapsed.TotalSeconds;
- spinSpeed = Math.Min(10f, spinSpeed + dt * 15f);
+ if (!activated)
+ return;
- animationTime += dt * 5;
- if (animationTime > Math.PI * 3)
- Entity.Transform.Scale = Vector3.Zero;
- }
+ spinSpeed = Math.Min(10f, spinSpeed + dt * 15f);
- public override void Start()
- {
- base.Start();
+ animationTime += dt * 5;
+ if (animationTime > Math.PI * 3)
+ Entity.Transform.Scale = Vector3.Zero;
+ }
- triggeredEvent = (Trigger != null) ? new EventReceiver(Trigger.TriggerEvent) : null;
+ public override void Start()
+ {
+ base.Start();
- sfxInstance = SoundEffect?.CreateInstance();
- sfxInstance?.Stop();
- }
+ triggeredEvent = (Trigger != null) ? new EventReceiver(Trigger.TriggerEvent) : null;
- protected void CollisionStarted()
- {
- activated = true;
+ sfxInstance = SoundEffect?.CreateInstance();
+ sfxInstance?.Stop();
+ }
- // Play a sound effect
- sfxInstance?.Play();
+ protected void CollisionStarted()
+ {
+ activated = true;
- // Add a visual effect
- var effectMatrix = Matrix.Translation(Entity.Transform.WorldMatrix.TranslationVector);
- this.SpawnPrefabInstance(CoinGetEffect, null, 3, effectMatrix);
+ // Play a sound effect
+ sfxInstance?.Play();
- Func cleanupTask = async () =>
- {
- await Game.WaitTime(TimeSpan.FromMilliseconds(3000));
+ // Add a visual effect
+ var effectMatrix = Matrix.Translation(Entity.Transform.WorldMatrix.TranslationVector);
+ this.SpawnPrefabInstance(CoinGetEffect, null, 3, effectMatrix);
- Game.RemoveEntity(Entity.GetParent());
- };
+ Func cleanupTask = async () =>
+ {
+ await Game.WaitTime(TimeSpan.FromMilliseconds(3000));
- Script.AddTask(cleanupTask);
- }
+ Game.RemoveEntity(Entity.GetParent());
+ };
+
+ Script.AddTask(cleanupTask);
}
}
diff --git a/samples/Templates/TopDownRPG/TopDownRPG/TopDownRPG.Game/Gameplay/MusicScript.cs b/samples/Templates/TopDownRPG/TopDownRPG/TopDownRPG.Game/Gameplay/MusicScript.cs
index d8da8b038c..2fecd98a9d 100644
--- a/samples/Templates/TopDownRPG/TopDownRPG/TopDownRPG.Game/Gameplay/MusicScript.cs
+++ b/samples/Templates/TopDownRPG/TopDownRPG/TopDownRPG.Game/Gameplay/MusicScript.cs
@@ -1,36 +1,35 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
-using System.Threading.Tasks;
+
using Stride.Audio;
using Stride.Engine;
-namespace TopDownRPG.Gameplay
+namespace TopDownRPG.Gameplay;
+
+///
+/// The main script in charge of the sound.
+///
+public class MusicScript : AsyncScript
{
- ///
- /// The main script in charge of the sound.
- ///
- public class MusicScript : AsyncScript
- {
- public Sound SoundMusic { get; set; }
+ public Sound SoundMusic { get; set; }
- private SoundInstance music;
+ private SoundInstance music;
- public override async Task Execute()
- {
- music = SoundMusic.CreateInstance();
+ public override async Task Execute()
+ {
+ music = SoundMusic.CreateInstance();
- if (!IsLiveReloading)
- {
- // start ambient music
- music.IsLooping = true;
- music.Play();
- }
+ if (!IsLiveReloading)
+ {
+ // start ambient music
+ music.IsLooping = true;
+ music.Play();
+ }
- while (Game.IsRunning)
- {
- // wait for next frame
- await Script.NextFrame();
- }
+ while (Game.IsRunning)
+ {
+ // wait for next frame
+ await Script.NextFrame();
}
}
}
diff --git a/samples/Templates/TopDownRPG/TopDownRPG/TopDownRPG.Game/Gameplay/SceneStreaming.cs b/samples/Templates/TopDownRPG/TopDownRPG/TopDownRPG.Game/Gameplay/SceneStreaming.cs
index fc09360246..0930e024f9 100644
--- a/samples/Templates/TopDownRPG/TopDownRPG/TopDownRPG.Game/Gameplay/SceneStreaming.cs
+++ b/samples/Templates/TopDownRPG/TopDownRPG/TopDownRPG.Game/Gameplay/SceneStreaming.cs
@@ -1,161 +1,153 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
-using System;
-using System.Collections.Generic;
-using System.Collections.Specialized;
+
using System.ComponentModel;
-using System.Linq;
-using System.Text;
-using System.Threading;
-using System.Threading.Tasks;
using Stride.Core;
-using Stride.Core.Mathematics;
using Stride.Core.Serialization;
using Stride.Engine;
using Stride.Physics;
-namespace Gameplay
+namespace Gameplay;
+
+public class SceneStreaming : SyncScript
{
- public class SceneStreaming : SyncScript
+ private Task loadingTask;
+ private CancellationTokenSource loadCancellation;
+
+ ///
+ /// The loaded scene
+ ///
+ [DataMemberIgnore]
+ public Scene Instance { get; private set; }
+
+ ///
+ /// The url of the scene to load
+ ///
+ public UrlReference Url { get; set; }
+
+ ///
+ /// The trigger volume. This should be a static collider, set to be a trigger
+ ///
+ public PhysicsComponent Trigger { get; set; }
+
+ ///
+ /// The distance a collider has to enter the trigger before the scene starts loading asynchronously
+ ///
+ [DefaultValue(0.25f)]
+ public float PreLoadDepth { get; set; } = 0.25f;
+
+ ///
+ /// The distance a collider has to enter the trigger before the scene starts loading synchronously
+ ///
+ [DefaultValue(0.5f)]
+ public float LoadDepth { get; set; } = 0.5f;
+
+ public override void Update()
{
- private Task loadingTask;
- private CancellationTokenSource loadCancellation;
-
- ///
- /// The loaded scene
- ///
- [DataMemberIgnore]
- public Scene Instance { get; private set; }
-
- ///
- /// The url of the scene to load
- ///
- public UrlReference Url { get; set; }
-
- ///
- /// The trigger volume. This should be a static collider, set to be a trigger
- ///
- public PhysicsComponent Trigger { get; set; }
-
- ///
- /// The distance a collider has to enter the trigger before the scene starts loading asynchronously
- ///
- [DefaultValue(0.25f)]
- public float PreLoadDepth { get; set; } = 0.25f;
-
- ///
- /// The distance a collider has to enter the trigger before the scene starts loading synchronously
- ///
- [DefaultValue(0.5f)]
- public float LoadDepth { get; set; } = 0.5f;
-
- public override void Update()
- {
- if (Trigger == null)
- return;
+ if (Trigger == null)
+ return;
- bool shouldLoad = false;
- bool shouldPreLoad = false;
- bool shouldUnload = true;
+ bool shouldLoad = false;
+ bool shouldPreLoad = false;
+ bool shouldUnload = true;
- foreach (var collision in Trigger.Collisions)
- {
- // Check all colliders that can collide with the trigger volume
- if ((collision.ColliderA.CanCollideWith & (CollisionFilterGroupFlags)collision.ColliderB.CollisionGroup) == 0 ||
- (collision.ColliderB.CanCollideWith & (CollisionFilterGroupFlags)collision.ColliderA.CollisionGroup) == 0)
- continue;
+ foreach (var collision in Trigger.Collisions)
+ {
+ // Check all colliders that can collide with the trigger volume
+ if ((collision.ColliderA.CanCollideWith & (CollisionFilterGroupFlags)collision.ColliderB.CollisionGroup) == 0 ||
+ (collision.ColliderB.CanCollideWith & (CollisionFilterGroupFlags)collision.ColliderA.CollisionGroup) == 0)
+ continue;
- foreach (var contact in collision.Contacts)
+ foreach (var contact in collision.Contacts)
+ {
+ // Are there any contacts that are deep enough for synchronous loading?
+ if (contact.Distance < -LoadDepth)
{
- // Are there any contacts that are deep enough for synchronous loading?
- if (contact.Distance < -LoadDepth)
- {
- shouldLoad = true;
- shouldUnload = false;
- break;
- }
-
- // Otherwise, are there any contacts that are deep enough for asynchronous loading?
- if (contact.Distance < -PreLoadDepth)
- {
- shouldPreLoad = true;
- shouldUnload = false;
- }
- else if (contact.Distance < 0.0f)
- {
- // Are there any contacts at all?
- shouldUnload = false;
- }
+ shouldLoad = true;
+ shouldUnload = false;
+ break;
}
- if (shouldLoad)
- break;
+ // Otherwise, are there any contacts that are deep enough for asynchronous loading?
+ if (contact.Distance < -PreLoadDepth)
+ {
+ shouldPreLoad = true;
+ shouldUnload = false;
+ }
+ else if (contact.Distance < 0.0f)
+ {
+ // Are there any contacts at all?
+ shouldUnload = false;
+ }
}
- if (!shouldUnload)
+ if (shouldLoad)
+ break;
+ }
+
+ if (!shouldUnload)
+ {
+ // Loading is already in progress, or even finished
+ if (loadingTask == null)
{
- // Loading is already in progress, or even finished
- if (loadingTask == null)
+ if (shouldLoad)
{
- if (shouldLoad)
- {
- // If we should load syncrhonously, just create a completed task and load
- Instance = Content.Load(Url);
- loadingTask = Task.FromResult(Instance);
- }
- else if (shouldPreLoad)
+ // If we should load syncrhonously, just create a completed task and load
+ Instance = Content.Load(Url);
+ loadingTask = Task.FromResult(Instance);
+ }
+ else if (shouldPreLoad)
+ {
+ loadCancellation = new CancellationTokenSource();
+
+ var localLoadingTask = loadingTask = Content.LoadAsync(Url);
+ Script.AddTask(async () =>
{
- loadCancellation = new CancellationTokenSource();
+ await loadingTask;
- var localLoadingTask = loadingTask = Content.LoadAsync(Url);
- Script.AddTask(async () =>
+ // Immediately unload if unload or sync load was triggered in the meantime
+ if (loadCancellation.IsCancellationRequested || loadingTask != localLoadingTask)
+ {
+ Content.Unload(localLoadingTask.Result);
+ loadCancellation = null;
+
+ // Unloading was triggered
+ if (loadingTask == localLoadingTask)
+ loadingTask = null;
+ }
+ else
{
- await loadingTask;
-
- // Immediately unload if unload or sync load was triggered in the meantime
- if (loadCancellation.IsCancellationRequested || loadingTask != localLoadingTask)
- {
- Content.Unload(localLoadingTask.Result);
- loadCancellation = null;
-
- // Unloading was triggered
- if (loadingTask == localLoadingTask)
- loadingTask = null;
- }
- else
- {
- Instance = loadingTask.Result;
- }
- });
- }
+ Instance = loadingTask.Result;
+ }
+ });
}
+ }
- // Once loaded, add it to the scene
- if (Instance != null)
- {
- Instance.Parent = Entity.Scene;
- }
+ // Once loaded, add it to the scene
+ if (Instance != null)
+ {
+ Instance.Parent = Entity.Scene;
}
- else
+ }
+ else
+ {
+ // Cancel loading if currently in progress, and reset state
+ loadCancellation?.Cancel();
+ loadCancellation = null;
+ loadingTask = null;
+
+ // Unload if already finished
+ if (Instance != null)
{
- // Cancel loading if currently in progress, and reset state
- loadCancellation?.Cancel();
- loadCancellation = null;
- loadingTask = null;
+ Content.Unload(Instance);
- // Unload if already finished
- if (Instance != null)
+ // If we were the last user, detach. Ideally scripts should cooperate differently
+ if (!Content.IsLoaded(Url))
{
- Content.Unload(Instance);
-
- // If we were the last user, detach. Ideally scripts should cooperate differently
- if (!Content.IsLoaded(Url))
- {
- Instance.Parent = null;
- }
-
- Instance = null;
+ Instance.Parent = null;
}
+
+ Instance = null;
}
}
}
diff --git a/samples/Templates/TopDownRPG/TopDownRPG/TopDownRPG.Game/Gameplay/Trigger.cs b/samples/Templates/TopDownRPG/TopDownRPG/TopDownRPG.Game/Gameplay/Trigger.cs
index 1b2a6881e9..5856f3de83 100644
--- a/samples/Templates/TopDownRPG/TopDownRPG/TopDownRPG.Game/Gameplay/Trigger.cs
+++ b/samples/Templates/TopDownRPG/TopDownRPG/TopDownRPG.Game/Gameplay/Trigger.cs
@@ -1,80 +1,78 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
-using System;
-using Stride.Engine;
-using Stride.Physics;
-using System.Threading.Tasks;
+
using Stride.Core;
+using Stride.Engine;
using Stride.Engine.Events;
+using Stride.Physics;
+
+namespace TopDownRPG.Gameplay;
-namespace TopDownRPG.Gameplay
+public enum CollisionEventType
{
- public enum CollisionEventType
- {
- ///
- /// Will broadcast an event only when the collision starts
- ///
- [Display("On Start")]
- StartOnly,
+ ///
+ /// Will broadcast an event only when the collision starts
+ ///
+ [Display("On Start")]
+ StartOnly,
- ///
- /// Will broadcast an event only when the collision ends
- ///
- [Display("On End")]
- EndOnly,
+ ///
+ /// Will broadcast an event only when the collision ends
+ ///
+ [Display("On End")]
+ EndOnly,
- ///
- /// Will broadcast an event both when the collision starts and when it ends
- ///
- [Display("On Start and End")]
- StartAndEnd,
- }
+ ///
+ /// Will broadcast an event both when the collision starts and when it ends
+ ///
+ [Display("On Start and End")]
+ StartAndEnd,
+}
- public class Trigger : AsyncScript
- {
- [Display("Condition")]
- public CollisionEventType TriggerCondition { get; set; } = CollisionEventType.StartOnly;
+public class Trigger : AsyncScript
+{
+ [Display("Condition")]
+ public CollisionEventType TriggerCondition { get; set; } = CollisionEventType.StartOnly;
- [DataMemberIgnore]
- public EventKey TriggerEvent = new EventKey();
+ [DataMemberIgnore]
+ public EventKey TriggerEvent = new();
- public override async Task Execute()
- {
- var trigger = Entity.Get();
- // trigger.ProcessCollisions = true;
+ public override async Task Execute()
+ {
+ var trigger = Entity.Get();
+ // trigger.ProcessCollisions = true;
- while (Game.IsRunning)
- {
- // Wait for the next collision event
- var firstCollision = await trigger.NewCollision();
+ while (Game.IsRunning)
+ {
+ // Wait for the next collision event
+ var firstCollision = await trigger.NewCollision();
- // Filter collisions based on collision groups
- var filterAhitB = ((int)firstCollision.ColliderA.CanCollideWith) & ((int)firstCollision.ColliderB.CollisionGroup);
- var filterBhitA = ((int)firstCollision.ColliderB.CanCollideWith) & ((int)firstCollision.ColliderA.CollisionGroup);
- if (filterAhitB == 0 || filterBhitA == 0)
- continue;
+ // Filter collisions based on collision groups
+ var filterAhitB = ((int)firstCollision.ColliderA.CanCollideWith) & ((int)firstCollision.ColliderB.CollisionGroup);
+ var filterBhitA = ((int)firstCollision.ColliderB.CanCollideWith) & ((int)firstCollision.ColliderA.CollisionGroup);
+ if (filterAhitB == 0 || filterBhitA == 0)
+ continue;
- // Broadcast the collision start event
- if (TriggerCondition == CollisionEventType.StartOnly || TriggerCondition == CollisionEventType.StartAndEnd)
- TriggerEvent.Broadcast(true);
+ // Broadcast the collision start event
+ if (TriggerCondition is CollisionEventType.StartOnly or CollisionEventType.StartAndEnd)
+ TriggerEvent.Broadcast(true);
- if (TriggerCondition == CollisionEventType.StartOnly)
- continue;
+ if (TriggerCondition == CollisionEventType.StartOnly)
+ continue;
- // Wait for the collision to end and broadcast that event
- Func collisionEndTask = async () =>
+ // Wait for the collision to end and broadcast that event
+ Func collisionEndTask = async () =>
+ {
+ Collision collision;
+ do
{
- Collision collision;
- do
- {
- collision = await trigger.CollisionEnded();
- } while (collision != firstCollision);
+ collision = await trigger.CollisionEnded();
+ } while (collision != firstCollision);
- TriggerEvent.Broadcast(false);
- };
+ TriggerEvent.Broadcast(false);
+ };
- Script.AddTask(collisionEndTask);
- }
+ Script.AddTask(collisionEndTask);
}
}
}
diff --git a/samples/Templates/TopDownRPG/TopDownRPG/TopDownRPG.Game/Player/AnimationController.cs b/samples/Templates/TopDownRPG/TopDownRPG/TopDownRPG.Game/Player/AnimationController.cs
index 04754faeb6..1665bb129c 100644
--- a/samples/Templates/TopDownRPG/TopDownRPG/TopDownRPG.Game/Player/AnimationController.cs
+++ b/samples/Templates/TopDownRPG/TopDownRPG/TopDownRPG.Game/Player/AnimationController.cs
@@ -1,213 +1,210 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
-using System;
+
+using Stride.Animations;
using Stride.Core;
using Stride.Core.Annotations;
using Stride.Core.Collections;
using Stride.Core.Mathematics;
-using Stride.Animations;
using Stride.Engine;
using Stride.Engine.Events;
-namespace TopDownRPG.Player
+namespace TopDownRPG.Player;
+
+public class AnimationController : SyncScript, IBlendTreeBuilder
{
- public class AnimationController : SyncScript, IBlendTreeBuilder
- {
- [Display("Animation Component")]
- public AnimationComponent AnimationComponent { get; set; }
+ [Display("Animation Component")]
+ public AnimationComponent AnimationComponent { get; set; }
- [Display("Idle")]
- public AnimationClip AnimationIdle { get; set; }
+ [Display("Idle")]
+ public AnimationClip AnimationIdle { get; set; }
- [Display("Walk")]
- public AnimationClip AnimationWalk { get; set; }
+ [Display("Walk")]
+ public AnimationClip AnimationWalk { get; set; }
- [Display("Run")]
- public AnimationClip AnimationRun { get; set; }
+ [Display("Run")]
+ public AnimationClip AnimationRun { get; set; }
- [Display("Punch")]
- public AnimationClip AnimationPunch { get; set; }
+ [Display("Punch")]
+ public AnimationClip AnimationPunch { get; set; }
- [DataMemberRange(0, 1, 0.01, 0.1, 3)]
- [Display("Walk Threshold")]
- public float WalkThreshold { get; set; } = 0.25f;
+ [DataMemberRange(0, 1, 0.01, 0.1, 3)]
+ [Display("Walk Threshold")]
+ public float WalkThreshold { get; set; } = 0.25f;
- [Display("Time Scale")]
- public double TimeFactor { get; set; } = 1;
+ [Display("Time Scale")]
+ public double TimeFactor { get; set; } = 1;
- private AnimationClipEvaluator animEvaluatorIdle;
- private AnimationClipEvaluator animEvaluatorWalk;
- private AnimationClipEvaluator animEvaluatorRun;
- private AnimationClipEvaluator animEvaluatorPunch;
- private double currentTime = 0;
+ private AnimationClipEvaluator animEvaluatorIdle;
+ private AnimationClipEvaluator animEvaluatorWalk;
+ private AnimationClipEvaluator animEvaluatorRun;
+ private AnimationClipEvaluator animEvaluatorPunch;
+ private double currentTime;
- // Idle-Walk-Run lerp
- private AnimationClipEvaluator animEvaluatorWalkLerp1;
- private AnimationClipEvaluator animEvaluatorWalkLerp2;
- private AnimationClip animationClipWalkLerp1;
- private AnimationClip animationClipWalkLerp2;
- private float walkLerpFactor = 0.5f;
+ // Idle-Walk-Run lerp
+ private AnimationClipEvaluator animEvaluatorWalkLerp1;
+ private AnimationClipEvaluator animEvaluatorWalkLerp2;
+ private AnimationClip animationClipWalkLerp1;
+ private AnimationClip animationClipWalkLerp2;
+ private float walkLerpFactor = 0.5f;
- // Internal state
- private readonly EventReceiver runSpeedEvent = new EventReceiver(PlayerController.RunSpeedEventKey);
- private AnimationState state = AnimationState.Walking;
+ // Internal state
+ private readonly EventReceiver runSpeedEvent = new(PlayerController.RunSpeedEventKey);
+ private AnimationState state = AnimationState.Walking;
- private readonly EventReceiver attackEvent = new EventReceiver(PlayerController.IsAttackingEventKey);
+ private readonly EventReceiver attackEvent = new(PlayerController.IsAttackingEventKey);
- float runSpeed;
+ float runSpeed;
- public override void Start()
- {
- base.Start();
+ public override void Start()
+ {
+ base.Start();
+
+ if (AnimationComponent == null)
+ throw new InvalidOperationException("The animation component is not set");
- if (AnimationComponent == null)
- throw new InvalidOperationException("The animation component is not set");
+ if (AnimationIdle == null)
+ throw new InvalidOperationException("Idle animation is not set");
- if (AnimationIdle == null)
- throw new InvalidOperationException("Idle animation is not set");
+ if (AnimationWalk == null)
+ throw new InvalidOperationException("Walking animation is not set");
- if (AnimationWalk == null)
- throw new InvalidOperationException("Walking animation is not set");
+ if (AnimationRun == null)
+ throw new InvalidOperationException("Running animation is not set");
- if (AnimationRun == null)
- throw new InvalidOperationException("Running animation is not set");
+ if (AnimationPunch == null)
+ throw new InvalidOperationException("Punching animation is not set");
- if (AnimationPunch == null)
- throw new InvalidOperationException("Punching animation is not set");
+ // By setting a custom blend tree builder we can override the default behavior of the animation system
+ // Instead, BuildBlendTree(FastList blendStack) will be called each frame
+ AnimationComponent.BlendTreeBuilder = this;
- // By setting a custom blend tree builder we can override the default behavior of the animation system
- // Instead, BuildBlendTree(FastList blendStack) will be called each frame
- AnimationComponent.BlendTreeBuilder = this;
+ animEvaluatorIdle = AnimationComponent.Blender.CreateEvaluator(AnimationIdle);
+ animEvaluatorWalk = AnimationComponent.Blender.CreateEvaluator(AnimationWalk);
+ animEvaluatorRun = AnimationComponent.Blender.CreateEvaluator(AnimationRun);
+ animEvaluatorPunch = AnimationComponent.Blender.CreateEvaluator(AnimationPunch);
- animEvaluatorIdle = AnimationComponent.Blender.CreateEvaluator(AnimationIdle);
- animEvaluatorWalk = AnimationComponent.Blender.CreateEvaluator(AnimationWalk);
- animEvaluatorRun = AnimationComponent.Blender.CreateEvaluator(AnimationRun);
- animEvaluatorPunch = AnimationComponent.Blender.CreateEvaluator(AnimationPunch);
+ // Initial walk lerp
+ walkLerpFactor = 0;
+ animEvaluatorWalkLerp1 = animEvaluatorIdle;
+ animEvaluatorWalkLerp2 = animEvaluatorWalk;
+ animationClipWalkLerp1 = AnimationIdle;
+ animationClipWalkLerp2 = AnimationWalk;
+ }
+
+ public override void Cancel()
+ {
+ AnimationComponent.Blender.ReleaseEvaluator(animEvaluatorIdle);
+ AnimationComponent.Blender.ReleaseEvaluator(animEvaluatorWalk);
+ AnimationComponent.Blender.ReleaseEvaluator(animEvaluatorRun);
+ AnimationComponent.Blender.ReleaseEvaluator(animEvaluatorPunch);
+ }
- // Initial walk lerp
- walkLerpFactor = 0;
+ private void UpdateWalking()
+ {
+ if (runSpeed < WalkThreshold)
+ {
+ walkLerpFactor = runSpeed / WalkThreshold;
+ walkLerpFactor = (float)Math.Sqrt(walkLerpFactor); // Idle-Walk blend looks really werid, so skew the factor towards walking
animEvaluatorWalkLerp1 = animEvaluatorIdle;
animEvaluatorWalkLerp2 = animEvaluatorWalk;
animationClipWalkLerp1 = AnimationIdle;
animationClipWalkLerp2 = AnimationWalk;
}
-
- public override void Cancel()
+ else
{
- AnimationComponent.Blender.ReleaseEvaluator(animEvaluatorIdle);
- AnimationComponent.Blender.ReleaseEvaluator(animEvaluatorWalk);
- AnimationComponent.Blender.ReleaseEvaluator(animEvaluatorRun);
- AnimationComponent.Blender.ReleaseEvaluator(animEvaluatorPunch);
+ walkLerpFactor = (runSpeed - WalkThreshold) / (1.0f - WalkThreshold);
+ animEvaluatorWalkLerp1 = animEvaluatorWalk;
+ animEvaluatorWalkLerp2 = animEvaluatorRun;
+ animationClipWalkLerp1 = AnimationWalk;
+ animationClipWalkLerp2 = AnimationRun;
}
- private void UpdateWalking()
+ // Use DrawTime rather than UpdateTime
+ var time = Game.DrawTime;
+ // This update function will account for animation with different durations, keeping a current time relative to the blended maximum duration
+ long blendedMaxDuration =
+ (long)MathUtil.Lerp(animationClipWalkLerp1.Duration.Ticks, animationClipWalkLerp2.Duration.Ticks, walkLerpFactor);
+
+ var currentTicks = TimeSpan.FromTicks((long)(currentTime * blendedMaxDuration));
+
+ currentTicks = blendedMaxDuration == 0
+ ? TimeSpan.Zero
+ : TimeSpan.FromTicks((currentTicks.Ticks + (long)(time.Elapsed.Ticks * TimeFactor)) %
+ blendedMaxDuration);
+
+ currentTime = (currentTicks.Ticks / (double)blendedMaxDuration);
+ }
+
+ private void UpdatePunching()
+ {
+ const int speedFactor = 1;
+ var currentTicks = TimeSpan.FromTicks((long)(currentTime * AnimationPunch.Duration.Ticks));
+ var updatedTicks = currentTicks.Ticks + (long)(Game.DrawTime.Elapsed.Ticks * TimeFactor * speedFactor);
+
+ if (updatedTicks < AnimationPunch.Duration.Ticks)
{
- if (runSpeed < WalkThreshold)
- {
- walkLerpFactor = runSpeed / WalkThreshold;
- walkLerpFactor = (float)Math.Sqrt(walkLerpFactor); // Idle-Walk blend looks really werid, so skew the factor towards walking
- animEvaluatorWalkLerp1 = animEvaluatorIdle;
- animEvaluatorWalkLerp2 = animEvaluatorWalk;
- animationClipWalkLerp1 = AnimationIdle;
- animationClipWalkLerp2 = AnimationWalk;
- }
- else
- {
- walkLerpFactor = (runSpeed - WalkThreshold) / (1.0f - WalkThreshold);
- animEvaluatorWalkLerp1 = animEvaluatorWalk;
- animEvaluatorWalkLerp2 = animEvaluatorRun;
- animationClipWalkLerp1 = AnimationWalk;
- animationClipWalkLerp2 = AnimationRun;
- }
-
- // Use DrawTime rather than UpdateTime
- var time = Game.DrawTime;
- // This update function will account for animation with different durations, keeping a current time relative to the blended maximum duration
- long blendedMaxDuration = 0;
- blendedMaxDuration =
- (long)MathUtil.Lerp(animationClipWalkLerp1.Duration.Ticks, animationClipWalkLerp2.Duration.Ticks, walkLerpFactor);
-
- var currentTicks = TimeSpan.FromTicks((long)(currentTime * blendedMaxDuration));
-
- currentTicks = blendedMaxDuration == 0
- ? TimeSpan.Zero
- : TimeSpan.FromTicks((currentTicks.Ticks + (long)(time.Elapsed.Ticks * TimeFactor)) %
- blendedMaxDuration);
-
- currentTime = ((double)currentTicks.Ticks / (double)blendedMaxDuration);
+ currentTicks = TimeSpan.FromTicks(updatedTicks);
+ currentTime = (currentTicks.Ticks / (double)AnimationPunch.Duration.Ticks);
}
-
- private void UpdatePunching()
+ else
{
- var speedFactor = 1;
- var currentTicks = TimeSpan.FromTicks((long)(currentTime * AnimationPunch.Duration.Ticks));
- var updatedTicks = currentTicks.Ticks + (long)(Game.DrawTime.Elapsed.Ticks * TimeFactor * speedFactor);
-
- if (updatedTicks < AnimationPunch.Duration.Ticks)
- {
- currentTicks = TimeSpan.FromTicks(updatedTicks);
- currentTime = ((double)currentTicks.Ticks / (double)AnimationPunch.Duration.Ticks);
- }
- else
- {
- state = AnimationState.Walking;
- currentTime = 0;
- UpdateWalking();
- }
+ state = AnimationState.Walking;
+ currentTime = 0;
+ UpdateWalking();
}
+ }
- public override void Update()
+ public override void Update()
+ {
+ // State control
+ runSpeedEvent.TryReceive(out runSpeed);
+
+ if (attackEvent.TryReceive(out var isAttackingNewValue) && isAttackingNewValue && state != AnimationState.Punching)
{
- // State control
- runSpeedEvent.TryReceive(out runSpeed);
-
- bool isAttackingNewValue;
- if (attackEvent.TryReceive(out isAttackingNewValue) && isAttackingNewValue && state != AnimationState.Punching)
- {
- currentTime = 0;
- state = AnimationState.Punching;
- }
-
- switch (state)
- {
- case AnimationState.Walking: UpdateWalking(); break;
- case AnimationState.Punching: UpdatePunching(); break;
- }
+ currentTime = 0;
+ state = AnimationState.Punching;
}
- ///
- /// BuildBlendTree is called every frame from the animation system when the needs to be evaluated
- /// It overrides the default behavior of the by setting a custom blend tree
- ///
- /// The stack of animation operations to be blended
- public void BuildBlendTree(FastList blendStack)
+ switch (state)
{
- switch (state)
- {
- case AnimationState.Walking:
- {
- // Note! The tree is laid out as a stack and has to be flattened before returning it to the animation system!
- blendStack.Add(AnimationOperation.NewPush(animEvaluatorWalkLerp1,
- TimeSpan.FromTicks((long)(currentTime * animationClipWalkLerp1.Duration.Ticks))));
- blendStack.Add(AnimationOperation.NewPush(animEvaluatorWalkLerp2,
- TimeSpan.FromTicks((long)(currentTime * animationClipWalkLerp2.Duration.Ticks))));
- blendStack.Add(AnimationOperation.NewBlend(CoreAnimationOperation.Blend, walkLerpFactor));
- }
- break;
-
- case AnimationState.Punching:
- {
- blendStack.Add(AnimationOperation.NewPush(animEvaluatorPunch,
- TimeSpan.FromTicks((long)(currentTime * AnimationPunch.Duration.Ticks))));
- }
- break;
- }
+ case AnimationState.Walking: UpdateWalking(); break;
+ case AnimationState.Punching: UpdatePunching(); break;
}
+ }
- enum AnimationState
+ ///
+ /// BuildBlendTree is called every frame from the animation system when the needs to be evaluated
+ /// It overrides the default behavior of the by setting a custom blend tree
+ ///
+ /// The stack of animation operations to be blended
+ public void BuildBlendTree(FastList blendStack)
+ {
+ switch (state)
{
- Walking,
- Punching,
+ case AnimationState.Walking:
+ {
+ // Note! The tree is laid out as a stack and has to be flattened before returning it to the animation system!
+ blendStack.Add(AnimationOperation.NewPush(animEvaluatorWalkLerp1,
+ TimeSpan.FromTicks((long)(currentTime * animationClipWalkLerp1.Duration.Ticks))));
+ blendStack.Add(AnimationOperation.NewPush(animEvaluatorWalkLerp2,
+ TimeSpan.FromTicks((long)(currentTime * animationClipWalkLerp2.Duration.Ticks))));
+ blendStack.Add(AnimationOperation.NewBlend(CoreAnimationOperation.Blend, walkLerpFactor));
+ }
+ break;
+
+ case AnimationState.Punching:
+ {
+ blendStack.Add(AnimationOperation.NewPush(animEvaluatorPunch,
+ TimeSpan.FromTicks((long)(currentTime * AnimationPunch.Duration.Ticks))));
+ }
+ break;
}
}
+
+ enum AnimationState
+ {
+ Walking,
+ Punching,
+ }
}
diff --git a/samples/Templates/TopDownRPG/TopDownRPG/TopDownRPG.Game/Player/PlayerController.cs b/samples/Templates/TopDownRPG/TopDownRPG/TopDownRPG.Game/Player/PlayerController.cs
index 9d1543a582..a578725a59 100644
--- a/samples/Templates/TopDownRPG/TopDownRPG/TopDownRPG.Game/Player/PlayerController.cs
+++ b/samples/Templates/TopDownRPG/TopDownRPG/TopDownRPG.Game/Player/PlayerController.cs
@@ -1,7 +1,6 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
-using System;
-using System.Collections.Generic;
+
using Stride.Core;
using Stride.Core.Mathematics;
using Stride.Engine;
@@ -10,293 +9,290 @@
using Stride.Physics;
using TopDownRPG.Core;
-namespace TopDownRPG.Player
+namespace TopDownRPG.Player;
+
+public class PlayerController : SyncScript
{
- public class PlayerController : SyncScript
+ // The character controller does only two things - moves the character and makes it attack close targets
+ // If the character is too far from its target it will run after it until it's close enough then halt movement and attack
+ // If the character is walking towards a specific location instead it will run to it then halt movement when close enough
+
+ private readonly EventReceiver moveDestinationEvent = new(PlayerInput.MoveDestinationEventKey);
+
+ ///
+ /// The maximum speed the character can run at
+ ///
+ [Display("Run Speed")]
+ public float MaxRunSpeed { get; set; } = 10;
+
+ ///
+ /// The distance from the destination at which the character will stop moving
+ ///
+ public float DestinationThreshold { get; set; } = 0.2f;
+
+ ///
+ /// A number from 0 to 1 indicating how much a character should slow down when going around corners
+ ///
+ /// 0 is no slowdown and 1 is completely stopping (on >90 degree angles)
+ public float CornerSlowdown { get; set; } = 0.6f;
+
+ ///
+ /// Multiplied by the distance to the target and clamped to 1 and used to slow down when nearing the destination
+ ///
+ public float DestinationSlowdown { get; set; } = 0.4f;
+
+ // The PlayerController will propagate its speed to the AnimationController
+ public static readonly EventKey RunSpeedEventKey = new();
+
+ // Allow some inertia to the movement
+ private Vector3 moveDirection = Vector3.Zero;
+
+ private bool isRunning;
+
+ // Attacking
+ [Display("Punch Collision")]
+ public RigidbodyComponent PunchCollision { get; set; }
+
+ ///
+ /// The maximum distance from which the character can perform an attack
+ ///
+ [Display("Attack Distance")]
+ public float AttackDistance { get; set; } = 1f;
+
+ ///
+ /// Cooldown in seconds required for the character to recover from starting an attack until it can choose another action
+ ///
+ [Display("Attack Cooldown")]
+ public float AttackCooldown { get; set; } = 0.65f;
+
+ // The PlayerController will propagate if it is attacking to the AnimationController
+ public static readonly EventKey IsAttackingEventKey = new();
+
+ // Character Component
+ private CharacterComponent character;
+ private Entity modelChildEntity;
+ private float yawOrientation;
+
+ private Entity attackEntity;
+ private float attackCooldown;
+
+ // Pathfinding Component
+ private NavigationComponent navigation;
+ private readonly List pathToDestination = [];
+ private int waypointIndex;
+ private Vector3 moveDestination;
+
+ private bool ReachedDestination => waypointIndex >= pathToDestination.Count;
+
+ private Vector3 CurrentWaypoint => waypointIndex < pathToDestination.Count ? pathToDestination[waypointIndex] : Vector3.Zero;
+
+ ///
+ /// Called when the script is first initialized
+ ///
+ public override void Start()
{
- // The character controller does only two things - moves the character and makes it attack close targets
- // If the character is too far from its target it will run after it until it's close enough then halt movement and attack
- // If the character is walking towards a specific location instead it will run to it then halt movement when close enough
-
- private readonly EventReceiver moveDestinationEvent =
- new EventReceiver(PlayerInput.MoveDestinationEventKey);
-
- ///
- /// The maximum speed the character can run at
- ///
- [Display("Run Speed")]
- public float MaxRunSpeed { get; set; } = 10;
-
- ///
- /// The distance from the destination at which the character will stop moving
- ///
- public float DestinationThreshold { get; set; } = 0.2f;
-
- ///
- /// A number from 0 to 1 indicating how much a character should slow down when going around corners
- ///
- /// 0 is no slowdown and 1 is completely stopping (on >90 degree angles)
- public float CornerSlowdown { get; set; } = 0.6f;
-
- ///
- /// Multiplied by the distance to the target and clamped to 1 and used to slow down when nearing the destination
- ///
- public float DestinationSlowdown { get; set; } = 0.4f;
-
- // The PlayerController will propagate its speed to the AnimationController
- public static readonly EventKey RunSpeedEventKey = new EventKey();
-
- // Allow some inertia to the movement
- private Vector3 moveDirection = Vector3.Zero;
-
- private bool isRunning = false;
-
- // Attacking
- [Display("Punch Collision")]
- public RigidbodyComponent PunchCollision { get; set; }
-
- ///
- /// The maximum distance from which the character can perform an attack
- ///
- [Display("Attack Distance")]
- public float AttackDistance { get; set; } = 1f;
-
- ///
- /// Cooldown in seconds required for the character to recover from starting an attack until it can choose another action
- ///
- [Display("Attack Cooldown")]
- public float AttackCooldown { get; set; } = 0.65f;
-
- // The PlayerController will propagate if it is attacking to the AnimationController
- public static readonly EventKey IsAttackingEventKey = new EventKey();
-
- // Character Component
- private CharacterComponent character;
- private Entity modelChildEntity;
- private float yawOrientation;
-
- private Entity attackEntity = null;
- private float attackCooldown = 0f;
-
- // Pathfinding Component
- private NavigationComponent navigation;
- private readonly List pathToDestination = new List();
- private int waypointIndex;
- private Vector3 moveDestination;
-
- private bool ReachedDestination => waypointIndex >= pathToDestination.Count;
-
- private Vector3 CurrentWaypoint => waypointIndex < pathToDestination.Count ? pathToDestination[waypointIndex] : Vector3.Zero;
-
- ///
- /// Called when the script is first initialized
- ///
- public override void Start()
- {
- base.Start();
+ base.Start();
- // Get the navigation component on the same entity as this script
- navigation = Entity.Get();
+ // Get the navigation component on the same entity as this script
+ navigation = Entity.Get();
- // Will search for an CharacterComponent within the same entity as this script
- character = Entity.Get();
- if (character == null) throw new ArgumentException("Please add a CharacterComponent to the entity containing PlayerController!");
+ // Will search for an CharacterComponent within the same entity as this script
+ character = Entity.Get();
+ if (character == null) throw new ArgumentException("Please add a CharacterComponent to the entity containing PlayerController!");
- if (PunchCollision == null) throw new ArgumentException("Please add a RigidbodyComponent as a PunchCollision to the entity containing PlayerController!");
+ if (PunchCollision == null) throw new ArgumentException("Please add a RigidbodyComponent as a PunchCollision to the entity containing PlayerController!");
- modelChildEntity = Entity.GetChild(0);
+ modelChildEntity = Entity.GetChild(0);
- moveDestination = Entity.Transform.WorldMatrix.TranslationVector;
+ moveDestination = Entity.Transform.WorldMatrix.TranslationVector;
- PunchCollision.Enabled = false;
- }
+ PunchCollision.Enabled = false;
+ }
- ///
- /// Called on every frame update
- ///
- public override void Update()
- {
- Attack();
+ ///
+ /// Called on every frame update
+ ///
+ public override void Update()
+ {
+ Attack();
- Move(MaxRunSpeed);
- }
+ Move(MaxRunSpeed);
+ }
- private void Attack()
- {
- var dt = (float) Game.UpdateTime.Elapsed.TotalSeconds;
- attackCooldown = (attackCooldown > 0) ? attackCooldown - dt : 0f;
+ private void Attack()
+ {
+ var dt = (float) Game.UpdateTime.Elapsed.TotalSeconds;
+ attackCooldown = (attackCooldown > 0) ? attackCooldown - dt : 0f;
- PunchCollision.Enabled = (attackCooldown > 0);
+ PunchCollision.Enabled = (attackCooldown > 0);
- if (attackEntity == null)
- return;
+ if (attackEntity == null)
+ return;
- var directionToCharacter = attackEntity.Transform.WorldMatrix.TranslationVector -
- modelChildEntity.Transform.WorldMatrix.TranslationVector;
- directionToCharacter.Y = 0;
+ var directionToCharacter = attackEntity.Transform.WorldMatrix.TranslationVector -
+ modelChildEntity.Transform.WorldMatrix.TranslationVector;
+ directionToCharacter.Y = 0;
- var currentDistance = directionToCharacter.Length();
- if (currentDistance <= AttackDistance)
- {
- // Attack!
- HaltMovement();
+ var currentDistance = directionToCharacter.Length();
+ if (currentDistance <= AttackDistance)
+ {
+ // Attack!
+ HaltMovement();
- attackEntity = null;
- attackCooldown = AttackCooldown;
- PunchCollision.Enabled = true;
- IsAttackingEventKey.Broadcast(true);
- }
- else
- {
- directionToCharacter.Normalize();
- UpdateDestination(attackEntity.Transform.WorldMatrix.TranslationVector);
- }
+ attackEntity = null;
+ attackCooldown = AttackCooldown;
+ PunchCollision.Enabled = true;
+ IsAttackingEventKey.Broadcast(true);
}
-
- private void HaltMovement()
+ else
{
- isRunning = false;
- moveDirection = Vector3.Zero;
- character.SetVelocity(Vector3.Zero);
- moveDestination = modelChildEntity.Transform.WorldMatrix.TranslationVector;
+ directionToCharacter.Normalize();
+ UpdateDestination(attackEntity.Transform.WorldMatrix.TranslationVector);
}
+ }
- private void UpdateDestination(Vector3 destination)
+ private void HaltMovement()
+ {
+ isRunning = false;
+ moveDirection = Vector3.Zero;
+ character.SetVelocity(Vector3.Zero);
+ moveDestination = modelChildEntity.Transform.WorldMatrix.TranslationVector;
+ }
+
+ private void UpdateDestination(Vector3 destination)
+ {
+ Vector3 delta = moveDestination - destination;
+ if (delta.Length() > 0.01f) // Only recalculate path when the target position is different
{
- Vector3 delta = moveDestination - destination;
- if (delta.Length() > 0.01f) // Only recalculate path when the target position is different
+ // Generate a new path using the navigation component
+ pathToDestination.Clear();
+ if (navigation.TryFindPath(destination, pathToDestination))
{
- // Generate a new path using the navigation component
- pathToDestination.Clear();
- if (navigation.TryFindPath(destination, pathToDestination))
+ // Skip the points that are too close to the player
+ waypointIndex = 0;
+ while (!ReachedDestination && (CurrentWaypoint - Entity.Transform.WorldMatrix.TranslationVector).Length() < 0.25f)
{
- // Skip the points that are too close to the player
- waypointIndex = 0;
- while (!ReachedDestination && (CurrentWaypoint - Entity.Transform.WorldMatrix.TranslationVector).Length() < 0.25f)
- {
- waypointIndex++;
- }
-
- // If this path still contains more points, set the player to running
- if (!ReachedDestination)
- {
- isRunning = true;
- moveDestination = destination;
- }
+ waypointIndex++;
}
- else
+
+ // If this path still contains more points, set the player to running
+ if (!ReachedDestination)
{
- // Could not find a path to the target location
- pathToDestination.Clear();
- HaltMovement();
+ isRunning = true;
+ moveDestination = destination;
}
}
+ else
+ {
+ // Could not find a path to the target location
+ pathToDestination.Clear();
+ HaltMovement();
+ }
}
+ }
- private void UpdateMoveTowardsDestination(float speed)
+ private void UpdateMoveTowardsDestination(float speed)
+ {
+ if (!ReachedDestination)
{
- if (!ReachedDestination)
- {
- var direction = CurrentWaypoint - Entity.Transform.WorldMatrix.TranslationVector;
+ var direction = CurrentWaypoint - Entity.Transform.WorldMatrix.TranslationVector;
- // Get distance towards next point and normalize the direction at the same time
- var length = direction.Length();
- direction /= length;
+ // Get distance towards next point and normalize the direction at the same time
+ var length = direction.Length();
+ direction /= length;
- // Check when to advance to the next waypoint
- bool advance = false;
+ // Check when to advance to the next waypoint
+ bool advance = false;
- // Check to see if an intermediate point was passed by projecting the position along the path
- if (pathToDestination.Count > 0 && waypointIndex > 0 && waypointIndex != pathToDestination.Count - 1)
+ // Check to see if an intermediate point was passed by projecting the position along the path
+ if (pathToDestination.Count > 0 && waypointIndex > 0 && waypointIndex != pathToDestination.Count - 1)
+ {
+ Vector3 pointNormal = CurrentWaypoint - pathToDestination[waypointIndex-1];
+ pointNormal.Normalize();
+ float current = Vector3.Dot(Entity.Transform.WorldMatrix.TranslationVector, pointNormal);
+ float target = Vector3.Dot(CurrentWaypoint, pointNormal);
+ if (current > target)
{
- Vector3 pointNormal = CurrentWaypoint - pathToDestination[waypointIndex-1];
- pointNormal.Normalize();
- float current = Vector3.Dot(Entity.Transform.WorldMatrix.TranslationVector, pointNormal);
- float target = Vector3.Dot(CurrentWaypoint, pointNormal);
- if (current > target)
- {
- advance = true;
- }
+ advance = true;
}
- else
+ }
+ else
+ {
+ if (length < DestinationThreshold) // Check distance to final point
{
- if (length < DestinationThreshold) // Check distance to final point
- {
- advance = true;
- }
+ advance = true;
}
+ }
- // Advance waypoint?
- if (advance)
+ // Advance waypoint?
+ if (advance)
+ {
+ waypointIndex++;
+ if (ReachedDestination)
{
- waypointIndex++;
- if (ReachedDestination)
- {
- // Final waypoint reached
- HaltMovement();
- return;
- }
+ // Final waypoint reached
+ HaltMovement();
+ return;
}
+ }
- // Calculate speed based on distance from final destination
- float moveSpeed = (moveDestination - Entity.Transform.WorldMatrix.TranslationVector).Length() * DestinationSlowdown;
- if (moveSpeed > 1.0f)
- moveSpeed = 1.0f;
+ // Calculate speed based on distance from final destination
+ float moveSpeed = (moveDestination - Entity.Transform.WorldMatrix.TranslationVector).Length() * DestinationSlowdown;
+ if (moveSpeed > 1.0f)
+ moveSpeed = 1.0f;
- // Slow down around corners
- float cornerSpeedMultiply = Math.Max(0.0f, Vector3.Dot(direction, moveDirection)) * CornerSlowdown + (1.0f - CornerSlowdown);
+ // Slow down around corners
+ float cornerSpeedMultiply = Math.Max(0.0f, Vector3.Dot(direction, moveDirection)) * CornerSlowdown + (1.0f - CornerSlowdown);
- // Allow a very simple inertia to the character to make animation transitions more fluid
- moveDirection = moveDirection * 0.85f + direction * moveSpeed * cornerSpeedMultiply * 0.15f;
+ // Allow a very simple inertia to the character to make animation transitions more fluid
+ moveDirection = moveDirection * 0.85f + direction * moveSpeed * cornerSpeedMultiply * 0.15f;
- character.SetVelocity(moveDirection * speed);
+ character.SetVelocity(moveDirection * speed);
- // Broadcast speed as per cent of the max speed
- RunSpeedEventKey.Broadcast(moveDirection.Length());
+ // Broadcast speed as per cent of the max speed
+ RunSpeedEventKey.Broadcast(moveDirection.Length());
- // Character orientation
- if (moveDirection.Length() > 0.001)
- {
- yawOrientation = MathUtil.RadiansToDegrees((float) Math.Atan2(-moveDirection.Z, moveDirection.X) + MathUtil.PiOverTwo);
- }
- modelChildEntity.Transform.Rotation = Quaternion.RotationYawPitchRoll(MathUtil.DegreesToRadians(yawOrientation), 0, 0);
- }
- else
+ // Character orientation
+ if (moveDirection.Length() > 0.001)
{
- // No target
- HaltMovement();
+ yawOrientation = MathUtil.RadiansToDegrees((float) Math.Atan2(-moveDirection.Z, moveDirection.X) + MathUtil.PiOverTwo);
}
+ modelChildEntity.Transform.Rotation = Quaternion.RotationYawPitchRoll(MathUtil.DegreesToRadians(yawOrientation), 0, 0);
}
-
- private void Move(float speed)
+ else
{
- if (attackCooldown > 0)
- return;
+ // No target
+ HaltMovement();
+ }
+ }
- // Character speed
- ClickResult clickResult;
- if (moveDestinationEvent.TryReceive(out clickResult) && clickResult.Type != ClickType.Empty)
- {
- if (clickResult.Type == ClickType.Ground)
- {
- attackEntity = null;
- UpdateDestination(clickResult.WorldPosition);
- }
+ private void Move(float speed)
+ {
+ if (attackCooldown > 0)
+ return;
- if (clickResult.Type == ClickType.LootCrate)
- {
- attackEntity = clickResult.ClickedEntity;
- Attack();
- }
+ // Character speed
+ if (moveDestinationEvent.TryReceive(out var clickResult) && clickResult.Type != ClickType.Empty)
+ {
+ if (clickResult.Type == ClickType.Ground)
+ {
+ attackEntity = null;
+ UpdateDestination(clickResult.WorldPosition);
}
- if (!isRunning)
+ if (clickResult.Type == ClickType.LootCrate)
{
- RunSpeedEventKey.Broadcast(0);
- return;
+ attackEntity = clickResult.ClickedEntity;
+ Attack();
}
+ }
- UpdateMoveTowardsDestination(speed);
+ if (!isRunning)
+ {
+ RunSpeedEventKey.Broadcast(0);
+ return;
}
+
+ UpdateMoveTowardsDestination(speed);
}
}
diff --git a/samples/Templates/TopDownRPG/TopDownRPG/TopDownRPG.Game/Player/PlayerInput.cs b/samples/Templates/TopDownRPG/TopDownRPG/TopDownRPG.Game/Player/PlayerInput.cs
index d9d379fae2..6f42f464fa 100644
--- a/samples/Templates/TopDownRPG/TopDownRPG/TopDownRPG.Game/Player/PlayerInput.cs
+++ b/samples/Templates/TopDownRPG/TopDownRPG/TopDownRPG.Game/Player/PlayerInput.cs
@@ -1,6 +1,6 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
-using System.Linq;
+
using Stride.Core.Mathematics;
using Stride.Engine;
using Stride.Engine.Events;
@@ -9,89 +9,86 @@
using Stride.Rendering;
using TopDownRPG.Core;
-namespace TopDownRPG.Player
+namespace TopDownRPG.Player;
+
+public class PlayerInput : SyncScript
{
- public class PlayerInput : SyncScript
- {
- ///
- /// Raised every frame with the intended direction of movement from the player.
- ///
- public static readonly EventKey MoveDestinationEventKey = new EventKey();
+ ///
+ /// Raised every frame with the intended direction of movement from the player.
+ ///
+ public static readonly EventKey MoveDestinationEventKey = new();
- public static readonly EventKey JumpEventKey = new EventKey();
+ public static readonly EventKey JumpEventKey = new();
- public int ControllerIndex { get; set; }
+ public int ControllerIndex { get; set; }
- public float DeadZone { get; set; } = 0.25f;
+ public float DeadZone { get; set; } = 0.25f;
- public Entity Highlight { get; set; }
+ public Entity Highlight { get; set; }
- public Material HighlightMaterial { get; set; }
+ public Material HighlightMaterial { get; set; }
- public CameraComponent Camera { get; set; }
+ public CameraComponent Camera { get; set; }
- public Prefab ClickEffect { get; set; }
+ public Prefab ClickEffect { get; set; }
- private ClickResult lastClickResult;
+ private ClickResult lastClickResult;
- public override void Update()
+ public override void Update()
+ {
+ if (Input.HasMouse)
{
- if (Input.HasMouse)
- {
- ClickResult clickResult;
- Utils.ScreenPositionToWorldPositionRaycast(Input.MousePosition, Camera, this.GetSimulation(), out clickResult);
+ Utils.ScreenPositionToWorldPositionRaycast(Input.MousePosition, Camera, this.GetSimulation(), out var clickResult);
- var isMoving = (Input.IsMouseButtonDown(MouseButton.Left) && lastClickResult.Type == ClickType.Ground && clickResult.Type == ClickType.Ground);
+ var isMoving = (Input.IsMouseButtonDown(MouseButton.Left) && lastClickResult.Type == ClickType.Ground && clickResult.Type == ClickType.Ground);
- var isHighlit = (!isMoving && clickResult.Type == ClickType.LootCrate);
+ var isHighlit = (!isMoving && clickResult.Type == ClickType.LootCrate);
- // Character continuous moving
- if (isMoving)
- {
- lastClickResult.WorldPosition = clickResult.WorldPosition;
- MoveDestinationEventKey.Broadcast(lastClickResult);
- }
+ // Character continuous moving
+ if (isMoving)
+ {
+ lastClickResult.WorldPosition = clickResult.WorldPosition;
+ MoveDestinationEventKey.Broadcast(lastClickResult);
+ }
- // Object highlighting
- if (isHighlit)
- {
- var modelComponentA = Highlight?.Get();
- var modelComponentB = clickResult.ClickedEntity.Get();
-
- if (modelComponentA != null && modelComponentB != null)
- {
- var materialCount = modelComponentB.Model.Materials.Count;
- modelComponentA.Model = modelComponentB.Model;
- modelComponentA.Materials.Clear();
- for (int i = 0; i < materialCount; i++)
- modelComponentA.Materials.Add(i, HighlightMaterial);
-
- modelComponentA.Entity.Transform.UseTRS = false;
- modelComponentA.Entity.Transform.LocalMatrix = modelComponentB.Entity.Transform.WorldMatrix;
- }
- }
- else
+ // Object highlighting
+ if (isHighlit)
+ {
+ var modelComponentA = Highlight?.Get();
+ var modelComponentB = clickResult.ClickedEntity.Get();
+
+ if (modelComponentA != null && modelComponentB != null)
{
- var modelComponentA = Highlight?.Get();
- if (modelComponentA != null)
- modelComponentA.Entity.Transform.LocalMatrix = Matrix.Scaling(0);
+ var materialCount = modelComponentB.Model.Materials.Count;
+ modelComponentA.Model = modelComponentB.Model;
+ modelComponentA.Materials.Clear();
+ for (int i = 0; i < materialCount; i++)
+ modelComponentA.Materials.Add(i, HighlightMaterial);
+
+ modelComponentA.Entity.Transform.UseTRS = false;
+ modelComponentA.Entity.Transform.LocalMatrix = modelComponentB.Entity.Transform.WorldMatrix;
}
}
+ else
+ {
+ var modelComponentA = Highlight?.Get();
+ if (modelComponentA != null)
+ modelComponentA.Entity.Transform.LocalMatrix = Matrix.Scaling(0);
+ }
+ }
- // Mouse-based camera rotation. Only enabled after you click the screen to lock your cursor, pressing escape cancels this
- foreach (var pointerEvent in Input.PointerEvents.Where(x => x.EventType == PointerEventType.Pressed))
+ // Mouse-based camera rotation. Only enabled after you click the screen to lock your cursor, pressing escape cancels this
+ foreach (var pointerEvent in Input.PointerEvents.Where(x => x.EventType == PointerEventType.Pressed))
+ {
+ if (Utils.ScreenPositionToWorldPositionRaycast(pointerEvent.Position, Camera, this.GetSimulation(),
+ out var clickResult))
{
- ClickResult clickResult;
- if (Utils.ScreenPositionToWorldPositionRaycast(pointerEvent.Position, Camera, this.GetSimulation(),
- out clickResult))
- {
- lastClickResult = clickResult;
- MoveDestinationEventKey.Broadcast(clickResult);
+ lastClickResult = clickResult;
+ MoveDestinationEventKey.Broadcast(clickResult);
- if (ClickEffect != null && clickResult.Type == ClickType.Ground)
- {
- this.SpawnPrefabInstance(ClickEffect, null, 1.2f, Matrix.RotationQuaternion(Quaternion.BetweenDirections(Vector3.UnitY, clickResult.HitResult.Normal)) * Matrix.Translation(clickResult.WorldPosition));
- }
+ if (ClickEffect != null && clickResult.Type == ClickType.Ground)
+ {
+ this.SpawnPrefabInstance(ClickEffect, null, 1.2f, Matrix.RotationQuaternion(Quaternion.BetweenDirections(Vector3.UnitY, clickResult.HitResult.Normal)) * Matrix.Translation(clickResult.WorldPosition));
}
}
}
diff --git a/samples/Templates/TopDownRPG/TopDownRPG/TopDownRPG.Game/TopDownRPG.Game.csproj b/samples/Templates/TopDownRPG/TopDownRPG/TopDownRPG.Game/TopDownRPG.Game.csproj
index 4a510e631b..b03770d37d 100644
--- a/samples/Templates/TopDownRPG/TopDownRPG/TopDownRPG.Game/TopDownRPG.Game.csproj
+++ b/samples/Templates/TopDownRPG/TopDownRPG/TopDownRPG.Game/TopDownRPG.Game.csproj
@@ -2,6 +2,8 @@
net8.0
TopDownRPG
+ enable
+ latest
diff --git a/samples/Templates/TopDownRPG/TopDownRPG/TopDownRPG.Windows/TopDownRPG.Windows.csproj b/samples/Templates/TopDownRPG/TopDownRPG/TopDownRPG.Windows/TopDownRPG.Windows.csproj
index 9e5e9a9c6c..1a40851ba9 100644
--- a/samples/Templates/TopDownRPG/TopDownRPG/TopDownRPG.Windows/TopDownRPG.Windows.csproj
+++ b/samples/Templates/TopDownRPG/TopDownRPG/TopDownRPG.Windows/TopDownRPG.Windows.csproj
@@ -7,6 +7,8 @@
..\Bin\Windows\$(Configuration)\
false
STRIDE_PLATFORM_DESKTOP
+ enable
+ latest
$(MSBuildThisFileDirectory)..\TopDownRPG.sdpkg
diff --git a/samples/Templates/VRSandbox/VRSandbox/VRSandbox.Game/Core/InputManagerExtensions.cs b/samples/Templates/VRSandbox/VRSandbox/VRSandbox.Game/Core/InputManagerExtensions.cs
index 61cec60d9a..abc092e06a 100644
--- a/samples/Templates/VRSandbox/VRSandbox/VRSandbox.Game/Core/InputManagerExtensions.cs
+++ b/samples/Templates/VRSandbox/VRSandbox/VRSandbox.Game/Core/InputManagerExtensions.cs
@@ -1,55 +1,43 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
+
using Stride.Core.Mathematics;
using Stride.Input;
-namespace VRSandbox.Core
+namespace VRSandbox.Core;
+
+public static class InputManagerExtensions
{
- public static class InputManagerExtensions
+ public static bool IsGamePadButtonDown(this InputManager input, GamePadButton button, int index)
+ {
+ var gamepad = input.GetGamePadByIndex(index);
+ if (gamepad == null)
+ return false;
+
+ return (gamepad.State.Buttons & button) == button;
+ }
+
+ public static Vector2 GetLeftThumb(this InputManager input, int index)
+ {
+ var gamepad = input.GetGamePadByIndex(index);
+ return gamepad == null ? Vector2.Zero : gamepad.State.LeftThumb;
+ }
+
+ public static Vector2 GetRightThumb(this InputManager input, int index)
+ {
+ var gamepad = input.GetGamePadByIndex(index);
+ return gamepad == null ? Vector2.Zero : gamepad.State.RightThumb;
+ }
+
+ public static float GetLeftTrigger(this InputManager input, int index)
+ {
+ var gamepad = input.GetGamePadByIndex(index);
+ return gamepad == null ? 0.0f : gamepad.State.LeftTrigger;
+ }
+
+ public static float GetRightTrigger(this InputManager input, int index)
{
- public static bool IsGamePadButtonDown(this InputManager input, GamePadButton button, int index)
- {
- var gamepad = input.GetGamePadByIndex(index);
- if (gamepad == null)
- return false;
-
- return (gamepad.State.Buttons & button) == button;
- }
-
- public static Vector2 GetLeftThumb(this InputManager input, int index)
- {
- var gamepad = input.GetGamePadByIndex(index);
- if (gamepad == null)
- return Vector2.Zero;
-
- return gamepad.State.LeftThumb;
- }
-
- public static Vector2 GetRightThumb(this InputManager input, int index)
- {
- var gamepad = input.GetGamePadByIndex(index);
- if (gamepad == null)
- return Vector2.Zero;
-
- return gamepad.State.RightThumb;
- }
-
- public static float GetLeftTrigger(this InputManager input, int index)
- {
- var gamepad = input.GetGamePadByIndex(index);
- if (gamepad == null)
- return 0.0f;
-
- return gamepad.State.LeftTrigger;
- }
-
- public static float GetRightTrigger(this InputManager input, int index)
- {
- var gamepad = input.GetGamePadByIndex(index);
- if (gamepad == null)
- return 0.0f;
-
- return gamepad.State.RightTrigger;
- }
+ var gamepad = input.GetGamePadByIndex(index);
+ return gamepad == null ? 0.0f : gamepad.State.RightTrigger;
}
}
diff --git a/samples/Templates/VRSandbox/VRSandbox/VRSandbox.Game/Core/Utils.cs b/samples/Templates/VRSandbox/VRSandbox/VRSandbox.Game/Core/Utils.cs
index fe966b1985..a10abc7893 100644
--- a/samples/Templates/VRSandbox/VRSandbox/VRSandbox.Game/Core/Utils.cs
+++ b/samples/Templates/VRSandbox/VRSandbox/VRSandbox.Game/Core/Utils.cs
@@ -1,24 +1,24 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
+
using Stride.Core.Mathematics;
using Stride.Engine;
-namespace VRSandbox.Core
+namespace VRSandbox.Core;
+
+public static class Utils
{
- public static class Utils
+ public static Vector3 LogicDirectionToWorldDirection(Vector2 logicDirection, CameraComponent camera, Vector3 upVector)
{
- public static Vector3 LogicDirectionToWorldDirection(Vector2 logicDirection, CameraComponent camera, Vector3 upVector)
- {
- camera.Update();
- var inverseView = Matrix.Invert(camera.ViewMatrix);
+ camera.Update();
+ var inverseView = Matrix.Invert(camera.ViewMatrix);
- var forward = Vector3.Cross(upVector, inverseView.Right);
- forward.Normalize();
+ var forward = Vector3.Cross(upVector, inverseView.Right);
+ forward.Normalize();
- var right = Vector3.Cross(forward, upVector);
- var worldDirection = forward * logicDirection.Y + right * logicDirection.X;
- worldDirection.Normalize();
- return worldDirection;
- }
+ var right = Vector3.Cross(forward, upVector);
+ var worldDirection = forward * logicDirection.Y + right * logicDirection.X;
+ worldDirection.Normalize();
+ return worldDirection;
}
}
diff --git a/samples/Templates/VRSandbox/VRSandbox/VRSandbox.Game/Player/HandController.cs b/samples/Templates/VRSandbox/VRSandbox/VRSandbox.Game/Player/HandController.cs
index 51eda26c23..0bf755f4a2 100644
--- a/samples/Templates/VRSandbox/VRSandbox/VRSandbox.Game/Player/HandController.cs
+++ b/samples/Templates/VRSandbox/VRSandbox/VRSandbox.Game/Player/HandController.cs
@@ -1,230 +1,222 @@
-// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
+// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
-using System;
-using System.Linq;
+
+using Stride.Animations;
using Stride.Core;
-using Stride.Core.Collections;
using Stride.Core.Mathematics;
-using Stride.Animations;
using Stride.Engine;
using Stride.Engine.Events;
using Stride.Physics;
using Stride.VirtualReality;
-namespace VRSandbox.Player
+namespace VRSandbox.Player;
+
+public class HandController : SyncScript
{
- public class HandController : SyncScript
+ private readonly EventReceiver handsControlEvent = new(PlayerInput.HandsControlEventKey);
+
+ [Display("Move Speed")]
+ public float MaxMoveSpeed { get; set; } = 1;
+
+ [Display("Hand")]
+ public HandSide Hand { get; set; } = HandSide.Right;
+
+ private Entity grabbedEntity;
+
+ public Entity Head;
+
+ private AnimationComponent animationComponent;
+
+ private PlayingAnimation animation;
+
+ private VRDeviceSystem vrDeviceSystem;
+
+ public override void Start()
{
- private readonly EventReceiver handsControlEvent = new EventReceiver(PlayerInput.HandsControlEventKey);
+ base.Start();
+
+ vrDeviceSystem = Services.GetService();
- [Display("Move Speed")]
- public float MaxMoveSpeed { get; set; } = 1;
+ animationComponent = Entity.FindChild("Entity")?.Get();
- [Display("Hand")]
- public HandSide Hand { get; set; } = HandSide.Right;
+ // Assume Mars gravity for the sake of more enjoyable game
+ this.GetSimulation().Gravity = new Vector3(0, -3.711f, 0);
- private Entity grabbedEntity;
+ animation = animationComponent?.Play("Grab");
+ if(animation != null)
+ animation.TimeFactor = -1.0f;
+ }
- public Entity Head;
+ ///
+ /// Called on every frame update
+ ///
+ public override void Update()
+ {
+ UpdateVrController();
+ }
- private AnimationComponent animationComponent;
+ // Use this if you have one or two vr controllers (usually one for each hand)
+ private void UpdateVrController()
+ {
+ var vrController = Hand == HandSide.Left ? vrDeviceSystem.Device?.LeftHand : vrDeviceSystem.Device?.RightHand;
- private PlayingAnimation animation;
+ if (vrController == null) return;
- private VRDeviceSystem vrDeviceSystem;
+ if (vrController.State == DeviceState.Invalid) return;
- public override void Start()
- {
- base.Start();
+ Head.Transform.UpdateWorldMatrix();
+ Entity.Transform.Parent.UpdateWorldMatrix();
+ var parentWorldInv = Entity.Transform.Parent.WorldMatrix;
+ parentWorldInv.Invert();
- vrDeviceSystem = Services.GetService();
+ var handPose = Matrix.RotationQuaternion(vrController.Rotation) * Matrix.Translation(vrController.Position);
- animationComponent = Entity.FindChild("Entity")?.Get();
+ var mat = handPose * Head.Transform.WorldMatrix * parentWorldInv;
+ Vector3 scale;
+ mat.Decompose(out scale, out Quaternion rot, out var pos);
+ Entity.Transform.Position = pos;
+ Entity.Transform.Rotation = rot;
- // Assume Mars gravity for the sake of more enjoyable game
- this.GetSimulation().Gravity = new Vector3(0, -3.711f, 0);
+ if (vrController.Trigger > 0.5f)
+ {
+ if (animation != null)
+ animation.TimeFactor = 1.0f;
- animation = animationComponent?.Play("Grab");
- if(animation != null)
- animation.TimeFactor = -1.0f;
+ GrabNewEntity();
}
-
- ///
- /// Called on every frame update
- ///
- public override void Update()
+ else
{
- UpdateVrController();
+ if (animation != null)
+ animation.TimeFactor = -1.0f;
+
+ var rb = grabbedEntity?.Get();
+
+ ReleaseGrabbedEntity();
+
+ rb?.ApplyImpulse(vrController.LinearVelocity);
+ rb?.ApplyTorqueImpulse(vrController.AngularVelocity / 5.0f);
}
+ }
- // Use this if you have one or two vr controllers (usually one for each hand)
- private void UpdateVrController()
- {
- var vrController = Hand == HandSide.Left ? vrDeviceSystem.Device?.LeftHand : vrDeviceSystem.Device?.RightHand;
+ private void GrabNewEntity()
+ {
+ if (grabbedEntity != null)
+ return;
- if (vrController == null) return;
+ var collisions = Entity.Get().Collisions;
+ if (collisions.Count == 0)
+ return;
- if (vrController.State == DeviceState.Invalid) return;
+ var enumerator = collisions.GetEnumerator();
+ while (enumerator.MoveNext())
+ {
+ var collision = enumerator.Current;
+ var entityA = collision.ColliderA?.Entity;
+ var entityB = collision.ColliderB?.Entity;
- Head.Transform.UpdateWorldMatrix();
- Entity.Transform.Parent.UpdateWorldMatrix();
- var parentWorldInv = Entity.Transform.Parent.WorldMatrix;
- parentWorldInv.Invert();
+ var otherEntity = (entityA == Entity) ? entityB : entityA;
- var handPose = Matrix.RotationQuaternion(vrController.Rotation) * Matrix.Translation(vrController.Position);
+ var otherRigidBody = otherEntity?.Get();
+ if (otherRigidBody == null || otherRigidBody.IsKinematic ||
+ otherRigidBody.CollisionGroup == CollisionFilterGroups.CharacterFilter)
+ continue;
- var mat = handPose * Head.Transform.WorldMatrix * parentWorldInv;
- Vector3 pos, scale;
- Quaternion rot;
- mat.Decompose(out scale, out rot, out pos);
- Entity.Transform.Position = pos;
- Entity.Transform.Rotation = rot;
+ grabbedEntity = otherEntity;
+ break;
+ }
- if (vrController.Trigger > 0.5f)
- {
- if (animation != null)
- animation.TimeFactor = 1.0f;
+ if (grabbedEntity == null)
+ return;
- GrabNewEntity();
- }
- else
- {
- if (animation != null)
- animation.TimeFactor = -1.0f;
+ var rigidBody = grabbedEntity?.Get();
+ rigidBody.IsKinematic = true;
+ rigidBody.CanSleep = false;
- var rb = grabbedEntity?.Get();
+ Vector3 sclObject;
- ReleaseGrabbedEntity();
+ // Make sure old positions are up to date
+ grabbedEntity.Transform.UpdateWorldMatrix();
+ grabbedEntity.Transform.WorldMatrix.Decompose(out sclObject, out Quaternion rotObject, out var posObject);
+ var parentEntity = Entity.GetChild(0);
+ parentEntity.Transform.WorldMatrix.Decompose(out var sclParent, out Quaternion rotParent, out var posParent);
- rb?.ApplyImpulse(vrController.LinearVelocity);
- rb?.ApplyTorqueImpulse(vrController.AngularVelocity / 5.0f);
- }
- }
+ // Calculate relative transformations
+ posObject -= posParent;
+ posObject /= sclParent;
+ rotParent.Conjugate();
+ rotParent.Rotate(ref posObject);
+ rotObject = rotParent * rotObject;
- private void GrabNewEntity()
+ // Attach the object to the parent
+ var transformLink = grabbedEntity.Get();
+ if (transformLink != null)
{
- if (grabbedEntity != null)
- return;
-
- var collisions = Entity.Get().Collisions;
- if (collisions.Count == 0)
- return;
-
- var enumerator = collisions.GetEnumerator();
- while (enumerator.MoveNext())
- {
- var collision = enumerator.Current;
- var entityA = collision.ColliderA?.Entity;
- var entityB = collision.ColliderB?.Entity;
-
- var otherEntity = (entityA == Entity) ? entityB : entityA;
-
- var otherRigidBody = otherEntity?.Get();
- if (otherRigidBody == null || otherRigidBody.IsKinematic ||
- otherRigidBody.CollisionGroup == CollisionFilterGroups.CharacterFilter)
- continue;
-
- grabbedEntity = otherEntity;
- break;
- }
-
- if (grabbedEntity == null)
- return;
-
- var rigidBody = grabbedEntity?.Get();
- rigidBody.IsKinematic = true;
- rigidBody.CanSleep = false;
-
- Vector3 posObject, posParent;
- Vector3 sclObject, sclParent;
- Quaternion rotObject, rotParent;
-
- // Make sure old positions are up to date
- grabbedEntity.Transform.UpdateWorldMatrix();
- grabbedEntity.Transform.WorldMatrix.Decompose(out sclObject, out rotObject, out posObject);
- var parentEntity = Entity.GetChild(0);
- parentEntity.Transform.WorldMatrix.Decompose(out sclParent, out rotParent, out posParent);
-
- // Calculate relative transformations
- posObject -= posParent;
- posObject /= sclParent;
- rotParent.Conjugate();
- rotParent.Rotate(ref posObject);
- rotObject = rotParent * rotObject;
-
- // Attach the object to the parent
- var transformLink = grabbedEntity.Get();
- if (transformLink != null)
- {
- transformLink.Target = parentEntity.Get();
- }
- else
- {
- transformLink = new ModelNodeLinkComponent();
- transformLink.Target = parentEntity.Get();
- grabbedEntity.Add(transformLink);
- }
-
- grabbedEntity.Transform.UseTRS = true;
- grabbedEntity.Transform.Position = posObject;
- grabbedEntity.Transform.Rotation = rotObject;
+ transformLink.Target = parentEntity.Get();
}
-
- private void ReleaseGrabbedEntity()
+ else
{
- if (grabbedEntity == null)
- return;
+ transformLink = new ModelNodeLinkComponent { Target = parentEntity.Get() };
+ grabbedEntity.Add(transformLink);
+ }
- var rigidBody = grabbedEntity.Get();
+ grabbedEntity.Transform.UseTRS = true;
+ grabbedEntity.Transform.Position = posObject;
+ grabbedEntity.Transform.Rotation = rotObject;
+ }
- rigidBody.IsKinematic = false;
- rigidBody.CanSleep = true;
+ private void ReleaseGrabbedEntity()
+ {
+ if (grabbedEntity == null)
+ return;
- // Update the entity world matrix and set it as local, because the link will disappear after that
- grabbedEntity.Transform.UpdateWorldMatrix();
- grabbedEntity.Transform.LocalMatrix = grabbedEntity.Transform.WorldMatrix;
+ var rigidBody = grabbedEntity.Get();
- // Remove the model node link
- var transformLink = grabbedEntity.Get();
- if (transformLink != null)
- {
- grabbedEntity.Remove();
- transformLink.Target = null;
- }
+ rigidBody.IsKinematic = false;
+ rigidBody.CanSleep = true;
- grabbedEntity.Transform.UseTRS = false;
- grabbedEntity.Transform.TransformLink = null;
- grabbedEntity.Transform.UpdateWorldMatrix(); // Will set World matrix = Local matrix
+ // Update the entity world matrix and set it as local, because the link will disappear after that
+ grabbedEntity.Transform.UpdateWorldMatrix();
+ grabbedEntity.Transform.LocalMatrix = grabbedEntity.Transform.WorldMatrix;
- grabbedEntity = null;
+ // Remove the model node link
+ var transformLink = grabbedEntity.Get();
+ if (transformLink != null)
+ {
+ grabbedEntity.Remove();
+ transformLink.Target = null;
}
- // Use this if you have a regular controller/gamepad
- private void UpdatePlayerInput()
- {
- var vrController = Hand == HandSide.Left ? vrDeviceSystem.Device?.LeftHand : vrDeviceSystem.Device?.RightHand;
+ grabbedEntity.Transform.UseTRS = false;
+ grabbedEntity.Transform.TransformLink = null;
+ grabbedEntity.Transform.UpdateWorldMatrix(); // Will set World matrix = Local matrix
- if (vrController != null && vrController.State != DeviceState.Invalid) return;
+ grabbedEntity = null;
+ }
- HandsInput handsInput;
- if (!handsControlEvent.TryReceive(out handsInput))
- return;
+ // Use this if you have a regular controller/gamepad
+ private void UpdatePlayerInput()
+ {
+ var vrController = Hand == HandSide.Left ? vrDeviceSystem.Device?.LeftHand : vrDeviceSystem.Device?.RightHand;
- var hand = (int) Hand;
+ if (vrController != null && vrController.State != DeviceState.Invalid) return;
- var dt = (float) (Game.UpdateTime.Elapsed.Milliseconds * 0.001);
+ if (!handsControlEvent.TryReceive(out var handsInput))
+ return;
- // Movement
- var amountMovement = handsInput.HandMovement[hand] * (dt * MaxMoveSpeed);
- Entity.Transform.Position += amountMovement;
+ var hand = (int) Hand;
- // TODO Hand orientation should match the controller orientation
+ var dt = (float) (Game.UpdateTime.Elapsed.Milliseconds * 0.001);
- // Grabbed object
- if (handsInput.HandGrab[hand] >= 0.5f)
- GrabNewEntity();
- else
- ReleaseGrabbedEntity();
- }
+ // Movement
+ var amountMovement = handsInput.HandMovement[hand] * (dt * MaxMoveSpeed);
+ Entity.Transform.Position += amountMovement;
+
+ // TODO Hand orientation should match the controller orientation
+
+ // Grabbed object
+ if (handsInput.HandGrab[hand] >= 0.5f)
+ GrabNewEntity();
+ else
+ ReleaseGrabbedEntity();
}
}
diff --git a/samples/Templates/VRSandbox/VRSandbox/VRSandbox.Game/Player/PlayerInput.cs b/samples/Templates/VRSandbox/VRSandbox/VRSandbox.Game/Player/PlayerInput.cs
index ec72167f33..827fd18c27 100644
--- a/samples/Templates/VRSandbox/VRSandbox/VRSandbox.Game/Player/PlayerInput.cs
+++ b/samples/Templates/VRSandbox/VRSandbox/VRSandbox.Game/Player/PlayerInput.cs
@@ -1,68 +1,76 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// 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.Engine.Events;
using VRSandbox.Core;
-namespace VRSandbox.Player
+namespace VRSandbox.Player;
+
+public enum HandSide
{
- public enum HandSide
- {
- Left = 0,
- Right = 1,
- }
+ Left = 0,
+ Right = 1,
+}
- public class HandsInput
- {
- ///
- /// Movement of each hand since the last frame, in world space units (meters)
- ///
- public Vector3[] HandMovement = new Vector3[System.Enum.GetNames(typeof(HandSide)).Length];
-
- ///
- /// Grabbing power of each hand, 0 being none and 1 being maximum power
- ///
- public float[] HandGrab = new float[System.Enum.GetNames(typeof(HandSide)).Length];
- }
+public class HandsInput
+{
+ ///
+ /// Movement of each hand since the last frame, in world space units (meters)
+ ///
+ public Vector3[] HandMovement = new Vector3[Enum.GetNames(typeof(HandSide)).Length];
- public class PlayerInput : SyncScript
- {
- public static readonly EventKey HandsControlEventKey = new EventKey();
+ ///
+ /// Grabbing power of each hand, 0 being none and 1 being maximum power
+ ///
+ public float[] HandGrab = new float[Enum.GetNames(typeof(HandSide)).Length];
+}
+
+public class PlayerInput : SyncScript
+{
+ public static readonly EventKey HandsControlEventKey = new();
- public int ControllerIndex { get; set; }
+ public int ControllerIndex { get; set; }
- public float DeadZone { get; set; } = 0.25f;
+ public float DeadZone { get; set; } = 0.25f;
- public CameraComponent Camera { get; set; }
+ public CameraComponent Camera { get; set; }
- private Vector3 AsWorldVector(Vector2 inputVector)
- {
- var worldSpeed = (Camera != null)
- ? Utils.LogicDirectionToWorldDirection(inputVector, Camera, Vector3.UnitY)
- : new Vector3(inputVector.X, 0, inputVector.Y);
+ private Vector3 AsWorldVector(Vector2 inputVector)
+ {
+ var worldSpeed = (Camera != null)
+ ? Utils.LogicDirectionToWorldDirection(inputVector, Camera, Vector3.UnitY)
+ : new Vector3(inputVector.X, 0, inputVector.Y);
- var moveLength = inputVector.Length();
- var isDeadZoneLeft = moveLength < DeadZone;
- if (isDeadZoneLeft)
- return Vector3.Zero;
+ var moveLength = inputVector.Length();
+ var isDeadZoneLeft = moveLength < DeadZone;
+ if (isDeadZoneLeft)
+ return Vector3.Zero;
- moveLength = (moveLength > 1) ? 1 : (moveLength - DeadZone) / (1f - DeadZone);
+ moveLength = (moveLength > 1) ? 1 : (moveLength - DeadZone) / (1f - DeadZone);
- worldSpeed *= moveLength;
+ worldSpeed *= moveLength;
- return worldSpeed;
- }
+ return worldSpeed;
+ }
- public override void Update()
+ public override void Update()
+ {
+ var handsInput = new HandsInput
{
- var handsInput = new HandsInput();
- handsInput.HandMovement[(int)HandSide.Left] = AsWorldVector(Input.GetLeftThumb(ControllerIndex));
- handsInput.HandMovement[(int)HandSide.Right] = AsWorldVector(Input.GetRightThumb(ControllerIndex));
- handsInput.HandGrab[(int)HandSide.Left] = Input.GetLeftTrigger(ControllerIndex);
- handsInput.HandGrab[(int)HandSide.Right] = Input.GetRightTrigger(ControllerIndex);
-
- HandsControlEventKey.Broadcast(handsInput);
- }
+ HandMovement =
+ {
+ [(int)HandSide.Left] = AsWorldVector(Input.GetLeftThumb(ControllerIndex)),
+ [(int)HandSide.Right] = AsWorldVector(Input.GetRightThumb(ControllerIndex))
+ },
+ HandGrab =
+ {
+ [(int)HandSide.Left] = Input.GetLeftTrigger(ControllerIndex),
+ [(int)HandSide.Right] = Input.GetRightTrigger(ControllerIndex)
+ }
+ };
+
+ HandsControlEventKey.Broadcast(handsInput);
}
}
diff --git a/samples/Templates/VRSandbox/VRSandbox/VRSandbox.Game/Player/TeleportController.cs b/samples/Templates/VRSandbox/VRSandbox/VRSandbox.Game/Player/TeleportController.cs
index 0c8aeb0866..ffd8961a26 100644
--- a/samples/Templates/VRSandbox/VRSandbox/VRSandbox.Game/Player/TeleportController.cs
+++ b/samples/Templates/VRSandbox/VRSandbox/VRSandbox.Game/Player/TeleportController.cs
@@ -1,94 +1,87 @@
-// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
+// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+
using Stride.Core.Mathematics;
-using Stride.Input;
using Stride.Engine;
using Stride.Particles.Components;
using Stride.Particles.Initializers;
using Stride.VirtualReality;
-namespace Player
+namespace Player;
+
+public class TeleportController : SyncScript
{
- public class TeleportController : SyncScript
- {
- // Declared public member fields and properties will show in the game studio
- public Entity Player { get; set; }
+ // Declared public member fields and properties will show in the game studio
+ public Entity Player { get; set; }
- public Entity Pointer { get; set; }
+ public Entity Pointer { get; set; }
- public Entity Target { get; set; }
+ public Entity Target { get; set; }
- public ParticleSystemComponent Arc { get; set; }
+ public ParticleSystemComponent Arc { get; set; }
- public RectangleF Constraints { get; set; }
+ public RectangleF Constraints { get; set; }
- private VRDeviceSystem vrDeviceSystem;
+ private VRDeviceSystem vrDeviceSystem;
- private bool wasOn = false;
+ private bool wasOn;
- public override void Start()
- {
- base.Start();
+ public override void Start()
+ {
+ base.Start();
+
+ vrDeviceSystem = Services.GetService();
+ }
+
+ public override void Update()
+ {
+ // We need a valid controller, otherwise ignore teleport effects
+ var vrController = vrDeviceSystem.Device?.RightHand;
- vrDeviceSystem = Services.GetService();
+ if (vrController == null) return;
+
+ if (vrController.State == DeviceState.Invalid) return;
+
+ // Do stuff every new frame
+ if (Pointer == null || Target == null)
+ return;
+
+ Vector3 position = Pointer.Transform.WorldMatrix.TranslationVector;
+ var arcHeightBias = (position.Y > 0) ? position.Y : 0;
+ // Shorten the pointer
+ if (position.Y < 0)
+ {
+ var distanceToTarget = Entity.Transform.WorldMatrix.TranslationVector - position;
+ var coefficient = -position.Y / distanceToTarget.Y;
+ position.X += distanceToTarget.X * coefficient;
+ position.Z += distanceToTarget.Z * coefficient;
}
- public override void Update()
+ position.Y = 0.1f;
+ position.X = Math.Min(Math.Max(Constraints.Left, position.X), Constraints.Right);
+ position.Z = Math.Min(Math.Max(Constraints.Top, position.Z), Constraints.Bottom);
+ Target.Transform.Position = position;
+
+ if (Arc == null)
+ return;
+
+ if (Arc.ParticleSystem?.Emitters[0].Initializers[2] is not InitialPositionArc arcInitializer)
+ return;
+
+ var distance = arcHeightBias + (Arc.Entity.Transform.WorldMatrix.TranslationVector - position).Length();
+ arcInitializer.ArcHeight = distance * 0.25f;
+
+ // Turn the arc on and off
+ var isOn = (vrController.IsPressed(TouchControllerButton.A) || (vrController.IsPressed(TouchControllerButton.Thumbstick)));
+ Arc.Enabled = isOn;
+ Target.Get().Enabled = isOn;
+
+ // Teleport
+ if ((wasOn && !isOn) && (Player != null))
{
- // We need a valid controller, otherwise ignore teleport effects
- var vrController = vrDeviceSystem.Device?.RightHand;
-
- if (vrController == null) return;
-
- if (vrController.State == DeviceState.Invalid) return;
-
- // Do stuff every new frame
- if (Pointer == null || Target == null)
- return;
-
- Vector3 position = Pointer.Transform.WorldMatrix.TranslationVector;
- var arcHeightBias = (position.Y > 0) ? position.Y : 0;
- // Shorten the pointer
- if (position.Y < 0)
- {
- var distanceToTarget = Entity.Transform.WorldMatrix.TranslationVector - position;
- var coefficient = -position.Y / distanceToTarget.Y;
- position.X += distanceToTarget.X * coefficient;
- position.Z += distanceToTarget.Z * coefficient;
- }
-
- position.Y = 0.1f;
- position.X = Math.Min(Math.Max(Constraints.Left, position.X), Constraints.Right);
- position.Z = Math.Min(Math.Max(Constraints.Top, position.Z), Constraints.Bottom);
- Target.Transform.Position = position;
-
- if (Arc == null)
- return;
-
- var arcInitializer = Arc.ParticleSystem?.Emitters[0].Initializers[2] as InitialPositionArc;
- if (arcInitializer == null)
- return;
-
- var distance = arcHeightBias + (Arc.Entity.Transform.WorldMatrix.TranslationVector - position).Length();
- arcInitializer.ArcHeight = distance * 0.25f;
-
- // Turn the arc on and off
- var isOn = (vrController.IsPressed(TouchControllerButton.A) || (vrController.IsPressed(TouchControllerButton.Thumbstick)));
- Arc.Enabled = isOn;
- Target.Get().Enabled = isOn;
-
- // Teleport
- if ((wasOn && !isOn) && (Player != null))
- {
- Player.Transform.Position.X = position.X;
- Player.Transform.Position.Z = position.Z;
- }
- wasOn = isOn;
+ Player.Transform.Position.X = position.X;
+ Player.Transform.Position.Z = position.Z;
}
+ wasOn = isOn;
}
}
diff --git a/samples/Templates/VRSandbox/VRSandbox/VRSandbox.Game/VRGame.cs b/samples/Templates/VRSandbox/VRSandbox/VRSandbox.Game/VRGame.cs
index b2ab907c1b..c5349b524c 100644
--- a/samples/Templates/VRSandbox/VRSandbox/VRSandbox.Game/VRGame.cs
+++ b/samples/Templates/VRSandbox/VRSandbox/VRSandbox.Game/VRGame.cs
@@ -1,20 +1,18 @@
-using System;
using Stride.Engine;
using Stride.Graphics;
-namespace VRSandbox
+namespace VRSandbox;
+
+public class VRGame : Game
{
- public class VRGame : Game
+ protected override void BeginRun()
{
- protected override void BeginRun()
- {
- base.BeginRun();
- // Ensure framerate is not capped if the window is in an unexpected state while the user is in VR
- MinimizedMinimumUpdateRate.MinimumElapsedTime = TimeSpan.Zero;
- WindowMinimumUpdateRate.MinimumElapsedTime = TimeSpan.Zero;
- DrawWhileMinimized = true;
- // Present interval only affects the window and is based on the monitor's refresh rate, not the HMD
- GraphicsDevice.Presenter.PresentInterval = PresentInterval.Immediate;
- }
+ base.BeginRun();
+ // Ensure framerate is not capped if the window is in an unexpected state while the user is in VR
+ MinimizedMinimumUpdateRate.MinimumElapsedTime = TimeSpan.Zero;
+ WindowMinimumUpdateRate.MinimumElapsedTime = TimeSpan.Zero;
+ DrawWhileMinimized = true;
+ // Present interval only affects the window and is based on the monitor's refresh rate, not the HMD
+ GraphicsDevice.Presenter.PresentInterval = PresentInterval.Immediate;
}
}
diff --git a/samples/Templates/VRSandbox/VRSandbox/VRSandbox.Game/VRSandbox.Game.csproj b/samples/Templates/VRSandbox/VRSandbox/VRSandbox.Game/VRSandbox.Game.csproj
index 2fa3ccf9da..c92e561012 100644
--- a/samples/Templates/VRSandbox/VRSandbox/VRSandbox.Game/VRSandbox.Game.csproj
+++ b/samples/Templates/VRSandbox/VRSandbox/VRSandbox.Game/VRSandbox.Game.csproj
@@ -2,6 +2,8 @@
net8.0
VRSandbox
+ enable
+ latest
diff --git a/samples/Templates/VRSandbox/VRSandbox/VRSandbox.Windows/VRSandbox.Windows.csproj b/samples/Templates/VRSandbox/VRSandbox/VRSandbox.Windows/VRSandbox.Windows.csproj
index 8fb8d853c8..621667c7af 100644
--- a/samples/Templates/VRSandbox/VRSandbox/VRSandbox.Windows/VRSandbox.Windows.csproj
+++ b/samples/Templates/VRSandbox/VRSandbox/VRSandbox.Windows/VRSandbox.Windows.csproj
@@ -7,6 +7,8 @@
..\Bin\Windows\$(Configuration)\
false
STRIDE_PLATFORM_DESKTOP
+ enable
+ latest
$(MSBuildThisFileDirectory)..\VRSandbox.sdpkg
diff --git a/samples/Tutorials/CSharpBeginner/CSharpBeginner/CSharpBeginner.Game/Code/AddingAComponentDemo.cs b/samples/Tutorials/CSharpBeginner/CSharpBeginner/CSharpBeginner.Game/Code/AddingAComponentDemo.cs
index abc69d53ae..ace36e3557 100644
--- a/samples/Tutorials/CSharpBeginner/CSharpBeginner/CSharpBeginner.Game/Code/AddingAComponentDemo.cs
+++ b/samples/Tutorials/CSharpBeginner/CSharpBeginner/CSharpBeginner.Game/Code/AddingAComponentDemo.cs
@@ -1,44 +1,43 @@
using Stride.Core.Mathematics;
using Stride.Engine;
-namespace CSharpBeginner.Code
+namespace CSharpBeginner.Code;
+
+///
+/// This script demonstrates how to add a component to an entiy.
+/// We also learn a way to automically create and attach a component to our entity.
+///
+/// https://doc.stride3d.net/latest/en/tutorials/csharpbeginner/add-component.html
+///
+///
+public class AddingAComponentDemo : SyncScript
{
- ///
- /// This script demonstrates how to add a component to an entiy.
- /// We also learn a way to automically create and attach a component to our entity.
- ///
- /// https://doc.stride3d.net/latest/en/tutorials/csharpbeginner/add-component.html
- ///
- ///
- public class AddingAComponentDemo : SyncScript
+ private AmmoComponent ammoComponent1;
+ private AmmoComponent ammoComponent2;
+ private AmmoComponent ammoComponent3;
+
+ public override void Start()
+ {
+ // We can add a new component to an entity using the 'Add' method.
+ ammoComponent1 = new AmmoComponent();
+ Entity.Add(ammoComponent1);
+
+ // We can even add the component a second time
+ ammoComponent2 = new AmmoComponent();
+ Entity.Add(ammoComponent2);
+
+ // Lets remove all components of type AmmoComponent
+ Entity.RemoveAll();
+
+
+ // When there is no AmmoComponent of attached, but we like there to be one, we can create it automatically
+ // NOTE: when a component is created this way,
+ // the 'Start' method of the AmmoComponent will be called after this script's Update method has executed
+ ammoComponent3 = Entity.GetOrCreate();
+ }
+
+ public override void Update()
{
- private AmmoComponent ammoComponent1;
- private AmmoComponent ammoComponent2;
- private AmmoComponent ammoComponent3;
-
- public override void Start()
- {
- // We can add a new component to an entity using the 'Add' method.
- ammoComponent1 = new AmmoComponent();
- Entity.Add(ammoComponent1);
-
- // We can even add the component a second time
- ammoComponent2 = new AmmoComponent();
- Entity.Add(ammoComponent2);
-
- // Lets remove all components of type AmmoComponent
- Entity.RemoveAll();
-
-
- // When there is no AmmoComponent of attached, but we like there to be one, we can create it automatically
- // NOTE: when a component is created this way,
- // the 'Start' method of the AmmoComponent will be called after this script's Update method has executed
- ammoComponent3 = Entity.GetOrCreate();
- }
-
- public override void Update()
- {
- DebugText.Print("Remaining ammo: " + ammoComponent3.GetRemainingAmmo().ToString(), new Int2(440, 200));
- }
+ DebugText.Print("Remaining ammo: " + ammoComponent3.GetRemainingAmmo().ToString(), new Int2(440, 200));
}
}
diff --git a/samples/Tutorials/CSharpBeginner/CSharpBeginner/CSharpBeginner.Game/Code/AmmoComponent.cs b/samples/Tutorials/CSharpBeginner/CSharpBeginner/CSharpBeginner.Game/Code/AmmoComponent.cs
index 90b61ab33b..dd5c045c64 100644
--- a/samples/Tutorials/CSharpBeginner/CSharpBeginner/CSharpBeginner.Game/Code/AmmoComponent.cs
+++ b/samples/Tutorials/CSharpBeginner/CSharpBeginner/CSharpBeginner.Game/Code/AmmoComponent.cs
@@ -1,20 +1,19 @@
using Stride.Engine;
-namespace CSharpBeginner.Code
+namespace CSharpBeginner.Code;
+
+///
+/// This script is used in combination with the GettingAComponent.cs script
+///
+public class AmmoComponent : StartupScript
{
- ///
- /// This script is used in combination with the GettingAComponent.cs script
- ///
- public class AmmoComponent : StartupScript
- {
- private readonly int maxBullets = 30;
- private readonly int currentBullets = 12;
+ private readonly int maxBullets = 30;
+ private readonly int currentBullets = 12;
- public override void Start() { }
+ public override void Start() { }
- public int GetRemainingAmmo()
- {
- return maxBullets - currentBullets;
- }
+ public int GetRemainingAmmo()
+ {
+ return maxBullets - currentBullets;
}
}
diff --git a/samples/Tutorials/CSharpBeginner/CSharpBeginner/CSharpBeginner.Game/Code/ChildEntitiesDemo.cs b/samples/Tutorials/CSharpBeginner/CSharpBeginner/CSharpBeginner.Game/Code/ChildEntitiesDemo.cs
index a093322841..f9dfbd17f9 100644
--- a/samples/Tutorials/CSharpBeginner/CSharpBeginner/CSharpBeginner.Game/Code/ChildEntitiesDemo.cs
+++ b/samples/Tutorials/CSharpBeginner/CSharpBeginner/CSharpBeginner.Game/Code/ChildEntitiesDemo.cs
@@ -1,51 +1,50 @@
using Stride.Core.Mathematics;
using Stride.Engine;
-namespace CSharpBeginner.Code
+namespace CSharpBeginner.Code;
+
+///
+/// This script is used to demonstrate how we can get child entities of an entity
+///
+/// https://doc.stride3d.net/latest/en/tutorials/csharpbeginner/child-entities.html
+///
+///
+public class ChildEntitiesDemo : SyncScript
{
- ///
- /// This script is used to demonstrate how we can get child entities of an entity
- ///
- /// https://doc.stride3d.net/latest/en/tutorials/csharpbeginner/child-entities.html
- ///
- ///
- public class ChildEntitiesDemo : SyncScript
+ private Entity child0;
+ private Entity child1;
+
+ public override void Start()
{
- private Entity child0;
- private Entity child1;
+ // We can get a child by using GetChild(). This takes an index number starting at 0
+ child0 = Entity.GetChild(0);
+ child1 = Entity.GetChild(1);
- public override void Start()
- {
- // We can get a child by using GetChild(). This takes an index number starting at 0
- child0 = Entity.GetChild(0);
- child1 = Entity.GetChild(1);
+ // If we would try to get Child 3 (which doesn't exist), we would get an exception
+ // var nonExistingChild = Entity.GetChild(2);
+ }
- // If we would try to get Child 3 (which doesn't exist), we would get an exception
- // var nonExistingChild = Entity.GetChild(2);
- }
+ public override void Update()
+ {
+ // We store some drawing positions
+ int drawX = 350, drawY = 230, increment = 70;
- public override void Update()
- {
- // We store some drawing positions
- int drawX = 350, drawY = 230, increment = 70;
+ // We print the name of the our entity
+ DebugText.Print(Entity.Name, new Int2(drawX, drawY));
- // We print the name of the our entity
- DebugText.Print(Entity.Name, new Int2(drawX, drawY));
+ // We loop over all the children of our entity using GetChildren()
+ // NOTE: This does not include any subchildren of those children
+ foreach (var child in Entity.GetChildren())
+ {
+ // We print the name of the child
+ drawY += increment;
+ DebugText.Print(child.Name, new Int2(drawX + increment, drawY));
- // We loop over all the children of our entity using GetChildren()
- // NOTE: This does not include any subchildren of those children
- foreach (var child in Entity.GetChildren())
+ // It is possible that this child, also has children. We now loop over these 'subchildren' and print their name too
+ foreach (var subChild in child.GetChildren())
{
- // We print the name of the child
drawY += increment;
- DebugText.Print(child.Name, new Int2(drawX + increment, drawY));
-
- // It is possible that this child, also has children. We now loop over these 'subchildren' and print their name too
- foreach (var subChild in child.GetChildren())
- {
- drawY += increment;
- DebugText.Print(subChild.Name, new Int2(drawX + (increment * 2), drawY));
- }
+ DebugText.Print(subChild.Name, new Int2(drawX + (increment * 2), drawY));
}
}
}
diff --git a/samples/Tutorials/CSharpBeginner/CSharpBeginner/CSharpBeginner.Game/Code/CloneEntityDemo.cs b/samples/Tutorials/CSharpBeginner/CSharpBeginner/CSharpBeginner.Game/Code/CloneEntityDemo.cs
index 805fca23de..eab0b6091c 100644
--- a/samples/Tutorials/CSharpBeginner/CSharpBeginner/CSharpBeginner.Game/Code/CloneEntityDemo.cs
+++ b/samples/Tutorials/CSharpBeginner/CSharpBeginner/CSharpBeginner.Game/Code/CloneEntityDemo.cs
@@ -1,69 +1,68 @@
using Stride.Core.Mathematics;
using Stride.Engine;
-namespace CSharpBeginner.Code
+namespace CSharpBeginner.Code;
+
+///
+/// This script demonstrates how to clone an existing entity.
+/// Cloned entities can be added to the scene hierarchy.
+///
+/// https://doc.stride3d.net/latest/en/tutorials/csharpbeginner/cloning-entities.html
+///
+///
+public class CloneEntityDemo : SyncScript
{
- ///
- /// This script demonstrates how to clone an existing entity.
- /// Cloned entities can be added to the scene hierarchy.
- ///
- /// https://doc.stride3d.net/latest/en/tutorials/csharpbeginner/cloning-entities.html
- ///
- ///
- public class CloneEntityDemo : SyncScript
- {
- public Entity MasterSword;
+ public Entity MasterSword;
- private Entity clone1;
- private Entity clone2;
- private Entity clone3;
+ private Entity clone1;
+ private Entity clone2;
+ private Entity clone3;
- public override void Start()
- {
- // Clone 0
- // The Clone method clones an existing entity, including all of its components
- // However, if we don't add it to the scene, we will never get to see it.
- var clone0 = MasterSword.Clone();
- clone0.Transform.Position += new Vector3(0, 1, 0);
+ public override void Start()
+ {
+ // Clone 0
+ // The Clone method clones an existing entity, including all of its components
+ // However, if we don't add it to the scene, we will never get to see it.
+ var clone0 = MasterSword.Clone();
+ clone0.Transform.Position += new Vector3(0, 1, 0);
- // Clone 1
- // We can add Clone1 to the same scene that the current entity is part of
- clone1 = MasterSword.Clone();
- Entity.Scene.Entities.Add(clone1);
- // The cloned entity will be at the same worldposition as the original Sword entity
- // Move it to the right so that we can see it
- clone1.Transform.Position += new Vector3(-1, 0, 0);
- clone1.Transform.Scale *= new Vector3(0.8f);
+ // Clone 1
+ // We can add Clone1 to the same scene that the current entity is part of
+ clone1 = MasterSword.Clone();
+ Entity.Scene.Entities.Add(clone1);
+ // The cloned entity will be at the same worldposition as the original Sword entity
+ // Move it to the right so that we can see it
+ clone1.Transform.Position += new Vector3(-1, 0, 0);
+ clone1.Transform.Scale *= new Vector3(0.8f);
- // Clone 2
- // We can also add a cloned entity as a child of an existing entity.
- clone2 = MasterSword.Clone();
- Entity.AddChild(clone2);
- clone2.Transform.Position += new Vector3(1, 0, 0);
- clone2.Transform.Scale = new Vector3(0.6f);
+ // Clone 2
+ // We can also add a cloned entity as a child of an existing entity.
+ clone2 = MasterSword.Clone();
+ Entity.AddChild(clone2);
+ clone2.Transform.Position += new Vector3(1, 0, 0);
+ clone2.Transform.Scale = new Vector3(0.6f);
- // Clone 3
- // We can also add a cloned entity as a child of an existing entity by setting the parent
- // That means it will use the parent's world position + parent's local position
- clone3 = MasterSword.Clone();
- clone3.Transform.Parent = Entity.Transform; // Or Entity.SetParent(Entity.Transform)
- clone3.Transform.Position += new Vector3(0, 0, -0.5f);
- clone3.Transform.Scale = new Vector3(0.4f);
- }
+ // Clone 3
+ // We can also add a cloned entity as a child of an existing entity by setting the parent
+ // That means it will use the parent's world position + parent's local position
+ clone3 = MasterSword.Clone();
+ clone3.Transform.Parent = Entity.Transform; // Or Entity.SetParent(Entity.Transform)
+ clone3.Transform.Position += new Vector3(0, 0, -0.5f);
+ clone3.Transform.Scale = new Vector3(0.4f);
+ }
- public override void Update()
- {
- DebugText.Print("This is the MasterSword, with a Z of 1", new Int2(500, 320));
- DebugText.Print("Clone 0 has not been added to the scene and is therefore not visible", new Int2(600, 250));
+ public override void Update()
+ {
+ DebugText.Print("This is the MasterSword, with a Z of 1", new Int2(500, 320));
+ DebugText.Print("Clone 0 has not been added to the scene and is therefore not visible", new Int2(600, 250));
- DebugText.Print("Clone 1 is placed in the same scene as the entity with the script", new Int2(700, 600));
- DebugText.Print("Clone 1 got the same world position as the 'MasterSword'...", new Int2(700, 620));
- DebugText.Print("... and was then moved to the right", new Int2(700, 640));
+ DebugText.Print("Clone 1 is placed in the same scene as the entity with the script", new Int2(700, 600));
+ DebugText.Print("Clone 1 got the same world position as the 'MasterSword'...", new Int2(700, 620));
+ DebugText.Print("... and was then moved to the right", new Int2(700, 640));
- DebugText.Print("Clone 2 and 3 are a child of 'MasterSword'.", new Int2(330, 600));
- }
+ DebugText.Print("Clone 2 and 3 are a child of 'MasterSword'.", new Int2(330, 600));
}
}
diff --git a/samples/Tutorials/CSharpBeginner/CSharpBeginner/CSharpBeginner.Game/Code/DeltaTimeDemo.cs b/samples/Tutorials/CSharpBeginner/CSharpBeginner/CSharpBeginner.Game/Code/DeltaTimeDemo.cs
index abfe9c5724..f13a55bfa1 100644
--- a/samples/Tutorials/CSharpBeginner/CSharpBeginner/CSharpBeginner.Game/Code/DeltaTimeDemo.cs
+++ b/samples/Tutorials/CSharpBeginner/CSharpBeginner/CSharpBeginner.Game/Code/DeltaTimeDemo.cs
@@ -1,55 +1,54 @@
using Stride.Core.Mathematics;
using Stride.Engine;
-namespace CSharpBeginner.Code
+namespace CSharpBeginner.Code;
+
+///
+/// DeltaTime is used to calculate frame independent values.
+/// DeltaTime can also be used for creating Timers.
+///
+/// https://doc.stride3d.net/latest/en/tutorials/csharpbeginner/delta-time.html
+///
+///
+public class DeltaTimeDemo : SyncScript
{
- ///
- /// DeltaTime is used to calculate frame independent values.
- /// DeltaTime can also be used for creating Timers.
- ///
- /// https://doc.stride3d.net/latest/en/tutorials/csharpbeginner/delta-time.html
- ///
- ///
- public class DeltaTimeDemo : SyncScript
- {
- private float rotationSpeed = 0.6f;
+ private float rotationSpeed = 0.6f;
- // In this variable we keep track of the total time the game runs
- private float totalTime = 0;
+ // In this variable we keep track of the total time the game runs
+ private float totalTime = 0;
- // We use these variable for creating a simple countdown timer
- private float countdownStartTime = 5.0f;
- private float countdownTime = 0;
+ // We use these variable for creating a simple countdown timer
+ private float countdownStartTime = 5.0f;
+ private float countdownTime = 0;
- public override void Start()
- {
- // We start the countdown timer at the initial countdown time of 5 seconds
- countdownTime = countdownStartTime;
- }
+ public override void Start()
+ {
+ // We start the countdown timer at the initial countdown time of 5 seconds
+ countdownTime = countdownStartTime;
+ }
- public override void Update()
- {
- /// We can access Delta time through the static 'Game' object.
- var deltaTime = (float)Game.UpdateTime.Elapsed.TotalSeconds;
+ public override void Update()
+ {
+ // We can access Delta time through the static 'Game' object.
+ var deltaTime = (float)Game.UpdateTime.Elapsed.TotalSeconds;
- // We update the total time
- totalTime += deltaTime;
+ // We update the total time
+ totalTime += deltaTime;
- // Since we have a countdown timer, we subtract the delta time from the count down time
- countdownTime -= deltaTime;
+ // Since we have a countdown timer, we subtract the delta time from the count down time
+ countdownTime -= deltaTime;
- // If the repeatTimer, reaches 0, we reset the countdownTime back to the count down start time
- if (countdownTime < 0)
- {
- countdownTime = countdownStartTime;
- rotationSpeed *= -1;
- }
+ // If the repeatTimer, reaches 0, we reset the countdownTime back to the count down start time
+ if (countdownTime < 0)
+ {
+ countdownTime = countdownStartTime;
+ rotationSpeed *= -1;
+ }
- Entity.Transform.Rotation *= Quaternion.RotationY(deltaTime * rotationSpeed);
+ Entity.Transform.Rotation *= Quaternion.RotationY(deltaTime * rotationSpeed);
- // We display the total time and the countdown time on screen
- DebugText.Print("Total time: " + totalTime, new Int2(480, 540));
- DebugText.Print("Countdown time: " + countdownTime, new Int2(480, 560));
- }
+ // We display the total time and the countdown time on screen
+ DebugText.Print("Total time: " + totalTime, new Int2(480, 540));
+ DebugText.Print("Countdown time: " + countdownTime, new Int2(480, 560));
}
}
diff --git a/samples/Tutorials/CSharpBeginner/CSharpBeginner/CSharpBeginner.Game/Code/GettingAComponentDemo.cs b/samples/Tutorials/CSharpBeginner/CSharpBeginner/CSharpBeginner.Game/Code/GettingAComponentDemo.cs
index 659a6b5144..450477fce6 100644
--- a/samples/Tutorials/CSharpBeginner/CSharpBeginner/CSharpBeginner.Game/Code/GettingAComponentDemo.cs
+++ b/samples/Tutorials/CSharpBeginner/CSharpBeginner/CSharpBeginner.Game/Code/GettingAComponentDemo.cs
@@ -1,49 +1,48 @@
using Stride.Core.Mathematics;
using Stride.Engine;
-namespace CSharpBeginner.Code
-{
- ///
- /// This script demonstrates how to get and remove components that are attached to an entity.
- /// Try not to Get a component every frame as this will have negative performance impact.
- /// Instead try to cache a component in the start method or when an object is initialized/triggered
- ///
- /// https://doc.stride3d.net/latest/en/tutorials/csharpbeginner/get-component.html
- ///
- ///
- public class GettingAComponentDemo : SyncScript
- {
- private int ammoCount1 = 0;
- private int ammoCount2 = 0;
+namespace CSharpBeginner.Code;
- public override void Start()
- {
- // We retrieve the Ammo component that is also attached to the current entity
- var ammoComponent1 = Entity.Get();
+///
+/// This script demonstrates how to get and remove components that are attached to an entity.
+/// Try not to Get a component every frame as this will have negative performance impact.
+/// Instead try to cache a component in the start method or when an object is initialized/triggered
+///
+/// https://doc.stride3d.net/latest/en/tutorials/csharpbeginner/get-component.html
+///
+///
+public class GettingAComponentDemo : SyncScript
+{
+ private int ammoCount1 = 0;
+ private int ammoCount2 = 0;
- // We can now access public methods and properties of the retrieve component
- ammoCount1 = ammoComponent1.GetRemainingAmmo();
+ public override void Start()
+ {
+ // We retrieve the Ammo component that is also attached to the current entity
+ var ammoComponent1 = Entity.Get();
- // We now remove the AmmoComponent from our entity. If we try to retrieve it again, null will be returned
- Entity.Remove();
- var ammoComponent2 = Entity.Get();
+ // We can now access public methods and properties of the retrieve component
+ ammoCount1 = ammoComponent1.GetRemainingAmmo();
- // Now that 'ammoComponent' is null, we will never be able to retrieve the total ammo
- if (ammoComponent2 != null)
- {
- // This line will never happen
- ammoCount2 = ammoComponent2.GetRemainingAmmo();
- }
+ // We now remove the AmmoComponent from our entity. If we try to retrieve it again, null will be returned
+ Entity.Remove();
+ var ammoComponent2 = Entity.Get();
- // Add the component again so that it doesn't crash next run
- Entity.Add(ammoComponent1);
- }
-
- public override void Update()
+ // Now that 'ammoComponent' is null, we will never be able to retrieve the total ammo
+ if (ammoComponent2 != null)
{
- // We display the stored ammo count on screen
- DebugText.Print("Ammo count 1: " + ammoCount1.ToString(), new Int2(300, 200));
- DebugText.Print("Ammo count 2: " + ammoCount2.ToString(), new Int2(300, 220));
+ // This line will never happen
+ ammoCount2 = ammoComponent2.GetRemainingAmmo();
}
+
+ // Add the component again so that it doesn't crash next run
+ Entity.Add(ammoComponent1);
+ }
+
+ public override void Update()
+ {
+ // We display the stored ammo count on screen
+ DebugText.Print("Ammo count 1: " + ammoCount1.ToString(), new Int2(300, 200));
+ DebugText.Print("Ammo count 2: " + ammoCount2.ToString(), new Int2(300, 220));
}
}
diff --git a/samples/Tutorials/CSharpBeginner/CSharpBeginner/CSharpBeginner.Game/Code/GettingTheEntityDemo.cs b/samples/Tutorials/CSharpBeginner/CSharpBeginner/CSharpBeginner.Game/Code/GettingTheEntityDemo.cs
index ec47d5138e..72d82aa854 100644
--- a/samples/Tutorials/CSharpBeginner/CSharpBeginner/CSharpBeginner.Game/Code/GettingTheEntityDemo.cs
+++ b/samples/Tutorials/CSharpBeginner/CSharpBeginner/CSharpBeginner.Game/Code/GettingTheEntityDemo.cs
@@ -1,47 +1,46 @@
using Stride.Core.Mathematics;
using Stride.Engine;
-namespace CSharpBeginner.Code
-{
- ///
- /// This script demonstrates how to access the entity where the script is attached to.
- /// We also learn how to access a parent of our entity and how to check if that entity exists.
- ///
- /// https://doc.stride3d.net/latest/en/tutorials/csharpbeginner/entity.html
- ///
- ///
- public class GettingTheEntityDemo : SyncScript
- {
- private string name = string.Empty;
- private string parentName = string.Empty;
+namespace CSharpBeginner.Code;
- // Executes only once, at the start of the game
- public override void Start()
- {
- // We store the name of the Entity that we are attached to
- name = Entity.Name;
+///
+/// This script demonstrates how to access the entity where the script is attached to.
+/// We also learn how to access a parent of our entity and how to check if that entity exists.
+///
+/// https://doc.stride3d.net/latest/en/tutorials/csharpbeginner/entity.html
+///
+///
+public class GettingTheEntityDemo : SyncScript
+{
+ private string name = string.Empty;
+ private string parentName = string.Empty;
- // We retrieve the parent entity by using the GetParent() command.
- var parentEntity = Entity.GetParent();
+ // Executes only once, at the start of the game
+ public override void Start()
+ {
+ // We store the name of the Entity that we are attached to
+ name = Entity.Name;
- // It is possible that our entity does not have a parent. We therefore check if the parent is not null.
- if (parentEntity != null)
- {
- // We store the name of our Parent entity
- parentName = parentEntity.Name;
- }
+ // We retrieve the parent entity by using the GetParent() command.
+ var parentEntity = Entity.GetParent();
- // The above code can be shortened to 1 line by using the '?' operator
- parentName = Entity.GetParent()?.Name ?? string.Empty;
- }
-
- // Updates every frame
- public override void Update()
+ // It is possible that our entity does not have a parent. We therefore check if the parent is not null.
+ if (parentEntity != null)
{
- // Using the 'DebugText.Print' command, we can quickly print information to the screen
- // NOTE: DebugText only works when debugging the game. During release it is automatically disabled
- DebugText.Print(parentName, new Int2(580, 580));
- DebugText.Print(name, new Int2(800, 580));
+ // We store the name of our Parent entity
+ parentName = parentEntity.Name;
}
+
+ // The above code can be shortened to 1 line by using the '?' operator
+ parentName = Entity.GetParent()?.Name ?? string.Empty;
+ }
+
+ // Updates every frame
+ public override void Update()
+ {
+ // Using the 'DebugText.Print' command, we can quickly print information to the screen
+ // NOTE: DebugText only works when debugging the game. During release it is automatically disabled
+ DebugText.Print(parentName, new Int2(580, 580));
+ DebugText.Print(name, new Int2(800, 580));
}
}
diff --git a/samples/Tutorials/CSharpBeginner/CSharpBeginner/CSharpBeginner.Game/Code/InstantiatingPrefabsDemo.cs b/samples/Tutorials/CSharpBeginner/CSharpBeginner/CSharpBeginner.Game/Code/InstantiatingPrefabsDemo.cs
index f44ed59d32..38e83fb67f 100644
--- a/samples/Tutorials/CSharpBeginner/CSharpBeginner/CSharpBeginner.Game/Code/InstantiatingPrefabsDemo.cs
+++ b/samples/Tutorials/CSharpBeginner/CSharpBeginner/CSharpBeginner.Game/Code/InstantiatingPrefabsDemo.cs
@@ -1,46 +1,45 @@
using Stride.Core.Mathematics;
using Stride.Engine;
-namespace CSharpBeginner.Code
+namespace CSharpBeginner.Code;
+
+///
+/// This script demonstrates how we can instantiate prefabs
+///
+/// https://doc.stride3d.net/latest/en/tutorials/csharpbeginner/instantiating-prefabs.html
+///
+///
+public class InstantiatingPrefabsDemo : SyncScript
{
- ///
- /// This script demonstrates how we can instantiate prefabs
- ///
- /// https://doc.stride3d.net/latest/en/tutorials/csharpbeginner/instantiating-prefabs.html
- ///
- ///
- public class InstantiatingPrefabsDemo : SyncScript
+ public Prefab PileOfBoxesPrefab;
+ public override void Start()
{
- public Prefab PileOfBoxesPrefab;
- public override void Start()
- {
- // A prefab can be instantiated. Is does not give you a new prefab, but instead gives you a list of entities
- var pileOfBoxesInstance = PileOfBoxesPrefab.Instantiate();
+ // A prefab can be instantiated. Is does not give you a new prefab, but instead gives you a list of entities
+ var pileOfBoxesInstance = PileOfBoxesPrefab.Instantiate();
- // An instantiated prefab does nothing and isn't visible untill we add it to the scene
- Entity.Scene.Entities.AddRange(pileOfBoxesInstance);
+ // An instantiated prefab does nothing and isn't visible untill we add it to the scene
+ Entity.Scene.Entities.AddRange(pileOfBoxesInstance);
- // We can also load a prefab by using the Content.Load method
- var pileOfBoxesPrefabFromContent = Content.Load("Prefabs/Pile of boxes");
- var pileOfBoxesInstance2 = pileOfBoxesPrefabFromContent.Instantiate();
-
- // We add the entities to a new entity that we can use a parent
- // We can easily position and rotate the parent entity
- var pileOfBoxesParent = new Entity("PileOfBoxes2", new Vector3(0, 0, -2));
- pileOfBoxesParent.Transform.Rotation = Quaternion.RotationY(135);
- foreach (var entity in pileOfBoxesInstance2)
- {
- pileOfBoxesParent.AddChild(entity);
- }
- Entity.Scene.Entities.Add(pileOfBoxesParent);
- }
+ // We can also load a prefab by using the Content.Load method
+ var pileOfBoxesPrefabFromContent = Content.Load("Prefabs/Pile of boxes");
+ var pileOfBoxesInstance2 = pileOfBoxesPrefabFromContent.Instantiate();
- public override void Update()
+ // We add the entities to a new entity that we can use a parent
+ // We can easily position and rotate the parent entity
+ var pileOfBoxesParent = new Entity("PileOfBoxes2", new Vector3(0, 0, -2));
+ pileOfBoxesParent.Transform.Rotation = Quaternion.RotationY(135);
+ foreach (var entity in pileOfBoxesInstance2)
{
- DebugText.Print("The original prefab", new Int2(310, 320));
- DebugText.Print("The prefab instance PileOfBoxes", new Int2(560, 370));
- DebugText.Print("The prefab instance PileOfBoxes2 with custom parent", new Int2(565, 650));
+ pileOfBoxesParent.AddChild(entity);
}
+ Entity.Scene.Entities.Add(pileOfBoxesParent);
+ }
+
+ public override void Update()
+ {
+ DebugText.Print("The original prefab", new Int2(310, 320));
+ DebugText.Print("The prefab instance PileOfBoxes", new Int2(560, 370));
+ DebugText.Print("The prefab instance PileOfBoxes2 with custom parent", new Int2(565, 650));
}
}
diff --git a/samples/Tutorials/CSharpBeginner/CSharpBeginner/CSharpBeginner.Game/Code/KeyboardInputDemo.cs b/samples/Tutorials/CSharpBeginner/CSharpBeginner/CSharpBeginner.Game/Code/KeyboardInputDemo.cs
index 2b0ef41933..ae55f22119 100644
--- a/samples/Tutorials/CSharpBeginner/CSharpBeginner/CSharpBeginner.Game/Code/KeyboardInputDemo.cs
+++ b/samples/Tutorials/CSharpBeginner/CSharpBeginner/CSharpBeginner.Game/Code/KeyboardInputDemo.cs
@@ -2,48 +2,47 @@
using Stride.Engine;
using Stride.Input;
-namespace CSharpBeginner.Code
+namespace CSharpBeginner.Code;
+
+///
+/// This script demonstrates how to check for keyboard input.
+///
+/// https://doc.stride3d.net/latest/en/tutorials/csharpbeginner/keyboard-input.html
+///
+///
+public class KeyboardInputDemo : SyncScript
{
- ///
- /// This script demonstrates how to check for keyboard input.
- ///
- /// https://doc.stride3d.net/latest/en/tutorials/csharpbeginner/keyboard-input.html
- ///
- ///
- public class KeyboardInputDemo : SyncScript
- {
- public Entity BlueTeapot;
- public Entity YellowTeapot;
- public Entity GreenTeapot;
+ public Entity BlueTeapot;
+ public Entity YellowTeapot;
+ public Entity GreenTeapot;
- public override void Start() { }
+ public override void Start() { }
- public override void Update()
+ public override void Update()
+ {
+ // First lets check if we have a keyboard.
+ if (Input.HasKeyboard)
{
- // First lets check if we have a keyboard.
- if (Input.HasKeyboard)
+ // Key down is used for when a key is being held down.
+ DebugText.Print("Hold the 1 key down to rotate the blue teapot", new Int2(340, 500));
+ if (Input.IsKeyDown(Keys.D1))
{
- // Key down is used for when a key is being held down.
- DebugText.Print("Hold the 1 key down to rotate the blue teapot", new Int2(340, 500));
- if (Input.IsKeyDown(Keys.D1))
- {
- var deltaTime = (float)Game.UpdateTime.Elapsed.TotalSeconds;
- BlueTeapot.Transform.Rotation *= Quaternion.RotationY(0.3f * deltaTime);
- }
+ var deltaTime = (float)Game.UpdateTime.Elapsed.TotalSeconds;
+ BlueTeapot.Transform.Rotation *= Quaternion.RotationY(0.3f * deltaTime);
+ }
- // Use 'IsKeyPressed' for a single key press event.
- DebugText.Print("Press F to rotate the yellow teapot (and to pay respects)", new Int2(340, 520));
- if (Input.IsKeyPressed(Keys.F))
- {
- YellowTeapot.Transform.Rotation *= Quaternion.RotationY(-0.4f);
- }
+ // Use 'IsKeyPressed' for a single key press event.
+ DebugText.Print("Press F to rotate the yellow teapot (and to pay respects)", new Int2(340, 520));
+ if (Input.IsKeyPressed(Keys.F))
+ {
+ YellowTeapot.Transform.Rotation *= Quaternion.RotationY(-0.4f);
+ }
- // 'IsKeyReleased' is used for when you want to know when a key is released after being either held down or pressed.
- DebugText.Print("Press and release the Space bar to rotate the green teapot", new Int2(340, 540));
- if (Input.IsKeyReleased(Keys.Space))
- {
- GreenTeapot.Transform.Rotation *= Quaternion.RotationY(0.6f);
- }
+ // 'IsKeyReleased' is used for when you want to know when a key is released after being either held down or pressed.
+ DebugText.Print("Press and release the Space bar to rotate the green teapot", new Int2(340, 540));
+ if (Input.IsKeyReleased(Keys.Space))
+ {
+ GreenTeapot.Transform.Rotation *= Quaternion.RotationY(0.6f);
}
}
}
diff --git a/samples/Tutorials/CSharpBeginner/CSharpBeginner/CSharpBeginner.Game/Code/LerpDemo.cs b/samples/Tutorials/CSharpBeginner/CSharpBeginner/CSharpBeginner.Game/Code/LerpDemo.cs
index 211508ced3..6cf61ada24 100644
--- a/samples/Tutorials/CSharpBeginner/CSharpBeginner/CSharpBeginner.Game/Code/LerpDemo.cs
+++ b/samples/Tutorials/CSharpBeginner/CSharpBeginner/CSharpBeginner.Game/Code/LerpDemo.cs
@@ -2,63 +2,62 @@
using Stride.Core.Mathematics;
using Stride.Engine;
-namespace CSharpBeginner.Code
+namespace CSharpBeginner.Code;
+
+///
+/// Liniear interpolation or in short 'Lerp' can be used to graduatly change a value from a start value to a target value
+/// This is used during animation of models, ui elements, camera movements and many other scenarios
+/// This example uses Lerp to graduatly move from a start vector3 coordinate to target Vector3 coordinate
+/// The same thing can be done with Vector2 and Vector4
+///
+/// https://doc.stride3d.net/latest/en/tutorials/csharpbeginner/linear-interpolation.html
+///
+///
+public class LerpDemo : SyncScript
{
- ///
- /// Liniear interpolation or in short 'Lerp' can be used to graduatly change a value from a start value to a target value
- /// This is used during animation of models, ui elements, camera movements and many other scenarios
- /// This example uses Lerp to graduatly move from a start vector3 coordinate to target Vector3 coordinate
- /// The same thing can be done with Vector2 and Vector4
- ///
- /// https://doc.stride3d.net/latest/en/tutorials/csharpbeginner/linear-interpolation.html
- ///
- ///
- public class LerpDemo : SyncScript
- {
- public float AnimationTimer = 5.0f;
-
- private float elapsedTime = 0;
- private Random random = new Random();
- private Vector3 startPosition;
- private Vector3 targetPosition;
-
- public override void Start()
- {
- SetNewLerpTargetAndResetTimer();
- }
+ public float AnimationTimer = 5.0f;
- public override void Update()
- {
- // Keep track of elapsed time
- var deltaTime = (float)Game.UpdateTime.Elapsed.TotalSeconds;
- elapsedTime += deltaTime;
+ private float elapsedTime = 0;
+ private Random random = new Random();
+ private Vector3 startPosition;
+ private Vector3 targetPosition;
- // In order to make use of the lerp method, we need to calculate the 'interpolation value': a value going from 0 to 1.
- var lerpValue = elapsedTime / AnimationTimer;
+ public override void Start()
+ {
+ SetNewLerpTargetAndResetTimer();
+ }
- // The Vector3 class exposes a 'Lerp' method that requires a start and target position. The third argument is the lerp value.
- Entity.Transform.Position = Vector3.Lerp(startPosition, targetPosition, lerpValue);
+ public override void Update()
+ {
+ // Keep track of elapsed time
+ var deltaTime = (float)Game.UpdateTime.Elapsed.TotalSeconds;
+ elapsedTime += deltaTime;
- // If the elapsedTime passes the animation timer we reset the timer and set a new target
- if (elapsedTime > AnimationTimer)
- {
- SetNewLerpTargetAndResetTimer();
- }
+ // In order to make use of the lerp method, we need to calculate the 'interpolation value': a value going from 0 to 1.
+ var lerpValue = elapsedTime / AnimationTimer;
- DebugText.Print("Elapsed time: " + elapsedTime, new Int2(480, 120));
- DebugText.Print("Lerp value: " + lerpValue, new Int2(480, 140));
- DebugText.Print("Start position: " + startPosition, new Int2(480, 160));
- DebugText.Print("Target position: " + targetPosition, new Int2(480, 180));
- }
+ // The Vector3 class exposes a 'Lerp' method that requires a start and target position. The third argument is the lerp value.
+ Entity.Transform.Position = Vector3.Lerp(startPosition, targetPosition, lerpValue);
- ///
- /// Resets timer, stores the current position and randomly sets a new target position
- ///
- private void SetNewLerpTargetAndResetTimer()
+ // If the elapsedTime passes the animation timer we reset the timer and set a new target
+ if (elapsedTime > AnimationTimer)
{
- elapsedTime = 0;
- startPosition = Entity.Transform.Position;
- targetPosition = new Vector3(random.Next(-2, 2), random.Next(0, 3), random.Next(-1, 1));
+ SetNewLerpTargetAndResetTimer();
}
+
+ DebugText.Print("Elapsed time: " + elapsedTime, new Int2(480, 120));
+ DebugText.Print("Lerp value: " + lerpValue, new Int2(480, 140));
+ DebugText.Print("Start position: " + startPosition, new Int2(480, 160));
+ DebugText.Print("Target position: " + targetPosition, new Int2(480, 180));
+ }
+
+ ///
+ /// Resets timer, stores the current position and randomly sets a new target position
+ ///
+ private void SetNewLerpTargetAndResetTimer()
+ {
+ elapsedTime = 0;
+ startPosition = Entity.Transform.Position;
+ targetPosition = new Vector3(random.Next(-2, 2), random.Next(0, 3), random.Next(-1, 1));
}
}
diff --git a/samples/Tutorials/CSharpBeginner/CSharpBeginner/CSharpBeginner.Game/Code/LoadingContentDemo.cs b/samples/Tutorials/CSharpBeginner/CSharpBeginner/CSharpBeginner.Game/Code/LoadingContentDemo.cs
index 5f97841a96..dfab897bc2 100644
--- a/samples/Tutorials/CSharpBeginner/CSharpBeginner/CSharpBeginner.Game/Code/LoadingContentDemo.cs
+++ b/samples/Tutorials/CSharpBeginner/CSharpBeginner/CSharpBeginner.Game/Code/LoadingContentDemo.cs
@@ -5,81 +5,80 @@
using Stride.Input;
using Stride.Rendering;
-namespace CSharpBeginner.Code
+namespace CSharpBeginner.Code;
+
+///
+/// This script demonstrates how we can load contect from code, and attach it to an entity
+///
+/// https://doc.stride3d.net/latest/en/tutorials/csharpbeginner/loading-content.html
+///
+///
+public class LoadingContentDemo : SyncScript
{
- ///
- /// This script demonstrates how we can load contect from code, and attach it to an entity
- ///
- /// https://doc.stride3d.net/latest/en/tutorials/csharpbeginner/loading-content.html
- ///
- ///
- public class LoadingContentDemo : SyncScript
- {
- private Model loadedMannequinModel = null;
- private Stack spawnedEntities = new Stack();
- private Random random = new Random();
+ private Model loadedMannequinModel = null;
+ private Stack spawnedEntities = new Stack();
+ private Random random = new Random();
- public override void Start() { }
+ public override void Start() { }
- public override void Update()
+ public override void Update()
+ {
+ // To load any content we use the Load method. First we need to specify the type between the '< >'. The we provide the URL
+ if (Input.IsKeyPressed(Keys.L))
{
- // To load any content we use the Load method. First we need to specify the type between the '< >'. The we provide the URL
- if (Input.IsKeyPressed(Keys.L))
- {
- loadedMannequinModel = Content.Load("Models/mannequinModel");
- }
+ loadedMannequinModel = Content.Load("Models/mannequinModel");
+ }
- // To remove loaded content we use the unload method to remove all existing models from the scene.
- // Note: when we remove content, we can no longer see the model, but the entity still exists in the scene
- if (Input.IsKeyPressed(Keys.U))
- {
- Content.Unload(loadedMannequinModel);
- loadedMannequinModel = null;
- }
+ // To remove loaded content we use the unload method to remove all existing models from the scene.
+ // Note: when we remove content, we can no longer see the model, but the entity still exists in the scene
+ if (Input.IsKeyPressed(Keys.U))
+ {
+ Content.Unload(loadedMannequinModel);
+ loadedMannequinModel = null;
+ }
- // If the model has been loaded, create a new entity and randomly place it in the scene
- if (Input.IsKeyPressed(Keys.S))
- {
- CreateEntityWithModelAndRandomlyPositionInScene();
- }
+ // If the model has been loaded, create a new entity and randomly place it in the scene
+ if (Input.IsKeyPressed(Keys.S))
+ {
+ CreateEntityWithModelAndRandomlyPositionInScene();
+ }
- // Clear all entities from the tutorial scene. This does not unload the model
- if (Input.IsKeyPressed(Keys.C))
+ // Clear all entities from the tutorial scene. This does not unload the model
+ if (Input.IsKeyPressed(Keys.C))
+ {
+ while (spawnedEntities.Count > 0)
{
- while (spawnedEntities.Count > 0)
- {
- Entity.Scene.Entities.Remove(spawnedEntities.Pop());
- }
+ Entity.Scene.Entities.Remove(spawnedEntities.Pop());
}
-
- DebugText.Print("Model is " + (loadedMannequinModel == null ? "not loaded" : "loaded"), new Int2(340, 580));
- DebugText.Print("Press L to load the manequin model", new Int2(340, 600));
- DebugText.Print("Press U to unload the mannequin model", new Int2(340, 620));
- DebugText.Print("Press S to spawn an entity if the model has been loaded", new Int2(340, 660));
- DebugText.Print("Press C to clear all spawned entities", new Int2(340, 680));
- DebugText.Print("Spawned entities count: " + spawnedEntities.Count, new Int2(340, 700));
}
- private void CreateEntityWithModelAndRandomlyPositionInScene()
+ DebugText.Print("Model is " + (loadedMannequinModel == null ? "not loaded" : "loaded"), new Int2(340, 580));
+ DebugText.Print("Press L to load the manequin model", new Int2(340, 600));
+ DebugText.Print("Press U to unload the mannequin model", new Int2(340, 620));
+ DebugText.Print("Press S to spawn an entity if the model has been loaded", new Int2(340, 660));
+ DebugText.Print("Press C to clear all spawned entities", new Int2(340, 680));
+ DebugText.Print("Spawned entities count: " + spawnedEntities.Count, new Int2(340, 700));
+ }
+
+ private void CreateEntityWithModelAndRandomlyPositionInScene()
+ {
+ if (loadedMannequinModel != null)
{
- if (loadedMannequinModel != null)
- {
- // Create a new model component that references the loaded mannequin model
- var modelComponent = new ModelComponent(loadedMannequinModel);
+ // Create a new model component that references the loaded mannequin model
+ var modelComponent = new ModelComponent(loadedMannequinModel);
- // Get a random position near the center of the scene
- var randomPosition = new Vector3(random.Next(-2, 4), 0, random.Next(-2, 2));
+ // Get a random position near the center of the scene
+ var randomPosition = new Vector3(random.Next(-2, 4), 0, random.Next(-2, 2));
- // Create a new entity and attach a model component
- var entity = new Entity("My new entity with a model component", randomPosition);
- entity.Add(modelComponent);
+ // Create a new entity and attach a model component
+ var entity = new Entity("My new entity with a model component", randomPosition);
+ entity.Add(modelComponent);
- // Add the new entity to the current tutorial scene
- Entity.Scene.Entities.Add(entity);
+ // Add the new entity to the current tutorial scene
+ Entity.Scene.Entities.Add(entity);
- // We add the spawned entities to a stack to keep track of them
- spawnedEntities.Push(entity);
- }
+ // We add the spawned entities to a stack to keep track of them
+ spawnedEntities.Push(entity);
}
}
}
diff --git a/samples/Tutorials/CSharpBeginner/CSharpBeginner/CSharpBeginner.Game/Code/MouseInputDemo.cs b/samples/Tutorials/CSharpBeginner/CSharpBeginner/CSharpBeginner.Game/Code/MouseInputDemo.cs
index 53010f74a5..acf10efc3c 100644
--- a/samples/Tutorials/CSharpBeginner/CSharpBeginner/CSharpBeginner.Game/Code/MouseInputDemo.cs
+++ b/samples/Tutorials/CSharpBeginner/CSharpBeginner/CSharpBeginner.Game/Code/MouseInputDemo.cs
@@ -2,63 +2,62 @@
using Stride.Engine;
using Stride.Input;
-namespace CSharpBeginner.Code
+namespace CSharpBeginner.Code;
+
+///
+/// This script demonstrates how to check for any mouse input.
+///
+/// https://doc.stride3d.net/latest/en/tutorials/csharpbeginner/mouse-input.html
+///
+///
+public class MouseInputDemo : SyncScript
{
- ///
- /// This script demonstrates how to check for any mouse input.
- ///
- /// https://doc.stride3d.net/latest/en/tutorials/csharpbeginner/mouse-input.html
- ///
- ///
- public class MouseInputDemo : SyncScript
- {
- public Entity BlueTeapot;
- public Entity YellowTeapot;
- public Entity GreenTeapot;
- public Entity PinkTeapot;
+ public Entity BlueTeapot;
+ public Entity YellowTeapot;
+ public Entity GreenTeapot;
+ public Entity PinkTeapot;
- private float currentScrollIndex = 0;
+ private float currentScrollIndex = 0;
- public override void Start() { }
+ public override void Start() { }
- public override void Update()
+ public override void Update()
+ {
+ // First lets check if we have a mouse.
+ if (Input.HasMouse)
{
- // First lets check if we have a mouse.
- if (Input.HasMouse)
+ // Key down is used for when a key is being held down.
+ DebugText.Print("Hold the left mouse button down to rotate the blue teapot", new Int2(400, 600));
+ if (Input.IsMouseButtonDown(MouseButton.Left))
{
- // Key down is used for when a key is being held down.
- DebugText.Print("Hold the left mouse button down to rotate the blue teapot", new Int2(400, 600));
- if (Input.IsMouseButtonDown(MouseButton.Left))
- {
- var deltaTime = (float)Game.UpdateTime.Elapsed.TotalSeconds;
- BlueTeapot.Transform.Rotation *= Quaternion.RotationY(0.4f * deltaTime);
- }
+ var deltaTime = (float)Game.UpdateTime.Elapsed.TotalSeconds;
+ BlueTeapot.Transform.Rotation *= Quaternion.RotationY(0.4f * deltaTime);
+ }
- // Use 'IsMouseButtonPressed' for a single mouse click event.
- DebugText.Print("Click the right mouse button to rotate the yellow teapot", new Int2(400, 620));
- if (Input.IsMouseButtonPressed(MouseButton.Right))
- {
- YellowTeapot.Transform.Rotation *= Quaternion.RotationY(-0.4f);
- }
+ // Use 'IsMouseButtonPressed' for a single mouse click event.
+ DebugText.Print("Click the right mouse button to rotate the yellow teapot", new Int2(400, 620));
+ if (Input.IsMouseButtonPressed(MouseButton.Right))
+ {
+ YellowTeapot.Transform.Rotation *= Quaternion.RotationY(-0.4f);
+ }
- // 'IsMouseButtonReleased' is used for when you want to know when a mouse button is released after being either held down or pressed.
- DebugText.Print("Press and release the scrollwheel to rotate the green teapot", new Int2(400, 640));
- if (Input.IsMouseButtonReleased(MouseButton.Middle))
- {
- GreenTeapot.Transform.Rotation *= Quaternion.RotationY(0.4f);
- }
+ // 'IsMouseButtonReleased' is used for when you want to know when a mouse button is released after being either held down or pressed.
+ DebugText.Print("Press and release the scrollwheel to rotate the green teapot", new Int2(400, 640));
+ if (Input.IsMouseButtonReleased(MouseButton.Middle))
+ {
+ GreenTeapot.Transform.Rotation *= Quaternion.RotationY(0.4f);
+ }
- // We can use the mousewheel delta do determine if a mousewheel has rotated.
- // Scrolling forward gives a mousewheel delta of 1, and scrolling backwards gives a mousewheel delta of -1.
- // If in the next frame the mousewheel is not scrolled, the mouse wheel delta is 0 again.
- currentScrollIndex += Input.MouseWheelDelta;
- DebugText.Print("Scroll the mouse wheel to rotate the pink teapot. Scroll index: " + currentScrollIndex, new Int2(400, 660));
- PinkTeapot.Transform.Rotation = Quaternion.RotationY(0.02f * currentScrollIndex);
+ // We can use the mousewheel delta do determine if a mousewheel has rotated.
+ // Scrolling forward gives a mousewheel delta of 1, and scrolling backwards gives a mousewheel delta of -1.
+ // If in the next frame the mousewheel is not scrolled, the mouse wheel delta is 0 again.
+ currentScrollIndex += Input.MouseWheelDelta;
+ DebugText.Print("Scroll the mouse wheel to rotate the pink teapot. Scroll index: " + currentScrollIndex, new Int2(400, 660));
+ PinkTeapot.Transform.Rotation = Quaternion.RotationY(0.02f * currentScrollIndex);
- // We can draw some text at the position of our mouse by getting the absolute mouse position
- var mousePos = Input.AbsoluteMousePosition;
- DebugText.Print("Mouse position: " + mousePos, new Int2(mousePos));
- }
+ // We can draw some text at the position of our mouse by getting the absolute mouse position
+ var mousePos = Input.AbsoluteMousePosition;
+ DebugText.Print("Mouse position: " + mousePos, new Int2(mousePos));
}
}
}
diff --git a/samples/Tutorials/CSharpBeginner/CSharpBeginner/CSharpBeginner.Game/Code/PropertiesDemo.cs b/samples/Tutorials/CSharpBeginner/CSharpBeginner/CSharpBeginner.Game/Code/PropertiesDemo.cs
index f097995963..d15282ae95 100644
--- a/samples/Tutorials/CSharpBeginner/CSharpBeginner/CSharpBeginner.Game/Code/PropertiesDemo.cs
+++ b/samples/Tutorials/CSharpBeginner/CSharpBeginner/CSharpBeginner.Game/Code/PropertiesDemo.cs
@@ -4,85 +4,84 @@
using Stride.Core.Mathematics;
using Stride.Engine;
-namespace CSharpBeginner.Code
+namespace CSharpBeginner.Code;
+
+///
+/// This script demonstrates the most common properties you can expose to the editor.
+/// When we add the public keyword to the variables, they show up as properties in the editor.
+///
+/// https://doc.stride3d.net/latest/en/tutorials/csharpbeginner/editor-properties.html
+///
+///
+public class PropertiesDemo : SyncScript
{
- ///
- /// This script demonstrates the most common properties you can expose to the editor.
- /// When we add the public keyword to the variables, they show up as properties in the editor.
- ///
- /// https://doc.stride3d.net/latest/en/tutorials/csharpbeginner/editor-properties.html
- ///
- ///
- public class PropertiesDemo : SyncScript
- {
- // By default public properties are ordered alphabetically
- public string SomeString = "Hello Stride";
- public int SomeInteger = 10;
+ // By default public properties are ordered alphabetically
+ public string SomeString = "Hello Stride";
+ public int SomeInteger = 10;
- // Use DataMember followed by a number to order properties by number
- [DataMember(5)]
- public bool SomeBoolean = true;
+ // Use DataMember followed by a number to order properties by number
+ [DataMember(5)]
+ public bool SomeBoolean = true;
- // Instead of using the name of the variable, you can also define your own text
- [DataMember(4, "My custom text")]
- public float SomeFloat = 5.6f;
+ // Instead of using the name of the variable, you can also define your own text
+ [DataMember(4, "My custom text")]
+ public float SomeFloat = 5.6f;
- // Vectors
- public Vector2 SomeVector2; // Is the same as = new Vector2(0, 0);
- public Vector3 SomeVector3 = new Vector3(1, 2, 3);
- public Vector4 SomeVector4 = new Vector4(5); // All 4 float value get the value of 5
- public Color SomeColor = Color.Red;
+ // Vectors
+ public Vector2 SomeVector2; // Is the same as = new Vector2(0, 0);
+ public Vector3 SomeVector3 = new Vector3(1, 2, 3);
+ public Vector4 SomeVector4 = new Vector4(5); // All 4 float value get the value of 5
+ public Color SomeColor = Color.Red;
- // Turns a float in to a range slider
- // Dragging the slider uses the smallstep value
- // Clicking the slider uses the bigstep value
- [DataMemberRange(1, 100, 0.1, 1, 3)]
- public float RangedFloat = 10.0f;
+ // Turns a float in to a range slider
+ // Dragging the slider uses the smallstep value
+ // Clicking the slider uses the bigstep value
+ [DataMemberRange(1, 100, 0.1, 1, 3)]
+ public float RangedFloat = 10.0f;
- // Entities and components
- public Entity ASingleEntity;
- public CameraComponent ASingleCameraComponent;
+ // Entities and components
+ public Entity ASingleEntity;
+ public CameraComponent ASingleCameraComponent;
- // If we want a list of objects like strings, entities or specific components,
- // we have to initialize the new List<> right away
- public List StringList = new List();
- public List EntityList = new List();
- public List CameraList = new List();
+ // If we want a list of objects like strings, entities or specific components,
+ // we have to initialize the new List<> right away
+ public List StringList = new List();
+ public List EntityList = new List();
+ public List CameraList = new List();
- // Dictionaries also need to be initialized. The first value needs to be a primitive type like string
- public Dictionary aSimpleDictionary = new Dictionary();
+ // Dictionaries also need to be initialized. The first value needs to be a primitive type like string
+ public Dictionary aSimpleDictionary = new Dictionary();
- // If we dont want a public property to be visible in the editor we can use '[DataMemberIgnore]'
- [DataMemberIgnore]
- public string HideMe;
+ // If we dont want a public property to be visible in the editor we can use '[DataMemberIgnore]'
+ [DataMemberIgnore]
+ public string HideMe;
- // Enums can be used for dropdowns
- public CharacterType Character;
- public enum CharacterType
- {
- Warrior,
- Archer,
- Mage
- }
+ // Enums can be used for dropdowns
+ public CharacterType Character;
+ public enum CharacterType
+ {
+ Warrior,
+ Archer,
+ Mage
+ }
- /// This is a super long description. Use it to help the people that use your components, understand what a propery does.
- /// The text above is displayed in game studio when a property is selected and also shows up when you hover over the property
- public string Explanation;
+ /// This is a super long description. Use it to help the people that use your components, understand what a propery does.
+ /// The text above is displayed in game studio when a property is selected and also shows up when you hover over the property
+ public string Explanation;
- public override void Update()
- {
- var x = 400;
- DebugText.Print("Integer: " + SomeInteger, new Int2(x, 200));
- DebugText.Print("Float: " + SomeFloat, new Int2(x, 220));
- DebugText.Print("Boolean: " + SomeBoolean, new Int2(x, 240));
- DebugText.Print("String: " + SomeString, new Int2(x, 260));
- DebugText.Print("Vector2: " + SomeVector2, new Int2(x, 280));
- DebugText.Print("Vector3: " + SomeVector3, new Int2(x, 300));
- DebugText.Print("Vector4: " + SomeVector4, new Int2(x, 320));
- DebugText.Print("Color: " + SomeColor, new Int2(x, 340));
- DebugText.Print("String list count: " + StringList.Count, new Int2(x, 360));
- DebugText.Print("Entity list count: " + EntityList.Count, new Int2(x, 380));
- DebugText.Print("Camera list count: " + CameraList.Count, new Int2(x, 400));
- }
+ public override void Update()
+ {
+ var x = 400;
+ DebugText.Print("Integer: " + SomeInteger, new Int2(x, 200));
+ DebugText.Print("Float: " + SomeFloat, new Int2(x, 220));
+ DebugText.Print("Boolean: " + SomeBoolean, new Int2(x, 240));
+ DebugText.Print("String: " + SomeString, new Int2(x, 260));
+ DebugText.Print("Vector2: " + SomeVector2, new Int2(x, 280));
+ DebugText.Print("Vector3: " + SomeVector3, new Int2(x, 300));
+ DebugText.Print("Vector4: " + SomeVector4, new Int2(x, 320));
+ DebugText.Print("Color: " + SomeColor, new Int2(x, 340));
+ DebugText.Print("String list count: " + StringList.Count, new Int2(x, 360));
+ DebugText.Print("Entity list count: " + EntityList.Count, new Int2(x, 380));
+ DebugText.Print("Camera list count: " + CameraList.Count, new Int2(x, 400));
}
}
diff --git a/samples/Tutorials/CSharpBeginner/CSharpBeginner/CSharpBeginner.Game/Code/RemoveEntitiesDemo.cs b/samples/Tutorials/CSharpBeginner/CSharpBeginner/CSharpBeginner.Game/Code/RemoveEntitiesDemo.cs
index d177b4d693..12fa29580e 100644
--- a/samples/Tutorials/CSharpBeginner/CSharpBeginner/CSharpBeginner.Game/Code/RemoveEntitiesDemo.cs
+++ b/samples/Tutorials/CSharpBeginner/CSharpBeginner/CSharpBeginner.Game/Code/RemoveEntitiesDemo.cs
@@ -1,100 +1,99 @@
using Stride.Core.Mathematics;
using Stride.Engine;
-namespace CSharpBeginner.Code
+namespace CSharpBeginner.Code;
+
+///
+/// This script demonstrates how to remove an existing entity from the scene hierarchy.
+///
+/// https://doc.stride3d.net/latest/en/tutorials/csharpbeginner/removing-entities.html
+///
+///
+public class RemoveEntitiesDemo : SyncScript
{
- ///
- /// This script demonstrates how to remove an existing entity from the scene hierarchy.
- ///
- /// https://doc.stride3d.net/latest/en/tutorials/csharpbeginner/removing-entities.html
- ///
- ///
- public class RemoveEntitiesDemo : SyncScript
- {
- public Entity EntityToClone;
+ public Entity EntityToClone;
- private Entity clonedEntity1;
- private Entity clonedEntity2;
- private float timer = 0;
+ private Entity clonedEntity1;
+ private Entity clonedEntity2;
+ private float timer = 0;
- private float currentTimer = 0;
- private float existTime = 4;
- private float goneTime = 2;
+ private float currentTimer = 0;
+ private float existTime = 4;
+ private float goneTime = 2;
- private bool entitiesExist = false;
+ private bool entitiesExist = false;
- public override void Start()
- {
- CloneEntityAndAddToScene();
- CloneEntityAndAddAsChild();
- entitiesExist = true;
- }
+ public override void Start()
+ {
+ CloneEntityAndAddToScene();
+ CloneEntityAndAddAsChild();
+ entitiesExist = true;
+ }
- /// This method clones an entity, adds it as a child of the current entity
- private void CloneEntityAndAddAsChild()
- {
- clonedEntity1 = EntityToClone.Clone();
- clonedEntity1.Transform.Position = new Vector3(0);
- Entity.AddChild(clonedEntity1);
- }
+ /// This method clones an entity, adds it as a child of the current entity
+ private void CloneEntityAndAddAsChild()
+ {
+ clonedEntity1 = EntityToClone.Clone();
+ clonedEntity1.Transform.Position = new Vector3(0);
+ Entity.AddChild(clonedEntity1);
+ }
- /// This method clones an entity, adds it to the scene root
- private void CloneEntityAndAddToScene()
- {
- clonedEntity2 = EntityToClone.Clone();
- clonedEntity2.Transform.Position += new Vector3(0, 0, -0.5f);
- Entity.Scene.Entities.Add(clonedEntity2);
- }
+ /// This method clones an entity, adds it to the scene root
+ private void CloneEntityAndAddToScene()
+ {
+ clonedEntity2 = EntityToClone.Clone();
+ clonedEntity2.Transform.Position += new Vector3(0, 0, -0.5f);
+ Entity.Scene.Entities.Add(clonedEntity2);
+ }
- public override void Update()
+ public override void Update()
+ {
+ // We use a simple timer
+ timer += (float)Game.UpdateTime.Elapsed.TotalSeconds;
+ if (timer > currentTimer)
{
- // We use a simple timer
- timer += (float)Game.UpdateTime.Elapsed.TotalSeconds;
- if (timer > currentTimer)
+ // If the entities exist, we remove them from the scene
+ if (entitiesExist)
{
- // If the entities exist, we remove them from the scene
- if (entitiesExist)
- {
- // We remove the cloned entity that is a child of the current entity
- Entity.RemoveChild(clonedEntity1); // Alternative: clonedEntity1.Transform.Parent = null;
-
- // We remove the cloned entity from the scene root
- Entity.Scene.Entities.Remove(clonedEntity2);
-
- // We also need to set the clones to null, otherwise the clones still exist
- clonedEntity1 = null;
- clonedEntity2 = null;
+ // We remove the cloned entity that is a child of the current entity
+ Entity.RemoveChild(clonedEntity1); // Alternative: clonedEntity1.Transform.Parent = null;
- entitiesExist = false;
- currentTimer = goneTime;
- }
- else // If the entities don't exist, we create new clones
- {
- CloneEntityAndAddToScene();
- CloneEntityAndAddAsChild();
- entitiesExist = true;
+ // We remove the cloned entity from the scene root
+ Entity.Scene.Entities.Remove(clonedEntity2);
+
+ // We also need to set the clones to null, otherwise the clones still exist
+ clonedEntity1 = null;
+ clonedEntity2 = null;
- currentTimer = existTime;
- }
+ entitiesExist = false;
+ currentTimer = goneTime;
+ }
+ else // If the entities don't exist, we create new clones
+ {
+ CloneEntityAndAddToScene();
+ CloneEntityAndAddAsChild();
+ entitiesExist = true;
- // Reset timer
- timer = 0;
+ currentTimer = existTime;
}
- DebugText.Print("For " + existTime.ToString() + " seconds: ", new Int2(860, 240));
- DebugText.Print("- Clone 1 is a child of the script entity", new Int2(860, 260));
- DebugText.Print("- Clone 2 is a child of the scene root", new Int2(860, 280));
- DebugText.Print("For " + goneTime.ToString() + " seconds, the cloned entities are gone", new Int2(860, 300));
+ // Reset timer
+ timer = 0;
+ }
- if (entitiesExist)
- {
- DebugText.Print("Cloned entity 1 is a child of the Script entity", new Int2(450, 350));
- DebugText.Print("Cloned entity 2 is in the scene root", new Int2(450, 600));
- }
- else
- {
- DebugText.Print("Cloned entity 1 and 2 have been removed", new Int2(450, 600));
- }
+ DebugText.Print("For " + existTime.ToString() + " seconds: ", new Int2(860, 240));
+ DebugText.Print("- Clone 1 is a child of the script entity", new Int2(860, 260));
+ DebugText.Print("- Clone 2 is a child of the scene root", new Int2(860, 280));
+ DebugText.Print("For " + goneTime.ToString() + " seconds, the cloned entities are gone", new Int2(860, 300));
+
+ if (entitiesExist)
+ {
+ DebugText.Print("Cloned entity 1 is a child of the Script entity", new Int2(450, 350));
+ DebugText.Print("Cloned entity 2 is in the scene root", new Int2(450, 600));
+ }
+ else
+ {
+ DebugText.Print("Cloned entity 1 and 2 have been removed", new Int2(450, 600));
}
}
}
diff --git a/samples/Tutorials/CSharpBeginner/CSharpBeginner/CSharpBeginner.Game/Code/TransformPositionDemo.cs b/samples/Tutorials/CSharpBeginner/CSharpBeginner/CSharpBeginner.Game/Code/TransformPositionDemo.cs
index c7617fe40e..507bc61dd4 100644
--- a/samples/Tutorials/CSharpBeginner/CSharpBeginner/CSharpBeginner.Game/Code/TransformPositionDemo.cs
+++ b/samples/Tutorials/CSharpBeginner/CSharpBeginner/CSharpBeginner.Game/Code/TransformPositionDemo.cs
@@ -1,27 +1,26 @@
using Stride.Core.Mathematics;
using Stride.Engine;
-namespace CSharpBeginner.Code
+namespace CSharpBeginner.Code;
+
+///
+/// This script demonstrates how to access the entity's local and world position and displays them on screen.
+///
+/// https://doc.stride3d.net/latest/en/tutorials/csharpbeginner/transform-position.html
+///
+///
+public class TransformPositionDemo : SyncScript
{
- ///
- /// This script demonstrates how to access the entity's local and world position and displays them on screen.
- ///
- /// https://doc.stride3d.net/latest/en/tutorials/csharpbeginner/transform-position.html
- ///
- ///
- public class TransformPositionDemo : SyncScript
- {
- public override void Start() { }
+ public override void Start() { }
- public override void Update()
- {
- // We store the local and world position of our entity's tranform in a Vector3 variable
- Vector3 localPosition = Entity.Transform.Position;
- Vector3 worldPosition = Entity.Transform.WorldMatrix.TranslationVector;
+ public override void Update()
+ {
+ // We store the local and world position of our entity's tranform in a Vector3 variable
+ Vector3 localPosition = Entity.Transform.Position;
+ Vector3 worldPosition = Entity.Transform.WorldMatrix.TranslationVector;
- // We display the entity's name and its local and world position on screen
- DebugText.Print(Entity.Name + " - local position: " + localPosition, new Int2(400, 450));
- DebugText.Print(Entity.Name + " - world position: " + worldPosition, new Int2(400, 470));
- }
+ // We display the entity's name and its local and world position on screen
+ DebugText.Print(Entity.Name + " - local position: " + localPosition, new Int2(400, 450));
+ DebugText.Print(Entity.Name + " - world position: " + worldPosition, new Int2(400, 470));
}
}
diff --git a/samples/Tutorials/CSharpBeginner/CSharpBeginner/CSharpBeginner.Game/Code/TutorialUI.cs b/samples/Tutorials/CSharpBeginner/CSharpBeginner/CSharpBeginner.Game/Code/TutorialUI.cs
index 8e5fbb5106..74e6ff2531 100644
--- a/samples/Tutorials/CSharpBeginner/CSharpBeginner/CSharpBeginner.Game/Code/TutorialUI.cs
+++ b/samples/Tutorials/CSharpBeginner/CSharpBeginner/CSharpBeginner.Game/Code/TutorialUI.cs
@@ -6,130 +6,129 @@
using Stride.UI.Events;
using Stride.UI.Panels;
-namespace CSharpBeginner.Code
+namespace CSharpBeginner.Code;
+
+public class TutorialUI : SyncScript
{
- public class TutorialUI : SyncScript
- {
- public Entity Camera;
+ public Entity Camera;
- private Scene tutorialScene;
- private UIPage activePage;
- private Button btnTutorialMenu;
- private StackPanel tutorialButtonsStackPanel;
- private TextBlock tutorialTitleTxt;
+ private Scene tutorialScene;
+ private UIPage activePage;
+ private Button btnTutorialMenu;
+ private StackPanel tutorialButtonsStackPanel;
+ private TextBlock tutorialTitleTxt;
- private float cameraLerpTimer = 0;
- private float cameraLerpTime = 2.0f;
+ private float cameraLerpTimer = 0;
+ private float cameraLerpTime = 2.0f;
- private TransformComponent startTransform;
- private TransformComponent targetTransform;
+ private TransformComponent startTransform;
+ private TransformComponent targetTransform;
- public override void Start()
+ public override void Start()
+ {
+ Game.Window.IsMouseVisible = true;
+
+ activePage = Entity.Get().Page;
+
+ btnTutorialMenu = activePage.RootElement.FindVisualChildOfType("BtnTutorialMenu");
+ btnTutorialMenu.Click += BtnTutorialMenuClicked;
+
+ tutorialTitleTxt = activePage.RootElement.FindVisualChildOfType("tutorialTitleTxt");
+ tutorialTitleTxt.Text = "";
+
+ tutorialButtonsStackPanel = activePage.RootElement.FindVisualChildOfType("TutorialButtonsStackPanel");
+ var placeHolderButton = tutorialButtonsStackPanel.Children[0] as Button;
+ var placeHolderTextBlock = placeHolderButton.VisualChildren[0] as TextBlock;
+ placeHolderButton.Visibility = Visibility.Hidden;
+
+ //Tutorial button text - Tutorial scene name
+ var tutorialScenes = new Dictionary();
+ tutorialScenes.Add("Getting the entity", "Getting the entity");
+ tutorialScenes.Add("Child entities", "Child entities");
+ tutorialScenes.Add("Transform position", "TransformPosition");
+ tutorialScenes.Add("Properties", "Properties");
+ tutorialScenes.Add("Getting a component", "Getting a component");
+ tutorialScenes.Add("Adding a component", "Adding a component");
+ tutorialScenes.Add("Delta time", "DeltaTime");
+ tutorialScenes.Add("Cloning entities", "Cloning entities");
+ tutorialScenes.Add("Removing entities", "Removing entities");
+ tutorialScenes.Add("Keyboard input", "Keyboard input");
+ tutorialScenes.Add("Mouse input", "Mouse input");
+ tutorialScenes.Add("Virtual buttons", "Virtual buttons");
+ tutorialScenes.Add("Linear Interpolation", "Linear Interpolation");
+ tutorialScenes.Add("Loading content from code", "Loading content");
+ tutorialScenes.Add("Instantiating prefabs", "Instantiating prefabs");
+
+ foreach (var keyPair in tutorialScenes)
{
- Game.Window.IsMouseVisible = true;
-
- activePage = Entity.Get().Page;
-
- btnTutorialMenu = activePage.RootElement.FindVisualChildOfType("BtnTutorialMenu");
- btnTutorialMenu.Click += BtnTutorialMenuClicked;
-
- tutorialTitleTxt = activePage.RootElement.FindVisualChildOfType("tutorialTitleTxt");
- tutorialTitleTxt.Text = "";
-
- tutorialButtonsStackPanel = activePage.RootElement.FindVisualChildOfType("TutorialButtonsStackPanel");
- var placeHolderButton = tutorialButtonsStackPanel.Children[0] as Button;
- var placeHolderTextBlock = placeHolderButton.VisualChildren[0] as TextBlock;
- placeHolderButton.Visibility = Visibility.Hidden;
-
- //Tutorial button text - Tutorial scene name
- var tutorialScenes = new Dictionary();
- tutorialScenes.Add("Getting the entity", "Getting the entity");
- tutorialScenes.Add("Child entities", "Child entities");
- tutorialScenes.Add("Transform position", "TransformPosition");
- tutorialScenes.Add("Properties", "Properties");
- tutorialScenes.Add("Getting a component", "Getting a component");
- tutorialScenes.Add("Adding a component", "Adding a component");
- tutorialScenes.Add("Delta time", "DeltaTime");
- tutorialScenes.Add("Cloning entities", "Cloning entities");
- tutorialScenes.Add("Removing entities", "Removing entities");
- tutorialScenes.Add("Keyboard input", "Keyboard input");
- tutorialScenes.Add("Mouse input", "Mouse input");
- tutorialScenes.Add("Virtual buttons", "Virtual buttons");
- tutorialScenes.Add("Linear Interpolation", "Linear Interpolation");
- tutorialScenes.Add("Loading content from code", "Loading content");
- tutorialScenes.Add("Instantiating prefabs", "Instantiating prefabs");
-
- foreach (var keyPair in tutorialScenes)
+ var button = new Button
{
- var button = new Button
- {
- Content = new TextBlock
- {
- Font = placeHolderTextBlock.Font,
- TextSize = placeHolderTextBlock.TextSize,
- Height = placeHolderButton.Content.Height,
- Text = keyPair.Key,
- TextColor = Color.White,
- HorizontalAlignment = HorizontalAlignment.Left,
- VerticalAlignment = VerticalAlignment.Center
- },
- Height = placeHolderButton.Height,
- NotPressedImage = placeHolderButton.NotPressedImage,
- PressedImage = placeHolderButton.PressedImage,
- MouseOverImage = placeHolderButton.MouseOverImage,
-
- };
- button.Click += (sender, e) => BtnLoadTutorial(sender, e, keyPair);
-
- tutorialButtonsStackPanel.Children.Add(button);
- }
- tutorialButtonsStackPanel.Children.Remove(placeHolderButton);
+ Content = new TextBlock
+ {
+ Font = placeHolderTextBlock.Font,
+ TextSize = placeHolderTextBlock.TextSize,
+ Height = placeHolderButton.Content.Height,
+ Text = keyPair.Key,
+ TextColor = Color.White,
+ HorizontalAlignment = HorizontalAlignment.Left,
+ VerticalAlignment = VerticalAlignment.Center
+ },
+ Height = placeHolderButton.Height,
+ NotPressedImage = placeHolderButton.NotPressedImage,
+ PressedImage = placeHolderButton.PressedImage,
+ MouseOverImage = placeHolderButton.MouseOverImage,
+
+ };
+ button.Click += (sender, e) => BtnLoadTutorial(sender, e, keyPair);
+
+ tutorialButtonsStackPanel.Children.Add(button);
}
+ tutorialButtonsStackPanel.Children.Remove(placeHolderButton);
+ }
- private void BtnTutorialMenuClicked(object sender, RoutedEventArgs e)
+ private void BtnTutorialMenuClicked(object sender, RoutedEventArgs e)
+ {
+ tutorialButtonsStackPanel.Visibility = tutorialButtonsStackPanel.IsVisible ? Visibility.Hidden : Visibility.Visible;
+ }
+
+ private void BtnLoadTutorial(object sender, RoutedEventArgs e, KeyValuePair newTutorialScene)
+ {
+ startTransform = new TransformComponent();
+ targetTransform = new TransformComponent();
+ cameraLerpTimer = 0;
+
+ if (tutorialScene != null)
{
- tutorialButtonsStackPanel.Visibility = tutorialButtonsStackPanel.IsVisible ? Visibility.Hidden : Visibility.Visible;
+ SceneSystem.SceneInstance.RootScene.Children.Remove(tutorialScene);
}
-
- private void BtnLoadTutorial(object sender, RoutedEventArgs e, KeyValuePair newTutorialScene)
+ startTransform.Position = Camera.Transform.Position;
+ startTransform.Rotation = Camera.Transform.Rotation;
+
+ tutorialTitleTxt.Text = newTutorialScene.Key;
+ tutorialButtonsStackPanel.Visibility = Visibility.Hidden;
+ tutorialScene = Content.Load("Scenes/Basics/" + newTutorialScene.Value);
+ tutorialScene.Parent = Entity.Scene;
+ foreach (var entity in this.tutorialScene.Entities)
{
- startTransform = new TransformComponent();
- targetTransform = new TransformComponent();
- cameraLerpTimer = 0;
-
- if (tutorialScene != null)
- {
- SceneSystem.SceneInstance.RootScene.Children.Remove(tutorialScene);
- }
- startTransform.Position = Camera.Transform.Position;
- startTransform.Rotation = Camera.Transform.Rotation;
-
- tutorialTitleTxt.Text = newTutorialScene.Key;
- tutorialButtonsStackPanel.Visibility = Visibility.Hidden;
- tutorialScene = Content.Load("Scenes/Basics/" + newTutorialScene.Value);
- tutorialScene.Parent = Entity.Scene;
- foreach (var entity in this.tutorialScene.Entities)
+ if (entity.Name == "Camera")
{
- if (entity.Name == "Camera")
- {
- targetTransform.Position = entity.Transform.Position;
- targetTransform.Rotation = entity.Transform.Rotation;
- break;
- }
+ targetTransform.Position = entity.Transform.Position;
+ targetTransform.Rotation = entity.Transform.Rotation;
+ break;
}
}
+ }
- public override void Update()
+ public override void Update()
+ {
+ if (startTransform != null && cameraLerpTimer < cameraLerpTime)
{
- if (startTransform != null && cameraLerpTimer < cameraLerpTime)
- {
- var deltaTime = (float)Game.UpdateTime.Elapsed.TotalSeconds;
- cameraLerpTimer += deltaTime;
- var lerpTime = cameraLerpTimer / cameraLerpTime;
- Camera.Transform.Position = Vector3.Lerp(startTransform.Position, targetTransform.Position, lerpTime);
- Camera.Transform.Rotation = Quaternion.Lerp(startTransform.Rotation, targetTransform.Rotation, lerpTime);
- }
+ var deltaTime = (float)Game.UpdateTime.Elapsed.TotalSeconds;
+ cameraLerpTimer += deltaTime;
+ var lerpTime = cameraLerpTimer / cameraLerpTime;
+ Camera.Transform.Position = Vector3.Lerp(startTransform.Position, targetTransform.Position, lerpTime);
+ Camera.Transform.Rotation = Quaternion.Lerp(startTransform.Rotation, targetTransform.Rotation, lerpTime);
}
}
}
diff --git a/samples/Tutorials/CSharpBeginner/CSharpBeginner/CSharpBeginner.Game/Code/VirtualButtonsDemo.cs b/samples/Tutorials/CSharpBeginner/CSharpBeginner/CSharpBeginner.Game/Code/VirtualButtonsDemo.cs
index 8d101f26b6..9ff857353f 100644
--- a/samples/Tutorials/CSharpBeginner/CSharpBeginner/CSharpBeginner.Game/Code/VirtualButtonsDemo.cs
+++ b/samples/Tutorials/CSharpBeginner/CSharpBeginner/CSharpBeginner.Game/Code/VirtualButtonsDemo.cs
@@ -2,59 +2,58 @@
using Stride.Engine;
using Stride.Input;
-namespace CSharpBeginner.Code
+namespace CSharpBeginner.Code;
+
+///
+/// This script demonstrates how to create virtual buttons and how to use them.
+///
+/// https://doc.stride3d.net/latest/en/tutorials/csharpbeginner/virtual-buttons.html
+///
+///
+public class VirtualButtonsDemo : SyncScript
{
- ///
- /// This script demonstrates how to create virtual buttons and how to use them.
- ///
- /// https://doc.stride3d.net/latest/en/tutorials/csharpbeginner/virtual-buttons.html
- ///
- ///
- public class VirtualButtonsDemo : SyncScript
+ public Entity BlueTeapot;
+
+ public override void Start()
{
- public Entity BlueTeapot;
+ // Create a new VirtualButtonConfigSet if none exists.
+ Input.VirtualButtonConfigSet = Input.VirtualButtonConfigSet ?? new VirtualButtonConfigSet();
- public override void Start()
+ // Bind the "W" key and "Up arrow" to a virtual button called "Forward".
+ var forwardW = new VirtualButtonBinding("Forward", VirtualButton.Keyboard.W);
+ var forwardUpArrow = new VirtualButtonBinding("Forward", VirtualButton.Keyboard.Up);
+ var forwardLeftMouse = new VirtualButtonBinding("Forward", VirtualButton.Mouse.Left);
+ var forwardLeftTrigger = new VirtualButtonBinding("Forward", VirtualButton.GamePad.LeftTrigger);
+
+ // Create a new virtual button configuration and add the virtual button bindings
+ var virtualButtonForward = new VirtualButtonConfig
{
- // Create a new VirtualButtonConfigSet if none exists.
- Input.VirtualButtonConfigSet = Input.VirtualButtonConfigSet ?? new VirtualButtonConfigSet();
-
- // Bind the "W" key and "Up arrow" to a virtual button called "Forward".
- var forwardW = new VirtualButtonBinding("Forward", VirtualButton.Keyboard.W);
- var forwardUpArrow = new VirtualButtonBinding("Forward", VirtualButton.Keyboard.Up);
- var forwardLeftMouse = new VirtualButtonBinding("Forward", VirtualButton.Mouse.Left);
- var forwardLeftTrigger = new VirtualButtonBinding("Forward", VirtualButton.GamePad.LeftTrigger);
-
- // Create a new virtual button configuration and add the virtual button bindings
- var virtualButtonForward = new VirtualButtonConfig
- {
- forwardW,
- forwardUpArrow,
- forwardLeftMouse,
- forwardLeftTrigger
- };
-
- // Add the virtual button binding to the virtual button configuration
- Input.VirtualButtonConfigSet.Add(virtualButtonForward);
- }
+ forwardW,
+ forwardUpArrow,
+ forwardLeftMouse,
+ forwardLeftTrigger
+ };
+
+ // Add the virtual button binding to the virtual button configuration
+ Input.VirtualButtonConfigSet.Add(virtualButtonForward);
+ }
+
+ public override void Update()
+ {
+ // We retrieve a float value from the virtual button.
+ // When the value is higher than 0, we know that we have at least one of the keys or mouse pressed
+ // Keyboard and mouse return a value of 1 if they are being pressed.
+ // Gamepads can have a more accurate value between 0 and 1 depending on how far a trigger is being pressed
+ var forward = Input.GetVirtualButton(0, "Forward");
- public override void Update()
+ // Note: Gamepad sticks can be a negative value. For this example we only check if the value is higher than 0
+ if (forward > 0)
{
- // We retrieve a float value from the virtual button.
- // When the value is higher than 0, we know that we have at least one of the keys or mouse pressed
- // Keyboard and mouse return a value of 1 if they are being pressed.
- // Gamepads can have a more accurate value between 0 and 1 depending on how far a trigger is being pressed
- var forward = Input.GetVirtualButton(0, "Forward");
-
- // Note: Gamepad sticks can be a negative value. For this example we only check if the value is higher than 0
- if (forward > 0)
- {
- var deltaTime = (float)Game.UpdateTime.Elapsed.TotalSeconds;
- BlueTeapot.Transform.Rotation *= Quaternion.RotationY(0.6f * forward * deltaTime);
- }
-
- DebugText.Print("Hold down W, the Up arrow the left mouse button or the Left trigger on a gamepad", new Int2(600, 200));
- DebugText.Print("Virtual button 'Forward': " + forward, new Int2(600, 220));
+ var deltaTime = (float)Game.UpdateTime.Elapsed.TotalSeconds;
+ BlueTeapot.Transform.Rotation *= Quaternion.RotationY(0.6f * forward * deltaTime);
}
+
+ DebugText.Print("Hold down W, the Up arrow the left mouse button or the Left trigger on a gamepad", new Int2(600, 200));
+ DebugText.Print("Virtual button 'Forward': " + forward, new Int2(600, 220));
}
}
diff --git a/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/01_UI-Basics/UIByCode.cs b/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/01_UI-Basics/UIByCode.cs
index 5f6b7cf2c7..b294b2702e 100644
--- a/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/01_UI-Basics/UIByCode.cs
+++ b/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/01_UI-Basics/UIByCode.cs
@@ -8,81 +8,80 @@
using Stride.UI.Controls;
using Stride.UI.Panels;
-namespace CSharpIntermediate.Code
+namespace CSharpIntermediate.Code;
+
+public class UIByCode : StartupScript
{
- public class UIByCode : StartupScript
- {
- private SpriteFont font;
- private Button button;
- private TextBlock textBlock;
+ private SpriteFont font;
+ private Button button;
+ private TextBlock textBlock;
- public override void Start()
- {
- font = Content.Load("UI/OpenSans-font");
- button = CreateButton("Show me the time!");
- textBlock = CreateTextBlock("...");
+ public override void Start()
+ {
+ font = Content.Load("UI/OpenSans-font");
+ button = CreateButton("Show me the time!");
+ textBlock = CreateTextBlock("...");
- //We get or create a UI component and create a page with various elements
- var uiComponent = Entity.GetOrCreate();
+ //We get or create a UI component and create a page with various elements
+ var uiComponent = Entity.GetOrCreate();
- uiComponent.Page = new UIPage
+ uiComponent.Page = new UIPage
+ {
+ RootElement = new StackPanel
{
- RootElement = new StackPanel
+ Height = 200,
+ Width = 400,
+ Margin = new Thickness(0, 0, 10, 10),
+ VerticalAlignment = VerticalAlignment.Bottom,
+ HorizontalAlignment = HorizontalAlignment.Right,
+ BackgroundColor = new Color(0, 1, 0, 0.1f),
+ Children =
{
- Height = 200,
- Width = 400,
- Margin = new Thickness(0, 0, 10, 10),
- VerticalAlignment = VerticalAlignment.Bottom,
- HorizontalAlignment = HorizontalAlignment.Right,
- BackgroundColor = new Color(0, 1, 0, 0.1f),
- Children =
- {
- button,
- textBlock
- }
+ button,
+ textBlock
}
- };
- }
+ }
+ };
+ }
- private Button CreateButton(string buttonText)
+ private Button CreateButton(string buttonText)
+ {
+ // We create a new button. The content of the button is a TextBlock
+ var button = new Button
{
- // We create a new button. The content of the button is a TextBlock
- var button = new Button
- {
- Name = "ButtonByCode",
- HorizontalAlignment = HorizontalAlignment.Center,
- BackgroundColor = Color.DarkKhaki,
- Content = new TextBlock {
- Text = buttonText,
- Font = font,
- TextSize = 16,
- TextColor = Color.Black,
- VerticalAlignment = VerticalAlignment.Center
- }
- };
+ Name = "ButtonByCode",
+ HorizontalAlignment = HorizontalAlignment.Center,
+ BackgroundColor = Color.DarkKhaki,
+ Content = new TextBlock {
+ Text = buttonText,
+ Font = font,
+ TextSize = 16,
+ TextColor = Color.Black,
+ VerticalAlignment = VerticalAlignment.Center
+ }
+ };
- // We send up the click event of the button
- button.Click += (sender, args) =>
- {
- textBlock.Text = $"Date: {DateTime.Now.ToShortTimeString()}";
- };
+ // We send up the click event of the button
+ button.Click += (sender, args) =>
+ {
+ textBlock.Text = $"Date: {DateTime.Now.ToShortTimeString()}";
+ };
- return button;
- }
+ return button;
+ }
- private TextBlock CreateTextBlock(string defaultText)
+ private TextBlock CreateTextBlock(string defaultText)
+ {
+ var textBlock = new TextBlock
{
- var textBlock = new TextBlock
- {
- Name = "TextBlockByCode",
- Text = defaultText,
- Font = font,
- TextColor = Color.Yellow,
- BackgroundColor = Color.OrangeRed,
- HorizontalAlignment = HorizontalAlignment.Center
- };
+ Name = "TextBlockByCode",
+ Text = defaultText,
+ Font = font,
+ TextColor = Color.Yellow,
+ BackgroundColor = Color.OrangeRed,
+ HorizontalAlignment = HorizontalAlignment.Center
+ };
- return textBlock;
- }
+ return textBlock;
}
}
diff --git a/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/01_UI-Basics/UIByEditor.cs b/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/01_UI-Basics/UIByEditor.cs
index 7dec3b64ed..fc8a6d88af 100644
--- a/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/01_UI-Basics/UIByEditor.cs
+++ b/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/01_UI-Basics/UIByEditor.cs
@@ -6,42 +6,41 @@
using Stride.UI.Controls;
using Stride.UI.Events;
-namespace CSharpIntermediate.Code
+namespace CSharpIntermediate.Code;
+
+public class UIByEditor : StartupScript
{
- public class UIByEditor : StartupScript
- {
- public SpriteFont Font;
+ public SpriteFont Font;
- private TextBlock textBlock;
- private EditText editText;
+ private TextBlock textBlock;
+ private EditText editText;
- public override void Start()
- {
- // Retrieve the page property from the UI component
- var page = Entity.Get().Page;
+ public override void Start()
+ {
+ // Retrieve the page property from the UI component
+ var page = Entity.Get().Page;
- // Retrieve UI elements by Type and name
- textBlock = page.RootElement.FindVisualChildOfType("MyTextBlock");
- editText = page.RootElement.FindVisualChildOfType("MyEditText");
+ // Retrieve UI elements by Type and name
+ textBlock = page.RootElement.FindVisualChildOfType("MyTextBlock");
+ editText = page.RootElement.FindVisualChildOfType("MyEditText");
- // When the text changes, update the textblock
- editText.TextChanged += (s, e) =>
- {
- textBlock.Text = "My name is: " + editText.Text;
- };
+ // When the text changes, update the textblock
+ editText.TextChanged += (s, e) =>
+ {
+ textBlock.Text = "My name is: " + editText.Text;
+ };
- // When the button is clicked, we execute a method that clears the textbox
- var button = page.RootElement.FindVisualChildOfType("MyButton");
- button.Click += ButtonClicked;
- }
+ // When the button is clicked, we execute a method that clears the textbox
+ var button = page.RootElement.FindVisualChildOfType("MyButton");
+ button.Click += ButtonClicked;
+ }
- private void ButtonClicked(object sender, RoutedEventArgs e)
- {
- // Changing the text triggers the TextChanged event again
- editText.Text = "";
+ private void ButtonClicked(object sender, RoutedEventArgs e)
+ {
+ // Changing the text triggers the TextChanged event again
+ editText.Text = "";
- // We also want to reset the text in the textblock
- textBlock.Text = "...";
- }
+ // We also want to reset the text in the textblock
+ textBlock.Text = "...";
}
}
diff --git a/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/02_Collision-Triggers/CollisionTriggerDemo.cs b/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/02_Collision-Triggers/CollisionTriggerDemo.cs
index 1f2da25aaf..6b599ce1b7 100644
--- a/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/02_Collision-Triggers/CollisionTriggerDemo.cs
+++ b/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/02_Collision-Triggers/CollisionTriggerDemo.cs
@@ -6,54 +6,53 @@
using Stride.Engine;
using Stride.Physics;
-namespace CSharpIntermediate.Code
+namespace CSharpIntermediate.Code;
+
+public class CollisionTriggerDemo : SyncScript
{
- public class CollisionTriggerDemo : SyncScript
+ StaticColliderComponent staticCollider;
+ string collisionStatus = "";
+
+ public override void Start()
{
- StaticColliderComponent staticCollider;
- string collisionStatus = "";
+ // Retrieve the Physics component of the current entity
+ staticCollider = Entity.Get();
- public override void Start()
- {
- // Retrieve the Physics component of the current entity
- staticCollider = Entity.Get();
+ // When the 'CollectionChanged' event occurs, execute the CollisionsChanged method
+ staticCollider.Collisions.CollectionChanged += CollisionsChanged;
+ }
- // When the 'CollectionChanged' event occurs, execute the CollisionsChanged method
- staticCollider.Collisions.CollectionChanged += CollisionsChanged;
- }
+ private void CollisionsChanged(object sender, TrackingCollectionChangedEventArgs args)
+ {
+ // Cast the argument 'item' to a collision object
+ var collision = (Collision)args.Item;
- private void CollisionsChanged(object sender, TrackingCollectionChangedEventArgs args)
+ // We need to make sure which collision object is not the Trigger collider
+ // We perform a little check to find the ballCollider
+ var ballCollider = staticCollider == collision.ColliderA ? collision.ColliderB : collision.ColliderA;
+
+ if (args.Action == NotifyCollectionChangedAction.Add)
+ {
+ // When a collision has been added to the collision collection, we know an object has 'entered' our trigger
+ collisionStatus = ballCollider.Entity.Name + " entered " + staticCollider.Entity.Name;
+ }
+ else if (args.Action == NotifyCollectionChangedAction.Remove)
{
- // Cast the argument 'item' to a collision object
- var collision = (Collision)args.Item;
-
- // We need to make sure which collision object is not the Trigger collider
- // We perform a little check to find the ballCollider
- var ballCollider = staticCollider == collision.ColliderA ? collision.ColliderB : collision.ColliderA;
-
- if (args.Action == NotifyCollectionChangedAction.Add)
- {
- // When a collision has been added to the collision collection, we know an object has 'entered' our trigger
- collisionStatus = ballCollider.Entity.Name + " entered " + staticCollider.Entity.Name;
- }
- else if (args.Action == NotifyCollectionChangedAction.Remove)
- {
- // When a collision has been removed from the collision collection, we know an object 'left' our trigger
- collisionStatus = ballCollider.Entity.Name + " left " + staticCollider.Entity.Name;
- }
+ // When a collision has been removed from the collision collection, we know an object 'left' our trigger
+ collisionStatus = ballCollider.Entity.Name + " left " + staticCollider.Entity.Name;
}
+ }
- public override void Update()
+ public override void Update()
+ {
+ // The trigger collider can have 0, 1, or multiple collision going on in a single frame
+ int drawX = 500, drawY = 300;
+ foreach (var collision in staticCollider.Collisions)
{
- // The trigger collider can have 0, 1, or multiple collision going on in a single frame
- int drawX = 500, drawY = 300;
- foreach (var collision in staticCollider.Collisions)
- {
- DebugText.Print("ColliderA: " + collision.ColliderA.Entity.Name, new Int2(drawX, drawY += 20));
- DebugText.Print("ColliderB: " + collision.ColliderB.Entity.Name, new Int2(drawX, drawY += 20));
- }
-
- DebugText.Print(collisionStatus, new Int2(500, 400));
+ DebugText.Print("ColliderA: " + collision.ColliderA.Entity.Name, new Int2(drawX, drawY += 20));
+ DebugText.Print("ColliderB: " + collision.ColliderB.Entity.Name, new Int2(drawX, drawY += 20));
}
+
+ DebugText.Print(collisionStatus, new Int2(500, 400));
}
}
diff --git a/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/02_Collision-Triggers/Teleport.cs b/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/02_Collision-Triggers/Teleport.cs
index ffc97985a4..d2f1ee1eac 100644
--- a/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/02_Collision-Triggers/Teleport.cs
+++ b/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/02_Collision-Triggers/Teleport.cs
@@ -5,28 +5,27 @@
using Stride.Input;
using Stride.Physics;
-namespace CSharpIntermediate.Code
+namespace CSharpIntermediate.Code;
+
+public class Teleport : SyncScript
{
- public class Teleport : SyncScript
- {
- public Entity Ball;
+ public Entity Ball;
- public override void Start() { }
+ public override void Start() { }
- public override void Update()
- {
- DebugText.Print("Press Space to teleport ball back in the air", new Int2(500, 180));
+ public override void Update()
+ {
+ DebugText.Print("Press Space to teleport ball back in the air", new Int2(500, 180));
- if (Input.IsKeyPressed(Keys.Space))
- {
- Ball.Transform.Position = Entity.Transform.WorldMatrix.TranslationVector;
- Ball.Transform.UpdateWorldMatrix();
-
- // We have to update the physics transform since we manually positioned the ball's position
- var physicsComponent = Ball.Get();
- physicsComponent.LinearVelocity = new Vector3();
- physicsComponent.UpdatePhysicsTransformation();
- }
+ if (Input.IsKeyPressed(Keys.Space))
+ {
+ Ball.Transform.Position = Entity.Transform.WorldMatrix.TranslationVector;
+ Ball.Transform.UpdateWorldMatrix();
+
+ // We have to update the physics transform since we manually positioned the ball's position
+ var physicsComponent = Ball.Get();
+ physicsComponent.LinearVelocity = new Vector3();
+ physicsComponent.UpdatePhysicsTransformation();
}
}
}
diff --git a/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/03_Raycasting/RaycastDemo.cs b/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/03_Raycasting/RaycastDemo.cs
index c697e921eb..43847ccc44 100644
--- a/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/03_Raycasting/RaycastDemo.cs
+++ b/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/03_Raycasting/RaycastDemo.cs
@@ -5,56 +5,55 @@
using Stride.Engine;
using Stride.Physics;
-namespace CSharpIntermediate.Code
+namespace CSharpIntermediate.Code;
+
+public class RaycastDemo : SyncScript
{
- public class RaycastDemo : SyncScript
+ public CollisionFilterGroupFlags CollideWithGroup;
+ public bool CollideWithTriggers = false;
+ public Entity HitPoint;
+
+ private const float maxDistance = 4.0f;
+ private Entity laser;
+ private Simulation simulation;
+
+ public override void Start()
+ {
+ //Store the physics simulation object
+ simulation = this.GetSimulation();
+ laser = Entity.FindChild("Laser");
+ }
+
+ public override void Update()
{
- public CollisionFilterGroupFlags CollideWithGroup;
- public bool CollideWithTriggers = false;
- public Entity HitPoint;
+ int drawX = 340;
+ int drawY = 80;
+ DebugText.Print("Press Q and E to raise/lower weapons", new Int2(drawX, drawY));
- private const float maxDistance = 4.0f;
- private Entity laser;
- private Simulation simulation;
+ var raycastStart = Entity.Transform.Position;
+ var raycastEnd = Entity.Transform.Position + new Vector3(0, 0, maxDistance);
- public override void Start()
- {
- //Store the physics simulation object
- simulation = this.GetSimulation();
- laser = Entity.FindChild("Laser");
- }
+ drawY += 40;
- public override void Update()
+ // Send a raycast from the start to the endposition
+ if (simulation.Raycast(raycastStart, raycastEnd, out HitResult hitResult, CollisionFilterGroups.DefaultFilter, CollideWithGroup, CollideWithTriggers))
{
- int drawX = 340;
- int drawY = 80;
- DebugText.Print("Press Q and E to raise/lower weapons", new Int2(drawX, drawY));
-
- var raycastStart = Entity.Transform.Position;
- var raycastEnd = Entity.Transform.Position + new Vector3(0, 0, maxDistance);
-
- drawY += 40;
-
- // Send a raycast from the start to the endposition
- if (simulation.Raycast(raycastStart, raycastEnd, out HitResult hitResult, CollisionFilterGroups.DefaultFilter, CollideWithGroup, CollideWithTriggers))
- {
- // If we hit something, calculate the distance to the hitpoint and scale the laser to that distance
- HitPoint.Transform.Position = hitResult.Point;
- var distance = Vector3.Distance(hitResult.Point, raycastStart);
- laser.Transform.Scale.Z = distance;
+ // If we hit something, calculate the distance to the hitpoint and scale the laser to that distance
+ HitPoint.Transform.Position = hitResult.Point;
+ var distance = Vector3.Distance(hitResult.Point, raycastStart);
+ laser.Transform.Scale.Z = distance;
- DebugText.Print("Hit a collider", new Int2(drawX, drawY));
- DebugText.Print($"Raycast hit distance: {distance}", new Int2(drawX, drawY + 20));
- DebugText.Print($"Raycast hit point: {hitResult.Point.Print()}", new Int2(drawX, drawY + 40));
- DebugText.Print($"Raycast hit entity: {hitResult.Collider.Entity.Name}", new Int2(drawX, drawY + 60));
- }
- else
- {
- // If we didn't hit anything, scale the laser to match the distance between start and end
- HitPoint.Transform.Position = raycastEnd;
- laser.Transform.Scale.Z = Vector3.Distance(raycastStart, raycastEnd);
- DebugText.Print("No collider hit", new Int2(drawX, drawY));
- }
+ DebugText.Print("Hit a collider", new Int2(drawX, drawY));
+ DebugText.Print($"Raycast hit distance: {distance}", new Int2(drawX, drawY + 20));
+ DebugText.Print($"Raycast hit point: {hitResult.Point.Print()}", new Int2(drawX, drawY + 40));
+ DebugText.Print($"Raycast hit entity: {hitResult.Collider.Entity.Name}", new Int2(drawX, drawY + 60));
+ }
+ else
+ {
+ // If we didn't hit anything, scale the laser to match the distance between start and end
+ HitPoint.Transform.Position = raycastEnd;
+ laser.Transform.Scale.Z = Vector3.Distance(raycastStart, raycastEnd);
+ DebugText.Print("No collider hit", new Int2(drawX, drawY));
}
}
}
diff --git a/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/03_Raycasting/RaycastPenetratingDemo.cs b/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/03_Raycasting/RaycastPenetratingDemo.cs
index 0f9dfaf3b4..4c9426853f 100644
--- a/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/03_Raycasting/RaycastPenetratingDemo.cs
+++ b/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/03_Raycasting/RaycastPenetratingDemo.cs
@@ -5,53 +5,52 @@
using Stride.Engine;
using Stride.Physics;
-namespace CSharpIntermediate.Code
+namespace CSharpIntermediate.Code;
+
+public class RaycastPenetratingDemo : SyncScript
{
- public class RaycastPenetratingDemo : SyncScript
- {
- public CollisionFilterGroupFlags CollideWithGroup;
- public bool CollideWithTriggers = false;
+ public CollisionFilterGroupFlags CollideWithGroup;
+ public bool CollideWithTriggers = false;
- private Entity laser;
- private const float maxDistance = 3.0f;
- private Simulation simulation;
+ private Entity laser;
+ private const float maxDistance = 3.0f;
+ private Simulation simulation;
- public override void Start()
- {
- simulation = this.GetSimulation();
- laser = Entity.FindChild("Laser");
- }
+ public override void Start()
+ {
+ simulation = this.GetSimulation();
+ laser = Entity.FindChild("Laser");
+ }
- public override void Update()
- {
- int drawX = 700;
- int drawY = 80;
- DebugText.Print("Raycast penetration demo", new Int2(drawX, drawY));
+ public override void Update()
+ {
+ int drawX = 700;
+ int drawY = 80;
+ DebugText.Print("Raycast penetration demo", new Int2(drawX, drawY));
- var raycastStart = Entity.Transform.Position;
- var raycastEnd = Entity.Transform.Position + new Vector3(0, 0, -maxDistance);
+ var raycastStart = Entity.Transform.Position;
+ var raycastEnd = Entity.Transform.Position + new Vector3(0, 0, -maxDistance);
- var distance = Vector3.Distance(raycastStart, raycastEnd);
- laser.Transform.Scale.Z = distance;
+ var distance = Vector3.Distance(raycastStart, raycastEnd);
+ laser.Transform.Scale.Z = distance;
- var hitResults = new List();
- simulation.RaycastPenetrating(raycastStart, raycastEnd, hitResults, CollisionFilterGroups.DefaultFilter, CollideWithGroup, CollideWithTriggers);
+ var hitResults = new List();
+ simulation.RaycastPenetrating(raycastStart, raycastEnd, hitResults, CollisionFilterGroups.DefaultFilter, CollideWithGroup, CollideWithTriggers);
- drawY += 40;
- if (hitResults.Count > 0)
- {
- DebugText.Print($"Raycast has hit {hitResults.Count} object(s)", new Int2(drawX, drawY));
+ drawY += 40;
+ if (hitResults.Count > 0)
+ {
+ DebugText.Print($"Raycast has hit {hitResults.Count} object(s)", new Int2(drawX, drawY));
- foreach (var hitResult in hitResults)
- {
- drawY += 20;
- DebugText.Print($"- Raycast has hit: {hitResult.Collider.Entity.Name}", new Int2(drawX, drawY));
- }
- }
- else
+ foreach (var hitResult in hitResults)
{
- DebugText.Print("No collider hit", new Int2(drawX, drawY));
+ drawY += 20;
+ DebugText.Print($"- Raycast has hit: {hitResult.Collider.Entity.Name}", new Int2(drawX, drawY));
}
}
+ else
+ {
+ DebugText.Print("No collider hit", new Int2(drawX, drawY));
+ }
}
}
diff --git a/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/04_Project-UnProject/ProjectDemo.cs b/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/04_Project-UnProject/ProjectDemo.cs
index 6a2ed35050..c9afe76d4f 100644
--- a/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/04_Project-UnProject/ProjectDemo.cs
+++ b/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/04_Project-UnProject/ProjectDemo.cs
@@ -2,34 +2,32 @@
// 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.Graphics;
-namespace CSharpIntermediate.Code
+namespace CSharpIntermediate.Code;
+
+public class ProjectDemo : SyncScript
{
- public class ProjectDemo : SyncScript
- {
- public Entity projectSphere;
- public Entity projectSphereChild;
- private CameraComponent camera;
+ public Entity projectSphere;
+ public Entity projectSphereChild;
+ private CameraComponent camera;
- public override void Start()
- {
- camera = Entity.Get();
- }
+ public override void Start()
+ {
+ camera = Entity.Get();
+ }
- public override void Update()
- {
- var backBuffer = GraphicsDevice.Presenter.BackBuffer;
- var sphereProjection = Vector3.Project(projectSphere.Transform.WorldMatrix.TranslationVector, 0, 0, backBuffer.Width, backBuffer.Height,0, 8, camera.ViewProjectionMatrix);
- var sphereChildProjection = Vector3.Project(projectSphereChild.Transform.WorldMatrix.TranslationVector, 0, 0, backBuffer.Width, backBuffer.Height,0, 8, camera.ViewProjectionMatrix);
+ public override void Update()
+ {
+ var backBuffer = GraphicsDevice.Presenter.BackBuffer;
+ var sphereProjection = Vector3.Project(projectSphere.Transform.WorldMatrix.TranslationVector, 0, 0, backBuffer.Width, backBuffer.Height,0, 8, camera.ViewProjectionMatrix);
+ var sphereChildProjection = Vector3.Project(projectSphereChild.Transform.WorldMatrix.TranslationVector, 0, 0, backBuffer.Width, backBuffer.Height,0, 8, camera.ViewProjectionMatrix);
- // Similar method using Viewports
- //var viewport = new Viewport(0, 0, backBuffer.Width, backBuffer.Height);
- //var sphereProjection = viewport.Project(projectSphere.Transform.WorldMatrix.TranslationVector, camera.ProjectionMatrix, camera.ViewMatrix, Matrix.Identity);
- //var sphereChildProjection = viewport.Project(projectSphereChild.Transform.WorldMatrix.TranslationVector, camera.ProjectionMatrix, camera.ViewMatrix, Matrix.Identity);
+ // Similar method using Viewports
+ //var viewport = new Viewport(0, 0, backBuffer.Width, backBuffer.Height);
+ //var sphereProjection = viewport.Project(projectSphere.Transform.WorldMatrix.TranslationVector, camera.ProjectionMatrix, camera.ViewMatrix, Matrix.Identity);
+ //var sphereChildProjection = viewport.Project(projectSphereChild.Transform.WorldMatrix.TranslationVector, camera.ProjectionMatrix, camera.ViewMatrix, Matrix.Identity);
- DebugText.Print($"Parent", new Int2(sphereProjection.XY()));
- DebugText.Print($"Child", new Int2(sphereChildProjection.XY()));
- }
+ DebugText.Print($"Parent", new Int2(sphereProjection.XY()));
+ DebugText.Print($"Child", new Int2(sphereChildProjection.XY()));
}
}
diff --git a/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/04_Project-UnProject/UnprojectDemo.cs b/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/04_Project-UnProject/UnprojectDemo.cs
index 51a16254d9..a941938e40 100644
--- a/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/04_Project-UnProject/UnprojectDemo.cs
+++ b/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/04_Project-UnProject/UnprojectDemo.cs
@@ -6,37 +6,36 @@
using Stride.Input;
using Stride.Physics;
-namespace CSharpIntermediate.Code
+namespace CSharpIntermediate.Code;
+
+public class UnprojectDemo : SyncScript
{
- public class UnprojectDemo : SyncScript
- {
- private CameraComponent camera;
- public Entity sphereToClone;
+ private CameraComponent camera;
+ public Entity sphereToClone;
- public override void Start()
- {
- camera = Entity.Get();
- }
+ public override void Start()
+ {
+ camera = Entity.Get();
+ }
- public override void Update()
+ public override void Update()
+ {
+ if (Input.IsMouseButtonPressed(MouseButton.Left))
{
- if (Input.IsMouseButtonPressed(MouseButton.Left))
- {
- var backBuffer = GraphicsDevice.Presenter.BackBuffer;
- var viewport = new Viewport(0, 0, backBuffer.Width, backBuffer.Height);
+ var backBuffer = GraphicsDevice.Presenter.BackBuffer;
+ var viewport = new Viewport(0, 0, backBuffer.Width, backBuffer.Height);
- var nearPosition = viewport.Unproject(new Vector3(Input.AbsoluteMousePosition, 0.0f), camera.ProjectionMatrix, camera.ViewMatrix, Matrix.Identity);
- var farPosition = viewport.Unproject(new Vector3(Input.AbsoluteMousePosition, 1.0f), camera.ProjectionMatrix, camera.ViewMatrix, Matrix.Identity);
+ var nearPosition = viewport.Unproject(new Vector3(Input.AbsoluteMousePosition, 0.0f), camera.ProjectionMatrix, camera.ViewMatrix, Matrix.Identity);
+ var farPosition = viewport.Unproject(new Vector3(Input.AbsoluteMousePosition, 1.0f), camera.ProjectionMatrix, camera.ViewMatrix, Matrix.Identity);
- var hitResult = this.GetSimulation().Raycast(nearPosition, farPosition);
+ var hitResult = this.GetSimulation().Raycast(nearPosition, farPosition);
- // If there is a hitresult, clone the sphere and place it on that position
- if (hitResult.Succeeded)
- {
- var sphereClone = sphereToClone.Clone();
- sphereClone.Transform.Position = hitResult.Point;
- Entity.Scene.Entities.Add(sphereClone);
- }
+ // If there is a hitresult, clone the sphere and place it on that position
+ if (hitResult.Succeeded)
+ {
+ var sphereClone = sphereToClone.Clone();
+ sphereClone.Transform.Position = hitResult.Point;
+ Entity.Scene.Entities.Add(sphereClone);
}
}
}
diff --git a/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/05_Async/AsyncCollisionTriggerDemo.cs b/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/05_Async/AsyncCollisionTriggerDemo.cs
index 90732e38d3..73d4468e0e 100644
--- a/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/05_Async/AsyncCollisionTriggerDemo.cs
+++ b/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/05_Async/AsyncCollisionTriggerDemo.cs
@@ -5,49 +5,48 @@
using Stride.Physics;
using Stride.Rendering;
-namespace CSharpIntermediate.Code
+namespace CSharpIntermediate.Code;
+
+public class AsyncCollisionTriggerDemo : AsyncScript
{
- public class AsyncCollisionTriggerDemo : AsyncScript
+ private Material yellowMaterial;
+ private Material redMaterial;
+
+ public override async Task Execute()
{
- private Material yellowMaterial;
- private Material redMaterial;
+ // Store the collider component
+ var staticCollider = Entity.Get();
- public override async Task Execute()
- {
- // Store the collider component
- var staticCollider = Entity.Get();
-
- //Preload some materials
- yellowMaterial = Content.Load("Materials/Yellow");
-
- while (Game.IsRunning)
- {
- // Wait for an entity to collide with the trigger
- var collision = await staticCollider.NewCollision();
- var ballCollider = staticCollider == collision.ColliderA ? collision.ColliderB : collision.ColliderA;
-
- // Store current material
- var modelComponent = ballCollider.Entity.Get();
- var originalMaterial = modelComponent.Materials[0];
-
- // Change the material on the entity
- modelComponent.Materials[0] = yellowMaterial;
-
- // Wait for the entity to exit the trigger
- await staticCollider.CollisionEnded();
-
- // Alternative
- // await collision.Ended(); //This checks for the end of any collision on the actual collision object
-
- // Change the material back to the original one
- modelComponent.Materials[0] = originalMaterial;
- }
- }
+ //Preload some materials
+ yellowMaterial = Content.Load("Materials/Yellow");
- public override void Cancel()
+ while (Game.IsRunning)
{
- Content.Unload(yellowMaterial);
- Content.Unload(redMaterial);
+ // Wait for an entity to collide with the trigger
+ var collision = await staticCollider.NewCollision();
+ var ballCollider = staticCollider == collision.ColliderA ? collision.ColliderB : collision.ColliderA;
+
+ // Store current material
+ var modelComponent = ballCollider.Entity.Get();
+ var originalMaterial = modelComponent.Materials[0];
+
+ // Change the material on the entity
+ modelComponent.Materials[0] = yellowMaterial;
+
+ // Wait for the entity to exit the trigger
+ await staticCollider.CollisionEnded();
+
+ // Alternative
+ // await collision.Ended(); //This checks for the end of any collision on the actual collision object
+
+ // Change the material back to the original one
+ modelComponent.Materials[0] = originalMaterial;
}
}
+
+ public override void Cancel()
+ {
+ Content.Unload(yellowMaterial);
+ Content.Unload(redMaterial);
+ }
}
diff --git a/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/05_Async/AsyncWebApi.cs b/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/05_Async/AsyncWebApi.cs
index 2aab93c40c..722a66503c 100644
--- a/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/05_Async/AsyncWebApi.cs
+++ b/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/05_Async/AsyncWebApi.cs
@@ -7,59 +7,58 @@
using Stride.Core.Mathematics;
using Stride.Engine;
-namespace CSharpIntermediate.Code
+namespace CSharpIntermediate.Code;
+
+public class AsyncWebApi : AsyncScript
{
- public class AsyncWebApi : AsyncScript
+ private List openCollectiveEvents;
+
+ public override async Task Execute()
{
- private List openCollectiveEvents;
+ openCollectiveEvents = new List();
- public override async Task Execute()
+ while (Game.IsRunning)
{
- openCollectiveEvents = new List();
+ int drawX = 500, drawY = 600;
+ DebugText.Print($"Press A to get Api data from https://opencollective.com/stride3d", new Int2(drawX, drawY));
- while (Game.IsRunning)
+ if (Input.IsKeyPressed(Stride.Input.Keys.G))
{
- int drawX = 500, drawY = 600;
- DebugText.Print($"Press A to get Api data from https://opencollective.com/stride3d", new Int2(drawX, drawY));
-
- if (Input.IsKeyPressed(Stride.Input.Keys.G))
- {
- await RetrieveStrideRepos();
- await Script.NextFrame();
- }
-
- foreach (var openCollectiveEvent in openCollectiveEvents)
- {
- drawY += 20;
- DebugText.Print(openCollectiveEvent.Name, new Int2(drawX, drawY));
- }
-
- // We have to await the next frame. If we don't do this, our game will be stuck in an infinite loop
+ await RetrieveStrideRepos();
await Script.NextFrame();
}
- }
-
- private async Task RetrieveStrideRepos()
- {
- // We can use an HttpClient to make requests to web api's
- var client = new HttpClient();
- HttpResponseMessage response = await client.GetAsync("https://opencollective.com/stride3d/events.json?limit=4");
- if (response.StatusCode == System.Net.HttpStatusCode.OK)
+ foreach (var openCollectiveEvent in openCollectiveEvents)
{
- // We store the contents of the response in a string
- string responseContent = await response.Content.ReadAsStringAsync();
-
- // We deserialze the string into an object
- openCollectiveEvents = JsonSerializer.Deserialize>(responseContent);
+ drawY += 20;
+ DebugText.Print(openCollectiveEvent.Name, new Int2(drawX, drawY));
}
+
+ // We have to await the next frame. If we don't do this, our game will be stuck in an infinite loop
+ await Script.NextFrame();
}
+ }
+
+ private async Task RetrieveStrideRepos()
+ {
+ // We can use an HttpClient to make requests to web api's
+ var client = new HttpClient();
+ HttpResponseMessage response = await client.GetAsync("https://opencollective.com/stride3d/events.json?limit=4");
- public class OpenCollectiveEvent
+ if (response.StatusCode == System.Net.HttpStatusCode.OK)
{
- public string Name { get; set; }
+ // We store the contents of the response in a string
+ string responseContent = await response.Content.ReadAsStringAsync();
- public string StartsAt { get; set; }
+ // We deserialze the string into an object
+ openCollectiveEvents = JsonSerializer.Deserialize>(responseContent);
}
}
+
+ public class OpenCollectiveEvent
+ {
+ public string Name { get; set; }
+
+ public string StartsAt { get; set; }
+ }
}
diff --git a/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/06_Scenes/LoadChildScene.cs b/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/06_Scenes/LoadChildScene.cs
index 01d34215e7..6cc5deef29 100644
--- a/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/06_Scenes/LoadChildScene.cs
+++ b/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/06_Scenes/LoadChildScene.cs
@@ -5,43 +5,42 @@
using Stride.Engine;
using Stride.Input;
-namespace CSharpIntermediate
+namespace CSharpIntermediate;
+
+public class LoadChildScene : SyncScript
{
- public class LoadChildScene : SyncScript
- {
- // We can load a scene by name, however if the scene would be renamed, this property would not update
- //public string childSceneToLoad;
+ // We can load a scene by name, however if the scene would be renamed, this property would not update
+ //public string childSceneToLoad;
- public UrlReference childSceneToLoad;
- private int loaded = 0;
- private Scene loadedChildScene;
+ public UrlReference childSceneToLoad;
+ private int loaded = 0;
+ private Scene loadedChildScene;
- public override void Update()
+ public override void Update()
+ {
+ DebugText.Print("Press C to load/unload child scene", new Int2(20, 60));
+ if (Input.IsKeyPressed(Keys.C))
{
- DebugText.Print("Press C to load/unload child scene", new Int2(20, 60));
- if (Input.IsKeyPressed(Keys.C))
+ if (loadedChildScene == null)
{
- if (loadedChildScene == null)
- {
- // loadedChildScene = Content.Load(childSceneToLoad);
- // Or
- loadedChildScene = Content.Load(childSceneToLoad);
- loadedChildScene.Offset = new Vector3(0, 0.5f * loaded, 0);
- loaded++;
+ // loadedChildScene = Content.Load(childSceneToLoad);
+ // Or
+ loadedChildScene = Content.Load(childSceneToLoad);
+ loadedChildScene.Offset = new Vector3(0, 0.5f * loaded, 0);
+ loaded++;
- // Entity.Scene.Children.Add(loadedChildScene);
- // Or
- loadedChildScene.Parent = Entity.Scene;
- }
- else
- {
- // Entity.Scene.Children.Remove(loadedChildScene);
- // Or
- loadedChildScene.Parent = null;
+ // Entity.Scene.Children.Add(loadedChildScene);
+ // Or
+ loadedChildScene.Parent = Entity.Scene;
+ }
+ else
+ {
+ // Entity.Scene.Children.Remove(loadedChildScene);
+ // Or
+ loadedChildScene.Parent = null;
- Content.Unload(loadedChildScene);
- loadedChildScene = null;
- }
+ Content.Unload(loadedChildScene);
+ loadedChildScene = null;
}
}
}
diff --git a/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/06_Scenes/LoadScene.cs b/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/06_Scenes/LoadScene.cs
index 67d7ee7956..31082a72a4 100644
--- a/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/06_Scenes/LoadScene.cs
+++ b/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/06_Scenes/LoadScene.cs
@@ -5,24 +5,23 @@
using Stride.Engine;
using Stride.Input;
-namespace CSharpIntermediate
+namespace CSharpIntermediate;
+
+public class LoadScene : SyncScript
{
- public class LoadScene : SyncScript
+ public UrlReference SceneToLoad;
+ public int DrawY = 20;
+ public string Info = "Info text";
+ public Keys KeyToPress;
+
+ public override void Update()
{
- public UrlReference SceneToLoad;
- public int DrawY = 20;
- public string Info = "Info text";
- public Keys KeyToPress;
+ DebugText.Print($"{Info}: {KeyToPress}", new Int2(20, DrawY));
- public override void Update()
+ if (Input.IsKeyPressed(KeyToPress))
{
- DebugText.Print($"{Info}: {KeyToPress}", new Int2(20, DrawY));
-
- if (Input.IsKeyPressed(KeyToPress))
- {
- Content.Unload(SceneSystem.SceneInstance.RootScene);
- SceneSystem.SceneInstance.RootScene = Content.Load(SceneToLoad);
- }
+ Content.Unload(SceneSystem.SceneInstance.RootScene);
+ SceneSystem.SceneInstance.RootScene = Content.Load(SceneToLoad);
}
}
}
diff --git a/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/07_Animation/AnimationBasics.cs b/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/07_Animation/AnimationBasics.cs
index 73d9df3bd9..76e44143f3 100644
--- a/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/07_Animation/AnimationBasics.cs
+++ b/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/07_Animation/AnimationBasics.cs
@@ -6,87 +6,86 @@
using Stride.Engine;
using Stride.Input;
-namespace CSharpIntermediate.Code
+namespace CSharpIntermediate.Code;
+
+public class AnimationBasics : SyncScript
{
- public class AnimationBasics : SyncScript
- {
- public float AnimationSpeed = 1.0f;
- private AnimationComponent animation;
- private PlayingAnimation latestAnimation;
+ public float AnimationSpeed = 1.0f;
+ private AnimationComponent animation;
+ private PlayingAnimation latestAnimation;
- public override void Start()
- {
- animation = Entity.Get();
+ public override void Start()
+ {
+ animation = Entity.Get();
- // Set the default animation
- latestAnimation = animation.Play("Idle");
- }
+ // Set the default animation
+ latestAnimation = animation.Play("Idle");
+ }
- public override void Update()
- {
- int drawX = 800, drawY = 600;
+ public override void Update()
+ {
+ int drawX = 800, drawY = 600;
- StopOrResumeAnimations(drawX, drawY += 20);
+ StopOrResumeAnimations(drawX, drawY += 20);
- AdjustAnimationSpeed(drawX, drawY += 20);
+ AdjustAnimationSpeed(drawX, drawY += 20);
- DebugText.Print("I to start playing Idle", new Int2(drawX, drawY += 20));
- if (Input.IsKeyPressed(Keys.I))
- {
- latestAnimation = animation.Play("Idle");
- latestAnimation.TimeFactor = AnimationSpeed;
- }
+ DebugText.Print("I to start playing Idle", new Int2(drawX, drawY += 20));
+ if (Input.IsKeyPressed(Keys.I))
+ {
+ latestAnimation = animation.Play("Idle");
+ latestAnimation.TimeFactor = AnimationSpeed;
+ }
- DebugText.Print("R to crossfade to Run", new Int2(drawX, drawY += 20));
- if (Input.IsKeyPressed(Keys.R))
- {
- latestAnimation = animation.Crossfade("Run", TimeSpan.FromSeconds(0.5));
- latestAnimation.TimeFactor = AnimationSpeed;
- }
+ DebugText.Print("R to crossfade to Run", new Int2(drawX, drawY += 20));
+ if (Input.IsKeyPressed(Keys.R))
+ {
+ latestAnimation = animation.Crossfade("Run", TimeSpan.FromSeconds(0.5));
+ latestAnimation.TimeFactor = AnimationSpeed;
+ }
- // We can crossfade to a punch animation, but only if it is not already playing
- DebugText.Print("P to crossfade to Punch and play it once", new Int2(drawX, drawY += 20));
- if (Input.IsKeyPressed(Keys.P) && !animation.IsPlaying("Punch"))
- {
- latestAnimation = animation.Crossfade("Punch", TimeSpan.FromSeconds(0.1));
- latestAnimation.RepeatMode = AnimationRepeatMode.PlayOnce;
- latestAnimation.TimeFactor = AnimationSpeed;
- }
+ // We can crossfade to a punch animation, but only if it is not already playing
+ DebugText.Print("P to crossfade to Punch and play it once", new Int2(drawX, drawY += 20));
+ if (Input.IsKeyPressed(Keys.P) && !animation.IsPlaying("Punch"))
+ {
+ latestAnimation = animation.Crossfade("Punch", TimeSpan.FromSeconds(0.1));
+ latestAnimation.RepeatMode = AnimationRepeatMode.PlayOnce;
+ latestAnimation.TimeFactor = AnimationSpeed;
+ }
- // When the punch animation is the latest animation, but it is no longer playing, we set a new animation
- if (latestAnimation.Name == "Punch" && !animation.IsPlaying("Punch"))
- {
- latestAnimation = animation.Play("Idle");
- latestAnimation.RepeatMode = AnimationRepeatMode.LoopInfinite;
- latestAnimation.TimeFactor = AnimationSpeed;
- }
+ // When the punch animation is the latest animation, but it is no longer playing, we set a new animation
+ if (latestAnimation.Name == "Punch" && !animation.IsPlaying("Punch"))
+ {
+ latestAnimation = animation.Play("Idle");
+ latestAnimation.RepeatMode = AnimationRepeatMode.LoopInfinite;
+ latestAnimation.TimeFactor = AnimationSpeed;
}
+ }
- private void StopOrResumeAnimations(int drawX, int drawY)
+ private void StopOrResumeAnimations(int drawX, int drawY)
+ {
+ DebugText.Print($"S to pause or resume animations", new Int2(drawX, drawY));
+ if (Input.IsKeyPressed(Keys.S))
{
- DebugText.Print($"S to pause or resume animations", new Int2(drawX, drawY));
- if (Input.IsKeyPressed(Keys.S))
+ foreach (var playingAnimation in animation.PlayingAnimations)
{
- foreach (var playingAnimation in animation.PlayingAnimations)
- {
- playingAnimation.Enabled = !playingAnimation.Enabled;
- }
+ playingAnimation.Enabled = !playingAnimation.Enabled;
}
}
+ }
- private void AdjustAnimationSpeed(int drawX, int drawY)
+ private void AdjustAnimationSpeed(int drawX, int drawY)
+ {
+ DebugText.Print($"Q and E for speed {AnimationSpeed:0.0}", new Int2(drawX, drawY));
+ if (Input.IsKeyPressed(Keys.E))
{
- DebugText.Print($"Q and E for speed {AnimationSpeed:0.0}", new Int2(drawX, drawY));
- if (Input.IsKeyPressed(Keys.E))
- {
- AnimationSpeed += 0.1f;
- latestAnimation.TimeFactor = AnimationSpeed;
- }
- if (Input.IsKeyPressed(Keys.Q))
- {
- AnimationSpeed -= 0.1f;
- latestAnimation.TimeFactor = AnimationSpeed;
- }
+ AnimationSpeed += 0.1f;
+ latestAnimation.TimeFactor = AnimationSpeed;
+ }
+ if (Input.IsKeyPressed(Keys.Q))
+ {
+ AnimationSpeed -= 0.1f;
+ latestAnimation.TimeFactor = AnimationSpeed;
}
}
}
diff --git a/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/08_Audio/AudioDemo.cs b/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/08_Audio/AudioDemo.cs
index 587995aeb6..48254edcde 100644
--- a/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/08_Audio/AudioDemo.cs
+++ b/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/08_Audio/AudioDemo.cs
@@ -6,41 +6,40 @@
using Stride.Engine;
using Stride.Input;
-namespace CSharpIntermediate.Code
+namespace CSharpIntermediate.Code;
+
+public class AudioDemo : SyncScript
{
- public class AudioDemo : SyncScript
+ public Sound UkuleleSound;
+
+ private SoundInstance ukuleleInstance;
+ private AudioEmitterComponent audioEmitterComponent;
+ private AudioEmitterSoundController gunSoundEmitter;
+
+ public override void Start()
{
- public Sound UkuleleSound;
+ // We need to create an instance of Sound object in order to play them
+ ukuleleInstance = UkuleleSound.CreateInstance();
- private SoundInstance ukuleleInstance;
- private AudioEmitterComponent audioEmitterComponent;
- private AudioEmitterSoundController gunSoundEmitter;
+ audioEmitterComponent = Entity.Get();
+ gunSoundEmitter = audioEmitterComponent["Gun"];
+ }
- public override void Start()
+ public override void Update()
+ {
+ // Play a sound
+ DebugText.Print($"U to play the Ukelele once", new Int2(200, 580));
+ if (Input.IsKeyPressed(Keys.U))
{
- // We need to create an instance of Sound object in order to play them
- ukuleleInstance = UkuleleSound.CreateInstance();
-
- audioEmitterComponent = Entity.Get();
- gunSoundEmitter = audioEmitterComponent["Gun"];
+ ukuleleInstance.Stop();
+ ukuleleInstance.Play();
}
- public override void Update()
+ // Press right mouse button for gun fire sound
+ DebugText.Print($"Press right mouse button fire gun", new Int2(200, 640));
+ if (Input.IsMouseButtonPressed(MouseButton.Right))
{
- // Play a sound
- DebugText.Print($"U to play the Ukelele once", new Int2(200, 580));
- if (Input.IsKeyPressed(Keys.U))
- {
- ukuleleInstance.Stop();
- ukuleleInstance.Play();
- }
-
- // Press right mouse button for gun fire sound
- DebugText.Print($"Press right mouse button fire gun", new Int2(200, 640));
- if (Input.IsMouseButtonPressed(MouseButton.Right))
- {
- gunSoundEmitter.Play();
- }
+ gunSoundEmitter.Play();
}
}
}
diff --git a/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/08_Audio/LoadMusic.cs b/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/08_Audio/LoadMusic.cs
index 9fe5dd3bdc..97570b8301 100644
--- a/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/08_Audio/LoadMusic.cs
+++ b/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/08_Audio/LoadMusic.cs
@@ -9,62 +9,61 @@
using Stride.Input;
using Stride.Media;
-namespace CSharpIntermediate.Code
+namespace CSharpIntermediate.Code;
+
+public class LoadMusic : AsyncScript
{
- public class LoadMusic : AsyncScript
- {
- public Sound BackgroundMusic;
+ public Sound BackgroundMusic;
- private SoundInstance musicInstance;
+ private SoundInstance musicInstance;
- public override async Task Execute()
- {
- musicInstance = BackgroundMusic.CreateInstance();
+ public override async Task Execute()
+ {
+ musicInstance = BackgroundMusic.CreateInstance();
- // Wait till the music is done loading
- await musicInstance.ReadyToPlay();
+ // Wait till the music is done loading
+ await musicInstance.ReadyToPlay();
- while (Game.IsRunning)
+ while (Game.IsRunning)
+ {
+ // Play or pause
+ DebugText.Print($"Space to play/pause. Currently: {musicInstance.PlayState}", new Int2(800, 580));
+ if (Input.IsKeyPressed(Keys.Space))
{
- // Play or pause
- DebugText.Print($"Space to play/pause. Currently: {musicInstance.PlayState}", new Int2(800, 580));
- if (Input.IsKeyPressed(Keys.Space))
+ if (musicInstance.PlayState == PlayState.Playing)
{
- if (musicInstance.PlayState == PlayState.Playing)
- {
- musicInstance.Pause();
- }
- else
- {
- musicInstance.Play();
- }
+ musicInstance.Pause();
}
-
- // Volume
- DebugText.Print($"Up/Down to change volume: {musicInstance.Volume:0.0}", new Int2(800, 600));
- if (Input.IsKeyPressed(Keys.Up))
+ else
{
- musicInstance.Volume = Math.Clamp(musicInstance.Volume + 0.1f, 0, 2);
- }
- if (Input.IsKeyPressed(Keys.Down))
- {
- musicInstance.Volume = Math.Clamp(musicInstance.Volume - 0.1f, 0, 2);
+ musicInstance.Play();
}
+ }
- // Panning
- DebugText.Print($"Left/Right to change panning: {musicInstance.Pan:0.0}", new Int2(800, 620));
- if (Input.IsKeyPressed(Keys.Left))
- {
- musicInstance.Pan = Math.Clamp(musicInstance.Pan - 0.1f, -1, 1);
- }
- if (Input.IsKeyPressed(Keys.Right))
- {
- musicInstance.Pan = Math.Clamp(musicInstance.Pan + 0.1f, -1, 1);
- }
+ // Volume
+ DebugText.Print($"Up/Down to change volume: {musicInstance.Volume:0.0}", new Int2(800, 600));
+ if (Input.IsKeyPressed(Keys.Up))
+ {
+ musicInstance.Volume = Math.Clamp(musicInstance.Volume + 0.1f, 0, 2);
+ }
+ if (Input.IsKeyPressed(Keys.Down))
+ {
+ musicInstance.Volume = Math.Clamp(musicInstance.Volume - 0.1f, 0, 2);
+ }
- // Wait for next frame
- await Script.NextFrame();
+ // Panning
+ DebugText.Print($"Left/Right to change panning: {musicInstance.Pan:0.0}", new Int2(800, 620));
+ if (Input.IsKeyPressed(Keys.Left))
+ {
+ musicInstance.Pan = Math.Clamp(musicInstance.Pan - 0.1f, -1, 1);
}
+ if (Input.IsKeyPressed(Keys.Right))
+ {
+ musicInstance.Pan = Math.Clamp(musicInstance.Pan + 0.1f, -1, 1);
+ }
+
+ // Wait for next frame
+ await Script.NextFrame();
}
}
}
diff --git a/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/09_FirstPersonCamera/FirstPersonCamera.cs b/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/09_FirstPersonCamera/FirstPersonCamera.cs
index 114a7a9265..d504fb0095 100644
--- a/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/09_FirstPersonCamera/FirstPersonCamera.cs
+++ b/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/09_FirstPersonCamera/FirstPersonCamera.cs
@@ -5,67 +5,66 @@
using Stride.Input;
using Stride.Physics;
-namespace CSharpIntermediate.Code
+namespace CSharpIntermediate.Code;
+
+public class FirstPersonCamera : SyncScript
{
- public class FirstPersonCamera : SyncScript
- {
- public float MouseSpeed = 0.6f;
- public float MaxLookUpAngle = -50;
- public float MaxLookDownAngle = 50;
- public bool InvertMouseY = false;
+ 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;
+ private Entity firstPersonCameraPivot;
+ private Vector3 camRotation;
+ private bool isActive = false;
+ private Vector2 maxCameraAnglesRadians;
+ private CharacterComponent character;
- public override void Start()
- {
- firstPersonCameraPivot = Entity.FindChild("CameraPivot");
+ 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;
+ // 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);
+ // Set the mouse to the middle of the screen
+ Input.MousePosition = new Vector2(0.5f, 0.5f);
- isActive = true;
- Game.IsMouseVisible = false;
+ isActive = true;
+ Game.IsMouseVisible = false;
- character = Entity.Get();
- }
+ character = Entity.Get();
+ }
- public override void Update()
+ public override void Update()
+ {
+ if (Input.IsKeyPressed(Keys.Escape))
{
- if (Input.IsKeyPressed(Keys.Escape))
- {
- isActive = !isActive;
- Game.IsMouseVisible = !isActive;
- Input.UnlockMousePosition();
- }
+ isActive = !isActive;
+ Game.IsMouseVisible = !isActive;
+ Input.UnlockMousePosition();
+ }
- if (isActive)
- {
- Input.LockMousePosition();
- var mouseMovement = Input.MouseDelta * MouseSpeed;
+ 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);
+ // 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 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);
- }
+ // Apply X camera rotation to the existing camera rotations
+ firstPersonCameraPivot.Transform.Rotation = Quaternion.RotationX(camRotation.X);
}
}
}
diff --git a/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/10_ThirdPersonCamera/CharacterMovement.cs b/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/10_ThirdPersonCamera/CharacterMovement.cs
index 22a29656f8..b56e723a7a 100644
--- a/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/10_ThirdPersonCamera/CharacterMovement.cs
+++ b/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/10_ThirdPersonCamera/CharacterMovement.cs
@@ -5,43 +5,42 @@
using Stride.Input;
using Stride.Physics;
-namespace CSharpIntermediate.Code
+namespace CSharpIntermediate.Code;
+
+public class CharacterMovement : SyncScript
{
- public class CharacterMovement : SyncScript
- {
- public Vector3 MovementMultiplier = new Vector3(3, 0, 4);
- private CharacterComponent character;
+ public Vector3 MovementMultiplier = new Vector3(3, 0, 4);
+ private CharacterComponent character;
- public override void Start()
- {
- character = Entity.Get();
- }
+ public override void Start()
+ {
+ character = Entity.Get();
+ }
- public override void Update()
+ public override void Update()
+ {
+ var velocity = new Vector3();
+ if (Input.IsKeyDown(Keys.W))
{
- 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.Z++;
+ }
+ if (Input.IsKeyDown(Keys.S))
+ {
+ velocity.Z--;
+ }
- velocity.Normalize();
- velocity *= MovementMultiplier;
- velocity = Vector3.Transform(velocity, Entity.Transform.Rotation);
- character.SetVelocity(velocity);
+ 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);
}
}
diff --git a/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/10_ThirdPersonCamera/ThirdPersonCamera.cs b/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/10_ThirdPersonCamera/ThirdPersonCamera.cs
index fcfbc709f3..99313635a9 100644
--- a/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/10_ThirdPersonCamera/ThirdPersonCamera.cs
+++ b/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/10_ThirdPersonCamera/ThirdPersonCamera.cs
@@ -5,92 +5,91 @@
using Stride.Input;
using Stride.Physics;
-namespace CSharpIntermediate.Code
+namespace CSharpIntermediate.Code;
+
+public class ThirdPersonCamera : SyncScript
{
- public class ThirdPersonCamera : SyncScript
+ public bool InvertMouseY = false;
+ public Vector2 MouseSpeed = new Vector2(0.6f, 0.5f);
+ public float MaxLookUpAngle = -40;
+ public float MaxLookDownAngle = 40;
+ public float MinimumCameraDistance = 1.5f;
+ public Vector3 CameraOffset = new Vector3(0, 0, -3);
+
+ private Entity firstPersonPivot;
+ private Entity thirdPersonPivot;
+
+ private Vector2 maxCameraAnglesRadians;
+ private Vector3 camRotation;
+ private bool isActive = false;
+ private Simulation simulation;
+ private CharacterComponent character;
+
+ public override void Start()
{
- public bool InvertMouseY = false;
- public Vector2 MouseSpeed = new Vector2(0.6f, 0.5f);
- public float MaxLookUpAngle = -40;
- public float MaxLookDownAngle = 40;
- public float MinimumCameraDistance = 1.5f;
- public Vector3 CameraOffset = new Vector3(0, 0, -3);
-
- private Entity firstPersonPivot;
- private Entity thirdPersonPivot;
-
- private Vector2 maxCameraAnglesRadians;
- private Vector3 camRotation;
- private bool isActive = false;
- private Simulation simulation;
- private CharacterComponent character;
-
- public override void Start()
- {
- Game.IsMouseVisible = false;
- isActive = true;
+ Game.IsMouseVisible = false;
+ isActive = true;
+
+ firstPersonPivot = Entity.FindChild("FirstPersonPivot");
+ thirdPersonPivot = Entity.FindChild("ThirdPersonPivot");
- firstPersonPivot = Entity.FindChild("FirstPersonPivot");
- thirdPersonPivot = Entity.FindChild("ThirdPersonPivot");
+ maxCameraAnglesRadians = new Vector2(MathUtil.DegreesToRadians(MaxLookUpAngle), MathUtil.DegreesToRadians(MaxLookDownAngle));
+ camRotation = Entity.Transform.RotationEulerXYZ;
+ Input.MousePosition = new Vector2(0.5f, 0.5f);
+ simulation = this.GetSimulation();
+ character = Entity.Get();
+ }
- maxCameraAnglesRadians = new Vector2(MathUtil.DegreesToRadians(MaxLookUpAngle), MathUtil.DegreesToRadians(MaxLookDownAngle));
- camRotation = Entity.Transform.RotationEulerXYZ;
- Input.MousePosition = new Vector2(0.5f, 0.5f);
- simulation = this.GetSimulation();
- character = Entity.Get();
+ public override void Update()
+ {
+ if (Input.IsKeyPressed(Keys.Escape))
+ {
+ isActive = !isActive;
+ Game.IsMouseVisible = !isActive;
+ Input.UnlockMousePosition();
}
- public override void Update()
+ if (isActive)
{
- if (Input.IsKeyPressed(Keys.Escape))
- {
- isActive = !isActive;
- Game.IsMouseVisible = !isActive;
- Input.UnlockMousePosition();
- }
+ Input.LockMousePosition();
+ var mouseMovement = -Input.MouseDelta * MouseSpeed;
- if (isActive)
- {
- Input.LockMousePosition();
- var mouseMovement = -Input.MouseDelta * MouseSpeed;
+ // Update rotation values with the mouse movement
+ camRotation.Y += mouseMovement.X;
+ camRotation.X += InvertMouseY ? mouseMovement.Y : -mouseMovement.Y;
+ camRotation.X = MathUtil.Clamp(camRotation.X, maxCameraAnglesRadians.X, maxCameraAnglesRadians.Y);
- // Update rotation values with the mouse movement
- 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);
- // Apply Y rotation to character entity
- character.Orientation = Quaternion.RotationY(camRotation.Y);
+ // Apply X rotation the existing first person pivot
+ firstPersonPivot.Transform.Rotation = Quaternion.RotationX(camRotation.X);
- // Apply X rotation the existing first person pivot
- firstPersonPivot.Transform.Rotation = Quaternion.RotationX(camRotation.X);
+ // The third person pivot gets the same position and rotation as the first person pivot + the camera offset
+ thirdPersonPivot.Transform.Position = new Vector3(0);
+ thirdPersonPivot.Transform.Position += CameraOffset;
- // The third person pivot gets the same position and rotation as the first person pivot + the camera offset
- thirdPersonPivot.Transform.Position = new Vector3(0);
- thirdPersonPivot.Transform.Position += CameraOffset;
+ // Make sure that the WorldMatrix of the thirdperson pivot is up to date
+ thirdPersonPivot.Transform.UpdateWorldMatrix();
- // Make sure that the WorldMatrix of the thirdperson pivot is up to date
- thirdPersonPivot.Transform.UpdateWorldMatrix();
+ // Raycast from first person pivot to third person pivot
+ var raycastStart = firstPersonPivot.Transform.WorldMatrix.TranslationVector;
+ var raycastEnd = thirdPersonPivot.Transform.WorldMatrix.TranslationVector;
- // Raycast from first person pivot to third person pivot
- var raycastStart = firstPersonPivot.Transform.WorldMatrix.TranslationVector;
- var raycastEnd = thirdPersonPivot.Transform.WorldMatrix.TranslationVector;
+ if (simulation.Raycast(raycastStart, raycastEnd, out HitResult hitResult))
+ {
+ // If we hit something along the way, calculate the distance
+ var hitDistance = Vector3.Distance(raycastStart, hitResult.Point);
- if (simulation.Raycast(raycastStart, raycastEnd, out HitResult hitResult))
+ if (hitDistance >= MinimumCameraDistance)
+ {
+ // If the distance is larger than the minimum distance, place the camera at the hitpoint
+ thirdPersonPivot.Transform.Position.Z = -(hitDistance - 0.1f);
+ }
+ else
{
- // If we hit something along the way, calculate the distance
- var hitDistance = Vector3.Distance(raycastStart, hitResult.Point);
-
- if (hitDistance >= MinimumCameraDistance)
- {
- // If the distance is larger than the minimum distance, place the camera at the hitpoint
- thirdPersonPivot.Transform.Position.Z = -(hitDistance - 0.1f);
- }
- else
- {
- // If the distance is lower than the minimum distance, place the camera at first person pivot
- thirdPersonPivot.Transform.Position = new Vector3(0);
- }
+ // If the distance is lower than the minimum distance, place the camera at first person pivot
+ thirdPersonPivot.Transform.Position = new Vector3(0);
}
}
}
diff --git a/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/11_Navigation/NavigateCharacter.cs b/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/11_Navigation/NavigateCharacter.cs
index 60f463d3e4..71e3b22531 100644
--- a/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/11_Navigation/NavigateCharacter.cs
+++ b/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/11_Navigation/NavigateCharacter.cs
@@ -1,8 +1,6 @@
// 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 System;
using System.Collections.Generic;
-using CSharpIntermediate.Code.Extensions;
using Stride.Core.Mathematics;
using Stride.Engine;
using Stride.Graphics;
@@ -10,114 +8,113 @@
using Stride.Navigation;
using Stride.Physics;
-namespace CSharpIntermediate.Code
+namespace CSharpIntermediate.Code;
+
+public class NavigateCharacter : SyncScript
{
- public class NavigateCharacter : SyncScript
- {
- public Entity RegularCharacter;
- public Entity PathSphere;
- public float MovementSpeed;
+ public Entity RegularCharacter;
+ public Entity PathSphere;
+ public float MovementSpeed;
+
+ private NavigationComponent navigationComponent;
+ private List waypoints = new();
+ private List wayPointSpheres = new();
+ private int waypointIndex = 0;
- private NavigationComponent navigationComponent;
- private List waypoints = new();
- private List wayPointSpheres = new();
- private int waypointIndex = 0;
+ public override void Start()
+ {
+ navigationComponent = RegularCharacter.Get();
+ }
- public override void Start()
+ public override void Update()
+ {
+ DebugText.Print($"Left click to set Regular character target", new Int2(200, 20));
+ if (Input.IsMouseButtonPressed(MouseButton.Left))
{
- navigationComponent = RegularCharacter.Get();
+ CleanupExistingPath();
+ SetTarget();
}
- public override void Update()
- {
- DebugText.Print($"Left click to set Regular character target", new Int2(200, 20));
- if (Input.IsMouseButtonPressed(MouseButton.Left))
- {
- CleanupExistingPath();
- SetTarget();
- }
+ UpdateMovement();
+ }
- UpdateMovement();
+ private void UpdateMovement()
+ {
+ if (waypoints.Count == 0)
+ {
+ DebugText.Print($"No target", new Int2(200, 60));
+ return;
}
- private void UpdateMovement()
- {
- if (waypoints.Count == 0)
- {
- DebugText.Print($"No target", new Int2(200, 60));
- return;
- }
+ var deltaTime = (float)Game.UpdateTime.Elapsed.TotalSeconds;
+ var curPosition = RegularCharacter.Transform.WorldMatrix.TranslationVector;
+ var nextWaypointPosition = waypoints[waypointIndex];
+ var distanceToWaypoint = Vector3.Distance(curPosition, nextWaypointPosition);
- var deltaTime = (float)Game.UpdateTime.Elapsed.TotalSeconds;
- var curPosition = RegularCharacter.Transform.WorldMatrix.TranslationVector;
- var nextWaypointPosition = waypoints[waypointIndex];
- var distanceToWaypoint = Vector3.Distance(curPosition, nextWaypointPosition);
+ DebugText.Print($"Distance to waypoint {distanceToWaypoint.ToString("0.0")} ", new Int2(200, 60));
+
+ // When the distance between the character and the next waypoint is large enough, move closer to the waypoint
+ if (distanceToWaypoint > 0.1)
+ {
+ var direction = nextWaypointPosition - curPosition;
+ direction.Normalize();
+ direction *= MovementSpeed * deltaTime;
- DebugText.Print($"Distance to waypoint {distanceToWaypoint.ToString("0.0")} ", new Int2(200, 60));
-
- // When the distance between the character and the next waypoint is large enough, move closer to the waypoint
- if (distanceToWaypoint > 0.1)
+ RegularCharacter.Transform.Position += direction;
+ }
+ else
+ {
+ // If we are close enough to the waypoint, set the next waypoint or we are done and we do a final cleanup
+ if(waypointIndex+1 < waypoints.Count)
{
- var direction = nextWaypointPosition - curPosition;
- direction.Normalize();
- direction *= MovementSpeed * deltaTime;
-
- RegularCharacter.Transform.Position += direction;
+ waypointIndex++;
}
else
{
- // If we are close enough to the waypoint, set the next waypoint or we are done and we do a final cleanup
- if(waypointIndex+1 < waypoints.Count)
- {
- waypointIndex++;
- }
- else
- {
- CleanupExistingPath();
- }
+ CleanupExistingPath();
}
}
+ }
- private void SetTarget()
- {
- // Determine the 3d position in our scene, based on were our mouse is
- var backBuffer = GraphicsDevice.Presenter.BackBuffer;
- var viewport = new Viewport(0, 0, backBuffer.Width, backBuffer.Height);
- var camera = Entity.Get();
- var nearPosition = viewport.Unproject(new Vector3(Input.AbsoluteMousePosition, 0.0f), camera.ProjectionMatrix, camera.ViewMatrix, Matrix.Identity);
- var farPosition = viewport.Unproject(new Vector3(Input.AbsoluteMousePosition, 1.0f), camera.ProjectionMatrix, camera.ViewMatrix, Matrix.Identity);
+ private void SetTarget()
+ {
+ // Determine the 3d position in our scene, based on were our mouse is
+ var backBuffer = GraphicsDevice.Presenter.BackBuffer;
+ var viewport = new Viewport(0, 0, backBuffer.Width, backBuffer.Height);
+ var camera = Entity.Get();
+ var nearPosition = viewport.Unproject(new Vector3(Input.AbsoluteMousePosition, 0.0f), camera.ProjectionMatrix, camera.ViewMatrix, Matrix.Identity);
+ var farPosition = viewport.Unproject(new Vector3(Input.AbsoluteMousePosition, 1.0f), camera.ProjectionMatrix, camera.ViewMatrix, Matrix.Identity);
- var hitResult = this.GetSimulation().Raycast(nearPosition, farPosition);
+ var hitResult = this.GetSimulation().Raycast(nearPosition, farPosition);
- if (hitResult.Succeeded)
+ if (hitResult.Succeeded)
+ {
+ // Try to find the path to the hit point and store the path in the Waypoints variable
+ if (navigationComponent.TryFindPath(hitResult.Point, waypoints))
{
- // Try to find the path to the hit point and store the path in the Waypoints variable
- if (navigationComponent.TryFindPath(hitResult.Point, waypoints))
- {
- waypointIndex = 0;
+ waypointIndex = 0;
- // For each waypoint create a waypoint sphere and add it to the scene
- foreach (var waypoint in waypoints)
- {
- var waypointSphere = PathSphere.Clone();
- waypointSphere.Transform.Position = waypoint;
+ // For each waypoint create a waypoint sphere and add it to the scene
+ foreach (var waypoint in waypoints)
+ {
+ var waypointSphere = PathSphere.Clone();
+ waypointSphere.Transform.Position = waypoint;
- wayPointSpheres.Add(waypointSphere);
- Entity.Scene.Entities.Add(waypointSphere);
- }
+ wayPointSpheres.Add(waypointSphere);
+ Entity.Scene.Entities.Add(waypointSphere);
}
}
}
+ }
- // Cleans up the waypoints in the scene and the waypoint information in mememory
- private void CleanupExistingPath()
+ // Cleans up the waypoints in the scene and the waypoint information in mememory
+ private void CleanupExistingPath()
+ {
+ foreach (var waypointSphere in wayPointSpheres)
{
- foreach (var waypointSphere in wayPointSpheres)
- {
- Entity.Scene.Entities.Remove(waypointSphere);
- }
- wayPointSpheres.Clear();
- waypoints.Clear();
+ Entity.Scene.Entities.Remove(waypointSphere);
}
+ wayPointSpheres.Clear();
+ waypoints.Clear();
}
}
diff --git a/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/Utils/ObjectSpawner.cs b/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/Utils/ObjectSpawner.cs
index 764aa4f4f2..f147c14c6b 100644
--- a/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/Utils/ObjectSpawner.cs
+++ b/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/Utils/ObjectSpawner.cs
@@ -6,48 +6,47 @@
using Stride.Input;
using Stride.Physics;
-namespace CSharpIntermediate.Code
+namespace CSharpIntermediate.Code;
+
+public class ObjectSpawner : SyncScript
{
- public class ObjectSpawner : SyncScript
- {
- public Prefab ObjectToSpawn;
+ public Prefab ObjectToSpawn;
- private Entity prefabClone = null;
+ private Entity prefabClone = null;
- public override void Start() { }
+ public override void Start() { }
- public override void Update()
- {
+ public override void Update()
+ {
- DebugText.Print("Press S to spawn ball", new Int2(300, 180));
+ DebugText.Print("Press S to spawn ball", new Int2(300, 180));
- if (Input.IsKeyPressed(Keys.S))
+ if (Input.IsKeyPressed(Keys.S))
+ {
+ prefabClone ??= ObjectToSpawn.Instantiate()[0];
+ if (!Entity.Scene.Entities.Contains(prefabClone))
{
- prefabClone ??= ObjectToSpawn.Instantiate()[0];
- if (!Entity.Scene.Entities.Contains(prefabClone))
- {
- Entity.Scene.Entities.Add(prefabClone);
- }
-
- Entity.Transform.GetWorldTransformation(out Vector3 worldPos, out Quaternion rot, out Vector3 scale);
- prefabClone.Transform.Position = worldPos;
- prefabClone.Transform.UpdateWorldMatrix();
-
- var physicsComponent = prefabClone.Get();
- physicsComponent.Enabled = true;
- physicsComponent.LinearVelocity = new Vector3(0);
- physicsComponent.AngularVelocity = new Vector3(0);
- physicsComponent.UpdatePhysicsTransformation();
+ Entity.Scene.Entities.Add(prefabClone);
}
+
+ Entity.Transform.GetWorldTransformation(out Vector3 worldPos, out Quaternion rot, out Vector3 scale);
+ prefabClone.Transform.Position = worldPos;
+ prefabClone.Transform.UpdateWorldMatrix();
+
+ var physicsComponent = prefabClone.Get();
+ physicsComponent.Enabled = true;
+ physicsComponent.LinearVelocity = new Vector3(0);
+ physicsComponent.AngularVelocity = new Vector3(0);
+ physicsComponent.UpdatePhysicsTransformation();
}
+ }
- public override void Cancel()
+ public override void Cancel()
+ {
+ if (prefabClone != null)
{
- if (prefabClone != null)
- {
- Entity.Scene.Entities.Remove(prefabClone);
- prefabClone = null;
- }
+ Entity.Scene.Entities.Remove(prefabClone);
+ prefabClone = null;
}
}
}
diff --git a/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/Utils/OmniDirectionMovement.cs b/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/Utils/OmniDirectionMovement.cs
index 014855849f..78c47eb2e8 100644
--- a/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/Utils/OmniDirectionMovement.cs
+++ b/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/Utils/OmniDirectionMovement.cs
@@ -5,58 +5,57 @@
using Stride.Engine;
using Stride.Input;
-namespace CSharpIntermediate.Code
+namespace CSharpIntermediate.Code;
+
+public class OmniDirectionMovement : SyncScript
{
- public class OmniDirectionMovement : SyncScript
- {
- [DataMember(1)]
- public float MoveSpeed = 3.0f;
+ [DataMember(1)]
+ public float MoveSpeed = 3.0f;
+
+ [DataMember(2)]
+ public bool Vertical = true;
+
+ [DataMember(3)]
+ public bool Horizontal = false;
- [DataMember(2)]
- public bool Vertical = true;
+ [DataMember(4)]
+ public bool Forward = false;
- [DataMember(3)]
- public bool Horizontal = false;
+ public override void Start()
+ {
+ }
- [DataMember(4)]
- public bool Forward = false;
+ public override void Update()
+ {
+ var movement = new Vector3(0);
+ if (Input.IsKeyDown(Keys.Q) && Vertical)
+ {
+ movement.Y -= 1;
+ }
+ if (Input.IsKeyDown(Keys.E) && Vertical)
+ {
+ movement.Y += 1;
+ }
- public override void Start()
+ if (Input.IsKeyDown(Keys.W) && Forward)
+ {
+ movement.Z += 1;
+ }
+ if (Input.IsKeyDown(Keys.S) && Forward)
{
+ movement.Z -= 1;
}
- public override void Update()
+ if (Input.IsKeyDown(Keys.A) && Horizontal)
+ {
+ movement.X += 1;
+ }
+ if (Input.IsKeyDown(Keys.D) && Horizontal)
{
- var movement = new Vector3(0);
- if (Input.IsKeyDown(Keys.Q) && Vertical)
- {
- movement.Y -= 1;
- }
- if (Input.IsKeyDown(Keys.E) && Vertical)
- {
- movement.Y += 1;
- }
-
- if (Input.IsKeyDown(Keys.W) && Forward)
- {
- movement.Z += 1;
- }
- if (Input.IsKeyDown(Keys.S) && Forward)
- {
- movement.Z -= 1;
- }
-
- if (Input.IsKeyDown(Keys.A) && Horizontal)
- {
- movement.X += 1;
- }
- if (Input.IsKeyDown(Keys.D) && Horizontal)
- {
- movement.X -= 1;
- }
-
- var delta = (float)Game.UpdateTime.Elapsed.TotalSeconds;
- Entity.Transform.Position += movement * delta * MoveSpeed;
+ movement.X -= 1;
}
+
+ var delta = (float)Game.UpdateTime.Elapsed.TotalSeconds;
+ Entity.Transform.Position += movement * delta * MoveSpeed;
}
}
diff --git a/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/Utils/TutorialUI.cs b/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/Utils/TutorialUI.cs
index 0ca6dbd338..f19e094fc8 100644
--- a/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/Utils/TutorialUI.cs
+++ b/samples/Tutorials/CSharpIntermediate/CSharpIntermediate/CSharpIntermediate.Game/Utils/TutorialUI.cs
@@ -8,144 +8,143 @@
using Stride.UI.Events;
using Stride.UI.Panels;
-namespace CSharpIntermediate.Code
+namespace CSharpIntermediate.Code;
+
+public class TutorialUI : StartupScript
{
- public class TutorialUI : StartupScript
+ public bool ShowMenuOnSceneLoad = false;
+ private UIPage activePage;
+ private Button btnTutorialMenu;
+ private Canvas tutorialMenu;
+ private StackPanel buttonsStartUI;
+ private StackPanel buttonsCompletedUI;
+
+ public override void Start()
{
- public bool ShowMenuOnSceneLoad = false;
- private UIPage activePage;
- private Button btnTutorialMenu;
- private Canvas tutorialMenu;
- private StackPanel buttonsStartUI;
- private StackPanel buttonsCompletedUI;
-
- public override void Start()
- {
- activePage = Entity.Get().Page;
- tutorialMenu = activePage.RootElement.FindVisualChildOfType
$(MSBuildThisFileDirectory)..\GameMenu.sdpkg
diff --git a/samples/UI/UIElementLink/UIElementLink.Game/AnimationStart.cs b/samples/UI/UIElementLink/UIElementLink.Game/AnimationStart.cs
index 64454f0609..c3513efadd 100644
--- a/samples/UI/UIElementLink/UIElementLink.Game/AnimationStart.cs
+++ b/samples/UI/UIElementLink/UIElementLink.Game/AnimationStart.cs
@@ -1,56 +1,49 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Stride.Core;
-using Stride.Core.Mathematics;
+
using Stride.Animations;
-using Stride.Input;
+using Stride.Core;
using Stride.Engine;
-namespace UIElementLink
+namespace UIElementLink;
+
+[DataContract]
+public class PlayAnimation
+{
+ public AnimationClip Clip;
+ public AnimationBlendOperation BlendOperation = AnimationBlendOperation.LinearBlend;
+ public double StartTime = 0;
+}
+
+///
+/// Script which starts a few animations on its entity
+///
+public class AnimationStart : StartupScript
{
- [DataContract]
- public class PlayAnimation
- {
- public AnimationClip Clip;
- public AnimationBlendOperation BlendOperation = AnimationBlendOperation.LinearBlend;
- public double StartTime = 0;
- }
-
///
- /// Script which starts a few animations on its entity
+ /// Al list of animations to be loaded when the script starts
///
- public class AnimationStart : StartupScript
- {
- ///
- /// Al list of animations to be loaded when the script starts
- ///
- public readonly List Animations = new List();
+ public readonly List Animations = [];
- public override void Start()
- {
+ public override void Start()
+ {
var animComponent = Entity.GetOrCreate();
-
- if (animComponent != null)
- PlayAnimations(animComponent);
+
+ if (animComponent != null)
+ PlayAnimations(animComponent);
- // Destroy this script since it's no longer needed
- Entity.Remove(this);
- }
+ // Destroy this script since it's no longer needed
+ Entity.Remove(this);
+ }
- private void PlayAnimations(AnimationComponent animComponent)
+ private void PlayAnimations(AnimationComponent animComponent)
+ {
+ foreach (var anim in Animations)
{
- foreach (var anim in Animations)
- {
- if (anim.Clip != null)
- animComponent.Add(anim.Clip, anim.StartTime, anim.BlendOperation);
- }
-
- Animations.Clear();
+ if (anim.Clip != null)
+ animComponent.Add(anim.Clip, anim.StartTime, anim.BlendOperation);
}
+
+ Animations.Clear();
}
}
diff --git a/samples/UI/UIElementLink/UIElementLink.Game/SplashScript.cs b/samples/UI/UIElementLink/UIElementLink.Game/SplashScript.cs
index 9ec22a3aa4..66ea0cc338 100644
--- a/samples/UI/UIElementLink/UIElementLink.Game/SplashScript.cs
+++ b/samples/UI/UIElementLink/UIElementLink.Game/SplashScript.cs
@@ -1,7 +1,6 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
-using System;
-using Stride.Core.Extensions;
+
using Stride.Core.Mathematics;
using Stride.Core.Serialization;
using Stride.Engine;
@@ -11,82 +10,81 @@
using Stride.UI.Controls;
using Stride.UI.Panels;
-namespace UIElementLink
+namespace UIElementLink;
+
+public class SplashScript : UISceneBase
{
- public class SplashScript : UISceneBase
- {
- public SpriteSheet SplashScreenImages;
+ public SpriteSheet SplashScreenImages;
- public UrlReference NextScene;
+ public UrlReference NextScene;
- private Button followedButton;
+ private Button followedButton;
- private Vector2 centerPoint;
+ private Vector2 centerPoint;
- private void LoadNextScene()
- {
- if (NextScene?.IsEmpty ?? true)
- return;
+ private void LoadNextScene()
+ {
+ if (NextScene?.IsEmpty ?? true)
+ return;
- SceneSystem.SceneInstance.RootScene = Content.Load(NextScene);
- Cancel();
- }
+ SceneSystem.SceneInstance.RootScene = Content.Load(NextScene);
+ Cancel();
+ }
- protected override void LoadScene()
- {
- Game.Window.AllowUserResizing = false;
+ protected override void LoadScene()
+ {
+ Game.Window.AllowUserResizing = false;
- var backBufferSize = new Vector2(GraphicsDevice.Presenter.BackBuffer.Width, GraphicsDevice.Presenter.BackBuffer.Height);
- centerPoint = new Vector2(backBufferSize.X / 2, backBufferSize.Y / 2);
+ var backBufferSize = new Vector2(GraphicsDevice.Presenter.BackBuffer.Width, GraphicsDevice.Presenter.BackBuffer.Height);
+ centerPoint = new Vector2(backBufferSize.X / 2, backBufferSize.Y / 2);
- var longButton = (SpriteFromTexture) SplashScreenImages["button_long"];
- var longSize = new Vector3(SplashScreenImages["button_long"].SizeInPixels.X,
- SplashScreenImages["button_long"].SizeInPixels.Y, 0);
+ var longButton = (SpriteFromTexture) SplashScreenImages["button_long"];
+ var longSize = new Vector3(SplashScreenImages["button_long"].SizeInPixels.X,
+ SplashScreenImages["button_long"].SizeInPixels.Y, 0);
- // This button will be followed
- followedButton = new Button
- {
- PressedImage = longButton,
- NotPressedImage = longButton,
- MouseOverImage = longButton,
+ // This button will be followed
+ followedButton = new Button
+ {
+ PressedImage = longButton,
+ NotPressedImage = longButton,
+ MouseOverImage = longButton,
- Size = longSize,
+ Size = longSize,
- // This element will be followed, because we have specified the same name in the FollowingEntity's UI Element Link
- Name = "ElementName",
- };
+ // This element will be followed, because we have specified the same name in the FollowingEntity's UI Element Link
+ Name = "ElementName",
+ };
- // Load the next scene when the user clicks the button
- followedButton.Click += delegate { LoadNextScene(); };
+ // Load the next scene when the user clicks the button
+ followedButton.Click += delegate { LoadNextScene(); };
- // Corner buttons
- var boxButton = (SpriteFromTexture)SplashScreenImages["button_box"];
- var boxSize = new Vector3(SplashScreenImages["button_box"].SizeInPixels.X,
- SplashScreenImages["button_box"].SizeInPixels.Y, 0);
+ // Corner buttons
+ var boxButton = (SpriteFromTexture)SplashScreenImages["button_box"];
+ var boxSize = new Vector3(SplashScreenImages["button_box"].SizeInPixels.X,
+ SplashScreenImages["button_box"].SizeInPixels.Y, 0);
- var cornerTL = new Button { PressedImage = boxButton, NotPressedImage = boxButton, MouseOverImage = boxButton, Size = boxSize };
- cornerTL.SetCanvasAbsolutePosition(new Vector3(0, 0, 0));
+ var cornerTL = new Button { PressedImage = boxButton, NotPressedImage = boxButton, MouseOverImage = boxButton, Size = boxSize };
+ cornerTL.SetCanvasAbsolutePosition(new Vector3(0, 0, 0));
- var cornerTR = new Button { PressedImage = boxButton, NotPressedImage = boxButton, MouseOverImage = boxButton, Size = boxSize };
- cornerTR.SetCanvasAbsolutePosition(new Vector3(backBufferSize.X - boxSize.X, 0, 0));
+ var cornerTR = new Button { PressedImage = boxButton, NotPressedImage = boxButton, MouseOverImage = boxButton, Size = boxSize };
+ cornerTR.SetCanvasAbsolutePosition(new Vector3(backBufferSize.X - boxSize.X, 0, 0));
- var cornerBL = new Button { PressedImage = boxButton, NotPressedImage = boxButton, MouseOverImage = boxButton, Size = boxSize };
- cornerBL.SetCanvasAbsolutePosition(new Vector3(0, backBufferSize.Y - boxSize.Y, 0));
+ var cornerBL = new Button { PressedImage = boxButton, NotPressedImage = boxButton, MouseOverImage = boxButton, Size = boxSize };
+ cornerBL.SetCanvasAbsolutePosition(new Vector3(0, backBufferSize.Y - boxSize.Y, 0));
- var cornerBR = new Button { PressedImage = boxButton, NotPressedImage = boxButton, MouseOverImage = boxButton, Size = boxSize };
- cornerBR.SetCanvasAbsolutePosition(new Vector3(backBufferSize.X - boxSize.X, backBufferSize.Y - boxSize.Y, 0));
+ var cornerBR = new Button { PressedImage = boxButton, NotPressedImage = boxButton, MouseOverImage = boxButton, Size = boxSize };
+ cornerBR.SetCanvasAbsolutePosition(new Vector3(backBufferSize.X - boxSize.X, backBufferSize.Y - boxSize.Y, 0));
- var rootElement = new Canvas() { Children = { followedButton, cornerTL, cornerTR, cornerBL, cornerBR },
- MaximumWidth = backBufferSize.X, MaximumHeight = backBufferSize.Y };
+ var rootElement = new Canvas { Children = { followedButton, cornerTL, cornerTR, cornerBL, cornerBR },
+ MaximumWidth = backBufferSize.X, MaximumHeight = backBufferSize.Y };
- Entity.Get().Page = new UIPage { RootElement = rootElement };
- }
+ Entity.Get().Page = new UIPage { RootElement = rootElement };
+ }
- protected override void UpdateScene()
- {
- // Move the followed button around
- var distance = (float) Math.Sin(Game.UpdateTime.Total.TotalSeconds * 0.2f) * centerPoint.X * 0.75f;
- followedButton.SetCanvasAbsolutePosition(new Vector3(centerPoint.X + distance, centerPoint.Y, 0));
- }
+ protected override void UpdateScene()
+ {
+ // Move the followed button around
+ var distance = (float) Math.Sin(Game.UpdateTime.Total.TotalSeconds * 0.2f) * centerPoint.X * 0.75f;
+ followedButton.SetCanvasAbsolutePosition(new Vector3(centerPoint.X + distance, centerPoint.Y, 0));
}
}
diff --git a/samples/UI/UIElementLink/UIElementLink.Game/UIElementLink.Game.csproj b/samples/UI/UIElementLink/UIElementLink.Game/UIElementLink.Game.csproj
index c8eb51a644..0ce1992a43 100644
--- a/samples/UI/UIElementLink/UIElementLink.Game/UIElementLink.Game.csproj
+++ b/samples/UI/UIElementLink/UIElementLink.Game/UIElementLink.Game.csproj
@@ -2,6 +2,8 @@
net8.0
UIElementLink
+ enable
+ latest
diff --git a/samples/UI/UIElementLink/UIElementLink.Game/UISceneBase.cs b/samples/UI/UIElementLink/UIElementLink.Game/UISceneBase.cs
index a04930079a..44b6fc0af6 100644
--- a/samples/UI/UIElementLink/UIElementLink.Game/UISceneBase.cs
+++ b/samples/UI/UIElementLink/UIElementLink.Game/UISceneBase.cs
@@ -1,65 +1,62 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
-using System;
-using System.Collections.Generic;
-using Stride.Core;
+
using Stride.Core.Mathematics;
using Stride.Engine;
using Stride.Games;
-namespace UIElementLink
-{
- public abstract class UISceneBase : SyncScript
- {
- protected Game UIGame;
+namespace UIElementLink;
- protected bool IsRunning;
+public abstract class UISceneBase : SyncScript
+{
+ protected Game UIGame;
- protected bool SceneCreated;
+ protected bool IsRunning;
- public override void Start()
- {
- IsRunning = true;
+ protected bool SceneCreated;
- UIGame = (Game)Services.GetService();
+ public override void Start()
+ {
+ IsRunning = true;
- AdjustVirtualResolution(this, EventArgs.Empty);
- Game.Window.ClientSizeChanged += AdjustVirtualResolution;
+ UIGame = (Game)Services.GetService();
- CreateScene();
- }
+ AdjustVirtualResolution(this, EventArgs.Empty);
+ Game.Window.ClientSizeChanged += AdjustVirtualResolution;
- public override void Update()
- {
- UpdateScene();
- }
+ CreateScene();
+ }
- protected virtual void UpdateScene()
- {
- }
+ public override void Update()
+ {
+ UpdateScene();
+ }
- public override void Cancel()
- {
- Game.Window.ClientSizeChanged -= AdjustVirtualResolution;
+ protected virtual void UpdateScene()
+ {
+ }
- IsRunning = false;
- SceneCreated = false;
- }
+ public override void Cancel()
+ {
+ Game.Window.ClientSizeChanged -= AdjustVirtualResolution;
- private void AdjustVirtualResolution(object sender, EventArgs e)
- {
- var backBufferSize = new Vector2(GraphicsDevice.Presenter.BackBuffer.Width, GraphicsDevice.Presenter.BackBuffer.Height);
- Entity.Get().Resolution = new Vector3(backBufferSize, 1000);
- }
+ IsRunning = false;
+ SceneCreated = false;
+ }
- protected void CreateScene()
- {
- if (!SceneCreated)
- LoadScene();
+ private void AdjustVirtualResolution(object sender, EventArgs e)
+ {
+ var backBufferSize = new Vector2(GraphicsDevice.Presenter.BackBuffer.Width, GraphicsDevice.Presenter.BackBuffer.Height);
+ Entity.Get().Resolution = new Vector3(backBufferSize, 1000);
+ }
- SceneCreated = true;
- }
+ protected void CreateScene()
+ {
+ if (!SceneCreated)
+ LoadScene();
- protected abstract void LoadScene();
+ SceneCreated = true;
}
+
+ protected abstract void LoadScene();
}
diff --git a/samples/UI/UIElementLink/UIElementLink.Windows/UIElementLink.Windows.csproj b/samples/UI/UIElementLink/UIElementLink.Windows/UIElementLink.Windows.csproj
index f36a7c5c80..91c054940e 100644
--- a/samples/UI/UIElementLink/UIElementLink.Windows/UIElementLink.Windows.csproj
+++ b/samples/UI/UIElementLink/UIElementLink.Windows/UIElementLink.Windows.csproj
@@ -7,6 +7,8 @@
..\Bin\Windows\$(Configuration)\
false
STRIDE_PLATFORM_DESKTOP
+ enable
+ latest
$(MSBuildThisFileDirectory)..\UIElementLink.sdpkg
diff --git a/samples/UI/UIParticles/UIParticles.Game/SplashScript.cs b/samples/UI/UIParticles/UIParticles.Game/SplashScript.cs
index f7da3a9891..f043fd046c 100644
--- a/samples/UI/UIParticles/UIParticles.Game/SplashScript.cs
+++ b/samples/UI/UIParticles/UIParticles.Game/SplashScript.cs
@@ -1,9 +1,6 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading.Tasks;
+
using Stride.Core;
using Stride.Core.Mathematics;
using Stride.Engine;
@@ -15,365 +12,364 @@
using Stride.UI.Controls;
using Stride.UI.Panels;
-namespace UIParticles
+namespace UIParticles;
+
+public enum GameState
{
- public enum GameState
- {
- None,
- NewGame,
- EndGame
- }
+ None,
+ NewGame,
+ EndGame
+}
- public class SplashScript : UISceneBase
- {
- // Life gauge
- private RectangleF gaugeBarRegion;
- private Grid lifeBarGrid;
- private Sprite lifeBarGaugeImage;
+public class SplashScript : UISceneBase
+{
+ // Life gauge
+ private RectangleF gaugeBarRegion;
+ private Grid lifeBarGrid;
+ private Sprite lifeBarGaugeImage;
- public SpriteFont WesternFont;
- public SpriteSheet SplashScreenImages;
+ public SpriteFont WesternFont;
+ public SpriteSheet SplashScreenImages;
- public SpriteSheet ButtonsImages;
+ public SpriteSheet ButtonsImages;
- [Display("Hit Effect Prefab")]
- public Prefab Prefab;
+ [Display("Hit Effect Prefab")]
+ public Prefab Prefab;
- private const int virtualWidth = 600;
- private const int virtualHeight = 600;
+ private const int virtualWidth = 600;
+ private const int virtualHeight = 600;
- private GameState currentState = GameState.NewGame;
- private GameState desiredState = GameState.NewGame;
- private float fusePercentage = 1f;
+ private GameState currentState = GameState.NewGame;
+ private GameState desiredState = GameState.NewGame;
+ private float fusePercentage = 1f;
- protected override void LoadScene()
- {
- // Allow user to resize the window with the mouse.
- Game.Window.AllowUserResizing = true;
+ protected override void LoadScene()
+ {
+ // Allow user to resize the window with the mouse.
+ Game.Window.AllowUserResizing = true;
- // Create and initialize "Stride Samples" Text
- var strideSampleTextBlock = new ContentDecorator
+ // Create and initialize "Stride Samples" Text
+ var strideSampleTextBlock = new ContentDecorator
+ {
+ BackgroundImage = SpriteFromSheet.Create(SplashScreenImages, "stride_sample_text_bg"),
+ Content = new TextBlock
{
- BackgroundImage = SpriteFromSheet.Create(SplashScreenImages, "stride_sample_text_bg"),
- Content = new TextBlock
- {
- Font = WesternFont,
- TextSize = 60,
- Text = "Stride UI Particles",
- TextColor = Color.White,
- },
- Padding = new Thickness(35, 15, 35, 25),
- HorizontalAlignment = HorizontalAlignment.Center
- };
-
- strideSampleTextBlock.SetPanelZIndex(1);
-
-
- //*********************************
- // Confetti button
- var buttonImage = SpriteFromSheet.Create(SplashScreenImages, "button_long");
-
- var strideButtonConfetti = new Button
+ Font = WesternFont,
+ TextSize = 60,
+ Text = "Stride UI Particles",
+ TextColor = Color.White,
+ },
+ Padding = new Thickness(35, 15, 35, 25),
+ HorizontalAlignment = HorizontalAlignment.Center
+ };
+
+ strideSampleTextBlock.SetPanelZIndex(1);
+
+
+ //*********************************
+ // Confetti button
+ var buttonImage = SpriteFromSheet.Create(SplashScreenImages, "button_long");
+
+ var strideButtonConfetti = new Button
+ {
+ NotPressedImage = buttonImage,
+ PressedImage = buttonImage,
+ MouseOverImage = buttonImage,
+
+ Content = new TextBlock
{
- NotPressedImage = buttonImage,
- PressedImage = buttonImage,
- MouseOverImage = buttonImage,
-
- Content = new TextBlock
- {
- Font = WesternFont,
- TextColor = Color.White,
- Text = "Click here to start the game over",
- TextSize = 24
- },
-
- HorizontalAlignment = HorizontalAlignment.Right,
- Padding = new Thickness(90, 22, 25, 35),
+ Font = WesternFont,
+ TextColor = Color.White,
+ Text = "Click here to start the game over",
+ TextSize = 24
+ },
+
+ HorizontalAlignment = HorizontalAlignment.Right,
+ Padding = new Thickness(90, 22, 25, 35),
// BackgroundColor = Color.DarkOrchid
- };
+ };
- strideButtonConfetti.SetPanelZIndex(1);
- strideButtonConfetti.SetGridRow(1);
+ strideButtonConfetti.SetPanelZIndex(1);
+ strideButtonConfetti.SetGridRow(1);
- strideButtonConfetti.Click += delegate
- {
- fusePercentage = 1f;
- desiredState = GameState.NewGame;
- var effectOffset = new Vector3(45 - strideButtonConfetti.RenderSize.X / 2, -5, 0);
- SpawnParticles(strideButtonConfetti.WorldMatrix.TranslationVector + effectOffset, Prefab, 2f);
- };
- //*********************************
-
- //*********************************
- // Stars button
- var buttonStars = SpriteFromSheet.Create(SplashScreenImages, "button_short");
-
- var strideButtonStars = new Button
- {
- NotPressedImage = buttonStars,
- PressedImage = buttonStars,
- MouseOverImage = buttonStars,
-
- Content = new TextBlock
- {
- Font = WesternFont,
- TextColor = Color.White,
- Text = "Congratulations",
- TextSize = 24
- },
-
- HorizontalAlignment = HorizontalAlignment.Right,
- Padding = new Thickness(90, 22, 25, 35),
-// BackgroundColor = Color.DarkOrchid
+ strideButtonConfetti.Click += delegate
+ {
+ fusePercentage = 1f;
+ desiredState = GameState.NewGame;
+ var effectOffset = new Vector3(45 - strideButtonConfetti.RenderSize.X / 2, -5, 0);
+ SpawnParticles(strideButtonConfetti.WorldMatrix.TranslationVector + effectOffset, Prefab, 2f);
+ };
+ //*********************************
- };
+ //*********************************
+ // Stars button
+ var buttonStars = SpriteFromSheet.Create(SplashScreenImages, "button_short");
- strideButtonStars.SetPanelZIndex(1);
- strideButtonStars.SetGridRow(4);
+ var strideButtonStars = new Button
+ {
+ NotPressedImage = buttonStars,
+ PressedImage = buttonStars,
+ MouseOverImage = buttonStars,
- strideButtonStars.Click += delegate
+ Content = new TextBlock
{
- desiredState = GameState.EndGame;
- var effectOffset = new Vector3(45 - strideButtonStars.RenderSize.X / 2, -5, 0);
- SpawnParticles(strideButtonStars.WorldMatrix.TranslationVector + effectOffset, Prefab, 2f);
- };
- //*********************************
+ Font = WesternFont,
+ TextColor = Color.White,
+ Text = "Congratulations",
+ TextSize = 24
+ },
+
+ HorizontalAlignment = HorizontalAlignment.Right,
+ Padding = new Thickness(90, 22, 25, 35),
+// BackgroundColor = Color.DarkOrchid
- var bottomBar = CreateBottomBar();
- bottomBar.SetPanelZIndex(1);
- bottomBar.SetGridRow(6);
+ };
- var grid = new Grid
- {
- MaximumWidth = virtualWidth,
- MaximumHeight = virtualHeight,
- VerticalAlignment = VerticalAlignment.Center,
- HorizontalAlignment = HorizontalAlignment.Center,
- };
-
- grid.RowDefinitions.Add(new StripDefinition(StripType.Auto)); // 0
- grid.RowDefinitions.Add(new StripDefinition(StripType.Auto)); // 1
- grid.RowDefinitions.Add(new StripDefinition(StripType.Auto)); // 2
- grid.RowDefinitions.Add(new StripDefinition(StripType.Auto)); // 3
- grid.RowDefinitions.Add(new StripDefinition(StripType.Auto)); // 4
- grid.RowDefinitions.Add(new StripDefinition(StripType.Fixed, 100)); // 5
- grid.RowDefinitions.Add(new StripDefinition(StripType.Fixed, 50)); // 5
- grid.ColumnDefinitions.Add(new StripDefinition());
- grid.LayerDefinitions.Add(new StripDefinition());
-
- grid.Children.Add(strideSampleTextBlock);
- grid.Children.Add(strideButtonConfetti);
- grid.Children.Add(strideButtonStars);
- grid.Children.Add(bottomBar);
-
- // Add the background
- var background = new ImageElement { Source = SpriteFromSheet.Create(SplashScreenImages, "background_uiimage"), StretchType = StretchType.Fill };
- background.SetPanelZIndex(-1);
-
- Entity.Get().Page = new UIPage { RootElement = new UniformGrid { Children = { background, grid } } };
- }
+ strideButtonStars.SetPanelZIndex(1);
+ strideButtonStars.SetGridRow(4);
- protected Vector3 ToOrthographicCamera(Vector3 worldPosition)
+ strideButtonStars.Click += delegate
{
- // Use a screen resolution of the same size as the one we set in the game settings
- // Y axis is reveres, because in UI Y is down, but in our scene Y is up
- var screenResolution = new Vector3(virtualWidth, -virtualHeight, 1);
- return worldPosition / screenResolution;
- }
+ desiredState = GameState.EndGame;
+ var effectOffset = new Vector3(45 - strideButtonStars.RenderSize.X / 2, -5, 0);
+ SpawnParticles(strideButtonStars.WorldMatrix.TranslationVector + effectOffset, Prefab, 2f);
+ };
+ //*********************************
+
+ var bottomBar = CreateBottomBar();
+ bottomBar.SetPanelZIndex(1);
+ bottomBar.SetGridRow(6);
- protected void SpawnParticles(Vector3 uiPosition, Prefab hitEffectPrefab, float time)
+ var grid = new Grid
{
- if (hitEffectPrefab == null)
- return;
+ MaximumWidth = virtualWidth,
+ MaximumHeight = virtualHeight,
+ VerticalAlignment = VerticalAlignment.Center,
+ HorizontalAlignment = HorizontalAlignment.Center,
+ };
+
+ grid.RowDefinitions.Add(new StripDefinition(StripType.Auto)); // 0
+ grid.RowDefinitions.Add(new StripDefinition(StripType.Auto)); // 1
+ grid.RowDefinitions.Add(new StripDefinition(StripType.Auto)); // 2
+ grid.RowDefinitions.Add(new StripDefinition(StripType.Auto)); // 3
+ grid.RowDefinitions.Add(new StripDefinition(StripType.Auto)); // 4
+ grid.RowDefinitions.Add(new StripDefinition(StripType.Fixed, 100)); // 5
+ grid.RowDefinitions.Add(new StripDefinition(StripType.Fixed, 50)); // 5
+ grid.ColumnDefinitions.Add(new StripDefinition());
+ grid.LayerDefinitions.Add(new StripDefinition());
+
+ grid.Children.Add(strideSampleTextBlock);
+ grid.Children.Add(strideButtonConfetti);
+ grid.Children.Add(strideButtonStars);
+ grid.Children.Add(bottomBar);
+
+ // Add the background
+ var background = new ImageElement { Source = SpriteFromSheet.Create(SplashScreenImages, "background_uiimage"), StretchType = StretchType.Fill };
+ background.SetPanelZIndex(-1);
+
+ Entity.Get().Page = new UIPage { RootElement = new UniformGrid { Children = { background, grid } } };
+ }
- Func spawnTask = async () =>
- {
- var spawnedEntities = new List();
+ protected Vector3 ToOrthographicCamera(Vector3 worldPosition)
+ {
+ // Use a screen resolution of the same size as the one we set in the game settings
+ // Y axis is reveres, because in UI Y is down, but in our scene Y is up
+ var screenResolution = new Vector3(virtualWidth, -virtualHeight, 1);
+ return worldPosition / screenResolution;
+ }
- // Add
- foreach (var prefabEntity in hitEffectPrefab.Entities)
- {
- var clonedEntity = EntityCloner.Clone(prefabEntity);
+ protected void SpawnParticles(Vector3 uiPosition, Prefab hitEffectPrefab, float time)
+ {
+ if (hitEffectPrefab == null)
+ return;
- var component = clonedEntity.Get();
- if (component != null)
- component.ParticleSystem.ResetSimulation();
+ Func spawnTask = async () =>
+ {
+ var spawnedEntities = new List();
- clonedEntity.Transform.Position = ToOrthographicCamera(uiPosition);
+ // Add
+ foreach (var prefabEntity in hitEffectPrefab.Entities)
+ {
+ var clonedEntity = EntityCloner.Clone(prefabEntity);
- SceneSystem.SceneInstance.RootScene.Entities.Add(clonedEntity);
+ var component = clonedEntity.Get();
+ if (component != null)
+ component.ParticleSystem.ResetSimulation();
- spawnedEntities.Add(clonedEntity);
- }
+ clonedEntity.Transform.Position = ToOrthographicCamera(uiPosition);
- // Countdown
- var secondsCountdown = time;
- while (secondsCountdown > 0f)
- {
- await Script.NextFrame();
- secondsCountdown -= (float)Game.UpdateTime.Elapsed.TotalSeconds;
- }
+ SceneSystem.SceneInstance.RootScene.Entities.Add(clonedEntity);
- // Remove
- foreach (var clonedEntity in spawnedEntities)
- {
- SceneSystem.SceneInstance.RootScene.Entities.Remove(clonedEntity);
+ spawnedEntities.Add(clonedEntity);
+ }
- var component = clonedEntity.Get();
- if (component != null)
- component.ParticleSystem.Dispose();
- clonedEntity.Dispose();
- }
+ // Countdown
+ var secondsCountdown = time;
+ while (secondsCountdown > 0f)
+ {
+ await Script.NextFrame();
+ secondsCountdown -= (float)Game.UpdateTime.Elapsed.TotalSeconds;
+ }
- spawnedEntities.Clear();
- };
+ // Remove
+ foreach (var clonedEntity in spawnedEntities)
+ {
+ SceneSystem.SceneInstance.RootScene.Entities.Remove(clonedEntity);
- Script.AddTask(spawnTask);
- }
+ var component = clonedEntity.Get();
+ if (component != null)
+ component.ParticleSystem.Dispose();
+ clonedEntity.Dispose();
+ }
+ spawnedEntities.Clear();
+ };
- protected override void UpdateScene()
- {
- // Update camera
- // The orthographic camera is centered at the center of the virtual grid and assumes positions in the
- // range (-0.5, 0.5) - (0.5, -0.5) to map to the virtual grid (0, 0) - (virtualWidth, virtualHeight)
- var cameraEntity = SceneSystem.SceneInstance.RootScene.Entities.FirstOrDefault(item => item.Name.Equals("UIParticlesCamera"));
- if (cameraEntity == null)
- return;
+ Script.AddTask(spawnTask);
+ }
- var windowWidth = GraphicsDevice.Presenter.BackBuffer.Width;
- var windowHeight = GraphicsDevice.Presenter.BackBuffer.Height;
- cameraEntity.Get().AspectRatio = ((float) windowWidth / (float) windowHeight);
- cameraEntity.Get().OrthographicSize = ((float)windowHeight / virtualHeight);
+ protected override void UpdateScene()
+ {
+ // Update camera
+ // The orthographic camera is centered at the center of the virtual grid and assumes positions in the
+ // range (-0.5, 0.5) - (0.5, -0.5) to map to the virtual grid (0, 0) - (virtualWidth, virtualHeight)
+ var cameraEntity = SceneSystem.SceneInstance.RootScene.Entities.FirstOrDefault(item => item.Name.Equals("UIParticlesCamera"));
+ if (cameraEntity == null)
+ return;
- switch (currentState)
- {
- case GameState.NewGame: NewGameState();
- break;
+ var windowWidth = GraphicsDevice.Presenter.BackBuffer.Width;
+ var windowHeight = GraphicsDevice.Presenter.BackBuffer.Height;
- case GameState.EndGame: EndGameState();
- break;
- }
+ cameraEntity.Get().AspectRatio = (windowWidth / (float) windowHeight);
+ cameraEntity.Get().OrthographicSize = ((float)windowHeight / virtualHeight);
- desiredState = GameState.None;
- }
-
- private void EnterNewGame()
+ switch (currentState)
{
- currentState = GameState.NewGame;
- fusePercentage = 1f;
+ case GameState.NewGame: NewGameState();
+ break;
- var particleFire = SceneSystem.SceneInstance.RootScene.Entities.FirstOrDefault(item => item.Name.Equals("Fire"));
- if (particleFire != null)
- {
- particleFire.Transform.Position = new Vector3(0, 0.65f, 0);
- particleFire.Get().ParticleSystem.Play();
- }
+ case GameState.EndGame: EndGameState();
+ break;
+ }
- var particleConfetti = SceneSystem.SceneInstance.RootScene.Entities.FirstOrDefault(item => item.Name.Equals("ConfettiBig"));
- if (particleConfetti != null)
- {
- particleConfetti.Transform.Position = new Vector3(10, 0, 0);
- particleConfetti.Get().ParticleSystem.Stop();
- }
+ desiredState = GameState.None;
+ }
+
+ private void EnterNewGame()
+ {
+ currentState = GameState.NewGame;
+ fusePercentage = 1f;
- DrawFuse();
+ var particleFire = SceneSystem.SceneInstance.RootScene.Entities.FirstOrDefault(item => item.Name.Equals("Fire"));
+ if (particleFire != null)
+ {
+ particleFire.Transform.Position = new Vector3(0, 0.65f, 0);
+ particleFire.Get().ParticleSystem.Play();
}
- private void DrawFuse()
+ var particleConfetti = SceneSystem.SceneInstance.RootScene.Entities.FirstOrDefault(item => item.Name.Equals("ConfettiBig"));
+ if (particleConfetti != null)
{
- fusePercentage = Math.Min(1f, fusePercentage - (float)Game.UpdateTime.Elapsed.TotalSeconds * 0.04f);
+ particleConfetti.Transform.Position = new Vector3(10, 0, 0);
+ particleConfetti.Get().ParticleSystem.Stop();
+ }
- var gaugeCurrentRegion = lifeBarGaugeImage.Region;
- gaugeCurrentRegion.Width = Math.Max(1, fusePercentage * gaugeBarRegion.Width);
- lifeBarGaugeImage.Region = gaugeCurrentRegion;
+ DrawFuse();
+ }
- lifeBarGrid.ColumnDefinitions[1].SizeValue = gaugeCurrentRegion.Width / gaugeBarRegion.Width;
- lifeBarGrid.ColumnDefinitions[2].SizeValue = 1 - lifeBarGrid.ColumnDefinitions[1].SizeValue;
+ private void DrawFuse()
+ {
+ fusePercentage = Math.Min(1f, fusePercentage - (float)Game.UpdateTime.Elapsed.TotalSeconds * 0.04f);
- var particleFire = SceneSystem.SceneInstance.RootScene.Entities.FirstOrDefault(item => item.Name.Equals("Fire"));
- if (particleFire == null)
- return;
+ var gaugeCurrentRegion = lifeBarGaugeImage.Region;
+ gaugeCurrentRegion.Width = Math.Max(1, fusePercentage * gaugeBarRegion.Width);
+ lifeBarGaugeImage.Region = gaugeCurrentRegion;
- var firePos = lifeBarGrid.WorldMatrix.TranslationVector - new Vector3(lifeBarGrid.ActualWidth/2 - lifeBarGrid.ColumnDefinitions[0].ActualSize - lifeBarGrid.ColumnDefinitions[1].ActualSize + 5, 10, 0);
- particleFire.Transform.Position = ToOrthographicCamera(firePos);
- }
+ lifeBarGrid.ColumnDefinitions[1].SizeValue = gaugeCurrentRegion.Width / gaugeBarRegion.Width;
+ lifeBarGrid.ColumnDefinitions[2].SizeValue = 1 - lifeBarGrid.ColumnDefinitions[1].SizeValue;
- private void EnterEndGame()
- {
- currentState = GameState.EndGame;
- fusePercentage = 0;
- DrawFuse();
+ var particleFire = SceneSystem.SceneInstance.RootScene.Entities.FirstOrDefault(item => item.Name.Equals("Fire"));
+ if (particleFire == null)
+ return;
- var particleFire = SceneSystem.SceneInstance.RootScene.Entities.FirstOrDefault(item => item.Name.Equals("Fire"));
- if (particleFire != null)
- {
- particleFire.Transform.Position = new Vector3(10, 0, 0);
- particleFire.Get().ParticleSystem.Stop();
- }
+ var firePos = lifeBarGrid.WorldMatrix.TranslationVector - new Vector3(lifeBarGrid.ActualWidth/2 - lifeBarGrid.ColumnDefinitions[0].ActualSize - lifeBarGrid.ColumnDefinitions[1].ActualSize + 5, 10, 0);
+ particleFire.Transform.Position = ToOrthographicCamera(firePos);
+ }
- var particleConfetti = SceneSystem.SceneInstance.RootScene.Entities.FirstOrDefault(item => item.Name.Equals("ConfettiBig"));
- if (particleConfetti != null)
- {
- particleConfetti.Transform.Position = new Vector3(0, 0.5f, 0);
- particleConfetti.Get().ParticleSystem.Play();
- }
- }
+ private void EnterEndGame()
+ {
+ currentState = GameState.EndGame;
+ fusePercentage = 0;
+ DrawFuse();
- private void NewGameState()
+ var particleFire = SceneSystem.SceneInstance.RootScene.Entities.FirstOrDefault(item => item.Name.Equals("Fire"));
+ if (particleFire != null)
{
- fusePercentage = Math.Min(1f, fusePercentage - (float)Game.UpdateTime.Elapsed.TotalSeconds * 0.03f);
- DrawFuse();
-
- if (desiredState == GameState.EndGame || fusePercentage <= 0f)
- EnterEndGame();
+ particleFire.Transform.Position = new Vector3(10, 0, 0);
+ particleFire.Get().ParticleSystem.Stop();
}
- private void EndGameState()
+ var particleConfetti = SceneSystem.SceneInstance.RootScene.Entities.FirstOrDefault(item => item.Name.Equals("ConfettiBig"));
+ if (particleConfetti != null)
{
- if (desiredState == GameState.NewGame)
- EnterNewGame();
+ particleConfetti.Transform.Position = new Vector3(0, 0.5f, 0);
+ particleConfetti.Get().ParticleSystem.Play();
}
+ }
- private UIElement CreateBottomBar()
- {
- // Create Life bar
- lifeBarGaugeImage = ButtonsImages["rope_small"];
- gaugeBarRegion = lifeBarGaugeImage.Region;
+ private void NewGameState()
+ {
+ fusePercentage = Math.Min(1f, fusePercentage - (float)Game.UpdateTime.Elapsed.TotalSeconds * 0.03f);
+ DrawFuse();
- var lifebarGauge = new ImageElement
- {
- Name = "LifeBarBackground",
- Source = SpriteFromSheet.Create(ButtonsImages, "rope_small"),
- StretchType = StretchType.Fill,
- };
- lifebarGauge.SetGridColumn(1);
-
- lifeBarGrid = new Grid();
- lifeBarGrid.Children.Add(lifebarGauge);
- lifeBarGrid.ColumnDefinitions.Add(new StripDefinition(StripType.Fixed, 8));
- lifeBarGrid.ColumnDefinitions.Add(new StripDefinition(StripType.Star, 0));
- lifeBarGrid.ColumnDefinitions.Add(new StripDefinition(StripType.Star, 100));
- lifeBarGrid.ColumnDefinitions.Add(new StripDefinition(StripType.Fixed, 8));
- lifeBarGrid.RowDefinitions.Add(new StripDefinition());
- lifeBarGrid.LayerDefinitions.Add(new StripDefinition());
- lifeBarGrid.SetCanvasRelativePosition(new Vector3(0f, 0.185f, 0f));
- lifeBarGrid.SetCanvasRelativeSize(new Vector3(1f, 1f, 1f));
- lifeBarGrid.SetPanelZIndex(-1);
-
-
- // the main grid of the top bar
- var mainLayer = new Canvas
- {
- VerticalAlignment = VerticalAlignment.Top,
- MaximumHeight = 10
- };
+ if (desiredState == GameState.EndGame || fusePercentage <= 0f)
+ EnterEndGame();
+ }
- mainLayer.Children.Add(lifeBarGrid);
+ private void EndGameState()
+ {
+ if (desiredState == GameState.NewGame)
+ EnterNewGame();
+ }
- return mainLayer;
- }
+ private UIElement CreateBottomBar()
+ {
+ // Create Life bar
+ lifeBarGaugeImage = ButtonsImages["rope_small"];
+ gaugeBarRegion = lifeBarGaugeImage.Region;
+ var lifebarGauge = new ImageElement
+ {
+ Name = "LifeBarBackground",
+ Source = SpriteFromSheet.Create(ButtonsImages, "rope_small"),
+ StretchType = StretchType.Fill,
+ };
+ lifebarGauge.SetGridColumn(1);
+
+ lifeBarGrid = new Grid();
+ lifeBarGrid.Children.Add(lifebarGauge);
+ lifeBarGrid.ColumnDefinitions.Add(new StripDefinition(StripType.Fixed, 8));
+ lifeBarGrid.ColumnDefinitions.Add(new StripDefinition(StripType.Star, 0));
+ lifeBarGrid.ColumnDefinitions.Add(new StripDefinition(StripType.Star, 100));
+ lifeBarGrid.ColumnDefinitions.Add(new StripDefinition(StripType.Fixed, 8));
+ lifeBarGrid.RowDefinitions.Add(new StripDefinition());
+ lifeBarGrid.LayerDefinitions.Add(new StripDefinition());
+ lifeBarGrid.SetCanvasRelativePosition(new Vector3(0f, 0.185f, 0f));
+ lifeBarGrid.SetCanvasRelativeSize(new Vector3(1f, 1f, 1f));
+ lifeBarGrid.SetPanelZIndex(-1);
+
+
+ // the main grid of the top bar
+ var mainLayer = new Canvas
+ {
+ VerticalAlignment = VerticalAlignment.Top,
+ MaximumHeight = 10
+ };
+
+ mainLayer.Children.Add(lifeBarGrid);
+
+ return mainLayer;
}
+
}
diff --git a/samples/UI/UIParticles/UIParticles.Game/UIParticles.Game.csproj b/samples/UI/UIParticles/UIParticles.Game/UIParticles.Game.csproj
index f448a4f2a1..bdca2f75ef 100644
--- a/samples/UI/UIParticles/UIParticles.Game/UIParticles.Game.csproj
+++ b/samples/UI/UIParticles/UIParticles.Game/UIParticles.Game.csproj
@@ -2,6 +2,8 @@
net8.0
UIParticles
+ enable
+ latest
diff --git a/samples/UI/UIParticles/UIParticles.Game/UISceneBase.cs b/samples/UI/UIParticles/UIParticles.Game/UISceneBase.cs
index f5a3029ff1..906864cb5c 100644
--- a/samples/UI/UIParticles/UIParticles.Game/UISceneBase.cs
+++ b/samples/UI/UIParticles/UIParticles.Game/UISceneBase.cs
@@ -1,65 +1,62 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
-using System;
-using System.Collections.Generic;
-using Stride.Core;
+
using Stride.Core.Mathematics;
using Stride.Engine;
using Stride.Games;
-namespace UIParticles
-{
- public abstract class UISceneBase : SyncScript
- {
- protected Game UIGame;
+namespace UIParticles;
- protected bool IsRunning;
+public abstract class UISceneBase : SyncScript
+{
+ protected Game UIGame;
- protected bool SceneCreated;
+ protected bool IsRunning;
- public override void Start()
- {
- IsRunning = true;
+ protected bool SceneCreated;
- UIGame = (Game)Services.GetService();
+ public override void Start()
+ {
+ IsRunning = true;
- AdjustVirtualResolution(this, EventArgs.Empty);
- Game.Window.ClientSizeChanged += AdjustVirtualResolution;
+ UIGame = (Game)Services.GetService();
- CreateScene();
- }
+ AdjustVirtualResolution(this, EventArgs.Empty);
+ Game.Window.ClientSizeChanged += AdjustVirtualResolution;
- public override void Update()
- {
- UpdateScene();
- }
+ CreateScene();
+ }
- protected virtual void UpdateScene()
- {
- }
+ public override void Update()
+ {
+ UpdateScene();
+ }
- public override void Cancel()
- {
- Game.Window.ClientSizeChanged -= AdjustVirtualResolution;
+ protected virtual void UpdateScene()
+ {
+ }
- IsRunning = false;
- SceneCreated = false;
- }
+ public override void Cancel()
+ {
+ Game.Window.ClientSizeChanged -= AdjustVirtualResolution;
- private void AdjustVirtualResolution(object sender, EventArgs e)
- {
- var backBufferSize = new Vector2(GraphicsDevice.Presenter.BackBuffer.Width, GraphicsDevice.Presenter.BackBuffer.Height);
- Entity.Get().Resolution = new Vector3(backBufferSize, 1000);
- }
+ IsRunning = false;
+ SceneCreated = false;
+ }
- protected void CreateScene()
- {
- if (!SceneCreated)
- LoadScene();
+ private void AdjustVirtualResolution(object sender, EventArgs e)
+ {
+ var backBufferSize = new Vector2(GraphicsDevice.Presenter.BackBuffer.Width, GraphicsDevice.Presenter.BackBuffer.Height);
+ Entity.Get().Resolution = new Vector3(backBufferSize, 1000);
+ }
- SceneCreated = true;
- }
+ protected void CreateScene()
+ {
+ if (!SceneCreated)
+ LoadScene();
- protected abstract void LoadScene();
+ SceneCreated = true;
}
+
+ protected abstract void LoadScene();
}
diff --git a/samples/UI/UIParticles/UIParticles.Windows/UIParticles.Windows.csproj b/samples/UI/UIParticles/UIParticles.Windows/UIParticles.Windows.csproj
index 91a2b30ac9..d357afe923 100644
--- a/samples/UI/UIParticles/UIParticles.Windows/UIParticles.Windows.csproj
+++ b/samples/UI/UIParticles/UIParticles.Windows/UIParticles.Windows.csproj
@@ -7,6 +7,8 @@
..\Bin\Windows\$(Configuration)\
false
STRIDE_PLATFORM_DESKTOP
+ enable
+ latest
$(MSBuildThisFileDirectory)..\UIParticles.sdpkg