Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: nested snap zone is not grabbable by default #57

Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 23 additions & 12 deletions Runtime/Interaction/SnapZone.cs
Original file line number Diff line number Diff line change
Expand Up @@ -152,24 +152,22 @@ public Mesh PreviewMesh
previewMesh = value;
}
}

private Material activeMaterial;

private List<Validator> validators = new List<Validator>();

private Transform initialParent;
private Material activeMaterial;
private Vector3 tmpCenterOfMass;

private List<Validator> validators = new List<Validator>();

protected override void Awake()
{
base.Awake();

validators = GetComponents<Validator>().ToList();

Collider triggerCollider = gameObject.GetComponentsInChildren<Collider>().FirstOrDefault(foundCollider => foundCollider.isTrigger);
if (triggerCollider == null)
validators = GetComponents<Validator>().ToList();

if (GetComponentsInChildren<Collider>()?.Any(foundCollider => foundCollider.isTrigger) == false)
{
Debug.LogErrorFormat(gameObject, "The Snap Zone '{0}' does not have any trigger collider. "
+ "Make sure you have at least one collider with the property `Is Trigger` enabled.", gameObject.name);
Debug.LogError($"The Snap Zone '{name}' does not have any trigger collider. "
+ "Make sure you have at least one collider with the property `Is Trigger` enabled.", gameObject);
}

ShowHighlightObject = ShownHighlightObject != null;
Expand All @@ -180,12 +178,19 @@ protected override void Awake()
{
UpdateHighlightMeshFilterCache();
}

initialParent = transform.parent;

if (initialParent != null)
{
transform.SetParent(null);
}
}

protected override void OnEnable()
{
base.OnEnable();

onSelectEnter.AddListener(OnAttach);
onSelectExit.AddListener(OnDetach);
}
Expand Down Expand Up @@ -218,6 +223,12 @@ private void OnDrawGizmos()

protected virtual void Update()
{
if (initialParent != null)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any particular reason to have it here and not in Start() or Update()?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes.

The interactables register all their child colliders as part of it in the interaction manager at their Awake.

The idea is to deattach the snap zone from the interactable object and reattach it at the next first frame.

Unfortunately, the Awake and OnEnable from all interactors are called before than the Awake and OnEnable from all interactables so Awake and OnEnable are not an optional.

Additionally, Sockets already have a private Start, so calling a start will override their own and since it is private, there is no way to call as base.

The workaround I found is to call only once in the first frame in the Update, I don't entirely like it but, we can change it if the XR interaction framework becomes less private in the future.

{
transform.SetParent(initialParent);
initialParent = null;
}

if (socketActive && selectTarget == null)
{
DrawHighlightMesh();
Expand Down