基本流程
因为在现有的项目中,像开始场景的切换或者Telepot组件都需要手动输入场景名,有时还可能键入出错,而该特性能用选择的方式去解决这一问题
1.代码实现
SceneNameDrawer.cs
//参数绘制
using UnityEditor;
using UnityEngine;
#if UNITY_EDITOR
[CustomPropertyDrawer(typeof(SceneNameAttribute))]
public class SceneNameDrawer : PropertyDrawer
{
int sceneIndex = -1;//代表没有任何场景
GUIContent[] sceneNames;
readonly string[] scenePathSplit = { "/", ".unity" };
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)//(position)长宽高;(property)需要绘制的property
{
if (EditorBuildSettings.scenes.Length == 0) return;
if (sceneIndex == -1)
GetSceneNameArray(property);
int oldIndex = sceneIndex;
sceneIndex = EditorGUI.Popup(position, label, sceneIndex, sceneNames);//Popup弹出式窗口
if (oldIndex != sceneIndex)
property.stringValue = sceneNames[sceneIndex].text;
}
private void GetSceneNameArray(SerializedProperty property)
{
var scenes = EditorBuildSettings.scenes;
//初始化数组
sceneNames = new GUIContent[scenes.Length];
for (int i = 0; i < sceneNames.Length; i++)
{
string path = scenes[i].path;
string[] splitPath = path.Split(scenePathSplit, System.StringSplitOptions.RemoveEmptyEntries);
string sceneName = "";
if (splitPath.Length > 0)
{
sceneName = splitPath[splitPath.Length - 1];
}
else
{
sceneName = "(Deleted Scene)";
}
sceneNames[i] = new GUIContent(sceneName);
}
if (sceneNames.Length == 0)
{
sceneNames = new[] { new GUIContent("Check Your Build Settings") };
}
if (!string.IsNullOrEmpty(property.stringValue))
{
bool nameFound = false;
for (int i = 0; i < sceneNames.Length; i++)
{
if (sceneNames[i].text == property.stringValue)
{
sceneIndex = i;
nameFound = true;
break;
}
}
if (nameFound == false)
sceneIndex = 0;
}
else
{
sceneIndex = 0;
}
property.stringValue = sceneNames[sceneIndex].text;
}
}
#endif
SceneNameAttribute.cs
public class SceneNameAttribute : PropertyAttribute
{ }
然后在需要的脚本中增加[SceneName]就能实现效果了