Skip to content

Commit 97b28e4

Browse files
author
Unity Technologies
committed
com.unity.splines@2.5.1
## [2.5.1] - 2023-10-17 ### Bug Fixes - [SPLB-208] Fixed a bug where `SplineToolContext` would attempt to draw empty Splines and flood the console with errors. ## [2.5.0] - 2023-10-16 ### Added - Exposed public API for `SplineInstantiate.Seed`. ### Bug Fixes - [SPLB-201] Fixed error messages showing in edit mode with spline components. - [SPLB-203] Fixed a bug where baking `SplineInstantiate` instances broke prefab connections. - [SPLB-196] Fixed a bug where the `Random` state was not restored after an update of the instances in `SplineInstantiate`. - Fixed a bug where the `SplineCacheUtility` would send null reference exceptions. - [SPLB-183] Fixed a bug where duplicating the `SplineExtrude` component was not updating the mesh asset reference. - [SPLB-178] Fixed a bug where linking knots would not trigger a `Spline.changed` event. - [SPLB-185] Fixed a bug where the Up vector evaluation would return NaN values when normals and curve tangents are parallel. ### Changed - [SPLB-187] Fixed a bug where `Spline.EvaluatePosition` was allocating memory when called. - [SPLB-181] Fixed a bug where the Auto tangent mode computed incorrect knot rotations. - Changed the `SplineComponent` display name in the Inspector to `Spline Container` as a response to user feedback.
1 parent fea9edb commit 97b28e4

22 files changed

+265
-114
lines changed

.buginfo

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
system: jira
22
server: jira.unity3d.com
33
project: SPLB
4-
issuetype: Bug
4+
issuetype: Bug
5+
package: Splines

CHANGELOG.md

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,33 @@ All notable changes to this package will be documented in this file.
55
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
66
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
77

8-
## [Unreleased]
8+
## [2.5.1] - 2023-10-17
99

10+
### Bug Fixes
11+
12+
- [SPLB-208] Fixed a bug where `SplineToolContext` would attempt to draw empty Splines and flood the console with errors.
13+
14+
## [2.5.0] - 2023-10-16
15+
16+
### Added
17+
18+
- Exposed public API for `SplineInstantiate.Seed`.
19+
20+
### Bug Fixes
21+
22+
- [SPLB-201] Fixed error messages showing in edit mode with spline components.
23+
- [SPLB-203] Fixed a bug where baking `SplineInstantiate` instances broke prefab connections.
24+
- [SPLB-196] Fixed a bug where the `Random` state was not restored after an update of the instances in `SplineInstantiate`.
25+
- Fixed a bug where the `SplineCacheUtility` would send null reference exceptions.
26+
- [SPLB-183] Fixed a bug where duplicating the `SplineExtrude` component was not updating the mesh asset reference.
27+
- [SPLB-178] Fixed a bug where linking knots would not trigger a `Spline.changed` event.
28+
- [SPLB-185] Fixed a bug where the Up vector evaluation would return NaN values when normals and curve tangents are parallel.
29+
30+
### Changed
31+
32+
- [SPLB-187] Fixed a bug where `Spline.EvaluatePosition` was allocating memory when called.
33+
- [SPLB-181] Fixed a bug where the Auto tangent mode computed incorrect knot rotations.
34+
- Changed the `SplineComponent` display name in the Inspector to `Spline Container` as a response to user feedback.
1035

1136
## [2.4.0] - 2023-07-26
1237

Editor/Components/SplineAnimateEditor.cs

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using System;
2-
using System.Collections.Generic;
32
using System.Linq;
43
using UnityEngine.Splines;
54
using UnityEditor.UIElements;
@@ -19,10 +18,7 @@ class SplineAnimateEditor : UnityEditor.Editor
1918
EnumField m_ObjectForwardField;
2019
EnumField m_ObjectUpField;
2120

22-
SerializedProperty m_TargetProperty;
2321
SerializedProperty m_MethodProperty;
24-
SerializedProperty m_DurationProperty;
25-
SerializedProperty m_SpeedProperty;
2622
SerializedProperty m_ObjectForwardProperty;
2723
SerializedProperty m_ObjectUpProperty;
2824
SerializedProperty m_StartOffsetProperty;
@@ -45,10 +41,7 @@ void OnEnable()
4541
m_SplineAnimate.Updated += OnSplineAnimateUpdated;
4642

