-
Notifications
You must be signed in to change notification settings - Fork 68
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #265 from Doprez/add-jitter-fix-tutorial
Taking care of this..
- Loading branch information
Showing
1 changed file
with
115 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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. |