当前位置: 首页 > article >正文

【threejs】实现不同动画的播放和平滑切换

关键代码

主要是通过 修改动作的速度和幅度达到平滑切换



        action.setEffectiveTimeScale(1);
        action.setEffectiveWeight(weight);//0-1


要用到的工具 ,一个简易的动画class Anim

代码点击下方链接获取
开箱即用,无需安装

加载模型并创建mixer和actions

import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";

import { AnimationMixer, Clock } from "three";   
//前置条件
  this.actions = []
  this.clock = new Clock()
  this.mixer = null
  this.currentAct = "idle"
  this.weights = {
            idle: 1,
            walk: 0,
            run: 0,
            workOnDevice: 0,
            waving: 0
        }

//加载带动画的模型
let url = `/static/threeResources/models/cyberPerson.glb`
        let loader = new GLTFLoader()
        loader.load(url, (gltf) => {
           

            let animations = gltf.animations

            let model = gltf.scene

     
            this.add(model)//加入场景

            let mixer = new AnimationMixer(model)
			//创建mixer和action
            let actions = []
            for (let i = 0; i < animations.length; i++) {
                let animation = animations[i]
                let name = animation.name
                let action = mixer.clipAction(animation);
                // let animationName = animation.name
                Object.assign(action, { name })//这里标记名称方便后面切换动画查找
                actions.push(action)

            }

            this.actions = actions
            this.mixer = mixer



            this._mesh = model
            this.modelUrl = ""
            this.activateAllActions()
            console.log(mixer, actions);

        })

//激活所有动画轨道

   activateAllActions() {
        let { actions, weights } = this

        for (let i = 0; i < actions.length; i++) {
            let action = actions[i]

            let name = action.name//这里是上面加载后添加了name信息,原生action没有这个属性
            console.log(name, weights[name]);

            if (weights[name]) {
                this.setWeight(action, weights[name])

            } else {
                this.setWeight(action, 0)
            }


            action.play();
        }

    }
     activateAllActions() 
   setWeight(action, weight) {

        action.enabled = true;
        action.setEffectiveTimeScale(1);
        action.setEffectiveWeight(weight);

    }
//使用刚才备注的名称可以平滑切换动画
/**
主要是通过
        action.setEffectiveTimeScale(1);
        action.setEffectiveWeight(weight);
  修改动作的速度和幅度达到平滑切换
*/
    setAnimate(animate = 'idle') {
        let { weights, actions } = this
        let nWeights = {
            idle: 0,
            walk: 0,
            run: 0,
            workOnDevice: 0,
            waving: 0
        }

        for (let k in nWeights) {
            if (k == animate) {
                nWeights[k] = 1
            }
        }
        console.log(nWeights);

        let anim = new Anim(weights, nWeights, {
            duration: 750,
            easingFunction: Anim.linear,

            onUpdate: (_weights) => {

                for (let i = 0; i < actions.length; i++) {
                    let action = actions[i]

                    let name = action.name


                    if (_weights[name]) {
                        this.setWeight(action, _weights[name])

                    } else {
                        this.setWeight(action, 0)
                    }


                }


            },
            onComplete: () => {
                this.weights = nWeights

            }
        })
        anim.start()
    }

//这个函数在更新renderer的时候执行,一般用requestAnimationFrame(){
//}循环调用
 _render(t) {
        let mixerUpdateDelta = this.clock.getDelta();
  
        this.mixer.update(mixerUpdateDelta);
    }



http://www.kler.cn/a/421225.html

相关文章:

  • Redis使用场景-缓存-缓存雪崩
  • POI和easyExcel详解
  • 【Spring】介绍一下 Spring 的 xml 标签以及 Bean 的常用配置
  • 基于链表的基础笔试/面试题
  • wordpress网站首页底部栏显示网站备案信息
  • 【iOS】多线程基础
  • (长期更新)《零基础入门 ArcGIS(ArcMap) 》实验三----学校选址与路径规划(超超超详细!!!)
  • <数据集>路面坑洼识别数据集<目标检测>
  • 王道操作系统目录以及学习感受和总结
  • 《向量数据库指南》——Florence:多模态应用的新基石!
  • 2024年大热,Access平替升级方案,也适合Excel用户
  • Vuex的理解及使用场景
  • 南昌榉之乡托养机构解读:自闭症与看电视并无必然联系
  • 大数据新视界 -- Hive 数据湖架构中的角色与应用(上)(25 / 30)
  • CTF之WEB(sqlmap tamper 参数)
  • 零基础快速掌握——【c语言基础】数组的操作,冒泡排序,选择排序
  • 基于单片机的智能宠物喂食系统设计
  • 华为HarmonyOS 让应用快速拥有账号能力 -- 2 获取用户头像昵称
  • 服务器数据恢复—EVA存储硬盘磁头和盘片损坏离线的数据恢复案例
  • PH热榜 | 2024-12-03
  • taro小程序马甲包插件
  • 链表的分类以及双向链表的实现
  • Unity类银河战士恶魔城学习总结(P157 Audio Time Limter ---P158 Area Sound范围音效)
  • 【微服务】Docker
  • ELK的Filebeat
  • Mac安装MINIO服务器实现本地上传和下载服务