4743
try {
48-
m_TargetProperty = serializedObject.FindProperty("m_Target");
4944
m_MethodProperty = serializedObject.FindProperty("m_Method");
50-
m_DurationProperty = serializedObject.FindProperty("m_Duration");
51-
m_SpeedProperty = serializedObject.FindProperty("m_MaxSpeed");
5245
m_ObjectForwardProperty = serializedObject.FindProperty("m_ObjectForwardAxis");
5346
m_ObjectUpProperty = serializedObject.FindProperty("m_ObjectUpAxis");
5447
m_StartOffsetProperty = serializedObject.FindProperty("m_StartOffset");
@@ -146,7 +139,7 @@ public override VisualElement CreateInspectorGUI()
146139
s_ThemeStyleSheet = AssetDatabase.LoadAssetAtPath<StyleSheet>($"Packages/com.unity.splines/Editor/Stylesheets/SplineAnimateInspector{(EditorGUIUtility.isProSkin ? "Dark" : "Light")}.uss");
147140

148141
m_Root.styleSheets.Add(s_ThemeStyleSheet);
149-
142+
150143
var methodField = m_Root.Q<PropertyField>("method");
151144
methodField.RegisterValueChangeCallback((_) => { RefreshMethodParamFields((SplineAnimate.Method)m_MethodProperty.enumValueIndex); });
152145
RefreshMethodParamFields((SplineAnimate.Method)m_MethodProperty.enumValueIndex);

Editor/Controls/SplineHandles.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,9 @@ public static void DoHandles(IReadOnlyList<SplineInfo> splines)
9696
// Drawing done in two separate passes to make sure the curves are drawn behind the spline elements.
9797
// Draw the curves.
9898
for (int i = 0; i < splines.Count; ++i)
99+
{
99100
DoSegmentsHandles(splines[i]);
101+
}
100102

101103
DoKnotsAndTangentsHandles(splines);
102104
}
@@ -147,6 +149,9 @@ public static void DoKnotsAndTangentsHandles(IReadOnlyList<SplineInfo> splines)
147149
public static void DoSegmentsHandles(SplineInfo splineInfo)
148150
{
149151
var spline = splineInfo.Spline;
152+
if (spline == null || spline.Count < 2)
153+
return;
154+
150155
var localToWorld = splineInfo.LocalToWorld;
151156

152157
// If the spline isn't closed, skip the last index of the spline

Editor/GUI/Editors/SplineComponentEditor.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
class SplineComponentEditor : Editor
66
{
77
static GUIStyle s_FoldoutStyle;
8+
9+
internal static readonly string k_Helpbox = L10n.Tr("Instantiated Objects need a SplineContainer target to be created.");
810

911
protected bool Foldout(bool foldout, GUIContent content)
1012
{

Editor/GUI/Editors/SplineExtrudeEditor.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,9 @@ public override void OnInspectorGUI()
100100
EditorGUI.BeginChangeCheck();
101101

102102
EditorGUILayout.PropertyField(m_Container, new GUIContent(k_Spline, m_Container.tooltip));
103+
if(m_Container.objectReferenceValue == null)
104+
EditorGUILayout.HelpBox(k_Helpbox, MessageType.Warning);
105+
103106
EditorGUILayout.LabelField(k_Geometry, EditorStyles.boldLabel);
104107

105108
if(m_AnyMissingMesh)

Editor/GUI/Editors/SplineInstantiateEditor.cs

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ enum SpawnType
107107
SerializedProperty m_ItemsToInstantiate;
108108
SerializedProperty m_InstantiateMethod;
109109

110+
SerializedProperty m_Seed;
110111
SerializedProperty m_Space;
111112
SerializedProperty m_UpAxis;
112113
SerializedProperty m_ForwardAxis;
@@ -123,8 +124,6 @@ enum SpawnType
123124
L10n.Tr("Spacing (Linear)")
124125
};
125126

126-
static readonly string k_Helpbox = L10n.Tr("Instantiated Objects need a SplineContainer target to be created.");
127-
128127
//Setup Section
129128
static readonly string k_Setup = L10n.Tr("Instantiated Object Setup");
130129
static readonly string k_ObjectUp = L10n.Tr("Up Axis");
@@ -143,7 +142,6 @@ enum SpawnType
143142
SpawnType m_SpacingType;
144143

145144
//Offsets
146-
static readonly string k_Offset = L10n.Tr("Offsets");
147145
static readonly string k_PositionOffset = L10n.Tr("Position Offset");
148146
static readonly string k_PositionOffsetTooltip = L10n.Tr("Whether or not to use a position offset.");
149147
static readonly string k_RotationOffset = L10n.Tr("Rotation Offset");
@@ -156,6 +154,9 @@ enum SpawnType
156154
static readonly string k_AutoRefresh = L10n.Tr("Auto Refresh Generation");
157155
static readonly string k_AutoRefreshTooltip = L10n.Tr("Automatically refresh the instances when the spline or the values are changed.");
158156

157+
static readonly string k_Seed = L10n.Tr("Randomization Seed");
158+
static readonly string k_SeedTooltip = L10n.Tr("Value used to initialize the pseudorandom number generator of the instances.");
159+
159160
static readonly string k_Randomize = L10n.Tr("Randomize");
160161
static readonly string k_RandomizeTooltip = L10n.Tr("Compute a new randomization of the instances along the spline.");
161162
static readonly string k_Regenerate = L10n.Tr("Regenerate");
@@ -204,6 +205,7 @@ bool Initialize()
204205
m_PositionOffset = serializedObject.FindProperty("m_PositionOffset");
205206
m_RotationOffset = serializedObject.FindProperty("m_RotationOffset");
206207
m_ScaleOffset = serializedObject.FindProperty("m_ScaleOffset");
208+
m_Seed = serializedObject.FindProperty("m_Seed");
207209

208210
m_AutoRefresh = serializedObject.FindProperty("m_AutoRefresh");
209211

@@ -276,13 +278,18 @@ public override void OnInspectorGUI()
276278
EditorGUI.BeginChangeCheck();
277279
EditorGUILayout.PropertyField(m_ItemsToInstantiate);
278280
dirtyInstances = EditorGUI.EndChangeCheck();
279-
281+
280282
DoSetupSection();
281283
dirtyInstances |= DoInstantiateSection();
282284
updateInstances |= DisplayOffsets();
283285

284286
EditorGUILayout.LabelField(k_Generation, EditorStyles.boldLabel);
285287
EditorGUI.indentLevel++;
288+
EditorGUI.BeginChangeCheck();
289+
EditorGUILayout.PropertyField(m_Seed, new GUIContent(k_Seed, k_SeedTooltip));
290+
var newSeed = EditorGUI.EndChangeCheck();
291+
dirtyInstances |= newSeed;
292+
updateInstances |= newSeed;
286293
EditorGUILayout.PropertyField(m_AutoRefresh, new GUIContent(k_AutoRefresh, k_AutoRefreshTooltip));
287294
EditorGUI.indentLevel--;
288295
serializedObject.ApplyModifiedProperties();
@@ -291,7 +298,7 @@ public override void OnInspectorGUI()
291298
EditorGUILayout.BeginHorizontal();
292299
EditorGUILayout.Space();
293300
if (GUILayout.Button(new GUIContent(k_Randomize, k_RandomizeTooltip), GUILayout.MaxWidth(100f)))
294-
{
301+
{
295302
Undo.RecordObjects(targets, "Changing SplineInstantiate seed");
296303
splineInstantiate.Randomize();
297304
updateInstances = true;
@@ -318,16 +325,13 @@ public override void OnInspectorGUI()
318325
EditorGUILayout.Separator();
319326

320327
if (dirtyInstances)
321-
{
322328
splineInstantiate.SetDirty();
323-
SceneView.RepaintAll();
324-
}
325329

326330
if (updateInstances)
327-
{
328331
splineInstantiate.UpdateInstances();
332+
333+
if (dirtyInstances || updateInstances)
329334
SceneView.RepaintAll();
330-
}
331335
}
332336

333337
void DoSetupSection()
@@ -599,19 +603,20 @@ void BakeInstances(SplineInstantiate splineInstantiate)
599603
splineInstantiate.UpdateInstances();
600604
for (int i = 0; i < splineInstantiate.instances.Count; ++i)
601605
{
602-
var newInstance = Instantiate(splineInstantiate.instances[i], splineInstantiate.transform, true);
606+
var newInstance = splineInstantiate.instances[i];
603607
newInstance.name = "Instance-" + i;
604608
newInstance.hideFlags = HideFlags.None;
609+
newInstance.transform.SetParent(((SplineInstantiate)target).gameObject.transform, true);
605610

606611
Undo.RegisterCreatedObjectUndo(newInstance, "Baking instance");
607612
}
608613

614+
splineInstantiate.instances.Clear();
609615
if(splineInstantiate.InstancesRoot != null)
610616
Undo.DestroyObjectImmediate(splineInstantiate.InstancesRoot);
611617

612618
Undo.DestroyObjectImmediate(splineInstantiate);
613619

614-
splineInstantiate.instances.Clear();
615620
Undo.CollapseUndoOperations(group);
616621
}
617622
}

Editor/Tools/SplineToolContext.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,10 @@ void DeleteSelected()
275275
}
276276
}
277277

