【Unity万人同屏插件】使用手册 保姆级教程 GPU动画 Jobs多线程渲染

⚠注意:近日存在盗版插件出售,插件有防盗机制,盗版无法正常使用功能,谨防受骗。一经发现传播盗版,将永久禁用其插件使用

官方正版唯一店铺:游戏开发资源商店


【万人同屏插件】

基于Dots技术,高性能实现3D、2D Spine渲染、海量单位锁敌/碰撞检测。同时通过自定义BRG渲染器绕过对Entities包的依赖,也就是不用写ECS代码即可拥有Entities Graphics的高性能渲染,使用传统开发方式BRG接管Renderer组件。

可以大幅提升PC或移动平台的游戏帧数,GPU动画同样支持WebGL,对于开发小游戏也有着巨大性能提升。同时,转换为GPU动画后可以大幅减少动画文件大小,可用作包体大小优化。

适用于海量单位游戏项目突破技术门槛,同时也适用于任何需要做性能优化的项目。例如:割草、类吸血鬼、RTS、SLG、弹幕游戏,以及海量树木、植被、建筑渲染等。

Dots正式版发布于Unity2022.3 LTS版,因此强烈建议使用Unity 2022.3.x及以上版本,插件同样支持最新版Unity 6.

功能/性能测试Demo下载

https://pan.baidu.com/s/1ML0DC8s0RkkTAraN9maltw?pwd=bluehttps://pan.baidu.com/s/1ML0DC8s0RkkTAraN9maltw?pwd=bluehttps://pan.baidu.com/s/1ML0DC8s0RkkTAraN9maltw?pwd=bluehttps://pan.baidu.com/s/1ML0DC8s0RkkTAraN9maltw?pwd=blue

网页版在线测试性能Unity Web Player | rvo_gpuanim_brghttp://efunny.com.cn/gpu_animhttp://efunny.com.cn/gpu_animhttp://efunny.com.cn/gpu_anim

插件获取【万人同屏插件】

首页-游戏开发资源商店-淘宝网PC店铺https://shop106471535.taobao.com/https://shop106471535.taobao.com/https://shop106471535.taobao.com/

万人红蓝对抗项目​​​

Unity万人同屏 新版ECSGraphics pc 手机 性能测试 安卓也能万人同屏战斗了

测试环境

系统:Windows 11

Unity:Unity 2022.3.45f1

CPU: i7-13700KF

GPU: RTX 3070 8G

Unity万人同屏 新功能ECSGraphics接口用法 详解 性能 功能 大幅提升 简单易用保姆级使用教程

GPU动画插件(支持3D\2D Spine):

兼容性

纯Shader实现的GPU动画,超高性能。插件支持Unity全平台,兼容WebGL,可用于H5/小游戏开发。支持动画事件、保留骨骼信息(动态获得骨骼节点位置/旋转/缩放)、2D Spine半透物体渲染顺序、动画平滑融合过渡(Pro)、LOD生成(Pro)。

实现原理

由于Animator或Spine动画都是CPU计算,因此存在性能瓶颈、并且蒙皮动画无法合批渲染,DrawCall大幅降低帧数(以性能测试demo为例,1w个Animator仅有8 fps)。

GPU动画是把Animator转换为GPU计算, Shader中播放动画。使用MeshRenderer或BRG渲染,自动合批渲染,大幅降低DrawCall。以性能测试demo为例, 1w个GPU动画117 fps; 而使用BRG渲染GPU动画,帧数高达800 fps

一、3D动画转GPU动画 

1. GPU动画转换工具界面

通过Unity顶部菜单Game Framework->GPU Animation->GPU Animation Converter打开工具界面

 GPU动画转换工具面板:

①拖入需要转换的Animator/Animation预制体;

②动画模式:支持GPU骨骼动画和顶点动画;推荐骨骼动画,功能更强大;

③合并网格:合并Mesh降低DC, 对于Spine动画将进行排序,确保半透物体渲染排序正确;仅支持共用相同材质的网格合并,对于不同材质、多张贴图的物体,可通过三方插件Mesh Baker先合并材质/贴图,再转换GPU动画。

④Animator相关设置,默认值即可。 如是否冻结根骨骼位置/旋转等;

