/// <summary> /// Static method to show the menu /// </summary> /// <param name="sceneItem">Scene (not canvas) item that initiated the call</param> /// <param name="callBack">A callback to call when choice happens</param> public static void LaunchMenu(LinkableSceneItem sceneItem, Action<ChoiceItem> callBack) { // If our popupmenu instance is null if (_popupMenu == null) { // We create a game object, name it a Popup Menu var newGameObject = new GameObject { name = "Popup Menu" }; // And we add a Popup Menu component menu _popupMenu = newGameObject.AddComponent<PopupTowerMenu>(); } // We then launch a choice menu _popupMenu.LaunchChoiceMenu(sceneItem.ChoicePack.ChoiceItems, sceneItem.TransformCache.position, callBack, sceneItem); }
public TowerOrPadWasPressedEvent(LinkableSceneItem sceneItem) { SceneItem = sceneItem; }
/// <summary> /// Launches the Choice menu /// </summary> /// <param name="choiceItems">Choice items to show</param> /// <param name="position">Current WORLD position to display the menu</param> /// <param name="callback">Callback to call when something gets picked</param> /// <param name="sceneItem">Scene item that initiated the click</param> public void LaunchChoiceMenu(ChoiceItem[] choiceItems, Vector3 position, Action<ChoiceItem> callback, LinkableSceneItem sceneItem) { // Setting our instance delegate to current callback so we will be able to call it later _currentCallbackAction = callback; // Setting our gameObject cache to true base.GameObjectCache.SetActive(true); // We also enable our click blocker // that transparent light panel UiClickBlocker.Instance.Enable(); // And set it to the top "layer" so it covers everyting (except the actual menu that we will add later) UiClickBlocker.Instance.TransformCache.SetAsLastSibling(); // We then recalculate our position and get actual screen point in pixels position = Camera.main.WorldToScreenPoint(position); // And set this menu to this point TransformCache.position = position; // Sometimes it's not obvious, but we also need to set this gameObject as a child of the Canvas // So it will be rendered properly TransformCache.SetParent(OverlayCanvas.Instance.TransformCache); // And set it to the top "layer" so it covers everyting TransformCache.SetAsLastSibling(); // Calculating positions of the choice items // They should uniformly fill the 360 circle int totalChoiceCount = choiceItems.Length; // Actual angle step is calculated by dividing the 2 PI (360 degrees) by total count of items float angleStep = 2f * Mathf.PI / totalChoiceCount; // Scale to step items from the center const float scale = 45f; // Creating a local array of actual choice items _currentItems = new ChoiceItem[totalChoiceCount]; // For every passed choice item for (int i = 0; i < totalChoiceCount; i++) { var currentChoiceItem = choiceItems[i]; // If we're given a prefab (that's what .activeInHierarchy means) if (!currentChoiceItem.gameObject.activeInHierarchy) { // We instantiate it first // Destory and Instantiate things can be easily rewired to some object pool logic currentChoiceItem = Instantiate(currentChoiceItem, position, Quaternion.identity) as ChoiceItem; } // We link this choice item to a passed scene item currentChoiceItem.SceneItem = sceneItem; // Set it as a child of the canvas (it's an UI.Image) currentChoiceItem.transform.SetParent(OverlayCanvas.Instance.TransformCache); // And set it to the top of everything else currentChoiceItem.transform.SetAsLastSibling(); // We find the X and Y positions of the item var rotationVector = new Vector3 { x = Mathf.Sin(angleStep * i) * scale, y = Mathf.Cos(angleStep * i) * scale }; // Change the position of the element itself currentChoiceItem.transform.position += rotationVector; // And subscribe to it's Pressed event so we are able to catch the item that was chosen currentChoiceItem.ChoiceItemPressedEvent += ChoiceItemWasPressedEventHandler; // Finally, we store newly created item in our array _currentItems[i] = currentChoiceItem; } // After all is done, we're just waiting for either any of the choices to fire a ChoiceItemPressedEvent event, // or a click blocker to fire its BlockerWasClickedEvent event }