一、需求:
需要做基於BIM的大場景展示,先不提功能,模型展示就是個問題。基本核心的優化是LOD,把Revit通過3dmax轉換,處理,分解成一個個模型單元,再在Unity中進行場景重建。這個已經完成了。在Unity中再結合LOD,能夠一定程度上優化性能,提高幀率,但是不夠。現在是1000w個點,從15FPS提高到25FPS,這時因爲用了LOD,內存中有2000w個點了。
在路上開車開車就想起了ECS,是否能夠用這種宣傳上適合大規模重複類似行爲的場景的技術來動態控制模型的LOD呢,而且我還需要從內存中動態加載卸載模型的功能。
第一次知道ECS是半年前了,雖然公司的Unity也升級到2019.3了,但是一直沒有時間好好學習一下ECS。其實應該說是找不到必要性吧,最近學了Maxscript和Revit二次開發,說明時間不是問題,優先級纔是原因。有必要,任何技術都會馬上去學習的。另外UE5宣傳片看到了,似乎能完全解決大量模型加載的問題,下次去學一下吧。
二、學習與練習
現在學習東西都是在B站上了,https://www.bilibili.com/video/BV1W54y197sb?from=search&seid=16767424865285994023,
把視頻的內容整理一下,同時把碰到的問題記錄一下。
1.安裝需要的包
這裏就碰到一個問題,Burst安裝後,會出現問題:
The type or namespace name 'CompilerServices' does not exist in the namespace
總共有好幾條,google了一下,參考:https://forum.unity.com/threads/missing-references-in-the-collections-package.847027/,將Burst升級到最新版本1.3.0,默認安裝的是verified-1.2.3版本
-------------------------------------------------------------------------------------------------------
官方例子:https://github.com/Unity-Technologies/EntityComponentSystemSamples
安裝一個就行,已經安裝了,就沒操作過了。
2.ComponentSystem / JobComponentSystem / SystemBase
最上面的視頻中的代碼是用ComponentSystem
public class LevelUpSystem : ComponentSystem
{
protected override void OnUpdate()
{
Entities.ForEach((ref LevelComponent levelComponent) =>
{
levelComponent.Level += 1f * Time.DeltaTime;
});
}
}
public struct LevelComponent : IComponentData
{
public float Level;
}
另一個教程裏面的是JobComponentSystem
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Unity.Entities;
using Unity.Jobs;
using Unity.Transforms;
using System;
//public class VelocityScript : MonoBehaviour,IConvertGameObjectToEntity
//{
// public float Value;
// public void Convert(Entity entity, EntityManager dstManager, GameObjectConversionSystem conversionSystem)
// {
// dstManager.AddComponent<Velocity>(entity);
// dstManager.SetComponentData(entity,new Velocity(){ Value=Value});
// }
//}
[GenerateAuthoringComponent]
struct Velocity:IComponentData
{
public float Value;
}
class ApplyVelocitySystem : JobComponentSystem
{
//struct ApplyVelocityJob : IJobForEach<Translation, Velocity>
//{
// public float deltaTime;
// public void Execute(ref Translation translation, ref Velocity velocity)
// {
// translation.Value += velocity.Value * deltaTime;
// }
//}
protected override JobHandle OnUpdate(JobHandle inputDeps)
{
//var job = new ApplyVelocityJob();
//job.deltaTime = Time.DeltaTime;
//return job.Schedule(this, inputDeps);
float deltaTime = Time.DeltaTime;
return Entities.ForEach((ref Translation translation, in Velocity velocity) =>
{
translation.Value += velocity.Value * deltaTime;
}).Schedule(inputDeps);
}
}
這個視頻是官方(中國)講解2019.3的,應該是比較新的。
然後查詢了一下二則的區別,unity論壇中提到SystemBase(https://forum.unity.com/threads/jobcomponentsystem-vs-componentsystem-for-singlethread.850381/#post-5610469)。
測試了一下,2w個Capsule物體移動, 感覺ComponentSystem最慢了 15-20FPS,JobComponentSystem和SystemBase都是25-35。
有人專門也問了一下用哪裏(https://forum.unity.com/threads/is-there-any-difference-between-systembase-jobcomponentsystem-and-componentsystem-anymore.892978/#post-5868991),樓主很較真,有點爭執,就是不求甚解聽官方的就行和一定要知道爲什麼的人之間的爭執。反正,結論就是用 SystemBase,另外兩個遲早會被刪除掉。
現在的Unity.Entities(preview.6-0.10.0)的文檔中就是這麼說的(https://docs.unity3d.com/Packages/[email protected]/manual/ecs_systems.html?_ga=2.71828115.1406000335.1590492138-1802642859.1577498182)。
SystemBase的話,還有的問題,用Run()還是Schedule(),還是ScheduleParallel()?
3.Samples
有個博客寫的不錯,https://blog.csdn.net/qq_30137245/article/details/99071697,就按照這個順序學習,磨刀不誤砍柴工,前期學的越充分,動起手來越順手。
三、問題