⑤选择GPU动画shader, Spine动画要选择2D shader;也可生成GPU动画后再切换材质shader;

⑥需要烘焙到GPU动画贴图的Animation Clips 工具默认添加Animator中引用的所有Animation Clip;通过列表的索引值切换动画状态;

⑦把需要运行时获取transform值的骨骼节点拖到此处 转换为GPU动画后仍能实时获取到骨骼transform值;  此功能可使转换为GPU动画后骨骼信息不丢失,比如可以实时获取头部、手部位置;

2. GPU动画工具用法

①把Animator或Animation动画角色预制体拖入场景;

②把拖入场景的预制体拖入GPU动画转换工具的Input栏;

③拖动Animation Clips列表元素,组织好自己的动画索引对应的动画(可选);

④把需要保留骨骼transform信息的节点拖到Record Bones列表;

⑤点击Convert按钮,转换为GPU动画;

3. GPU动画资源

转换后会生成以下GPU动画文件:

①动画贴图。记录着动画数据;

②GPU动画Prefab。将原动画Prefab中的SkinnedMeshRenderer转换为了MeshRenderer,同时拥有动画播放功能和自动合批渲染;

③GPU动画帧事件,用于GPU动画播放时触发动画事件。工具默认会把Animation Clip文件中添加Event事件转换为GPU动画帧事件;

④GPU动画材质,由于是纯shader实现,因此可以不依赖任何脚本,仅修改材质属性切换动画;

⑤GPU动画Mesh,Mesh中寄存了某些信息,以便GPU动画Shader读取使用;

4. 自定义GPU动画Shader 

 插件使用Shader GraphAmplify Shader Editor封装好了函数节点,只需添加GPU动画节点连接顶点位置、顶点法线即可轻松实现自定义Shader

使用Amplify Shader Editor
使用Shader Graph

对于使用BRG渲染需要向Shader传递参数的情况:

由于每个渲染节点在GPU中都有一块连续的内存,以高效访问。对于自定义Shader添加的每个渲染物体实例需要单独设置的shader字段,需要修改BatchRendererComponent代码,参考_ClipId进行扩展参数。

例如:新增一个Vector4类型作为预留参数以供传递数据:

0. 重新计算单个渲染物体占用内存:

由于新增了一个Vector4字段,因此内存新增了4个float大小,需修改BRGUtility.kBytesPerInstance大小:

每个渲染物占GPU内存:两个4x3矩阵 + BaseColor(4个float) + ClipId(4个float) + 新增Vector4字段(4个float):

public static readonly int kBytesPerInstance = kSizeOfPackedMatrix * 2 + kSizeOfFloat4 * 3;

1. 定义Shader Property字段名:

int objectToWorldID = Shader.PropertyToID("unity_ObjectToWorld");
int worldToObjectID = Shader.PropertyToID("unity_WorldToObject");
int colorID = Shader.PropertyToID("_BaseColor");
int clipIdID = Shader.PropertyToID("_ClipId");
int userVec4ID = Shader.PropertyToID("_UserdataVec4");//新增vector4字段

2. 计算新增字段的起始内存:

...
int clipIdIndex = colorIndex + batchInstanceCount;
int userdataVec4Index = clipIdIndex + batchInstanceCount;
var drawBatch = new SrpBatch
{
    ...
    clipIdIdx = clipIdIndex,
    userdataVec4Idx = userdataVec4Index
};

3. 重新计算metadata地址:

if (UseConstantBuffer)
{
    ...
    metadataValues[3] = CreateMetadataValue(clipIdID, (clipIdIndex - offsetInFloat4) * kSizeOfFloat4, true);
    metadataValues[4] = CreateMetadataValue(userVec4ID, (userdataVec4Index - offsetInFloat4) * kSizeOfFloat4, true);
}
else
{
    ...
    metadataValues[3] = CreateMetadataValue(clipIdID, clipIdIndex * kSizeOfFloat4, true);
    metadataValues[4] = CreateMetadataValue(userVec4ID, userdataVec4Index * kSizeOfFloat4, true);
}

4. 新增字段上传GPU:

修改UploadParallelJob代码,Ouput数据追加一行:

