add Support for XR anchors #442
Conversation
📝 WalkthroughWalkthroughAdds WebXR Anchors: WebGL JS bindings and heap-backed anchor state, managed C# anchor data/events/subsystem APIs and WebXRManager surface methods, a new settings flag, package samples (prefabs, example, asmdef), and a CHANGELOG entry documenting usage. Changes
Sequence Diagram(s)sequenceDiagram
actor User
participant Manager as WebXRManager
participant Subsystem as WebXRSubsystem
participant JS as Module.WebXR
participant Browser as Browser/WebXR
participant App as Application
User->>Manager: CreateAnchorFromViewerHitTest()
Manager->>Subsystem: CreateAnchorFromViewerHitTest()
Subsystem->>JS: createAnchorFromViewerHitTest()
JS->>Browser: request anchor (viewer hit-test)
Browser-->>JS: anchor created (id, pose)
JS->>Subsystem: OnAnchorCreated(anchorId)
Subsystem->>Manager: OnAnchorCreated event
Manager->>App: OnAnchorCreated
Note over Browser,JS: per-frame anchor pose updates
Browser->>JS: anchor pose update
JS->>Subsystem: update anchorsDataArray
Subsystem->>Manager: OnAnchorUpdate(WebXRAnchorData)
Manager->>App: update GameObject transform
User->>Manager: DeleteAnchor(id)
Manager->>Subsystem: DeleteAnchor(id)
Subsystem->>JS: deleteAnchor(id)
JS->>Browser: delete anchor
Browser-->>JS: anchor deleted
JS->>Subsystem: OnAnchorDeleted(id)
Subsystem->>Manager: OnAnchorDeleted
Manager->>App: destroy GameObject
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Review rate limit: 7/8 reviews remaining, refill in 7 minutes and 30 seconds.Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (3)
Packages/webxr/Runtime/XRPlugin/WebXRSettings.cs (1)
24-25: ⚡ Quick winGate anchor operations when
anchorsfeature is not enabled.Now that
ExtraFeatureTypes.anchorsexists, runtime behavior should align with it. Anchor methods inPackages/webxr/Runtime/XRPlugin/WebXRSubsystem.cs(Lines 776-820) currently execute without checking whether anchors were requested, which can create confusing no-op/failure behavior depending on session capabilities.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@Packages/webxr/Runtime/XRPlugin/WebXRSettings.cs` around lines 24 - 25, Anchor-related methods in WebXRSubsystem (the anchor add/remove/update APIs) must be gated by the new ExtraFeatureTypes.anchors flag; update the anchor methods (e.g., the methods that currently run between the previous block ~776-820 — TryAddAnchor/TryRemoveAnchor or similarly named anchor ops) to first check whether anchors were requested/enabled and immediately return the appropriate failure/no-op if not. Concretely, locate the anchor operation methods in WebXRSubsystem, add a guard that checks the requested/session features for ExtraFeatureTypes.anchors (or the subsystem’s requestedFeatures/sessionFeatures set) and short-circuit the operation with a clear false/early-return when anchors are not enabled, so anchors never run unless ExtraFeatureTypes.anchors was requested.Packages/webxr/Runtime/XRPlugin/WebXRSubsystem.cs (1)
235-249: 💤 Low valueConsider initializing the
anchorsarray upfront.Currently,
WebXRAnchorDataobjects are lazily created on everyUpdateAnchorscall. Since the array size is fixed at 32, initializing all slots once (e.g., inInternalStart) would avoid repeated null checks.♻️ Proposed initialization
Add to
InternalStart():private void InternalStart() { + for (int i = 0; i < MaxWebXRAnchors; i++) + { + anchors[i] = new WebXRAnchorData { frame = -1, id = -1 }; + } `#if` UNITY_WEBGL Native.SetWebXREvents(OnStartAR, OnStartVR, UpdateVisibilityState, OnEndXR, OnXRCapabilities, OnInputProfiles);Then simplify
UpdateAnchors:private void UpdateAnchors() { for (int i = 0; i < MaxWebXRAnchors; i++) { - if (anchors[i] == null) - { - anchors[i] = new WebXRAnchorData { frame = -1, id = -1 }; - } - if (GetAnchorFromAnchorsArray(i, anchors[i])) { OnAnchorUpdate?.Invoke(anchors[i]); } } }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@Packages/webxr/Runtime/XRPlugin/WebXRSubsystem.cs` around lines 235 - 249, The anchors array is lazily populated every UpdateAnchors call causing repeated null checks; in InternalStart() preallocate and initialize anchors[0..MaxWebXRAnchors-1] with new WebXRAnchorData { frame = -1, id = -1 } so UpdateAnchors can assume anchors[i] is non-null; keep using GetAnchorFromAnchorsArray(i, anchors[i]) and OnAnchorUpdate?.Invoke(anchors[i]) but remove the per-iteration null creation logic to rely on the preinitialized anchors array.Packages/webxr/Samples~/Anchors/Scripts/WebXRAnchorExample.cs (1)
56-68: 💤 Low valueConsider adding a null check for
anchoredPrefab.If
anchoredPrefabis not assigned in the Inspector,Instantiate(anchoredPrefab)will throw aNullReferenceException.🛡️ Proposed defensive check
private void OnAnchorUpdate(WebXRAnchorData anchor) { if (!anchor.tracked) return; if (!instances.TryGetValue(anchor.id, out Transform instance)) { + if (anchoredPrefab == null) + { + Debug.LogWarning("WebXRAnchorExample: anchoredPrefab is not assigned."); + return; + } instance = Instantiate(anchoredPrefab); instances.Add(anchor.id, instance); } instance.SetPositionAndRotation(anchor.position, anchor.rotation); }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@Packages/webxr/Samples`~/Anchors/Scripts/WebXRAnchorExample.cs around lines 56 - 68, OnAnchorUpdate can throw a NullReferenceException if anchoredPrefab is not set; add a defensive null check for the anchoredPrefab before calling Instantiate(anchoredPrefab) (e.g., if anchoredPrefab is null, log a warning via Debug.LogWarning and return), ensuring you still respect the tracked check and avoid adding to instances; update the logic around instances.TryGetValue / Instantiate in OnAnchorUpdate to early-exit when anchoredPrefab is null so Instantiate is never called with a null prefab.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@Packages/webxr/Runtime/XRPlugin/WebXRSettings.cs`:
- Around line 24-25: Anchor-related methods in WebXRSubsystem (the anchor
add/remove/update APIs) must be gated by the new ExtraFeatureTypes.anchors flag;
update the anchor methods (e.g., the methods that currently run between the
previous block ~776-820 — TryAddAnchor/TryRemoveAnchor or similarly named anchor
ops) to first check whether anchors were requested/enabled and immediately
return the appropriate failure/no-op if not. Concretely, locate the anchor
operation methods in WebXRSubsystem, add a guard that checks the
requested/session features for ExtraFeatureTypes.anchors (or the subsystem’s
requestedFeatures/sessionFeatures set) and short-circuit the operation with a
clear false/early-return when anchors are not enabled, so anchors never run
unless ExtraFeatureTypes.anchors was requested.
In `@Packages/webxr/Runtime/XRPlugin/WebXRSubsystem.cs`:
- Around line 235-249: The anchors array is lazily populated every UpdateAnchors
call causing repeated null checks; in InternalStart() preallocate and initialize
anchors[0..MaxWebXRAnchors-1] with new WebXRAnchorData { frame = -1, id = -1 }
so UpdateAnchors can assume anchors[i] is non-null; keep using
GetAnchorFromAnchorsArray(i, anchors[i]) and OnAnchorUpdate?.Invoke(anchors[i])
but remove the per-iteration null creation logic to rely on the preinitialized
anchors array.
In `@Packages/webxr/Samples`~/Anchors/Scripts/WebXRAnchorExample.cs:
- Around line 56-68: OnAnchorUpdate can throw a NullReferenceException if
anchoredPrefab is not set; add a defensive null check for the anchoredPrefab
before calling Instantiate(anchoredPrefab) (e.g., if anchoredPrefab is null, log
a warning via Debug.LogWarning and return), ensuring you still respect the
tracked check and avoid adding to instances; update the logic around
instances.TryGetValue / Instantiate in OnAnchorUpdate to early-exit when
anchoredPrefab is null so Instantiate is never called with a null prefab.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 917fe127-f323-42ce-b428-f5e7ef1cc3e0
⛔ Files ignored due to path filters (6)
Packages/webxr/Samples~/Anchors/Prefabs/Anchor.prefabis excluded by!**/*.prefabPackages/webxr/Samples~/Anchors/Prefabs/Blue.matis excluded by!**/*.matPackages/webxr/Samples~/Anchors/Prefabs/Green.matis excluded by!**/*.matPackages/webxr/Samples~/Anchors/Prefabs/Red.matis excluded by!**/*.matPackages/webxr/Samples~/Anchors/Prefabs/Transparent.matis excluded by!**/*.matPackages/webxr/Samples~/Anchors/Prefabs/WebXRAnchor.prefabis excluded by!**/*.prefab
📒 Files selected for processing (21)
Packages/webxr/CHANGELOG.mdPackages/webxr/Runtime/Plugins/WebGL/webxr.jslibPackages/webxr/Runtime/Plugins/WebGL/webxr.jsprePackages/webxr/Runtime/Scripts/WebXRControllerData.csPackages/webxr/Runtime/Scripts/WebXRManager.Anchors.csPackages/webxr/Runtime/Scripts/WebXRManager.Anchors.cs.metaPackages/webxr/Runtime/Scripts/WebXRManager.csPackages/webxr/Runtime/XRPlugin/WebXRSettings.csPackages/webxr/Runtime/XRPlugin/WebXRSubsystem.csPackages/webxr/Samples~/Anchors/Prefabs/Anchor.prefab.metaPackages/webxr/Samples~/Anchors/Prefabs/Blue.mat.metaPackages/webxr/Samples~/Anchors/Prefabs/Green.mat.metaPackages/webxr/Samples~/Anchors/Prefabs/Red.mat.metaPackages/webxr/Samples~/Anchors/Prefabs/Transparent.mat.metaPackages/webxr/Samples~/Anchors/Prefabs/WebXRAnchor.prefab.metaPackages/webxr/Samples~/Anchors/Scripts.metaPackages/webxr/Samples~/Anchors/Scripts/WebXRAnchorExample.csPackages/webxr/Samples~/Anchors/Scripts/WebXRAnchorExample.cs.metaPackages/webxr/Samples~/Anchors/WebXRAnchorSample.asmdefPackages/webxr/Samples~/Anchors/WebXRAnchorSample.asmdef.metaPackages/webxr/package.json
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@Packages/webxr/Runtime/Plugins/WebGL/webxr.jspre`:
- Around line 1263-1306: Async createAnchor promises (from
this.lastViewerHitTestResult.createAnchor and frame.createAnchor) can resolve
after onEndSession or a new session starts and incorrectly call
thisXRMananger.registerAnchor; fix by capturing a current session token or
reference before calling createAnchor (e.g., const activeSession = session or a
sessionCounter snapshot) and, in each .then/.catch, verify the captured token
still matches the live session (or that session is not ended) before calling
thisXRMananger.registerAnchor; if it doesn't match, drop the result and
optionally clean up the late anchor. Apply the same guard to all three async
creation branches that call createAnchor.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 2e994e1d-3911-4a17-85f3-c1db7024db59
📒 Files selected for processing (2)
Packages/webxr/CHANGELOG.mdPackages/webxr/Runtime/Plugins/WebGL/webxr.jspre
✅ Files skipped from review due to trivial changes (1)
- Packages/webxr/CHANGELOG.md
| this.lastViewerHitTestResult.createAnchor().then(function(anchor) { | ||
| thisXRMananger.registerAnchor(anchor); | ||
| }).catch(function(error) { | ||
| console.warn('Could not create WebXR anchor from hit-test result:', error); | ||
| }); | ||
| } else if (request.type == 'wait-viewer-hit-test') { | ||
| if (!this.lastViewerHitTestResult) { | ||
| console.info('Cannot create WebXR anchor now will try again.'); | ||
| this.pendingAnchorRequests.push(request); | ||
| continue; | ||
| } | ||
|
|
||
| if (!this.lastViewerHitTestResult.createAnchor) { | ||
| console.warn('Cannot create WebXR anchor: XRHitTestResult.createAnchor is unavailable.'); | ||
| continue; | ||
| } | ||
|
|
||
| this.lastViewerHitTestResult.createAnchor().then(function(anchor) { | ||
| thisXRMananger.registerAnchor(anchor); | ||
| }).catch(function(error) { | ||
| console.warn('Could not create WebXR anchor from hit-test result:', error); | ||
| }); | ||
| } else if (request.type == 'pose') { | ||
| if (!frame.createAnchor || !window.XRRigidTransform) { | ||
| console.warn('Cannot create WebXR anchor: XRFrame.createAnchor or XRRigidTransform is unavailable.'); | ||
| continue; | ||
| } | ||
|
|
||
| var transform = new XRRigidTransform( | ||
| { | ||
| x: request.position.x, | ||
| y: request.position.y, | ||
| z: -request.position.z | ||
| }, | ||
| { | ||
| x: -request.rotation.x, | ||
| y: -request.rotation.y, | ||
| z: request.rotation.z, | ||
| w: request.rotation.w | ||
| } | ||
| ); | ||
|
|
||
| frame.createAnchor(transform, session.refSpace).then(function(anchor) { | ||
| thisXRMananger.registerAnchor(anchor); |
There was a problem hiding this comment.
Guard async anchor creation against session teardown.
These createAnchor(...).then(...) callbacks can resolve after onEndSession() runs or after a new XR session starts. In that case registerAnchor() will recreate stale entries, fire onAnchorCreated, and leak anchors into the next session. Capture the current session (or a monotonically increasing session token) and ignore/delete late results before registering them.
💡 One way to harden the callbacks
- this.lastViewerHitTestResult.createAnchor().then(function(anchor) {
- thisXRMananger.registerAnchor(anchor);
+ this.lastViewerHitTestResult.createAnchor().then(function(anchor) {
+ if (thisXRMananger.xrSession !== session || !session.isInSession) {
+ if (anchor && anchor.delete) {
+ anchor.delete();
+ }
+ return;
+ }
+ thisXRMananger.registerAnchor(anchor);
}).catch(function(error) {
console.warn('Could not create WebXR anchor from hit-test result:', error);
});Apply the same guard to the other two async creation branches in this block.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@Packages/webxr/Runtime/Plugins/WebGL/webxr.jspre` around lines 1263 - 1306,
Async createAnchor promises (from this.lastViewerHitTestResult.createAnchor and
frame.createAnchor) can resolve after onEndSession or a new session starts and
incorrectly call thisXRMananger.registerAnchor; fix by capturing a current
session token or reference before calling createAnchor (e.g., const
activeSession = session or a sessionCounter snapshot) and, in each .then/.catch,
verify the captured token still matches the live session (or that session is not
ended) before calling thisXRMananger.registerAnchor; if it doesn't match, drop
the result and optionally clean up the late anchor. Apply the same guard to all
three async creation branches that call createAnchor.
De-Panther
left a comment
There was a problem hiding this comment.
Sorry, but here I'm going to disappoint you.
My plan for anchors is implementing XRAnchorSubsystem for ARFoundation.
That way existing experiences that use the OpenXR package with anchors won't need changes. (Or will need minimum changes)
You can look at WebXRLoader on how to init and manage some XR Subsystems.
I think it is possible with your current JS changes.
In the future I would also like to switch to ARFoundation XRRaycastSubsystem for the hit-test.
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
Packages/webxr/Runtime/XRPlugin/WebXRSubsystem.cs (1)
580-585:⚠️ Potential issue | 🟠 Major | ⚡ Quick winDrop anchor callbacks once the XR session is no longer active.
Anchor creation/deletion completes via callbacks, but
OnEndXR()only flips the state. A completion that arrives after teardown will still raiseOnAnchorCreated/OnAnchorDeleted, which leaks anchor lifecycle events from a dead AR session.Suggested fix
[MonoPInvokeCallback(typeof(AnchorCreatedEvent))] public static void OnAnchorCreatedInternal(int anchorId) { + if (Instance == null || Instance.xrState != WebXRState.AR) + { + return; + } OnAnchorCreated?.Invoke(anchorId); } [MonoPInvokeCallback(typeof(AnchorDeletedEvent))] public static void OnAnchorDeletedInternal(int anchorId) { + if (Instance == null || Instance.xrState != WebXRState.AR) + { + return; + } OnAnchorDeleted?.Invoke(anchorId); }Also applies to: 587-597
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@Packages/webxr/Runtime/XRPlugin/WebXRSubsystem.cs` around lines 580 - 585, OnEndXR currently only flips state, but anchor lifecycle callbacks (OnAnchorCreated/OnAnchorDeleted) can still fire after teardown and leak events; update OnEndXR to unregister or clear any anchor-related callbacks/delegates (e.g., remove listeners for OnAnchorCreated and OnAnchorDeleted) or set a session-ended flag on Instance that the anchor handlers check and return early, and ensure the same change is applied to the similar teardown block around the 587-597 region so no anchor callbacks are processed after webXRLoader.EndEssentialSubsystems() and Instance.setXrState(...) are called.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@Packages/webxr/Runtime/XRPlugin/WebXRSubsystem.cs`:
- Around line 237-239: The guard currently only returns when settings exists and
the anchors flag is off, which allows code to proceed when
WebXRSettings.GetSettings() is null; change each occurrence to explicitly
require the anchors feature by returning early when settings is null OR the
anchors flag is not set (i.e. replace conditions like "if (settings != null &&
!settings.AROptionalFeatures.HasFlag(WebXRSettings.ExtraFeatureTypes.anchors))"
with "if (settings == null ||
!settings.AROptionalFeatures.HasFlag(WebXRSettings.ExtraFeatureTypes.anchors))"
so the polling and the anchor create/delete API paths never run unless the
anchors feature is explicitly present).
---
Outside diff comments:
In `@Packages/webxr/Runtime/XRPlugin/WebXRSubsystem.cs`:
- Around line 580-585: OnEndXR currently only flips state, but anchor lifecycle
callbacks (OnAnchorCreated/OnAnchorDeleted) can still fire after teardown and
leak events; update OnEndXR to unregister or clear any anchor-related
callbacks/delegates (e.g., remove listeners for OnAnchorCreated and
OnAnchorDeleted) or set a session-ended flag on Instance that the anchor
handlers check and return early, and ensure the same change is applied to the
similar teardown block around the 587-597 region so no anchor callbacks are
processed after webXRLoader.EndEssentialSubsystems() and
Instance.setXrState(...) are called.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 5ff29e1c-cf25-4695-a687-634e880cf0e0
📒 Files selected for processing (1)
Packages/webxr/Runtime/XRPlugin/WebXRSubsystem.cs
|
Thanks, that makes sense. I agree that The current implementation was created to unblock a customer project, and for that use case the anchors are working well already. Because of that, I cannot invest the time for a proper I think the current JS anchor backend could still be useful as a starting point for the subsystem implementation. Would you prefer me to close this PR for now, or keep it open as a prototype/reference until I or someone else can pick up the subsystem approach? |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@Packages/webxr/Runtime/XRPlugin/WebXRSubsystem.cs`:
- Around line 833-845: In DeleteAnchor, validate the public API parameter before
calling into native: check that the anchorId parameter is non-negative (e.g.,
anchorId >= 0) and bail out (or log and return) if it is negative, then only
call Native.DeleteAnchor(anchorId); update the guard in the DeleteAnchor method
(and keep the existing UNITY_WEBGL / AnchorsFeatureEnabled checks) to prevent
forwarding invalid anchor IDs to Native.DeleteAnchor.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 073b3077-478b-4989-8c92-98e5005f3bb8
📒 Files selected for processing (1)
Packages/webxr/Runtime/XRPlugin/WebXRSubsystem.cs
| public void DeleteAnchor(int anchorId) | ||
| { | ||
| #if UNITY_WEBGL | ||
| if (xrState != WebXRState.AR) | ||
| { | ||
| return; | ||
| } | ||
| if (!AnchorsFeatureEnabled()) | ||
| { | ||
| return; | ||
| } | ||
| Native.DeleteAnchor(anchorId); | ||
| #endif |
There was a problem hiding this comment.
Validate anchorId before native delete call.
Line 844 currently forwards any integer to native code. Since this is a public API, add a non-negative guard to prevent invalid calls from misuse paths.
Suggested patch
public void DeleteAnchor(int anchorId)
{
`#if` UNITY_WEBGL
if (xrState != WebXRState.AR)
{
return;
}
if (!AnchorsFeatureEnabled())
{
return;
}
+ if (anchorId < 0)
+ {
+ return;
+ }
Native.DeleteAnchor(anchorId);
`#endif`
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| public void DeleteAnchor(int anchorId) | |
| { | |
| #if UNITY_WEBGL | |
| if (xrState != WebXRState.AR) | |
| { | |
| return; | |
| } | |
| if (!AnchorsFeatureEnabled()) | |
| { | |
| return; | |
| } | |
| Native.DeleteAnchor(anchorId); | |
| #endif | |
| public void DeleteAnchor(int anchorId) | |
| { | |
| `#if` UNITY_WEBGL | |
| if (xrState != WebXRState.AR) | |
| { | |
| return; | |
| } | |
| if (!AnchorsFeatureEnabled()) | |
| { | |
| return; | |
| } | |
| if (anchorId < 0) | |
| { | |
| return; | |
| } | |
| Native.DeleteAnchor(anchorId); | |
| `#endif` | |
| } |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@Packages/webxr/Runtime/XRPlugin/WebXRSubsystem.cs` around lines 833 - 845, In
DeleteAnchor, validate the public API parameter before calling into native:
check that the anchorId parameter is non-negative (e.g., anchorId >= 0) and bail
out (or log and return) if it is negative, then only call
Native.DeleteAnchor(anchorId); update the guard in the DeleteAnchor method (and
keep the existing UNITY_WEBGL / AnchorsFeatureEnabled checks) to prevent
forwarding invalid anchor IDs to Native.DeleteAnchor.
|
Yes, the JS code is a start. |
Summary by CodeRabbit