Create two snap zones that potentially overlap each other or at are least close enough to each other that when an interactable is placed it can activate both snap zones.

Now place the interactable between the two snap zones and release it so it snaps.

The Interactable will snap to the first zone it touched.
The Interactable should only run the snap logic on the first snap zone it touches.
The snapped interactable runs the snap logic on every snap zone it is touching, which is immediately noticeable when it is trying to reset the scale of the object as the zone it first snaps to will set the size and the second zone will then cache the current size so when the object is removed it is of the wrong size.

My current solution for this is to have each Snap Drop Zone contain a Manager script that basically holds a list of all GameObjects that are currently being snapped in a static List<GameObject> so all snap zones are referring to the same global list (without the need to have a Snap Zone component manager)
Then when an object is dropped into two snap zones it will first check if it can snap the object by checking in this list, if the object doesn't appear in the list then it emits an event that then goes through the snap process and adds the item to the list.
Then the next time a zone tries to snap the item it will fail because it is in the list and therefore not run the snap process again.
Here is my proposed Manager:
```c#
namespace VRTK.Prefabs.Interactions.InteractableSnapZone
{
using UnityEngine;
using UnityEngine.Events;
using System;
using System.Collections.Generic;
using Malimbe.XmlDocumentationAttribute;
public class SnapZoneManager : MonoBehaviour
{
/// <summary>
/// Defines the event with the <see cref="GameObject"/>.
/// </summary>
[Serializable]
public class UnityEvent : UnityEvent<GameObject> { }
#region Zone Events
/// <summary>
/// Emitted when a valid <see cref="GameObject"/> is snapped to the zone.
/// </summary>
[DocumentedByXml]
public UnityEvent Validated = new UnityEvent();
/// <summary>
/// Emitted when a valid <see cref="GameObject"/> is snapped to the zone.
/// </summary>
[DocumentedByXml]
public UnityEvent NotValidated = new UnityEvent();
/// <summary>
/// Emitted when a valid <see cref="GameObject"/> is unsnapped from the zone.
/// </summary>
[DocumentedByXml]
public UnityEvent Cleared = new UnityEvent();
#endregion
protected static List<GameObject> snappedObjects = new List<GameObject>();
public virtual bool CanSnap(GameObject interactable)
{
if (snappedObjects.Contains(interactable))
{
NotValidated?.Invoke(interactable);
return false;
}
snappedObjects.Add(interactable);
Validated?.Invoke(interactable);
return true;
}
public virtual void DoCanSnap(GameObject interactable)
{
CanSnap(interactable);
}
public virtual void ClearSnap(GameObject interactable)
{
if (snappedObjects.Remove(interactable))
{
Cleared?.Invoke(interactable);
}
}
}
}
```
This is the output:

@bddckr thoughts on the proposed solution, or can you come up with any alternatives?
Further investigation led to show there was an actual issue with the CollisionNotifier.EventData comparator meaning the list of colliding objects was not being maintained correctly.
This has now been fixed in zinnia, meaning there's probably a better solution than the above solution.
Now the Interactable contains a list of active colliders (i.e. a list of all snap zones it's touching)
So can now probably query that list on point of snapping and determine if the current zone is the first item in that list, if it is then the snap can occur, if it isn't then the snap wont occur)
In the future that list could also be sorted to snap to the nearest zone origin, etc.
the above solution still isn't enough.
if an interactable intersects two drop zones at the same time, then only one drop zone should become active (the one that will be dropped into)
the above solution will only prevent running the dropped logic it won't prevent any highlighting logic.
This is my proposed logic for fixing the issue:
Is IO being grabbed?
First check to see if the IO can activate the SDZ. Only IOs that aren鈥檛 already activating another SDZ can activate it.
To check if the IO is activating another zone, loop through the active collisions on the IO. for each collision that is of type SDZ, if the first found is not this SDZ then it must be activating another SDZ.
If the IO is not activating another SDZ then listen for the ungrab event on the IO and when the IO is ungrabbed check if it can be snapped to this SDZ.

progress!
More progress with extra edge cases handled.

Most helpful comment
progress!