Output[srpBatch.userdataVec4Idx + j] = renderer.userdataVec4;

二、2D Spine转GPU动画

十代i5 + 1050显卡下依然性能强悍

实际上,只需要把Spine转换为Animator,就可以通过标题一的步骤把Animator转换为GPU动画

2d spine动画帧数提升数十倍?spine转gpu动画 2d spine动画 10w单位

1. Spine转Animator工具

①通过Unity顶部菜单栏 GameFramework->GPU Animation->Spine to Animator打开工具

②把Spine文件拖到工具,点击Bake按钮开始转换

Spine转Animator注意事项:

Spine独立实现了一些Animator不支持的特性,必须绕过这些特性才能完整转换为Animator后还原完整动画效果(不支持转换的关键帧是骨骼动画中非必要特性,可以轻松绕过)

烘焙骨骼不支持以下特性:
① 禁用旋转/缩放继承
② 局部错切变换
③ 所有约束类型
④ 绑定骨骼超过4根的权重顶点

烘焙动画不支持以下特性:
① 网格变形关键帧
② 颜色关键帧
③ 绘制顺序关键帧

2. Spine转GPU动画

 使用GPU Animation Converter把步骤1 Spine转换出的Animator预制体转换为GPU动画。

 注意:Spine通常是2D半透明物体,因此需要把GPU动画Shader切换为2D的Shader(如:GPUAnimation/2D/GPUBonesAnim2D)

三、GPU Animation LOD工具 [PRO版功能]

多线程渲染器支持LOD, 根据距离显示不同精度模型,大幅提升性能

1. 自动生成减面LODs

根据LOD 0 Mesh生成LOD 1~4简化Mesh; 

①此工具依赖三方插件MantisLOD,用于自动简化Mesh面数,同时尽量保留Mesh轮廓。安装MantisLOD后,解除代码GPUAnimationLODCreator.cs第一行注释即可使用功能:

#define ENABLE_MANTISLOD //安装MantisLOD插件后解除此行注释
...
#if ENABLE_MANTISLOD
using MantisLOD;
using MantisLODEditor;
#endif

②GameFramework->GPU Animation->GPU Animation LOD打开工具

2. 使用已有LOD Mesh生成(可选)

除了使用工具自动生成减面LOD Mesh, 当然也可以根据已有的Mesh直接生成LODs Mesh

四、武器挂载、动画事件、骨骼获取

武器挂载 帧事件 骨骼获取 视频教程

1. 武器挂载

①把武器作为GPU动画角色的子节点,修改材质shader为GPUAnimation/GPUAttachBoneLit,并将主角的动画贴图赋值到材质;

②通过修改武器材质的AttachBoneIndex来设置武器绑定到哪个骨骼

说明: 这里AttachBoneIndex对应的就是GPU动画工具界面RecordBones记录的骨骼节点索引

2. 动画事件

GPU动画事件触发时实时获取拳头骨骼位置

 转换GPU动画时会自动生成动画事件文件,如下图:

 默认情况下,工具是从Animation Clip文件读取动画事件,以key, value形式保存。key是触发帧,value是事件名。用户可直接修改此文件增删事件。

①. GPU动画帧事件用法:

使用GPUAnimation脚本,设置好Event Data:

 GPU动画事件实例代码:

using Cysharp.Threading.Tasks;
using GPUAnimation.Runtime;
using UnityEngine;

public class GPUAnimEventDemo : MonoBehaviour
{
    GPUAnimation.Runtime.GPUAnimation m_GPUAnim;

