Skip to content

Commit 8c3c786

Browse files
committed
Add dynamically usable event listeners
This is quite powerful, since it makes it very easy to listen to js events without writing a lot of code
1 parent 0d9b8c5 commit 8c3c786

12 files changed

+311
-5
lines changed

Assets/Plugins/WebGL/WebBridge/CommonCommands.cs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
using System;
1212
using System.Collections;
1313
using System.Collections.Generic;
14+
using System.Linq;
15+
using System.Text;
1416
using Supyrb.Attributes;
1517
using UnityEngine;
1618
using UnityEngine.Rendering;
@@ -161,6 +163,47 @@ public void SetTimeTimeScale(float timeScale)
161163
Debug.Log($"Time.timeScale: {Time.timeScale}");
162164
}
163165

166+
/// <summary>
167+
/// Finds GameObject(s) by name and logs the found GameObject(s) and their components
168+
/// </summary>
169+
/// <param name="name">The name of the GameObject to find</param>
170+
[WebCommand(Description = "Find GameObject by name and log its components")]
171+
[ContextMenu(nameof(FindGameObjectByName))]
172+
public void FindGameObjectByName(string name)
173+
{
174+
var gameObjects = GameObject.FindObjectsOfType<GameObject>().Where(go => go.name == name).ToArray();
175+
if (gameObjects.Length == 0)
176+
{
177+
Debug.Log($"No GameObject found with the name: {name}");
178+
}
179+
else
180+
{
181+
StringBuilder sb = new StringBuilder();
182+
foreach (var go in gameObjects)
183+
{
184+
int pathStartIndex = 0;
185+
var currentTransform = go.transform;
186+
sb.Insert(pathStartIndex, currentTransform.name);
187+
currentTransform = currentTransform.parent;
188+
while (currentTransform != null)
189+
{
190+
sb.Insert(pathStartIndex, currentTransform.name + "/");
191+
currentTransform = currentTransform.parent;
192+
}
193+
194+
sb.AppendLine($", Tag: {go.tag}, Layer: {go.layer}, ActiveSelf: {go.activeSelf}, ActiveInHierarchy: {go.activeInHierarchy}");
195+
sb.AppendLine("Attached Components:");
196+
var components = go.GetComponents<Component>();
197+
foreach (var component in components)
198+
{
199+
sb.AppendLine($"- {component.GetType().Name}");
200+
}
201+
Debug.Log(sb.ToString());
202+
sb.Clear();
203+
}
204+
}
205+
}
206+
164207
/// <summary>
165208
/// Toggle the visibility of the info panel in the top right corner
166209
/// Browser Usage: <code>unityGame.SendMessage("WebGL", "ToggleInfoPanel");</code>

Assets/Plugins/WebGL/WebBridge/WebBridge.cs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,22 +18,23 @@
1818

