Unity Dots 动画渲染方案

本文探讨了Unity Dots动画渲染方案,包括采用的GPU ECS Animation Baker插件及其短板,GPU分析方法,如何优化GPU性能,以及渲染管线选择与非URP项目升级URP的注意事项。在万人项目中,Lod策略与骨骼信息的保留至关重要。
摘要由CSDN通过智能技术生成

日期:2023-8-2

Unity至今,尚未推出官方的渲染方案,Dots的渲染,还在Unity2023的开发蓝图之中。

1,采用的插件

UnityStore有一款插件,目前我们项目正在使用。

已知的短板,战斗单位的特效挂点,会丢失。

GPU ECS Animation Baker | Animation Tools | Unity Asset Store

2,GPU分析

如何分析压力在CPU还是GPU,打开Profiler,

CPU时间,GPU时间,都写得很清楚。 

一旦出现超级长的GfxDevice.WaitForLastPresent,便要重视。

Unity DOTS 1.0中,可以使用ECS(Entity Component System)来播放帧动画。以下是一个简单的例子: 1. 创建一个帧动画组件 ```csharp public struct FrameAnimationComponent : IComponentData { public int currentFrame; public int maxFrame; public float timePerFrame; public float elapsedTime; } ``` 这个组件包含了当前帧、最大帧数、每帧持续时间以及已经经过的时间。 2. 创建一个帧动画系统 ```csharp [UpdateInGroup(typeof(PresentationSystemGroup))] public class FrameAnimationSystem : SystemBase { protected override void OnUpdate() { float deltaTime = Time.DeltaTime; Entities.ForEach((ref FrameAnimationComponent animationComponent) => { animationComponent.elapsedTime += deltaTime; if (animationComponent.elapsedTime >= animationComponent.timePerFrame) { animationComponent.currentFrame++; animationComponent.elapsedTime = 0f; if (animationComponent.currentFrame >= animationComponent.maxFrame) { animationComponent.currentFrame = 0; } } }).ScheduleParallel(); } } ``` 这个系统会遍历所有包含了帧动画组件的实体,更新它们的当前帧,同时检查是否到达最大帧数,如果是则重置为0。 3. 创建一个帧动画渲染系统 ```csharp [UpdateInGroup(typeof(PresentationSystemGroup))] public class FrameAnimationRenderSystem : SystemBase { private EntityQuery frameAnimationQuery; private Material material; protected override void OnCreate() { frameAnimationQuery = GetEntityQuery(ComponentType.ReadOnly<FrameAnimationComponent>(), ComponentType.ReadOnly<SpriteRenderer>()); material = Resources.Load<Material>("FrameAnimationMaterial"); // 用于渲染动画的材质 } protected override void OnUpdate() { var sprites = GetComponentDataFromEntity<SpriteRenderer>(true); var frameAnimations = GetComponentDataFromEntity<FrameAnimationComponent>(true); Entities.WithoutBurst().ForEach((Entity entity, ref DynamicBuffer<SpriteBufferElement> spriteBuffer) => { if (!frameAnimations.HasComponent(entity)) { return; } var animation = frameAnimations[entity]; var sprite = sprites[entity]; int frameIndex = animation.currentFrame * sprite.numSubMeshes; for (int i = 0; i < sprite.numSubMeshes; i++) { spriteBuffer[i] = new SpriteBufferElement { sprite = sprite.subMeshes[i].sprites[frameIndex + i], material = material }; } }).WithStructuralChanges().Run(); } } ``` 这个系统会遍历所有包含了帧动画组件和SpriteRenderer组件的实体,根据当前帧数和SpriteRenderer的子网格数来更新DynamicBuffer中的SpriteBufferElement,这样就可以渲染出帧动画了。 需要注意的是,这个例子仅适用于单个SpriteRenderer组件中包含了整个帧动画的情况。如果需要对不同的子网格分别播放帧动画,则需要做一些修改。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

高远呢

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值