    private void Start()
    {
        m_GPUAnim = GetComponent<GPUAnimation.Runtime.GPUAnimation>();

        //添加GPU动画事件监听
        m_GPUAnim.Events.AddListener(OnGPUAnimEventCallback);

        m_GPUAnim.GPUAnimMaterial.SetVector("_ClipId", new Vector4(4, Time.time, 0, 0));
    }
    private void OnDestroy()
    {
        m_GPUAnim.Events.RemoveListener(OnGPUAnimEventCallback);
    }
    /// <summary>
    /// GPU动画事件回调
    /// </summary>
    /// <param name="clipIndex">动画index</param>
    /// <param name="frame">触发帧</param>
    /// <param name="eventName">事件名</param>
    private void OnGPUAnimEventCallback(int clipIndex, int frame, string eventName)
    {
        if (eventName == "DamageTrigger") //挥拳动画事件触发时在拳头位置发射小球
        {
            var boneData = GPUAnimationUtility.GetAttachBoneTransform(m_GPUAnim.GPUAnimMaterial, 1);//获取右手当前动画帧的位置
            GameObject ball = GameObject.CreatePrimitive(PrimitiveType.Sphere);
            ball.transform.localScale = Vector3.one * 0.2f;
            ball.transform.position = m_GPUAnim.transform.position + boneData.Position;

            _ = UniTask.Delay(1000).ContinueWith(() =>
            {
                Destroy(ball);
            });
            
        }
    }
}

②. BRG多线程渲染下GPU动画帧事件用法

为了应对海量单位下动画事件触发依然流畅,BRG组件专门提供了jobs多线程实现的事件触发检测函数:

public bool TryTriggerGPUAnimationEvents(out NativeQueue<GPUAnimTriggerInfo> triggerResults)

 代码示例:

 在Update中每帧调用,以批量检测动画事件触发

/// <summary>
/// 查询已经触发的GPU动画事件
/// </summary>
private void GPUAnimTriggerUpdate()
{
    if (BatchRendererComponent.Instance.TryTriggerGPUAnimationEvents(out var triggerResults))
    {
        while (triggerResults.TryDequeue(out var result))
        {
            if (m_Players.TryGetValue(result.AgentId, out BRG_Player unit))
            {
                //触发某个单位的GPU动画事件
                unit.OnGPUAnimationEvent(result.ResIndex, result.ClipIndex, result.TriggerAtFrame);
            }
        }
        triggerResults.Dispose();
    }
}

3. 骨骼获取

用于GPU动画运行时,实时获取某个骨骼节点的Transform信息;例如,角色持枪射击,子弹应从枪口位置创建发射(市面上其它GPU动画插件,转换GPU动画后骨骼信息全部丢失,无法获取枪口位置)。

GPUAnimationUtility类提供了多种获取当前GPU动画帧某个骨骼的transform信息的接口

例如,获取RecordBones记录的索引为1的骨骼transform信息:

GPUAnimationUtility.GetAttachBoneTransform(GPUAnimMaterial, 1);

 BRG多线程渲染接口同样提供了封装好的接口:

BatchRendererComponent.Instance.GetAnimationAttachBone(m_RendererNodeId, boneIndex)

五、动画平滑过渡、融合 [PRO版功能]

3D/2D Spine动画平滑切换,支持控制过渡时长

直接把GPU动画材质的Shader切换为支持平滑过渡的Shader即可,如:GPUAnimation/GPUBonesAnimMergeLit

ClipId:该参数用于切换动画,对于不支持动画融合的Shader, x是动画index, y是开始播放的时间(Time.time);

对于支持动画融合的Shader,z是上个动画的index,w是上个动画的播放时间,x是要切换到的动画index,y是动画第一帧开始的时间,也就是不算融合时间(Time.time + 动画过渡消耗时间)

AnimTransDration:动画平滑过渡(融合)速度

GPU动画使用限制

尽管已经实现大量GPU动画功能,但依然比不上高级动画系统的功能,如IK、Avatar Mask是不支持的。

由于GPU动画贴图储存动画信息有限,目前支持记录Transform信息和GameObject的显示隐藏。对于3D动画完全足够。但对于2D Spine动画,有时会记录特殊的关键帧,如修改颜色、修改贴图等,这些GPU动画是不支持的,但仍可以通过显示隐藏实现, 例如,皮肤A切换到皮肤B,可以通过隐藏皮肤A,显示皮肤B以实现换装功能。

ECSGraphics渲染器(最新更新)

随着Unity ECS方案逐步完善,目前已经不会频繁导致编辑器崩溃等问题,因此我们使用Entities Graphics高度封装了一套高性能渲染器用于平替之前的自定义BRG方案,虽然引入了ECS包,但同样不用写一行ECS代码,传统开发方式即可实现超高的渲染性能。提供更完善的功能,同时带来大幅性能提升,大家可以从文章开头下载Demo体验测试(PC和手机端都有不俗表现)。

