Skip to content

Commit

Permalink
Merge pull request #265 from Doprez/add-jitter-fix-tutorial
Browse files Browse the repository at this point in the history
Taking care of this..
  • Loading branch information
VaclavElias authored Apr 15, 2024
2 parents 33b1d76 + a3004ca commit 39f4201
Showing 1 changed file with 115 additions and 0 deletions.
115 changes: 115 additions & 0 deletions en/manual/physics/fix-physics-jitter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
# Fix Physics Jitter

<span class="badge text-bg-primary">Beginner</span>
<span class="badge text-bg-success">Programmer</span>

In Stride there is no default smoothing applied to Entities that are attached to physics entities. This can cause a noticable jitter especially if you have the camera attached to a character component.
In this tutorial we will look at whats needed to add smoothing to an entity through a SyncScript.

>[!Note]
>You can also decrease the `Fixed Time Step` in the physics configuration, for example change it from `0.016667` to `0.008` for more accurate physics but this will be more expensive on the CPU.
## Code to handle smoothing between 2 entities
This should be all thats needed to attach 2 entities together. Make sure that you unparent the entity you are trying to smooth or else the transofrm processor will override this script.
```cs
[ComponentCategory("Utils")]
[DataContract("SmoothFollowAndRotate")]
public class SmoothFollowAndRotate : SyncScript
{
public Entity EntityToFollow { get; set; }
public float Speed { get; set; } = 1;

public override void Update()
{
var deltaTime = (float)Game.UpdateTime.Elapsed.TotalSeconds;
var currentPosition = Entity.Transform.Position;
var currentRotation = Entity.Transform.Rotation;

var lerpSpeed = 1f - MathF.Exp(-Speed * deltaTime);

EntityToFollow.Transform.GetWorldTransformation(out var otherPosition, out var otherRotation, out var _);

var newPosition = Vector3.Lerp(currentPosition, otherPosition, lerpSpeed);
Entity.Transform.Position = newPosition;

Quaternion.Slerp(ref currentRotation, ref otherRotation, lerpSpeed, out var newRotation);
Entity.Transform.Rotation = newRotation;
}
}
```

## Example Usage
For this example we will modify the First Person Shooter Template.

Step 1: Detach the camera from the Physics entity

Step 2: Remove the FPS camera script from the camera

Step 3: create a new entity as a child to the character body

Step 4: Add the FPS script to the new entity

Step 5: change the following code since they reference the CameraComponent directly

### PlayerInput.cs
change
```cs
public CameraComponent Camera { get; set; }
```
to
```cs
public Entity Camera { get; set; }
```

---

### Utils.cs
change
```cs
CameraComponent camera
```
to
```cs
Entity camera,
```
and change
```cs
camera.Update();
var inverseView = Matrix.Invert(camera.ViewMatrix);
```
to
`var inverseView = camera.Transform.WorldMatrix;`

---

### FpsCamera.cs
Remove
```cs

/// <summary>
/// Gets the camera component used to visualized the scene.
/// </summary>
private Entity Component;
```
and change
```cs
private void UpdateViewMatrix()
{
var camera = Component;
if (camera == null) return;
var rotation = Quaternion.RotationYawPitchRoll(Yaw, Pitch, 0);

Entity.Transform.Rotation = rotation;
}
```
to
```cs
private void UpdateViewMatrix()
{
var rotation = Quaternion.RotationYawPitchRoll(Yaw, Pitch, 0);

Entity.Transform.Rotation = rotation;
}
```

That should be all thats needed to see the smoothing in action as a before and after. You can see the original issue in the Stride Github [here](https://github.com/stride3d/stride/issues/2216) if you need to find more info on the problem.

0 comments on commit 39f4201

Please sign in to comment.