Skip to content

feat: WIP: improving animations #1086

@dragoncoder047

Description

@dragoncoder047

Is your feature request related to a problem? Please describe.

Already WIP by MF, just opening an issue to track/talk about it.

  • sprite animations are their own thing, being that they were the O.G. animation system before we got the animate() component. however with the animation component now we can do the sprite animations by targeting the frame property and using easing none. this would actually kind of obviate the need for the frames list on sprite animations I added in feat: add frames list option to sprite animation #575 but still it's nice to define animations like that in the sprite metadata

  • currently the animation component can only target direct properties of the object, but we could also support sub-objects or potentially multiple targets given the object has a name(). Unsure of the notation, could be explicit object-property selection via {target: property, of: object name}

    MF: You'd do obj.playAnimation("walk") and it starts playing the walking animation on the obj and all children where it is defined, as animate is meant for hierarchical animation

more ideas by me and possibly by MF (we discussed a lot of things):

  • currently all channels of the same animation have the same duration. there ought to be a way to make each channel have different durations. Simplest solution may be to give every channel its own duration and every animation its own time counter, this would also fix the pausing since you could just not update the time counter

    MF seemed to not like this idea:

    wouldn't it have a sepparate time for each property you animate? Certainly not. You are defining a composite animation, not simple tweens. Also, there are keyframes, the animation of angle doesn't need to start on the same time as your pos animation.

    In the future, the animation clock can probably even be external, not associated with a single object, which is more convenient when animating a composite object.

  • i think the biggest complaint is you couldn't pause an animation and have it start back up where it left off because the time keeps counting while it's paused and you get a huge jump

    this is still relevant because the .animation.paused attribute is not used as far as I can tell lmao

    MF: shouldn't it start counting when you do obj.animate() ? No, animate is used to define your animation, it doesn't have any influence on playing.

  • have one-off animations/tweens be able to use the current value as keyframe 0

  • multiple animations playing at once with weights between them (maybe also make the relative weight animatable as well!)

  • "sticky animations", where they get to the end and stop, but they keep forcing their animated value at the final value, and it's only when you start the next animation targeting that value that the sticky anims clear themselves and stop controlling the value

  • animation grouping and shadowing logic, when you define an animation, it has a list of other animations it will forcibly stop() when played, and a list of animations that are "shadowed", that is they will be implicitly paused, and the time not updated, and if they're weighting with something their effective weight will be forced to 0 when shadowed

  • exponential smoothing of output values to prevent jerky movement between animations (configurable at animation-level since some animations may require less smoothing than others)

  • give an explicit animation channel type (number, vec2, color, absolute or relative, follow path or not) to prevent channel type autodetection on custom components from screwing things up or allowing things like follow path logic to work on custom targets
    could just do this by exposing the AnimChannel classes directly and passing an instance in to anim.addChannel() or something

  • make addKaboom() use animate()

  • get rid of fadeIn()

  • everything kaplay-native animation should use animate() !!!

Any more information?

From MF (copied from discord):

...I was thinking that sprite shouldn't have play, and an animated sprite should actually have used animate("frameIndex", ...). For the user it would still be play("walk"), but internally animate would take care of the animation. It would make more sense since now functionality is duplicated. It would also allow for adding fading, coloring or movement to and existing sprite index animation.

obj.animation.get("idle").animate("opacity", [1.0, 0.0, 1.0]); would add opacity animation to the original sprite animation.

loading those animations into animate won't take much time, since everything is already parsed into memory.

It would make it really easy to add a fade out effect to a disappearing dead enemy, or a shake animation to an existing opening chest animation for example...

...onAnimStart(action: (anim: string) => void): KEventController

Register an event that runs when an animation is played.

onAnimEnd(action: (anim: string) => void): KEventController

Register an event that runs when an animation is ended.

we need onAnimLoop for when a loop restarts.

Also need pause() and resume(). And maybe instead of having this in SpriteComp, have play() return a controller with pause/resume/stop/isPlaying/isStopped/isPaused/isFinished. The stop() in SpriteComp can call the stop of the controller to remain backwards compatible. But just split off the animation playback control part...

...right now there's too much code duplication, tween, sprite animation, animation, it's all the same. Tween should be an on the fly created animation. Sprite should use animations. So it is easier to sync, blend, etc animations.

Having one universal play controller also makes it easier to switch. Like you used a tween, but need extra keyframes, so you move to animation. But you don't want to change how you interact with the animation....

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request
    No fields configured for Feature.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions