UP-Viagg-io/Viagg-io/Assets/Packages/MyBT/BT/Editor/TaskControllerInspector.cs

632 lines
29 KiB
C#

//============= Copyright (c) Ludic GmbH, All rights reserved. ==============
//
// Purpose: Part of the My Behaviour Tree Code
//
//=============================================================================
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace MyBT {
#if UNITY_EDITOR
using UnityEditor;
using System;
using System.Reflection;
using System.Linq;
[CustomEditor(typeof(TaskController)), InitializeOnLoadAttribute]
public class TaskControllerInspector : Editor {
public bool treeTaskViewer = false;
public CodeInspector _codeInspector;
#region editor gui repaint
private int minUpdatesPerSecond = 1;
private int maxUpdatesPerSecond = 10;
private float myLastUiUpdateTime = 0f;
private float nextUpdateDelay = 1.0f;
// this is called from TaskController every time a tick happens
public void InspectorRedrawCallback(bool forceUpdate = false) {
//Debug.Log($"InspectorRedrawCallback {forceUpdate}");
TaskController _taskController = (TaskController)target;
// reduce to min time, when chages in ui
bool hasUiUpdate = ((TaskController)target).UiChangedThisFrame(); // LastUiChangeTimeEquals(_taskController.lastTickTime);
if (hasUiUpdate) {
nextUpdateDelay = 1.0f / maxUpdatesPerSecond;
}
if ((TaskController.currentUiTime > (myLastUiUpdateTime + nextUpdateDelay)) || forceUpdate) {
ForceInspectorRedraw();
}
}
public void InspectorRegenerateCallback(bool forceUpdate = false) {
//Debug.Log($"InspectorRegenerateCallback {forceUpdate}");
TaskController _taskController = (TaskController)target;
_taskController.RegenerateBehaviourTreeIfRequired(forceUpdate);
_codeInspector.RegenerateNodeLineNumberListIfRequired(forceUpdate);
ForceInspectorRedraw();
}
public void ForceInspectorRedraw () {
//Debug.Log($"TaskControllerInspector.ForceInspectorRedraw: ui update delta {(TaskController.currentUiTime - myLastUiUpdateTime)}");
myLastUiUpdateTime = TaskController.currentUiTime;
if (this != null) {
EditorUtility.SetDirty(this);
}
if (target != null) {
EditorUtility.SetDirty(target);
}
nextUpdateDelay = 1.0f / minUpdatesPerSecond;
Repaint();
}
public override bool RequiresConstantRepaint() {
return false;
}
#endregion
//TaskControllerInspector() {
// //Debug.Log($"TaskControllerInspector.Constructor {this.GetInstanceID()}");
// //EditorApplication.playModeStateChanged += LogPlayModeState;
//}
//private static void LogPlayModeState(PlayModeStateChange state) {
// switch (state) {
// // start playing
// case PlayModeStateChange.ExitingEditMode:
// Debug.Log("ExitingEditMode");
// break;
// case PlayModeStateChange.EnteredPlayMode:
// Debug.Log("EnteredPlayMode");
// break;
// // stopping playing
// case PlayModeStateChange.ExitingPlayMode:
// Debug.Log("ExitingPlayMode");
// break;
// case PlayModeStateChange.EnteredEditMode:
// Debug.Log("EnteredEditMode");
// break;
// }
//}
// http://www.voidbred.com/blog/2014/12/auto-updating-custom-inspectors-for-unity/
public void SetInspectorCallbacks () {
#if true
TaskController _taskController = (TaskController)target;
_taskController.InspectorRedraw = (val) => this.InspectorRedrawCallback(val);
_taskController.InspectorRegenerate = (val) => this.InspectorRegenerateCallback(val);
#endif
}
public void OnEnable() {
TaskController _taskController = (TaskController)target;
Debug.Log($"TaskControllerInspector.OnEnable {this.GetInstanceID()} {_taskController.name}");
// call this once to preload it (preventing error when called not in main thread)
GUISkin myBtGuiSkin = MyBtResources.myBtGuiSkin;
if (_codeInspector == null) {
_codeInspector = ScriptableObject.CreateInstance<CodeInspector>();
_codeInspector.Init((TaskController)target);
}
// fixed version of generating the code after stopping the playmode
//_taskController.ClearBinding();
//_codeInspector.ResetNodeLinenumberList();
EditorApplication.playModeStateChanged += PlayModeStateChanged;
SetInspectorCallbacks();
// update if required (forced = false)
InspectorRegenerateCallback(false);
}
public void OnDisable() {
//Debug.Log($"TaskControllerInspector.OnDisable {this.GetInstanceID()}");
if (_codeInspector != null) {
if (Application.isPlaying) {
Destroy(_codeInspector);
} else {
DestroyImmediate(_codeInspector);
}
}
_codeInspector = null;
//if (target != null) { Debug.Log($"OnDisable {((TaskController)target).gameObject.name}"); }
EditorApplication.playModeStateChanged -= PlayModeStateChanged;
}
// this is called when selecting the object
//public TaskControllerInspector() {
// Debug.Log($"TaskControllerInspector");
// EditorApplication.playModeStateChanged += PlayModeStateChanged;
//}
//~TaskControllerInspector() {
// Debug.Log($"~TaskControllerInspector");
// EditorApplication.playModeStateChanged -= PlayModeStateChanged;
//}
#region generating and clearing node line dictionary
private void PlayModeStateChanged(PlayModeStateChange playModeStateChange) {
Debug.Log($"TaskControllerInspector.PlayModeStateChanged {playModeStateChange}");
// lets rely on awake instead for rebinding of nodes
//_codeInspector.ResetNodeLinenumberList();
switch (playModeStateChange) {
case PlayModeStateChange.EnteredEditMode:
case PlayModeStateChange.EnteredPlayMode:
InspectorRegenerateCallback();
break;
case PlayModeStateChange.ExitingEditMode:
case PlayModeStateChange.ExitingPlayMode:
break;
}
}
[SerializeField]
FileHash btFileHash;
public override void OnInspectorGUI() {
//Debug.Log("TaskControllerInspector.OnInspectorGUI");
TaskController _taskController = (TaskController)target;
// Testing
// if (GUILayout.Button("Test")) {
// _taskController.destroyNextFrame = true;
// }
// TODO: check, if this is needed here as well?
// connection to TaskController calling the repaint function of this inspector
SetInspectorCallbacks();
// end of connection to TaskController
bool tick = false;
bool regenerateRequest = false;
bool restartRequest = false;
DrawCustomInspector(_taskController, ref tick, ref regenerateRequest, ref restartRequest);
// if manual reset requested
if (regenerateRequest) {
if (_taskController.runtimeLogging) Debug.Log("TaskControllerInspector.OnInspectorGUI: reset");
// clear
_codeInspector.ResetNodeLinenumberList();
_taskController.FullReset();
// generate
_taskController.FullGenerate(true);
_codeInspector.GenerateNodeLineNumberList();
}
if (restartRequest) {
if (_taskController.runtimeLogging) Debug.Log("TaskControllerInspector.OnInspectorGUI: restart");
_taskController.Restart(true);
}
if (tick) {
if (_taskController.runtimeLogging) Debug.Log("TaskControllerInspector.OnInspectorGUI: tick");
// because this can be run in edit (non playing) mode, we check if the bindings are setup in depth
_taskController.VerifyBindings();
_codeInspector.CheckLineNumberHashOutdated();
_taskController.TickUpdate();
}
if ((_codeInspector != null) && !_codeInspector.nodeLineNumberListError) {
_codeInspector.DrawCodeInspector();
}
}
Rect stateIconRect;
public void StateButton (string label, bool state, int textWidth=20) {
EditorGUILayout.BeginHorizontal(EditorStyles.helpBox);
stateIconRect = GUILayoutUtility.GetRect(GUIContent.none, new GUIStyle(), new GUILayoutOption[] {GUILayout.Width(16)});
stateIconRect.height += 2;
stateIconRect.y += 1;
stateIconRect.x += 1;
if (state) {
GUI.color = Color.green;
GUI.DrawTexture(stateIconRect, MyBtResources.trueIcon, ScaleMode.ScaleToFit);
} else {
GUI.color = Color.red;
GUI.DrawTexture(stateIconRect, MyBtResources.falseIcon, ScaleMode.ScaleToFit);
}
GUI.color = Color.white;
GUI.color = Color.white;
EditorGUILayout.LabelField(label, GUILayout.MinWidth(textWidth));
EditorGUILayout.EndHorizontal();
}
bool displayUpdateInfo = false;
public void DrawCustomInspector (TaskController _taskController, ref bool tick, ref bool regenerateRequest, ref bool restartRequest) {
GUI.enabled = false;
EditorGUILayout.PropertyField(serializedObject.FindProperty("m_Script"), true, new GUILayoutOption[0]);
GUI.enabled = true;
bool btSettingsChanged = false;
EditorGUILayout.Space();
EditorGUILayout.BeginVertical(EditorStyles.helpBox);
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField("Behaviour Tree Script Files:");
if (GUILayout.Button("+", GUILayout.Width(40))) {
_taskController.taskScripts.Add(null);
btSettingsChanged |= true;
}
EditorGUILayout.EndHorizontal();
for (int i=0; i<_taskController.taskScripts.Count; i++) {
TextAsset txtAss = _taskController.taskScripts[i];
EditorGUILayout.BeginHorizontal();
TextAsset newTxtAss = EditorGUILayout.ObjectField(txtAss, typeof(UnityEngine.TextAsset), false) as UnityEngine.TextAsset;
if (newTxtAss != txtAss) {
_taskController.taskScripts[i] = newTxtAss;
regenerateRequest |= true;
btSettingsChanged |= true;
}
if (GUILayout.Button("-", GUILayout.Width(40))) {
_taskController.taskScripts.RemoveAt(i);
btSettingsChanged |= true;
break;
}
EditorGUILayout.EndHorizontal();
}
EditorGUILayout.EndVertical();
EditorGUILayout.BeginVertical(EditorStyles.helpBox);
EditorGUILayout.LabelField("Configuration:");
EditorGUILayout.BeginHorizontal();
bool newRuntimeLogging = GUILayout.Toggle(_taskController.runtimeLogging, "Runtime Debug");
if (newRuntimeLogging != _taskController.runtimeLogging) {
_taskController.runtimeLogging = newRuntimeLogging;
btSettingsChanged |= true;
}
bool newDebugLog = GUILayout.Toggle(_taskController.generatorLogging, "Generation Debug");
if (newDebugLog != _taskController.generatorLogging){
_taskController.generatorLogging = newDebugLog;
btSettingsChanged |= true;
}
EditorGUILayout.EndHorizontal();
//EditorGUILayout.BeginHorizontal();
//bool newResetDataOnCodeChange = GUILayout.Toggle(_taskController.resetDataOnCodeChange, "Reset on Method Change");
//if (newResetDataOnCodeChange != _taskController.resetDataOnCodeChange){
// _taskController.resetDataOnCodeChange = newResetDataOnCodeChange;
// btSettingsChanged |= true;
//}
//bool newAutoGen = GUILayout.Toggle(_taskController.runtimeAutomaticRegenerate, "Code Regeneration (at runtime)");
//if (newAutoGen != _taskController.runtimeAutomaticRegenerate) {
// _taskController.runtimeAutomaticRegenerate = newAutoGen;
// btSettingsChanged |= true;
//}
//EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
TickUpdateMode newTickMode = (TickUpdateMode)EditorGUILayout.EnumPopup(new GUIContent("Update Mode", "When is the BT Executed"), _taskController.tickMode);
if (newTickMode != _taskController.tickMode) {
_taskController.tickMode = newTickMode;
btSettingsChanged |= true;
}
//GUI.color = lineNode.debugInternalActive ? Color.red : Color.white;
displayUpdateInfo = EditorGUILayout.Toggle(displayUpdateInfo, MyBtResources.helpButtonGuiStyle, GUILayout.Width(MyBtResources.defaultGuiIconWidth), GUILayout.Height(MyBtResources.defaultGuiHeight));
EditorGUILayout.EndHorizontal();
if (displayUpdateInfo) {
EditorGUILayout.BeginVertical(EditorStyles.helpBox);
GUILayout.Label(
"Update in Update or LateUpdate.\n" +
"Standard: Run One Step\n" +
"Delayed: Run One Step with Interval in Seconds\n" +
"Maximum Time: Run Steps for a Maximum Time\n" +
"Fullrun: Run Steps until Root Finishes in One Frame");
EditorGUILayout.EndVertical();
}
switch (_taskController.tickMode) {
case TickUpdateMode.Update:
case TickUpdateMode.LateUpdate:
break;
case TickUpdateMode.DelayedUpdate:
case TickUpdateMode.DelayedLateUpdate:
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField("Tick Update Interval");
float newTickDelay = EditorGUILayout.FloatField(_taskController.tickDelay);
if (newTickDelay != _taskController.tickDelay) {
_taskController.tickDelay = newTickDelay;
btSettingsChanged |= true;
}
EditorGUILayout.EndHorizontal();
break;
case TickUpdateMode.MaximumTimeLateUpdate:
case TickUpdateMode.MaximumTimeUpdate:
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField("Maximum Runtime");
float newMaximumRuntime = EditorGUILayout.FloatField(_taskController.maximumRuntime);
if (newMaximumRuntime != _taskController.maximumRuntime) {
_taskController.maximumRuntime = newMaximumRuntime;
btSettingsChanged |= true;
}
EditorGUILayout.EndHorizontal();
break;
case TickUpdateMode.Manual:
break;
}
EditorGUILayout.BeginHorizontal();
restartRequest |= GUILayout.Button("Restart", GUILayout.Width(80));
regenerateRequest |= GUILayout.Button("Regenerate", GUILayout.Width(80));
EditorGUILayout.Space();
GUI.enabled = (_taskController.tickMode == TickUpdateMode.Manual) || !Application.isPlaying;
tick |= GUILayout.Button("Manual Tick", GUILayout.Width(80));
if (GUILayout.Button("Clear Console", GUILayout.Width(80))) {
ClearLogConsole();
}
GUI.enabled = true;
EditorGUILayout.EndHorizontal();
EditorGUILayout.Space();
EditorGUILayout.EndVertical();
if (_taskController.runtimeLogging) {
EditorGUILayout.BeginVertical(EditorStyles.helpBox);
if (GUILayout.Button("Re-Draw", GUILayout.Width(80))) {
_taskController.SetUiUpdate();
}
bool newOverrideLogStringDisplay = EditorGUILayout.ToggleLeft("overrideLogStringDisplay (default off)", _taskController.overrideLogStringDisplay, GUILayout.MinWidth(60));
if (newOverrideLogStringDisplay != _taskController.overrideLogStringDisplay) {
_taskController.overrideLogStringDisplay = newOverrideLogStringDisplay;
btSettingsChanged |= true;
}
bool newOverrideDebugChangesActive = EditorGUILayout.ToggleLeft("overrideDebugChangesActive (default off)", _taskController.overrideDebugChangesActive, GUILayout.MinWidth(60));
if (newOverrideDebugChangesActive != _taskController.overrideDebugChangesActive) {
_taskController.overrideDebugChangesActive = newOverrideDebugChangesActive;
btSettingsChanged |= true;
}
bool newOverrideDebugInternalActive = EditorGUILayout.ToggleLeft("overrideDebugInternalActive (default off)", _taskController.overrideDebugInternalActive, GUILayout.MinWidth(60));
if (newOverrideDebugInternalActive != _taskController.overrideDebugInternalActive) {
_taskController.overrideDebugInternalActive = newOverrideDebugInternalActive;
btSettingsChanged |= true;
}
EditorGUILayout.EndVertical();
}
if (!_taskController.internalAutomaticRegenerate || _taskController.generatorLogging) {
EditorGUILayout.BeginVertical(EditorStyles.helpBox);
GUILayout.BeginHorizontal();
GUI.color = Color.white;
int numberOfNodes = _taskController.nodeCount;
GUILayout.Label($"{numberOfNodes} nodes Generated");
// GUILayout.TextArea(NodeGenerator.GeneratedSize(_taskController.treeRootNodes).ToString(), GUILayout.Width(30));
if (_taskController.generationError || _taskController.bindingError) {
GUI.color = Color.red;
}
//regenerateRequest |= GUILayout.Button("Re-Generate", GUILayout.Width(80));
//btSettingsChanged |= regenerateRequest;
GUILayout.EndHorizontal();
bool newInternalAutomaticRegenerate = EditorGUILayout.ToggleLeft("internalAutomaticRegenerate (default on)", _taskController.internalAutomaticRegenerate, GUILayout.MinWidth(60));
if (newInternalAutomaticRegenerate != _taskController.internalAutomaticRegenerate) {
_taskController.internalAutomaticRegenerate = newInternalAutomaticRegenerate;
btSettingsChanged |= true;
}
EditorGUILayout.EndVertical();
}
if (_taskController.generatorLogging) {
EditorGUILayout.BeginVertical(EditorStyles.helpBox);
float inspectorWidth = 0;
inspectorWidth = EditorGUIUtility.currentViewWidth - 60;
float halfWidth = (inspectorWidth - 1) / 2 - 2;
float thirdWidth = 20;
EditorGUILayout.BeginHorizontal();
if (GUILayout.Button("BtScriptChangeDetected", GUILayout.MinWidth(thirdWidth))) {
_taskController.BtScriptChangeDetected();
btSettingsChanged |= true;
}
if (GUILayout.Button("BtMethodChanged", GUILayout.MinWidth(thirdWidth))) {
_taskController.ClearBindingsAndScanAndBindMethods();
btSettingsChanged |= true;
}
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
if (GUILayout.Button("ResetNodesAndTokens", GUILayout.MinWidth(thirdWidth))) {
_taskController.ResetNodesAndTokens();
btSettingsChanged |= true;
}
if (GUILayout.Button("GenerateTokensAndNodes", GUILayout.MinWidth(thirdWidth))) {
_taskController.GenerateTokensAndNodes(true);
btSettingsChanged |= true;
}
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
if (GUILayout.Button("ClearBinding", GUILayout.MinWidth(thirdWidth))) {
_taskController.ClearBinding();
btSettingsChanged |= true;
}
if (GUILayout.Button("Bind", GUILayout.MinWidth(thirdWidth))) {
_taskController.ScanAndBindMethods(false);
btSettingsChanged |= true;
}
if (GUILayout.Button("Bind Force", GUILayout.MinWidth(thirdWidth))) {
_taskController.ScanAndBindMethods(true);
btSettingsChanged |= true;
}
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
if (GUILayout.Button("ResetNodeLinenumberList", GUILayout.MinWidth(thirdWidth))) {
_codeInspector.ResetNodeLinenumberList();
btSettingsChanged |= true;
}
if (GUILayout.Button("GenerateNodeLineNumberList", GUILayout.MinWidth(thirdWidth))) {
_codeInspector.GenerateNodeLineNumberList();
btSettingsChanged |= true;
}
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
if (GUILayout.Button("Set TaskController", GUILayout.MinWidth(thirdWidth))) {
_taskController.SetTaskController();
btSettingsChanged |= true;
}
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
NodeGenerator.debugActive = EditorGUILayout.ToggleLeft("NodeGenerator debugActive", NodeGenerator.debugActive, GUILayout.MinWidth(60));
MethodScanner.debugActive = EditorGUILayout.ToggleLeft("MethodScanner debugActive", MethodScanner.debugActive, GUILayout.MinWidth(60));
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField($"MethodBinder:", GUILayout.MaxWidth(80));
MethodBinder.debug = EditorGUILayout.ToggleLeft("debug", MethodBinder.debug, GUILayout.MinWidth(40));
MethodBinder.debugIsBound = EditorGUILayout.ToggleLeft("debugIsBound", MethodBinder.debugIsBound, GUILayout.MinWidth(60));
MethodBinder.debugRunTreeBinding = EditorGUILayout.ToggleLeft("debugRunTreeBinding", MethodBinder.debugRunTreeBinding, GUILayout.MinWidth(60));
MethodBinder.debugActionBinding = EditorGUILayout.ToggleLeft("debugActionBinding", MethodBinder.debugActionBinding, GUILayout.MinWidth(60));
EditorGUILayout.EndHorizontal();
int hashMinWidth = 60;
EditorGUILayout.BeginHorizontal();
StateButton("Has Script", _taskController.hasScript);
StateButton("Has TickEnumerator", (_taskController.tickEnumerator != null));
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField($"Script Count: {_taskController.taskScripts.Count}", GUILayout.MinWidth(hashMinWidth));
GUILayout.FlexibleSpace();
EditorGUILayout.LabelField($"{(_taskController.textAssetHashes!=null?_taskController.textAssetHashes.ToString():"undefined")}", GUILayout.MinWidth(hashMinWidth));
EditorGUILayout.EndHorizontal();
// EditorGUILayout.BeginHorizontal();
// StateButton("Tokens Generated", _taskController.tokensGenerated);
// StateButton("Nodes Generated", _taskController.nodesGenerated);
// StateButton("isGenerated", _taskController.isGenerated);
// EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
StateButton("Generation Succeeded", !_taskController.generationError);
StateButton("Generation Updated", !_taskController.CheckGenerationOutdated(false));
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
int count = _taskController.treeRootNodes!=null?_taskController.treeRootNodes.Sum(o => o.Count):0;
EditorGUILayout.LabelField($"TreeRootNode Count: {count}", GUILayout.MinWidth(hashMinWidth));
GUILayout.FlexibleSpace();
EditorGUILayout.LabelField($"{(_taskController.generatedCodeBtFileHashes!=null?_taskController.generatedCodeBtFileHashes.ToString():"undefined")}", GUILayout.MinWidth(hashMinWidth));
EditorGUILayout.EndHorizontal();
// EditorGUILayout.BeginHorizontal();
// StateButton("methodsScanned", _taskController.methodsScanned);
// StateButton("methodsBound", _taskController.methodsBound);
// StateButton("isBound", _taskController.methodsBound);
// EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
StateButton("Binding Succeeded", !_taskController.bindingError);
StateButton("Binding Updated", !_taskController.CheckBindingOutdated(false));
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField($"Method Count: {(_taskController.methods != null ? _taskController.methods.Count : 0)}", GUILayout.MinWidth(hashMinWidth));
GUILayout.FlexibleSpace();
EditorGUILayout.LabelField($"{_taskController.boundCodeBtFileHashes.ToString()}", GUILayout.MinWidth(hashMinWidth));
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
StateButton("NodeLineNumberList Generated", _codeInspector.nodeLineNumberListGenerated);
StateButton("Has TaskController", _codeInspector.hasTaskControllerDefined);
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
StateButton("Code Succeeded", !_codeInspector.nodeLineNumberListError);
StateButton("LineNumberHash Updated", !_codeInspector.CheckLineNumberHashOutdated(false));
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField($"nodeLineCount: {_codeInspector.nodeLineCount}", GUILayout.MinWidth(hashMinWidth));
GUILayout.FlexibleSpace();
EditorGUILayout.LabelField($"{(_codeInspector.lineNumberListBtFileHashes !=null? _codeInspector.lineNumberListBtFileHashes.ToString():"undefined")}", GUILayout.MinWidth(hashMinWidth));
EditorGUILayout.EndHorizontal();
// SerializedObject sObj = new SerializedObject(_taskController);
SerializedProperty sProp = _taskController.treeRootNodesAsSerializedProperty;
if (sProp != null) {
EditorGUILayout.PropertyField(sProp, true);
}
else {
EditorGUILayout.LabelField($"treeRootNodes missing", GUILayout.MinWidth(hashMinWidth));
}
SerializedProperty tProp = _codeInspector.openNodeLinesAsSerializedProperty;
if (tProp != null) {
EditorGUILayout.PropertyField(tProp, true);
}
else {
EditorGUILayout.LabelField($"openNodeLinesAsSerializedProperty missing", GUILayout.MinWidth(hashMinWidth));
}
EditorGUILayout.EndVertical();
}
if (btSettingsChanged) {
_codeInspector.SetDirty();
}
}
#endregion
static MethodInfo _clearConsoleMethod;
static MethodInfo clearConsoleMethod {
get {
if (_clearConsoleMethod == null) {
Assembly assembly = Assembly.GetAssembly(typeof(SceneView));
Type logEntries = assembly.GetType("UnityEditor.LogEntries");
_clearConsoleMethod = logEntries.GetMethod("Clear");
}
return _clearConsoleMethod;
}
}
public static void ClearLogConsole() {
clearConsoleMethod.Invoke(new object(), null);
}
public static void GameViewRepaint () {
System.Reflection.Assembly assembly = typeof(UnityEditor.EditorWindow).Assembly;
System.Type type = assembly.GetType("UnityEditor.GameView");
EditorWindow gameview = EditorWindow.GetWindow(type);
gameview.Repaint();
}
}
#endif
}