Megacity demo game for UOS
您最多选择25个主题 主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

181 行
7.2 KiB

using Unity.Burst;
using Unity.Collections;
using Unity.Entities;
using Unity.Jobs;
using Unity.Mathematics;
using Unity.Transforms;
using Hash128 = Unity.Entities.Hash128;
namespace Unity.MegaCity.Streaming
{
/// <summary>
/// Set of jobs to handle streaming in/out of sub scenes
/// </summary>
[BurstCompile]
public partial struct StreamSubScenesIn : IJobEntity
{
public NativeList<Entity> AddRequestList;
public float3 CameraPosition;
public float MaxDistanceSquared;
public void Execute(Entity entity, in SceneSectionData sceneData)
{
AABB boundingVolume = sceneData.BoundingVolume;
var distanceSq = boundingVolume.DistanceSq(CameraPosition);
if (distanceSq < MaxDistanceSquared)
AddRequestList.Add(entity);
}
}
[BurstCompile]
public partial struct StreamSubScenesOut : IJobEntity
{
public NativeList<Entity> RemoveRequestList;
public float3 CameraPosition;
public float MaxDistanceSquared;
public Hash128 PlayerSectionGUID;
public void Execute(Entity entity, in SceneSectionData sceneData)
{
if (sceneData.SceneGUID == PlayerSectionGUID)
return;
AABB boundingVolume = sceneData.BoundingVolume;
var distanceSq = boundingVolume.DistanceSq(CameraPosition);
if (distanceSq > MaxDistanceSquared)
RemoveRequestList.Add(entity);
}
}
[BurstCompile]
public struct BuildCommandBufferJob : IJob
{
public EntityCommandBuffer CommandBuffer;
public NativeArray<Entity> AddRequestArray;
public NativeArray<Entity> RemoveRequestArray;
public void Execute()
{
foreach (var entity in AddRequestArray)
{
CommandBuffer.AddComponent(entity, new RequestSceneLoaded { LoadFlags = SceneLoadFlags.LoadAdditive });
}
foreach (var entity in RemoveRequestArray)
{
CommandBuffer.RemoveComponent<RequestSceneLoaded>(entity);
}
}
}
[BurstCompile]
[UpdateInGroup(typeof(InitializationSystemGroup))]
[WorldSystemFilter(WorldSystemFilterFlags.LocalSimulation | WorldSystemFilterFlags.ClientSimulation)]
public partial struct StreamingLogicSystem : ISystem
{
private EntityQuery _query;
public void OnCreate(ref SystemState state)
{
state.RequireForUpdate<StreamingConfig>();
_query = state.GetEntityQuery(ComponentType.ReadOnly<LocalToWorld>(),
ComponentType.ReadOnly<StreamingConfig>());
}
public void OnUpdate(ref SystemState state)
{
state.CompleteDependency();
var entityCommandBufferSystem =
state.World.GetExistingSystemManaged<BeginInitializationEntityCommandBufferSystem>();
var streamingLogicConfig = _query.GetSingleton<StreamingConfig>();
var cameraPosition = _query.GetSingleton<LocalToWorld>().Position;
var addRequestList = new NativeList<Entity>(Allocator.TempJob);
var removeRequestList = new NativeList<Entity>(Allocator.TempJob);
var streamIn = new StreamSubScenesIn
{
AddRequestList = addRequestList,
CameraPosition = cameraPosition,
MaxDistanceSquared = streamingLogicConfig.DistanceForStreamingIn *
streamingLogicConfig.DistanceForStreamingIn
};
state.Dependency = streamIn.Schedule(state.Dependency);
var streamOut = new StreamSubScenesOut
{
RemoveRequestList = removeRequestList,
CameraPosition = cameraPosition,
MaxDistanceSquared = streamingLogicConfig.DistanceForStreamingOut *
streamingLogicConfig.DistanceForStreamingOut,
PlayerSectionGUID = streamingLogicConfig.PlayerSectionGUID,
};
state.Dependency = streamOut.Schedule(state.Dependency);
state.Dependency = new BuildCommandBufferJob
{
CommandBuffer = entityCommandBufferSystem.CreateCommandBuffer(),
AddRequestArray = addRequestList.AsDeferredJobArray(),
RemoveRequestArray = removeRequestList.AsDeferredJobArray()
}.Schedule(state.Dependency);
entityCommandBufferSystem.AddJobHandleForProducer(state.Dependency);
addRequestList.Dispose(state.Dependency);
removeRequestList.Dispose(state.Dependency);
}
}
[BurstCompile]
[UpdateInGroup(typeof(InitializationSystemGroup))]
[WorldSystemFilter(WorldSystemFilterFlags.Presentation)]
public partial struct ServerStreamingLogicSystem : ISystem
{
private EntityQuery m_Query;
public void OnCreate(ref SystemState state)
{
state.RequireForUpdate<StreamingConfig>();
m_Query = state.GetEntityQuery(ComponentType.ReadOnly<LocalToWorld>(),
ComponentType.ReadOnly<StreamingConfig>());
}
public void OnUpdate(ref SystemState state)
{
var entityCommandBufferSystem =
state.World.GetExistingSystemManaged<BeginInitializationEntityCommandBufferSystem>();
var streamingLogicConfig = m_Query.GetSingleton<StreamingConfig>();
var cameraPosition = m_Query.GetSingleton<LocalToWorld>().Position;
var addRequestList = new NativeList<Entity>(Allocator.TempJob);
var removeRequestList = new NativeList<Entity>(Allocator.TempJob);
var streamIn = new StreamSubScenesIn
{
AddRequestList = addRequestList,
CameraPosition = cameraPosition,
MaxDistanceSquared = streamingLogicConfig.DistanceForStreamingIn *
streamingLogicConfig.DistanceForStreamingIn
};
state.Dependency = streamIn.Schedule(state.Dependency);
var streamOut = new StreamSubScenesOut
{
RemoveRequestList = removeRequestList,
CameraPosition = cameraPosition,
MaxDistanceSquared = streamingLogicConfig.DistanceForStreamingOut *
streamingLogicConfig.DistanceForStreamingOut,
PlayerSectionGUID = streamingLogicConfig.PlayerSectionGUID,
};
state.Dependency = streamOut.Schedule(state.Dependency);
state.Dependency = new BuildCommandBufferJob
{
CommandBuffer = entityCommandBufferSystem.CreateCommandBuffer(),
AddRequestArray = addRequestList.AsDeferredJobArray(),
RemoveRequestArray = removeRequestList.AsDeferredJobArray()
}.Schedule(state.Dependency);
entityCommandBufferSystem.AddJobHandleForProducer(state.Dependency);
addRequestList.Dispose(state.Dependency);
removeRequestList.Dispose(state.Dependency);
}
}
}