ECSGraphics功能:

1. 支持子物体

比如给角色添加血条为子物体,就能跟随角色自动移动。解决之前BRG不支持子物体,想要添加武器还需要自行同步武器位置的问题。

2. 支持武器挂载,挂载点切换等。

我们的GPU动画方案支持挂载,但之前只能在Prefab模式使用武器挂载。现在我们直接支持将武器挂载到GPU动画主体,并支持动态切换挂载点,使武器跟随骨骼位置运动。

3. 不再限制最大创建数量

BRG版本固定内存长度,因此有数量限制。ECSGraphics渲染器无限数量、动态扩容。

4. LODs等级数量由BRG版本最大4级,ECSGraphics渲染器最大支持8级LOD。

5. 更好的支持半透明物体,同时性能翻倍。

6. RVO渲染同步、GPU动画事件检测等性能提升。

ECSGraphics用法: 

1. 注册要渲染的物体:

与使用BRG渲染器一样,需要将渲染的Mesh和Material添加到ECS Renders列表,如果有GPU动画事件也需要配置事件文件,如果需要LOD功能,则将不同等级mesh配置到LOD Renders列表。最大支持8个LOD等级。

2. 创建/销毁一个物体

先要渲染一个物体只需要调用Add方法, 移除Remove

var entity = ECSGraphicsComponent.Instance.Add(0, Vector3.zero, Quaternion.identity, 1);

ECSGraphicsComponent.Instance.Remove(entity);//移除指定物体
ECSGraphicsComponent.Instance.RemoveAll(); //移除全部

创建物体时也可以指定父节点,使其跟随父节点移动:

public Unity.Entities.Entity Add(int renderId, float3 pos, quaternion rot, float scale = 1, Unity.Entities.Entity parentEntity = default, int customId = 0)

 3. 添加/删除GPU动画挂载物体

可以将任意Mesh挂载到GPU动画物体的任意骨骼上,使挂载物跟随GPU动画骨骼运动。挂载物的Material需使用GPU动画提供的GPU动画的AttachBone shader。同时支持动态切换挂载到哪个骨骼。

比如给GPU动画玩家右手挂载一把枪:

player = ECSGraphicsComponent.Instance.Add(0, Vector3.zero, Quaternion.Euler(0, 180, 0), 3);
weapon = ECSGraphicsComponent.Instance.AddAttachment(2, player, 0, Vector3.zero, Quaternion.identity);

ECSGraphicsComponent.Instance.RemoveAttachment(player, weapon);//移除player身上的weapon挂载物
ECSGraphicsComponent.Instance.RemoveAllAttachments(player); //移除player身上所有挂载物体

 切换挂载点, 比如将武器从右手切换到左手:

ECSGraphicsComponent.Instance.SetAttachmentBoneIndex(weapon, boneindex);

4. 播放/平滑切换GPU动画:

ECSGraphicsComponent.Instance.PlayGPUAnimation(player, gpuAnimationClipIndex);

同时也支持切换动画时传入动画平滑过渡时间,若不传入过渡时间,程序将默认读取GPU动画shader材质上的 _AnimTransDuration字段配置的时间

public void PlayGPUAnimation(Unity.Entities.Entity entity, int animClipIndex, float animCrossFadeDuration)

5. GPU动画事件触发检测

全局只需要在一处Update中实时跳用GPU动画事件检测刷新函数ECSGraphicsComponent.Instance.GPUAnimationEventsUpdate(out var events),即可得到事件触发列表,批量对已触发事件做出响应.

void Update()
{
//GPU动画事件触发检测
    if (ECSGraphicsComponent.Instance.GPUAnimationEventsUpdate(out var events))
    {
        while (events.TryDequeue(out var eventInfo))
        {
            Debug.Log($">>>>>>>>>>>>>>动画事件触发: 动画clip:{eventInfo.ClipIndex}, entity:{eventInfo.ECSEntity}, 触发帧:{eventInfo.TriggerAtFrame}");
            //实时获取GPU动画骨骼的Transform信息
            var bone = ECSGraphicsComponent.Instance.GetGPUAnimationBone(player, 1);
            //在当前骨骼位置创建一个物体,并0.5秒后删除
            var ball = ECSGraphicsComponent.Instance.Add(1, bone.Position, bone.Rotation, 0.5f);
            UniTask.Delay(500).ContinueWith(() =>
            {
                ECSGraphicsComponent.Instance.Remove(ball);
            }).Forget();
        }
        events.Dispose();
    }
}

 此次渲染器升级相比BRG不仅增加了多项功能、更简单易用,同时性能也普遍大幅提升。

