99// --------------------------------------------------------------------------------------------------------------------
1010
1111using System ;
12+ using System . Collections ;
1213using System . Collections . Generic ;
14+ using System . Linq ;
15+ using System . Text ;
1316using Supyrb . Attributes ;
1417using UnityEngine ;
1518using UnityEngine . Rendering ;
@@ -21,6 +24,11 @@ namespace Supyrb
2124 /// </summary>
2225 public class CommonCommands : WebCommands
2326 {
27+ /// <summary>
28+ /// List that stores allocated byte arrays to prevent them from being garbage collected
29+ /// </summary>
30+ private List < byte [ ] > byteArrayMemory = new List < byte [ ] > ( ) ;
31+
2432 /// <summary>
2533 /// Disable capturing all keyboard input, e.g. for using native html input fields
2634 /// Browser Usage: <code>unityGame.SendMessage("WebGL","DisableCaptureAllKeyboardInput");</code>
@@ -58,6 +66,41 @@ public void LogMemory()
5866 WebToolPlugins . LogMemory ( ) ;
5967 }
6068
69+ /// <summary>
70+ /// Allocate memory to test memory usage and limits
71+ /// The memory will be stored in a list to prevent it from being garbage collected
72+ /// </summary>
73+ /// <param name="mb">MB to allocate</param>
74+ [ WebCommand ( Description = "Allocate memory to test memory usage and limits" ) ]
75+ public void AllocateByteArrayMemory ( int mb )
76+ {
77+ byte [ ] memory = new byte [ mb * 1024 * 1024 ] ;
78+ byteArrayMemory . Add ( memory ) ;
79+ Debug . Log ( $ "Allocated { mb } MB of memory, total memory usage: { WebToolPlugins . GetTotalMemorySize ( ) : 0.00} MB") ;
80+ }
81+
82+ /// <summary>
83+ /// Release all allocated byte array memory
84+ /// </summary>
85+ [ WebCommand ( Description = "Release all allocated byte array memory" ) ]
86+ [ ContextMenu ( nameof ( ReleaseByteArrayMemory ) ) ]
87+ public void ReleaseByteArrayMemory ( )
88+ {
89+ byteArrayMemory . Clear ( ) ;
90+ Debug . Log ( "Released all allocated byte array memory, it can now be garbage collected" ) ;
91+ }
92+
93+ /// <summary>
94+ /// Trigger garbage collection
95+ /// </summary>
96+ [ WebCommand ( Description = "Trigger garbage collection" ) ]
97+ [ ContextMenu ( nameof ( TriggerGarbageCollection ) ) ]
98+ public void TriggerGarbageCollection ( )
99+ {
100+ GC . Collect ( ) ;
101+ Debug . Log ( "Garbage collection triggered" ) ;
102+ }
103+
61104 /// <summary>
62105 /// Unloads all unused assets <see cref="Resources.UnloadUnusedAssets"/>
63106 /// Browser Usage: <code>unityGame.SendMessage("WebGL","UnloadUnusedAssets");</code>
@@ -67,6 +110,7 @@ public void LogMemory()
67110 public void UnloadUnusedAssets ( )
68111 {
69112 Resources . UnloadUnusedAssets ( ) ;
113+ Debug . Log ( "Unloaded unused assets" ) ;
70114 }
71115
72116 /// <summary>
@@ -79,6 +123,7 @@ public void UnloadUnusedAssets()
79123 public void SetApplicationRunInBackground ( int runInBackground )
80124 {
81125 Application . runInBackground = runInBackground == 1 ;
126+ Debug . Log ( $ "Application.runInBackground: { Application . runInBackground } ") ;
82127 }
83128
84129 /// <summary>
@@ -90,6 +135,7 @@ public void SetApplicationRunInBackground(int runInBackground)
90135 public void SetApplicationTargetFrameRate ( int targetFrameRate )
91136 {
92137 Application . targetFrameRate = targetFrameRate ;
138+ Debug . Log ( $ "Application.targetFrameRate: { Application . targetFrameRate } ") ;
93139 }
94140
95141 /// <summary>
@@ -101,6 +147,7 @@ public void SetApplicationTargetFrameRate(int targetFrameRate)
101147 public void SetTimeFixedDeltaTime ( float fixedDeltaTime )
102148 {
103149 Time . fixedDeltaTime = fixedDeltaTime ;
150+ Debug . Log ( $ "Time.fixedDeltaTime: { Time . fixedDeltaTime } ") ;
104151 }
105152
106153 /// <summary>
@@ -113,6 +160,69 @@ public void SetTimeFixedDeltaTime(float fixedDeltaTime)
113160 public void SetTimeTimeScale ( float timeScale )
114161 {
115162 Time . timeScale = timeScale ;
163+ Debug . Log ( $ "Time.timeScale: { Time . timeScale } ") ;
164+ }
165+
166+ /// <summary>
167+ /// Log information about when the WebBridge was initialized
168+ /// </summary>
169+ [ WebCommand ( Description = "Log initialization time information" ) ]
170+ [ ContextMenu ( nameof ( LogInitializationTime ) ) ]
171+ public void LogInitializationTime ( )
172+ {
173+ var currentUnityTime = Time . realtimeSinceStartupAsDouble ;
174+ var currentUtcTime = DateTime . UtcNow ;
175+
176+ var unityTimeSinceInit = currentUnityTime - WebBridge . InitializationUnityTime ;
177+ var utcTimeSinceInit = currentUtcTime - WebBridge . InitializationUtcTime ;
178+
179+ var timeComparison = unityTimeSinceInit > utcTimeSinceInit . TotalSeconds
180+ ? "future"
181+ : "past" ;
182+
183+ Debug . Log ( $ "Unity Time since init: { unityTimeSinceInit : F2} s\n " +
184+ $ "UTC Time since init: { utcTimeSinceInit . TotalSeconds : F2} s\n " +
185+ $ "Unity time lies { Math . Abs ( unityTimeSinceInit - utcTimeSinceInit . TotalSeconds ) : F2} s in the { timeComparison } compared to UTC") ;
186+ }
187+
188+ /// <summary>
189+ /// Finds GameObject(s) by name and logs the found GameObject(s) and their components
190+ /// </summary>
191+ /// <param name="name">The name of the GameObject to find</param>
192+ [ WebCommand ( Description = "Find GameObject by name and log its components" ) ]
193+ public void FindGameObjectByName ( string name )
194+ {
195+ var gameObjects = GameObject . FindObjectsOfType < GameObject > ( ) . Where ( go => go . name == name ) . ToArray ( ) ;
196+ if ( gameObjects . Length == 0 )
197+ {
198+ Debug . Log ( $ "No GameObject found with the name: { name } ") ;
199+ }
200+ else
201+ {
202+ StringBuilder sb = new StringBuilder ( ) ;
203+ foreach ( var go in gameObjects )
204+ {
205+ int pathStartIndex = 0 ;
206+ var currentTransform = go . transform ;
207+ sb . Insert ( pathStartIndex , currentTransform . name ) ;
208+ currentTransform = currentTransform . parent ;
209+ while ( currentTransform != null )
210+ {
211+ sb . Insert ( pathStartIndex , currentTransform . name + "/" ) ;
212+ currentTransform = currentTransform . parent ;
213+ }
214+
215+ sb . AppendLine ( $ ", Tag: { go . tag } , Layer: { go . layer } , ActiveSelf: { go . activeSelf } , ActiveInHierarchy: { go . activeInHierarchy } ") ;
216+ sb . AppendLine ( "Attached Components:" ) ;
217+ var components = go . GetComponents < Component > ( ) ;
218+ foreach ( var component in components )
219+ {
220+ sb . AppendLine ( $ "- { component . GetType ( ) . Name } ") ;
221+ }
222+ Debug . Log ( sb . ToString ( ) ) ;
223+ sb . Clear ( ) ;
224+ }
225+ }
116226 }
117227
118228 /// <summary>
@@ -214,6 +324,7 @@ public void LogTextureSupport()
214324 public void DeleteAllPlayerPrefs ( )
215325 {
216326 PlayerPrefs . DeleteAll ( ) ;
327+ Debug . Log ( "Deleted all player prefs" ) ;
217328 }
218329
219330 /// <summary>
@@ -222,10 +333,89 @@ public void DeleteAllPlayerPrefs()
222333 /// </summary>
223334 /// <param name="runInBackground">1 if it should run in background</param>
224335 [ WebCommand ( Description = "GraphicsSettings.logWhenShaderIsCompiled" ) ]
225- [ ContextMenu ( nameof ( LogShaderCompilation ) ) ]
226336 public void LogShaderCompilation ( int enabled )
227337 {
228338 GraphicsSettings . logWhenShaderIsCompiled = enabled == 1 ;
339+ Debug . Log ( $ "GraphicsSettings.logWhenShaderIsCompiled: { GraphicsSettings . logWhenShaderIsCompiled } ") ;
340+ }
341+
342+ /// <summary>
343+ /// Copy text to clipboard using the browser's clipboard API
344+ /// </summary>
345+ /// <param name="text">Text to copy to clipboard</param>
346+ [ WebCommand ( Description = "Copy text to clipboard" ) ]
347+ public void CopyToClipboard ( string text )
348+ {
349+ WebToolPlugins . CopyToClipboard ( text ) ;
350+ }
351+
352+ /// <summary>
353+ /// Check if the browser has an internet connection
354+ /// </summary>
355+ [ WebCommand ( Description = "Check if browser is online" ) ]
356+ public void CheckOnlineStatus ( )
357+ {
358+ bool isOnline = WebToolPlugins . IsOnline ( ) ;
359+ Debug . Log ( $ "<color=#4D65A4>Online Status:</color> { ( isOnline ? "<color=#3bb508>Connected</color>" : "<color=#b50808>Disconnected</color>" ) } ") ;
360+ }
361+
362+ /// <summary>
363+ /// Captures the current screen and saves it as a PNG file.
364+ /// </summary>
365+ [ WebCommand ( Description = "Save current screen as PNG" ) ]
366+ public void SaveScreenshot ( )
367+ {
368+ SaveScreenshotSuperSize ( 1 ) ;
369+ }
370+
371+ /// <summary>
372+ /// Captures the current screen and saves it as a PNG file.
373+ /// </summary>
374+ /// <param name="superSize">1 for normal size, 2 for double size, 4 for quadruple size</param>
375+ [ WebCommand ( Description = "Save current screen as PNG with variable super size" ) ]
376+ public void SaveScreenshotSuperSize ( int superSize )
377+ {
378+ StartCoroutine ( CaptureScreenshot ( superSize ) ) ;
379+ }
380+
381+ private IEnumerator CaptureScreenshot ( int superSize )
382+ {
383+ // Wait for the end of frame to ensure everything is rendered
384+ yield return new WaitForEndOfFrame ( ) ;
385+
386+ string filename = "screenshot.png" ;
387+ try
388+ {
389+ // Capture the screen
390+ Texture2D screenshot = ScreenCapture . CaptureScreenshotAsTexture ( superSize ) ;
391+
392+ try
393+ {
394+ // Convert to PNG
395+ byte [ ] pngData = screenshot . EncodeToPNG ( ) ;
396+
397+ // Download through browser
398+ WebToolPlugins . DownloadBinaryFile ( filename , pngData , "image/png" ) ;
399+
400+ Debug . Log ( $ "Screenshot saved as { filename } ({ screenshot . width } x{ screenshot . height } ) with size { pngData . Length } bytes") ;
401+ }
402+ finally
403+ {
404+ // Clean up the texture
405+ if ( Application . isPlaying )
406+ {
407+ Destroy ( screenshot ) ;
408+ }
409+ else
410+ {
411+ DestroyImmediate ( screenshot ) ;
412+ }
413+ }
414+ }
415+ catch ( System . Exception e )
416+ {
417+ Debug . LogError ( $ "Failed to save screenshot: { e . Message } ") ;
418+ }
229419 }
230420 }
231421}
0 commit comments