之前的博客中我们为了绕过ECS架构,相当于单独用Batch Renderer Group实现了一个精简版的Entities Graphics,又使用Jobs版RVO2实现了10w人同屏避障移动。
万人同屏对抗割草 性能测试 PC 手机端 性能表现 弹幕游戏 海量单位同屏渲染 锁敌 避障 非ECS
那么有没有高性能的物理方案呢?当然。万人同屏方案中我们使用RVO接管了移动,使用Jobs批量将RVO坐标同步到BRG中渲染,成功实现了数万人同屏。同样的,数万物理刚体只需要一个jobs版物理引擎,把物理引擎的计算结果(坐标、旋转)同步到BRG渲染,就同样能做到数万物理刚体同屏。
Unity Entities(ECS)方案提供了两套基于jobs的高性能物理引擎,Unity Physics和Havok Physics,其中Havok Physics想必开发者都有所耳闻,据网上消息,现象级游戏《塞尔达-王国之泪》逆天的物理效果就是基于Havok Physics做的修改。
先把物理引擎跑起来看看效果吧:
先下载官方案例:https://github.com/Unity-Technologies/EntityComponentSystemSamples/tree/master/PhysicsSamples
1. 先制作一个模型prefab,并添加Physics Shape(碰撞体)、Physics Body(刚体)以及ECS特有的Authoring脚本, PhysicsRenderEntity,用于把此刚体prefab转换为Entity。
2. 添加PhysicsStep脚本(物理引擎)
Simulation Type:可以一键切换物理引擎,同时安装com.havok.physics和com.unity.physics两个物理引擎后就可以在这里切换,选择使用哪套引擎。
MultiThreaded:多线程计算一定要勾选。
3. 写一个JobSystem脚本,一直创建物理单位,以测试两套物理引擎的性能:
代码很简单,就不做解释了,直接上代码:
限制刚体上限为2w.
using Unity.Entities;
using Unity.Mathematics;
using Unity.Physics.GraphicsIntegration;
using Unity.Transforms;
public partial class SpawnEntitiesSystem : SystemBase
{
static float m_Timer;
public static int Count { get; private set; }
protected override void OnCreate()
{
base.OnCreate();
Count = 0;
}
protected override void OnUpdate()
{
var ecbSingleton = SystemAPI.GetSingleton<BeginSimulationEntityCommandBufferSystem.Singleton>();
var ecb = ecbSingleton.CreateCommandBuffer(this.World.Unmanaged);
if ((m_Timer += SystemAPI.Time.DeltaTime) > 0.2f)
{
m_Timer = 0;
foreach (var data in SystemAPI.Query<PhysicsRenderEntity>())
{
for (int i = 0; i < 30; i++)
{
var spawnPoint = new float3(0, 100 + i, 0);
var entity = ecb.Instantiate(data.Entity);
ecb.SetComponent(entity, LocalTransform.FromPosition(spawnPoint));
}
Count += 30;
break;
}
if (Count > 20000)
{
this.Enabled = false;
}
}
}
}
4. 在文本上实时显示物理单位数量:
using UnityEngine;
using UnityEngine.UI;
public class DisplayCount : MonoBehaviour
{
[SerializeField] Text m_Text;
// Update is called once per frame
void Update()
{
m_Text.text = SpawnEntitiesSystem.Count.ToString();
}
}
性能测试:
测试环境比较恶劣,古董机。i5 十代 + 1050Ti, 越恶劣的环境越能体现性能差距。
Unity Physics:
Unity Physics,作为官方物理引擎表现差强人意,2w单位,15帧左右:
Havok Physics:
2w单位,38帧左右,这个硬件配置下,可以说是逆天了。
总结:
Havok Physics不愧为老牌物理引擎,2w单位下帧数竟然是Unity Physics的2.5倍。
我们不需要ECS的渲染,那么就可以把第1步的模型Prefab改为空GameObject挂载刚体和碰撞体,这样就可以纯数据物理模拟,我们只需要把空Entity的物理坐标和旋转数值同步到我们的万人同屏方案BRG渲染组件中即可实现海量物理单位同屏,同时绕过ECS的开发方式。