Exemple #1
0
        public static PickingObject PickGameObject(Vector2 mousePosition)
        {
            s_RetainHashes = true;

            var enumerator = GetAllOverlapping(mousePosition).GetEnumerator();

            if (!enumerator.MoveNext())
            {
                return(PickingObject.Empty);
            }

            PickingObject topmost     = enumerator.Current;
            var           pickingBase = topmost.TryGetComponent(out Transform trs)
                ? HandleUtility.FindSelectionBaseForPicking(trs)
                : null;
            // Selection base is only interesting if it's not the topmost
            PickingObject selectionBase = new PickingObject(pickingBase);
            PickingObject first         = selectionBase.target == null ? topmost : selectionBase;
            int           topmostHash   = topmost.GetHashCode();
            int           prefixHash    = topmostHash;

            if (Selection.activeObject == null)
            {
                // Nothing selected
                // Return selection base if it exists, otherwise topmost game object
                s_PreviousTopmostHash = topmostHash;
                s_PreviousPrefixHash  = prefixHash;
                return(first);
            }

            if (topmostHash != s_PreviousTopmostHash)
            {
                // Topmost game object changed
                // Return selection base if exists and is not already selected, otherwise topmost game object
                s_PreviousTopmostHash = topmostHash;
                s_PreviousPrefixHash  = prefixHash;
                return(Selection.activeObject == selectionBase.target ? topmost : first);
            }

            s_PreviousTopmostHash = topmostHash;

            // Pick potential selection base before topmost game object
            if (Selection.activeObject == selectionBase.target)
            {
                if (prefixHash == s_PreviousPrefixHash)
                {
                    return(topmost);
                }
                s_PreviousPrefixHash = prefixHash;
                return(selectionBase);
            }

            s_ActiveObjectFilter.Clear();
            s_ActiveObjectFilter.Add((PickingObject)Selection.activeObject);

            // Check if active game object will appear in selection stack
            PickingObject picked = HandleUtility.PickObject(mousePosition, false, null, s_ActiveObjectFilter);

            if (picked == ((PickingObject)Selection.activeObject))
            {
                // Advance enumerator to active game object
                while (enumerator.Current != ((PickingObject)Selection.activeObject))
                {
                    if (!enumerator.MoveNext())
                    {
                        s_PreviousPrefixHash = topmostHash;
                        return(first); // Should not occur
                    }

                    UpdateHash(ref prefixHash, enumerator.Current);
                }
            }

            if (prefixHash != s_PreviousPrefixHash)
            {
                // Prefix hash changed, start over
                s_PreviousPrefixHash = topmostHash;
                return(first);
            }

            // Move on to next game object
            if (!enumerator.MoveNext())
            {
                s_PreviousPrefixHash = topmostHash;
                return(first); // End reached, start over
            }

            UpdateHash(ref prefixHash, enumerator.Current);

            if (enumerator.Current == selectionBase)
            {
                // Skip selection base
                if (!enumerator.MoveNext())
                {
                    s_PreviousPrefixHash = topmostHash;
                    return(first); // End reached, start over
                }

                UpdateHash(ref prefixHash, enumerator.Current);
            }

            s_PreviousPrefixHash = prefixHash;
            return(enumerator.Current);
        }
Exemple #2
0
 static void UpdateHash(ref int hash, PickingObject obj)
 {
     hash = unchecked (hash * 33 + obj.GetHashCode());
 }