Project destinations to NavMesh height#49
Conversation
Sample NavMesh height for destination markers in LocationDialogueSpec and WalkToSpec so destination markers use the navmesh Y coordinate when creating NPC markers. This makes distance checks and walk completion logic consistent with where NPCs actually walk (fixes WalkResult.Partial / unreachable ReachedDestination and FaceDirection not being called).
📝 WalkthroughWalkthroughThe changes add NavMesh height alignment to destination markers in location dialogue and walk-to action specifications. A NavMesh.SamplePosition call projects destination coordinates onto the navmesh height, adjusting the y-coordinate for marker placement. Corresponding UnityEngine.AIModule.dll references are added to the project file for both IL2CPP and Mono compilation targets. Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
Tip Issue Planner is now in beta. Read the docs and try it out! Share your feedback on Discord. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
S1API/Entities/Schedule/ActionSpecs/LocationDialogueSpec.cs (1)
116-130: Consider extracting the shared NavMesh projection into a utility helper.The exact same six-line projection block (lines 118–125 here) is duplicated verbatim in
WalkToSpec.cs(lines 120–125). Extracting it keeps future radius or area-mask changes in one place.♻️ Suggested helper extraction in
NPCDestinationContainer.cs+// In NPCDestinationContainer.cs +using UnityEngine.AI; + +internal static class NPCDestinationContainer +{ + // ...existing members... + + /// <summary> + /// Projects a world position onto the NavMesh height, preserving X and Z. + /// Returns the adjusted position, or the original position if no NavMesh is found. + /// </summary> + public static Vector3 ProjectToNavMeshHeight(Vector3 position, float maxDistance = 5f) + { + if (NavMesh.SamplePosition(position, out NavMeshHit navHit, maxDistance, NavMesh.AllAreas)) + return new Vector3(position.x, navHit.position.y, position.z); + return position; + } +}Then in both specs:
- Vector3 markerPosition = Destination; - NavMeshHit navHit; - if (NavMesh.SamplePosition(Destination, out navHit, 5f, NavMesh.AllAreas)) - { - markerPosition = new Vector3(Destination.x, navHit.position.y, Destination.z); - } + Vector3 markerPosition = NPCDestinationContainer.ProjectToNavMeshHeight(Destination);Also, since
<LangVersion>latest</LangVersion>is set, the pre-C#7 two-stepoutdeclaration can be collapsed to inlineout var:- NavMeshHit navHit; - if (NavMesh.SamplePosition(Destination, out navHit, 5f, NavMesh.AllAreas)) + if (NavMesh.SamplePosition(Destination, out NavMeshHit navHit, 5f, NavMesh.AllAreas))🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@S1API/Entities/Schedule/ActionSpecs/LocationDialogueSpec.cs` around lines 116 - 130, Extract the duplicated NavMesh projection logic into a single helper (for example add a method like ProjectToNavMesh(Vector3 destination, float maxDistance = 5f, int areaMask = NavMesh.AllAreas) that returns the projected Vector3) on NPCDestinationContainer or another small utility class, then replace the six-line block in LocationDialogueSpec (the markerPosition/NavMesh.SamplePosition code) and the identical block in WalkToSpec with a call to that helper; while updating call sites, use inline out declaration (out var navHit) if you still call NavMesh.SamplePosition directly inside the helper or when testing, and pass Forward and markerPosition into NPCDestinationContainer.CreateDestinationMarker as before.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@S1API/Entities/Schedule/ActionSpecs/LocationDialogueSpec.cs`:
- Around line 120-123: NavMesh.SamplePosition call using a radius of 5f can snap
to the wrong floor on stacked NavMesh surfaces; update the SamplePosition
invocation in LocationDialogueSpec (the call using Destination and out navHit)
to use a smaller radius (e.g., 2f) to reduce cross-floor hits, and keep the
existing assignment to markerPosition (new Vector3(Destination.x,
navHit.position.y, Destination.z)) unchanged so vertical placement still uses
the sampled navHit.y when a hit occurs.
---
Nitpick comments:
In `@S1API/Entities/Schedule/ActionSpecs/LocationDialogueSpec.cs`:
- Around line 116-130: Extract the duplicated NavMesh projection logic into a
single helper (for example add a method like ProjectToNavMesh(Vector3
destination, float maxDistance = 5f, int areaMask = NavMesh.AllAreas) that
returns the projected Vector3) on NPCDestinationContainer or another small
utility class, then replace the six-line block in LocationDialogueSpec (the
markerPosition/NavMesh.SamplePosition code) and the identical block in
WalkToSpec with a call to that helper; while updating call sites, use inline out
declaration (out var navHit) if you still call NavMesh.SamplePosition directly
inside the helper or when testing, and pass Forward and markerPosition into
NPCDestinationContainer.CreateDestinationMarker as before.
Sample NavMesh height for destination markers in LocationDialogueSpec and WalkToSpec so destination markers use the navmesh Y coordinate when creating NPC markers. This makes distance checks and walk completion logic consistent with where NPCs actually walk (fixes WalkResult.Partial / unreachable ReachedDestination and FaceDirection not being called).
Release Notes
Contributor Statistics