Exemplo n.º 1
0
        // Selection logic

        // Find the next selectable object in the specified world-space direction.
        public SelectableUI FindSelectable(Vector3 dir)
        {
            dir = dir.normalized;
            Vector3      localDir = Quaternion.Inverse(transform.rotation) * dir;
            Vector3      pos      = transform.TransformPoint(GetPointOnRectEdge(transform as RectTransform, localDir));
            float        maxScore = Mathf.NegativeInfinity;
            SelectableUI bestPick = null;

            for (int i = 0; i < s_List.Count; ++i)
            {
                SelectableUI sel = s_List[i];

                if (sel == this || sel == null)
                {
                    continue;
                }

                if (!sel.IsInteractable() || sel.navigation.mode == NavigationUI.Mode.None)
                {
                    continue;
                }

                var     selRect   = sel.transform as RectTransform;
                Vector3 selCenter = selRect != null ? (Vector3)selRect.rect.center : Vector3.zero;
                Vector3 myVector  = sel.transform.TransformPoint(selCenter) - pos;

                // Value that is the distance out along the direction.
                float dot = Vector3.Dot(dir, myVector);

                // Skip elements that are in the wrong direction or which have zero distance.
                // This also ensures that the scoring formula below will not have a division by zero error.
                if (dot <= 0)
                {
                    continue;
                }

                // This scoring function has two priorities:
                // - Score higher for positions that are closer.
                // - Score higher for positions that are located in the right direction.
                // This scoring function combines both of these criteria.
                // It can be seen as this:
                //   Dot (dir, myVector.normalized) / myVector.magnitude
                // The first part equals 1 if the direction of myVector is the same as dir, and 0 if it's orthogonal.
                // The second part scores lower the greater the distance is by dividing by the distance.
                // The formula below is equivalent but more optimized.
                //
                // If a given score is chosen, the positions that evaluate to that score will form a circle
                // that touches pos and whose center is located along dir. A way to visualize the resulting functionality is this:
                // From the position pos, blow up a circular balloon so it grows in the direction of dir.
                // The first Selectable whose center the circular balloon touches is the one that's chosen.
                float score = dot / myVector.sqrMagnitude;

                if (score > maxScore)
                {
                    maxScore = score;
                    bestPick = sel;
                }
            }
            return(bestPick);
        }
Exemplo n.º 2
0
 // Convenience function -- change the selection to the specified object if it's not null and happens to be active.
 void Navigate(AxisEventData eventData, SelectableUI sel)
 {
     if (sel != null && sel.IsActive())
     {
         eventData.selectedObject = sel.gameObject;
     }
 }
Exemplo n.º 3
0
        private static void DrawNavigationArrow(Vector2 direction, SelectableUI fromObj, SelectableUI toObj)
        {
            if (fromObj == null || toObj == null)
            {
                return;
            }
            Transform fromTransform = fromObj.transform;
            Transform toTransform   = toObj.transform;

            Vector2 sideDir   = new Vector2(direction.y, -direction.x);
            Vector3 fromPoint = fromTransform.TransformPoint(GetPointOnRectEdge(fromTransform as RectTransform, direction));
            Vector3 toPoint   = toTransform.TransformPoint(GetPointOnRectEdge(toTransform as RectTransform, -direction));
            float   fromSize  = HandleUtility.GetHandleSize(fromPoint) * 0.05f;
            float   toSize    = HandleUtility.GetHandleSize(toPoint) * 0.05f;

            fromPoint += fromTransform.TransformDirection(sideDir) * fromSize;
            toPoint   += toTransform.TransformDirection(sideDir) * toSize;
            float   length      = Vector3.Distance(fromPoint, toPoint);
            Vector3 fromTangent = fromTransform.rotation * direction * length * 0.3f;
            Vector3 toTangent   = toTransform.rotation * -direction * length * 0.3f;

            Handles.DrawBezier(fromPoint, toPoint, fromPoint + fromTangent, toPoint + toTangent, Handles.color, null, kArrowThickness);
            Handles.DrawAAPolyLine(kArrowThickness, toPoint, toPoint + toTransform.rotation * (-direction - sideDir) * toSize * kArrowHeadSize);
            Handles.DrawAAPolyLine(kArrowThickness, toPoint, toPoint + toTransform.rotation * (-direction + sideDir) * toSize * kArrowHeadSize);
        }
