Table of Contents

SyncScript - moving a body every frame

A cube driven in a circle by a SyncScript, which is the ordinary way to run code every frame. The part worth copying is how it moves: the body is made kinematic and given a velocity, rather than a position written to Transform.Position. With a physics body attached the simulation owns the transform, so a position written there moves the mesh and leaves the collider behind; a velocity moves both, which is what lets the cube push dynamic bodies out of the way. SetTargetPose is the call for once-per-physics-step code, not for a per-frame Update.

The Program.cs file shows how to:

  • Running per-frame logic by deriving from SyncScript
  • Attaching a script to an entity with Entity.Add
  • Fetching a sibling component with Entity.Get
  • Why physics owns the transform once a body is attached
  • Moving a kinematic body with LinearVelocity, not Transform.Position
  • Why SetTargetPose belongs in ISimulationUpdate and not in a per-frame Update
  • Framerate independence with Game.DeltaTime
  • Using helpers: SceneSetup3D, UseSkybox, CreatePrimitive

SyncScript - moving a body every frame

View on GitHub.

using E02_3D_SyncScript;
using Stride.CommunityToolkit.Bepu;
using Stride.CommunityToolkit.Engine;
using Stride.CommunityToolkit.Rendering.ProceduralModels;
using Stride.CommunityToolkit.Skyboxes;
using Stride.Core.Mathematics;
using Stride.Engine;

using var game = new Game();

game.Run(new SceneSetup3D { Profiler = true }.UseBepu().UseSkybox(), start: Start);

void Start(Scene scene)
{
    // The cube starts on its circle; the script works the centre out from where it starts
    var entity = game.CreatePrimitive(Primitive3D.Cube());
    entity.Transform.Position = new Vector3(1f, 0.5f, 3f);
    entity.Add(new RotationComponentScript());
    entity.Scene = scene;

    var cone = game.CreatePrimitive(Primitive3D.Cone(0.5f, 5));
    cone.Transform.Position = new Vector3(0, 6, 0);
    cone.Scene = scene;
}