Game.Common.CommonUtils
Assembly: Game (game assembly)
Namespace: Game.Common
Type: public static class
Base: System.Object
Summary:
Utility helpers used by the game's ECS code (Cities: Skylines 2). CommonUtils provides helpers for selecting random entities from ArchetypeChunk arrays, swapping generic values, swapping bit flags inside a uint mask, mapping MeshLayer flags to BoundsMask flags, and a helper for checking exclusive ground collisions. These methods are intended to be used inside ECS systems/jobs and with Unity.Collections/Unity.Entities types.
Fields
- This type defines no fields. {{ No instance or static fields are declared in this static utility class. }}
Properties
- This type exposes no properties. {{ The class is a static utility container, so there are no properties to configure or access. }}
Constructors
- This static class has no public constructors. {{ Being declared static, the type cannot be instantiated and does not expose constructors. }}
Methods
-
public static Unity.Entities.Entity GetRandomEntity(ref Unity.Mathematics.Random random, Unity.Collections.NativeArray<Unity.Entities.ArchetypeChunk> chunks, Unity.Entities.EntityTypeHandle entityType)
{{ Returns a random Entity chosen uniformly from the provided ArchetypeChunk array. The method first sums the total entity count across all chunks, returns Entity.Null if zero, then selects a global random index via random.NextInt(totalCount) and walks the chunks to find the chunk+index that corresponds to that global index. The Random parameter is passed by ref because Unity.Mathematics.Random is a struct whose state is advanced by NextInt. Use an EntityTypeHandle obtained from SystemBase (GetEntityTypeHandle) or SystemState. If the chunks array is empty or contains no entities the method returns Entity.Null. This function reads the entity arrays directly from ArchetypeChunk so it is compatible with chunk-based iteration patterns and can be used inside jobs that already have archetype chunks.}} -
public static Unity.Entities.Entity GetRandomEntity<T>(ref Unity.Mathematics.Random random, Unity.Collections.NativeArray<Unity.Entities.ArchetypeChunk> chunks, Unity.Entities.EntityTypeHandle entityType, Unity.Entities.ComponentTypeHandle<T> componentType, out T componentData) where T : unmanaged, Unity.Entities.IComponentData
{{ Overload that also reads a single component of type T from the randomly selected entity. The method sets componentData to the component value for the chosen entity (or default(T) if no entity selected) and returns the corresponding Entity. The componentType must match the type and read/write intent used to create the ComponentTypeHandle (GetComponentTypeHandle(isReadOnly)). This avoids an extra lookup after selecting the entity because the component is already read from the chunk. If no entities are present the method returns Entity.Null and componentData is default(T). }} -
public static Unity.Entities.Entity GetRandomEntity<T1, T2>(ref Unity.Mathematics.Random random, Unity.Collections.NativeArray<Unity.Entities.ArchetypeChunk> chunks, Unity.Entities.EntityTypeHandle entityType, Unity.Entities.ComponentTypeHandle<T1> componentType1, Unity.Entities.ComponentTypeHandle<T2> componentType2, out T1 componentData1, out T2 componentData2) where T1 : unmanaged, Unity.Entities.IComponentData where T2 : unmanaged, Unity.Entities.IComponentData
{{ Overload that also reads two components (T1 and T2) from the randomly selected entity. Both componentData1 and componentData2 are filled with the values for the selected entity and the Entity is returned. If the chunks contain no entities the method returns Entity.Null and both outs are set to their default values. This is useful to sample both entity and few component values in a single pass over the chunks. }} -
public static void Swap<T>(ref T a, ref T b)
{{ Simple generic swap helper that exchanges the values a and b by reference. Useful for small utility code paths where you need to reorder two variables without allocations. Works for unmanaged and managed types. Equivalent to standard temp swap pattern. }} -
public static void SwapBits(ref uint bitMask, uint a, uint b)
{{ Swaps the bits corresponding to the bit masks a and b inside bitMask. The implementation computes which of the mask bits are set and swaps them (so bits set in a become set in b and vice versa) without affecting other bits. Useful when bitMask encodes multiple boolean flags in individual bit positions and you want to swap two flag positions atomically. Note: a and b should be single-bit masks (e.g., 1u << n). If a or b contain multiple bits the behavior swaps those groups as a block. }} -
public static BoundsMask GetBoundsMask(MeshLayer meshLayers)
{{ Maps MeshLayer flags to a BoundsMask value. Common mapping: - MeshLayer.Default, Moving, Tunnel, Marker -> BoundsMask.NormalLayers
- MeshLayer.Pipeline -> BoundsMask.PipelineLayer
- MeshLayer.SubPipeline -> BoundsMask.SubPipelineLayer
-
MeshLayer.Waterway -> BoundsMask.WaterwayLayer The method ORs the resulting BoundsMask bits together for any matching input mesh layers. Use this when you need to compute what bounding categories a mesh layer contributes to. }}
-
public static bool ExclusiveGroundCollision(CollisionMask mask1, CollisionMask mask2)
{{ Returns true when both masks overlap on the OnGround flag and at least one of the masks has the ExclusiveGround flag set. In other words, if both collisions are on the ground and one of them is marked as exclusive ground, this indicates an exclusive ground collision condition. If the masks do not overlap on OnGround the method returns false. This is a concise helper to enforce exclusive ground-collision rules. }}
Usage Example
// Example inside a SystemBase
protected override void OnUpdate()
{
// Prepare handles and query
var entityType = GetEntityTypeHandle();
var compHandle = GetComponentTypeHandle<MyComponent>(isReadOnly: true);
var query = GetEntityQuery(ComponentType.ReadOnly<MyComponent>());
// Grab archetype chunks (ensure lifetime handled properly)
var chunks = query.CreateArchetypeChunkArray(Allocator.TempJob);
// Create a Random seeded per-system or per-job (must be passed by ref)
Unity.Mathematics.Random rng = new Unity.Mathematics.Random((uint)DateTime.Now.Ticks);
// Sample a random entity and read its component
if (chunks.Length > 0)
{
MyComponent comp;
var entity = Game.Common.CommonUtils.GetRandomEntity(ref rng, chunks, entityType, compHandle, out comp);
if (entity != Entity.Null)
{
// Use entity and comp...
}
}
// Cleanup
chunks.Dispose();
}
{{ YOUR_INFO }}