Game.Simulation.WatercraftLaneSpeedIterator
Assembly:
Game (Cities: Skylines II game assembly context)
Namespace:
Game.Simulation
Type:
struct
Base:
System.ValueType
Summary:
WatercraftLaneSpeedIterator is a low-level simulation helper used by the watercraft movement / lane-following logic to iterate along lanes/curves and determine a safe maximum speed for a watercraft. It walks along lane curves (and overlapping lanes), inspects lane objects (other vehicles/objects), lane signals, lane reservations and geometry, and computes braking constraints (m_MaxSpeed) and blockers (m_Blocker / m_BlockerType) based on distances, priorities and the vehicle/prefab characteristics. This struct is intended for use inside the game's ECS simulation (Unity.Entities) and is used by vehicle movement systems to decide speeds and when to stop or yield. Modders should be careful to provide the required ComponentLookup / BufferLookup views and to call iterator methods with valid curve offsets and entity references.
Fields
-
public ComponentLookup<Transform> m_TransformData
Lookup to access Transform component data for entities being considered (used to compute positions/distances). -
public ComponentLookup<Moving> m_MovingData
Lookup to read Moving components (used to obtain object velocity used in relative-speed calculations). -
public ComponentLookup<Watercraft> m_WatercraftData
Lookup that identifies watercraft entities (used when checking priorities of other vehicles). -
public ComponentLookup<LaneReservation> m_LaneReservationData
Lookup used to read lane reservation information (priority, offsets) that influence speed reductions on merges/approaches. -
public ComponentLookup<LaneSignal> m_LaneSignalData
Lookup for lane signals (stop / safe stop logic) — used to decide if a signal should block the vehicle. -
public ComponentLookup<Curve> m_CurveData
Lookup for curve data (Bezier paths and lengths) used to sample positions along lanes. -
public ComponentLookup<Game.Net.CarLane> m_CarLaneData
Lookup for lane meta-data such as speed limits and flags. -
public ComponentLookup<PrefabRef> m_PrefabRefData
Lookup to map entities to their Prefab; needed to query object geometry or watercraft prefab data. -
public ComponentLookup<ObjectGeometryData> m_PrefabObjectGeometryData
Lookup containing prefab geometry bounds for objects; used to account for object length when computing spacing. -
public ComponentLookup<WatercraftData> m_PrefabWatercraftData
Lookup for watercraft prefab data (braking, priority, etc.) used to reason about other moving objects. -
public BufferLookup<LaneOverlap> m_LaneOverlapData
Buffer lookup that gives overlapping-lane ranges for a lane (used to check crossing/merge lanes). -
public BufferLookup<LaneObject> m_LaneObjectData
Buffer lookup to enumerate LaneObjects placed on a lane (other vehicles/objects occupying the lane). -
public Entity m_Entity
Entity for the vehicle running this iterator (the subject). Used to ignore self in checks. -
public Entity m_Ignore
Entity to be ignored during obstruction checks (e.g., a transient entity that should not be treated as a blocker). -
public int m_Priority
Priority value of the subject vehicle / movement (higher priorities influence yielding/merging behavior). -
public float m_TimeStep
Time step used in some braking/brake-distance calculations. -
public float m_SafeTimeStep
A safety timestep (often larger) used to ensure safe stopping distance. -
public float m_SpeedLimitFactor
Multiplier applied to lane speed limits before comparing with vehicle capabilities. -
public float m_CurrentSpeed
Current forward speed of the subject vehicle (used when evaluating signal braking distances, etc). -
public WatercraftData m_PrefabWatercraft
Prefab data for the subject watercraft; braking/acceleration properties used for braking/speed calculations. -
public ObjectGeometryData m_PrefabObjectGeometry
Geometry bounds for the subject (object) — used to compute offsets/clearance. -
public Bounds1 m_SpeedRange
Min/max clamp range for computed speeds. Results (m_MaxSpeed) are clamped within this range. -
public float m_MaxSpeed
Current computed maximum allowable speed (the iterator lowers this value as it encounters blockers). -
public float m_CanChangeLane
Float flag (0 or 1) used to indicate whether the subject can use/change a lane (modified by checks). -
public float3 m_CurrentPosition
Current sampled world position along the iterated curve (updated as iterator advances). -
public float m_Distance
Cumulative distance along iteration path used for braking / spacing computations. -
public Entity m_Blocker
Entity that is currently considered the blocker (the object restricting speed). Null if none. -
public BlockerType m_BlockerType
Type of blocker (Limit, Signal, Crossing, Continuing, None) associated with m_Blocker. -
private Entity m_Lane
Private: current lane entity being processed during iteration. -
private Curve m_Curve
Private: current Curve data for m_Lane. -
private float2 m_CurveOffset
Private: stored offsets along the current curve (used for sampling and comparisons). -
private float3 m_PrevPosition
Private: previous sampled position (used to compute distances and relative ordering). -
private float m_PrevDistance
Private: previous cumulative distance (helps handle discontinuities and distance comparisons).
Properties
- This struct does not define CLR-style properties. It uses public fields for data exchange and internal private fields for bookkeeping.
Constructors
public WatercraftLaneSpeedIterator()
Default value-type constructor (compiler-provided). All fields must be explicitly initialized by the caller before use — typical usage is to construct the iterator and then populate the ComponentLookup/BufferLookup and initial state (m_PrefabWatercraft, m_PrefabObjectGeometry, m_CurrentPosition, m_MaxSpeed, m_SpeedRange, time steps, etc.) before running iteration methods.
Methods
-
public bool IterateFirstLane(Entity lane, float3 curveOffset)
Walks from the subject's current position to the lane sample defined by curveOffset (x..z), updating m_CurrentPosition, m_Distance and computing lane speed limits, objects and overlaps on that lane. Considers lane speed limit, lane reservations, lane objects and overlapping lanes. Adjusts m_MaxSpeed, m_Blocker and m_BlockerType accordingly. Returns true when the iterator has advanced far enough that braking distance is exceeded (i.e., no need to continue scanning) or when the m_MaxSpeed reaches the minimum of m_SpeedRange. -
Parameters:
- lane: lane entity to evaluate.
- curveOffset: float3 representing positions along the curve (x=start, y=mid, z=end normalized offsets).
-
Side effects: modifies iterator state (m_CurrentPosition, m_Distance, m_MaxSpeed, m_Blocker, m_BlockerType, m_Lane, ...).
-
public bool IterateFirstLane(Entity lane1, Entity lane2, float3 curveOffset, float laneDelta)
A two-lane variant used for lanes that interpolate between two physical curves (e.g., lane blending or lane shifts). It evaluates both lane1 and lane2 taking laneDelta into account, updating state similarly to the single-lane variant. Uses both curves to compute sampling points and distance increments. -
Parameters:
- lane1, lane2: the two lanes involved in the blended lane.
- curveOffset: same format as above.
- laneDelta: blend factor between lanes (0..1).
-
Returns: same semantics as single-lane IterateFirstLane.
-
public bool IterateNextLane(Entity lane, float2 curveOffset, float minOffset, out bool needSignal)
Advance iteration along a lane segment defined by curveOffset (x..y) and inspect lane meta, lane signals and lane objects. Applies lane signal logic (Stop / SafeStop) to determine if a physical or priority-based stop is required. Adjusts m_MaxSpeed and blockers accordingly. Returns whether scanning can stop for braking reasons. Sets needSignal to true if a lane signal (level crossing / rail crossing) was encountered and influenced stopping decisions. -
Parameters:
- lane: lane entity to advance into.
- curveOffset: float2 offsets along the curve to sample.
- minOffset: minimum offset along the lane to consider (may be overwritten based on curveOffset.x).
- out needSignal: flag set if lane has a signal that must be considered.
-
Notes: This method checks both lane speed and lane signals. If a signal requires stopping and braking distance is close enough, this will reduce candidate speeds to zero and set a signal blocker.
-
public void IterateTarget(float3 targetPosition)
Convenience overload that computes a default maxLaneSpeed from the prefab and calls IterateTarget(targetPosition, maxLaneSpeed). Updates m_Distance and computes braking constraints when approaching the final target position (e.g., a docking point or the end of the lane). -
public void IterateTarget(float3 targetPosition, float maxLaneSpeed)
Used when iteration reaches a target world position (not necessarily a lane sample). Adds the final distance to m_Distance, computes maximum braking speed allowed based on the provided maxLaneSpeed and the iterator's state, and updates m_MaxSpeed / blockers as needed. -
Parameters:
- targetPosition: destination world position (x,z used).
- maxLaneSpeed: the lane speed to use when determining braking limits for the final stretch.
-
private void CheckCurrentLane(float distance, float2 minOffset)
Inspects the lane object buffer for the current lane and updates m_MaxSpeed based on each lane object that is ahead of the minOffset (i.e., relevant objects the subject may catch up to). This method ignores the subject entity itself and subtracts a small safety value from distance before checks. -
Parameters:
- distance: effective distance metric used for braking computations.
- minOffset: offset thresholds to determine which lane objects are "ahead".
-
private void CheckCurrentLane(float distance, float2 minOffset, ref float canUseLane)
Variant that additionally modifies canUseLane (m_CanChangeLane style flag). If a lane object occupies the close portion of the lane such that it blocks changing into/using the lane, canUseLane may be set to 0. Otherwise it behaves like the non-ref variant and updates maximum speeds for objects further ahead. -
Parameters:
- distance: as above.
- minOffset: as above.
- ref canUseLane: reference to a float that will be cleared to 0 if lane cannot be used because of an object immediately blocking the lane.
-
private void CheckOverlappingLanes(float origDistance, float origMinOffset)
Examines overlapping lanes (from the LaneOverlap buffer) to detect cross-traffic, merging traffic and lane-parallel objects that affect the subject. Computes relative offsets and distance factors, honours lane reservation priorities and merge flags, and calls UpdateMaxSpeed for objects in overlapping lanes. This method may lower m_MaxSpeed and set appropriate m_Blocker and m_BlockerType. -
Parameters:
- origDistance: original distance baseline from which to compute offsets into overlapping lane.
- origMinOffset: threshold offset used to filter overlaps.
-
private float GetObjectSpeed(Entity obj, float curveOffset)
Returns the forward speed component of the given object relative to the current curve tangent. If the object has no Moving component, returns 0. Uses MathUtils.Tangent(...) to compute direction and dot-product with the object's velocity. -
Parameters:
- obj: entity to query.
- curveOffset: offset on the current curve used to compute correct tangent.
-
private void UpdateMaxSpeed(Entity obj, BlockerType blockerType, float objectSpeed, float laneOffset, float distanceFactor, float distanceOffset, bool ignore)
Core method that computes the effective braking constraint imposed by a specific object on another lane (or same lane). It uses prefab geometry to compute spacing thresholds, transform positions to derive real distances, accounts for relative speeds and braking characteristics of the other object (if a vehicle), and then computes the maximum braking speed at which the subject can safely approach. If the computed max braking speed is lower than current m_MaxSpeed, it updates m_MaxSpeed and records the blocker entity and blocker type. The ignore parameter can be used to force a minimum speed (1f) in cases where the object should be ignored in practice but still needs special handling. -
Parameters:
- obj: the potentially blocking object entity.
- blockerType: Cross/Continuing/Limit/Signal etc.
- objectSpeed: forward speed of the object along the curve.
- laneOffset: object's offset along the lane/curve (normalized).
- distanceFactor: multiplier to scale perceived distance (used for parallel lanes/partials).
- distanceOffset: baseline offset added to the distance used in braking checks.
- ignore: if true, allows selecting a minimal speed (1f) rather than fully zeroing movement in some ignore scenarios.
Usage Example
// Example: creating and using a WatercraftLaneSpeedIterator inside a system.
// This pseudocode shows how to initialize the iterator and run iteration over lanes.
// Real usage must provide valid ComponentLookup/BufferLookup instances (from system.GetComponentLookup / GetBufferLookup)
// and correct Entity / curve offsets computed by other simulation code.
var iterator = new WatercraftLaneSpeedIterator
{
m_TransformData = transformLookup,
m_MovingData = movingLookup,
m_WatercraftData = watercraftLookup,
m_LaneReservationData = laneReservationLookup,
m_LaneSignalData = laneSignalLookup,
m_CurveData = curveLookup,
m_CarLaneData = carLaneLookup,
m_PrefabRefData = prefabRefLookup,
m_PrefabObjectGeometryData = prefabGeomLookup,
m_PrefabWatercraftData = prefabWatercraftLookup,
m_LaneOverlapData = laneOverlapBufferLookup,
m_LaneObjectData = laneObjectBufferLookup,
m_Entity = subjectEntity,
m_Ignore = ignoredEntity,
m_Priority = myPriority,
m_TimeStep = deltaTime,
m_SafeTimeStep = safeDeltaTime,
m_SpeedLimitFactor = 1.0f,
m_CurrentSpeed = currentSpeed,
m_PrefabWatercraft = myPrefabWatercraft,
m_PrefabObjectGeometry = myObjectGeom,
m_SpeedRange = new Bounds1(minSpeed, maxSpeed),
m_MaxSpeed = maxSpeedStart,
m_CanChangeLane = 1f,
m_CurrentPosition = startPosition,
m_Distance = 0f,
m_Blocker = Entity.Null,
m_BlockerType = BlockerType.None
};
// Example call: iterate the first lane segment
bool shouldStopScanning = iterator.IterateFirstLane(someLaneEntity, new float3(startOffset, midOffset, endOffset));
if (!shouldStopScanning)
{
// Continue calling IterateNextLane / IterateFirstLane as needed along route
bool needSignal;
iterator.IterateNextLane(nextLaneEntity, new float2(nextStart, nextMid), minOffset, out needSignal);
}
// After iteration you can read iterator.m_MaxSpeed, iterator.m_Blocker, iterator.m_BlockerType
Notes for modders: - This iterator relies heavily on ECS ComponentLookup/BufferLookup semantics. When used in a Job you must obtain the correct, up-to-date lookups from your System (and mark appropriate read/write permissions). - The iterator mutates many of its public fields; treat it as a transient object used per-vehicle per-tick. - Many internal calculations assume normalized curve offsets and correct curve lengths. Supplying incorrect offsets can produce incorrect braking and blocker results. - The iterator is performance-critical in the vehicle simulation; avoid expensive managed calls inside loops and prefer the provided lookups and math operations.