ContentsSetup
Radial Base Layers Button Selection Slider Elements Header Button Toggle Button Slider Button Selection Button Selection Arrow Input Manager Processing A Button Processing A Slider Layer Processing A Selection Layer Processing Return Values Getting Values For Returning Changing Layer Skip To Layer Change To Previous Layer Last Cancel Changing Scene Change Scene To A Custom Layer Quiting Application |
SetupTo start create a canvas in your hierarchy.- {Right click in your hierarchy} > UI > Canvas. Place the Radial Menu Prefab in to the newly created Canvas. The Radial Menu Asset is found at: - Assets > Level Boss Games > Boss Radial Menu > Prefabs > Boss Radial Menu. Resize the Radial Menu as you see fit ensuring all of the anchor points are set correctly. Radial BaseIf you click on the newly created Radial Menu you will get access to all of the options avalible to the menu.LayersLayers can be used for holding elements and setting values from within the menu. They are an essential part, so you will need to create at least one.To create a new layer: - {Right click in any folder within your project} > Create > LBG > Radial Menu > Layer > {Choose one of the 3 layer types} All layers use these common variables that need setting: Button LayerA basic layer showing any amount of elements. You would use this for toggle buttons and any button that deals with transitions to either other layers, or other scenes.The top section will be the same as above Selection LayerA specialised button layer that deals with selecting a value from a pre-defined list of value.The top section will be the same as above Slider LayerA Specialised layer for dealing with changing a float value between 2 limits.The top section will be the same as above ElementsElements are used to populate the layers with images and functions. Without them the menu would be blank and do nothing.To create a new element: - {Right click in the folder of the layer you are adding the element to} > Create > LBG > Radial Menu > Element > {Choose one of the 6 element types} Header ElementAn element solely used for showing an image. The user cannot interact with this element.Button ElementA basic element that triggers something when the user interacts with it.Toggle Button ElementAn element that is linked to a boolean value. Each interact will flip the state of the boolean.Slider ElementAn element that is used to transition to a Slider Layer. It will return the current float value that the slider is attached to.Selection ElementAn element used ot transition to a Selection Layer. It will return the current string value that the selection is attached to.Same as: Button Selection Arrow ElementA special element only used in the Selection Layer. It is used to cycle through the values in the Selection Layer.Same as: Header Input ManagerThe input manager is the nerve center of your radial menu. It contains the code that is called when each button is pressed and each layer is confirmed or cancelled.To make an input manager for your menu: - {click on the Radial Base script of your menu} > {give the input manager a name in the "Input Manager Name" field} > {click the "Create Input Manager" button} This will create a template Input Manager in the root Assets folder of your project. Fill out the contents of this file for your menu and add the script to each instance of the menu. Drag the new script component on each menu into it's local Radial Base (under the "Input Manager" field) to link it. Note: After the file is created you can move it anywhere within your project's file structure   Processing A ButtonWhen a button is pressed this function is called in the input manager. The template has this structure:public static class Options { public static string[] difficulties = new string[] { "Easy", "Medium", "Hard" }; public static int currentDifficulty = 1; public static float volume = 100.0f; } public class TemplateInputManager : RadialMenuInputManager { public override void ProcessButton(string layerEvent, string buttonEvent) { switch (layerEvent) { case "Main Menu": switch (buttonEvent) { case "Play Button": GoToScene("Main Game"); break; case "Options Button": ChangeLayer("Options Layer"); break; case "Quit Button": QuitApplication(); break; default: Debug.LogWarning("No button event handler for " + buttonEvent + " in layer " + layerEvent); break; } break; case "Options Layer": switch (buttonEvent) { case "Volume Button": ChangeLayer("Volume Layer", Options.volume); break; case "Difficulty Button": ChangeLayer("Difficulty Layer", Options.currentDifficulty, Options.difficulties); break; case "Back To Main Menu Button": GoToPreviousLayer(); break; default: Debug.LogWarning("No button event handler for " + buttonEvent + " in layer " + layerEvent); break; } break; default: Debug.LogWarning("No layer event handler for " + layerEvent); break; } } } You need to create a case that matches each Layer Event Handle in the first switch statement. Then add a switch statement to each case. Finally populate those switch statements with case statements matching the Button Event Handles in each layer. The functions you can call from each button handler are detailed further down.   Processing A Slider LayerThis function is called every frame that an update is run on a Slider Layer (this is to allow live update of sound values).When confirm or cancel are pressed the SaveValue bool will turn true. Use this to save values into files or playerprefs. On cancel the passed in value is reverted back to its original value. The template has this structure: public static class Options { public static float volume = 100.0f; } public class TemplateInputManager : RadialMenuInputManager { public override void ProcessSlider(string layerEvent, float value, bool saveValue) { switch (layerEvent) { case "Volume Layer": Options.volume = value; if(saveValue == true) { PlayerPrefs.SetFloat("Volume", Options.volume); } break; default: Debug.LogWarning("No layer event handler for " + layerEvent); break; } } } You will need to create a case statement that matches the Layer Event Handle for each Slider Layer in the menu. The boolean that is passed in will let you know if the value needs to be saved/updated elsewhere or not. Confirming the layer will pass this boolean through as true and a cancel will be false. You should call functions to change layer here regardless of the boolean value.   Processing A Selection LayerWhen a Selection layer is confirmed or cancelled it will call this function with the index of the selection. The template has this structure:public static class Options { public static string[] difficulties = new string[] { "Easy", "Medium", "Hard" }; public static int currentDifficulty = 1; public static int defaultDifficulty = 0; } public class TemplateInputManager : RadialMenuInputManager { public override void ProcessSelection(string layerEvent, string buttonEvent, int newIndex, int originalIndex) { switch (layerEvent) { case "Difficulty Layer": switch (buttonEvent) { case "Confirm Button": Options.currentDifficulty = newIndex; GoToPreviousLayer(); break; case "Cancel Button": GoToPreviousLayer(); break; case "Reset To Default Button": Options.currentDifficulty = Options.defaultDifficulty; break; default: Debug.LogWarning("No button event handler for " + buttonEvent + " in layer " + layerEvent); break; } break; default: Debug.LogWarning("No layer event handler for " + layerEvent); break; } } } You will need to create a case statement that matches the Layer Event Handle for each Selection Layer in the menu. Like the Button Layers, you will need to create case statements for each of the Bottom Button Event Handles (up to 3) in each layer. The index value is in reference to the list of values the Selection Layer is selecting from. The original index is passed through so that you can reset the variable it is affecting. You should also call functions to change the layer here.   Processing Return ValuesUsed to return the value of Toggle, Slider and Selection Buttons before they have been pressed. An example looks like this:public static class Options { public static float volume = 100.0f; public static bool fullscreen = true; public static string[] difficulties = new string[] { "Easy", "Medium", "Hard" }; public static int currentDifficulty = 1; } public class TemplateInputManager : RadialMenuInputManager { public override T ProcessReturnValues<T>(string layerEvent, string buttonEvent) { switch (layerEvent) { case "Options Layer": switch (buttonEvent) { case "Volume Slider Button": return GetSliderValue<T>(Options.volume); case "Fullscreen Toggle Button": return GetToggleValue<T>(Options.fullscreen); case "Difficulties Selection Button": return GetSelectionValue<T>(Options.difficulties[Options.currentDifficulty]); default: Debug.LogWarning("No button event handler for " + buttonEvent + " in layer " + layerEvent); return GetNullValue<T>(); } default: Debug.LogWarning("No layer event handler for " + layerEvent); return GetNullValue<T>(); } } } The structure is the same as the Process Layer functions, it contains one case statement for each Button Event Handle of each Toggle, Slider or Selection Button. It utilises the Getter Functions to get the correct values for the display panel.   Getting Values For ReturningThese functions are used inside the ProcessReturnValues function to get values from different sources. The 4 functions are:GetToggleValue - Used to return a boolean to the display panel. public static class Options { public static bool fullscreen = true; } public class TemplateInputManager : RadialMenuInputManager { public override T ProcessReturnValues<T>(string layerEvent, string buttonEvent) { switch (layerEvent) { case "Options Layer": switch (buttonEvent) { case "Fullscreen Toggle Button": return GetToggleValue<T>(Options.fullscreen); default: Debug.LogWarning("No button event handler for " + buttonEvent + " in layer " + layerEvent); return GetNullValue<T>(); } default: Debug.LogWarning("No layer event handler for " + layerEvent); return GetNullValue<T>(); } } } GetSliderValue - Used to return a float value to the display panel. public static class Options { public static bool fullscreen = true; } public class TemplateInputManager : RadialMenuInputManager { public override T ProcessReturnValues<T>(string layerEvent, string buttonEvent) { switch (layerEvent) { case "Options Layer": switch (buttonEvent) { case "Fullscreen Toggle Button": return GetToggleValue<T>(Options.fullscreen); default: Debug.LogWarning("No button event handler for " + buttonEvent + " in layer " + layerEvent); return GetNullValue<T>(); } default: Debug.LogWarning("No layer event handler for " + layerEvent); return GetNullValue<T>(); } } } GetSelectionValue - Used to return a string value to the display panel. public static class Options { public static string[] difficulties = new string[] { "Easy", "Medium", "Hard" }; public static int currentDifficulty = 1; } public class TemplateInputManager : RadialMenuInputManager { public override T ProcessReturnValues<T>(string layerEvent, string buttonEvent) { switch (layerEvent) { case "Options Layer": switch (buttonEvent) { case "Difficulties Selection Button": return GetSelectionValue<T>(Options.difficulties[Options.currentDifficulty]); default: Debug.LogWarning("No button event handler for " + buttonEvent + " in layer " + layerEvent); return GetNullValue<T>(); } default: Debug.LogWarning("No layer event handler for " + layerEvent); return GetNullValue<T>(); } } } GetNullValue - Used by the default case to return a null value if the Button Event Handle does not have a case statement. public class TemplateInputManager : RadialMenuInputManager { public override T ProcessReturnValues<T>(string layerEvent, string buttonEvent) { switch (layerEvent) { case "Main Menu Layer": switch (buttonEvent) { default: Debug.LogWarning("No button event handler for " + buttonEvent + " in layer " + layerEvent); return GetNullValue<T>(); } default: Debug.LogWarning("No layer event handler for " + layerEvent); return GetNullValue<T>(); } } }   Changing LayerThese function swill trigger the process of changing to a different layer. Each type of layer hass it's own overload.Button Layer - Just references a standard layer by its Layer Event Handle. public override void ProcessButton(string layerEvent, string buttonEvent) { switch (layerEvent) { case "Main Menu Layer": switch (buttonEvent) { case "Play Button": ChangeLayer("Play Layer"); break; } break; } } Slider Layer - References a slider layer by its Layer Event Handle and passes in the starting float value. public static class Options { public static float volume = 100.0f; } public class TemplateInputManager : RadialMenuInputManager { public override void ProcessButton(string layerEvent, string buttonEvent) { switch (layerEvent) { case "Options Layer": switch (buttonEvent) { case "Volume Button": ChangeLayer("Volume", Options.volume); break; } break; } } } Selection Layer - References a standard layer by its Layer Event Handle and passes in the array of values with the starting index. public static class Options { public static string[] difficulties = new string[] { "Easy", "Medium", "Hard" }; public static int currentDifficulty = 1; } public class TemplateInputManager : RadialMenuInputManager { public override void ProcessButton(string layerEvent, string buttonEvent) { switch (layerEvent) { case "Main Menu Layer": switch (buttonEvent) { case "Resolution Button" ChangeLayer("Resolution Layer", Options.currentDifficulty, Options.difficulties); break; } break; } } }   Skip To LayerThese functions allow the user to skip layers out of the normal progression but still keep the correct chain to reverse out.Button Layer - Same as Change Layer (Button Layer) but includes a pass through for each layer for the chain in order. Slider Layer - Same as Change Layer (Slider Layer) but includes a pass through for each layer for the chain in order. Selection Layer - Same as Change Layer (Selection Layer) but includes a pass through for each layer for the chain in order. public static class Options { public static string[] difficulties = new string[] { "Easy", "Medium", "Hard" }; public static int currentDifficulty = 1; public static float volume = 100.0f; } public class TemplateInputManager : RadialMenuInputManager { public override void ProcessButton(string layerEvent, string buttonEvent) { switch (layerEvent) { case "Main Menu": switch (buttonEvent) { //For a Button layer case "Quick Play Button": SkipToLayer("Single Player Standard Game Layer", "Main Menu Layer", "Play Layer", "Single Player Layer"); break; //For a Slider layer case "Volume Button": SkipToLayer("Volume Layer", Options.volume, "Main Menu Layer", "Options Layer"); break; //For a Selection layer case "Difficulty Button": SkipToLayer("Difficulty Layer", Options.currentDifficulty, Options.difficulties, "Main Menu Layer", "Options Layer"); break; default: Debug.LogWarning("No button event handler for " + buttonEvent + " in layer " + layerEvent); break; } break; default: Debug.LogWarning("No layer event handler for " + layerEvent); break; } } }   Change To Previous LayerWhen used this function will look at the current chain of layers and transition back one layer.public override void ProcessButton(string layerEvent, string buttonEvent) { switch (layerEvent) { case "Options Layer": switch (buttonEvent) { case "Return To Previous Layer Button": GoToPreviousLayer(); break; default: Debug.LogWarning("No button event handler for " + buttonEvent + " in layer " + layerEvent); break; } break; default: Debug.LogWarning("No layer event handler for " + layerEvent); break; } }   Last CancelIf the GoToPreviousLayer function is called when the chain of layers is empty (the current layer is the base layer) this function is called.//Example 1 public override void LastCancel() { QuitApplication(); } //Example 2 public override void LastCancel() { ChangeLayer("Quit Layer"); } You can specify what happens to the menu when cancel is pressed on the base layer here or it can be left blank to do nothing.   Changing SceneCall this function when a button needs to transition to a different scene.public override void ProcessButton(string layerEvent, string buttonEvent) { switch (layerEvent) { case "Play Layer": switch (buttonEvent) { case "Single Player Button": GoToScene("Single Player Scene"); break; } break; } }   Changing Scene To A Custom LayerCall any of the functions when a button needs to transition to a different scene and the menu in that scene needs to start on a different layer to it's own start layer.The primary use of this function is exit back to a main menu but not go back to the main layer to allow fast gamemode restarts. There are 3 function overloads for the 3 different layer types. They are the same in use as the Skip Layer functions. Note: You must call the Change Scene function after calling this one as it will opnly create the istruction shuttle. A transition will activate it. public static class Options { public static string[] difficulties = new string[] { "Easy", "Medium", "Hard" }; public static int currentDifficulty = 1; public static float volume = 100.0f; } public class TemplateInputManager : RadialMenuInputManager { public override void ProcessButton(string layerEvent, string buttonEvent) { switch (layerEvent) { case "Pause Layer": switch (buttonEvent) { //For a Button layer case "Return To Play Mode Button": CreateShuttle("Single Player Layer", "Main Menu Layer", "Play Layer"); GoToScene("Main Menu"); break; //For a Slider layer case "Return To Volume Button": CreateShuttle("Volume Layer", Options.volume, "Main Menu Layer", "Options Layer"); GoToScene("Main Menu"); break; //For a Selection layer case "Return to Difficulty Button": CreateShuttle("Difficulty Layer", Options.currentDifficulty, Options.difficulties, "Main Menu Layer", "Options Layer"); GoToScene("Main Menu"); break; default: Debug.LogWarning("No button event handler for " + buttonEvent + " in layer " + layerEvent); break; } break; default: Debug.LogWarning("No layer event handler for " + layerEvent); break; } } }   Quiting ApplicationUse this function in a button event handler to exit the application.public override void ProcessButton(string layerEvent, string buttonEvent) { switch (layerEvent) { case "Quit Layer": switch (buttonEvent) { case "Yes Button": QuitApplication(); break; default: Debug.LogWarning("No button event handler for " + buttonEvent + " in layer " + layerEvent); break; } break; default: Debug.LogWarning("No layer event handler for " + layerEvent); break; } } |