• 原创文章如需转载请注明:转载自 脱莫柔Unity3D学习之旅 Unity3D引擎技术交流QQ群:【119706192】本文链接地址: Unity3D 导入脚本のAnimation动画切割 近期项目中为了缩减资源包,想把一个角色的所有动作全部...

    原创文章如需转载请注明:转载自 脱莫柔Unity3D学习之旅 Unity3D引擎技术交流QQ群:【119706192本文链接地址: Unity3D 导入脚本のAnimation动画切割

    近期项目中为了缩减资源包,想把一个角色的所有动作全部放在原始模型模型中(后期证实,并无优化效果,所以把动作文件和原始模型文件又拆分成了单独的文件)。

    原始模型中有600多帧动作,需要手动设置AnimationClip的起始帧和结束帧还有是否循环,。每个模型30个动作,一共25个主角模型,想想都蛋疼。于是研究了下unity的资源处理器(AssetPostprocessor)。

    在导入模型之前(OnPreprocessModel)对动画进行切割。

    1.首先导入脚本不可能智能到知道我们的某个动作的动作名、开始帧、结束帧和是否循环,这个时候就需要一个配置表。
    • 为了让结构更加清晰,我把这几个需要导表的数据用类封装一下,这个类是一个AnimationClip需要的数据。
    • clipST这个类只记录一个AnimationClip的数据,一个模型会有N个AnimationClip组成,所以还要有一个类(modelst)来封装这一堆AnimationClip。并且还要记录这堆AnimationClip是给哪个模型用的。
    • 然后用一个List存储所有modelst。
    • 最后我们用init()方法,把美工提供的动作信息这些写入结构即可。

    具体代码如下:

    using UnityEngine;
    using System.Collections;
    using System.Collections.Generic;
     
    //自定义的动作配置表(用来预先配置各动作的动作名、起始帧、结束帧和是否循环。)
    public static class AnimationClipConfig
    {
        //是否已经初始化
        public static bool isInit = false;
        //模型动作配置表(只记录需要配置模型动作的模型)
        public static List<modelST> modelList = new List<modelST>();
     
        public static void init()
        {
            if (isInit)
                return;
            isInit = true;
     
            modelST tempModel = new modelST();
            //需要配置动作的模型名字
            tempModel.ModelName = "id_3000";
            //给该模型配置的动作(动作名、起始帧、结束帧、是否循环)
            tempModel.clipSTs = new clipST[]{
                new clipST("stand01" , 0, 60, true),         
                new clipST("stand02" , 143, 193, true),       
                new clipST("stand01_to_02" , 61, 100, false),  
                new clipST("stand02_to_01" , 120, 142, false),
     
                new clipST("shouji01" , 101, 119, false), 
                new clipST("run01" , 253, 275, true),           
     
                new clipST("jump01" , 606, 626, false),       
                new clipST("jump01_01" , 627, 645, false),     
                new clipST("jump02" , 646, 663, false),       
                new clipST("jump02_01" , 664, 686, false),      
                new clipST("jump02_atk01" , 687, 714, false), 
                new clipST("jump02_atk02" , 442, 456, false),   
     
                new clipST("1atk01" , 275, 285, false),       
                new clipST("1atk02" , 297, 317, false),         
                new clipST("1atk03" , 329, 349, false),    
                new clipST("1atk04_end" , 361, 381, false),  
     
                new clipST("1atk01_01" , 286, 296, false),      
                new clipST("1atk02_01" , 318, 328, false),       
                new clipST("1atk03_01" , 350, 360, false), 
     
                new clipST("2atk01" , 382, 392, false),       
                new clipST("2atk02" , 404, 424, false),         
                new clipST("2atk03" , 436, 456, false),      
                new clipST("2atk04_end" , 468, 488, false), 
     
                new clipST("2atk01_01" , 393, 403, false),      
                new clipST("2atk02_01" , 425, 435, false),       
                new clipST("2atk03_01" , 457, 467, false),  
     
                new clipST("3atk01" , 489, 499, false),       
                new clipST("3atk02" , 521, 541, false),         
                new clipST("3atk03" , 553, 573, false),       
                new clipST("3atk04_end" , 585, 605, false), 
     
                new clipST("3atk01_01" , 500, 520, false),      
                new clipST("3atk02_01" , 542, 552, false),       
                new clipST("3atk03_01" , 574, 584, false),      
     
                new clipST("xl_atk01_01" , 194, 252 , false),      
                new clipST("xl_atk01_02" , 194, 252, true),
                new clipST("xl_atk01_03" , 194, 252, false),      
     
                new clipST("dead01" , 715, 745, false), 
            };
            modelList.Add(tempModel);
     
     
        }
     
        #region ST
        //动作配置格式
        public class clipST
        {
            public string name;
            public int firstFrame;
            public int lastFrame;
            public bool isloop;
     
            public clipST(string _n,int _f,int _l,bool _i) {
                name = _n;
                firstFrame = _f;
                lastFrame = _l;
                isloop = _i;
            }
        }
        //模型动作表配置搁置
        public class modelST{
            public string ModelName;
            public clipST[] clipSTs;
        }
        #endregion
    }
    2.知道了数据,然后就是高端洋气的自动切割AnimationClip了。直接上代码:

    using UnityEditor;
    using UnityEngine;
     
    public class FBXAnimationsFix : AssetPostprocessor
    {
        public void OnPreprocessModel()
        {
            //当前正在导入的模型
            ModelImporter modelImporter = (ModelImporter) assetImporter;
            //初始化配置表
            AnimationClipConfig.init();
     
            //遍历模型动作配置表,获取每个需要配置动作的模型
            foreach (AnimationClipConfig.modelST item in AnimationClipConfig.modelList)
            {
                //当前导入模型的路径 ↓
                //包含我们配置表中的模型名字(即AnimationClipConfig.modelList.ModelName),
                //那就要对这个模型的动画进行切割
                if (assetPath.Contains(item.ModelName))
                {
                    //先将导入模型的动画类型(Rig)设置成成legacy动画
                    modelImporter.animationType = ModelImporterAnimationType.Legacy;
                    modelImporter.generateAnimations = ModelImporterGenerateAnimations.GenerateAnimations;
     
                    //记录模型动作数组的修改
                    ModelImporterClipAnimation[] animations = new ModelImporterClipAnimation[item.clipSTs.Length];
                    for (int i = 0; i < item.clipSTs.Length; i++)
                    {
                        //将配置表的动作clip的名字、起始帧、结束帧和是否循环属性保存到动作clip数组(animations[])。
                        animations = SetClipAnimation(item.clipSTs.name, item.clipSTs.firstFrame, item.clipSTs.lastFrame, item.clipSTs.isloop);
                    }
     
                    //将修改后的动作数组设置给导入模型的动作数组
                    modelImporter.clipAnimations = animations;
                }
            }
        }
    }
     
    ModelImporterClipAnimation SetClipAnimation(string _name, int _first, int _last, bool _isLoop)
    {
        ModelImporterClipAnimation tempClip = new ModelImporterClipAnimation();
        tempClip.name = _name;
        tempClip.firstFrame = _first;
        tempClip.lastFrame = _last;
        tempClip.loop = _isLoop;
        if (_isLoop)
            tempClip.wrapMode = WrapMode.Loop;
        else
            tempClip.wrapMode = WrapMode.Default;
     
        return tempClip;
    }

    后来逐渐发现,讲所有动作合并到原始模型中并没有起到多少优化的作用,反而对维护增添了很多不必要的麻烦,后来又把动作切割开了。
    动作和原始模型分成单独文件后,每个动作文件导入unity时,还会“非常智能”的把关联的材质、贴图再创建一个.fbm的文件夹导入一遍,但是我们原始模型已经导入了一套材质和贴图,动作就没必要再带进来一堆。所以要对动作进行一个设置,让他们不关联材质。

    using System.Collections.Generic;
    using UnityEditor;
    using UnityEngine;
     
    public class FBXScaleFix : AssetPostprocessor
    {
        public void OnPreprocessModel()
        {
            ModelImporter modelImporter = (ModelImporter) assetImporter;
     
            if (assetPath.Contains("@"))
            {
                modelImporter.importMaterials = false;
            }
        }
    }



    展开全文
  • 不过这也在情理之中,毕竟Unity3D是做3D的,要切割图片的地方还是很少的。 因为我用Unity3D主要是用于做2D游戏的(PS:很蛋疼吧?我也觉得),所以就不得不考虑切图和播放序列帧这两个在2D上常见的功能了,下面废话...
  • Unity提供了Animation编辑器,它可以为我们编辑物理动画。举个例子比如场景中有一个来回摇动的秋千,这个秋千在项目中完全只起到衬托作用,它不会与别的游戏对象有任何交互。如果这个秋千也用代码来写控制它来回摇动...
  • 对于模型动画的分割,不论Animation,还是Animator,在动画的分割上稍有一些不同,但整个操作的思路是一致的,希望大家在本课内容的学习过程中与Animation的动画分割方式进行相应比较。分割动画导入的一个角色资源,...
  • Unity-动画系统 2018-03-03 17:01:18
    Unity引擎中,大致上可以分为两大类动画控制系统,分别是Animation和Mecanim动画系统.。Aniamtion是低版本中的动画控制系统。而Aniamtor是Unity新的动画系统Mecanim动画系统的核心组件.通过它能够实现对动画的...
  • Unity3D创建素材(2):模型、绑定、动画 https://www.jianshu.com/p/e2aa4d898fb7 模型(Mesh) 在Unity3D中使用三维模型,主要依靠Mesh Filter组件载入多边形表面物体(polygon mesh),然后依靠Mesh ...
  • unity3d将一张图片切成多张图片
  • 转自:http://jingyan.baidu.com/article/f96699bbb1a0d6894f3c1b77.html 参考:... ...本篇教程为基础篇,针对U3D入门新手,讲解粒子系统播放序列图的一种实现方法,随着基础教程的知识点的慢慢
  • unity3d简历的重要性 2019-06-29 23:31:17
    大家好,我是灰太狼,看到好多unity3d学员说学unity3d,毕业找不到工作,我很是不解,但是当我看到一个泰课学员的简历(对不起石峰弟弟,我又卖你了),我才明白,原来是简历写的不好,不会包装自己,今天写这篇文章...
  • 用脚本分割动画 unity3d 2015-01-23 17:32:48
    关于用脚本分割动画 unity3d,我来分享一下我在做项目的时候,涉及到的有关分割动画的一些资源给大家分享一下,大家可以参考和学习。 近期项目中为了缩减资源包,想把一个角色的所有动作全部放在原始模型模型中...
  • Unity3D 4.3新特性 —— 2D 2013-11-14 21:04:21
    Unity3D 终于发布了4.3版本。先来看看有啥特性: 这次发布的包主要包括这些特性:  一个完整的2D工具集  动画:混合变形和用于动画驱动的动画事件  MonoDevelop4.0.1  导航网格:动态切断的网格链接和障碍切割...
  • Unity动画系统Unity动画系统,也称为“Mecanim”,提供了以下功能:简单的工作流程,设置动画的所有元素,包括对象,角色和属性。支持导入外部创建的动画片段和使用内置动画编辑器制作的动画片段。人型动画重新定位...
  • 1.以下哪一个选项不属于Unity引擎所支持的视频格式文件? 【D】 后缀名为mov的文件 后缀名为mpg的文件 后缀名为avi的文件 后缀名为swf的文件 2. HDR高动态光照渲染属于下列哪个选项的属性? 【D】 Lightmapping...
  •  大家好。我是秦培。欢迎关注我的博客。我的博客地址blog.csdn.net/qinyuanpei。...作为这个月的最后一篇文章,今天博主想和大家分享的是关于Unity3D中的Mecanim动画系统。博主非常早就想写这...
  • 博主本来想自己写,有大大写的异常详细...在Unity3D中使用三维模型,主要依靠Mesh Filter组件载入多边形表面物体(polygon mesh),然后依靠Mesh Renderer组件将Mesh正确渲染出来。 内置基本3D模型 Unity3D内置有...
  • 1:准备好unity使用Spine所需要的运行库,可到如下地址 https://github.com/EsotericSoftware/spine-runtimes/tree/master/spine-unity  使用git下载,或直接下载master.zip文件,资源下载看下面的优化部分。 2:...
  • ▶蒙皮绘画 在3D绘制允许您绘制动画对象与伟大的性能。看看WebGL的演示,看看僵尸油漆看起来有多棒。 ▶无缝紫外线绘画 如果你有一个复杂的网格,它是常见的接缝时绘画,甚至当使用专业的绘画软件。3D绘画解决 了这...
  • 小时候,大家都应玩过或听说过《俄罗斯方块》,它是红白机,掌机等一些电子设备中最常见的一款游戏。而随着时代的发展,信息的进步,游戏画面从简单的...首先,看标题都知道这篇文章中所用到的游戏引擎是:unity3d,...
  • Max动画分割脚本 Unity 自动识别动画分割信息
  • Unity3d相关: http://www.u3dchina.com/forum.php?mod=viewthread&tid=1817  Unity3d c#开发 http://blog.csdn.net/quannenggou/article/details/7332687  Unity3d开发的博文 ... Un
1 2 3 4 5 ... 10
收藏数 184
精华内容 73