using UnityEngine;
using UnityEngine.Splines;
namespace UnityEditor.Splines
{
///
/// A utility class providing methods to handle and manage spline extrusion operations.
/// Initializes event listeners on load to monitor and respond to object changes, duplication, and paste operations specific to splines.
///
[InitializeOnLoad]
public static class SplineExtrudeUtility
{
static SplineExtrudeUtility()
{
#if UNITY_2022_2_OR_NEWER
ClipboardUtility.duplicatedGameObjects += OnPasteOrDuplicated;
ClipboardUtility.pastedGameObjects += OnPasteOrDuplicated;
ObjectChangeEvents.changesPublished += ObjectEventChangesPublished;
#else
ObjectChangeEvents.changesPublished += ObjectEventChangesPublished;
#endif
}
#if UNITY_2022_2_OR_NEWER
static void OnPasteOrDuplicated(GameObject[] duplicates)
{
foreach (var duplicate in duplicates)
CheckForExtrudeMeshCreatedOrModified(duplicate);
}
static void ObjectEventChangesPublished(ref ObjectChangeEventStream stream)
{
for (int i = 0; i < stream.length; ++i)
{
var type = stream.GetEventType(i);
if (type == ObjectChangeKind.ChangeGameObjectStructure)
{
stream.GetChangeGameObjectStructureEvent(i, out var changeGameObjectStructure);
if (EditorUtility.InstanceIDToObject(changeGameObjectStructure.instanceId) is GameObject go)
CheckForSplineExtrudeAdded(go);
}
}
}
#else
static void ObjectEventChangesPublished(ref ObjectChangeEventStream stream)
{
for (int i = 0, c = stream.length; i < c; ++i)
{
// SplineExtrude was created via duplicate, copy paste
var type = stream.GetEventType(i);
if (type == ObjectChangeKind.CreateGameObjectHierarchy)
{
stream.GetCreateGameObjectHierarchyEvent(i, out CreateGameObjectHierarchyEventArgs data);
GameObjectCreatedOrStructureModified(data.instanceId);
}
else if (type == ObjectChangeKind.ChangeGameObjectStructure)
{
stream.GetChangeGameObjectStructureEvent(i, out var changeGameObjectStructure);
if (EditorUtility.InstanceIDToObject(changeGameObjectStructure.instanceId) is GameObject go)
CheckForSplineExtrudeAdded(go);
}
}
}
static void GameObjectCreatedOrStructureModified(int instanceId)
{
if (EditorUtility.InstanceIDToObject(instanceId) is GameObject go)
CheckForExtrudeMeshCreatedOrModified(go);
}
#endif
static void CheckForSplineExtrudeAdded(GameObject go)
{
if (go.TryGetComponent(out var splineExtrude))
splineExtrude.SetSplineContainerOnGO();
var childCount = go.transform.childCount;
if (childCount > 0)
{
for (int childIndex = 0; childIndex < childCount; ++childIndex)
CheckForSplineExtrudeAdded(go.transform.GetChild(childIndex).gameObject);
}
}
static void CheckForExtrudeMeshCreatedOrModified(GameObject go)
{
//Check if the current GameObject has a SplineExtrude component
if(go.TryGetComponent(out var extrudeComponent))
extrudeComponent.Reset();
var childCount = go.transform.childCount;
if (childCount > 0)
{
//Check through the children
for(int childIndex = 0; childIndex < childCount; ++childIndex)
CheckForExtrudeMeshCreatedOrModified(go.transform.GetChild(childIndex).gameObject);
}
}
}
}