载入中...
搜索中...
未找到
动画模块

动画模块

脚本入口: eve.Animation()

支持七类能力:

  1. **Tween**:标量/角度属性补间(delay、repeat、yoyo、缓动)
  2. **2D 帧动画**:SpriteSheet + SpriteClip + SpriteAnim(sprite sheet / 图集格子)
  3. **Spine(region 子集)**:.atlas + skeleton JSON → SpineAnim.collectDrawItems 进 2D 队列
  4. **3D 骨骼动画播放**:AnimSkeleton + AnimClip,可用 AnimPlayer、状态机 AnimStateMachine、或 Motion Matching(MotionDatabase + MotionMatcher)驱动
  5. **CPU 蒙皮**:AnimSkinModelData 读取骨骼权重与 inverse-bind,按 AnimPose 世界矩阵做线性混合蒙皮
  6. **控制论程序动画**:ControlAnim(命名标量通道)与 ControlPose(骨骼姿态跟踪),基于二阶 LTI / 闭式阻尼弹簧 / 单位质量 PD
  7. **拖尾轨迹**:AnimTrail 记录采样点并绘制淡出轨迹(2D 点或骨骼世界坐标投影)

基本用法(Tween)

local anim = eve.Animation();
local move = anim.newTween(0.6);
move.setFrom("x", 0);
move.setTo("x", 200);
move.setEase("outQuad");
move.start();
anim.update(dt);

基本用法(2D 帧动画)

local anim = eve.Animation();
local gfx = eve.Graphics();
local sheet = anim.newSpriteSheet();
sheet.setGrid(4, 2, 32, 48, 0, 0, 0, 0); // cols, rows, frameW, frameH, margin, spacing, ox, oy
local walk = anim.newSpriteClip("walk");
walk.setLoop(true);
walk.addFrame(0, 0.1);
walk.addFrame(1, 0.1);
walk.addFrame(2, 0.1);
walk.addFrame(3, 0.1);
local quad = gfx.newQuad(0, 0, 32, 48);
local player = anim.newSpriteAnim();
player.setSheet(sheet);
player.bindQuad(quad); // 每帧自动 setViewport
player.play(walk);
// eve_update:
anim.update(dt);
// 把 quad 挂到 Renderable2D.sprite.quad 即可换帧

基本用法(Spine region)

内置解析器支持 Spine .atlas + skeleton JSON 的 **region 附件**子集(骨骼 TRS、slot 附件切换)。Mesh / IK / path / deform 需自行接入官方 spine-cpp 插件。

local anim = eve.Animation();
local atlas = anim.newSpineAtlasFromFile("hero.atlas");
local data = anim.newSpineSkeletonDataFromFile("hero.json");
local sk = anim.newSpineSkeleton(data);
local spine = anim.newSpineAnim(sk);
spine.setAtlas(atlas);
spine.setPageTextureByName("hero.png", tex); // Graphics 纹理
spine.setPosition(400, 300);
spine.setFlipY(true); // 默认 true:Spine Y-up → 屏幕 Y-down
spine.play("idle");
// eve_update:
anim.update(dt);
// C++ / 自定义系统:spine.collectDrawItems(queue)
// 脚本可读:spine.getDrawSlotCount / getDrawSlotX/Y/Width/Height

基本用法(3D 状态机)

local anim = eve.Animation();
local sk = anim.newSkeleton();
local root = sk.addBone("root", -1);
local hip = sk.addBone("hip", root);
sk.setBindPosition(hip, 0, 1, 0);
local idle = anim.newClip("idle");
// idle.addPositionKey / addRotationKey ...
local walk = anim.newClip("walk");
local sm = anim.newStateMachine(sk);
sm.addState("Idle", idle);
sm.addState("Walk", walk);
sm.setEntry("Idle");
local t = sm.addTransition("Idle", "Walk", 0.15);
sm.addFloatCondition(t, "speed", ">", 0.5);
sm.setFloat("speed", 1.0);
sm.update(dt);
local pose = sm.getPose();

基本用法(Motion Matching)

local db = anim.newMotionDatabase(sk);
db.setRootBoneByName("mixamorig:Hips"); // Mixamo 等角色常用髋骨做轨迹根
db.addFeatureBoneByName("mixamorig:LeftFoot");
db.addFeatureBoneByName("mixamorig:RightFoot");
db.addClip(walk);
db.addClip(run);
db.bake();
local mm = anim.newMotionMatcher(sk, db);
mm.setDesiredVelocity(0, 3);
mm.setDesiredYaw(0);
mm.setSearchInterval(0.1);
mm.update(dt);
local pose = mm.getPose();

基本用法(控制论程序动画)

二阶动力学把目标当成输入 x,输出 y 满足:

[ \ddot y + k_1