update CCK to 3.10, fixing unity 2021 crash :)
This commit is contained in:
parent
48a978fa2a
commit
d11e0fb3a9
492 changed files with 2165204 additions and 437687 deletions
57
Assets/ABI.CCK/Scripts/Editor/CCK_BodyControlEditor/CCK_BodyControlEditor.cs
Executable file
57
Assets/ABI.CCK/Scripts/Editor/CCK_BodyControlEditor/CCK_BodyControlEditor.cs
Executable file
|
@ -0,0 +1,57 @@
|
|||
#if UNITY_EDITOR
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using ABI.CCK.Scripts;
|
||||
using ABI.CCK.Scripts.Editor;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace ABI.CCK.Components
|
||||
{
|
||||
[CanEditMultipleObjects]
|
||||
[CustomEditor(typeof(BodyControl))]
|
||||
public partial class CCK_BodyControlEditor : Editor
|
||||
{
|
||||
#region Variables
|
||||
|
||||
private BodyControl _bodyControl;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Serialized Properties
|
||||
|
||||
private SerializedProperty m_EnterTasksProp;
|
||||
private SerializedProperty m_ExitTasksProp;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Unity Events
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
if (target == null) return;
|
||||
_bodyControl = (BodyControl)target;
|
||||
|
||||
m_EnterTasksProp = serializedObject.FindProperty(nameof(BodyControl.EnterTasks));
|
||||
m_ExitTasksProp = serializedObject.FindProperty(nameof(BodyControl.ExitTasks));
|
||||
|
||||
Initialize_TaskLists();
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
if (_bodyControl == null)
|
||||
return;
|
||||
|
||||
serializedObject.Update();
|
||||
|
||||
Draw_Tasks();
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 0f8ef1acbc515f14a95ab5d052d380aa
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,357 @@
|
|||
#if UNITY_EDITOR
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using ABI.CCK.Scripts.Editor;
|
||||
using ABI.CCK.Scripts.Editor.Tools;
|
||||
using UnityEditor;
|
||||
using UnityEditorInternal;
|
||||
using UnityEngine;
|
||||
|
||||
namespace ABI.CCK.Components
|
||||
{
|
||||
public partial class CCK_BodyControlEditor
|
||||
{
|
||||
private ReorderableList _onEnterList;
|
||||
private ReorderableList _onExitList;
|
||||
private int _selectedEnterEntry = -1;
|
||||
private int _selectedExitEntry = -1;
|
||||
|
||||
private bool _isInPlayMode;
|
||||
|
||||
private void Initialize_TaskLists()
|
||||
{
|
||||
_isInPlayMode = Application.isPlaying;
|
||||
|
||||
_onEnterList ??= new ReorderableList(serializedObject, m_EnterTasksProp,
|
||||
true, true, !_isInPlayMode, !_isInPlayMode)
|
||||
{
|
||||
drawHeaderCallback = OnDrawHeaderTaskEnter,
|
||||
drawElementCallback = OnDrawElementTaskEnter,
|
||||
elementHeightCallback = OnHeightElementTaskEnter,
|
||||
onAddCallback = OnAddElement,
|
||||
onMouseUpCallback = OnMouseUpEnter,
|
||||
//multiSelect = true, // TODO: Can we implement changing multiple tasks at once?
|
||||
list = _bodyControl.EnterTasks,
|
||||
index = -1
|
||||
};
|
||||
|
||||
_onExitList ??= new ReorderableList(serializedObject, m_ExitTasksProp,
|
||||
true, true, !_isInPlayMode, !_isInPlayMode)
|
||||
{
|
||||
drawHeaderCallback = OnDrawHeaderTaskExit,
|
||||
drawElementCallback = OnDrawElementTaskExit,
|
||||
elementHeightCallback = OnHeightElementTaskExit,
|
||||
onAddCallback = OnAddElement,
|
||||
onMouseUpCallback = OnMouseUpExit,
|
||||
list = _bodyControl.ExitTasks,
|
||||
index = -1
|
||||
};
|
||||
}
|
||||
|
||||
private void Draw_Tasks()
|
||||
{
|
||||
using (new EditorGUILayout.VerticalScope(new GUIStyle() { padding = new RectOffset(10, 10, 10, 10) }))
|
||||
{
|
||||
EditorGUILayout.Space();
|
||||
_onEnterList.displayAdd = CanAddTarget(_onEnterList.list as IEnumerable<BodyControlTask>);
|
||||
_onEnterList.DoLayoutList();
|
||||
|
||||
EditorGUILayout.Space();
|
||||
_onExitList.displayAdd = CanAddTarget(_onExitList.list as IEnumerable<BodyControlTask>);
|
||||
_onExitList.DoLayoutList();
|
||||
}
|
||||
}
|
||||
|
||||
#region ReorderableList Callbacks
|
||||
|
||||
// Enter Tasks
|
||||
|
||||
private void OnDrawHeaderTaskEnter(Rect rect)
|
||||
{
|
||||
Rect labelRect = new Rect(rect.x, rect.y, rect.width - 35, EditorGUIUtility.singleLineHeight);
|
||||
GUI.Label(labelRect, "On Enter Tasks");
|
||||
EditorGUIExtensions.UtilityMenu(rect, _onEnterList, m_EnterTasksProp,
|
||||
appendAdditionalMenuItems: (menuBuilder, list) => {
|
||||
AppendUtilityMenu(menuBuilder, _onEnterList, true);
|
||||
});
|
||||
}
|
||||
|
||||
private void OnDrawElementTaskEnter(Rect rect, int index, bool isactive, bool isfocused)
|
||||
{
|
||||
if (index >= _bodyControl.EnterTasks.Count) return;
|
||||
SerializedProperty taskProperty = _onEnterList.serializedProperty.GetArrayElementAtIndex(index);
|
||||
if (taskProperty == null || index >= _onEnterList.serializedProperty.arraySize)
|
||||
return;
|
||||
|
||||
using (new EditorGUI.DisabledScope(_isInPlayMode))
|
||||
RenderTask(rect, _onEnterList, taskProperty);
|
||||
}
|
||||
|
||||
private float OnHeightElementTaskEnter(int index)
|
||||
{
|
||||
float lineHeight = EditorGUIUtility.singleLineHeight * 1.25f;
|
||||
if (index < 0 || index >= _bodyControl.EnterTasks.Count)
|
||||
return lineHeight;
|
||||
|
||||
BodyControlTask task = _bodyControl.EnterTasks[index];
|
||||
return TaskLines(task) * lineHeight;
|
||||
}
|
||||
|
||||
private void OnMouseUpEnter(ReorderableList list)
|
||||
{
|
||||
if (list.index != _selectedEnterEntry)
|
||||
{
|
||||
_selectedEnterEntry = list.index;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (list.index == -1)
|
||||
return;
|
||||
|
||||
list.Deselect(_selectedEnterEntry);
|
||||
list.index = _selectedEnterEntry = -1;
|
||||
Repaint();
|
||||
}
|
||||
}
|
||||
|
||||
// Exit Tasks
|
||||
|
||||
private void OnDrawHeaderTaskExit(Rect rect)
|
||||
{
|
||||
Rect labelRect = new Rect(rect.x, rect.y, rect.width - 35, EditorGUIUtility.singleLineHeight);
|
||||
GUI.Label(labelRect, "On Exit Tasks");
|
||||
EditorGUIExtensions.UtilityMenu(rect, _onExitList, m_ExitTasksProp,
|
||||
appendAdditionalMenuItems: (menuBuilder, list) => {
|
||||
AppendUtilityMenu(menuBuilder, _onExitList, false);
|
||||
});
|
||||
}
|
||||
|
||||
private void OnDrawElementTaskExit(Rect rect, int index, bool isactive, bool isfocused)
|
||||
{
|
||||
if (index >= _bodyControl.ExitTasks.Count) return;
|
||||
SerializedProperty taskProperty = _onExitList.serializedProperty.GetArrayElementAtIndex(index);
|
||||
if (taskProperty == null || index >= _onExitList.serializedProperty.arraySize)
|
||||
return;
|
||||
|
||||
using (new EditorGUI.DisabledScope(_isInPlayMode))
|
||||
RenderTask(rect, _onExitList, taskProperty);
|
||||
}
|
||||
|
||||
private float OnHeightElementTaskExit(int index)
|
||||
{
|
||||
float lineHeight = EditorGUIUtility.singleLineHeight * 1.25f;
|
||||
if (index < 0 || index >= _bodyControl.ExitTasks.Count)
|
||||
return lineHeight;
|
||||
|
||||
BodyControlTask task = _bodyControl.ExitTasks[index];
|
||||
return TaskLines(task) * lineHeight;
|
||||
}
|
||||
|
||||
private void OnMouseUpExit(ReorderableList list)
|
||||
{
|
||||
if (list.index != _selectedExitEntry)
|
||||
{
|
||||
_selectedExitEntry = list.index;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (list.index == -1)
|
||||
return;
|
||||
|
||||
list.Deselect(_selectedExitEntry);
|
||||
list.index = _selectedExitEntry = -1;
|
||||
Repaint();
|
||||
}
|
||||
}
|
||||
|
||||
// Shared
|
||||
|
||||
private void OnAddElement(ReorderableList list)
|
||||
{
|
||||
int targetIndex = list.count;
|
||||
list.serializedProperty.InsertArrayElementAtIndex(targetIndex);
|
||||
|
||||
// list.list is the direct list of tasks
|
||||
|
||||
int nextTarget = 0; // get the first target that isn't already in use
|
||||
while (list.list.Cast<BodyControlTask>().Any(task => task.target == (BodyControlTask.BodyMask)nextTarget))
|
||||
nextTarget++;
|
||||
|
||||
list.serializedProperty.GetArrayElementAtIndex(targetIndex).FindPropertyRelative(nameof(BodyControlTask.target)).intValue = nextTarget;
|
||||
|
||||
// select it
|
||||
list.index = targetIndex;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region BodyControlTask Drawing
|
||||
|
||||
private int TaskLines(BodyControlTask task)
|
||||
{
|
||||
int length = 1;
|
||||
|
||||
if (task.isBlend)
|
||||
length += 2;
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
private void RenderTask(Rect rect, ReorderableList list, SerializedProperty taskProperty)
|
||||
{
|
||||
rect = new Rect(rect.x, rect.y + 2, rect.width, EditorGUIUtility.singleLineHeight);
|
||||
|
||||
float spacing = EditorGUIUtility.singleLineHeight * 1.25f;
|
||||
float originalLabelWidth = EditorGUIUtility.labelWidth;
|
||||
EditorGUIUtility.labelWidth = 100;
|
||||
|
||||
SerializedProperty targetProp = taskProperty.FindPropertyRelative(nameof(BodyControlTask.target));
|
||||
SerializedProperty targetWeightProp = taskProperty.FindPropertyRelative(nameof(BodyControlTask.targetWeight));
|
||||
SerializedProperty transitionDurationProp = taskProperty.FindPropertyRelative(nameof(BodyControlTask.transitionDuration));
|
||||
|
||||
SerializedProperty isBlendProp = taskProperty.FindPropertyRelative(nameof(BodyControlTask.isBlend));
|
||||
|
||||
// Draw setting type dropdowns
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
Rect position = rect;
|
||||
float halfWidth = (position.width) / 2 - 2;
|
||||
|
||||
// Target Dropdown
|
||||
|
||||
// display popup of targets that are not already in use in the list
|
||||
var availableTargets = GetAvailableTargets(list.list as IEnumerable<BodyControlTask>, targetProp);
|
||||
int selectedIndex = EditorGUI.Popup(new Rect(position.x, position.y, halfWidth, position.height), availableTargets.IndexOf((BodyControlTask.BodyMask)targetProp.intValue), availableTargets.Select(t => t.ToString()).ToArray());
|
||||
if (selectedIndex >= 0) targetProp.intValue = (int)availableTargets[selectedIndex];
|
||||
|
||||
// Type Dropdown
|
||||
int selectedOption = isBlendProp.boolValue switch
|
||||
{
|
||||
true => 2,
|
||||
_ => targetWeightProp.floatValue switch
|
||||
{
|
||||
0f => 1, // On
|
||||
1f => 0, // Off
|
||||
_ => 2 // Blend
|
||||
}
|
||||
};
|
||||
|
||||
selectedOption =
|
||||
EditorGUI.Popup(new Rect(position.x + halfWidth + 4, position.y, halfWidth, position.height),
|
||||
selectedOption, new [] { "Enabled", "Disabled" /*, "Blend" */ });
|
||||
|
||||
isBlendProp.boolValue = selectedOption == 2;
|
||||
targetWeightProp.floatValue = selectedOption switch
|
||||
{
|
||||
0 => 1f, // On
|
||||
1 => 0f, // Off
|
||||
_ => targetWeightProp.floatValue // Blend
|
||||
};
|
||||
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
if (selectedOption == 2)
|
||||
{
|
||||
rect.y += spacing;
|
||||
|
||||
EditorGUI.PropertyField(rect, targetWeightProp);
|
||||
rect.y += spacing;
|
||||
|
||||
EditorGUI.PropertyField(rect, transitionDurationProp, new GUIContent("Transition (s)"));
|
||||
}
|
||||
|
||||
EditorGUIUtility.labelWidth = originalLabelWidth;
|
||||
}
|
||||
|
||||
private static bool CanAddTarget(IEnumerable<BodyControlTask> tasks)
|
||||
{
|
||||
var allTargets = Enum.GetValues(typeof(BodyControlTask.BodyMask)).Cast<BodyControlTask.BodyMask>().ToList();
|
||||
var usedTargets = tasks.Select(task => task.target).Distinct().ToList();
|
||||
return allTargets.Except(usedTargets).Any();
|
||||
}
|
||||
|
||||
private static List<BodyControlTask.BodyMask> GetAvailableTargets(IEnumerable<BodyControlTask> tasks, SerializedProperty targetProp)
|
||||
{
|
||||
var allTargets = Enum.GetValues(typeof(BodyControlTask.BodyMask)).Cast<BodyControlTask.BodyMask>().ToList();
|
||||
var usedTargets = tasks.Select(task => task.target).Distinct().ToList();
|
||||
var availableTargets = allTargets.Where(target => !usedTargets.Contains(target)).ToList();
|
||||
|
||||
if (targetProp.intValue >= 0 && !availableTargets.Contains((BodyControlTask.BodyMask)targetProp.intValue))
|
||||
availableTargets.Add((BodyControlTask.BodyMask)targetProp.intValue);
|
||||
|
||||
return availableTargets;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Utility
|
||||
|
||||
private void AppendUtilityMenu(GenericMenuBuilder genericMenuBuilder, ReorderableList list, bool isEnterList)
|
||||
{
|
||||
bool hasSelectedTask = list.index != -1;
|
||||
bool hasTasks = list.count > 0;
|
||||
|
||||
genericMenuBuilder.AddMenuItem("Set All Enabled", hasTasks, () => SetAllTasksState(list, 1f));
|
||||
genericMenuBuilder.AddMenuItem("Set All Disabled", hasTasks, () => SetAllTasksState(list, 0f));
|
||||
|
||||
genericMenuBuilder.AddSeparator();
|
||||
|
||||
string moveToOtherListLabel = isEnterList ? "To Exit Task" : "To Enter Task";
|
||||
genericMenuBuilder.AddMenuItem(moveToOtherListLabel, hasTasks && hasSelectedTask,
|
||||
() => ConvertSelectedTask(list, isEnterList ? _bodyControl.EnterTasks : _bodyControl.ExitTasks,
|
||||
isEnterList ? _bodyControl.ExitTasks : _bodyControl.EnterTasks));
|
||||
|
||||
string convertAllLabel = isEnterList ? "All to Exit Task" : "All to Enter Task";
|
||||
genericMenuBuilder.AddMenuItem(convertAllLabel, hasTasks,
|
||||
() => ConvertAllTasks(isEnterList ? _bodyControl.EnterTasks : _bodyControl.ExitTasks,
|
||||
isEnterList ? _bodyControl.ExitTasks : _bodyControl.EnterTasks));
|
||||
}
|
||||
|
||||
private void ConvertAllTasks(List<BodyControlTask> fromTasks, List<BodyControlTask> toTasks)
|
||||
{
|
||||
foreach (BodyControlTask task in fromTasks)
|
||||
{
|
||||
BodyControlTask existingTask = toTasks.FirstOrDefault(t => t.target == task.target);
|
||||
if (existingTask != null)
|
||||
{
|
||||
existingTask.targetWeight = task.targetWeight;
|
||||
}
|
||||
else
|
||||
{
|
||||
toTasks.Add(task);
|
||||
}
|
||||
}
|
||||
fromTasks.Clear();
|
||||
}
|
||||
|
||||
private void ConvertSelectedTask(ReorderableList list, List<BodyControlTask> fromTasks, List<BodyControlTask> toTasks)
|
||||
{
|
||||
if (list.index == -1 || list.index >= fromTasks.Count)
|
||||
return;
|
||||
|
||||
BodyControlTask selectedTask = fromTasks[list.index];
|
||||
BodyControlTask existingTask = toTasks.FirstOrDefault(t => t.target == selectedTask.target);
|
||||
|
||||
if (existingTask != null)
|
||||
{
|
||||
existingTask.targetWeight = selectedTask.targetWeight;
|
||||
}
|
||||
else
|
||||
{
|
||||
toTasks.Add(selectedTask);
|
||||
}
|
||||
|
||||
fromTasks.RemoveAt(list.index);
|
||||
}
|
||||
|
||||
private void SetAllTasksState(ReorderableList list, float stateValue)
|
||||
{
|
||||
IList tasks = list.list;
|
||||
foreach (BodyControlTask task in tasks) task.targetWeight = stateValue;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 5dcbab43e1f6d26409fe31f9bd79ca2c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Loading…
Add table
Add a link
Reference in a new issue