Skip to content

feat: point at in world#7305

Open
lorenzo-ranciaffi wants to merge 103 commits intodevfrom
shape/point-at-in-world
Open

feat: point at in world#7305
lorenzo-ranciaffi wants to merge 103 commits intodevfrom
shape/point-at-in-world

Conversation

@lorenzo-ranciaffi
Copy link
Contributor

@lorenzo-ranciaffi lorenzo-ranciaffi commented Mar 2, 2026

Pull Request Description

Fixes #7301

Protocol PR
Notion Page

What does this PR change?

This PR introduces the point-at feature: users are now able to point at things in world using the middle click mouse button.
When pointing at something, if the hit is near enough, a marker will appear at the point (only for friends). Avatars never generate a hit marker.
By pointing at something, the avatar reacts with a pointing pose that is solved with IK.

The whole action/marker is shared between clients.

The marker uses the SpriteData of the Profile attached to the ECS entity. There was a bug where sprites were loaded incorrectly due to a hash clash caused by the exclusion of AvatarTextureUserId in the hash. Now every Profile carries the right sprite data (local player included).

Test Instructions

Prerequisites

  • use multiple clients to test the network behaviour
  • launch the client with the flag --debug --point-at

Test Steps

  1. Pointing at something and clicking the middle mouse button will trigger the pointing pose if
    • you are not moving
    • the avatar is grounded
    • the avatar is not stunned
    • you are not pointing at a remote avatar that is closer than 1.5m from you
  2. Emote action is cancelled when you point at something (and vice-versa)
  3. When you (or a friend) point at something, a marker showing the user's profile picture and color will appear on the hit position (if the hit point is > 100m, there's no marker) with a fade in/out animation and a sound
  4. By continuously pressing the button, you are able to drag the marker
    • vertical IK positions are clamped such that you are not able to glitch the avatar and the IK stops following the hit point
    • dragging in circles around the avatar makes it rotate with an animation
  5. All animations and IK poses are shared and visible by peers
  6. Make sure that all feature's reference and the feature itself is not present without the app args/feature flag

Quality Checklist

  • Changes have been tested locally
  • Documentation has been updated (if required)
  • Performance impact has been considered
  • For SDK features: Test scene is included

Code Review Reference

Please review our Code Review Standards before submitting.

@lorenzo-ranciaffi lorenzo-ranciaffi self-assigned this Mar 2, 2026
@lorenzo-ranciaffi lorenzo-ranciaffi added the shape-up It has been shaped and is awaiting the cycle. label Mar 2, 2026
@lorenzo-ranciaffi lorenzo-ranciaffi moved this from Todo to In Progress in Explorer Alpha Mar 2, 2026
@github-actions
Copy link
Contributor

github-actions bot commented Mar 2, 2026

lorenzo-ranciaffi and others added 21 commits March 2, 2026 18:19
# Conflicts:
#	Explorer/Assets/DCL/AvatarRendering/AvatarShape/Assets/Animator/CharacterAnimator.controller
#	Explorer/Assets/DCL/Character/CharacterMotion/Settings/CharacterControllerSettings.asset
#	Explorer/Assets/DCL/PluginSystem/Global/CharacterMotionPlugin.cs
#	Explorer/Assets/DCL/PluginSystem/Global/CharacterMotionSettings.cs
#	Explorer/Assets/DCL/PluginSystem/Global/Global Plugins Settings.asset
@lorenzo-ranciaffi
Copy link
Contributor Author

@claude review

@claude
Copy link
Contributor

claude bot commented Mar 18, 2026

Claude finished @lorenzo-ranciaffi's task in 3m 54s —— View job


Code Review — feat: point at in world

  • Gathering context
  • Reading changed files
  • Analyzing code quality
  • Posting review feedback

Summary

5 issues found across the new systems. Inline comments have been posted on the relevant lines.


Issues Found

