The fucking 3rd time i had to upload this project to git
This commit is contained in:
126
Assets/DebugConsole/Scripts/CircularBuffer.cs
Normal file
126
Assets/DebugConsole/Scripts/CircularBuffer.cs
Normal file
@ -0,0 +1,126 @@
|
||||
// #define RESET_REMOVED_ELEMENTS
|
||||
|
||||
using System;
|
||||
|
||||
namespace IngameDebugConsole
|
||||
{
|
||||
public class CircularBuffer<T>
|
||||
{
|
||||
private readonly T[] arr;
|
||||
private int startIndex;
|
||||
|
||||
public CircularBuffer(int capacity)
|
||||
{
|
||||
arr = new T[capacity];
|
||||
}
|
||||
|
||||
public int Count { get; private set; }
|
||||
public T this[int index] => arr[(startIndex + index) % arr.Length];
|
||||
|
||||
// Old elements are overwritten when capacity is reached
|
||||
public void Add(T value)
|
||||
{
|
||||
if (Count < arr.Length)
|
||||
{
|
||||
arr[Count++] = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
arr[startIndex] = value;
|
||||
if (++startIndex >= arr.Length)
|
||||
startIndex = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class DynamicCircularBuffer<T>
|
||||
{
|
||||
private T[] arr;
|
||||
private int startIndex;
|
||||
|
||||
public DynamicCircularBuffer(int initialCapacity = 2)
|
||||
{
|
||||
arr = new T[initialCapacity];
|
||||
}
|
||||
|
||||
public int Count { get; private set; }
|
||||
public int Capacity => arr.Length;
|
||||
|
||||
public T this[int index]
|
||||
{
|
||||
get => arr[(startIndex + index) % arr.Length];
|
||||
set => arr[(startIndex + index) % arr.Length] = value;
|
||||
}
|
||||
|
||||
public void Add(T value)
|
||||
{
|
||||
if (Count >= arr.Length)
|
||||
{
|
||||
var prevSize = arr.Length;
|
||||
var newSize =
|
||||
prevSize > 0
|
||||
? prevSize * 2
|
||||
: 2; // Size must be doubled (at least), or the shift operation below must consider IndexOutOfRange situations
|
||||
|
||||
Array.Resize(ref arr, newSize);
|
||||
|
||||
if (startIndex > 0)
|
||||
{
|
||||
if (startIndex <= (prevSize - 1) / 2)
|
||||
{
|
||||
// Move elements [0,startIndex) to the end
|
||||
for (var i = 0; i < startIndex; i++)
|
||||
{
|
||||
arr[i + prevSize] = arr[i];
|
||||
#if RESET_REMOVED_ELEMENTS
|
||||
arr[i] = default( T );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Move elements [startIndex,prevSize) to the end
|
||||
var delta = newSize - prevSize;
|
||||
for (var i = prevSize - 1; i >= startIndex; i--)
|
||||
{
|
||||
arr[i + delta] = arr[i];
|
||||
#if RESET_REMOVED_ELEMENTS
|
||||
arr[i] = default( T );
|
||||
#endif
|
||||
}
|
||||
|
||||
startIndex += delta;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this[Count++] = value;
|
||||
}
|
||||
|
||||
public T RemoveFirst()
|
||||
{
|
||||
var element = arr[startIndex];
|
||||
#if RESET_REMOVED_ELEMENTS
|
||||
arr[startIndex] = default( T );
|
||||
#endif
|
||||
|
||||
if (++startIndex >= arr.Length)
|
||||
startIndex = 0;
|
||||
|
||||
Count--;
|
||||
return element;
|
||||
}
|
||||
|
||||
public T RemoveLast()
|
||||
{
|
||||
var index = (startIndex + Count - 1) % arr.Length;
|
||||
var element = arr[index];
|
||||
#if RESET_REMOVED_ELEMENTS
|
||||
arr[index] = default( T );
|
||||
#endif
|
||||
|
||||
Count--;
|
||||
return element;
|
||||
}
|
||||
}
|
||||
}
|
12
Assets/DebugConsole/Scripts/CircularBuffer.cs.meta
Normal file
12
Assets/DebugConsole/Scripts/CircularBuffer.cs.meta
Normal file
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6136cb3c00eac0149901b8e7f2fecef8
|
||||
timeCreated: 1550943949
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Assets/DebugConsole/Scripts/Commands.meta
Normal file
8
Assets/DebugConsole/Scripts/Commands.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bb9b6e1ab379cec46bfae8f8abcc1f45
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
60
Assets/DebugConsole/Scripts/Commands/PlayerCommands.cs
Normal file
60
Assets/DebugConsole/Scripts/Commands/PlayerCommands.cs
Normal file
@ -0,0 +1,60 @@
|
||||
// using Player.Interactions;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Scripting;
|
||||
using Player.Information;
|
||||
using Player.Movement;
|
||||
|
||||
namespace IngameDebugConsole.Commands
|
||||
{
|
||||
public class PlayerCommands
|
||||
{
|
||||
[ConsoleMethod("player.jetpack", "Sets Jetpack Active State")]
|
||||
[Preserve]
|
||||
public static void PlayerJetpack(bool boolValue)
|
||||
{
|
||||
var player = GameObject.Find("Player");
|
||||
if (player != null)
|
||||
{
|
||||
// set jetpack component active
|
||||
player.GetComponent<PlayerStats>().jetpackEnabled = boolValue;
|
||||
Debug.Log("Jetpack set to " + boolValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Log("Player not found");
|
||||
}
|
||||
}
|
||||
|
||||
[ConsoleMethod("player.grapple", "Sets Grapple Active State")]
|
||||
[Preserve]
|
||||
public static void PlayerGrapple(bool boolValue)
|
||||
{
|
||||
var player = GameObject.Find("Player");
|
||||
if (player != null)
|
||||
{
|
||||
player.GetComponent<PlayerStats>().grappleEnabled = boolValue;
|
||||
Debug.Log("Grapple set to " + boolValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Log("Player not found");
|
||||
}
|
||||
}
|
||||
[ConsoleMethod("player.sensitivity", "Sets Mouse Sensitivity")]
|
||||
[Preserve]
|
||||
public static void PlayerSensitivity(float sensitivity)
|
||||
{
|
||||
var player = GameObject.Find("Player");
|
||||
if (player != null)
|
||||
{
|
||||
Camera.main.GetComponent<MouseLook>().mouseSensitivity = sensitivity;
|
||||
PlayerPrefs.SetFloat("Sensitivity", sensitivity);
|
||||
Debug.Log("Mouse Sensitivity set to " + sensitivity);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Log("Player not found");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ed03242f9d95d614b8dbb178cc9ce59b
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
65
Assets/DebugConsole/Scripts/Commands/SceneCommands.cs
Normal file
65
Assets/DebugConsole/Scripts/Commands/SceneCommands.cs
Normal file
@ -0,0 +1,65 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.SceneManagement;
|
||||
using UnityEngine.Scripting;
|
||||
|
||||
namespace IngameDebugConsole.Commands
|
||||
{
|
||||
public class SceneCommands
|
||||
{
|
||||
[ConsoleMethod("scene.load", "Loads a scene")]
|
||||
[Preserve]
|
||||
public static void LoadScene(string sceneName)
|
||||
{
|
||||
LoadSceneInternal(sceneName, false, LoadSceneMode.Single);
|
||||
}
|
||||
|
||||
[ConsoleMethod("scene.load", "Loads a scene")]
|
||||
[Preserve]
|
||||
public static void LoadScene(string sceneName, LoadSceneMode mode)
|
||||
{
|
||||
LoadSceneInternal(sceneName, false, mode);
|
||||
}
|
||||
|
||||
[ConsoleMethod("scene.loadasync", "Loads a scene asynchronously")]
|
||||
[Preserve]
|
||||
public static void LoadSceneAsync(string sceneName)
|
||||
{
|
||||
LoadSceneInternal(sceneName, true, LoadSceneMode.Single);
|
||||
}
|
||||
|
||||
[ConsoleMethod("scene.loadasync", "Loads a scene asynchronously")]
|
||||
[Preserve]
|
||||
public static void LoadSceneAsync(string sceneName, LoadSceneMode mode)
|
||||
{
|
||||
LoadSceneInternal(sceneName, true, mode);
|
||||
}
|
||||
|
||||
private static void LoadSceneInternal(string sceneName, bool isAsync, LoadSceneMode mode)
|
||||
{
|
||||
if (SceneManager.GetSceneByName(sceneName).IsValid())
|
||||
{
|
||||
Debug.Log("Scene " + sceneName + " is already loaded");
|
||||
return;
|
||||
}
|
||||
|
||||
if (isAsync)
|
||||
SceneManager.LoadSceneAsync(sceneName, mode);
|
||||
else
|
||||
SceneManager.LoadScene(sceneName, mode);
|
||||
}
|
||||
|
||||
[ConsoleMethod("scene.unload", "Unloads a scene")]
|
||||
[Preserve]
|
||||
public static void UnloadScene(string sceneName)
|
||||
{
|
||||
SceneManager.UnloadSceneAsync(sceneName);
|
||||
}
|
||||
|
||||
[ConsoleMethod("scene.restart", "Restarts the active scene")]
|
||||
[Preserve]
|
||||
public static void RestartScene()
|
||||
{
|
||||
SceneManager.LoadScene(SceneManager.GetActiveScene().name, LoadSceneMode.Single);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 73f6112b4a7e5624583195aa8af9e548
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
22
Assets/DebugConsole/Scripts/Commands/TimeCommands.cs
Normal file
22
Assets/DebugConsole/Scripts/Commands/TimeCommands.cs
Normal file
@ -0,0 +1,22 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.Scripting;
|
||||
|
||||
namespace IngameDebugConsole.Commands
|
||||
{
|
||||
public class TimeCommands
|
||||
{
|
||||
[ConsoleMethod("time.scale", "Sets the Time.timeScale value")]
|
||||
[Preserve]
|
||||
public static void SetTimeScale(float value)
|
||||
{
|
||||
Time.timeScale = Mathf.Max(value, 0f);
|
||||
}
|
||||
|
||||
[ConsoleMethod("time.scale", "Returns the current Time.timeScale value")]
|
||||
[Preserve]
|
||||
public static float GetTimeScale()
|
||||
{
|
||||
return Time.timeScale;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c5061e3b82c469c4d9ee288d4ec03d5e
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
21
Assets/DebugConsole/Scripts/ConsoleMethodAttribute.cs
Normal file
21
Assets/DebugConsole/Scripts/ConsoleMethodAttribute.cs
Normal file
@ -0,0 +1,21 @@
|
||||
using System;
|
||||
|
||||
namespace IngameDebugConsole
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = true)]
|
||||
public class ConsoleMethodAttribute : Attribute
|
||||
{
|
||||
public ConsoleMethodAttribute(string command, string description, params string[] parameterNames)
|
||||
{
|
||||
Command = command;
|
||||
Description = description;
|
||||
ParameterNames = parameterNames;
|
||||
}
|
||||
|
||||
public string Command { get; }
|
||||
|
||||
public string Description { get; }
|
||||
|
||||
public string[] ParameterNames { get; }
|
||||
}
|
||||
}
|
12
Assets/DebugConsole/Scripts/ConsoleMethodAttribute.cs.meta
Normal file
12
Assets/DebugConsole/Scripts/ConsoleMethodAttribute.cs.meta
Normal file
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 324bb39c0bff0f74fa42f83e91f07e3a
|
||||
timeCreated: 1520710946
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
1716
Assets/DebugConsole/Scripts/DebugLogConsole.cs
Normal file
1716
Assets/DebugConsole/Scripts/DebugLogConsole.cs
Normal file
File diff suppressed because it is too large
Load Diff
12
Assets/DebugConsole/Scripts/DebugLogConsole.cs.meta
Normal file
12
Assets/DebugConsole/Scripts/DebugLogConsole.cs.meta
Normal file
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d15693a03d0d33b4892c6365a2a97e19
|
||||
timeCreated: 1472036503
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
174
Assets/DebugConsole/Scripts/DebugLogEntry.cs
Normal file
174
Assets/DebugConsole/Scripts/DebugLogEntry.cs
Normal file
@ -0,0 +1,174 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
|
||||
// Container for a simple debug entry
|
||||
namespace IngameDebugConsole
|
||||
{
|
||||
public class DebugLogEntry : IEquatable<DebugLogEntry>
|
||||
{
|
||||
private const int HASH_NOT_CALCULATED = -623218;
|
||||
|
||||
private string completeLog;
|
||||
|
||||
// Collapsed count
|
||||
public int count;
|
||||
|
||||
private int hashValue;
|
||||
|
||||
public string logString;
|
||||
|
||||
// Sprite to show with this entry
|
||||
public Sprite logTypeSpriteRepresentation;
|
||||
public string stackTrace;
|
||||
|
||||
// Check if two entries have the same origin
|
||||
public bool Equals(DebugLogEntry other)
|
||||
{
|
||||
return logString == other.logString && stackTrace == other.stackTrace;
|
||||
}
|
||||
|
||||
public void Initialize(string logString, string stackTrace)
|
||||
{
|
||||
this.logString = logString;
|
||||
this.stackTrace = stackTrace;
|
||||
|
||||
completeLog = null;
|
||||
count = 1;
|
||||
hashValue = HASH_NOT_CALCULATED;
|
||||
}
|
||||
|
||||
// Checks if logString or stackTrace contains the search term
|
||||
public bool MatchesSearchTerm(string searchTerm)
|
||||
{
|
||||
return (logString != null && DebugLogConsole.caseInsensitiveComparer.IndexOf(logString, searchTerm,
|
||||
CompareOptions.IgnoreCase | CompareOptions.IgnoreNonSpace) >= 0) ||
|
||||
(stackTrace != null && DebugLogConsole.caseInsensitiveComparer.IndexOf(stackTrace, searchTerm,
|
||||
CompareOptions.IgnoreCase | CompareOptions.IgnoreNonSpace) >= 0);
|
||||
}
|
||||
|
||||
// Return a string containing complete information about this debug entry
|
||||
public override string ToString()
|
||||
{
|
||||
if (completeLog == null)
|
||||
completeLog = string.Concat(logString, "\n", stackTrace);
|
||||
|
||||
return completeLog;
|
||||
}
|
||||
|
||||
// Credit: https://stackoverflow.com/a/19250516/2373034
|
||||
public override int GetHashCode()
|
||||
{
|
||||
if (hashValue == HASH_NOT_CALCULATED)
|
||||
unchecked
|
||||
{
|
||||
hashValue = 17;
|
||||
hashValue = hashValue * 23 + (logString == null ? 0 : logString.GetHashCode());
|
||||
hashValue = hashValue * 23 + (stackTrace == null ? 0 : stackTrace.GetHashCode());
|
||||
}
|
||||
|
||||
return hashValue;
|
||||
}
|
||||
}
|
||||
|
||||
public struct QueuedDebugLogEntry
|
||||
{
|
||||
public readonly string logString;
|
||||
public readonly string stackTrace;
|
||||
public readonly LogType logType;
|
||||
|
||||
public QueuedDebugLogEntry(string logString, string stackTrace, LogType logType)
|
||||
{
|
||||
this.logString = logString;
|
||||
this.stackTrace = stackTrace;
|
||||
this.logType = logType;
|
||||
}
|
||||
|
||||
// Checks if logString or stackTrace contains the search term
|
||||
public bool MatchesSearchTerm(string searchTerm)
|
||||
{
|
||||
return (logString != null && DebugLogConsole.caseInsensitiveComparer.IndexOf(logString, searchTerm,
|
||||
CompareOptions.IgnoreCase | CompareOptions.IgnoreNonSpace) >= 0) ||
|
||||
(stackTrace != null && DebugLogConsole.caseInsensitiveComparer.IndexOf(stackTrace, searchTerm,
|
||||
CompareOptions.IgnoreCase | CompareOptions.IgnoreNonSpace) >= 0);
|
||||
}
|
||||
}
|
||||
|
||||
public struct DebugLogEntryTimestamp
|
||||
{
|
||||
public readonly DateTime dateTime;
|
||||
#if !IDG_OMIT_ELAPSED_TIME
|
||||
public readonly float elapsedSeconds;
|
||||
#endif
|
||||
#if !IDG_OMIT_FRAMECOUNT
|
||||
public readonly int frameCount;
|
||||
#endif
|
||||
|
||||
#if !IDG_OMIT_ELAPSED_TIME && !IDG_OMIT_FRAMECOUNT
|
||||
public DebugLogEntryTimestamp(DateTime dateTime, float elapsedSeconds, int frameCount)
|
||||
#elif !IDG_OMIT_ELAPSED_TIME
|
||||
public DebugLogEntryTimestamp( System.DateTime dateTime, float elapsedSeconds )
|
||||
#elif !IDG_OMIT_FRAMECOUNT
|
||||
public DebugLogEntryTimestamp( System.DateTime dateTime, int frameCount )
|
||||
#else
|
||||
public DebugLogEntryTimestamp( System.DateTime dateTime )
|
||||
#endif
|
||||
{
|
||||
this.dateTime = dateTime;
|
||||
#if !IDG_OMIT_ELAPSED_TIME
|
||||
this.elapsedSeconds = elapsedSeconds;
|
||||
#endif
|
||||
#if !IDG_OMIT_FRAMECOUNT
|
||||
this.frameCount = frameCount;
|
||||
#endif
|
||||
}
|
||||
|
||||
public void AppendTime(StringBuilder sb)
|
||||
{
|
||||
// Add DateTime in format: [HH:mm:ss]
|
||||
sb.Append("[");
|
||||
|
||||
var hour = dateTime.Hour;
|
||||
if (hour >= 10)
|
||||
sb.Append(hour);
|
||||
else
|
||||
sb.Append("0").Append(hour);
|
||||
|
||||
sb.Append(":");
|
||||
|
||||
var minute = dateTime.Minute;
|
||||
if (minute >= 10)
|
||||
sb.Append(minute);
|
||||
else
|
||||
sb.Append("0").Append(minute);
|
||||
|
||||
sb.Append(":");
|
||||
|
||||
var second = dateTime.Second;
|
||||
if (second >= 10)
|
||||
sb.Append(second);
|
||||
else
|
||||
sb.Append("0").Append(second);
|
||||
|
||||
sb.Append("]");
|
||||
}
|
||||
|
||||
public void AppendFullTimestamp(StringBuilder sb)
|
||||
{
|
||||
AppendTime(sb);
|
||||
|
||||
#if !IDG_OMIT_ELAPSED_TIME && !IDG_OMIT_FRAMECOUNT
|
||||
// Append elapsed seconds and frame count in format: [1.0s at #Frame]
|
||||
sb.Append("[").Append(elapsedSeconds.ToString("F1")).Append("s at ").Append("#").Append(frameCount)
|
||||
.Append("]");
|
||||
#elif !IDG_OMIT_ELAPSED_TIME
|
||||
// Append elapsed seconds in format: [1.0s]
|
||||
sb.Append( "[" ).Append( elapsedSeconds.ToString( "F1" ) ).Append( "s]" );
|
||||
#elif !IDG_OMIT_FRAMECOUNT
|
||||
// Append frame count in format: [#Frame]
|
||||
sb.Append( "[#" ).Append( frameCount ).Append( "]" );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
12
Assets/DebugConsole/Scripts/DebugLogEntry.cs.meta
Normal file
12
Assets/DebugConsole/Scripts/DebugLogEntry.cs.meta
Normal file
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e7b1a420c564be040bf73b8a377fc2c2
|
||||
timeCreated: 1466375168
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
41
Assets/DebugConsole/Scripts/DebugLogIndexList.cs
Normal file
41
Assets/DebugConsole/Scripts/DebugLogIndexList.cs
Normal file
@ -0,0 +1,41 @@
|
||||
using System;
|
||||
|
||||
namespace IngameDebugConsole
|
||||
{
|
||||
public class DebugLogIndexList<T>
|
||||
{
|
||||
private T[] indices;
|
||||
|
||||
public DebugLogIndexList()
|
||||
{
|
||||
indices = new T[64];
|
||||
Count = 0;
|
||||
}
|
||||
|
||||
public int Count { get; private set; }
|
||||
|
||||
public T this[int index]
|
||||
{
|
||||
get => indices[index];
|
||||
set => indices[index] = value;
|
||||
}
|
||||
|
||||
public void Add(T value)
|
||||
{
|
||||
if (Count == indices.Length)
|
||||
Array.Resize(ref indices, Count * 2);
|
||||
|
||||
indices[Count++] = value;
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
Count = 0;
|
||||
}
|
||||
|
||||
public int IndexOf(T value)
|
||||
{
|
||||
return Array.IndexOf(indices, value);
|
||||
}
|
||||
}
|
||||
}
|
12
Assets/DebugConsole/Scripts/DebugLogIndexList.cs.meta
Normal file
12
Assets/DebugConsole/Scripts/DebugLogIndexList.cs.meta
Normal file
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 37c6c91e5bfac6f499698c03f593bcbb
|
||||
timeCreated: 1520627934
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
280
Assets/DebugConsole/Scripts/DebugLogItem.cs
Normal file
280
Assets/DebugConsole/Scripts/DebugLogItem.cs
Normal file
@ -0,0 +1,280 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
using UnityEngine.UI;
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
using System.Text.RegularExpressions;
|
||||
#endif
|
||||
|
||||
// A UI element to show information about a debug entry
|
||||
namespace IngameDebugConsole
|
||||
{
|
||||
public class DebugLogItem : MonoBehaviour, IPointerClickHandler
|
||||
{
|
||||
#region Platform Specific Elements
|
||||
|
||||
#if !UNITY_2018_1_OR_NEWER
|
||||
#if !UNITY_EDITOR && UNITY_ANDROID
|
||||
private static AndroidJavaClass m_ajc = null;
|
||||
private static AndroidJavaClass AJC
|
||||
{
|
||||
get
|
||||
{
|
||||
if( m_ajc == null )
|
||||
m_ajc = new AndroidJavaClass( "com.yasirkula.unity.DebugConsole" );
|
||||
|
||||
return m_ajc;
|
||||
}
|
||||
}
|
||||
|
||||
private static AndroidJavaObject m_context = null;
|
||||
private static AndroidJavaObject Context
|
||||
{
|
||||
get
|
||||
{
|
||||
if( m_context == null )
|
||||
{
|
||||
using( AndroidJavaObject unityClass = new AndroidJavaClass( "com.unity3d.player.UnityPlayer" ) )
|
||||
{
|
||||
m_context = unityClass.GetStatic<AndroidJavaObject>( "currentActivity" );
|
||||
}
|
||||
}
|
||||
|
||||
return m_context;
|
||||
}
|
||||
}
|
||||
#elif !UNITY_EDITOR && UNITY_IOS
|
||||
[System.Runtime.InteropServices.DllImport( "__Internal" )]
|
||||
private static extern void _DebugConsole_CopyText( string text );
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endregion
|
||||
|
||||
#pragma warning disable 0649
|
||||
// Cached components
|
||||
[SerializeField] private RectTransform transformComponent;
|
||||
public RectTransform Transform => transformComponent;
|
||||
|
||||
[SerializeField] private Image imageComponent;
|
||||
public Image Image => imageComponent;
|
||||
|
||||
[SerializeField] private CanvasGroup canvasGroupComponent;
|
||||
public CanvasGroup CanvasGroup => canvasGroupComponent;
|
||||
|
||||
[SerializeField] private Text logText;
|
||||
[SerializeField] private Image logTypeImage;
|
||||
|
||||
// Objects related to the collapsed count of the debug entry
|
||||
[SerializeField] private GameObject logCountParent;
|
||||
[SerializeField] private Text logCountText;
|
||||
|
||||
[SerializeField] private RectTransform copyLogButton;
|
||||
#pragma warning restore 0649
|
||||
|
||||
// Debug entry to show with this log item
|
||||
public DebugLogEntry Entry { get; private set; }
|
||||
|
||||
private DebugLogEntryTimestamp? logEntryTimestamp;
|
||||
public DebugLogEntryTimestamp? Timestamp => logEntryTimestamp;
|
||||
|
||||
// Index of the entry in the list of entries
|
||||
public int Index { get; private set; }
|
||||
|
||||
public bool Expanded { get; private set; }
|
||||
|
||||
private Vector2 logTextOriginalPosition;
|
||||
private Vector2 logTextOriginalSize;
|
||||
private float copyLogButtonHeight;
|
||||
|
||||
private DebugLogRecycledListView listView;
|
||||
|
||||
public void Initialize(DebugLogRecycledListView listView)
|
||||
{
|
||||
this.listView = listView;
|
||||
|
||||
logTextOriginalPosition = logText.rectTransform.anchoredPosition;
|
||||
logTextOriginalSize = logText.rectTransform.sizeDelta;
|
||||
copyLogButtonHeight =
|
||||
copyLogButton.anchoredPosition.y + copyLogButton.sizeDelta.y + 2f; // 2f: space between text and button
|
||||
|
||||
#if !UNITY_EDITOR && UNITY_WEBGL
|
||||
copyLogButton.gameObject.AddComponent<DebugLogItemCopyWebGL>().Initialize( this );
|
||||
#endif
|
||||
}
|
||||
|
||||
public void SetContent(DebugLogEntry logEntry, DebugLogEntryTimestamp? logEntryTimestamp, int entryIndex,
|
||||
bool isExpanded)
|
||||
{
|
||||
this.Entry = logEntry;
|
||||
this.logEntryTimestamp = logEntryTimestamp;
|
||||
this.Index = entryIndex;
|
||||
this.Expanded = isExpanded;
|
||||
|
||||
var size = transformComponent.sizeDelta;
|
||||
if (isExpanded)
|
||||
{
|
||||
logText.horizontalOverflow = HorizontalWrapMode.Wrap;
|
||||
size.y = listView.SelectedItemHeight;
|
||||
|
||||
if (!copyLogButton.gameObject.activeSelf)
|
||||
{
|
||||
copyLogButton.gameObject.SetActive(true);
|
||||
|
||||
logText.rectTransform.anchoredPosition = new Vector2(logTextOriginalPosition.x,
|
||||
logTextOriginalPosition.y + copyLogButtonHeight * 0.5f);
|
||||
logText.rectTransform.sizeDelta = logTextOriginalSize - new Vector2(0f, copyLogButtonHeight);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
logText.horizontalOverflow = HorizontalWrapMode.Overflow;
|
||||
size.y = listView.ItemHeight;
|
||||
|
||||
if (copyLogButton.gameObject.activeSelf)
|
||||
{
|
||||
copyLogButton.gameObject.SetActive(false);
|
||||
|
||||
logText.rectTransform.anchoredPosition = logTextOriginalPosition;
|
||||
logText.rectTransform.sizeDelta = logTextOriginalSize;
|
||||
}
|
||||
}
|
||||
|
||||
transformComponent.sizeDelta = size;
|
||||
|
||||
SetText(logEntry, logEntryTimestamp, isExpanded);
|
||||
logTypeImage.sprite = logEntry.logTypeSpriteRepresentation;
|
||||
}
|
||||
|
||||
// Show the collapsed count of the debug entry
|
||||
public void ShowCount()
|
||||
{
|
||||
logCountText.text = Entry.count.ToString();
|
||||
|
||||
if (!logCountParent.activeSelf)
|
||||
logCountParent.SetActive(true);
|
||||
}
|
||||
|
||||
// Hide the collapsed count of the debug entry
|
||||
public void HideCount()
|
||||
{
|
||||
if (logCountParent.activeSelf)
|
||||
logCountParent.SetActive(false);
|
||||
}
|
||||
|
||||
// Update the debug entry's displayed timestamp
|
||||
public void UpdateTimestamp(DebugLogEntryTimestamp timestamp)
|
||||
{
|
||||
logEntryTimestamp = timestamp;
|
||||
|
||||
if (Expanded || listView.manager.alwaysDisplayTimestamps)
|
||||
SetText(Entry, timestamp, Expanded);
|
||||
}
|
||||
|
||||
private void SetText(DebugLogEntry logEntry, DebugLogEntryTimestamp? logEntryTimestamp, bool isExpanded)
|
||||
{
|
||||
if (!logEntryTimestamp.HasValue || (!isExpanded && !listView.manager.alwaysDisplayTimestamps))
|
||||
{
|
||||
logText.text = isExpanded ? logEntry.ToString() : logEntry.logString;
|
||||
}
|
||||
else
|
||||
{
|
||||
var sb = listView.manager.sharedStringBuilder;
|
||||
sb.Length = 0;
|
||||
|
||||
if (isExpanded)
|
||||
{
|
||||
logEntryTimestamp.Value.AppendFullTimestamp(sb);
|
||||
sb.Append(": ").Append(logEntry);
|
||||
}
|
||||
else
|
||||
{
|
||||
logEntryTimestamp.Value.AppendTime(sb);
|
||||
sb.Append(" ").Append(logEntry.logString);
|
||||
}
|
||||
|
||||
logText.text = sb.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
// This log item is clicked, show the debug entry's stack trace
|
||||
public void OnPointerClick(PointerEventData eventData)
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (eventData.button == PointerEventData.InputButton.Right)
|
||||
{
|
||||
var regex = Regex.Match(Entry.stackTrace, @"\(at .*\.cs:[0-9]+\)$", RegexOptions.Multiline);
|
||||
if (regex.Success)
|
||||
{
|
||||
var line = Entry.stackTrace.Substring(regex.Index + 4, regex.Length - 5);
|
||||
var lineSeparator = line.IndexOf(':');
|
||||
var script = AssetDatabase.LoadAssetAtPath<MonoScript>(line.Substring(0, lineSeparator));
|
||||
if (script != null)
|
||||
AssetDatabase.OpenAsset(script, int.Parse(line.Substring(lineSeparator + 1)));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
listView.OnLogItemClicked(this);
|
||||
}
|
||||
#else
|
||||
listView.OnLogItemClicked( this );
|
||||
#endif
|
||||
}
|
||||
|
||||
public void CopyLog()
|
||||
{
|
||||
#if UNITY_EDITOR || !UNITY_WEBGL
|
||||
var log = GetCopyContent();
|
||||
if (string.IsNullOrEmpty(log))
|
||||
return;
|
||||
|
||||
#if UNITY_EDITOR || UNITY_2018_1_OR_NEWER || ( !UNITY_ANDROID && !UNITY_IOS )
|
||||
GUIUtility.systemCopyBuffer = log;
|
||||
#elif UNITY_ANDROID
|
||||
AJC.CallStatic( "CopyText", Context, log );
|
||||
#elif UNITY_IOS
|
||||
_DebugConsole_CopyText( log );
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
internal string GetCopyContent()
|
||||
{
|
||||
if (!logEntryTimestamp.HasValue)
|
||||
{
|
||||
return Entry.ToString();
|
||||
}
|
||||
|
||||
var sb = listView.manager.sharedStringBuilder;
|
||||
sb.Length = 0;
|
||||
|
||||
logEntryTimestamp.Value.AppendFullTimestamp(sb);
|
||||
sb.Append(": ").Append(Entry);
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public float CalculateExpandedHeight(DebugLogEntry logEntry, DebugLogEntryTimestamp? logEntryTimestamp)
|
||||
{
|
||||
var text = logText.text;
|
||||
var wrapMode = logText.horizontalOverflow;
|
||||
|
||||
SetText(logEntry, logEntryTimestamp, true);
|
||||
logText.horizontalOverflow = HorizontalWrapMode.Wrap;
|
||||
|
||||
var result = logText.preferredHeight + copyLogButtonHeight;
|
||||
|
||||
logText.text = text;
|
||||
logText.horizontalOverflow = wrapMode;
|
||||
|
||||
return Mathf.Max(listView.ItemHeight, result);
|
||||
}
|
||||
|
||||
// Return a string containing complete information about the debug entry
|
||||
public override string ToString()
|
||||
{
|
||||
return Entry.ToString();
|
||||
}
|
||||
}
|
||||
}
|
12
Assets/DebugConsole/Scripts/DebugLogItem.cs.meta
Normal file
12
Assets/DebugConsole/Scripts/DebugLogItem.cs.meta
Normal file
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d2ea291be9de70a4abfec595203c96c1
|
||||
timeCreated: 1465919949
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
36
Assets/DebugConsole/Scripts/DebugLogItemCopyWebGL.cs
Normal file
36
Assets/DebugConsole/Scripts/DebugLogItemCopyWebGL.cs
Normal file
@ -0,0 +1,36 @@
|
||||
#if !UNITY_EDITOR && UNITY_WEBGL
|
||||
using System.Runtime.InteropServices;
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
|
||||
namespace IngameDebugConsole
|
||||
{
|
||||
public class DebugLogItemCopyWebGL : MonoBehaviour, IPointerDownHandler, IPointerUpHandler
|
||||
{
|
||||
[DllImport( "__Internal" )]
|
||||
private static extern void IngameDebugConsoleStartCopy( string textToCopy );
|
||||
[DllImport( "__Internal" )]
|
||||
private static extern void IngameDebugConsoleCancelCopy();
|
||||
|
||||
private DebugLogItem logItem;
|
||||
|
||||
public void Initialize( DebugLogItem logItem )
|
||||
{
|
||||
this.logItem = logItem;
|
||||
}
|
||||
|
||||
public void OnPointerDown( PointerEventData eventData )
|
||||
{
|
||||
string log = logItem.GetCopyContent();
|
||||
if( !string.IsNullOrEmpty( log ) )
|
||||
IngameDebugConsoleStartCopy( log );
|
||||
}
|
||||
|
||||
public void OnPointerUp( PointerEventData eventData )
|
||||
{
|
||||
if( eventData.dragging )
|
||||
IngameDebugConsoleCancelCopy();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
11
Assets/DebugConsole/Scripts/DebugLogItemCopyWebGL.cs.meta
Normal file
11
Assets/DebugConsole/Scripts/DebugLogItemCopyWebGL.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5a7d9d894141e704d8160fb4632121ac
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
1752
Assets/DebugConsole/Scripts/DebugLogManager.cs
Normal file
1752
Assets/DebugConsole/Scripts/DebugLogManager.cs
Normal file
File diff suppressed because it is too large
Load Diff
12
Assets/DebugConsole/Scripts/DebugLogManager.cs.meta
Normal file
12
Assets/DebugConsole/Scripts/DebugLogManager.cs.meta
Normal file
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6a4f16ed905adcd4ab0d7c8c11f0d72c
|
||||
timeCreated: 1522092746
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: -9869
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
278
Assets/DebugConsole/Scripts/DebugLogPopup.cs
Normal file
278
Assets/DebugConsole/Scripts/DebugLogPopup.cs
Normal file
@ -0,0 +1,278 @@
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
using UnityEngine.UI;
|
||||
#if UNITY_EDITOR && UNITY_2021_1_OR_NEWER
|
||||
using Screen = UnityEngine.Device.Screen; // To support Device Simulator on Unity 2021.1+
|
||||
#endif
|
||||
|
||||
// Manager class for the debug popup
|
||||
namespace IngameDebugConsole
|
||||
{
|
||||
public class DebugLogPopup : MonoBehaviour, IPointerClickHandler, IBeginDragHandler, IDragHandler, IEndDragHandler
|
||||
{
|
||||
// Background image that will change color to indicate an alert
|
||||
private Image backgroundImage;
|
||||
|
||||
// Canvas group to modify visibility of the popup
|
||||
private CanvasGroup canvasGroup;
|
||||
|
||||
// Dimensions of the popup divided by 2
|
||||
private Vector2 halfSize;
|
||||
|
||||
private bool isPopupBeingDragged;
|
||||
|
||||
// Coroutines for simple code-based animations
|
||||
private IEnumerator moveToPosCoroutine;
|
||||
|
||||
// Number of new debug entries since the log window has been closed
|
||||
private int newInfoCount, newWarningCount, newErrorCount;
|
||||
|
||||
private Color normalColor;
|
||||
private Vector2 normalizedPosition;
|
||||
private RectTransform popupTransform;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
popupTransform = (RectTransform)transform;
|
||||
backgroundImage = GetComponent<Image>();
|
||||
canvasGroup = GetComponent<CanvasGroup>();
|
||||
|
||||
normalColor = backgroundImage.color;
|
||||
|
||||
halfSize = popupTransform.sizeDelta * 0.5f;
|
||||
|
||||
var pos = popupTransform.anchoredPosition;
|
||||
if (pos.x != 0f || pos.y != 0f)
|
||||
normalizedPosition = pos.normalized; // Respect the initial popup position set in the prefab
|
||||
else
|
||||
normalizedPosition = new Vector2(0.5f, 0f); // Right edge by default
|
||||
}
|
||||
|
||||
private void Reset()
|
||||
{
|
||||
newInfoCount = 0;
|
||||
newWarningCount = 0;
|
||||
newErrorCount = 0;
|
||||
|
||||
newInfoCountText.text = "0";
|
||||
newWarningCountText.text = "0";
|
||||
newErrorCountText.text = "0";
|
||||
|
||||
backgroundImage.color = normalColor;
|
||||
}
|
||||
|
||||
public void OnBeginDrag(PointerEventData data)
|
||||
{
|
||||
isPopupBeingDragged = true;
|
||||
|
||||
// If a smooth movement animation is in progress, cancel it
|
||||
if (moveToPosCoroutine != null)
|
||||
{
|
||||
StopCoroutine(moveToPosCoroutine);
|
||||
moveToPosCoroutine = null;
|
||||
}
|
||||
}
|
||||
|
||||
// Reposition the popup
|
||||
public void OnDrag(PointerEventData data)
|
||||
{
|
||||
Vector2 localPoint;
|
||||
if (RectTransformUtility.ScreenPointToLocalPointInRectangle(debugManager.canvasTR, data.position,
|
||||
data.pressEventCamera, out localPoint))
|
||||
popupTransform.anchoredPosition = localPoint;
|
||||
}
|
||||
|
||||
// Smoothly translate the popup to the nearest edge
|
||||
public void OnEndDrag(PointerEventData data)
|
||||
{
|
||||
isPopupBeingDragged = false;
|
||||
UpdatePosition(false);
|
||||
}
|
||||
|
||||
// Popup is clicked
|
||||
public void OnPointerClick(PointerEventData data)
|
||||
{
|
||||
// Hide the popup and show the log window
|
||||
if (!isPopupBeingDragged)
|
||||
debugManager.ShowLogWindow();
|
||||
}
|
||||
|
||||
public void NewLogsArrived(int newInfo, int newWarning, int newError)
|
||||
{
|
||||
if (newInfo > 0)
|
||||
{
|
||||
newInfoCount += newInfo;
|
||||
newInfoCountText.text = newInfoCount.ToString();
|
||||
}
|
||||
|
||||
if (newWarning > 0)
|
||||
{
|
||||
newWarningCount += newWarning;
|
||||
newWarningCountText.text = newWarningCount.ToString();
|
||||
}
|
||||
|
||||
if (newError > 0)
|
||||
{
|
||||
newErrorCount += newError;
|
||||
newErrorCountText.text = newErrorCount.ToString();
|
||||
}
|
||||
|
||||
if (newErrorCount > 0)
|
||||
backgroundImage.color = alertColorError;
|
||||
else if (newWarningCount > 0)
|
||||
backgroundImage.color = alertColorWarning;
|
||||
else
|
||||
backgroundImage.color = alertColorInfo;
|
||||
}
|
||||
|
||||
// A simple smooth movement animation
|
||||
private IEnumerator MoveToPosAnimation(Vector2 targetPos)
|
||||
{
|
||||
var modifier = 0f;
|
||||
var initialPos = popupTransform.anchoredPosition;
|
||||
|
||||
while (modifier < 1f)
|
||||
{
|
||||
modifier += 4f * Time.unscaledDeltaTime;
|
||||
popupTransform.anchoredPosition = Vector2.Lerp(initialPos, targetPos, modifier);
|
||||
|
||||
yield return null;
|
||||
}
|
||||
}
|
||||
|
||||
// Hides the log window and shows the popup
|
||||
public void Show()
|
||||
{
|
||||
canvasGroup.blocksRaycasts = true;
|
||||
canvasGroup.alpha = 1f;
|
||||
|
||||
// Reset the counters
|
||||
Reset();
|
||||
|
||||
// Update position in case resolution was changed while the popup was hidden
|
||||
UpdatePosition(true);
|
||||
}
|
||||
|
||||
// Hide the popup
|
||||
public void Hide()
|
||||
{
|
||||
canvasGroup.blocksRaycasts = false;
|
||||
canvasGroup.alpha = 0f;
|
||||
|
||||
isPopupBeingDragged = false;
|
||||
}
|
||||
|
||||
// There are 2 different spaces used in these calculations:
|
||||
// RectTransform space: raw anchoredPosition of the popup that's in range [-canvasSize/2, canvasSize/2]
|
||||
// Safe area space: Screen.safeArea space that's in range [safeAreaBottomLeft, safeAreaTopRight] where these corner positions
|
||||
// are all positive (calculated from bottom left corner of the screen instead of the center of the screen)
|
||||
public void UpdatePosition(bool immediately)
|
||||
{
|
||||
var canvasRawSize = debugManager.canvasTR.rect.size;
|
||||
|
||||
// Calculate safe area bounds
|
||||
var canvasWidth = canvasRawSize.x;
|
||||
var canvasHeight = canvasRawSize.y;
|
||||
|
||||
var canvasBottomLeftX = 0f;
|
||||
var canvasBottomLeftY = 0f;
|
||||
|
||||
if (debugManager.popupAvoidsScreenCutout)
|
||||
{
|
||||
#if UNITY_2017_2_OR_NEWER && ( UNITY_EDITOR || UNITY_ANDROID || UNITY_IOS )
|
||||
var safeArea = Screen.safeArea;
|
||||
|
||||
var screenWidth = Screen.width;
|
||||
var screenHeight = Screen.height;
|
||||
|
||||
canvasWidth *= safeArea.width / screenWidth;
|
||||
canvasHeight *= safeArea.height / screenHeight;
|
||||
|
||||
canvasBottomLeftX = canvasRawSize.x * (safeArea.x / screenWidth);
|
||||
canvasBottomLeftY = canvasRawSize.y * (safeArea.y / screenHeight);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Calculate safe area position of the popup
|
||||
// normalizedPosition allows us to glue the popup to a specific edge of the screen. It becomes useful when
|
||||
// the popup is at the right edge and we switch from portrait screen orientation to landscape screen orientation.
|
||||
// Without normalizedPosition, popup could jump to bottom or top edges instead of staying at the right edge
|
||||
var pos = canvasRawSize * 0.5f + (immediately
|
||||
? new Vector2(normalizedPosition.x * canvasWidth, normalizedPosition.y * canvasHeight)
|
||||
: popupTransform.anchoredPosition - new Vector2(canvasBottomLeftX, canvasBottomLeftY));
|
||||
|
||||
// Find distances to all four edges of the safe area
|
||||
var distToLeft = pos.x;
|
||||
var distToRight = canvasWidth - distToLeft;
|
||||
|
||||
var distToBottom = pos.y;
|
||||
var distToTop = canvasHeight - distToBottom;
|
||||
|
||||
var horDistance = Mathf.Min(distToLeft, distToRight);
|
||||
var vertDistance = Mathf.Min(distToBottom, distToTop);
|
||||
|
||||
// Find the nearest edge's safe area coordinates
|
||||
if (horDistance < vertDistance)
|
||||
{
|
||||
if (distToLeft < distToRight)
|
||||
pos = new Vector2(halfSize.x, pos.y);
|
||||
else
|
||||
pos = new Vector2(canvasWidth - halfSize.x, pos.y);
|
||||
|
||||
pos.y = Mathf.Clamp(pos.y, halfSize.y, canvasHeight - halfSize.y);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (distToBottom < distToTop)
|
||||
pos = new Vector2(pos.x, halfSize.y);
|
||||
else
|
||||
pos = new Vector2(pos.x, canvasHeight - halfSize.y);
|
||||
|
||||
pos.x = Mathf.Clamp(pos.x, halfSize.x, canvasWidth - halfSize.x);
|
||||
}
|
||||
|
||||
pos -= canvasRawSize * 0.5f;
|
||||
|
||||
normalizedPosition.Set(pos.x / canvasWidth, pos.y / canvasHeight);
|
||||
|
||||
// Safe area's bottom left coordinates are added to pos only after normalizedPosition's value
|
||||
// is set because normalizedPosition is in range [-canvasWidth / 2, canvasWidth / 2]
|
||||
pos += new Vector2(canvasBottomLeftX, canvasBottomLeftY);
|
||||
|
||||
// If another smooth movement animation is in progress, cancel it
|
||||
if (moveToPosCoroutine != null)
|
||||
{
|
||||
StopCoroutine(moveToPosCoroutine);
|
||||
moveToPosCoroutine = null;
|
||||
}
|
||||
|
||||
if (immediately)
|
||||
{
|
||||
popupTransform.anchoredPosition = pos;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Smoothly translate the popup to the specified position
|
||||
moveToPosCoroutine = MoveToPosAnimation(pos);
|
||||
StartCoroutine(moveToPosCoroutine);
|
||||
}
|
||||
}
|
||||
|
||||
#pragma warning disable 0649
|
||||
[SerializeField] private DebugLogManager debugManager;
|
||||
|
||||
[SerializeField] private Text newInfoCountText;
|
||||
|
||||
[SerializeField] private Text newWarningCountText;
|
||||
|
||||
[SerializeField] private Text newErrorCountText;
|
||||
|
||||
[SerializeField] private Color alertColorInfo;
|
||||
|
||||
[SerializeField] private Color alertColorWarning;
|
||||
|
||||
[SerializeField] private Color alertColorError;
|
||||
#pragma warning restore 0649
|
||||
}
|
||||
}
|
12
Assets/DebugConsole/Scripts/DebugLogPopup.cs.meta
Normal file
12
Assets/DebugConsole/Scripts/DebugLogPopup.cs.meta
Normal file
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 05cc4b1999716644c9308528e38e7081
|
||||
timeCreated: 1466533184
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
404
Assets/DebugConsole/Scripts/DebugLogRecycledListView.cs
Normal file
404
Assets/DebugConsole/Scripts/DebugLogRecycledListView.cs
Normal file
@ -0,0 +1,404 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
// Handles the log items in an optimized way such that existing log items are
|
||||
// recycled within the list instead of creating a new log item at each chance
|
||||
namespace IngameDebugConsole
|
||||
{
|
||||
public class DebugLogRecycledListView : MonoBehaviour
|
||||
{
|
||||
// Log items used to visualize the debug entries at specified indices
|
||||
private readonly Dictionary<int, DebugLogItem> logItemsAtIndices = new(256);
|
||||
|
||||
// Unique debug entries
|
||||
private List<DebugLogEntry> collapsedLogEntries;
|
||||
|
||||
// Current indices of debug entries shown on screen
|
||||
private int currentTopIndex = -1, currentBottomIndex = -1;
|
||||
private float deltaHeightOfSelectedLogEntry;
|
||||
|
||||
private int indexOfSelectedLogEntry = int.MaxValue;
|
||||
|
||||
// Indices of debug entries to show in collapsedLogEntries
|
||||
private DebugLogIndexList<int> indicesOfEntriesToShow;
|
||||
|
||||
private bool isCollapseOn;
|
||||
|
||||
private float _1OverLogItemHeight;
|
||||
|
||||
internal DebugLogManager manager;
|
||||
private float positionOfSelectedLogEntry = float.MaxValue;
|
||||
private ScrollRect scrollView;
|
||||
private DebugLogIndexList<DebugLogEntryTimestamp> timestampsOfEntriesToShow;
|
||||
private float viewportHeight;
|
||||
|
||||
public float ItemHeight { get; private set; }
|
||||
|
||||
public float SelectedItemHeight { get; private set; }
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
scrollView = viewportTransform.GetComponentInParent<ScrollRect>();
|
||||
scrollView.onValueChanged.AddListener(pos => UpdateItemsInTheList(false));
|
||||
|
||||
viewportHeight = viewportTransform.rect.height;
|
||||
}
|
||||
|
||||
public void Initialize(DebugLogManager manager, List<DebugLogEntry> collapsedLogEntries,
|
||||
DebugLogIndexList<int> indicesOfEntriesToShow,
|
||||
DebugLogIndexList<DebugLogEntryTimestamp> timestampsOfEntriesToShow, float logItemHeight)
|
||||
{
|
||||
this.manager = manager;
|
||||
this.collapsedLogEntries = collapsedLogEntries;
|
||||
this.indicesOfEntriesToShow = indicesOfEntriesToShow;
|
||||
this.timestampsOfEntriesToShow = timestampsOfEntriesToShow;
|
||||
ItemHeight = logItemHeight;
|
||||
_1OverLogItemHeight = 1f / logItemHeight;
|
||||
}
|
||||
|
||||
public void SetCollapseMode(bool collapse)
|
||||
{
|
||||
isCollapseOn = collapse;
|
||||
}
|
||||
|
||||
// A log item is clicked, highlight it
|
||||
public void OnLogItemClicked(DebugLogItem item)
|
||||
{
|
||||
OnLogItemClickedInternal(item.Index, item);
|
||||
}
|
||||
|
||||
// Force expand the log item at specified index
|
||||
public void SelectAndFocusOnLogItemAtIndex(int itemIndex)
|
||||
{
|
||||
if (indexOfSelectedLogEntry != itemIndex) // Make sure that we aren't deselecting the target log item
|
||||
OnLogItemClickedInternal(itemIndex);
|
||||
|
||||
var transformComponentCenterYAtTop = viewportHeight * 0.5f;
|
||||
var transformComponentCenterYAtBottom = transformComponent.sizeDelta.y - viewportHeight * 0.5f;
|
||||
var transformComponentTargetCenterY = itemIndex * ItemHeight + viewportHeight * 0.5f;
|
||||
if (transformComponentCenterYAtTop == transformComponentCenterYAtBottom)
|
||||
scrollView.verticalNormalizedPosition = 0.5f;
|
||||
else
|
||||
scrollView.verticalNormalizedPosition = Mathf.Clamp01(Mathf.InverseLerp(
|
||||
transformComponentCenterYAtBottom, transformComponentCenterYAtTop,
|
||||
transformComponentTargetCenterY));
|
||||
|
||||
manager.SetSnapToBottom(false);
|
||||
}
|
||||
|
||||
private void OnLogItemClickedInternal(int itemIndex, DebugLogItem referenceItem = null)
|
||||
{
|
||||
if (indexOfSelectedLogEntry != itemIndex)
|
||||
{
|
||||
DeselectSelectedLogItem();
|
||||
|
||||
if (!referenceItem)
|
||||
{
|
||||
if (currentTopIndex == -1)
|
||||
UpdateItemsInTheList(
|
||||
false); // Try to generate some DebugLogItems, we need one DebugLogItem to calculate the text height
|
||||
|
||||
referenceItem = logItemsAtIndices[currentTopIndex];
|
||||
}
|
||||
|
||||
indexOfSelectedLogEntry = itemIndex;
|
||||
positionOfSelectedLogEntry = itemIndex * ItemHeight;
|
||||
SelectedItemHeight = referenceItem.CalculateExpandedHeight(
|
||||
collapsedLogEntries[indicesOfEntriesToShow[itemIndex]],
|
||||
timestampsOfEntriesToShow != null ? timestampsOfEntriesToShow[itemIndex] : null);
|
||||
deltaHeightOfSelectedLogEntry = SelectedItemHeight - ItemHeight;
|
||||
|
||||
manager.SetSnapToBottom(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
DeselectSelectedLogItem();
|
||||
}
|
||||
|
||||
if (indexOfSelectedLogEntry >= currentTopIndex && indexOfSelectedLogEntry <= currentBottomIndex)
|
||||
ColorLogItem(logItemsAtIndices[indexOfSelectedLogEntry], indexOfSelectedLogEntry);
|
||||
|
||||
CalculateContentHeight();
|
||||
|
||||
HardResetItems();
|
||||
UpdateItemsInTheList(true);
|
||||
|
||||
manager.ValidateScrollPosition();
|
||||
}
|
||||
|
||||
// Deselect the currently selected log item
|
||||
public void DeselectSelectedLogItem()
|
||||
{
|
||||
var indexOfPreviouslySelectedLogEntry = indexOfSelectedLogEntry;
|
||||
indexOfSelectedLogEntry = int.MaxValue;
|
||||
|
||||
positionOfSelectedLogEntry = float.MaxValue;
|
||||
SelectedItemHeight = deltaHeightOfSelectedLogEntry = 0f;
|
||||
|
||||
if (indexOfPreviouslySelectedLogEntry >= currentTopIndex &&
|
||||
indexOfPreviouslySelectedLogEntry <= currentBottomIndex)
|
||||
ColorLogItem(logItemsAtIndices[indexOfPreviouslySelectedLogEntry], indexOfPreviouslySelectedLogEntry);
|
||||
}
|
||||
|
||||
// Number of debug entries may be changed, update the list
|
||||
public void OnLogEntriesUpdated(bool updateAllVisibleItemContents)
|
||||
{
|
||||
CalculateContentHeight();
|
||||
viewportHeight = viewportTransform.rect.height;
|
||||
|
||||
if (updateAllVisibleItemContents)
|
||||
HardResetItems();
|
||||
|
||||
UpdateItemsInTheList(updateAllVisibleItemContents);
|
||||
}
|
||||
|
||||
// A single collapsed log entry at specified index is updated, refresh its item if visible
|
||||
public void OnCollapsedLogEntryAtIndexUpdated(int index)
|
||||
{
|
||||
DebugLogItem logItem;
|
||||
if (logItemsAtIndices.TryGetValue(index, out logItem))
|
||||
{
|
||||
logItem.ShowCount();
|
||||
|
||||
if (timestampsOfEntriesToShow != null)
|
||||
logItem.UpdateTimestamp(timestampsOfEntriesToShow[index]);
|
||||
}
|
||||
}
|
||||
|
||||
// Log window's width has changed, update the expanded (currently selected) log's height
|
||||
public void OnViewportWidthChanged()
|
||||
{
|
||||
if (indexOfSelectedLogEntry >= indicesOfEntriesToShow.Count)
|
||||
return;
|
||||
|
||||
if (currentTopIndex == -1)
|
||||
{
|
||||
UpdateItemsInTheList(
|
||||
false); // Try to generate some DebugLogItems, we need one DebugLogItem to calculate the text height
|
||||
if (currentTopIndex == -1) // No DebugLogItems are generated, weird
|
||||
return;
|
||||
}
|
||||
|
||||
var referenceItem = logItemsAtIndices[currentTopIndex];
|
||||
|
||||
SelectedItemHeight = referenceItem.CalculateExpandedHeight(
|
||||
collapsedLogEntries[indicesOfEntriesToShow[indexOfSelectedLogEntry]],
|
||||
timestampsOfEntriesToShow != null ? timestampsOfEntriesToShow[indexOfSelectedLogEntry] : null);
|
||||
deltaHeightOfSelectedLogEntry = SelectedItemHeight - ItemHeight;
|
||||
|
||||
CalculateContentHeight();
|
||||
|
||||
HardResetItems();
|
||||
UpdateItemsInTheList(true);
|
||||
|
||||
manager.ValidateScrollPosition();
|
||||
}
|
||||
|
||||
// Log window's height has changed, update the list
|
||||
public void OnViewportHeightChanged()
|
||||
{
|
||||
viewportHeight = viewportTransform.rect.height;
|
||||
UpdateItemsInTheList(false);
|
||||
}
|
||||
|
||||
private void HardResetItems()
|
||||
{
|
||||
if (currentTopIndex != -1)
|
||||
{
|
||||
DestroyLogItemsBetweenIndices(currentTopIndex, currentBottomIndex);
|
||||
currentTopIndex = -1;
|
||||
}
|
||||
}
|
||||
|
||||
private void CalculateContentHeight()
|
||||
{
|
||||
var newHeight = Mathf.Max(1f, indicesOfEntriesToShow.Count * ItemHeight + deltaHeightOfSelectedLogEntry);
|
||||
transformComponent.sizeDelta = new Vector2(0f, newHeight);
|
||||
}
|
||||
|
||||
// Calculate the indices of log entries to show
|
||||
// and handle log items accordingly
|
||||
public void UpdateItemsInTheList(bool updateAllVisibleItemContents)
|
||||
{
|
||||
// If there is at least one log entry to show
|
||||
if (indicesOfEntriesToShow.Count > 0)
|
||||
{
|
||||
var contentPosTop = transformComponent.anchoredPosition.y - 1f;
|
||||
var contentPosBottom = contentPosTop + viewportHeight + 2f;
|
||||
|
||||
if (positionOfSelectedLogEntry <= contentPosBottom)
|
||||
{
|
||||
if (positionOfSelectedLogEntry <= contentPosTop)
|
||||
{
|
||||
contentPosTop -= deltaHeightOfSelectedLogEntry;
|
||||
contentPosBottom -= deltaHeightOfSelectedLogEntry;
|
||||
|
||||
if (contentPosTop < positionOfSelectedLogEntry - 1f)
|
||||
contentPosTop = positionOfSelectedLogEntry - 1f;
|
||||
|
||||
if (contentPosBottom < contentPosTop + 2f)
|
||||
contentPosBottom = contentPosTop + 2f;
|
||||
}
|
||||
else
|
||||
{
|
||||
contentPosBottom -= deltaHeightOfSelectedLogEntry;
|
||||
if (contentPosBottom < positionOfSelectedLogEntry + 1f)
|
||||
contentPosBottom = positionOfSelectedLogEntry + 1f;
|
||||
}
|
||||
}
|
||||
|
||||
var newTopIndex = (int)(contentPosTop * _1OverLogItemHeight);
|
||||
var newBottomIndex = (int)(contentPosBottom * _1OverLogItemHeight);
|
||||
|
||||
if (newTopIndex < 0)
|
||||
newTopIndex = 0;
|
||||
|
||||
if (newBottomIndex > indicesOfEntriesToShow.Count - 1)
|
||||
newBottomIndex = indicesOfEntriesToShow.Count - 1;
|
||||
|
||||
if (currentTopIndex == -1)
|
||||
{
|
||||
// There are no log items visible on screen,
|
||||
// just create the new log items
|
||||
updateAllVisibleItemContents = true;
|
||||
|
||||
currentTopIndex = newTopIndex;
|
||||
currentBottomIndex = newBottomIndex;
|
||||
|
||||
CreateLogItemsBetweenIndices(newTopIndex, newBottomIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
// There are some log items visible on screen
|
||||
|
||||
if (newBottomIndex < currentTopIndex || newTopIndex > currentBottomIndex)
|
||||
{
|
||||
// If user scrolled a lot such that, none of the log items are now within
|
||||
// the bounds of the scroll view, pool all the previous log items and create
|
||||
// new log items for the new list of visible debug entries
|
||||
updateAllVisibleItemContents = true;
|
||||
|
||||
DestroyLogItemsBetweenIndices(currentTopIndex, currentBottomIndex);
|
||||
CreateLogItemsBetweenIndices(newTopIndex, newBottomIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
// User did not scroll a lot such that, there are still some log items within
|
||||
// the bounds of the scroll view. Don't destroy them but update their content,
|
||||
// if necessary
|
||||
if (newTopIndex > currentTopIndex)
|
||||
DestroyLogItemsBetweenIndices(currentTopIndex, newTopIndex - 1);
|
||||
|
||||
if (newBottomIndex < currentBottomIndex)
|
||||
DestroyLogItemsBetweenIndices(newBottomIndex + 1, currentBottomIndex);
|
||||
|
||||
if (newTopIndex < currentTopIndex)
|
||||
{
|
||||
CreateLogItemsBetweenIndices(newTopIndex, currentTopIndex - 1);
|
||||
|
||||
// If it is not necessary to update all the log items,
|
||||
// then just update the newly created log items. Otherwise,
|
||||
// wait for the major update
|
||||
if (!updateAllVisibleItemContents)
|
||||
UpdateLogItemContentsBetweenIndices(newTopIndex, currentTopIndex - 1);
|
||||
}
|
||||
|
||||
if (newBottomIndex > currentBottomIndex)
|
||||
{
|
||||
CreateLogItemsBetweenIndices(currentBottomIndex + 1, newBottomIndex);
|
||||
|
||||
// If it is not necessary to update all the log items,
|
||||
// then just update the newly created log items. Otherwise,
|
||||
// wait for the major update
|
||||
if (!updateAllVisibleItemContents)
|
||||
UpdateLogItemContentsBetweenIndices(currentBottomIndex + 1, newBottomIndex);
|
||||
}
|
||||
}
|
||||
|
||||
currentTopIndex = newTopIndex;
|
||||
currentBottomIndex = newBottomIndex;
|
||||
}
|
||||
|
||||
if (updateAllVisibleItemContents)
|
||||
// Update all the log items
|
||||
UpdateLogItemContentsBetweenIndices(currentTopIndex, currentBottomIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
HardResetItems();
|
||||
}
|
||||
}
|
||||
|
||||
private void CreateLogItemsBetweenIndices(int topIndex, int bottomIndex)
|
||||
{
|
||||
for (var i = topIndex; i <= bottomIndex; i++)
|
||||
CreateLogItemAtIndex(i);
|
||||
}
|
||||
|
||||
// Create (or unpool) a log item
|
||||
private void CreateLogItemAtIndex(int index)
|
||||
{
|
||||
var logItem = manager.PopLogItem();
|
||||
|
||||
// Reposition the log item
|
||||
var anchoredPosition = new Vector2(1f, -index * ItemHeight);
|
||||
if (index > indexOfSelectedLogEntry)
|
||||
anchoredPosition.y -= deltaHeightOfSelectedLogEntry;
|
||||
|
||||
logItem.Transform.anchoredPosition = anchoredPosition;
|
||||
|
||||
// Color the log item
|
||||
ColorLogItem(logItem, index);
|
||||
|
||||
// To access this log item easily in the future, add it to the dictionary
|
||||
logItemsAtIndices[index] = logItem;
|
||||
}
|
||||
|
||||
private void DestroyLogItemsBetweenIndices(int topIndex, int bottomIndex)
|
||||
{
|
||||
for (var i = topIndex; i <= bottomIndex; i++)
|
||||
manager.PoolLogItem(logItemsAtIndices[i]);
|
||||
}
|
||||
|
||||
private void UpdateLogItemContentsBetweenIndices(int topIndex, int bottomIndex)
|
||||
{
|
||||
DebugLogItem logItem;
|
||||
for (var i = topIndex; i <= bottomIndex; i++)
|
||||
{
|
||||
logItem = logItemsAtIndices[i];
|
||||
logItem.SetContent(collapsedLogEntries[indicesOfEntriesToShow[i]],
|
||||
timestampsOfEntriesToShow != null ? timestampsOfEntriesToShow[i] : null, i,
|
||||
i == indexOfSelectedLogEntry);
|
||||
|
||||
if (isCollapseOn)
|
||||
logItem.ShowCount();
|
||||
else
|
||||
logItem.HideCount();
|
||||
}
|
||||
}
|
||||
|
||||
// Color a log item using its index
|
||||
private void ColorLogItem(DebugLogItem logItem, int index)
|
||||
{
|
||||
if (index == indexOfSelectedLogEntry)
|
||||
logItem.Image.color = logItemSelectedColor;
|
||||
else if (index % 2 == 0)
|
||||
logItem.Image.color = logItemNormalColor1;
|
||||
else
|
||||
logItem.Image.color = logItemNormalColor2;
|
||||
}
|
||||
#pragma warning disable 0649
|
||||
// Cached components
|
||||
[SerializeField] private RectTransform transformComponent;
|
||||
|
||||
[SerializeField] private RectTransform viewportTransform;
|
||||
|
||||
[SerializeField] private Color logItemNormalColor1;
|
||||
|
||||
[SerializeField] private Color logItemNormalColor2;
|
||||
|
||||
[SerializeField] private Color logItemSelectedColor;
|
||||
#pragma warning restore 0649
|
||||
}
|
||||
}
|
12
Assets/DebugConsole/Scripts/DebugLogRecycledListView.cs.meta
Normal file
12
Assets/DebugConsole/Scripts/DebugLogRecycledListView.cs.meta
Normal file
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ce231987d32488f43b6fb798f7df43f6
|
||||
timeCreated: 1466373025
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
23
Assets/DebugConsole/Scripts/DebugLogResizeListener.cs
Normal file
23
Assets/DebugConsole/Scripts/DebugLogResizeListener.cs
Normal file
@ -0,0 +1,23 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
|
||||
// Listens to drag event on the DebugLogManager's resize button
|
||||
namespace IngameDebugConsole
|
||||
{
|
||||
public class DebugLogResizeListener : MonoBehaviour, IBeginDragHandler, IDragHandler
|
||||
{
|
||||
#pragma warning disable 0649
|
||||
[SerializeField] private DebugLogManager debugManager;
|
||||
#pragma warning restore 0649
|
||||
|
||||
// This interface must be implemented in order to receive drag events
|
||||
void IBeginDragHandler.OnBeginDrag(PointerEventData eventData)
|
||||
{
|
||||
}
|
||||
|
||||
void IDragHandler.OnDrag(PointerEventData eventData)
|
||||
{
|
||||
debugManager.Resize(eventData);
|
||||
}
|
||||
}
|
||||
}
|
12
Assets/DebugConsole/Scripts/DebugLogResizeListener.cs.meta
Normal file
12
Assets/DebugConsole/Scripts/DebugLogResizeListener.cs.meta
Normal file
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6565f2084f5aef44abe57c988745b9c3
|
||||
timeCreated: 1601221093
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
60
Assets/DebugConsole/Scripts/DebugsOnScrollListener.cs
Normal file
60
Assets/DebugConsole/Scripts/DebugsOnScrollListener.cs
Normal file
@ -0,0 +1,60 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
using UnityEngine.UI;
|
||||
|
||||
// Listens to scroll events on the scroll rect that debug items are stored
|
||||
// and decides whether snap to bottom should be true or not
|
||||
//
|
||||
// Procedure: if, after a user input (drag or scroll), scrollbar is at the bottom, then
|
||||
// snap to bottom shall be true, otherwise it shall be false
|
||||
namespace IngameDebugConsole
|
||||
{
|
||||
public class DebugsOnScrollListener : MonoBehaviour, IScrollHandler, IBeginDragHandler, IEndDragHandler
|
||||
{
|
||||
public ScrollRect debugsScrollRect;
|
||||
public DebugLogManager debugLogManager;
|
||||
|
||||
public void OnBeginDrag(PointerEventData data)
|
||||
{
|
||||
debugLogManager.SetSnapToBottom(false);
|
||||
}
|
||||
|
||||
public void OnEndDrag(PointerEventData data)
|
||||
{
|
||||
if (IsScrollbarAtBottom())
|
||||
debugLogManager.SetSnapToBottom(true);
|
||||
else
|
||||
debugLogManager.SetSnapToBottom(false);
|
||||
}
|
||||
|
||||
public void OnScroll(PointerEventData data)
|
||||
{
|
||||
if (IsScrollbarAtBottom())
|
||||
debugLogManager.SetSnapToBottom(true);
|
||||
else
|
||||
debugLogManager.SetSnapToBottom(false);
|
||||
}
|
||||
|
||||
public void OnScrollbarDragStart(BaseEventData data)
|
||||
{
|
||||
debugLogManager.SetSnapToBottom(false);
|
||||
}
|
||||
|
||||
public void OnScrollbarDragEnd(BaseEventData data)
|
||||
{
|
||||
if (IsScrollbarAtBottom())
|
||||
debugLogManager.SetSnapToBottom(true);
|
||||
else
|
||||
debugLogManager.SetSnapToBottom(false);
|
||||
}
|
||||
|
||||
private bool IsScrollbarAtBottom()
|
||||
{
|
||||
var scrollbarYPos = debugsScrollRect.verticalNormalizedPosition;
|
||||
if (scrollbarYPos <= 1E-6f)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
12
Assets/DebugConsole/Scripts/DebugsOnScrollListener.cs.meta
Normal file
12
Assets/DebugConsole/Scripts/DebugsOnScrollListener.cs.meta
Normal file
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cb564dcb180e586429c57456166a76b5
|
||||
timeCreated: 1466004663
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
59
Assets/DebugConsole/Scripts/EventSystemHandler.cs
Normal file
59
Assets/DebugConsole/Scripts/EventSystemHandler.cs
Normal file
@ -0,0 +1,59 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
using UnityEngine.SceneManagement;
|
||||
|
||||
namespace IngameDebugConsole
|
||||
{
|
||||
// Avoid multiple EventSystems in the scene by activating the embedded EventSystem only if one doesn't already exist in the scene
|
||||
[DefaultExecutionOrder(1000)]
|
||||
public class EventSystemHandler : MonoBehaviour
|
||||
{
|
||||
#pragma warning disable 0649
|
||||
[SerializeField] private GameObject embeddedEventSystem;
|
||||
#pragma warning restore 0649
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
SceneManager.sceneLoaded -= OnSceneLoaded;
|
||||
SceneManager.sceneLoaded += OnSceneLoaded;
|
||||
SceneManager.sceneUnloaded -= OnSceneUnloaded;
|
||||
SceneManager.sceneUnloaded += OnSceneUnloaded;
|
||||
|
||||
ActivateEventSystemIfNeeded();
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
SceneManager.sceneLoaded -= OnSceneLoaded;
|
||||
SceneManager.sceneUnloaded -= OnSceneUnloaded;
|
||||
|
||||
DeactivateEventSystem();
|
||||
}
|
||||
|
||||
private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
|
||||
{
|
||||
#if UNITY_2017_2_OR_NEWER
|
||||
DeactivateEventSystem();
|
||||
#endif
|
||||
ActivateEventSystemIfNeeded();
|
||||
}
|
||||
|
||||
private void OnSceneUnloaded(Scene current)
|
||||
{
|
||||
// Deactivate the embedded EventSystem before changing scenes because the new scene might have its own EventSystem
|
||||
DeactivateEventSystem();
|
||||
}
|
||||
|
||||
private void ActivateEventSystemIfNeeded()
|
||||
{
|
||||
if (embeddedEventSystem && !EventSystem.current)
|
||||
embeddedEventSystem.SetActive(true);
|
||||
}
|
||||
|
||||
private void DeactivateEventSystem()
|
||||
{
|
||||
if (embeddedEventSystem)
|
||||
embeddedEventSystem.SetActive(false);
|
||||
}
|
||||
}
|
||||
}
|
12
Assets/DebugConsole/Scripts/EventSystemHandler.cs.meta
Normal file
12
Assets/DebugConsole/Scripts/EventSystemHandler.cs.meta
Normal file
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c3cc1b407f337e641ad32a2e91d5b478
|
||||
timeCreated: 1658741613
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Reference in New Issue
Block a user