/// The minimal preparation for use. If these are not set ShowChildLayer() can't work. public void Initialize(ConstellationMenuRoot root, AssetTree.Node asset, float scale) { menuRoot = root; menuRoot.MarkGraphDirty(); menuNode = asset; menuScale = scale; menuOrientation = transform.rotation; menuCenter = transform.position; startPosition = transform.position; savedCameraPosition = Camera.main.transform.position; savedCameraRotation = Camera.main.transform.rotation; state = IconState.Shown; }
/// Creates and shows a layer of icons below this one. /// Returns true if a fade needs to occur. public static bool ShowMenu(ConstellationMenuRoot root, AssetTree.Node treeNode, ConstellationMenuIcon parent, Quaternion orientation, float scale, IconState initialState = IconState.Shown) { // Determine how many children are in the sub-menu List <AssetTree.Node> childItems = treeNode.children; // If this is the end of a menu, invoke the action and return early if (childItems.Count == 0) { root.MakeSelection(parent.menuItem); root.CloseAll(); return(false); } if (parent.childMenus.Count == childItems.Count) { // children already exist. just fade them in. bool stateChanged = false; foreach (ConstellationMenuIcon child in parent.childMenus) { if (child.StartFade(initialState)) { stateChanged = true; } // Close any children. child.FadeChildren(IconState.Closed); } return(stateChanged); } List <Vector3> childPositions; float radius; if (parent.parentMenu != null) { radius = (parent.menuCenter - parent.startPosition).magnitude + ITEM_SPACING; childPositions = ArrangeInCircle(childItems.Count, radius, parent.angleToRoot - Mathf.PI * .5f, parent.angleToRoot + Mathf.PI * .5f, ITEM_SPACING); } else { // Radius needs to expand when there are more icons radius = ITEM_SPACING * Mathf.Max(childItems.Count, MIN_ITEM_SPACE) / (2.0f * Mathf.PI); // add one unused position to item positions childPositions = ArrangeInCircle(childItems.Count + 1, radius); } for (int i = 0; i < childItems.Count; ++i) { Vector3 posOffset = childPositions[i]; ConstellationMenuIcon childMenu = (ConstellationMenuIcon)Instantiate(root.menuIconPrefab, root.transform); childMenu.transform.position = parent.menuCenter + (orientation * posOffset); childMenu.transform.rotation = orientation; childMenu.transform.localScale = Vector3.one * scale; childMenu.Initialize(root, parent, childItems[i], parent.menuCenter, scale, initialState); childMenu.angleToRoot = Mathf.Atan2(posOffset[1], posOffset[0]); } return(true); }
/// Called to make this icon visible and interactable public void Initialize(ConstellationMenuRoot root, ConstellationMenuIcon _parentMenu, AssetTree.Node node, Vector3 _menuCenter, float scale, IconState initialState) { parentMenu = _parentMenu; startPosition = transform.position; startScale = transform.localScale; menuRoot = root; menuNode = node; menuCenter = _menuCenter; savedCameraPosition = _parentMenu.savedCameraPosition; savedCameraRotation = _parentMenu.savedCameraRotation; menuOrientation = transform.rotation; // Icons are oriented up in world space. Vector3 iconToCamera = savedCameraPosition - transform.position; Quaternion rotationToCamera = Quaternion.FromToRotation(-transform.forward, iconToCamera.normalized); transform.localRotation = rotationToCamera * transform.localRotation; menuScale = scale; background = null; state = IconState.Closed; if (node != null) { // Set foreground icon menuItem = (ConstellationMenuItem)node.value; spriteRenderer.sprite = menuItem.icon; gameObject.name = menuItem.name; // Set background icon background = new GameObject(name + " Item Background"); background.transform.parent = transform.parent; background.transform.localPosition = transform.localPosition + transform.forward * BACKGROUND_ICON_ZOFFSET; background.transform.localRotation = transform.localRotation; background.transform.localScale = transform.localScale; backgroundSpriteRenderer = background.AddComponent <SpriteRenderer>(); backgroundSpriteRenderer.sprite = menuRoot.iconBackground; if (menuNode.children.Count != 0 && decorationLabelPrefab != null && menuRoot.expandableIconDecoration) { decorationLabel = Instantiate(decorationLabelPrefab, background.transform); decorationLabelRenderer = decorationLabel.GetComponent <SpriteRenderer>(); decorationLabelRenderer.sprite = menuRoot.expandableIconDecoration; decorationLabel.SetActive(false); } menuRoot.MarkGraphDirty(); float tooltipOffset; if (menuItem.tooltipSprite) { tooltip = new GameObject(name + " Tooltip Sprite"); SpriteRenderer tooltipSpriteRenderer = tooltip.AddComponent <SpriteRenderer>(); tooltipSpriteRenderer.sprite = menuItem.tooltipSprite; tooltipRenderer = tooltipSpriteRenderer; tooltip.transform.localScale *= TOOLTIP_SPRITE_SCALE; tooltipOffset = TOOLTIP_SPRITE_OFFSET; } else { tooltip = Instantiate(tooltipPrefab); tooltip.name = name + " Tooltip Text"; tooltip.GetComponent <TextMesh>().text = menuItem.toolTip.Replace('\\', '\n'); tooltipRenderer = tooltip.GetComponent <MeshRenderer>(); tooltip.transform.localScale = Vector3.one * TOOLTIP_TEXT_SCALE; tooltipOffset = TOOLTIP_TEXT_OFFSET; } tooltip.transform.SetParent(transform, false); tooltip.transform.localPosition = Vector3.up * tooltipOffset; tooltip.transform.rotation = transform.rotation; SetRendererAlpha(tooltipRenderer, DEFAULT_TOOLTIP_ALPHA); } parentMenu.childMenus.Add(this); lineToParent = GetComponent <LineRenderer>(); lineToParent.startColor = Color.clear; lineToParent.endColor = Color.clear; UpdateLines(); SetDecorationLabelAlpha(decorationLabelAlpha.ValueAtTime(Time.time)); SetBackgroundTransparency(iconBgAlpha.ValueAtTime(Time.time)); SetRendererAlpha(spriteRenderer, iconAlpha.ValueAtTime(Time.time)); StartFade(initialState); SetColliderSize(0.0f); }