12.创建动画信息配置数据结构

12.具体实现-烘焙部分-动画信息配置


12.1 知识点

先搞清楚纹理里是怎么存的

在设计配置数据结构之前,得先回顾一下 VAT 纹理的存储方式。

回顾之前的的代码,纹理是按这个顺序写入的:

假设有一个模型,9500 个顶点,3 个动画(A、B、C),分别有 20、50、57 帧。纹理尺寸 2048×2048。

每个动画需要的像素数:

动画 帧数 像素数(帧数 × 顶点数)
A 20 190,000
B 50 475,000
C 57 541,500
总计 127 1,206,500

纹理中的存储区间:

纹理宽度 2048,每行可存 2048 个像素。

动画 像素索引范围 行范围 说明
A 0 ~ 189,999 第 0 ~ 92 行 20帧 × 9500顶点 = 190,000像素
B 190,000 ~ 664,999 第 93 ~ 324 行 紧接动画A,50帧 × 9500顶点 = 475,000像素
C 665,000 ~ 1,206,499 第 325 ~ 589 行 紧接动画B,57帧 × 9500顶点 = 541,500像素

总共占用约 590 行,纹理高度 2048 行,空间充足。

纹理是连续平铺的:先写完动画 A 的所有帧,再写动画 B 的所有帧,最后写动画 C 的所有帧。

运行时需要知道什么

Shader 在运行时要从纹理里取出正确的顶点位置,需要知道:

  1. 当前播放的是哪个动画
  2. 当前播放到第几帧
  3. 这个动画在纹理里的起始位置
  4. 这个模型有多少个顶点
  5. 顶点坐标的 min/max(用于从 0~1 还原回原始坐标)

把这些信息整理一下,可以分成两类:

同一个模型所有动画共用的信息

这些信息对于同一个模型来说是不变的:

信息 类型 示例值 用途
顶点总数 int 9500 计算纹理坐标时需要知道有多少个顶点
顶点最大坐标 int 128 从归一化坐标还原回原始坐标
顶点最小坐标 int -64 从归一化坐标还原回原始坐标
VAT 纹理 Texture2D[] 见下方说明 采样获取顶点位置

VAT 纹理说明:

  • 如果动画少、帧数少,一张纹理就够用,数组长度为 1。
  • 如果动画多、帧数多,超出单张纹理容量,就需要多张纹理。
  • 当前示例(9500 顶点、127 帧)只占用 590 行,一张 2048×2048 纹理足够,所以数组长度为 1。

每个动画独立的信息

这些信息每个动画都不一样:

信息 类型 示例值 用途
动画名 string “Walk” 识别是哪个动画
总帧数 int 50 控制动画播放范围
帧率 int 30 计算播放速度
像素索引起始位置 int 190000 知道从纹理的哪个位置开始读
使用的纹理索引 int 0 如果用到多张纹理,标记用哪一张

纹理索引说明:

  • 单张纹理时,所有动画的纹理索引都是 0。
  • 多张纹理时,需要记录该动画的数据存在第几张纹理里。

数据结构设计

根据上面的分析,需要创建两个类:

  1. AnimationInfo:存储单个动画的信息
using System;

// VAT中单个动画需要的信息
// 之后我们需要利用这些信息来进行动画更新
[Serializable]
public class AnimationInfo
{
    // 动画名
    public string animationName;

    // 总帧数
    public int frameCount;

    // 像素索引的起始位置
    public int pixelIndex;

    // 帧率
    public int frameRate;
}
  1. AnimationInfos:整个模型 VAT 的配置信息(继承 ScriptableObject,方便序列化存储为资源文件)
using UnityEngine;

// VAT需要记录的信息
public class AnimationInfos : ScriptableObject
{
    // 顶点总数
    public int vertexCount;

    // 顶点最大值坐标
    public int vertexMax;

    // 顶点最小值坐标
    public int vertexMin;

    // 烘焙的动作纹理(VAT)
    public Texture2D vat_texture;

    // 单个动画信息们
    public AnimationInfo[] allAnimationinfo;
}

12.2 知识点代码

AnimationInfo.cs

using System;

// VAT中单个动画需要的信息
// 之后我们需要利用这些信息来进行动画更新
[Serializable]
public class AnimationInfo
{
    // 动画名
    public string animationName;

    // 总帧数
    public int frameCount;

    // 像素索引的起始位置
    public int pixelIndex;

    // 帧率
    public int frameRate;
}

AnimationInfos.cs

using UnityEngine;

// VAT需要记录的信息
public class AnimationInfos : ScriptableObject
{
    // 顶点总数
    public int vertexCount;

    // 顶点最大值坐标
    public int vertexMax;

    // 顶点最小值坐标
    public int vertexMin;

    // 烘焙的动作纹理(VAT)
    public Texture2D vat_texture;

    // 单个动画信息们
    public AnimationInfo[] allAnimationinfo;
}


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