Unity3D 导入脚本のAnimation动画切割






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


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

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

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


  1. 首先导入脚本不可能智能到知道我们的某个动作的动作名、开始帧、结束帧和是否循环,这个时候就需要一个配置表。
    • 为了让结构更加清晰,我把这几个需要导表的数据用类封装一下,这个类是一个AnimationClip需要的数据。
    • clipST这个类只记录一个AnimationClip的数据,一个模型会有N个AnimationClip组成,所以还要有一个类(modelst)来封装这一堆AnimationClip。并且还要记录这堆AnimationClip是给哪个模型用的。
    • 然后用一个List存储所有modelst。
    • 最后我们用init()方法,把美工提供的动作信息这些写入结构即可。
    • 具体代码如下:
      1. using UnityEngine;  
      2. using System.Collections;  
      3. using System.Collections.Generic;  
      4.   
      5. public static class AnimationClipConfig  
      6. {  
      7.     public static bool isInit = false;  
      8.     public static List<modelST> modelList = new List<modelST>();  
      9.   
      10.     public static void init()  
      11.     {  
      12.         if (isInit)  
      13.             return;  
      14.         isInit = true;  
      15.   
      16.         modelST tempModel = new modelST();  
      17.         tempModel.ModelName = "id_3000";               //模型名字  
      18.         tempModel.clipSTs = new clipST[]{  
      19.             new clipST("stand01" , 0, 60, true),           
      20.             new clipST("stand02" , 143, 193, true),         
      21.             new clipST("stand01_to_02" , 61, 100, false),    
      22.             new clipST("stand02_to_01" , 120, 142, false),  
      23.   
      24.             new clipST("shouji01" , 101, 119, false),   
      25.             new clipST("run01" , 253, 275, true),             
      26.   
      27.             new clipST("jump01" , 606, 626, false),         
      28.             new clipST("jump01_01" , 627, 645, false),       
      29.             new clipST("jump02" , 646, 663, false),         
      30.             new clipST("jump02_01" , 664, 686, false),        
      31.             new clipST("jump02_atk01" , 687, 714, false),   
      32.             new clipST("jump02_atk02" , 442, 456, false),     
      33.   
      34.             new clipST("1atk01" , 275, 285, false),         
      35.             new clipST("1atk02" , 297, 317, false),           
      36.             new clipST("1atk03" , 329, 349, false),      
      37.             new clipST("1atk04_end" , 361, 381, false),    
      38.   
      39.             new clipST("1atk01_01" , 286, 296, false),        
      40.             new clipST("1atk02_01" , 318, 328, false),         
      41.             new clipST("1atk03_01" , 350, 360, false),   
      42.   
      43.             new clipST("2atk01" , 382, 392, false),         
      44.             new clipST("2atk02" , 404, 424, false),           
      45.             new clipST("2atk03" , 436, 456, false),        
      46.             new clipST("2atk04_end" , 468, 488, false),   
      47.   
      48.             new clipST("2atk01_01" , 393, 403, false),        
      49.             new clipST("2atk02_01" , 425, 435, false),         
      50.             new clipST("2atk03_01" , 457, 467, false),    
      51.   
      52.             new clipST("3atk01" , 489, 499, false),         
      53.             new clipST("3atk02" , 521, 541, false),           
      54.             new clipST("3atk03" , 553, 573, false),         
      55.             new clipST("3atk04_end" , 585, 605, false),   
      56.   
      57.             new clipST("3atk01_01" , 500, 520, false),        
      58.             new clipST("3atk02_01" , 542, 552, false),         
      59.             new clipST("3atk03_01" , 574, 584, false),        
      60.   
      61.             new clipST("xl_atk01_01" , 194, 252 , false),        
      62.             new clipST("xl_atk01_02" , 194, 252, true),  
      63.             new clipST("xl_atk01_03" , 194, 252, false),        
      64.   
      65.             new clipST("dead01" , 715, 745, false),   
      66.         };  
      67.         modelList.Add(tempModel);  
      68.   
      69.   
      70.     }  
      71.  
      72.     #region ST  
      73.     public class clipST  
      74.     {  
      75.         public string name;  
      76.         public int firstFrame;  
      77.         public int lastFrame;  
      78.         public bool isloop;  
      79.   
      80.         public clipST(string _n,int _f,int _l,bool _i) {  
      81.             name = _n;  
      82.             firstFrame = _f;  
      83.             lastFrame = _l;  
      84.             isloop = _i;  
      85.         }  
      86.     }  
      87.   
      88.     public class modelST{  
      89.         public string ModelName;  
      90.         public clipST[] clipSTs;  
      91.     }  
      92.     #endregion  
      93. }  

  2. 知道了数据,然后就是高端洋气的自动切割AnimationClip了。直接上代码:
    1. using UnityEditor;  
    2. using UnityEngine;  
    3.   
    4. public class FBXAnimationsFix : AssetPostprocessor  
    5. {  
    6.     public void OnPreprocessModel()  
    7.     {  
    8.         //当前正在导入的模型  
    9.         ModelImporter modelImporter = (ModelImporter) assetImporter;  
    10.   
    11.         AnimationClipConfig.init();  
    12.   
    13.         foreach (AnimationClipConfig.modelST item in AnimationClipConfig.modelList)  
    14.         {  
    15.             //当前导入模型的路径包含我们modelST动作数据表中的模型名字,那就要对这个模型的动画进行切割  
    16.             if (assetPath.Contains(item.ModelName))  
    17.             {  
    18.                 modelImporter.animationType = ModelImporterAnimationType.Legacy;  
    19.   
    20.                 //modelImporter.splitAnimations = true;  
    21.                 modelImporter.generateAnimations = ModelImporterGenerateAnimations.GenerateAnimations;  
    22.   
    23.                 ModelImporterClipAnimation[] animations = new ModelImporterClipAnimation[item.clipSTs.Length];  
    24.                 for (int i = 0; i < item.clipSTs.Length; i++)  
    25.                 {  
    26.                     animations[i] = SetClipAnimation(item.clipSTs[i].name, item.clipSTs[i].firstFrame, item.clipSTs[i].lastFrame, item.clipSTs[i].isloop);  
    27.                 }  
    28.   
    29.                 modelImporter.clipAnimations = animations;  
    30.             }  
    31.         }  
    32.     }  
    33. }  
    34.   
    35. ModelImporterClipAnimation SetClipAnimation(string _name, int _first, int _last, bool _isLoop)  
    36. {  
    37.     ModelImporterClipAnimation tempClip = new ModelImporterClipAnimation();  
    38.     tempClip.name = _name;  
    39.     tempClip.firstFrame = _first;  
    40.     tempClip.lastFrame = _last;  
    41.     tempClip.loop = _isLoop;  
    42.     if (_isLoop)  
    43.         tempClip.wrapMode = WrapMode.Loop;  
    44.     else  
    45.         tempClip.wrapMode = WrapMode.Default;  
    46.   
    47.     return tempClip;  
    48. }  

  3. 后来逐渐发现,讲所有动作合并到原始模型中并没有起到多少优化的作用,反而对维护增添了很多不必要的麻烦,后来又把动作切割开了。
    动作和原始模型分成单独文件后,每个动作文件导入unity时,还会“非常智能”的把关联的材质、贴图再创建一个.fbm的文件夹导入一遍,但是我们原始模型已经导入了一套材质和贴图,动作就没必要再带进来一堆。所以要对动作进行一个设置,让他们不关联材质。
    1. using System.Collections.Generic;  
    2. using UnityEditor;  
    3. using UnityEngine;  
    4.   
    5. public class FBXScaleFix : AssetPostprocessor  
    6. {  
    7.     public void OnPreprocessModel()  
    8.     {  
    9.         ModelImporter modelImporter = (ModelImporter) assetImporter;  
    10.   
    11.         if (assetPath.Contains("@"))  
    12.         {  
    13.             modelImporter.importMaterials = false;  
    14.         }  
    15.     }  
    16. }  







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值