1919
namespace Supyrb
2020
{
21+
2122
/// <summary>
2223
/// Bridge to Unity to access unity logic through the browser console
2324
/// You can extend your commands by creating a partial class for WebBridge, see WebBridge.Commands as an example
2425
/// </summary>
2526
public class WebBridge : WebCommands
2627
{
27-
private const string WebBridgeGameObjectName = "WebBridge";
28+
private const string GameObjectName = "WebBridge";
2829

29-
private static GameObject bridgeInstance;
30+
private static GameObject instance;
3031
#if UNITY_WEBGL
3132
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
3233
private static void OnBeforeSceneLoadRuntimeMethod()
3334
{
3435
SetGlobalVariables();
35-
bridgeInstance = new GameObject(WebBridgeGameObjectName);
36-
DontDestroyOnLoad(bridgeInstance);
36+
instance = new GameObject(GameObjectName);
37+
DontDestroyOnLoad(instance);
3738
AddAllWebCommands();
3839
}
3940
#endif
@@ -58,7 +59,7 @@ private static void AddAllWebCommands()
5859
webCommandTypes.Sort((a, b) => a.Name.CompareTo(b.Name));
5960
foreach (var webCommandType in webCommandTypes)
6061
{
61-
bridgeInstance.AddComponent(webCommandType);
62+
instance.AddComponent(webCommandType);
6263
}
6364
}
6465

Assets/Plugins/WebGL/WebTools/EventListeners.meta

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// --------------------------------------------------------------------------------------------------------------------
2+
// <copyright file="WebEventListener.cs">
3+
// Copyright (c) 2024 Johannes Deml. All rights reserved.
4+
// </copyright>
5+
// <author>
6+
// Johannes Deml
7+
// public@deml.io
8+
// </author>
9+
// --------------------------------------------------------------------------------------------------------------------
10+
11+
using UnityEngine;
12+
13+
namespace Supyrb
14+
{
15+
public class CommonWebEventListener : MonoBehaviour
16+
{
17+
private void Start()
18+
{
19+
WebEventListeners.AddEventListener("focus", () =>
20+
{
21+
Debug.Log("WebEvent focus triggered");
22+
});
23+
24+
WebEventListeners.AddEventListener("blur", () =>
25+
{
26+
Debug.Log("WebEvent blur triggered");
27+
});
28+
}
29+
}
30+
}

Assets/Plugins/WebGL/WebTools/EventListeners/CommonWebEventListener.cs.meta

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// --------------------------------------------------------------------------------------------------------------------
2+
// <copyright file="WebEventListener.cs">
3+
// Copyright (c) 2024 Johannes Deml. All rights reserved.
4+
// </copyright>
5+
// <author>
6+
// Johannes Deml
7+
// public@deml.io
8+
// </author>
9+
// --------------------------------------------------------------------------------------------------------------------
10+
11+
using System;
12+
using UnityEngine;
13+
14+
namespace Supyrb
15+
{
16+
public class WebEventListener : MonoBehaviour
17+
{
18+
public event Action OnEvent;
19+
20+
// Called from JavaScript
21+
public void TriggerEvent()
22+
{
23+
OnEvent?.Invoke();
24+
}
25+
26+
private void OnDestroy()
27+
{
28+
// Clean up event handlers when destroyed
29+
OnEvent = null;
30+
}
31+
}
32+
}

Assets/Plugins/WebGL/WebTools/EventListeners/WebEventListener.cs.meta

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
// --------------------------------------------------------------------------------------------------------------------
2+
// <copyright file="WebGlBridge.cs">
3+
// Copyright (c) 2021 Johannes Deml. All rights reserved.
4+
// </copyright>
5+
// <author>
6+
// Johannes Deml
7+
// public@deml.io
8+
// </author>
9+
// --------------------------------------------------------------------------------------------------------------------
10+
11+
using System;
12+
using System.Collections.Generic;
13+
using System.Runtime.InteropServices;
14+
using UnityEngine;
15+
16+
namespace Supyrb
17+
{
18+
public class WebEventListeners : MonoBehaviour
19+
{
20+
21+
#if UNITY_WEBGL
22+
[DllImport("__Internal")]
23+
private static extern void _AddJsEventListener(string eventName);
24+
#endif
25+
private const string GameObjectName = "WebEventListeners";
26+
27+
private Dictionary<string, WebEventListener> eventListeners = new Dictionary<string, WebEventListener>();
28+
private static WebEventListeners instance;
29+
#if UNITY_WEBGL
30+
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
31+
private static void OnBeforeSceneLoadRuntimeMethod()
32+
{
33+
GameObject instanceGo = new GameObject(GameObjectName);
34+
instance = instanceGo.AddComponent<WebEventListeners>();
35+
DontDestroyOnLoad(instanceGo);
36+
}
37+
#endif
38+
39+
public static void AddEventListener(string eventName, Action callback)
40+
{
41+
instance.AddEventListenerInternal(eventName, callback);
42+
}
43+
44+
private void AddEventListenerInternal(string eventName, Action callback)
45+
{
46+
if(eventListeners.TryGetValue(eventName, out var eventListener))
47+
{
48+
eventListener.OnEvent += callback;
49+
}
50+
else
51+
{
52+
var eventGo = new GameObject("WebEvent-" + eventName);
53+
eventGo.transform.parent = transform;
54+
var eventComponent = eventGo.AddComponent<WebEventListener>();
55+
eventListeners[eventName] = eventComponent;
56+
eventComponent.OnEvent += callback;
57+
58+
#if UNITY_WEBGL
59+
// Add event listener on javascript side
60+
_AddJsEventListener(eventName);
61+
#endif
62+
}
63+
}
64+
}
65+
}

Assets/Plugins/WebGL/WebTools/EventListeners/WebEventListeners.cs.meta

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
var WebGlEventListeners =
2+
{
3+
_AddJsEventListener: function(eventNamePtr) {
4+
var eventName = UTF8ToString(eventNamePtr);
5+
6+
// Add the event listener to the window object
7+
window.addEventListener(eventName, function(event) {
8+
if (typeof unityGame === 'undefined') {
9+
console.error('Unity instance "unityGame" not found - cannot send event ' + eventName);
10+
return;
11+
}
12+
unityGame.SendMessage("WebEvent-" + eventName, "TriggerEvent");
13+
});
14+
},
15+
};
16+
17+
mergeInto(LibraryManager.library, WebGlEventListeners);

Assets/Plugins/WebGL/WebTools/EventListeners/WebEventListeners.jslib.meta

Lines changed: 32 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Assets/Scenes/Main.unity

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -514,6 +514,50 @@ MonoBehaviour:
514514
spawnerCount: 5
515515
spawnerRadius: 0.5
516516
spawnerCoolDown: 0.5
517+
--- !u!1 &1401030096
518+
GameObject:
519+
m_ObjectHideFlags: 0
520+
m_CorrespondingSourceObject: {fileID: 0}
521+
m_PrefabInstance: {fileID: 0}
522+
m_PrefabAsset: {fileID: 0}
523+
serializedVersion: 6
524+
m_Component:
525+
- component: {fileID: 1401030098}
526+
- component: {fileID: 1401030097}
527+
m_Layer: 0
528+
m_Name: CommonWebEventListener
529+
m_TagString: Untagged
530+
m_Icon: {fileID: 0}
531+
m_NavMeshLayer: 0
532+
m_StaticEditorFlags: 0
533+
m_IsActive: 1
534+
--- !u!114 &1401030097
535+
MonoBehaviour:
536+
m_ObjectHideFlags: 0
537+
m_CorrespondingSourceObject: {fileID: 0}
538+
m_PrefabInstance: {fileID: 0}
539+
m_PrefabAsset: {fileID: 0}
540+
m_GameObject: {fileID: 1401030096}
541+
m_Enabled: 1
542+
m_EditorHideFlags: 0
543+
m_Script: {fileID: 11500000, guid: 2a36f15dbca612740a4822a71a1d75e1, type: 3}
544+
m_Name:
545+
m_EditorClassIdentifier:
546+
--- !u!4 &1401030098
547+
Transform:
548+
m_ObjectHideFlags: 0
549+
m_CorrespondingSourceObject: {fileID: 0}
550+
m_PrefabInstance: {fileID: 0}
551+
m_PrefabAsset: {fileID: 0}
552+
m_GameObject: {fileID: 1401030096}
553+
serializedVersion: 2
554+
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
555+
m_LocalPosition: {x: 0, y: 0, z: 0}
556+
m_LocalScale: {x: 1, y: 1, z: 1}
557+
m_ConstrainProportionsScale: 0
558+
m_Children: []
559+
m_Father: {fileID: 0}
560+
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
517561
--- !u!1 &1530667640
518562
GameObject:
519563
m_ObjectHideFlags: 0
@@ -947,3 +991,4 @@ SceneRoots:
947991
- {fileID: 1964540201}
948992
- {fileID: 170076735}
949993
- {fileID: 1530667642}
994+
- {fileID: 1401030098}

0 commit comments

Comments
 (0)