尤其是半透明物体渲染性能,BRG版本需要自行对半透明物体进行排序后渲染,对性能影响很大。

比如1万个2D GPU Spine动画,  红米K80P测试机下的表现,具体性能提升请见文章开头提供的demo下载:

ECSGraphics版手机端能达到最大限制帧数120帧:

ECSGraphics版120帧

BRG版手机端只有32帧

BRG版32帧

BRG多线程渲染(BatchRenderComponent)(已过时,最新版ECSGraphics平替):

使用Entities Graphics的底层接口BatchRendererGroup,自己组织内存、显存,利用Dots技术栈的高性能,使用Jobs多线程提交渲染数据到GPU,通过合批一次渲染大量单位,从而巨大提升渲染性能。

渲染10万个3D模型, 帧数148 fps

BRG多线程合批渲染 LODs功能用法

性能表现 

使用BRG组件渲染1w个GPU动画人物,800 fps

使用MeshRenderer渲染1w个GPU动画人物,117 fps:

直接Animator(SkinnedMeshRenderer)渲染1w个GPU动画人物, 10 fps:

一、注册要渲染的物体

 首先要把需要用BRG组件渲染的物体,添加到RendererResources列表。

1. Mesh, Material:把GPU动画转换工具生成的GPU动画文件(材质、Mesh)添加到Renderer Resources列表;

2. Capacity:该物体最大渲染数量,为了追求极致性能,BRG将根据最大渲染数量分配一片定长内存,以避免渲染单位数量变化导致重新分配存储拷贝数据造成性能消耗。

3. GPU Anim Event Data: GPU动画事件文件, 若该物体无动画事件可不设置;

4. Lod Distances:x,y,z,w分别为LOD 0 ~ 4各个等级的距离;距离越近显示的模型面数越高。此功能需勾选Enable LOD; 

5. 开启LOD功能:勾选Enable LOD, 然后把GPU Animation LOD工具生成合并后的LODs Mesh作为RendererResource的Mesh即可;

二、BatchRendererComponent接口用法

1. 添加一个物体

m_RendererId = BatchRendererComponent.Instance.AddRenderer(resId, pos, rotation, scale);

 其中,resId就是Renderer Resources列表中注册的渲染物的索引index;

返回值为RendererNodeId,可通过RendererNodeId设置渲染物的属性,如切换GPU动画:

BatchRendererComponent.Instance.SetRendererClipId(m_RendererId, animIndex);

2. 移除一个物体

BatchRendererComponent.Instance.RemoveRenderer(m_RendererId);

RVO多线程避让

Unity Dots 10万人同屏RVO避障是一种什么体验? 3D人物带动画,不使用ECS

1. 添加RVO单位

AddAgent()会返回一个RVOAgent对象,可通过此对象设置各种rvo参数

m_RVO = RVOComponent.Instance.AddAgent(position);

2. 移除RVO单位

RVOComponent.Instance.RemoveAgent(m_RVO);

3. RVO属性功能 

avoidWeight:避让权重,比如高级兵不给小兵让路,小兵需要给高级兵让路,以避免高级兵被小兵挡住的情况。只需设置avoidWeight,取值0-1,值越小越不让路。

searchRadius:寻敌半径

searchCount:寻敌数量,==1,单体攻击;>1, 群体攻击

targetPosition:移动目标点

camp:单位所属阵营,数据类型是位枚举,所以支持单个单位多个阵营(以满足用户特殊需要)

searchTag:标记自己的标签,数据类型是位枚举,支持标记多个标签;此标签配合ignoreSearchTag使用,用于精准控制寻敌过滤目标;例如:敌方阵营有个飞行单位,我方阵营的近战单位虽然属于敌对阵营,但近战单位不可能攻击到高空飞行目标。

