Game.Tools.ToolUtils
Assembly: Game
Namespace: Game.Tools
Type: static class
Base: N/A
Summary:
Utility helpers used by editor/mod tools for Cities: Skylines 2. Provides constants for infomode coloring and snapping behavior and a set of static helper methods for:
- converting 2D directions to rotations,
- calculating and comparing snap priorities,
- adding and merging snap lines/positions,
- direction snapping,
- computing rotated brush bounds,
- generating a random age from an AgeMask.
These helpers rely on Unity.Mathematics and project-specific math/geometry types (Line2/Line3, Bounds2, ControlPoint, SnapLine, Brush, Random, AgeMask, etc.) and are intended for use inside in-game tool code (placement, snapping and editing operations).
Fields
-
public const float WATER_DEPTH_LIMIT
0.2f — water depth threshold used by tools when evaluating water coverage or limitations. -
public const int MAX_ACTIVE_INFOMODES
100 — maximum number of concurrently active infomodes. -
public const int INFOMODE_COLOR_GROUP_COUNT
3 — number of colour groups used for infomode visualization. -
public const int INFOMODE_COLOR_GROUP_SIZE
4 — number of colors per infomode color group. -
public const int INFOMODE_COLOR_GROUP_TERRAIN
0 — index for the terrain color group. -
public const int INFOMODE_COLOR_GROUP_WATER
1 — index for the water color group. -
public const int INFOMODE_COLOR_GROUP_OTHER
2 — index for the “other” color group.
Properties
- None. (This is a static utility class; it exposes only constants and static methods.)
Constructors
- None. (Static class — no instance constructors.)
Methods
-
public static quaternion CalculateRotation(float2 direction)
Calculates a quaternion rotation that faces along the given 2D direction on the XZ plane. Returns quaternion.identity if the direction is the zero vector. Uses quaternion.LookRotation with math.up() as the up vector. -
public static float2 CalculateSnapPriority(float level, float priority, float heightWeight, float3 origPos, float3 newPos, float2 direction)
Transforms the 3D offset (newPos - origPos) into the coordinate frame defined by the provided 2D direction and its right perpendicular, then calls the overload below to compute a two-component snap priority value. The returned float2 encodes (level, computedPriority). -
public static float2 CalculateSnapPriority(float level, float priority, float heightWeight, float3 offset)
Computes a snap priority from an offset vector: - scales and squares the offset (divides by 8 then squares),
- computes planar closeness and anisotropy,
- factors in height difference using heightWeight,
-
returns a float2 where x = level and y = adjusted priority value (higher is better). Used to rank candidate snap positions.
-
public static bool CompareSnapPriority(float2 priority, float2 other)
Compares two snap priority float2 values. Comparison logic: - prefer larger x (level); if x are equal, prefer larger y;
-
implemented using component-wise comparison and tie-break logic.
-
public static void AddSnapLine(ref ControlPoint bestSnapPosition, NativeList<SnapLine> snapLines, SnapLine snapLine)
Adds a SnapLine to the provided NativeList. While adding, iterates existing snapLines and checks intersections between the new line and each existing line (skipping nearly-parallel ones). For intersections: - picks the dominant snap line (by level),
- moves the control point to the intersection point,
- resolves height weight differences and ExtendedCurve behavior (adjusts curve position and clamp/length),
-
recalculates snap priority for the merged control point and updates bestSnapPosition accordingly via AddSnapPosition. This method performs geometric merging of snap lines to produce consistent snapping targets.
-
public static void AddSnapPosition(ref ControlPoint bestSnapPosition, ControlPoint snapPosition)
Updates bestSnapPosition if snapPosition has a higher snap priority according to CompareSnapPriority. -
public static void DirectionSnap(ref float bestDirectionDistance, ref float3 resultPos, ref float3 resultDir, float3 refPos, float3 snapOrig, float3 snapDir, float snapDistance)
Performs direction snapping against a primary direction (snapDir) and its perpendicular: - builds two direction lines (primary and right-perpendicular),
- computes 2D distances from refPos to each line,
-
if a closer direction is found and within snapDistance, updates resultDir and resultPos (XZ) and lowers bestDirectionDistance. Used to snap object orientation/position to nearest cardinal/guide directions.
-
public static Bounds2 GetBounds(Brush brush)
Returns the axis-aligned Bounds2 that encloses a square brush rotated by brush.m_Angle and centered at brush.m_Position. Computes half-extents by rotating unit axes by the brush quaternion and summing absolute components. -
public static float GetRandomAge(ref Random random, AgeMask ageMask)
Chooses a random Age value (float) from the provided AgeMask bitmask. The method: - counts bits in ageMask,
- picks a random indexed bit,
- maps AgeMask entries to specific float ages:
- AgeMask.Sapling => 0.0
- AgeMask.Young => ~0.175
- AgeMask.Mature => 0.425
- AgeMask.Elderly => ~0.775
- returns 0.0 if none matched (fallback).
Notes on helper types used by methods: - ControlPoint, SnapLine, SnapLineFlags — snapping geometry and state used by tools. - Line2, Line3, Bounds2 — lightweight geometry primitives (2D/3D lines and bounds). - MathUtils and NetUtils — project math helpers used for intersections, distances, clamping and curve length computations. - Brush — brush state with m_Position (float3), m_Size and m_Angle used in GetBounds. - Random, AgeMask — custom RNG and age bitmask enum used by GetRandomAge.
Usage Example
// Calculate rotation from a 2D input direction (e.g., mouse drag on terrain)
float2 direction = new float2(1f, 0f); // east
quaternion rot = ToolUtils.CalculateRotation(direction);
// Compute a snap priority for a candidate point relative to an origin and direction
float level = 1f;
float priority = 2f;
float heightWeight = 0.5f;
float3 origPos = new float3(0f, 0f, 0f);
float3 newPos = new float3(4f, 0.5f, 0f);
float2 snapDir = new float2(1f, 0f);
float2 snapPriority = ToolUtils.CalculateSnapPriority(level, priority, heightWeight, origPos, newPos, snapDir);
// Get rotated brush bounds
Brush brush = new Brush { m_Position = new float3(10f, 0f, 10f), m_Size = 6f, m_Angle = math.radians(45f) };
Bounds2 bounds = ToolUtils.GetBounds(brush);
// Random age example
Random rng = new Random(12345);
AgeMask mask = AgeMask.Young | AgeMask.Mature;
float age = ToolUtils.GetRandomAge(ref rng, mask);