278-
void FrameSelected()
278+
/// <summary>
279+
/// This methods automatically frames the selected splines or spline elements in the scene view.
280+
/// </summary>
281+
public void FrameSelected()
279282
{
280283
Bounds selectionBounds;
281284
if (TransformOperation.canManipulate)

Editor/Utilities/SplineCacheUtility.cs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,7 @@ static void ClearCache(Spline spline, int knotIndex, SplineModification modifica
7575
if (knotIndex == -1 || modificationType != SplineModification.KnotModified)
7676
{
7777
s_CurvesBuffers?.Clear();
78-
79-
if(s_SplineCacheTable.ContainsKey(spline))
80-
s_SplineCacheTable[spline] = null;
78+
s_SplineCacheTable.Remove(spline);
8179
}
8280
else // If Knot modified by the tools
8381
{
@@ -109,7 +107,7 @@ static void UpdateCachePosition(Spline spline, int curveIndex)
109107
s_CurvesBuffers.Remove(curve);
110108
}
111109

112-
if (s_SplineCacheTable == null || !s_SplineCacheTable.ContainsKey(spline))
110+
if (s_SplineCacheTable == null || !s_SplineCacheTable.ContainsKey(spline) || s_SplineCacheTable[spline] == null)
113111
return;
114112

115113
// Update position cache
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
using UnityEngine;
2+
using UnityEngine.Splines;
3+
4+
namespace UnityEditor.Splines
5+
{
6+
[InitializeOnLoad]
7+
public static class SplineExtrudeUtility
8+
{
9+
static SplineExtrudeUtility()
10+
{
11+
#if UNITY_2022_2_OR_NEWER
12+
ClipboardUtility.duplicatedGameObjects += OnPasteOrDuplicated;
13+
ClipboardUtility.pastedGameObjects += OnPasteOrDuplicated;
14+
#else
15+
ObjectChangeEvents.changesPublished += ObjectEventChangesPublished;
16+
#endif
17+
}
18+
19+
#if UNITY_2022_2_OR_NEWER
20+
static void OnPasteOrDuplicated(GameObject[] duplicates)
21+
{
22+
foreach (var duplicate in duplicates)
23+
CheckForExtrudeMeshCreatedOrModified(duplicate);
24+
}
25+
#else
26+
static void ObjectEventChangesPublished(ref ObjectChangeEventStream stream)
27+
{
28+
for (int i = 0, c = stream.length; i < c; ++i)
29+
{
30+
// SplineExtrude was created via duplicate, copy paste
31+
if (stream.GetEventType(i) == ObjectChangeKind.CreateGameObjectHierarchy)
32+
{
33+
stream.GetCreateGameObjectHierarchyEvent(i, out CreateGameObjectHierarchyEventArgs data);
34+
GameObjectCreatedOrStructureModified(data.instanceId);
35+
}
36+
}
37+
}
38+
39+
static void GameObjectCreatedOrStructureModified(int instanceId)
40+
{
41+
if (EditorUtility.InstanceIDToObject(instanceId) is GameObject go)
42+
CheckForExtrudeMeshCreatedOrModified(go);
43+
}
44+
#endif
45+
46+
static void CheckForExtrudeMeshCreatedOrModified(GameObject go)
47+
{
48+
//Check if the current GameObject has a SplineExtrude component
49+
if(go.TryGetComponent<SplineExtrude>(out var extrudeComponent))
50+
extrudeComponent.Reset();
51+
52+
var childCount = go.transform.childCount;
53+
if (childCount > 0)
54+
{
55+
//Check through the children
56+
for(int childIndex = 0; childIndex < childCount; ++childIndex)
57+
CheckForExtrudeMeshCreatedOrModified(go.transform.GetChild(childIndex).gameObject);
58+
}
59+
}
60+
}
61+
}

0 commit comments

Comments
 (0)