UNPKG

vertecs

Version:

A typescript entity-component-system framework

94 lines (73 loc) 2.53 kB
import { AnimationAction, AnimationClip, AnimationMixer } from "three"; import { Component, Entity } from "../core"; import ThreeObject3D from "./ThreeObject3D"; export default class ThreeAnimation extends Component { #mixer?: AnimationMixer; #clips?: AnimationClip[]; #actions?: Map<string, AnimationAction>; #currentAnimation?: AnimationAction; public constructor() { super(); this.#actions = new Map(); } public onAddedToEntity(entity: Entity) { const component = entity.getComponent(ThreeObject3D); if (!component) { return; } this.createMixer(component); } public onComponentAddedToAttachedEntity(component: Component) { if (component instanceof ThreeObject3D) { this.createMixer(component); } } private createMixer(meshComponent: ThreeObject3D) { this.#mixer = new AnimationMixer(meshComponent.object3D); this.#clips = meshComponent.object3D.animations; this.#clips.forEach((clip) => { const action = this.#mixer?.clipAction(clip); if (action) { this.#actions?.set(clip.name, action); action.weight = 0; action.play(); } }); } public playAnimation(animationName?: string) { // TODO: Move this to the system if (!this.#clips || !animationName) { console.warn("No clips found or animation name not provided"); return; } if (this.#currentAnimation?.getClip().name === animationName) { return; } const action = this.#actions?.get(animationName); if (!action) { console.warn("No action found"); return; } action.enabled = true; action.setEffectiveTimeScale(1); action.setEffectiveWeight(1); if (this.#currentAnimation) { this.#currentAnimation.time = 0; this.#currentAnimation.weight = 1; this.#currentAnimation.crossFadeTo(action, 0.2, false); } this.#currentAnimation = action; } public stopAnimation() { this.#currentAnimation?.stop(); } public get currentAnimation(): AnimationAction | undefined { return this.#currentAnimation; } public get mixer(): AnimationMixer | undefined { return this.#mixer; } public get clips(): AnimationClip[] | undefined { return this.#clips; } }