Spawn Hints
Optional Spawn Hints - can be used by all spawner types
The Spawn Hints System provides authored control over where units appear during runtime.
Instead of relying entirely on procedural sampling, designers can place EnemySpawnHintPoint markers to bias or constrain spawn placement.
When enabled, the spawner will first attempt to use valid hint points near the spawn request location. If no hints qualify, it can either fall back to normal sampling or skip the spawn entirely depending on your configuration.
1. Enabling Spawn Hints
Select your RuntimeSpawner in the scene.
Enable Use Spawn Hints in the inspector.
Create and assign a Spawn Hint Settings asset:
Create → Runtime Spawner → Spawn Hint SettingsPlace
SpawnHintPointcomponents throughout your level:GameObject → Runtime Spawner → Create Enemy Spawn Hint
Tip: If you want strictly authored placement, enable Hint-Only in the settings to disable fallback sampling entirely.
2. How It Works
For each spawn request (Global, Region, or Wave):
Build a search circle:
Global: Radius = Cull Distance × Global Search Fraction
Region: Region bounds + Region Search Padding
Wave: Wave anchor range + Wave Search Padding
Filter by tags: If a
WaveSpawnPointhas Anchor Tags, hints with matching tags are preferred first.Evaluate candidates (up to
Max Hint Attempts):Check distance to player against hint
MinPlayerDist/MaxPlayerDist.If
Ignore Spawner’s Global Min Rangeis OFF, the spawner’s global minimum range is also enforced.
If Deny Line Of Sight is true, reject hints visible to the player (uses
LOS Block Mask).If Require NavMesh is true, project the position to the NavMesh (respecting the hint’s override area mask or the spawner’s default).
When a hint passes all checks, it’s soft-reserved for
Reservation Secondsto avoid overlapping bursts.
No hint qualifies:
Hint-Only OFF → Fall back to standard procedural sampling.
Hint-Only ON → Skip the spawn entirely.
3. Key Settings (Spawn Hint Settings Asset)
Hint-Only (no fallback)
Only spawn on hints; skip spawns if none qualify.
Ignore Spawner’s Global Min Range
Allows near-player hints even when the spawner’s Minimum Spawn Range is large.
Global Search Fraction / Region & Wave Padding
How far the system searches for hints per mode.
NavMesh Sample Max Dist
Maximum projection distance when Require NavMesh is true.
LOS Block Mask
Layers used for Line-of-Sight checks (camera visibility).
Reservation Seconds
Cooldown before a used hint becomes available again.
Max Hint Attempts
Cap on how many hints are evaluated per query.
Prefer Scoped First
Prefer hints inside the immediate scope (wave/region) before global search.
Debug Logs
Enable for detailed reasoning about candidate rejection (distance, LOS, reservation, etc.).
4. Authoring Tips
Place 2–5 hints per tile or encounter pocket (flanks, corners, behind cover).
Use Deny Line Of Sight to prevent pop-in near the player’s view direction.
Adjust Min/Max Player Distance per hint to control when it becomes eligible.
For grounded AI or uneven terrain, enable Require NavMesh on the hint.
Keep the
cellSizein settings modest (e.g., 4–8) for efficient spatial queries.
5. Example Workflow
Create a Spawn Hint Settings asset and assign it to your Runtime Spawner.
Place several
EnemySpawnHintPointcomponents around likely encounter spots.Adjust hint distances and line-of-sight options.
Toggle Debug Logs while testing to visualize hint use and rejection reasons.
In Play Mode, validate that enemies appear at expected authored locations.
If spawns are too sparse, lower
Reservation Secondsor increaseGlobal Search Fraction.
6. Troubleshooting
“Nothing spawns with Hint-Only”
Hints may be inside the spawner’s Minimum Spawn Range.
Enable Ignore Spawner’s Global Min Range, or lower the spawner’s min distance.
Player may be too far (outside hint’s
MaxPlayerDist).NavMesh projection failed — increase
NavMesh Sample Max Distor relax the area mask.For waves, ensure at least one hint shares the wave’s Anchor Tags (or clear the tags to accept any).
“Hints are ignored even when close”
Search radius too small — adjust padding or global fraction.
Hint may still be reserved — wait out the
Reservation Secondsor increase available hints.Enable Debug Logs in settings to see exact rejection causes (distance, LOS, reservation, NavMesh).
“Spawner warns about all hints being ineligible”
This happens when the Minimum Spawn Range exceeds all hint distances.
Enable Ignore Spawner’s Global Min Range in settings to fix it.
7. Debug Visualization
When Debug Logs are active:
Each tested hint draws a color-coded gizmo:
Green = valid and selected
Yellow = reserved
Red = rejected (LOS, distance, NavMesh)
Console logs show detailed reasoning for candidate failures and fallback decisions.
8. Best-Practice Patterns
Fully curated encounters
Enable Hint-Only, place hints manually, tune distances.
Semi-authored procedural mix
Use Prefer Scoped First with fallback enabled.
Fast waves / horde gameplay
Lower Reservation Seconds, increase Max Hint Attempts.
Dynamic or large maps
Adjust Global Search Fraction to cover broader areas.
✅ Summary
Spawn Hints give you granular control over where the Runtime Spawner places enemies, balancing authored intent with runtime flexibility.
By combining hint tagging, distance/LOS checks, and per-hint NavMesh validation, you can design encounters that feel deliberate, performant, and adaptable across multiple game modes.
Recommended setup:
Use hints for high-impact encounters (ambushes, flanks, scripted reveals).
Keep procedural fallback enabled for background or ambient spawns.
Fundamentals
SpawnHintPoint is a lightweight authoring component that marks good spawn locations in the scene.
These hints are used at runtime by the spawn locator (ISpawnLocator / SpawnLocator) when Spawn Hints are enabled in RuntimeSpawner.
Hints:
Are placed directly in the level (tiles, rooms, corridors).
Encode simple rules about player distance, line of sight, and NavMesh.
Can be tagged so waves or specials can request specific types of positions (“Flank”, “Ambush”, etc.).
When a SpawnHintPoint is enabled, it automatically registers with SpawnHintRegistry. When disabled, it unregisters.
Typical Usage
Place
SpawnHintPointcomponents in areas that work well for combat:Corners, flanks, behind cover, balcony edges, etc.
Adjust:
minPlayerDistandmaxPlayerDistto avoid spawns too close/too far from the player.denyLineOfSightto prevent obvious pop-in directly in front of the player.
Optionally:
Enable
requireNavMeshso hints are validated against the NavMesh.Set
tagsand have your waves/specials request those tags via their spawn context (SpawnContext.HintTags).
The RuntimeSpawner config controls whether spawn hints are used at all:
spawner.UseSpawnHints = true;
spawner.HintSettings = yourSpawnHintSettings;Once enabled, the locator will query SpawnHintRegistry and prefer hint positions over purely random sampling.
Fields and Rules
Visual Radius & Weight
[Min(0.1f)]
public float radius = 2f;
[Min(0f)]
public float weight = 1f;radiusVisual radius for the hint.
May also be treated as a local sampling radius if your game chooses to jitter positions around the hint.
weightOptional weighting value for custom selection strategies.
The built-in
SpawnLocatordoes not use this by default, but it can be read by custom systems if needed.
Player Distance Rules
[Header("Rules")]
[Min(0f)]
public float minPlayerDist = 12f;
[Min(0f)]
public float maxPlayerDist = 0f; // 0 = no upper limitminPlayerDistMinimum allowed distance between the player and this hint for it to be considered eligible.maxPlayerDistMaximum allowed distance:0means “no upper limit”.Any value > 0 will be treated as a hard maximum.
Hints outside the [minPlayerDist, maxPlayerDist] range for the current player position are ignored.
Line of Sight & NavMesh
[Tooltip("If true, reject if player has clear line of sight to the spawn point.")]
public bool denyLineOfSight = true;
[Tooltip("Require NavMesh within this hint's radius.")]
public bool requireNavMesh = true;denyLineOfSightIf
true, this hint is rejected when the player has a clear line of sight to it.LOS checks use
SpawnHintSettings.losBlockMask.
requireNavMeshIf
true, the hint is only accepted if a valid NavMesh position can be found near it.Sampling distance and area mask are controlled by
SpawnHintSettings.navSampleMaxDistand the hint’soverrideAreaMask(if set).
These rules are evaluated by the locator when it filters potential hints.
Tags and NavMesh Area Overrides
[Tooltip("Restrict to these tags if the spawn request asks for them.")]
public string[] tags;
[Tooltip("Optional: prefer specific NavMesh areas for this hint (0 = use spawner's mask).")]
public int overrideAreaMask = 0;tagsOptional semantic tags (e.g.,"Flank","Ambush","Backline"). When a spawn request includesHintTagsin itsSpawnContext, the locator:First searches for hints whose
tagsshare at least one entry with the request.If none are found, it falls back to any eligible hint.
overrideAreaMaskOptional NavMesh area mask override:0means “use the global area mask from the spawner/locator”.A non-zero value can constrain this hint to specific NavMesh areas (e.g., only walkable, only cover areas, etc.).
Registration Lifecycle
private void OnEnable() => SpawnHintRegistry.Register(this);
private void OnDisable() => SpawnHintRegistry.Unregister(this);OnEnableRegisters this hint with the globalSpawnHintRegistry.OnDisableUnregisters this hint and clears any reservations.
Hints are therefore only considered for placement while their component is enabled.
Example Workflows
1. Basic hint layout on a combat tile
Place 4–6
SpawnHintPointobjects around a combat arena:Two behind cover (
tags = ["Flank"],denyLineOfSight = true).One or two at long range (
minPlayerDist = 18,maxPlayerDist = 30).A couple of mid-range hints (
minPlayerDist = 12,maxPlayerDist = 24).
At runtime, with spawn hints enabled in RuntimeSpawner, ambient or wave spawns will naturally gravitate to these positions instead of appearing in awkward spots.
2. Using tags from a wave or special
When building a SpawnContext for a wave or special, you can provide hint tags:
var ctx = spawner.BuildWaveContext(trigger, point, range, groupParent);
ctx.HintTags = new[] { "Flank", "Ambush" };The locator will then:
Prefer hints whose
SpawnHintPoint.tagscontains"Flank"or"Ambush".Apply distance, LOS and NavMesh checks to those candidates.
Only fall back to generic hints if no tagged candidates are valid.
This allows different encounter types to express “where” they want to appear without hand-picking positions in code.
Last updated