210 lines
5.9 KiB
C#
210 lines
5.9 KiB
C#
using System.Collections.Generic;
|
|
using UnityEditor;
|
|
using UnityEditor.SceneManagement;
|
|
using UnityEngine;
|
|
using Test_2022.CameraControl;
|
|
|
|
[CustomEditor(typeof(CameraWaypointSwitcher))]
|
|
[CanEditMultipleObjects]
|
|
public sealed class CameraWaypointSwitcherEditor : Editor
|
|
{
|
|
SerializedProperty targetProp;
|
|
SerializedProperty waypointsProp;
|
|
|
|
void OnEnable()
|
|
{
|
|
targetProp = serializedObject.FindProperty("target");
|
|
waypointsProp = serializedObject.FindProperty("waypoints");
|
|
}
|
|
|
|
public override void OnInspectorGUI()
|
|
{
|
|
serializedObject.Update();
|
|
DrawDefaultInspector();
|
|
serializedObject.ApplyModifiedProperties();
|
|
|
|
EditorGUILayout.Space(10);
|
|
using (new EditorGUILayout.VerticalScope(EditorStyles.helpBox))
|
|
{
|
|
EditorGUILayout.LabelField("Tools", EditorStyles.boldLabel);
|
|
|
|
using (new EditorGUILayout.HorizontalScope())
|
|
{
|
|
if (GUILayout.Button("Use Main Camera"))
|
|
UseMainCamera();
|
|
|
|
if (GUILayout.Button("Create Point From Target"))
|
|
CreatePointFromTarget();
|
|
}
|
|
|
|
using (new EditorGUILayout.HorizontalScope())
|
|
{
|
|
if (GUILayout.Button("Add Selected"))
|
|
AddSelected(false);
|
|
|
|
if (GUILayout.Button("Add Selected (+Children)"))
|
|
AddSelected(true);
|
|
}
|
|
|
|
using (new EditorGUILayout.HorizontalScope())
|
|
{
|
|
if (GUILayout.Button("Remove Nulls"))
|
|
RemoveNulls();
|
|
|
|
if (GUILayout.Button("Clear Points"))
|
|
ClearPoints();
|
|
}
|
|
}
|
|
|
|
EditorGUILayout.Space(10);
|
|
using (new EditorGUILayout.VerticalScope(EditorStyles.helpBox))
|
|
{
|
|
EditorGUILayout.LabelField("Runtime", EditorStyles.boldLabel);
|
|
|
|
if (!Application.isPlaying)
|
|
EditorGUILayout.HelpBox("进入 Play 模式后才会执行点位切换与摇晃。Transition Mode = Instant 为瞬切,Tween 为平滑移动。Shake Mode = Handheld 为手持式平滑摇晃。", MessageType.Info);
|
|
|
|
using (new EditorGUI.DisabledScope(!Application.isPlaying))
|
|
{
|
|
using (new EditorGUILayout.HorizontalScope())
|
|
{
|
|
if (GUILayout.Button("Start"))
|
|
StartPlayback();
|
|
|
|
if (GUILayout.Button("Stop (Restore)"))
|
|
StopPlayback(true);
|
|
|
|
if (GUILayout.Button("Stop (No Restore)"))
|
|
StopPlayback(false);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void UseMainCamera()
|
|
{
|
|
var cam = Camera.main;
|
|
if (cam == null)
|
|
return;
|
|
|
|
foreach (var t in targets)
|
|
{
|
|
Undo.RecordObject(t, "Assign Main Camera");
|
|
var sw = (CameraWaypointSwitcher)t;
|
|
var so = new SerializedObject(sw);
|
|
so.FindProperty("target").objectReferenceValue = cam.transform;
|
|
so.ApplyModifiedPropertiesWithoutUndo();
|
|
EditorUtility.SetDirty(sw);
|
|
MarkSceneDirty(sw);
|
|
}
|
|
|
|
serializedObject.Update();
|
|
}
|
|
|
|
void CreatePointFromTarget()
|
|
{
|
|
if (targetProp == null)
|
|
return;
|
|
|
|
var target = targetProp.objectReferenceValue as Transform;
|
|
if (target == null)
|
|
return;
|
|
|
|
var go = new GameObject("CamPoint");
|
|
Undo.RegisterCreatedObjectUndo(go, "Create Camera Point");
|
|
go.transform.SetPositionAndRotation(target.position, target.rotation);
|
|
|
|
AddPointToAll(go.transform, -1f);
|
|
Selection.activeGameObject = go;
|
|
}
|
|
|
|
void AddSelected(bool includeChildren)
|
|
{
|
|
var selected = Selection.gameObjects;
|
|
if (selected == null || selected.Length == 0)
|
|
return;
|
|
|
|
var points = new List<Transform>();
|
|
for (var i = 0; i < selected.Length; i++)
|
|
{
|
|
var go = selected[i];
|
|
if (go == null)
|
|
continue;
|
|
|
|
if (includeChildren)
|
|
points.AddRange(go.GetComponentsInChildren<Transform>(true));
|
|
else
|
|
points.Add(go.transform);
|
|
}
|
|
|
|
for (var i = 0; i < points.Count; i++)
|
|
AddPointToAll(points[i], -1f);
|
|
}
|
|
|
|
void AddPointToAll(Transform point, float holdSeconds)
|
|
{
|
|
if (point == null)
|
|
return;
|
|
|
|
foreach (var t in targets)
|
|
{
|
|
var sw = (CameraWaypointSwitcher)t;
|
|
Undo.RecordObject(sw, "Add Waypoint");
|
|
sw.AddWaypoint(point, holdSeconds);
|
|
EditorUtility.SetDirty(sw);
|
|
MarkSceneDirty(sw);
|
|
}
|
|
}
|
|
|
|
void RemoveNulls()
|
|
{
|
|
foreach (var t in targets)
|
|
{
|
|
var sw = (CameraWaypointSwitcher)t;
|
|
Undo.RecordObject(sw, "Remove Null Waypoints");
|
|
sw.RemoveNullWaypoints();
|
|
EditorUtility.SetDirty(sw);
|
|
MarkSceneDirty(sw);
|
|
}
|
|
}
|
|
|
|
void ClearPoints()
|
|
{
|
|
foreach (var t in targets)
|
|
{
|
|
var sw = (CameraWaypointSwitcher)t;
|
|
Undo.RecordObject(sw, "Clear Waypoints");
|
|
sw.ClearWaypoints();
|
|
EditorUtility.SetDirty(sw);
|
|
MarkSceneDirty(sw);
|
|
}
|
|
}
|
|
|
|
void StartPlayback()
|
|
{
|
|
foreach (var t in targets)
|
|
{
|
|
var sw = (CameraWaypointSwitcher)t;
|
|
sw.StartPlayback();
|
|
}
|
|
}
|
|
|
|
void StopPlayback(bool restore)
|
|
{
|
|
foreach (var t in targets)
|
|
{
|
|
var sw = (CameraWaypointSwitcher)t;
|
|
sw.StopPlayback(restore);
|
|
}
|
|
}
|
|
|
|
static void MarkSceneDirty(CameraWaypointSwitcher sw)
|
|
{
|
|
if (Application.isPlaying)
|
|
return;
|
|
if (!sw.gameObject.scene.IsValid())
|
|
return;
|
|
EditorSceneManager.MarkSceneDirty(sw.gameObject.scene);
|
|
}
|
|
}
|