unity-atoms/Source/Editor/SceneFieldDrawer.cs

165 lines
6.4 KiB
C#
Raw Normal View History

using System.Linq;
using UnityEditor;
using UnityEngine;
using UnityEngine.SceneManagement;
namespace UnityAtoms
{
[CustomPropertyDrawer(typeof(SceneField))]
public class SceneFieldDrawer : PropertyDrawer
{
private static class HelperMethods
{
public static Rect SnipRectH(Rect rect, float range)
{
if (range == 0) return new Rect(rect);
if (range > 0)
{
return new Rect(rect.x, rect.y, range, rect.height);
}
return new Rect(rect.x + rect.width + range, rect.y, -range, rect.height);
}
public static Rect SnipRectH(Rect rect, float range, out Rect rest)
{
if (range == 0) rest = new Rect();
if (range > 0)
{
rest = new Rect(rect.x + range, rect.y, rect.width - range, rect.height);
2019-05-04 05:54:20 -04:00
}
else
{
rest = new Rect(rect.x, rect.y, rect.width + range, rect.height);
}
return SnipRectH(rect, range);
}
public static Rect SnipRectV(Rect rect, float range)
{
if (range == 0) return new Rect(rect);
if (range > 0)
{
return new Rect(rect.x, rect.y, rect.width, range);
}
return new Rect(rect.x, rect.y + rect.height + range, rect.width, -range);
}
public static Rect SnipRectV(Rect rect, float range, out Rect rest)
{
if (range == 0) rest = new Rect();
if (range > 0)
{
rest = new Rect(rect.x, rect.y + range, rect.width, rect.height - range);
2019-05-04 05:54:20 -04:00
}
else
{
rest = new Rect(rect.x, rect.y, rect.width, rect.height + range);
}
return SnipRectV(rect, range);
}
}
private bool HasValidBuildIndex(SerializedProperty property)
{
var scene = property.FindPropertyRelative("sceneAsset")?.objectReferenceValue;
if (scene == null) return true;
var scenePath = AssetDatabase.GetAssetPath(scene);
var buildIndex = SceneUtility.GetBuildIndexByScenePath(scenePath);
return buildIndex != -1;
}
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
EditorGUI.BeginProperty(position, label, property);
OnPropertyGUI(position, property, label);
EditorGUI.EndProperty();
}
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
2019-05-04 05:54:20 -04:00
if (HasValidBuildIndex(property)) return base.GetPropertyHeight(property, label);
return base.GetPropertyHeight(property, label) * 2 + 5;
}
private void OnPropertyGUI(Rect position, SerializedProperty property, GUIContent label)
{
Rect lower;
Rect buttonRect = new Rect();
var scene = property.FindPropertyRelative("sceneAsset")?.objectReferenceValue;
2019-05-04 05:54:20 -04:00
if (scene == null)
{ // update values cause the build index could've changed
property.FindPropertyRelative("sceneName").stringValue = "";
property.FindPropertyRelative("scenePath").stringValue = "";
property.FindPropertyRelative("buildIndex").intValue = -1;
}
position = HelperMethods.SnipRectV(position, EditorGUIUtility.singleLineHeight, out lower);
2019-05-04 05:54:20 -04:00
if (HasValidBuildIndex(property))
{
if (scene != null)
{ // update values cause the build index could've changed
property.FindPropertyRelative("sceneName").stringValue = scene.name;
property.FindPropertyRelative("scenePath").stringValue = AssetDatabase.GetAssetPath(scene);
property.FindPropertyRelative("buildIndex").intValue = SceneUtility.GetBuildIndexByScenePath(
property.FindPropertyRelative("scenePath").stringValue
);
}
2019-05-04 05:54:20 -04:00
}
else
{
position = HelperMethods.SnipRectH(position, position.width - 70, out buttonRect);
property.FindPropertyRelative("buildIndex").intValue = -1;
}
// int buildIndex = SceneUtility.GetBuildIndexByScenePath(property.FindPropertyRelative("scenePath").stringValue);
SceneAsset sceneAsset = scene as SceneAsset;
// RENDER LABEL:
position = EditorGUI.PrefixLabel(position, GUIUtility.GetControlID(FocusType.Passive), label);
// RENDER OBJECT FIELD:
EditorGUI.BeginChangeCheck();
scene = EditorGUI.ObjectField(position, scene, typeof(SceneAsset), false);
if (EditorGUI.EndChangeCheck())
{
property.FindPropertyRelative("sceneAsset").objectReferenceValue = scene;
sceneAsset = scene as SceneAsset;
if (sceneAsset != null)
{
property.FindPropertyRelative("sceneName").stringValue = scene.name;
property.FindPropertyRelative("scenePath").stringValue = AssetDatabase.GetAssetPath(scene);
property.FindPropertyRelative("buildIndex").intValue = SceneUtility.GetBuildIndexByScenePath(
property.FindPropertyRelative("scenePath").stringValue
);
}
}
if (property.FindPropertyRelative("buildIndex").intValue != -1) return;
// OPTIONAL: RENDER BUTTON
if (scene != null && scene is SceneAsset)
{
EditorGUI.HelpBox(lower, "Scene is not added in the build settings", MessageType.Warning);
if (GUI.Button(buttonRect, "Fix Now"))
{
AddSceneToBuildSettings(sceneAsset);
}
}
}
private void AddSceneToBuildSettings(SceneAsset sceneAsset)
{
var scenePath = AssetDatabase.GetAssetPath(sceneAsset);
var scenes = EditorBuildSettings.scenes.ToList();
scenes.Add(new EditorBuildSettingsScene(scenePath, true));
EditorBuildSettings.scenes = scenes.ToArray();
}
}
}