update CCK to 3.10, fixing unity 2021 crash :)

This commit is contained in:
Crispy 2024-08-03 22:24:42 +02:00
parent 48a978fa2a
commit d11e0fb3a9
492 changed files with 2165204 additions and 437687 deletions

View 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

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0f8ef1acbc515f14a95ab5d052d380aa
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -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

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5dcbab43e1f6d26409fe31f9bd79ca2c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: