This example is created using
Unity 2018.2.14f.
In Unity, when you have created a lot of scenes in different
.unity files, sometimes it is tough to setup the level selection scene. For
example, you create a lot of buttons to load the scene. In the button’s OnClick
method, you will have to write the level name. This takes a lot of effort if
you have more than 20 scenes and I’m super lazy to do that. So I want to setup
all the button using script. When I click the button, it has to load the
corresponding scene based on the parameter (ex: level2, level3, etc).
In order to do that, I created LevelSelectEditor.cs and LevelSelect.cs. LevelSelectEditor is a script that show a button to trigger the function where I want to generate all the buttons. Here is the LevelSelectEditor.cs:
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
// This script will copy one button in the level select screen,
// then paste its attribute from the button.
// Until the last button
[CustomEditor(typeof(LevelSelect))]
public class LevelSelectEditor : Editor
{
public override void OnInspectorGUI()
{
DrawDefaultInspector();
LevelSelect levelSelect = (LevelSelect)target;
if (GUILayout.Button("Generate Level Text"))
{
levelSelect.generateLevelText();
}
if (GUI.changed)
{
EditorUtility.SetDirty(levelSelect);
}
}
}
#endif
And this is the LevelSelect.cs
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Events;
using UnityEngine.Assertions;
using UnityEditor.Events;
// This class is used to create as many button as possible depends
// on the number of level in the game
public class LevelSelect : MonoBehaviour
{
public int numLevel = 10;
public GameObject button;
public GameObjectManager goManager;
public void generateLevelText()
{
// first we need to make sure that Button game object is not null
Assert.IsNotNull(button);
// hold the information of game object button
string buttonName = button.name;
Text levelText = button.gameObject.GetComponentInChildren<Text>();
// Button must have level text
Assert.IsNotNull(levelText); // level text must not null
// delete children except first child
while (transform.childCount > 1)
{
// delete it
Object.DestroyImmediate(transform.GetChild(1).gameObject);
}
// we iterate from 2 because the first button is already created
for (int i = 2; i <= numLevel; ++i)
{
// we want to change the parameter to match the level name of the scene
levelText.text = "level" + i;
// we create new button and set the parent to the same as the first button object
// the new button that we created is a copy of a button so it still has the same property
// however, we need to change the onClick parameter to match the level name
GameObject objButton = Object.Instantiate(button);
objButton.transform.SetParent(this.transform);
objButton.transform.localScale = Vector3.one;
// rename the button
objButton.name = buttonName;
// we need the component of the Button
var btnComponent = objButton.GetComponent<Button>();
// now we remove the existing levelbuttonpressed method with wrong parameter
UnityEventTools.RemovePersistentListener<string>(btnComponent.onClick, goManager.loadLevel);
// then we change it to the new one
UnityAction<string> action = new UnityAction<string>(goManager.loadLevel);
UnityEventTools.AddStringPersistentListener(btnComponent.onClick, action, levelText.text);
}
// set if back to default text
levelText.text = "level1";
}
}
You need to hook up the LevelSelect script to the content gameObject, set the properties (number of level, the button instance, the game object that has callback method), and you're done. The button onClick method will change to level1, level2, level3, etc automatically.
#if UNITY_EDITOR
using UnityEditor;
// This script will copy one button in the level select screen,
// then paste its attribute from the button.
// Until the last button
[CustomEditor(typeof(LevelSelect))]
public class LevelSelectEditor : Editor
{
public override void OnInspectorGUI()
{
DrawDefaultInspector();
LevelSelect levelSelect = (LevelSelect)target;
if (GUILayout.Button("Generate Level Text"))
{
levelSelect.generateLevelText();
}
if (GUI.changed)
{
EditorUtility.SetDirty(levelSelect);
}
}
}
#endif
And this is the LevelSelect.cs
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Events;
using UnityEngine.Assertions;
using UnityEditor.Events;
// This class is used to create as many button as possible depends
// on the number of level in the game
public class LevelSelect : MonoBehaviour
{
public int numLevel = 10;
public GameObject button;
public GameObjectManager goManager;
public void generateLevelText()
{
// first we need to make sure that Button game object is not null
Assert.IsNotNull(button);
// hold the information of game object button
string buttonName = button.name;
Text levelText = button.gameObject.GetComponentInChildren<Text>();
// Button must have level text
Assert.IsNotNull(levelText); // level text must not null
// delete children except first child
while (transform.childCount > 1)
{
// delete it
Object.DestroyImmediate(transform.GetChild(1).gameObject);
}
// we iterate from 2 because the first button is already created
for (int i = 2; i <= numLevel; ++i)
{
// we want to change the parameter to match the level name of the scene
levelText.text = "level" + i;
// we create new button and set the parent to the same as the first button object
// the new button that we created is a copy of a button so it still has the same property
// however, we need to change the onClick parameter to match the level name
GameObject objButton = Object.Instantiate(button);
objButton.transform.SetParent(this.transform);
objButton.transform.localScale = Vector3.one;
// rename the button
objButton.name = buttonName;
// we need the component of the Button
var btnComponent = objButton.GetComponent<Button>();
// now we remove the existing levelbuttonpressed method with wrong parameter
UnityEventTools.RemovePersistentListener<string>(btnComponent.onClick, goManager.loadLevel);
// then we change it to the new one
UnityAction<string> action = new UnityAction<string>(goManager.loadLevel);
UnityEventTools.AddStringPersistentListener(btnComponent.onClick, action, levelText.text);
}
// set if back to default text
levelText.text = "level1";
}
}
You need to hook up the LevelSelect script to the content gameObject, set the properties (number of level, the button instance, the game object that has callback method), and you're done. The button onClick method will change to level1, level2, level3, etc automatically.
No comments:
Post a Comment