ignoreSearchTag:寻敌时忽略掉ignoreSearchTag位枚举中包含的searchTag,用于精准控制筛选寻敌

collisionEnabled:rvo单位之间是否碰撞,为false时rvo之间将会重叠穿模

navigationEnabled:rvo单位是否自动移动,设为false后,即可通过rvo的position来随意设置位置;例如:击飞效果,单位受到攻击后被击飞,就可以通过设置navigationEnabled为false,然后自行设置position实现击飞效果,落地后再设置navigationEnabled为true即可从击飞落地位置重新移动。

4. 障碍物

①添加圆形障碍物:把CircleObstacle脚本挂到障碍物GameObject上即可

②添加举行障碍物:把BoxObstacle脚本挂到障碍物GameObject上即可

③添加边界障碍物:把EdgeObstacle脚本挂到障碍物GameObject上即可,通过面板参数添加边界顶点位置

④扩展自定义障碍物:自定义类继承ShapeObstacleBase,重写方法即可

海量单位多线程寻敌/碰撞检测:

Unity弹幕游戏, RVO红蓝对抗 割草游戏 海量单位高性能索敌攻击方案压测

方案是通过Jobs多线程批量查询单位,支持查询最近单位、范围内单位等,通过RVOComponent提供的接口查询

具体使用方法可参考插件提供的demo, EnemiesSearchDemo.cs

1. 查询最近单位

SearchAgentsNearest:查询最近的单位

2. 查询范围内目标

SearchAgentsWithin:查询半径内的目标,返回数量为rvo的searchCount,也支持指定个数

3. 查询范围内多目标(AOE) 

var ids = rvo.SearchAgentsWithin(tempQueryPoints, damageRadius, maxDamageCount);
for (int i = 0; i < ids.Length; i += maxDamageCount)
{
    int indexOffset = i * maxDamageCount;
    for (int j = 0; j < maxDamageCount; j++)
    {
        int agentId = ids[indexOffset + j];
        if (agentId <= 0) break;

        if (m_Players.ContainsKey(agentId))
        {
            m_Players[agentId].ApplyDamage(100);
        }
    }
}

注意事项:

一、BRG跨平台兼容性

BRG兼容性可参考官方文档:Unity - Manual: Getting started with BatchRendererGrouphttps://docs.unity3d.com/2022.3/Documentation/Manual/batch-renderer-group-getting-started.htmlhttps://docs.unity3d.com/2022.3/Documentation/Manual/batch-renderer-group-getting-started.htmlhttps://docs.unity3d.com/2022.3/Documentation/Manual/batch-renderer-group-getting-started.html

渲染管线:目前支持URP、HDRP、自定义SRP

兼容平台:目前不支持WebGL

  • Windows using DirectX 11
  • Windows using DirectX 12
  • Windows using Vulkan
  • Universal Windows Platform
  • Linux using Vulkan
  • macOS using Metal
  • iOS
  • Android (Vulkan and OpenGL ES 3.x)
  • PlayStation 4
  • PlayStation 5
  • Xbox One
  • Xbox Series X and Xbox Series S
  • Nintendo Switch
  • Google Stadia

二、打包设置

1. URP Rendering Path选择Forward+ (Forward+才能发挥BRG最大性能)

2. BatchRendererGroup Shader变体选择 Keep All

3. 打包后GPU Spine动画渲染顺序异常

BatchRendererComponent在Unity6下开启渲染排序(Sorting Position)后,编辑器下渲染顺序正常,打包后渲染顺序错误:

猜测这是BatchRendererGroup的bug,当项目只使用一个场景,没有任何场景切换时就会复现这个bug;

解决方法:使用两个场景,例如:场景A是空场景, 场景B是游戏场景,游戏开始后Additional方式加载场景B或者切换到场景B,这样渲染顺序就不会出现异常。

4. 打包WebGL

常见问题1:编辑器或其它平台正常,打包WebGL渲染异常;

解决方法:如果PlayerSettings设置的为WebGL 1,Shader Model需设置为2.0;WebGL2可设置Shader Model为3.0.

使用Amplify Shader Editor打开GPU动画Shader,设置Shader Model: 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值