Exemplo n.º 4
0
        private static string GetSaveControllerPath(SelectableUI target)
        {
            var defaultName = target.gameObject.name;
            var message     = string.Format("Create a new animator for the game object '{0}':", defaultName);

            return(EditorUtility.SaveFilePanelInProject("New Animation Contoller", defaultName, "controller", message));
        }
Exemplo n.º 5
0
        private static void DrawNavigationForSelectable(SelectableUI sel)
        {
            if (sel == null)
            {
                return;
            }

            Transform transform = sel.transform;
            bool      active    = Selection.transforms.Any(e => e == transform);

            Handles.color = new Color(1.0f, 0.9f, 0.1f, active ? 1.0f : 0.4f);
            DrawNavigationArrow(-Vector2.right, sel, sel.FindSelectableOnLeft());
            DrawNavigationArrow(Vector2.right, sel, sel.FindSelectableOnRight());
            DrawNavigationArrow(Vector2.up, sel, sel.FindSelectableOnUp());
            DrawNavigationArrow(-Vector2.up, sel, sel.FindSelectableOnDown());
        }
Exemplo n.º 6
0
        private static string BuildAnimationPath(SelectableUI target)
        {
            // if no target don't hook up any curves.
            var highlight = target.targetGraphic;

            if (highlight == null)
            {
                return(string.Empty);
            }

            var startGo  = highlight.gameObject;
            var toFindGo = target.gameObject;

            var pathComponents = new Stack <string>();

            while (toFindGo != startGo)
            {
                pathComponents.Push(startGo.name);

                // didn't exist in hierarchy!
                if (startGo.transform.parent == null)
                {
                    return(string.Empty);
                }

                startGo = startGo.transform.parent.gameObject;
            }

            // calculate path
            var animPath = new StringBuilder();

            if (pathComponents.Count > 0)
            {
                animPath.Append(pathComponents.Pop());
            }

            while (pathComponents.Count > 0)
            {
                animPath.Append("/").Append(pathComponents.Pop());
            }

            return(animPath.ToString());
        }
Exemplo n.º 7
0
        protected static UnityEditor.Animations.AnimatorController GenerateSelectableAnimatorContoller(AnimationTriggers animationTriggers, SelectableUI target)
        {
            if (target == null)
            {
                return(null);
            }

            // Where should we create the controller?
            var path = GetSaveControllerPath(target);

            if (string.IsNullOrEmpty(path))
            {
                return(null);
            }

            // figure out clip names
            var normalName      = string.IsNullOrEmpty(animationTriggers.normalTrigger) ? "Normal" : animationTriggers.normalTrigger;
            var highlightedName = string.IsNullOrEmpty(animationTriggers.highlightedTrigger) ? "Highlighted" : animationTriggers.highlightedTrigger;
            var pressedName     = string.IsNullOrEmpty(animationTriggers.pressedTrigger) ? "Pressed" : animationTriggers.pressedTrigger;
            var disabledName    = string.IsNullOrEmpty(animationTriggers.disabledTrigger) ? "Disabled" : animationTriggers.disabledTrigger;

            // Create controller and hook up transitions.
            var controller = UnityEditor.Animations.AnimatorController.CreateAnimatorControllerAtPath(path);

            GenerateTriggerableTransition(normalName, controller);
            GenerateTriggerableTransition(highlightedName, controller);
            GenerateTriggerableTransition(pressedName, controller);
            GenerateTriggerableTransition(disabledName, controller);

            AssetDatabase.ImportAsset(path);

            return(controller);
        }