Files
Cielonos/Assets/OtherPlugins/EasyColliderEditor/Scripts/EasyColliderPreferences.cs
SoulliesOfficial ef7b479712 initial
2025-11-25 08:19:33 -05:00

616 lines
22 KiB
C#

#if (UNITY_EDITOR)
using UnityEngine;
using UnityEditor;
using System.IO;
namespace ECE
{
[System.Serializable]
public class EasyColliderPreferences : ScriptableObject
{
#if (!UNITY_EDITOR_LINUX)
/// <summary>
/// Currently set vhacd parameters.
/// </summary>
[SerializeField] private VHACDParameters _VHACDParameters;
public VHACDParameters VHACDParameters
{
get
{
if (_VHACDParameters == null)
{
_VHACDParameters = new VHACDParameters();
}
return _VHACDParameters;
}
set { _VHACDParameters = value; }
}
/// <summary>
/// Float to convert to vhacd parameters resolution using 2^Value for UI Slider when advanced parameters is expanded
/// </summary>
[SerializeField] public float VHACDResFloat = 12.97f;
/// <summary>
/// Resets vhacd parameters to default.
/// </summary>
public void VHACDSetDefaultParameters()
{
VHACDParameters = new VHACDParameters();
}
#endif
/// <summary>
/// When enabled, selecting objects in the background of the scene view can be done with a single click even when an object is currently selected for collider creation.
/// </summary>
[SerializeField] public bool AllowBackgroundSelection;
/// <summary>
/// when enabled, allows convex hulls used in mesh colliders to be saved in Packages folder.
/// THESE FILES ARE NOT SHARED WITH JUST THE PROJECT. MUST BE HANDLED BY YOUR TEAM. MUST ALSO SHARE SOURCE PACKAGES FOLDERS
/// </summary>
[SerializeField] public bool AllowSavingConvexHullsInPackages;
/// <summary>
/// When entering prefab mode, should we automatically select the root object?
/// </summary>
[SerializeField] public bool AutoSelectOnPrefabOpen;
/// <summary>
/// Auto include child skinned meshes
/// </summary>
[SerializeField] public bool AutoIncludeChildSkinnedMeshes;
/// <summary>
/// Should we try to reduce the number of vertices in auto-skinned calculations for convex mesh colliders if the result ends up trying to create a collider that has >=256 triangles.
/// </summary>
[SerializeField] public bool AutoSkinnedForce256Triangles;
/// <summary>
/// The minimum weight for a vertex to be included in a bone's calculations.
/// </summary>
[SerializeField] public float AutoSkinnedMinBoneWeight;
/// <summary>
/// The angle of mis-alignedment above which we should create a better aligned child transform to hold colliders for skinned meshes.
/// </summary>
[SerializeField] public float AutoSkinnedMinRealignAngle;
/// <summary>
/// Should we allow transforms to be created that would better align the collider with the mesh than a mis-aligned bone?
/// </summary>
[SerializeField] public bool AutoSkinnedAllowRealign;
/// <summary>
/// Type of collider to use when auto generating skinned mesh colliders along a bone chain.
/// </summary>
[SerializeField] public SKINNED_MESH_COLLIDER_TYPE AutoSkinnedColliderType = SKINNED_MESH_COLLIDER_TYPE.Box;
/// <summary>
/// Should we be attempting to compute penetration and depenetrate the colliders on the skinned mesh?
/// </summary>
[SerializeField] public bool AutoSkinnedDepenetrate;
/// <summary>
/// Are we displaying with indentation?
/// </summary>
[SerializeField] public bool AutoSkinnedIndents = true;
/// <summary>
/// number of times to run depenetration methods before stopping.
/// </summary>
[SerializeField] public int AutoSkinnedIterativeDepenetrationCount = 15;
/// <summary>
/// Are we displaying with paired bones?
/// </summary>
[SerializeField] public bool AutoSkinnedPairing = true;
/// <summary>
/// Are we using per-bone settings
/// </summary>
[SerializeField] public bool AutoSkinnedPerBoneSettings;
/// <summary>
/// Amount of collider shrinking (along the various shift's) to do before trying to shift depenetrate.
/// </summary>
[SerializeField] public float AutoSkinnedShrinkAmount = 0.5f;
[Tooltip("Enables using bone position distances during pairing of bones. (AutoSkinnedPairedDistanceDelta controls the distance when enabled.")]
[SerializeField] public bool AutoSkinnedUseDistanceDeltaPairing = true;
[Tooltip("Max distance difference between possible bone pairs to still be considered as a pair. Checked along with length of child bone-chain.")]
[SerializeField] public float AutoSkinnedPairedDistanceDelta = 0.01f;
/// <summary>
/// The way we should sort the bone list in auto-skinned.
/// </summary>
[SerializeField] public SKINNED_MESH_DEPENETRATE_ORDER AutoSkinnedDepenetrateOrder;
/// <summary>
/// Key to hold before box selection to only add vertices in the box.
/// </summary>
[SerializeField] public KeyCode BoxSelectPlusKey;
/// <summary>
/// Key to hold before box selection to only remove vertices in the box.
/// </summary>
[SerializeField] public KeyCode BoxSelectMinusKey;
/// <summary>
/// Capsule collider generation method to use when creating a capsule collider.
/// </summary>
[SerializeField] public CAPSULE_COLLIDER_METHOD CapsuleColliderMethod;
/// <summary>
/// when enabled, when generating multiple convex mesh colliders with vhacd, they are all combined and stored in a single asset file.
/// </summary>
[SerializeField] public bool CombinedVHACDColliders;
/// <summary>
/// A helpful common multiplier for all scales when using any scaling method.
/// </summary>
[SerializeField] public float CommonScalingMultiplier = 1.0f;
/// <summary>
/// should created meshes used in convex mesh colliders be read/write enabled
/// </summary>
[SerializeField] public bool ConvexMeshReadWriteEnabled = true;
[Tooltip("Default scale of the displayed boxes / gizmos around vertices. Combined with common scaling multiplier.")]
/// <summary>
/// Default scale of displayed vertices used along with the common scaling multiplier.
/// </summary>
[SerializeField] public float DefaultScale = 0.01f;
/// <summary>
/// scale for vertices that are hovered / will be added to the selected vertices
/// </summary>
[SerializeField] public float HoveredScaleMult = 1.0f;
/// <summary>
/// scale multiplier for vertices when using display all vertices
/// </summary>
[SerializeField] public float DisplayAllScaleMult = 1.0f;
/// <summary>
/// scale multiplier for vertices that will be removed from the selected vertices
/// </summary>
[SerializeField] public float OverlapScaleMult = 1.0f;
/// <summary>
/// scale multiplier for vertices that are currently selected.
/// </summary>
[SerializeField] public float SelectedScaleMult = 1.0f;
/// <summary>
/// The method to use when creating a collider: if and how a gameobject should be made to hold the collider.
/// </summary>
[SerializeField] public COLLIDER_HOLDER ColliderHolder = COLLIDER_HOLDER.Default;
/// <summary>
/// key to press to create from the current preview.
/// </summary>
[SerializeField] public KeyCode CreateFromPreviewKey;
/// <summary>
/// Should cylinder orientation field apply to capsules as well.
/// </summary>
[SerializeField] public bool CylinderAsCapsuleOrientation = false;
/// <summary>
/// number of sides when creating a cylinder collider.
/// </summary>
[SerializeField] public int CylinderNumberOfSides = 16;
/// <summary>
/// Method to use to decide which axis a cylinder should be oriented on.
/// </summary>
[SerializeField] public CYLINDER_ORIENTATION CylinderOrientation;
/// <summary>
/// Offset in degrees when creating a cylinder.
/// </summary>
[SerializeField] public float CylinderRotationOffset = 0.0f;
/// <summary>
/// Should tips be displayed?
/// </summary>
[SerializeField] public bool DisplayTips;
/// <summary>
/// Should we display compute shader / gizmos on all the vertices?
/// </summary>
[SerializeField] public bool DisplayAllVertices;
/// <summary>
/// Display vertices colour
/// </summary>
[SerializeField] public Color DisplayVerticesColour;
[SerializeField] public bool EnableVertexToolsShortcuts = true;
/// <summary>
/// Type of gizmos to use when drawing gizmos for vertices
/// </summary>
public GIZMO_TYPE GizmoType;
/// <summary>
/// Hover vertices scaling colour
/// </summary>
[SerializeField] public Color HoverVertColour;
/// <summary>
/// Number of points to generate around a rounded portion of a collider like sphere or capsules
/// </summary>
[SerializeField] public int MergeCollidersRoundnessAccuracy = 10;
/// <summary>
/// Method to use when generating mesh colliders
/// </summary>
[SerializeField] public MESH_COLLIDER_METHOD MeshColliderMethod;
/// <summary>
/// Overlapped vertice scaling colour
/// </summary>
[SerializeField] public Color OverlapSelectedVertColour;
/// <summary>
/// Key used to select points (any point on a mesh that isn't a vertex)
/// </summary>
[SerializeField] public KeyCode PointSelectKeyCode;
[SerializeField] public bool PopupDialogOnFinish;
/// <summary>
/// Collider type we want to preview
/// </summary>
[SerializeField] public CREATE_COLLIDER_TYPE PreviewColliderType;
/// <summary>
/// Color of lines to draw previewed colliders with.
/// </summary>
[SerializeField] public Color PreviewDrawColor;
/// <summary>
/// Are previews enabled?
/// </summary>
[SerializeField] public bool PreviewEnabled;
/// <summary>
/// Raycast delay time, ie only check / select at increments of this time.
/// </summary>
[SerializeField] public float RaycastDelayTime;
/// <summary>
/// Render point method
/// </summary>
[SerializeField] public RENDER_POINT_TYPE RenderPointType;
/// <summary>
/// Should colliders that are merged together be removed after merging is completed?
/// </summary>
[SerializeField] public bool RemoveMergedColliders;
/// <summary>
/// If true, puts rotated colliders on the same layer as the selected gameobject.
/// </summary>
[SerializeField] public bool CopyParentObjectLayer;
/// <summary>
/// Should the rotated colliders pivot be created at the center of the points, or at 0?
/// </summary>
[SerializeField] public bool RotatedColliderPivotAtCenter;
/// <summary>
/// Settings of the current rotate and duplicate section in collider creation.
/// </summary>
[SerializeField] public EasyColliderRotateDuplicate rotatedDupeSettings;
/// <summary>
/// When true, meshes created from creating convex hulls are saved as assets.
/// </summary>
[SerializeField] public bool SaveConvexHullAsAsset;
/// <summary>
/// Specifies how to search for a location to save the convex hull .asset files.
/// </summary>
[SerializeField] public CONVEX_HULL_SAVE_METHOD ConvexHullSaveMethod = CONVEX_HULL_SAVE_METHOD.PrefabMesh;
/// <summary>
/// if SaveConvexHullMeshAtSelected is false, saves at the path specified.
/// </summary>
[SerializeField] public string SaveConvexHullPath;
/// <summary>
/// Provides a subfolder to save colliders in an asset path when saving near the mesh
/// IE: if the mesh/prefab is found in an Environments/Meshes folder, an Environments/Meshes/ConvexHulls folder would be created to store the collision meshes
/// if using anything other than CONVEX_HULL_SAVE_METHOD.Folder
/// </summary>
[SerializeField] public string SaveConvexHullSubFolder;
/// <summary>
/// Suffix with which to save convex hulls.
/// </summary>
[SerializeField] public string SaveConvexHullSuffix;
/// <summary>
/// Selected vertice scaling colour
/// </summary>
[SerializeField] public Color SelectedVertColour;
[SerializeField] public KeyCode ShortcutInvert = KeyCode.I;
[SerializeField] public KeyCode ShortcutGrow = KeyCode.G;
[SerializeField] public KeyCode ShortcutGrowLast = KeyCode.L;
[SerializeField] public KeyCode ShortcutClear = KeyCode.C;
[SerializeField] public KeyCode ShortcutRing = KeyCode.R;
/// <summary>
/// Should the number of selected vertices be displayed in the ui?
/// </summary>
[SerializeField] public bool ShowSelectedVertexCount;
/// <summary>
/// Sphere method to use when creating a sphere collider.
/// </summary>
public SPHERE_COLLIDER_METHOD SphereColliderMethod;
/// <summary>
/// Should HandleUtility.GetHandleSize be used when using gizmos to draw to keep gizmo size constant regardless of distance to camera?
/// </summary>
[SerializeField] public bool UseFixedGizmoScale;
/// <summary>
/// Enables using left click to select vertices, and right click to select points.
/// </summary>
[SerializeField] public bool UseMouseClickSelection = true;
[SerializeField] public NORMAL_OFFSET VertexNormalOffsetType = NORMAL_OFFSET.Both;
/// <summary>
/// Amount to offset the vertex (in direction of it's averaged normal)
/// </summary>
[SerializeField] public float VertexNormalOffset = 0f;
/// <summary>
/// Amount to inset the vertex (in opposite direction of it's averaged normal)
/// </summary>
[SerializeField] public float VertexNormalInset = 0f;
/// <summary>
/// Method used when raycasting for closest vertices, add (only snap to unselected verts), remove (only snap to selected verts), both (default)
/// </summary>
[SerializeField] public VERTEX_SNAP_METHOD VertexSnapMethod;
/// <summary>
/// Key used to select vertices.
/// </summary>
[SerializeField] public KeyCode VertSelectKeyCode;
/// <summary>
/// Should we update the VHACD calculation and preview as parameters change?
/// </summary>
[SerializeField] public bool VHACDPreview;
/// <summary>
/// For editor window tab tracking, maintains previously open tab.
/// </summary>
[SerializeField] public ECE_WINDOW_TAB CurrentWindowTab;
/// <summary>
/// Sets all values to default values.
/// </summary>
public void SetDefaultValues()
{
#region VHACD settings
#if (!UNITY_EDITOR_LINUX)
VHACDParameters = new VHACDParameters();
VHACDPreview = true;
#endif
#endregion
#region other settings
AutoIncludeChildSkinnedMeshes = true;
AutoSelectOnPrefabOpen = false;
DisplayTips = true;
DisplayAllVertices = false;
PopupDialogOnFinish = false;
PreviewEnabled = true;
RaycastDelayTime = 0.1f;
ShowSelectedVertexCount = false;
rotatedDupeSettings = new EasyColliderRotateDuplicate();
RotatedColliderPivotAtCenter = false;
CylinderAsCapsuleOrientation = false;
#endregion
#region autoskinned preferences
AutoSkinnedMinBoneWeight = 0.5f;
AutoSkinnedDepenetrate = false;
AutoSkinnedIterativeDepenetrationCount = 15;
AutoSkinnedPairing = true;
AutoSkinnedIndents = true;
AutoSkinnedColliderType = SKINNED_MESH_COLLIDER_TYPE.Box;
AutoSkinnedShrinkAmount = 0.5f;
// I find outside in to give the best results generally.
AutoSkinnedDepenetrateOrder = SKINNED_MESH_DEPENETRATE_ORDER.OutsideIn;
AutoSkinnedForce256Triangles = true;
AutoSkinnedUseDistanceDeltaPairing = true;
AutoSkinnedPairedDistanceDelta = 0.01f;
#endregion
#region inputs
// shifts do not work.
BoxSelectMinusKey = KeyCode.S;
BoxSelectPlusKey = KeyCode.A;
CreateFromPreviewKey = KeyCode.BackQuote;
PointSelectKeyCode = KeyCode.B;
UseMouseClickSelection = true;
VertSelectKeyCode = KeyCode.V;
EnableVertexToolsShortcuts = true;
ShortcutInvert = KeyCode.I;
ShortcutGrow = KeyCode.G;
ShortcutGrowLast = KeyCode.L;
ShortcutClear = KeyCode.C;
ShortcutRing = KeyCode.R;
#endregion
#region Collider Methods
CapsuleColliderMethod = CAPSULE_COLLIDER_METHOD.MinMax;
MeshColliderMethod = MESH_COLLIDER_METHOD.QuickHull;
PreviewColliderType = CREATE_COLLIDER_TYPE.BOX;
SphereColliderMethod = SPHERE_COLLIDER_METHOD.MinMax;
#endregion
#region Collider Settings / Paramaters
MergeCollidersRoundnessAccuracy = 10;
VertexNormalOffset = 0f;
VertexNormalInset = 0f;
VertexNormalOffsetType = NORMAL_OFFSET.Both;
ColliderHolder = COLLIDER_HOLDER.Default;
CylinderNumberOfSides = 16;
CylinderOrientation = CYLINDER_ORIENTATION.Automatic;
CylinderRotationOffset = 0.0f;
MeshColliderMethod = MESH_COLLIDER_METHOD.QuickHull;
RemoveMergedColliders = true;
CopyParentObjectLayer = true;
#endregion
#region drawing
CommonScalingMultiplier = 1.0f;
DefaultScale = 0.01f;
HoveredScaleMult = 1.0f;
DisplayAllScaleMult = 1.0f;
OverlapScaleMult = 1.0f;
SelectedScaleMult = 1.0f;
DisplayVerticesColour = Color.blue;
GizmoType = GIZMO_TYPE.SPHERE;
HoverVertColour = Color.cyan;
OverlapSelectedVertColour = Color.red;
PreviewDrawColor = Color.cyan;
if (SystemInfo.graphicsShaderLevel < 45)
{
RenderPointType = RENDER_POINT_TYPE.GIZMOS;
}
else
{
RenderPointType = RENDER_POINT_TYPE.SHADER;
}
SelectedVertColour = Color.green;
UseFixedGizmoScale = true;
#endregion
#region Save Convex Hull Settings
ConvexHullSaveMethod = CONVEX_HULL_SAVE_METHOD.PrefabMesh;
ResetDefaultSavePath();
SaveConvexHullAsAsset = true;
SaveConvexHullSuffix = "_ConvexHull_";
ConvexMeshReadWriteEnabled = true;
SaveConvexHullSubFolder = "";
#endregion
}
private static EasyColliderPreferences _Prefereneces;
public static EasyColliderPreferences Preferences
{
get
{
if (_Prefereneces == null)
{
// lazy load preferences when needed.
_Prefereneces = FindOrCreatePreferences();
}
return _Prefereneces;
}
}
private static EasyColliderPreferences FindOrCreatePreferences()
{
EasyColliderPreferences preferences;
string[] ecp = AssetDatabase.FindAssets("EasyColliderPreferences t:ScriptableObject");
string assetPath = "";
if (ecp.Length > 0)
{
assetPath = AssetDatabase.GUIDToAssetPath(ecp[0]);
if (ecp.Length > 1)
{
Debug.LogWarning("Easy Collider Editor has found multiple preferences files. Using the one located at " + assetPath);
}
preferences = AssetDatabase.LoadAssetAtPath(assetPath, typeof(EasyColliderPreferences)) as EasyColliderPreferences;
}
else
{
ecp = AssetDatabase.FindAssets("EasyColliderWindow t:script");
if (ecp.Length > 0)
{
assetPath = AssetDatabase.GUIDToAssetPath(ecp[0]);
if (ecp.Length > 1)
{
Debug.LogWarning("Easy Collider Editor has found multiple preferences files. Using the one located at " + assetPath);
}
}
// preferences = AssetDatabase.LoadAssetAtPath(assetPath, typeof(EasyColliderPreferences)) as EasyColliderPreferences;
// Create a new preferences file.
string prefPath = assetPath.Remove(assetPath.Length - 21) + "EasyColliderPreferences.asset";
preferences = CreateInstance<EasyColliderPreferences>();
preferences.SetDefaultValues();
AssetDatabase.CreateAsset(preferences, prefPath);
AssetDatabase.SaveAssets();
Debug.LogWarning("Easy Collider Editor did not find a preferences file, new preferences file created at " + prefPath);
}
return preferences;
}
static string defaultFolderName = "Convex Hulls";
/// <summary>
/// Resets the default save path to the location of the preferences scriptable object.
/// </summary>
public bool ResetDefaultSavePath()
{
// path to this preferences object.
SaveConvexHullPath = AssetDatabase.GetAssetPath(MonoScript.FromScriptableObject(this));
SaveConvexHullPath = SaveConvexHullPath.Remove(SaveConvexHullPath.LastIndexOf("/")) + "/";
string rootPath = SaveConvexHullPath.Remove(SaveConvexHullPath.LastIndexOf("/Scripts/"), 9);
// if the preferences is in soemthing other than Assets (like packages, create a new folder at the root to hold convex hulls)
if (!SaveConvexHullPath.StartsWith("Assets"))
{
if (!AssetDatabase.IsValidFolder("Assets/Convex Hulls"))
{
AssetDatabase.CreateFolder("Assets", "Convex Hulls");
AssetDatabase.Refresh();
Debug.LogWarning("A folder has been created at: Assets/Convex Hulls to save convex mesh collider assets because Easy Collider exists in the packages folder. Folder to save assets in can be changed in Easy Collider Editor's preferences foldout.");
}
SaveConvexHullPath = "Assets/Convex Hulls/";
return true;
}
// remove invalid characters.
SaveConvexHullPath = string.Join("", SaveConvexHullPath.Split(Path.GetInvalidPathChars()));
// try creating and saving a Convex Hull specific folder if it doesn't exist.
if (!AssetDatabase.IsValidFolder(rootPath + "/" + defaultFolderName))
{
AssetDatabase.CreateFolder(rootPath, defaultFolderName);
AssetDatabase.Refresh();
if (AssetDatabase.IsValidFolder(rootPath + "/" + defaultFolderName))
{
SaveConvexHullPath = rootPath + "/" + defaultFolderName + "/";
return true;
}
}
else
{
SaveConvexHullPath = rootPath + "/" + defaultFolderName + "/";
}
return false;
}
public int GetCreationValuesHashCode()
{
return 0;
}
}
}
#endif