# Severity File Issue
1 🔴 Bug PointAtMarkerHolder.cs:109 ResetState() does not cancel the ongoing fade CancellationTokenSource. When PointAtMarkerCleanUpSystem forcibly returns the marker to the pool, any in-flight AnimateColorAsync coroutine continues and will modify SpriteRenderer.color on a reused pooled instance, corrupting another player's marker. Fix: call fadeCts?.Cancel() inside ResetState().
2 🔴 Bug HandPointAtSystem.cs:167 result.HitPoint == Vector3.zero uses exact floating-point equality as a sentinel. If the scene has geometry at the world origin, a valid hit there triggers the far-plane fallback incorrectly. Fix: introduce a bool hitSomething flag instead of a sentinel value.
3 🟠 Performance HandPointAtSystem.cs:145 GetComponent<RemoteAvatarCollider>() is called on every raycast hit in Update(). This allocates and violates the allocation-free Update() rule. The collider→component mapping should be precomputed (e.g., a static dictionary keyed by collider, populated at instantiation).
4 🟡 Standards TorsoIKSystem.cs:39 ApplyPointAtIK query is missing [None(typeof(DeleteEntityIntention))]. All queries must exclude entities being deleted per project standards.
5 🟡 Standards RemoteHandPointAtSystem.cs:38 ApplyRemotePointAtIK query is missing [None(typeof(DeleteEntityIntention))]. Same issue as above.
6 🟡 Standards HandPointAtSystem.cs:180 Debug.DrawLine left in production code. Wrap in `#if UNITY_EDITOR

REVIEW_RESULT: FAIL ❌

@lorenzo-ranciaffi
Copy link
Contributor Author

@claude re-review

@claude
Copy link
Contributor

claude bot commented Mar 18, 2026

Claude finished @lorenzo-ranciaffi's task in 54s —— View job


Re-Review — feat: point at in world

  • Checking previously raised issues
  • Reading changed files
  • Posting results

Previous Issues — All Resolved ✅

# Severity File Status
1 🔴 Bug PointAtMarkerHolder.cs:109 Fixed — ResetState() now calls fadeCts?.SafeCancelAndDispose()
2 🔴 Bug HandPointAtSystem.cs Fixed — sentinel == Vector3.zero replaced with needRaycastFallback bool
3 🟠 Performance HandPointAtSystem.cs Fixed — GetComponent<RemoteAvatarCollider>() removed; layer check uses hit.collider.gameObject.layer (allocation-free)
4 🟡 Standards TorsoIKSystem.cs:41 Fixed — [None(typeof(DeleteEntityIntention))] added
5 🟡 Standards RemoteHandPointAtSystem.cs:40 Fixed — [None(typeof(DeleteEntityIntention))] added
6 🟡 Standards HandPointAtSystem.cs:183 Fixed — Debug.DrawLine wrapped in #if UNITY_EDITOR

REVIEW_RESULT: PASS ✅

@lorenzo-ranciaffi lorenzo-ranciaffi moved this from In Progress to With QA / Awaiting Review in Explorer Alpha Mar 19, 2026
@lorenzo-ranciaffi
Copy link
Contributor Author

@claude re-review

@claude
Copy link
Contributor

claude bot commented Mar 20, 2026

Claude finished @lorenzo-ranciaffi's task in 3m 53s —— View job


Re-Review — feat: point at in world

  • Checking previously raised issues
  • Reading changed files
  • Posting results

Previous Issues — All Resolved ✅

# Severity File Status
1 🔴 Bug PointAtMarkerHolder.cs:109 Fixed — ResetState() calls fadeCts?.SafeCancelAndDispose()
2 🔴 Bug HandPointAtSystem.cs Fixed — sentinel replaced with needRaycastFallback bool
3 🟠 Performance HandPointAtSystem.cs Fixed — GetComponent removed; layer check uses hit.collider.gameObject.layer
4 🟡 Standards TorsoIKSystem.cs:41 Fixed — [None(typeof(DeleteEntityIntention))] added
5 🟡 Standards RemoteHandPointAtSystem.cs:40 Fixed — [None(typeof(DeleteEntityIntention))] added
6 🟡 Standards HandPointAtSystem.cs:182 Fixed — Debug.DrawLine wrapped in #if UNITY_EDITOR

New Issue Found

# Severity File Issue
1 🟡 Standards PointAtMarkerHolder.cs:74 await UniTask.Yield(ct) uses exception-based cancellation. If the token fires during the yield (between the IsCancellationRequested check and the await), an OperationCanceledException escapes the UniTaskVoid, is passed to UniTask's global handler (logged as an error), and the post-loop pool?.Release(this) is bypassed. Project standard: "Handle cancellation with ct.IsCancellationRequested, never ThrowIfCancellationRequested()". Fix: use await UniTask.Yield() without the token — the top-of-loop check already handles cancellation correctly. Fix this →

REVIEW_RESULT: FAIL ❌

@lorenzo-ranciaffi
Copy link
Contributor Author

@claude re-review

@claude
Copy link
Contributor

claude bot commented Mar 20, 2026

Claude finished @lorenzo-ranciaffi's task in 43s —— View job


Re-Review — feat: point at in world

  • Checking previously raised issues
  • Reading changed files
  • Posting results

Previous Issue — Resolved ✅

# Severity File Status
1 🟡 Standards PointAtMarkerHolder.cs:74 Fixed — await UniTask.Yield(ct) changed to await UniTask.Yield(), cancellation handled by top-of-loop IsCancellationRequested check

All Prior Issues — Still Resolved ✅

# File Status
Bug PointAtMarkerHolder.cs:109 ResetState() calls fadeCts?.SafeCancelAndDispose()
Bug HandPointAtSystem.cs needRaycastFallback bool replaces sentinel
Perf HandPointAtSystem.cs GetComponent removed; layer check uses hit.collider.gameObject.layer
Standards TorsoIKSystem.cs:41 [None(typeof(DeleteEntityIntention))] present
Standards RemoteHandPointAtSystem.cs:40 [None(typeof(DeleteEntityIntention))] present
Standards HandPointAtSystem.cs:182 Debug.DrawLine wrapped in #if UNITY_EDITOR

REVIEW_RESULT: PASS ✅

lorenzo-ranciaffi and others added 6 commits March 23, 2026 11:10
# Conflicts:
#	Explorer/Assets/DCL/AvatarRendering/AvatarShape/Assets/AvatarBase.prefab
#	Explorer/Assets/DCL/AvatarRendering/AvatarShape/Systems/AvatarInstantiatorSystem.cs
#	Explorer/Assets/DCL/AvatarRendering/AvatarShape/UnityInterface/AvatarBase.cs
#	Explorer/Assets/DCL/FeatureFlags/FeatureFlagsStrings.cs
#	Explorer/Assets/DCL/FeatureFlags/FeaturesRegistry.cs
# Conflicts:
#	Explorer/Assets/DCL/Infrastructure/Global/Tests/PlayMode/IntegrationTestsSuite.cs
#	Explorer/Assets/DCL/PluginSystem/Global/AvatarPlugin.cs
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

shape-up It has been shaped and is awaiting the cycle.

Projects

Status: With QA / Awaiting Review

Development

Successfully merging this pull request may close these issues.

Shape: poit at in-world

3 participants