public void Execute(CollisionEvent collisionEvent) { CollisionEvent.Details collisionEventDetails = default; var aHasDetails = false; var bHasDetails = false; if (collisionEventsReceiverPropertiesFromEntity .HasComponent(collisionEvent.EntityA)) { aHasDetails = collisionEventsReceiverPropertiesFromEntity[collisionEvent.EntityA] .UsesCollisionDetails; } if (collisionEventsReceiverPropertiesFromEntity .HasComponent(collisionEvent.EntityB)) { bHasDetails = collisionEventsReceiverPropertiesFromEntity[collisionEvent.EntityB] .UsesCollisionDetails; } if (aHasDetails || bHasDetails) { collisionEventDetails = collisionEvent.CalculateDetails(ref physicsWorld); } if (collisionEventBufferFromEntity.HasComponent(collisionEvent.EntityA)) { ProcessForEntity( collisionEvent.EntityA, collisionEvent.EntityB, collisionEvent.Normal, aHasDetails, collisionEventDetails ); } if (collisionEventBufferFromEntity.HasComponent(collisionEvent.EntityB)) { ProcessForEntity( collisionEvent.EntityB, collisionEvent.EntityA, collisionEvent.Normal, bHasDetails, collisionEventDetails ); } }
public void Execute(TriggerEvent triggerEvent) { if (triggers.HasComponent(triggerEvent.EntityA)) { triggers[triggerEvent.EntityA].Add(new TriggerBuffer { entity = triggerEvent.EntityB }); } if (triggers.HasComponent(triggerEvent.EntityB)) { triggers[triggerEvent.EntityB].Add(new TriggerBuffer { entity = triggerEvent.EntityA }); } }
public void Execute(CollisionEvent collisionEvent) { if (Collisions.HasComponent(collisionEvent.EntityA)) { Collisions[collisionEvent.EntityA].Add(new CollisionBuffer { entity = collisionEvent.EntityB }); } if (Collisions.HasComponent(collisionEvent.EntityB)) { Collisions[collisionEvent.EntityB].Add(new CollisionBuffer { entity = collisionEvent.EntityA }); } }
protected override void OnUpdate() { BufferFromEntity <TweenDestroyCommand> destroyBufferFromEntity = GetBufferFromEntity <TweenDestroyCommand>(true); EndSimulationEntityCommandBufferSystem endSimECBSystem = World.GetOrCreateSystem <EndSimulationEntityCommandBufferSystem>(); EntityCommandBuffer.ParallelWriter parallelWriter = endSimECBSystem.CreateCommandBuffer().AsParallelWriter(); Entities .WithReadOnly(destroyBufferFromEntity) .WithAll <TweenStopCommand>() .ForEach((int entityInQueryIndex, Entity entity, ref DynamicBuffer <TweenState> tweenBuffer) => { for (int i = 0; i < tweenBuffer.Length; i++) { TweenState tween = tweenBuffer[i]; if (!destroyBufferFromEntity.HasComponent(entity)) { parallelWriter.AddBuffer <TweenDestroyCommand>(entityInQueryIndex, entity); } parallelWriter.AppendToBuffer(entityInQueryIndex, entity, new TweenDestroyCommand(tween.Id)); } parallelWriter.RemoveComponent <TweenStopCommand>(entityInQueryIndex, entity); if (HasComponent <TweenPause>(entity)) { parallelWriter.RemoveComponent <TweenPause>(entityInQueryIndex, entity); } }).ScheduleParallel(); endSimECBSystem.AddJobHandleForProducer(Dependency); }
protected override void OnUpdate() { BufferFromEntity <HighlightTile> highlightTilesFromEntity = GetBufferFromEntity <HighlightTile>(false); Entities.ForEach((Entity entity, ref Translation trans, ref CursorData cursorData) => //remove ref trans later it doesn't need to be ref { if (highlightTilesFromEntity.HasComponent(entity)) { DynamicBuffer <HighlightTile> highlightTiles = highlightTilesFromEntity[entity]; Point pointInfo = new Point((ushort)((trans.Value.x) / cursorData.tileSize), (ushort)((trans.Value.z) / cursorData.tileSize)); cursorData.currentHoverPoint = pointInfo; for (int i = 0; i < highlightTiles.Length; i++) { if (highlightTiles[i].state == (ushort)MapLayer.Hover) { highlightTiles[i] = new HighlightTile { point = new Point((ushort)((trans.Value.x) / cursorData.tileSize), (ushort)((trans.Value.z) / cursorData.tileSize)), state = (ushort)MapLayer.Hover }; //Realistically there should only be one hover tile... break; } } } }).Run(); }
void ChildLocalToWorld(float4x4 parentLocalToWorld, Entity entity, bool updateChildrenTransform) { updateChildrenTransform = updateChildrenTransform || LocalToParentFromEntity.DidChange(entity, LastSystemVersion); float4x4 localToWorldMatrix; if (updateChildrenTransform && LocalToWorldWriteGroupMask.Matches(entity)) { var localToParent = LocalToParentFromEntity[entity]; localToWorldMatrix = math.mul(parentLocalToWorld, localToParent.Value); LocalToWorldFromEntity[entity] = new LocalToWorld { Value = localToWorldMatrix }; } else //This entity has a component with the WriteGroup(LocalToWorld) { localToWorldMatrix = LocalToWorldFromEntity[entity].Value; updateChildrenTransform = updateChildrenTransform || LocalToWorldFromEntity.DidChange(entity, LastSystemVersion); } if (ChildFromEntity.HasComponent(entity)) { var children = ChildFromEntity[entity]; for (int i = 0; i < children.Length; i++) { ChildLocalToWorld(localToWorldMatrix, children[i].Value, updateChildrenTransform); } } }
private void RecurseChildrenAndDisabled(Entity entity) { if (!Children.HasComponent(entity)) { return; } var children = Children[entity].AsNativeArray(); for (int i = 0; i < children.Length; i++) { var child = children[i].Value; CmdBuffer.AddComponent <Disabled>(child); CmdBuffer.AddComponent <UpdateVertexColorTag>(child); RecurseChildrenAndDisabled(child); } }
public void Execute(Entity msgEntity, DynamicBuffer <CloseTarget> b0) { var buffer = b0.AsNativeArray(); for (int i = 0; i < buffer.Length; i++) { var targetEntity = buffer[i].Value; // Check the metadata of the entity and update its state var root = HierarchyUtils.GetRoot(targetEntity, Parents); var activeStates = Metadata[root]; if (activeStates.Value.TryGetValue(targetEntity, out bool isActive)) { isActive = !isActive; activeStates.Value[targetEntity] = isActive; } if (isActive && Disabled.HasComponent(targetEntity) && (ShowButtons.HasComponent(msgEntity) || ToggleButtons.HasComponent(msgEntity))) { CmdBuffer.RemoveComponent <Disabled>(targetEntity); CmdBuffer.AddComponent <EnableRenderingTag>(targetEntity); if (LocalVertices.HasComponent(targetEntity)) { CmdBuffer.AddComponent <UpdateVertexColorTag>(targetEntity); } RecurseChildrenAndEnable(targetEntity, ref activeStates.Value); } if (!isActive && (CloseButtons.HasComponent(msgEntity) || ToggleButtons.HasComponent(msgEntity))) { CmdBuffer.AddComponent <Disabled>(targetEntity); if (LocalVertices.HasComponent(targetEntity)) { CmdBuffer.AddComponent <UpdateVertexColorTag>(targetEntity); } RecurseChildrenAndDisabled(targetEntity); } } }
public static bool TryGetBufferFromEntity <T>(this BufferFromEntity <T> bufferFromEntity, Entity entity, out DynamicBuffer <T> buffer) where T : struct, IBufferElementData { if (bufferFromEntity.HasComponent(entity)) { buffer = bufferFromEntity[entity]; return(true); } buffer = default; return(false); }
public void Execute(CollisionEvent collisionEvent) { if (m_collisions.HasComponent(collisionEvent.EntityA)) { var buffer = new CollisionBuffer() { entity = collisionEvent.EntityB, }; m_collisions[collisionEvent.EntityA].Add(buffer); } if (m_collisions.HasComponent(collisionEvent.EntityB)) { var buffer = new CollisionBuffer() { entity = collisionEvent.EntityA, }; m_collisions[collisionEvent.EntityB].Add(buffer); } }
public void Execute(TriggerEvent triggerEvent) { //players[collisionEvent.EntityA] //add a collision pair to our collisionBuffer so it can be acted on by the CollisionSystem.OnUpdate() if (triggers.HasComponent(triggerEvent.EntityA)) { triggers[triggerEvent.EntityA].Add(new TriggerBuffer() { entity = triggerEvent.EntityB }); } if (triggers.HasComponent(triggerEvent.EntityB)) { triggers[triggerEvent.EntityB].Add(new TriggerBuffer() { entity = triggerEvent.EntityA }); } }
public void Execute(TriggerEvent triggerEvent) { if (m_triggers.HasComponent(triggerEvent.EntityA)) { var buffer = new TriggerBuffer() { entity = triggerEvent.EntityB, }; m_triggers[triggerEvent.EntityA].Add(buffer); } if (m_triggers.HasComponent(triggerEvent.EntityB)) { var buffer = new TriggerBuffer() { entity = triggerEvent.EntityA, }; m_triggers[triggerEvent.EntityB].Add(buffer); } }
public void Execute() { var parents = UniqueParents.GetKeyArray(Allocator.Temp); for (int i = 0; i < parents.Length; i++) { var parent = parents[i]; if (!ChildFromEntity.HasComponent(parent)) { ParentsMissingChild.Add(parent); } } }
public static Entity GetRootEntity <T>( Entity entity, ComponentDataFromEntity <Parent> parentFromEntity, BufferFromEntity <T> bufferFromEntity) where T : struct, IBufferElementData { if (!parentFromEntity.HasComponent(entity) || bufferFromEntity.HasComponent(entity)) { return(entity); } else { return(GetRootEntity(parentFromEntity[entity].Value, parentFromEntity, bufferFromEntity)); } }
public void Execute(CollisionEvent collisionEvent) { //players[collisionEvent.EntityA] //add a collision pair to our collisionBuffer so it can be acted on by the CollisionSystem.OnUpdate() if (collisions.HasComponent(collisionEvent.EntityA)) { collisions[collisionEvent.EntityA].Add(new CollisionBufferData() { entity = collisionEvent.EntityB }); } if (collisions.HasComponent(collisionEvent.EntityB)) { collisions[collisionEvent.EntityB].Add(new CollisionBufferData() { entity = collisionEvent.EntityA }); } }
private void EnableSelectionReentrant(Entity entity) { BufferFromEntity <Child> cb = GetBufferFromEntity <Child>(); if (cb.HasComponent(entity)) { DynamicBuffer <Child> children = GetBuffer <Child>(entity); foreach (var c in children) { EnableFresnel(c.Value); EnableSelectionReentrant(c.Value); } } }
void DestroyHierarchy(EntityCommandBuffer.ParallelWriter cmdBuffer, Entity entity, int index, BufferFromEntity <Child> childrenFromEntity) { cmdBuffer.DestroyEntity(index, entity); if (!childrenFromEntity.HasComponent(entity)) { return; } var children = childrenFromEntity[entity]; for (var i = 0; i < children.Length; ++i) { DestroyHierarchy(cmdBuffer, children[i].Value, index, childrenFromEntity); } }
public void Execute() { for (int i = 0; i < Parents.Length; i++) { var parent = Parents[i]; if (!EquipmentLists.HasComponent(parent)) { continue; } var equipmentList = EquipmentLists[parent]; equipmentList.Add(Equipments[i]); } }
private int GetLinkedEntitiesCount(BufferFromEntity <LinkedEntityGroup> linkedFE, NativeArray <Entity> roots) { int count = 0; for (int i = 0; i < roots.Length; i++) { if (linkedFE.HasComponent(roots[i])) { count += linkedFE[roots[i]].Length; } else { count++; } } return(count); }
void ChildLocalToWorld(float4x4 parentLocalToWorld, Entity entity) { var localToParent = LocalToParentFromEntity[entity]; var localToWorldMatrix = math.mul(parentLocalToWorld, localToParent.Value); LocalToWorldFromEntity[entity] = new LocalToWorld { Value = localToWorldMatrix }; if (ChildFromEntity.HasComponent(entity)) { var children = ChildFromEntity[entity]; for (int i = 0; i < children.Length; i++) { ChildLocalToWorld(localToWorldMatrix, children[i].Value); } } }
private void GetLinkedEntitiesFill(BufferFromEntity <LinkedEntityGroup> linkedFE, NativeArray <Entity> roots, NativeArray <Entity> entities) { int count = 0; for (int i = 0; i < roots.Length; i++) { if (linkedFE.HasComponent(roots[i])) { var currentGroup = linkedFE[roots[i]]; NativeArray <Entity> .Copy(currentGroup.AsNativeArray().Reinterpret <Entity>(), 0, entities, count, currentGroup.Length); count += currentGroup.Length; } else { entities[count] = roots[i]; count++; } } }
protected override void OnUpdate() { var ecbSync = m_EndSimulationEcbSystem.CreateCommandBuffer(); var ecb = m_EndSimulationEcbSystem.CreateCommandBuffer().AsParallelWriter(); BufferFromEntity <ChildBufferElement> buffersOfAllEntities = GetBufferFromEntity <ChildBufferElement>(false); var mapper = World.GetExistingSystem <SyncSendSystem>().Sender.Mapper; Entities .WithNone <ConnectedInitialized>() .ForEach((Entity entity, in ConnectedEntity connected) => { var val = connected.value; var parent = mapper.ToUnityEntity(val); if (HasComponent <Mapped>(parent)) { // checksb for parent existence DynamicBuffer <ChildBufferElement> bufferOfOneEntity; if (!buffersOfAllEntities.HasComponent(parent)) { bufferOfOneEntity = ecbSync.AddBuffer <ChildBufferElement>(parent); } else { bufferOfOneEntity = buffersOfAllEntities[parent]; } var index = bufferOfOneEntity.Add(new ChildBufferElement { Value = entity }); ecbSync.AddComponent(entity, new ConnectedInitialized { Index = index }); } }) .WithoutBurst() .Run(); m_EndSimulationEcbSystem.AddJobHandleForProducer(this.Dependency); }
private void ProcessEntityPair(Entity entityA, Entity entityB) { if (ActionOnContacts.HasComponent(entityA)) { DynamicBuffer <ActionOnColliderContact> actions = ActionOnContacts[entityA]; ActorFilterInfo entityAInfo = Helpers.GetActorFilterInfo(entityA, Teams, FirstInstigators, TileColliderTags); ActorFilterInfo entityBInfo = Helpers.GetActorFilterInfo(entityB, Teams, FirstInstigators, TileColliderTags); for (int i = 0; i < actions.Length; i++) { ActionOnColliderContact actionOnContact = actions[i]; if (MutedActions.IsMuted(entityA, entityB, actionOnContact.Data.Id)) { continue; } if (Helpers.ActorFilterMatches(entityAInfo, entityBInfo, actionOnContact.Data.ActionFilter)) { OutActions.Add(new GameActionRequest() { Instigator = entityA, Target = entityB, ActionEntity = actionOnContact.Data.ActionEntity, }); if (actionOnContact.Data.SameTargetCooldown > 0) { MutedActions.Add(new MutedContactActionElement() { Instigator = entityA, ContactActionBufferId = actionOnContact.Data.Id, ExpirationTime = actionOnContact.Data.SameTargetCooldown, Target = entityB }); } } } } }
private void ProcessForEntity(Entity entity, Entity otherEntity) { if (triggerEventBufferFromEntity.HasComponent(entity)) { DynamicBuffer <StatefulTriggerEvent> triggerEventBuffer = triggerEventBufferFromEntity[entity]; var foundMatch = false; for (var i = 0; i < triggerEventBuffer.Length; i++) { StatefulTriggerEvent triggerEvent = triggerEventBuffer[i]; // If entity is already there, update to Stay if (triggerEvent.Entity == otherEntity) { foundMatch = true; triggerEvent.State = PhysicsEventState.Stay; triggerEvent._isStale = false; triggerEventBuffer[i] = triggerEvent; break; } } // If it's a new entity, add as Enter if (!foundMatch) { triggerEventBuffer.Add( new StatefulTriggerEvent { Entity = otherEntity, State = PhysicsEventState.Enter, _isStale = false } ); } } }
static void GetComponentDataFromChildren <T>(Entity entity, BufferFromEntity <Child> childrenFromEntity, ComponentDataFromEntity <T> componentFromEntity, NativeList <T> result, int depth) where T : struct, IComponentData { if (depth == -1) { return; } if (componentFromEntity.HasComponent(entity)) { result.Add(componentFromEntity[entity]); } if (!childrenFromEntity.HasComponent(entity)) { return; } var children = childrenFromEntity[entity]; for (var i = 0; i < children.Length; ++i) { GetComponentDataFromChildren(children[i].Value, childrenFromEntity, componentFromEntity, result, depth - 1); } }
public void Execute() { foreach (Entity attack in Attacks) { var target = AttackTargets[attack]; if (!EquipmentLists.HasComponent(target.Value)) { continue; } var equipmentList = EquipmentLists[target.Value]; foreach (Entity equipment in equipmentList.AsNativeArray()) { if (!EquipmentHealths.HasComponent(equipment)) { continue; } // If both target and equipment have sizes, determine chance based on their area. var baseChance = 0.5f; if (CombatSize.HasComponent(equipment) && CombatSize.HasComponent(target.Value)) { baseChance = math.pow(CombatSize[equipment].Value, 2f) / math.pow(CombatSize[target.Value].Value, 1f); } if (Random.NextFloat(0f, 1f) > baseChance) { continue; } var health = EquipmentHealths[equipment]; health.Value -= AttackDamages[attack].Value; EquipmentHealths[equipment] = health; } } }
public void Execute(ArchetypeChunk chunk, int chunkIndex, int firstEntityIndex) { var textBufferAccessor = chunk.GetBufferAccessor(CharBufferType); var vertexBufferAccessor = chunk.GetBufferAccessor(MeshVertexDataType); var triangleIndexAccessor = chunk.GetBufferAccessor(TriangleIndexType); var textOptions = chunk.GetNativeArray(TextOptionType); var txtFontIDs = chunk.GetNativeArray(TxtFontIDType); var entities = chunk.GetNativeArray(EntityType); var colors = chunk.GetNativeArray(ColorType); var ltws = chunk.GetNativeArray(LTWType); var dimensionsChunk = chunk.GetNativeArray(DimensionType); for (int i = 0; i < chunk.Count; i++) { var text = textBufferAccessor[i].AsNativeArray(); var vertices = vertexBufferAccessor[i]; var indices = triangleIndexAccessor[i]; var fontID = txtFontIDs[i].Value; var textOption = textOptions[i]; var color = colors[i]; var dimensions = dimensionsChunk[i]; var ltw = ltws[i]; vertices.Clear(); indices.Clear(); var canvasScale = ltw.AverageScale(); var glyphTableExists = GlyphMap.TryGetValue(fontID, out var glyphEntity); var glyphBufferExists = GlyphData.HasComponent(glyphEntity); var fontFaceExists = FontFaces.HasComponent(glyphEntity); if (!(glyphTableExists && glyphBufferExists && fontFaceExists)) { continue; } var fontFace = FontFaces[glyphEntity]; var fontScale = textOption.Size > 0 ? ((float)textOption.Size / fontFace.PointSize) : 1f; var glyphData = GlyphData[glyphEntity].AsNativeArray(); var extents = dimensions.Extents() * ltw.Scale().xy; var stylePadding = TextUtil.SelectStylePadding(in textOption, in fontFace); var parentScale = textOption.Size * new float2(1) / fontFace.PointSize; var isBold = textOption.Style == FontStyles.Bold; var styleSpaceMultiplier = 1f + (isBold ? fontFace.BoldStyle.y * 0.01f : fontFace.NormalStyle.y * 0.01f); var padding = fontScale * styleSpaceMultiplier; var lines = new NativeList <TextUtil.LineInfo>(Allocator.Temp); TextUtil.CountLines(in text, in glyphData, dimensions, padding, ref lines); var linesHeight = lines.Length * fontFace.LineHeight * fontScale * ltw.Scale().y; var heights = new float3(fontFace.LineHeight, fontFace.AscentLine, fontFace.DescentLine) * ltw.Scale().y; var start = new float2( TextUtil.GetHorizontalAlignment(textOption.Alignment, extents, lines[0].LineWidth * ltw.Scale().x), TextUtil.GetVerticalAlignment(heights, fontScale, textOption.Alignment, in extents, in linesHeight, lines.Length)) + ltw.Position.xy; for (int k = 0, row = 0; k < text.Length; k++) { var c = text[k].Value; if (!glyphData.TryGetGlyph(c, out var glyph)) { continue; } var bl = (ushort)vertices.Length; if (row < lines.Length && k == lines[row].StartIndex) { var height = fontFace.LineHeight * fontScale * ltw.Scale().y *(row > 0 ? 1f : 0f); start.y -= height; start.x = TextUtil.GetHorizontalAlignment(textOption.Alignment, extents, lines[row].LineWidth * ltw.Scale().x) + ltw.Position.x; row++; } var xPos = start.x + (glyph.Bearings.x - stylePadding) * fontScale * ltw.Scale().x; var yPos = start.y - (glyph.Size.y - glyph.Bearings.y - stylePadding) * fontScale * ltw.Scale().y; var size = (glyph.Size + new float2(stylePadding * 2)) * fontScale * ltw.Scale().xy; var uv1 = glyph.RawUV.NormalizeAdjustedUV(stylePadding, fontFace.AtlasSize); var uv2 = new float2(glyph.Scale) * math.select(canvasScale, -canvasScale, isBold); var right = new float3(1, 0, 0); var vertexColor = color.Value.ToNormalizedFloat4(); vertices.Add(new LocalVertexData { Position = new float3(xPos, yPos, 0), Normal = right, Color = vertexColor, UV1 = uv1.c0, UV2 = uv2 }); vertices.Add(new LocalVertexData { Position = new float3(xPos, yPos + size.y, 0), Normal = right, Color = vertexColor, UV1 = uv1.c1, UV2 = uv2 }); vertices.Add(new LocalVertexData { Position = new float3(xPos + size.x, yPos + size.y, 0), Normal = right, Color = vertexColor, UV1 = uv1.c2, UV2 = uv2 }); vertices.Add(new LocalVertexData { Position = new float3(xPos + size.x, yPos, 0), Normal = right, Color = vertexColor, UV1 = uv1.c3, UV2 = uv2 }); var tl = (ushort)(bl + 1); var tr = (ushort)(bl + 2); var br = (ushort)(bl + 3); indices.Add(new LocalTriangleIndexElement { Value = bl }); indices.Add(new LocalTriangleIndexElement { Value = tl }); indices.Add(new LocalTriangleIndexElement { Value = tr }); indices.Add(new LocalTriangleIndexElement { Value = bl }); indices.Add(new LocalTriangleIndexElement { Value = tr }); indices.Add(new LocalTriangleIndexElement { Value = br }); start += new float2(glyph.Advance * padding, 0) * ltw.Scale().xy; } lines.Dispose(); var textEntity = entities[i]; CmdBuffer.RemoveComponent <BuildUIElementTag>(textEntity.Index, textEntity); var canvas = GetRootCanvas(textEntity); CmdBuffer.AddComponent(canvas.Index, canvas, new BatchCanvasTag { }); } }
protected override void OnUpdate() { BufferFromEntity <TweenDestroyCommand> destroyBufferFromEntity = GetBufferFromEntity <TweenDestroyCommand>(true); EndSimulationEntityCommandBufferSystem endSimECBSystem = World.GetOrCreateSystem <EndSimulationEntityCommandBufferSystem>(); EntityCommandBuffer.ParallelWriter parallelWriter = endSimECBSystem.CreateCommandBuffer().AsParallelWriter(); Entities .WithReadOnly(destroyBufferFromEntity) .WithNone <TweenPause>() .ForEach((Entity entity, int entityInQueryIndex, ref DynamicBuffer <TweenState> tweenBuffer) => { for (int i = tweenBuffer.Length - 1; i >= 0; i--) { TweenState tween = tweenBuffer[i]; bool isInfiniteLoop = tween.LoopCount == TweenState.LOOP_COUNT_INFINITE; float normalizedTime = tween.GetNormalizedTime(); if (tween.IsReverting && normalizedTime <= 0.0f) { if (!isInfiniteLoop) { tween.LoopCount--; } tween.IsReverting = false; tween.Time = 0.0f; } else if (!tween.IsReverting && normalizedTime >= 1.0f) { if (tween.IsPingPong) { tween.IsReverting = true; tween.Time = tween.Duration / 2.0f; } else { if (!isInfiniteLoop) { tween.LoopCount--; } tween.Time = 0.0f; } } if (!isInfiniteLoop && tween.LoopCount == 0) { if (!destroyBufferFromEntity.HasComponent(entity)) { parallelWriter.AddBuffer <TweenDestroyCommand>(entityInQueryIndex, entity); } parallelWriter.AppendToBuffer(entityInQueryIndex, entity, new TweenDestroyCommand(tween.Id)); } tweenBuffer[i] = tween; } }).ScheduleParallel(); endSimECBSystem.AddJobHandleForProducer(Dependency); }
public bool IsValid(BufferFromEntity <T> bfe) => bfe.HasComponent(entity);
private bool DeserializeEntity(uint serverTick, ref DataStreamReader dataStream, ref DeserializeData data) { if (data.targetArchLen == 0) { #if UNITY_EDITOR || DEVELOPMENT_BUILD data.curPos = dataStream.GetBitsRead(); if (data.statCount > 0) { int statType = (int)data.targetArch; netStats[statType * 3 + 4] = netStats[statType * 3 + 4] + data.statCount; netStats[statType * 3 + 5] = netStats[statType * 3 + 5] + (uint)(data.curPos - data.startPos); netStats[statType * 3 + 6] = netStats[statType * 3 + 6] + data.uncompressedCount; } data.startPos = data.curPos; data.statCount = 0; data.uncompressedCount = 0; #endif data.targetArch = dataStream.ReadPackedUInt(compressionModel); data.targetArchLen = dataStream.ReadPackedUInt(compressionModel); } --data.targetArchLen; if (data.baselineLen == 0) { data.baselineTick = serverTick - dataStream.ReadPackedUInt(compressionModel); data.baselineTick2 = serverTick - dataStream.ReadPackedUInt(compressionModel); data.baselineTick3 = serverTick - dataStream.ReadPackedUInt(compressionModel); data.baselineLen = dataStream.ReadPackedUInt(compressionModel); if (data.baselineTick3 != serverTick && (data.baselineTick3 == data.baselineTick2 || data.baselineTick2 == data.baselineTick)) { #if ENABLE_UNITY_COLLECTIONS_CHECKS UnityEngine.Debug.LogError("Received invalid snapshot baseline from server"); #endif return(false); } } --data.baselineLen; int ghostId = (int)dataStream.ReadPackedUInt(compressionModel); uint serverSpawnTick = 0; if (data.baselineTick == serverTick) { serverSpawnTick = dataStream.ReadPackedUInt(compressionModel); } var typeData = GhostTypeCollection[(int)data.targetArch]; int changeMaskUints = GhostCollectionSystem.ChangeMaskArraySizeInUInts(typeData.ChangeMaskBits); int snapshotOffset; int snapshotSize = typeData.SnapshotSize; byte *baselineData = (byte *)UnsafeUtility.Malloc(snapshotSize, 16, Allocator.Temp); UnsafeUtility.MemClear(baselineData, snapshotSize); Entity gent; DynamicBuffer <SnapshotDataBuffer> snapshotDataBuffer; SnapshotData snapshotDataComponent; byte * snapshotData; bool existingGhost = ghostEntityMap.TryGetValue(ghostId, out gent); if (existingGhost && snapshotDataBufferFromEntity.HasComponent(gent) && ghostFromEntity[gent].ghostType == data.targetArch) { snapshotDataBuffer = snapshotDataBufferFromEntity[gent]; #if ENABLE_UNITY_COLLECTIONS_CHECKS if (snapshotDataBuffer.Length != snapshotSize * GhostSystemConstants.SnapshotHistorySize) { throw new InvalidOperationException($"Invalid snapshot buffer size"); } #endif snapshotData = (byte *)snapshotDataBuffer.GetUnsafePtr(); snapshotDataComponent = snapshotDataFromEntity[gent]; snapshotDataComponent.LatestIndex = (snapshotDataComponent.LatestIndex + 1) % GhostSystemConstants.SnapshotHistorySize; snapshotDataFromEntity[gent] = snapshotDataComponent; if (data.baselineTick != serverTick) { for (int bi = 0; bi < snapshotDataBuffer.Length; bi += snapshotSize) { if (*(uint *)(snapshotData + bi) == data.baselineTick) { UnsafeUtility.MemCpy(baselineData, snapshotData + bi, snapshotSize); break; } } if (*(uint *)baselineData == 0) { return(false); // Ack desync detected } } if (data.baselineTick3 != serverTick) { byte *baselineData2 = null; byte *baselineData3 = null; for (int bi = 0; bi < snapshotDataBuffer.Length; bi += snapshotSize) { if (*(uint *)(snapshotData + bi) == data.baselineTick2) { baselineData2 = snapshotData + bi; } if (*(uint *)(snapshotData + bi) == data.baselineTick3) { baselineData3 = snapshotData + bi; } } if (baselineData2 == null || baselineData3 == null) { return(false); // Ack desync detected } snapshotOffset = GhostCollectionSystem.SnapshotSizeAligned(4 + changeMaskUints * 4); var predictor = new GhostDeltaPredictor(serverTick, data.baselineTick, data.baselineTick2, data.baselineTick3); for (int comp = 0; comp < typeData.NumComponents; ++comp) { int compIdx = GhostComponentIndex[typeData.FirstComponent + comp].ComponentIndex; #if ENABLE_UNITY_COLLECTIONS_CHECKS if (snapshotOffset + GhostComponentCollection[compIdx].SnapshotSize > snapshotSize) { throw new InvalidOperationException("Snapshot buffer overflow during predict"); } #endif GhostComponentCollection[compIdx].PredictDelta.Ptr.Invoke((IntPtr)(baselineData + snapshotOffset), (IntPtr)(baselineData2 + snapshotOffset), (IntPtr)(baselineData3 + snapshotOffset), ref predictor); snapshotOffset += GhostCollectionSystem.SnapshotSizeAligned(GhostComponentCollection[compIdx].SnapshotSize); } } } else { if (existingGhost) { // The ghost entity map is out of date, clean it up ghostEntityMap.Remove(ghostId); #if ENABLE_UNITY_COLLECTIONS_CHECKS if (ghostFromEntity.HasComponent(gent) && ghostFromEntity[gent].ghostType != data.targetArch) { UnityEngine.Debug.LogError("Received a ghost with an invalid ghost type"); } UnityEngine.Debug.LogError("Found a ghost in the ghost map which does not have an entity connected to it. This can happen if you delete ghost entities on the client."); #endif } if (data.baselineTick != serverTick) { // If the server specifies a baseline for a ghost we do not have that is an error return(false); } ++data.newGhosts; var ghostSpawnBuffer = ghostSpawnBufferFromEntity[ghostSpawnEntity]; snapshotDataBuffer = snapshotDataBufferFromEntity[ghostSpawnEntity]; var snapshotDataBufferOffset = snapshotDataBuffer.Length; ghostSpawnBuffer.Add(new GhostSpawnBuffer { GhostType = (int)data.targetArch, GhostID = ghostId, DataOffset = snapshotDataBufferOffset, ClientSpawnTick = serverTick, ServerSpawnTick = serverSpawnTick }); snapshotDataBuffer.ResizeUninitialized(snapshotDataBufferOffset + snapshotSize); snapshotData = (byte *)snapshotDataBuffer.GetUnsafePtr() + snapshotDataBufferOffset; UnsafeUtility.MemClear(snapshotData, snapshotSize); snapshotDataComponent = new SnapshotData { SnapshotSize = snapshotSize, LatestIndex = 0 }; } int maskOffset = 0; snapshotOffset = GhostCollectionSystem.SnapshotSizeAligned(4 + changeMaskUints * 4); snapshotData += snapshotSize * snapshotDataComponent.LatestIndex; *(uint *)(snapshotData) = serverTick; uint *changeMask = (uint *)(snapshotData + 4); for (int cm = 0; cm < changeMaskUints; ++cm) { changeMask[cm] = dataStream.ReadPackedUIntDelta(((uint *)(baselineData + 4))[cm], compressionModel); } for (int comp = 0; comp < typeData.NumComponents; ++comp) { int compIdx = GhostComponentIndex[typeData.FirstComponent + comp].ComponentIndex; #if ENABLE_UNITY_COLLECTIONS_CHECKS if (maskOffset + GhostComponentCollection[compIdx].ChangeMaskBits > typeData.ChangeMaskBits || snapshotOffset + GhostComponentCollection[compIdx].SnapshotSize > snapshotSize) { throw new InvalidOperationException("Snapshot buffer overflow during deserialize"); } #endif GhostComponentCollection[compIdx].Deserialize.Ptr.Invoke((IntPtr)(snapshotData + snapshotOffset), (IntPtr)(baselineData + snapshotOffset), ref dataStream, ref compressionModel, (IntPtr)changeMask, maskOffset); snapshotOffset += GhostCollectionSystem.SnapshotSizeAligned(GhostComponentCollection[compIdx].SnapshotSize); maskOffset += GhostComponentCollection[compIdx].ChangeMaskBits; } #if UNITY_EDITOR || DEVELOPMENT_BUILD ++data.statCount; if (data.baselineTick == serverTick) { ++data.uncompressedCount; } #endif if (typeData.IsGhostGroup != 0) { var groupLen = dataStream.ReadPackedUInt(compressionModel); for (var i = 0; i < groupLen; ++i) { if (!DeserializeEntity(serverTick, ref dataStream, ref data)) { return(false); } } } return(true); }