diff --git a/en/manual/game-studio/index.md b/en/manual/game-studio/index.md
index c1d07fc5b..b7b61f617 100644
--- a/en/manual/game-studio/index.md
+++ b/en/manual/game-studio/index.md
@@ -15,7 +15,7 @@ Game Studio is also integrated with your Visual Studio projects, so you can seam
![Game Studio](../get-started/media/game-studio-main-interface.png)
-The **asset editor** (A) is used to edit assets and scenes. Some asset types, such as scenes [scenes](create-a-scene.md), have dedicated editors where you can make complex changes to the asset. To open a dedicated editor (when available), double-click the asset or right-click it and select **Edit asset**.
+The **asset editor** (A) is used to edit assets and scenes. Some asset types, such as [scenes](create-a-scene.md), have dedicated editors where you can make complex changes to the asset. To open a dedicated editor (when available), double-click the asset or right-click it and select **Edit asset**.
The **Property Grid** (B) displays the properties of the asset or entity you select. You can edit the properties here.
@@ -47,4 +47,4 @@ You can show and hide different parts of the Game Studio in the View menu. You c
* [Edit prefabs](prefabs/edit-prefabs.md)
* [Nested prefabs](prefabs/nested-prefabs.md)
* [Override prefab properties](prefabs/override-prefab-properties.md)
-* [World units](world-units.md)
\ No newline at end of file
+* [World units](world-units.md)
diff --git a/en/manual/index.md b/en/manual/index.md
index b07be0fc2..9e061ab13 100644
--- a/en/manual/index.md
+++ b/en/manual/index.md
@@ -10,6 +10,7 @@ These pages contain information about how to use Stride, an open-source C# game
## Latest documentation
### Recent updates
+- New [Scripts - Gizmos](scripts/gizmos.md) - Description and example of the Flexible Processing system
- New [ECS - Flexible Processing](engine/entity-component-system/flexible-processing.md) - Description and example of the Flexible Processing system
- Updated [Linux - Setup and requirements](platforms/linux/setup-and-requirements.md) - Fedora OS option added
- New [Scripts - Serialization](scripts/serialization.md) - Explanation of serialization
diff --git a/en/manual/scripts/gizmos.md b/en/manual/scripts/gizmos.md
new file mode 100644
index 000000000..be60d4c8a
--- /dev/null
+++ b/en/manual/scripts/gizmos.md
@@ -0,0 +1,172 @@
+# Gizmos
+
+Intermediate
+Programmer
+
+**Gizmos** are a tool which you can implement over your components to provide visual assistance for designers when manipulating component values.
+
+Here's an exhaustive example one could implement:
+```cs
+using Stride.Core;
+using Stride.Core.Mathematics;
+using Stride.Engine;
+using Stride.Engine.Gizmos;
+using Stride.Graphics;
+using Stride.Graphics.GeometricPrimitives;
+using Stride.Rendering;
+using Stride.Rendering.Materials;
+using Stride.Rendering.Materials.ComputeColors;
+
+// We will be implementing a Gizmo for the following class
+public class MyScript : StartupScript
+{
+
+}
+
+// This attribute specifies to the engine that the following gizmo class is bound to 'MyScript',
+// the game studio will pick that up and spawn an instance of that class for each 'MyScript' in the scene
+[GizmoComponent(typeof(MyScript), isMainGizmo:false/*When true, only the first gizmo on an entity with true is visible, false means that it is always visible*/)]
+public class Gizmo : IEntityGizmo
+{
+ private bool _selected, _enabled;
+ private MyScript _component;
+ private ModelComponent _model;
+ private Material _material, _materialOnSelect;
+
+ // This property is set based on whether the gizmo is globally turned on or off in the editor's view settings
+ public bool IsEnabled
+ {
+ get
+ {
+ return _enabled;
+ }
+ set
+ {
+ _enabled = value;
+ _model.Enabled = _enabled;
+ }
+ }
+
+ // The size slider value in the view settings pane
+ public float SizeFactor { get; set; }
+
+ // The editor will set this property whenever the entity the component is on is selected
+ public bool IsSelected
+ {
+ get
+ {
+ return _selected;
+ }
+ set
+ {
+ _selected = value;
+ _model.Materials[0] = _selected ? _materialOnSelect : _material;
+ // The logic below shows gizmos for all components when they are on in the gizmo settings, and when off, only shows the one from the selected entity
+ // Removing the line hides gizmos even when selected when the gizmo settings is off
+ _model.Enabled = _selected || _enabled;
+ }
+ }
+
+ // This constructor is called by the editor,
+ // A gizmo class MUST contain a constructor with a single parameter of the component's type
+ public Gizmo(MyScript component)
+ {
+ _component = component;
+ }
+
+ public bool HandlesComponentId(OpaqueComponentId pickedComponentId, out Entity? selection)
+ {
+ // This function is called when scene picking/mouse clicking in the scene on a gizmo
+ // The engine calls this function on each gizmos, gizmos in term notify the engine
+ // when the given component comes from them by returning true, and provide the editor with the corresponding entity this gizmo represents
+ if (pickedComponentId.Match(_model))
+ {
+ selection = _component.Entity;
+ return true;
+ }
+ selection = null;
+ return false;
+ }
+
+ public void Initialize(IServiceRegistry services, Scene editorScene)
+ {
+ // As part of initialization, we create a model in the editor scene to visualize the gizmo
+ var graphicsDevice = services.GetSafeServiceAs().GraphicsDevice;
+
+ // In our case we'll just rely on the GeometricPrimitive API to create a sphere for us
+ // You don't have to create one right away, you can delay it until the component is in the appropriate state
+ // You can also dynamically create and update one in the Update() function further below
+ var sphere = GeometricPrimitive.Sphere.New(graphicsDevice);
+
+ var vertexBuffer = sphere.VertexBuffer;
+ var indexBuffer = sphere.IndexBuffer;
+ var vertexBufferBinding = new VertexBufferBinding(vertexBuffer, new VertexPositionNormalTexture().GetLayout(), vertexBuffer.ElementCount);
+ var indexBufferBinding = new IndexBufferBinding(indexBuffer, sphere.IsIndex32Bits, indexBuffer.ElementCount);
+
+ _material = Material.New(graphicsDevice, new MaterialDescriptor
+ {
+ Attributes =
+ {
+ Emissive = new MaterialEmissiveMapFeature(new ComputeColor(new Color4(0.25f,0.75f,0.25f,0.05f).ToColorSpace(graphicsDevice.ColorSpace))) { UseAlpha = true },
+ Transparency = new MaterialTransparencyBlendFeature()
+ },
+ });
+ _materialOnSelect = Material.New(graphicsDevice, new MaterialDescriptor
+ {
+ Attributes =
+ {
+ Emissive = new MaterialEmissiveMapFeature(new ComputeColor(new Color4(0.25f,0.75f,0.25f,0.5f).ToColorSpace(graphicsDevice.ColorSpace))) { UseAlpha = true },
+ Transparency = new MaterialTransparencyBlendFeature()
+ },
+ });
+
+ _model = new ModelComponent
+ {
+ Model = new Model
+ {
+ (_selected ? _materialOnSelect : _material),
+ new Mesh
+ {
+ Draw = new MeshDraw
+ {
+ StartLocation = 0,
+ // You can swap to LineList or LineStrip to show the model in wireframe mode, you'll have to adapt your index buffer to that new type though
+ PrimitiveType = PrimitiveType.TriangleList,
+ VertexBuffers = new[] { vertexBufferBinding },
+ IndexBuffer = indexBufferBinding,
+ DrawCount = indexBuffer.ElementCount,
+ }
+ }
+ },
+ RenderGroup = IEntityGizmo.PickingRenderGroup, // This RenderGroup allows scene picking/selection, use a different one if you don't want selection
+ Enabled = _selected || _enabled
+ };
+
+ var entity = new Entity($"{nameof(Gizmo)} for {_component.Entity.Name}"){ _model };
+ entity.Transform.UseTRS = false; // We're controlling the matrix directly in this case
+ entity.Scene = editorScene;
+
+ vertexBuffer.DisposeBy(entity);
+ indexBuffer.DisposeBy(entity); // Attach buffers to the entity for manual disposal later
+ }
+
+ public void Dispose()
+ {
+ _model.Entity.Scene = null;
+ _model.Entity.Dispose(); // Clear the two buffers we attached above
+ }
+
+ public void Update()
+ {
+ // This is where you'll update how the gizmo looks based on MyScript's state
+ // Here we'll just ensure the gizmo follows the entity it is representing whenever that entity moves,
+ // note that UseTRS is disabled above to improve performance and ensure that there are no world space issues
+ _model.Entity.Transform.LocalMatrix = _component.Entity.Transform.WorldMatrix;
+ }
+}
+```
+And the result:
+
+![Green sphere gizmo](media/gizmo.png)
+
+Do note that you may have to restart the editor if it was open while you introduced this new gizmo.
\ No newline at end of file
diff --git a/en/manual/scripts/index.md b/en/manual/scripts/index.md
index 3cc081fbc..96aa06820 100644
--- a/en/manual/scripts/index.md
+++ b/en/manual/scripts/index.md
@@ -39,4 +39,5 @@ You can still use standard C# classes in Stride, but these aren't called scripts
* [Events](events.md)
* [Debugging](debugging.md)
* [Preprocessor variables](preprocessor-variables.md)
-* [Create a model from code](create-a-model-from-code.md)
\ No newline at end of file
+* [Create a model from code](create-a-model-from-code.md)
+* [Create Gizmos for you components](gizmos.md)
\ No newline at end of file
diff --git a/en/manual/scripts/media/gizmo.png b/en/manual/scripts/media/gizmo.png
new file mode 100644
index 000000000..bc199a16e
--- /dev/null
+++ b/en/manual/scripts/media/gizmo.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:0a62f0db688ba96190cb147747afcb9c43818717b62eb334f86ca6a0dceb0c86
+size 92679
diff --git a/en/manual/toc.yml b/en/manual/toc.yml
index 61c2dcdb7..3b89b3431 100644
--- a/en/manual/toc.yml
+++ b/en/manual/toc.yml
@@ -498,6 +498,8 @@ items:
href: scripts/preprocessor-variables.md
- name: Create a model from code
href: scripts/create-a-model-from-code.md
+ - name: Create Gizmos for you components
+ href: scripts/gizmos.md
- name: Sprites
href: sprites/index.md
diff --git a/en/tutorials/toc.yml b/en/tutorials/toc.yml
index 55a98778f..9b43fd3c2 100644
--- a/en/tutorials/toc.yml
+++ b/en/tutorials/toc.yml
@@ -76,7 +76,7 @@ items:
href: csharpintermediate/ui-basics.md
- name: Collision triggers
href: csharpintermediate/collision-triggers.md
- - name: Racyasting
+ - name: Raycasting
href: csharpintermediate/raycasting.md
- name: Project and Unproject
href: csharpintermediate/project-and-unproject.md