-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
`AnimatorAspect` is high level API for changing animation + remove unused component `FrameGrid` + naming changes + update Animation.md
- Loading branch information
1 parent
bfdb604
commit c0b0096
Showing
8 changed files
with
92 additions
and
27 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 |
---|---|---|
|
@@ -3,13 +3,18 @@ Provides components / systems / authorings / data structures to simulate sprite | |
It just shifts UVs over time which looks like different sprite rendered. | ||
While it just UV shifting animation sprite sequence should be a solid texture sheet. | ||
|
||
## How it works | ||
All animation data lives in provided `ScriptableObject`s (mentioned below). | ||
In baking phase it bakes all immutable animation data into blob (see `SpriteAnimationAuthoring`). | ||
Then in runtime it changes `UVAtlas` component value over time to perform flipbook animation. | ||
|
||
## [`SpriteAnimationAuthoring`](https://github.com/Antoshidza/NSprites-Foundation/blob/main/Animation/Authoring/SpriteAnimationAuthoring.cs) | ||
Inherited from [`SpriteRenderAuthoring`](https://github.com/Antoshidza/NSprites-Foundation/blob/main/Base/Authoring/SpriteRendererAuthoring.cs) it also bakes all needed animation data provided as [`SpriteAnimationSet`](https://github.com/Antoshidza/NSprites-Foundation/blob/main/Animation/Data/SpriteAnimationSet.cs). | ||
If you want to implement your own authoring you can still use static methods provided by this class to perform same baking. | ||
|
||
## Prepare assets | ||
To work with animation part you will also need to create [`SpriteAnimationSet`](https://github.com/Antoshidza/NSprites-Foundation/blob/main/Animation/Data/SpriteAnimationSet.cs) and bunch of [`SpriteAnimation`](https://github.com/Antoshidza/NSprites-Foundation/blob/main/Animation/Data/SpriteAnimation.cs). | ||
You can create them like most of `ScriptableObjects` by calling context menu in project and selecting `Create/NSprites/Animation Set` or `Create/Nsprites/Animation (sprite sequence)`. | ||
To work with animation part you need to create [`SpriteAnimationSet`](https://github.com/Antoshidza/NSprites-Foundation/blob/main/Animation/Data/SpriteAnimationSet.cs) and bunch of [`SpriteAnimation`](https://github.com/Antoshidza/NSprites-Foundation/blob/main/Animation/Data/SpriteAnimation.cs). | ||
You can create them like most of `ScriptableObjects` by calling context menu in project and selecting `Create/NSprites/Animation Set` / `Create/Nsprites/Animation (sprite sequence)`. | ||
|
||
### `SpriteAnimation` | ||
A `ScriptableObject` containing sprite sequence (as solid sprite sheet) where each sprite has duration of how long it stays before switch to next frame. This class also requires additional data like frame count resolution. | ||
|
@@ -18,6 +23,29 @@ A `ScriptableObject` containing set of `SpriteAnimation`s with string names (whi | |
### `SpriteAnimationBlobData` | ||
A `struct` blob to contain runtime immutable animation data. Contains `int` ID which corresponds to animation name with help of `Animator.StringToHash`, atlas UVs of sprite sheet, it's frame resolution, `BlobArray<float>` of frame durations and sum of all frames duration. | ||
|
||
## Change animation during runtime | ||
### Using `AnimatorAspect` | ||
You can use this [aspect](https://docs.unity3d.com/Packages/[email protected]/manual/aspects-intro.html) to change animation by it's ID in a simple way. | ||
```csharp | ||
// this example is from Age-of-Sprites project https://github.com/Antoshidza/Age-of-Sprites/blob/main/Assets/Sources/Rome/Systems/MovableAnimationControlSystem.cs | ||
[BurstCompile] | ||
private partial struct ChangeAnimationJob : IJobEntity | ||
{ | ||
public int SetToAnimationID; | ||
public double Time; | ||
|
||
private void Execute(ref AnimatorAspect animator) | ||
{ | ||
animator.SetAnimation(SetToAnimationID, Time); | ||
} | ||
} | ||
``` | ||
|
||
### Manually | ||
Basically to change animation we should set `AnimationIndex` to another index and reset `AnimationTimer` and `FrameIndex` and also calculate proper `UVAtlas` of 1st frame of animation you choosed. Though the short way is to just change `AnimationIndex`, set `FrameIndex` to last frame index in choosed animation and set `AnimationTimer` to current `Time.ElapsedTime` which will trigger `SpriteUVAnimationSystem` to calculate next frame which should be the 1st frame of choosed animation. | ||
|
||
You can inspect example of doing this by looking at `AnimatorAspect` source code. | ||
|
||
## Components | ||
|Type|Description| | ||
|----|-----------| | ||
|
@@ -26,5 +54,3 @@ A `struct` blob to contain runtime immutable animation data. Contains `int` ID w | |
|`FrameIndex`|Currently displayed frame from sprite sheet texture| | ||
|`AnimationTimer`|Timer which has value of global time + frame duration. When timer excided (timer value equals current global time) frame index increases| | ||
|
||
## How to change animations during runtime | ||
Basically to change animation we should set `AnimationIndex` to another index and reset `AnimationTimer` and `FrameIndex` and also calculate proper `UVAtlas` of 1st frame of animation you choosed. Though the short way is to just change `AnimationIndex`, set `FrameIndex` to last frame index in choosed animation and set `AnimationTimer` to current `Time.ElapsedTime` which will trigger `SpriteUVAnimationSystem` to calculate next frame which should be the 1st frame of choosed animation. |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
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,51 @@ | ||
using Unity.Entities; | ||
|
||
namespace NSprites | ||
{ | ||
public readonly partial struct AnimatorAspect : IAspect | ||
{ | ||
#if UNITY_EDITOR || DEVELOPMENT_BUILD | ||
private readonly Entity _entity; | ||
#endif | ||
private readonly RefRW<AnimationIndex> _animationIndex; | ||
private readonly RefRW<AnimationTimer> _animationTimer; | ||
private readonly RefRW<FrameIndex> _frameIndex; | ||
private readonly RefRO<AnimationSetLink> _animationSetLink; | ||
|
||
public void SetAnimation(int toAnimationIndex, in double worldTime) | ||
{ | ||
// find animation by animation ID | ||
ref var animSet = ref _animationSetLink.ValueRO.value.Value; | ||
var setToAnimIndex = -1; | ||
for (int i = 0; i < animSet.Length; i++) | ||
if (animSet[i].ID == toAnimationIndex) | ||
{ | ||
setToAnimIndex = i; | ||
break; | ||
} | ||
|
||
if (setToAnimIndex == -1) | ||
throw new NSpritesException($"{nameof(AnimatorAspect)}.{nameof(SetAnimation)}: incorrect {nameof(toAnimationIndex)} was passed. {_entity} has no animation with such ID ({toAnimationIndex}) was found"); | ||
|
||
if (_animationIndex.ValueRO.value != setToAnimIndex) | ||
{ | ||
ref var animData = ref animSet[setToAnimIndex]; | ||
_animationIndex.ValueRW.value = setToAnimIndex; | ||
// here we want to set last frame and timer to 0 (equal to current time) to force animation system instantly switch | ||
// animation to 1st frame after we've modified it | ||
_frameIndex.ValueRW.value = animData.FrameDurations.Length - 1; | ||
_animationTimer.ValueRW.value = worldTime; | ||
} | ||
} | ||
|
||
public void SetToFrame(int frameIndex, in double worldTime) | ||
{ | ||
ref var animData = ref _animationSetLink.ValueRO.value.Value[_animationIndex.ValueRO.value]; | ||
_frameIndex.ValueRW.value = frameIndex; | ||
_animationTimer.ValueRW.value = worldTime + animData.FrameDurations[frameIndex]; | ||
} | ||
|
||
public void ResetAnimation(in double worldTime) => | ||
SetToFrame(0, worldTime); | ||
} | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
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
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