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

Unity Dots下的动画合批工具:GPU ECS Animation Baker

书接上文,为了实现大批量物体的生成,我们准备使用Unity最新的dots系统,在该系统下找到了动画解决方案:GPU ECS Animation Baker。

导入的同时,也需要导入以下两个插件,否则会提示报错:

PS:ECS主要用的也是这俩。

这是一款能够将物体自动合批并在ecs下使用的插件,导入之后可以看到几个示例场景,目前我们主要使用的是:

场景0 基础使用

场景1 LOD模型的使用

场景6 大批量物体的生成

1,基本使用示例

首先我们可以观察并测试场景0,从而大概了解其原理,并实现基础的合批。

基础原理:

如果之前用过合批工具的朋友应该知道,目前Unity主流合批原理,都是将模型的动画顶点信息记录在一张图上,然后通过解析图的信息,从而实现动画合批。

实现方法:

我们可以观察0_Basic场景,其中有个自带的模型,模型参数如下:

其中我们可以注意到,该模型有个动画状态机,且挂载了GpuEcsAnimationBakerBehaviour脚本,脚本中有预制体和动画指向两个关键参数。

由此,我们可以猜测这俩就是关于动画烘焙的参数,由此我们可以做个实验。

还是导入一只丧尸狗作为测试,我们在预制体上使用如下测试参数(必须要在预制体上):

PS:这里要注意,animation的数量要和animator里面的一样

点击下面Generate按钮之后,会在预制体文件夹下生成bake的同名文件夹,其中包含一个预制体,这个就是生成的合批文件:

但这个是不可以直接使用的,我们参考合批场景,需要在测试场景下面生成一个ecs专用的场景,然后在ecs中放入合批的物体:

最后,运行我们可以得到:

2,Lod模式下的使用示例

很明显,以上模型的面数太高,是不可以直接使用的,所以我们要进行LOD操作,而示例1中,则给我们提供了Lod的合批示例:

看起来和基础示例没什么区别,那么我们还是拿丧尸狗来测试下。

首先是使用autolod进行lod操作,具体可以参考上一篇帖子。

但接下来要注意的是,由于LOD加载模式的区别,所以我们要按照场景1中提供的例子进行LOD的层级操作,具体就是把mesh提到上层级,具体区别如下:

导出之后测试如下:

ps:这里涉及到一个问题,即在网格没合并的情况下,一个模型多个mesh的情况暂时没太好办法解决。所以选择模型的时候应该合理规避下。(有美术的话,可以让美术处理下。)

*或者参考4/5的示例,将武器绑定在对应的骨骼节点。但这个后面真用到再说,这里不再讨论。

3,大批量模型的加载

这里其实是和游戏逻辑挂钩的,模型上在材质球上打钩就行。

逻辑代码(这个之后博客会写注释,可以参考跳舞场景):

using Unity.Entities;
using UnityEngine;
using Unity.Mathematics;
using UnityEditor.PackageManager;


public class ZombieSpawnerAuthoring : MonoBehaviour
{
    public GameObject body1;

}

public class ZombieSpawnerBaker : Baker<ZombieSpawnerAuthoring>
{
    public override void Bake(ZombieSpawnerAuthoring authoring)
    {
        Entity entity = GetEntity(TransformUsageFlags.None);

        var _b1 = MyGetEntity(authoring.body1, 1);


        AddComponent(entity, new ZombieSpawnerComponent()
        {
            body1 = MyGetEntity(authoring.body1, 1),
            spawnPos = authoring.transform.position,
        });
    }

    public PrefabEntity MyGetEntity(GameObject _obj, int _id)
    {
        return new PrefabEntity()
        {
            id = _id + 1001,
            prefab = GetEntity(_obj, TransformUsageFlags.Dynamic)
        };
    }

}



public partial struct ZombieSpawnerComponent : IComponentData
{
    public PrefabEntity body1;
    public float3 spawnPos;
    public float updateTime;
}

public struct  PrefabEntity
{
    public int id;
    public Entity prefab;
}
using Unity.Burst;
using Unity.Entities;
using Unity.Mathematics;
using UnityEngine;

[BurstCompile]
public partial struct ZombieSpawnerSystem : ISystem
{
    public bool yet;
    Entity spawnerEntity;
    PrefabEntity body1;
   
    float3 spawnPos;

    double nextTime;

    int global_id;

    [BurstCompile]
    public void OnUpdate(ref SystemState state)
    {
  
        if (!yet)
        {
            if (!SystemAPI.TryGetSingletonEntity<ZombieSpawnerComponent>(out spawnerEntity)) return;

            RefRW<ZombieSpawnerComponent> refRW = SystemAPI.GetComponentRW<ZombieSpawnerComponent>(spawnerEntity);

            body1 = refRW.ValueRO.body1;
            spawnPos = refRW.ValueRO.spawnPos;



            yet = true;
        }
        else
        {
            EntityCommandBuffer ecb =new EntityCommandBuffer(Unity.Collections.Allocator.Temp);
            if (nextTime < SystemAPI.Time.ElapsedTime)
            {
                nextTime = SystemAPI.Time.ElapsedTime + 1f;

                var _new = ecb.Instantiate(body1.prefab);
                global_id++;

                Debug.Log("创建成功");
                //添加组件
                ecb.AddComponent(_new, new AgentComponent
                {
                    unit_id = body1.id,
                    id = global_id,
                    state = 0,
                    trigger_die = 0,
                });
            }
            ecb.Playback(state.EntityManager);
            ecb.Dispose();
        }

    }

}


public partial struct AgentComponent : IComponentData
{
    public int unit_id;//单位ID
    public int state;//0初始化 1移动 2死亡 3攻击
    public int id;//唯一ID
    public float trigger_die;//触发死亡的时间
}



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

相关文章:

  • autogen+ollama+litellm实现本地部署多代理智能体
  • 利用c语言详细介绍下插入排序
  • MySQL系列之身份鉴别(安全)
  • 递归------深度优先搜索
  • 使用Kotlin写一个将字符串加密成short数组,然后可以解密还原成原始的字符串的功能
  • 堆优化版本的Prim
  • 一文解决Latex中的eps报错eps-converted-to.pdf not found: using draft setting.
  • 【AI大模型引领变革】探索AI如何重塑软件开发流程与未来趋势
  • 《软件工程-北京大学》 学习笔记
  • elasticsearch介绍和部署
  • Apache Paimon】-- 6 -- 清理过期数据
  • 机器学习算法模型系列——Adam算法
  • 量子计算机全面解析:技术、应用与未来
  • 连接数据库:通过链和代理查询鲜花信息
  • 如何拆解问题
  • Git入门图文教程 -- 深入浅出 ( 保姆级 )
  • 【生物服务器】数据分析//论文润色/组学技术服务 、表观组分析、互作组分析、遗传转化实验、生物医学
  • ESP32移植Openharmony外设篇(6)光敏电阻ADC读取
  • Vue前端框架开发 npm安装Vite或CLI
  • 使用Python编写脚本,为Excel表格添加水印
  • 前端两大利器:Vue与TypeScript的渊源
  • 使用Python生成卡方分布表并导出为Excel文件
  • K8S数据存储持久化Volume和高级存储之PV、PVC
  • Git分布式版本控制系统
  • 【Linux】基础02
  • CommonsBeanutils与Shiro发序列化利用的学习