Skip to content

Commit 7120b14

Browse files
committed
Dragging in an interactive GLTF asset at runtime now works and immediately starts playback. Colliders now get added to any GLTF node object in Unity that if hover/select events are present and the object does not have a collider (if selectable/hoverable extension is present it only adds the collider if it is marked as hoverable/selectable).
1 parent bde865e commit 7120b14

File tree

1 file changed

+87
-23
lines changed

1 file changed

+87
-23
lines changed

Runtime/Scripts/Interactivity/Playback/Context/Import/InteractivityImportContext.cs

Lines changed: 87 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using GLTF.Schema;
22
using System;
3+
using System.Collections.Generic;
34
using UnityEngine;
45
using UnityGLTF.Plugins;
56

@@ -10,6 +11,8 @@ public class InteractivityImportContext : GLTFImportPluginContext
1011
internal readonly InteractivityImportPlugin settings;
1112
private PointerResolver _pointerResolver;
1213
private GLTFImportContext _context;
14+
private InteractivityGraphExtension _interactivityGraph;
15+
private bool _hasSelectOrHoverNode;
1316

1417
public InteractivityImportContext(InteractivityImportPlugin interactivityLoader, GLTFImportContext context)
1518
{
@@ -36,6 +39,49 @@ public override void OnBeforeImportRoot()
3639
/// </summary>
3740
public override void OnAfterImportRoot(GLTFRoot gltfRoot)
3841
{
42+
var extensions = _context.SceneImporter.Root?.Extensions;
43+
44+
if (extensions == null)
45+
{
46+
Util.Log("Extensions are null.");
47+
return;
48+
}
49+
50+
if (!extensions.TryGetValue(InteractivityGraphExtension.EXTENSION_NAME, out IExtension extensionValue))
51+
{
52+
Util.Log("Extensions does not contain interactivity.");
53+
return;
54+
}
55+
56+
if (extensionValue is not InteractivityGraphExtension interactivityGraph)
57+
{
58+
Util.Log("Extensions does not contain a graph.");
59+
return;
60+
}
61+
62+
Util.Log("Extensions contains interactivity.");
63+
64+
_interactivityGraph = interactivityGraph;
65+
66+
var graph = interactivityGraph.extensionData.graphs[interactivityGraph.extensionData.defaultGraphIndex];
67+
68+
for (int i = 0; i < graph.declarations.Count; i++)
69+
{
70+
switch(graph.declarations[i].op)
71+
{
72+
case "event/onSelect":
73+
case "event/onHoverIn":
74+
case "event/onHoverOut":
75+
_hasSelectOrHoverNode = true;
76+
break;
77+
}
78+
}
79+
80+
if(!_hasSelectOrHoverNode)
81+
return;
82+
83+
Util.Log("Select or hover node present.");
84+
3985
Util.Log($"InteractivityImportContext::OnAfterImportRoot Complete: {gltfRoot.ToString()}");
4086
}
4187

@@ -46,10 +92,45 @@ public override void OnBeforeImportScene(GLTFScene scene)
4692

4793
public override void OnAfterImportNode(GLTF.Schema.Node node, int nodeIndex, GameObject nodeObject)
4894
{
95+
AddColliderIfNecessary(node, nodeIndex, nodeObject);
96+
4997
Util.Log($"InteractivityImportContext::OnAfterImportNode Complete: {node.ToString()}");
5098
_pointerResolver.RegisterNode(node, nodeIndex, nodeObject);
5199
}
52100

101+
private void AddColliderIfNecessary(GLTF.Schema.Node node, int nodeIndex, GameObject nodeObject)
102+
{
103+
if (!_hasSelectOrHoverNode || nodeObject.TryGetComponent(out Collider collider))
104+
return;
105+
106+
Mesh mesh = null;
107+
108+
if (nodeObject.TryGetComponent(out MeshFilter mf))
109+
mesh = mf.sharedMesh;
110+
else if (nodeObject.TryGetComponent(out SkinnedMeshRenderer smr))
111+
mesh = smr.sharedMesh;
112+
113+
if (mesh == null)
114+
return;
115+
116+
var selectable = true;
117+
var hoverable = true;
118+
119+
if (node.Extensions != null)
120+
{
121+
if (node.Extensions.TryGetValue(GLTF.Schema.KHR_node_selectability_Factory.EXTENSION_NAME, out var selectableExtension))
122+
selectable = (selectableExtension as GLTF.Schema.KHR_node_selectability).selectable;
123+
124+
if (node.Extensions.TryGetValue(GLTF.Schema.KHR_node_hoverability_Factory.EXTENSION_NAME, out var hoverableExtension))
125+
hoverable = (hoverableExtension as GLTF.Schema.KHR_node_hoverability).hoverable;
126+
}
127+
128+
if (!selectable && !hoverable)
129+
return;
130+
131+
nodeObject.AddComponent<BoxCollider>();
132+
}
133+
53134
public override void OnAfterImportMesh(GLTFMesh mesh, int meshIndex, Mesh meshObject)
54135
{
55136
Util.Log($"InteractivityImportContext::OnAfterImportMesh Complete: {mesh.ToString()}");
@@ -77,35 +158,18 @@ public override void OnAfterImportScene(GLTFScene scene, int sceneIndex, GameObj
77158
{
78159
Util.Log($"InteractivityImportContext::OnAfterImportScene Complete: {scene.Extensions}");
79160

80-
var extensions = _context.SceneImporter.Root?.Extensions;
81-
82-
if (extensions == null)
83-
{
84-
Util.Log("Extensions are null.");
85-
return;
86-
}
87-
88-
if (!extensions.TryGetValue(InteractivityGraphExtension.EXTENSION_NAME, out IExtension extensionValue))
89-
{
90-
Util.Log("Extensions does not contain interactivity.");
91-
return;
92-
}
93-
94-
if (extensionValue is not InteractivityGraphExtension interactivityGraph)
95-
{
96-
Util.Log("Extensions does not contain a graph.");
161+
if (_interactivityGraph == null)
97162
return;
98-
}
99163

100164
try
101165
{
102166
_pointerResolver.RegisterSceneData(_context.SceneImporter.Root);
103167
_pointerResolver.CreatePointers();
104168

105-
var defaultGraphIndex = interactivityGraph.extensionData.defaultGraphIndex;
169+
var defaultGraphIndex = _interactivityGraph.extensionData.defaultGraphIndex;
106170
// Can be used to inject a graph created from code in a hacky way for testing.
107171
//interactivityGraph.extensionData.graphs[defaultGraphIndex] = TestGraph.CreateTestGraph();
108-
var defaultGraph = interactivityGraph.extensionData.graphs[defaultGraphIndex];
172+
var defaultGraph = _interactivityGraph.extensionData.graphs[defaultGraphIndex];
109173
var eng = new BehaviourEngine(defaultGraph, _pointerResolver);
110174

111175
GLTFInteractivityAnimationWrapper animationWrapper = null;
@@ -118,7 +182,7 @@ public override void OnAfterImportScene(GLTFScene scene, int sceneIndex, GameObj
118182

119183
var playback = sceneObject.AddComponent<GLTFInteractivityPlayback>();
120184

121-
playback.SetData(eng, interactivityGraph.extensionData);
185+
playback.SetData(eng, _interactivityGraph.extensionData);
122186

123187
var colliders = sceneObject.GetComponentsInChildren<Collider>(true);
124188

@@ -128,10 +192,10 @@ public override void OnAfterImportScene(GLTFScene scene, int sceneIndex, GameObj
128192
wrapper.playback = playback;
129193
}
130194

131-
if (!Application.isPlaying)
195+
if (_context.AssetContext != null)
132196
{
133197
var data = sceneObject.AddComponent<GLTFInteractivityData>();
134-
data.interactivityJson = interactivityGraph.json;
198+
data.interactivityJson = _interactivityGraph.json;
135199
data.animationWrapper = animationWrapper;
136200
data.pointerReferences = _pointerResolver;
137201
}

0 commit comments

Comments
 (0)