additional package setup

This commit is contained in:
2025-11-16 18:31:17 -05:00
parent 3da42beb46
commit 2ca8077013
55 changed files with 1746 additions and 12 deletions

View File

@@ -0,0 +1,16 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: e651dbb3fbac04af2b8f5abf007ddc23, type: 3}
m_Name: DefaultNetworkPrefabs
m_EditorClassIdentifier: Unity.Netcode.Runtime::Unity.Netcode.NetworkPrefabsList
IsDefault: 1
List: []

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 8c3b36de7a4eff74487a3afe2f72729e
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 322fa5a6c7d5b4b4ea6b8ffcf999a9c7
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,50 @@
fileFormatVersion: 2
guid: 53e4c6b0280fc234ab9d1ff619872df9
labels:
- RoslynAnalyzer
PluginImporter:
externalObjects: {}
serializedVersion: 3
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
Any:
enabled: 0
settings:
Exclude Editor: 1
Exclude Linux64: 1
Exclude OSXUniversal: 1
Exclude Win: 1
Exclude Win64: 1
Editor:
enabled: 0
settings:
DefaultValueInitialized: true
Linux64:
enabled: 0
settings:
CPU: None
OSXUniversal:
enabled: 0
settings:
CPU: None
Win:
enabled: 0
settings:
CPU: None
Win64:
enabled: 0
settings:
CPU: None
WindowsStoreApps:
enabled: 0
settings:
CPU: AnyCPU
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,50 @@
fileFormatVersion: 2
guid: 8102ec9fad25fcd4991c82074c987947
labels:
- RoslynAnalyzer
PluginImporter:
externalObjects: {}
serializedVersion: 3
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
Any:
enabled: 0
settings:
Exclude Editor: 1
Exclude Linux64: 1
Exclude OSXUniversal: 1
Exclude Win: 1
Exclude Win64: 1
Editor:
enabled: 0
settings:
DefaultValueInitialized: true
Linux64:
enabled: 0
settings:
CPU: None
OSXUniversal:
enabled: 0
settings:
CPU: None
Win:
enabled: 0
settings:
CPU: None
Win64:
enabled: 0
settings:
CPU: None
WindowsStoreApps:
enabled: 0
settings:
CPU: AnyCPU
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 1ed2c7f5ecdfb474598a777964327dde
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,39 @@
using System.IO;
using UnityEngine;
public class TALGeneratorSettings : ScriptableObject
{
public string FilePath;
public string FileName;
public int Seconds = 5;
private const string SettingsPath = @"ProjectSettings\TALGeneratorSettings.asset";
private static TALGeneratorSettings _instance;
public static TALGeneratorSettings GetOrCreate()
{
if (_instance == null)
_instance = CreateInstance<TALGeneratorSettings>();
var path = GetPath();
if (!File.Exists(path)) return _instance;
var json = File.ReadAllText(path);
JsonUtility.FromJsonOverwrite(json, _instance);
return _instance;
}
private static string GetPath()
{
var projectPath = Directory.GetParent(Application.dataPath).FullName;
return Path.Combine(projectPath, SettingsPath);
}
public void Save()
{
var json = JsonUtility.ToJson(this, true);
var path = GetPath();
File.WriteAllText(path, json);
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: b3a04823d2914c21a608882e87dc7d70
timeCreated: 1742631304

View File

@@ -0,0 +1,157 @@
using System.Collections.Generic;
using System.IO;
using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;
public class TALGeneratorSettingsProvider : SettingsProvider
{
private TALGeneratorSettings _settings;
public TALGeneratorSettingsProvider(string path, SettingsScope scopes, IEnumerable<string> keywords = null) : base(path, scopes, keywords) { }
[SettingsProvider]
public static SettingsProvider CreateCustomSettingsProvider()
{
return new TALGeneratorSettingsProvider("Project/Tags and Layers Generator", SettingsScope.Project);
}
public override void OnActivate(string searchContext, VisualElement rootElement)
{
_settings = TALGeneratorSettings.GetOrCreate();
var container = new VisualElement
{
style =
{
paddingTop = 10,
paddingLeft = 10,
paddingRight = 10
}
};
var titleLabel = new Label("Tags And Layers Generator Settings")
{
style =
{
fontSize = 14,
unityFontStyleAndWeight = FontStyle.Bold
}
};
container.Add(titleLabel);
var folderPickerRow = new VisualElement
{
style =
{
flexDirection = FlexDirection.Row,
marginBottom = 5
}
};
var folderPathField = new TextField("Selected Path")
{
value = _settings.FilePath,
tooltip = "Select a folder that the generated class will be placed into",
isReadOnly = true,
style =
{
flexGrow = 1
}
};
folderPickerRow.Add(folderPathField);
var button = new Button(() =>
{
var path = EditorUtility.OpenFolderPanel("Select a Folder", Application.dataPath, "");
if (string.IsNullOrWhiteSpace(path) || !IsInAssetFolder(path)) return;
_settings.FilePath = path;
_settings.Save();
folderPathField.value = path;
})
{
text = "Browse",
style =
{
marginLeft = 5
}
};
folderPickerRow.Add(button);
container.Add(folderPickerRow);
var fileNameRow = new VisualElement
{
style =
{
flexDirection = FlexDirection.Row,
marginBottom = 5
}
};
var fileNameField = new TextField("File Name")
{
value = _settings.FileName,
tooltip = "Select a name for the generated file",
style = { flexGrow = 1 }
};
fileNameField.RegisterValueChangedCallback(evt =>
{
_settings.FileName = evt.newValue;
_settings.Save();
});
fileNameRow.Add(fileNameField);
var csLabel = new Label(".cs")
{
style = { marginRight = 10 }
};
fileNameRow.Add(csLabel);
container.Add(fileNameRow);
var buttonRow = new VisualElement()
{
style =
{
flexGrow = 1,
flexDirection = FlexDirection.RowReverse,
justifyContent = new StyleEnum<Justify>(Justify.SpaceBetween),
marginBottom = 5
}
};
var generateButton = new Button(TagAndLayerGenerator.Generate)
{
text = "Manually Generate",
style =
{
flexGrow = 0,
marginRight = 10
}
};
buttonRow.Add(generateButton);
var secondsField = new IntegerField("AutoGenerate Threshold")
{
value = _settings.Seconds,
tooltip = "Minimum number of seconds to wait before allowing auto generation again. Minimum of 5 seconds",
style =
{
minWidth = 30
}
};
secondsField.RegisterValueChangedCallback(evt =>
{
_settings.Seconds = Mathf.Max(evt.newValue, 5);
_settings.Save();
});
buttonRow.Add(secondsField);
container.Add(buttonRow);
rootElement.Add(container);
}
private bool IsInAssetFolder(string path)
{
var fullName = Path.GetFullPath(path);
return fullName.StartsWith(Application.dataPath);
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 49bd8a9472aa46a3b4b3fa44e65a8599
timeCreated: 1742631234

View File

@@ -0,0 +1,99 @@
using System;
using System.IO;
using System.Text;
using UnityEditor;
using UnityEngine;
[InitializeOnLoad]
public static class TagAndLayerGenerator
{
private static readonly FileSystemWatcher _fileSystemWatcher;
static TagAndLayerGenerator()
{
if (_fileSystemWatcher != null) return;
var projectPath = Directory.GetParent(Application.dataPath).FullName;
var path = Path.Combine(projectPath, "ProjectSettings");
_fileSystemWatcher = new FileSystemWatcher(path, "TagManager.asset");
_fileSystemWatcher.NotifyFilter = NotifyFilters.LastWrite;
_fileSystemWatcher.Changed += OnChanged;
_fileSystemWatcher.EnableRaisingEvents = true;
Generate();
}
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
private static void OnChanged(object sender, FileSystemEventArgs e) => OnChanged();
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
private static async Awaitable OnChanged()
{
await Awaitable.MainThreadAsync();
Generate();
}
public static void Generate()
{
var settings = TALGeneratorSettings.GetOrCreate();
if (string.IsNullOrWhiteSpace(settings.FileName) || string.IsNullOrWhiteSpace(settings.FilePath))
return;
var relativeDir = Path.GetRelativePath(Application.dataPath, settings.FilePath);
var path = Path.Combine("Assets", relativeDir, settings.FileName + ".cs");
if (File.Exists(path))
{
var lastEdit = File.GetLastWriteTime(path);
var difference = DateTime.Now.Subtract(lastEdit).TotalSeconds;
if (difference < Mathf.Max(settings.Seconds, 5))
return;
}
AssetDatabase.StartAssetEditing();
var builder = new StringBuilder();
builder.AppendLine("namespace Boxfriend.Generated \n{");
builder.AppendLine(GenerateTags());
builder.AppendLine(GenerateLayers());
builder.AppendLine("}");
File.WriteAllText(path, builder.ToString());
AssetDatabase.StopAssetEditing();
AssetDatabase.ImportAsset(path);
}
private static string GenerateTags()
{
var builder = new StringBuilder();
builder.AppendLine("public static class Tags \n{");
var tags = UnityEditorInternal.InternalEditorUtility.tags;
foreach (var tag in tags)
{
builder.AppendLine($"public const string {tag} = \"{tag}\";");
builder.AppendLine($"public static readonly UnityEngine.TagHandle {tag}Handle = UnityEngine.TagHandle.GetExistingTag({tag});");
}
builder.AppendLine("}");
return builder.ToString();
}
private static string GenerateLayers()
{
var layerBuilder = new StringBuilder();
layerBuilder.AppendLine("public static class Layers \n{");
var maskBuilder = new StringBuilder();
maskBuilder.AppendLine("public static class Mask \n{");
maskBuilder.AppendLine("public const int All = int.MaxValue;\npublic const int None = 0;");
for (var i = 0; i < 32; i++)
{
var name = LayerMask.LayerToName(i);
if (string.IsNullOrWhiteSpace(name))
continue;
name = name.Replace(" ", "");
layerBuilder.AppendLine($"public const string {name} = \"{name}\";");
maskBuilder.AppendLine($"public const int {name} = 1 << {i};");
}
maskBuilder.AppendLine("}");
layerBuilder.Append(maskBuilder);
layerBuilder.AppendLine("}");
return layerBuilder.ToString();
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: c12eb4948b575804b8eaeac6a32ec517

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 1d57bd0548bbaf34ab7a410438a1c879
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 402f66c64d0efe844a7df49bf86a7b6d
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,103 @@
using System;
using System.Collections.Generic;
using UnityEngine;
namespace Boxfriend.Extensions
{
public static class GameObjectExtensions
{
/// <summary>
/// Recursively changes game object and its children to specified layer
/// </summary>
/// <param name="layer">Layer to change all objects to</param>
public static void SetLayerRecursively(this GameObject obj, int layer)
{
obj.layer = layer;
foreach (Transform child in obj.transform)
{
child.gameObject.SetLayerRecursively(layer);
}
}
/// <summary>
/// Returns the first child of the current GameObject that has the specified tag. Does not include itself.
/// </summary>
public static GameObject FindChildWithTag(this GameObject obj, string tag)
{
foreach(Transform child in obj.transform)
{
if(child.gameObject == obj) continue;
if(child.CompareTag(tag))
return child.gameObject;
}
return null;
}
/// <summary>
/// Returns an array containing all children of the current GameObject that have the specified tag. Does not include itself.
/// </summary>
public static GameObject[] FindChildrenWithTag(this GameObject obj, string tag)
{
var taggedArray = new GameObject[obj.transform.childCount];
var index = 0;
foreach(Transform child in obj.transform)
{
if(child.CompareTag(tag))
{
taggedArray[index] = child.gameObject;
index++;
}
}
if(index == 0) return null;
Array.Resize(ref taggedArray, index);
return taggedArray;
}
/// <summary>
/// Returns a List containing all children of the current GameObject that have the specified tag. Does not include itself.
/// </summary>
public static List<GameObject> FindChildrenWithTagList(this GameObject obj, string tag)
{
var taggedList = new List<GameObject>();
foreach(Transform child in obj.transform)
{
if(child.gameObject == obj) continue;
if(child.CompareTag(tag))
taggedList.Add(child.gameObject);
}
return taggedList;
}
/// <summary>
/// Destroys all children of the GameObject not including itself\
/// </summary>
public static void DestroyChildren(this GameObject parent)
{
var children = new Transform[parent.transform.childCount];
for (var i = 0; i < parent.transform.childCount; i++)
children[i] = parent.transform.GetChild(i);
for (var i = 0; i < children.Length; i++)
GameObject.Destroy(children[i].gameObject);
}
///<summary>
/// Checks if a GameObject is tagged with any of the strings in the provided collection
///</summary>
public static bool CompareTags(this GameObject go, IEnumerable<string> tags)
{
foreach (var tag in tags)
{
if (go.CompareTag(tag))
return true;
}
return false;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 70306add1702cb54c8da10e7385f4afd
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,44 @@
using System.Runtime.CompilerServices;
using UnityEngine;
namespace Boxfriend.Extensions
{
public static class MathExtensions
{
/// <summary>
/// Checks if value is within specified range.
/// </summary>
/// <param name="min">Lowest value of the range</param>
/// <param name="max">Largest value of the range</param>
/// <returns>True if less than min and greater than max</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool InRange(this int value, int min, int max) => (value >= min) && (value <= max);
/// <summary>
/// Checks if value is within specified range.
/// </summary>
/// <param name="min">Lowest value of the range</param>
/// <param name="max">Largest value of the range</param>
/// <returns>True if less than min and greater than max</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool InRange(this float value, float min, float max) => (value >= min) && (value <= max);
/// <summary>
/// Checks if value is within specified range.
/// </summary>
/// <param name="min">Lowest value of the range</param>
/// <param name="max">Largest value of the range</param>
/// <returns>True if less than min and greater than max</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool InRange(this double value, double min, double max) => (value >= min) && (value <= max);
public static Vector2 Rotate(this Vector2 vector, float degrees)
{
float sin = Mathf.Sin(degrees * Mathf.Deg2Rad);
float cos = Mathf.Cos(degrees * Mathf.Deg2Rad);
float tx = vector.x;
float ty = vector.y;
vector.x = (cos * tx) - (sin * ty);
vector.y = (sin * tx) + (cos * ty);
return vector;
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 750ee6f30f2644ffa9864f245b532846
timeCreated: 1640819035

View File

@@ -0,0 +1,22 @@
using System.Runtime.CompilerServices;
using UnityEngine;
namespace Boxfriend.Extensions
{
public static class StringExtensions
{
/// <summary>
/// Checks if two strings are the same without case sensitivity.
/// </summary>
/// <param name="value">String being compared</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool CaseInsensitveEquals (this string str, string value) => (str.ToLower() == value.ToLower());
/// <summary>
/// Applies a rich text color to string
/// </summary>
/// <param name="text">String to be colored</param>
/// <param name="col">Unity Color applied to all of 'text'</param>
public static string AddColor(this string text, Color col) => $"<color={ColorHexFromUnityColor(col)}>{text}</color>";
public static string ColorHexFromUnityColor(this Color unityColor) => $"#{ColorUtility.ToHtmlStringRGBA(unityColor)}";
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: ca16c6205a144610a6da0422c8bfa8c0
timeCreated: 1640894511

View File

@@ -0,0 +1,27 @@
using UnityEngine;
namespace Boxfriend.Extensions
{
public static class TransformExtensions
{
public static T GetComponentInInactiveParent<T>(this Transform transform) where T : Component
{
while(transform.parent != null)
{
transform = transform.parent;
if(transform.TryGetComponent(out T comp))
return comp;
}
return null;
}
public static void UnparentAll(this Transform transform)
{
foreach(Transform child in transform)
{
child.UnparentAll();
}
transform.SetParent(null);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f29e0d162e8b8054e86ab1bc8b687c8a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,11 @@
using UnityEngine;
namespace Boxfriend.Extensions
{
public static class Vector2Extensions
{
/// <summary>
/// Changes a Vector2 into a Vector3 where the V2 Y axis is represented on the V3 Z axis
/// </summary>
public static Vector3 To3D(this Vector2 v2) => new Vector3(v2.x, 0, v2.y);
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: a6f23bb55cb64524aca4cf21119a963b
timeCreated: 1641338003

View File

@@ -0,0 +1,14 @@
{
"name": "Utils",
"rootNamespace": "Boxfriend",
"references": [],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 753ee3d76e3343644abe0f9a98da4ded
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 2a3eedd59ab213c4fa2931489a6fe2ac
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,92 @@
using System.Collections;
using UnityEngine;
using UnityEngine.Audio;
namespace Boxfriend.Utils
{
public class AudioManager : SingletonBehaviour<AudioManager>
{
private ObjectPoolCircular<AudioSource> _sources;
[SerializeField] private AudioMixerGroup _audioMixer;
[SerializeField] private AudioSource _sourcePrefab;
private const string _inWaitingName = "AudioManager - Ready";
private void Awake () => _sources = new ObjectPoolCircular<AudioSource>(Create, x => x.enabled = true, ReturnSource, DestroySource, 32);
private AudioSource Create ()
{
AudioSource source;
if (_sourcePrefab == null)
{
var go = new GameObject
{
name = _inWaitingName
};
go.transform.parent = transform;
source = go.AddComponent<AudioSource>();
} else
{
source = Instantiate(_sourcePrefab, Vector3.zero, Quaternion.identity);
}
source.outputAudioMixerGroup = _audioMixer;
source.enabled = false;
return source;
}
private AudioSource GetSource (string clipName, Vector3 position)
{
var source = _sources.FromPool();
source.name = $"AudioManager - Playing: {clipName}";
source.transform.position = position;
return source;
}
private void ReturnSource (AudioSource source)
{
source.name = _inWaitingName;
source.clip = null;
#if UNITY_2023_2_OR_NEWER
source.resource = null;
#endif
source.enabled = false;
}
private void DestroySource (AudioSource source) => Destroy(source.gameObject);
public void PlayOneShot (AudioClip clip, float volume = 1f) => PlayOneShot(clip, Vector3.zero, volume);
public void PlayOneShot (AudioClip clip, Vector3 position, float volume = 1f)
{
var source = GetSource(clip.name, position);
source.PlayOneShot(clip, volume);
StartCoroutine(ReturnWhenDone(source));
}
#if !UNITY_2023_2_OR_NEWER
public void Play (AudioClip clip) => Play(clip, Vector3.zero);
public void Play (AudioClip clip, Vector3 position)
{
var source = GetSource(clip.name, position);
source.clip = clip;
source.Play();
StartCoroutine(ReturnWhenDone(source));
}
#else
public void Play (AudioResource resource) => Play(resource, Vector3.zero);
public void Play(AudioResource resource, Vector3 position)
{
var source = GetSource(resource.name, position);
source.resource = resource;
source.Play();
StartCoroutine(ReturnWhenDone(source));
}
#endif
private IEnumerator ReturnWhenDone (AudioSource source)
{
yield return new WaitUntil(() => !source.isPlaying);
_sources.ToPool(source);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 83b4266b5af7b0e43bdc7a1b68fc823d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,59 @@
using System;
using System.Collections.Generic;
namespace Boxfriend.Utils
{
public class EventManager : Singleton<EventManager>
{
public delegate void Event(object arg, object sender);
private readonly Dictionary<string, Event> _events = new ();
public void RegisterEvent(string name)
{
if (_events.ContainsKey(name))
throw new ArgumentException($"Event {name} already registered");
_events.Add(name, null);
}
public void RegisterEvent (string name, Event callback)
{
if (_events.ContainsKey(name))
throw new ArgumentException($"Event {name} already registered");
_events.Add(name, callback);
}
public void UnregisterEvent(string name)
{
if (!_events.ContainsKey(name))
throw new ArgumentException($"Event {name} not registered");
_events.Remove(name);
}
public void SubscribeEvent (string name, Event callback)
{
if (!_events.ContainsKey(name))
throw new ArgumentException($"Event {name} not registered");
_events[name] += callback ?? throw new ArgumentNullException($"Event {name} callback is null");
}
public void UnsubscribeEvent (string name, Event callback)
{
if (!_events.ContainsKey(name))
throw new ArgumentException($"Event {name} not registered");
_events[name] -= callback ?? throw new ArgumentNullException($"Event {name} callback is null");
}
public void InvokeEvent (string name, object arg, object sender)
{
if (!_events.ContainsKey(name))
throw new ArgumentException($"Event {name} not registered");
_events[name]?.Invoke(arg, sender);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 11ec534d1045abc468621d74f78bfe8e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,7 @@
using System;
///<summary>
/// Indicates a variable should only be assigned to in the inspector. Also allowed are field initializers and assignment in unity's Reset method.
/// Requires Boxfriend.Analyzers to function.
///</summary>
public class InspectorOnlyAttribute : Attribute { }

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 0c345dad59be440eadbaa7290ff86835

View File

@@ -0,0 +1,97 @@
using System;
using System.Collections.Generic;
namespace Boxfriend.Utils
{
/// <summary>
/// Pools objects of type T, will create new objects as necessary
/// </summary>
public class ObjectPool<T> where T : class
{
private readonly Stack<T> _stack = new ();
private readonly Func<T> _objectCreator;
private readonly Action<T> _returnObjectToPool, _getObjectFromPool, _destroyObject;
private readonly int _maxSize;
/// <summary>
/// Number of objects currently in the pool.
/// </summary>
public int Count => _stack.Count;
/// <param name="createObject">Creates and returns an object of the specified type.</param>
/// <param name="getObjectFromPool">Action called on object when pulled from the pool or created.</param>
/// <param name="returnObjectToPool">Action called on object when returned to pool.</param>
/// <param name="onDestroyObject">Action called on object when it is to be destroyed. Can be null</param>
/// <param name="defaultSize">Number of objects to immediately add to the pool</param>
/// <param name="maxSize">Maximum number of objects in the pool</param>
/// <exception cref="ArgumentOutOfRangeException"></exception>
/// <exception cref="ArgumentNullException"></exception>
public ObjectPool (Func<T> createObject, Action<T> getObjectFromPool, Action<T> returnObjectToPool, Action<T> onDestroyObject = null, int defaultSize = 10, int maxSize = 100)
{
if (maxSize < defaultSize)
throw new ArgumentOutOfRangeException(nameof(maxSize), "maxSize must be greater than or equal to defaultSize");
if (defaultSize < 0)
throw new ArgumentOutOfRangeException(nameof(defaultSize), "defaultSize must be greater than or equal to 0");
_returnObjectToPool = returnObjectToPool ?? throw new ArgumentNullException(nameof(returnObjectToPool));
_getObjectFromPool = getObjectFromPool ?? throw new ArgumentNullException(nameof(getObjectFromPool));
_objectCreator = createObject ?? throw new ArgumentNullException(nameof(createObject));
_destroyObject = onDestroyObject;
_maxSize = maxSize;
for (var i = 0; i < defaultSize; i++)
{
ToPool(_objectCreator());
}
}
/// <summary>
/// Gets an object from the pool or creates a new one if the pool is empty. Calls <see langword="Action"/> <see cref="_getObjectFromPool"/> on the object
/// </summary>
public T FromPool ()
{
var poolObject = _stack.Count > 0 ? _stack.Pop() : _objectCreator();
_getObjectFromPool(poolObject);
return poolObject;
}
/// <summary>
/// Adds an item to the pool and calls <see langword="Action"/> <see cref="_returnObjectToPool"/> on it
/// </summary>
/// <param name="item">Item to be added</param>
public void ToPool (T item)
{
if (item == null) throw new ArgumentNullException(nameof(item));
_returnObjectToPool(item);
if(_stack.Count >= _maxSize)
{
_destroyObject?.Invoke(item);
return;
}
_stack.Push(item);
}
/// <summary>
/// Removes all items from the pool, calling <see langword="Action"/> <see cref="_destroyObject"/> on it if not null.
/// </summary>
public void EmptyPool()
{
if(_destroyObject is null)
{
_stack.Clear();
return;
}
while(_stack.Count > 0)
{
var obj = _stack.Pop();
_destroyObject(obj);
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d79c194a0d7106f4dae9d2b503bae707
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,145 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace Boxfriend.Utils
{
/// <summary>
/// Pools a specific number of objects, will reuse oldest active objects when all objects are in use.
/// </summary>
public class ObjectPoolCircular<T> where T : class
{
private Queue<T> _activeQueue, _inactiveQueue;
private readonly Func<T> _objectCreator;
private readonly Action<T> _returnObjectToPool, _getObjectFromPool, _destroyObject;
private readonly int _size;
/// <summary>
/// Total number of objects in the pool.
/// </summary>
public int Count => _size;
/// <summary>
/// Total number of currently active pooled objects
/// </summary>
public int ActiveCount => _activeQueue.Count;
/// <summary>
/// Total number of currently inactive pooled objects
/// </summary>
public int InactiveCount => _inactiveQueue.Count;
/// <param name="createObject">Creates and returns an object of the specified type.</param>
/// <param name="getObjectFromPool">Action called on object when pulled from the pool or created.</param>
/// <param name="returnObjectToPool">Action called on object when returned to pool.</param>
/// <param name="onDestroyObject">Action called on object when it is to be destroyed. Can be null</param>
/// <param name="size">Total number of objects in the pool</param>
/// <exception cref="ArgumentOutOfRangeException">Size must be greater than zero</exception>
/// <exception cref="ArgumentNullException"></exception>
public ObjectPoolCircular (Func<T> createObject, Action<T> getObjectFromPool, Action<T> returnObjectToPool, Action<T> onDestroyObject = null, int size = 100)
{
if (size <= 0)
throw new ArgumentOutOfRangeException(nameof(size), "size must be greater than zero");
_returnObjectToPool = returnObjectToPool ?? throw new ArgumentNullException(nameof(returnObjectToPool));
_getObjectFromPool = getObjectFromPool ?? throw new ArgumentNullException(nameof(getObjectFromPool));
_objectCreator = createObject ?? throw new ArgumentNullException(nameof(createObject));
_destroyObject = onDestroyObject;
_size = size;
_inactiveQueue = new(size);
_activeQueue = new(size);
for (var i = 0; i < size; i++)
{
var obj = _objectCreator();
_returnObjectToPool(obj);
_inactiveQueue.Enqueue(obj);
}
}
/// <summary>
/// Gets an object from the pool or reuses the oldest active object if all pooled objects are in use. Calls <see langword="Action"/> <see cref="_getObjectFromPool"/> on the object
/// Will call <see langword="Action"/> <see cref="_returnObjectToPool"/> if reusing an active object.
/// </summary>
public T FromPool ()
{
if(_inactiveQueue.Count + _activeQueue.Count == 0)
throw new InvalidOperationException("Object pool has been cleared, there is nothing left to get");
T poolObject;
if(_inactiveQueue.Count == 0)
{
poolObject = _activeQueue.Dequeue();
_returnObjectToPool(poolObject);
}
else
{
poolObject = _inactiveQueue.Dequeue();
}
_getObjectFromPool(poolObject);
_activeQueue.Enqueue(poolObject);
return poolObject;
}
/// <summary>
/// Adds an item to the pool and calls <see langword="Action"/> <see cref="_returnObjectToPool"/> on it
/// Generates garbage if item is not the oldest object pulled from the pool
/// </summary>
/// <param name="item">Item to be added</param>
public void ToPool (T item)
{
if (item == null) throw new ArgumentNullException(nameof(item));
if(_activeQueue.Peek() == item)
_activeQueue.Dequeue();
else
_activeQueue = new Queue<T>(_activeQueue.Where(x => x != item));
_returnObjectToPool(item);
_inactiveQueue.Enqueue(item);
}
/// <summary>
/// Returns all active items to the inactive queue
/// </summary>
public void ReturnAllToPool()
{
while(ActiveCount > 0)
{
var obj = _activeQueue.Dequeue();
_returnObjectToPool(obj);
_inactiveQueue.Enqueue(obj);
}
}
/// <summary>
/// Removes all items from the pool, calling <see langword="Action"/> <see cref="_destroyObject"/> on it if not null.
/// Does not call <see langword="Action"/> <see cref="_returnObjectToPool"/>.
/// </summary>
public void EmptyPool()
{
if(_destroyObject is null)
{
_activeQueue.Clear();
_inactiveQueue.Clear();
return;
}
while(_activeQueue.Count > 0)
{
var obj = _activeQueue.Dequeue();
_destroyObject(obj);
}
while(_inactiveQueue.Count > 0)
{
var obj = _inactiveQueue.Dequeue();
_destroyObject(obj);
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c9d2a88b19aa9ad4ab0b9adb718f2a0a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,81 @@
using UnityEngine;
namespace Boxfriend.Utils
{
/// <summary>
/// Class to draw debug information such as physics2d casts
/// </summary>
public static class PhysicsCastDebug
{
/// <summary>
/// Casts a Physics2D BoxCast with debug lines drawn
/// </summary>
public static RaycastHit2D BoxCast(Vector2 origin,
Vector2 size,
float angle,
Vector2 direction,
float distance = 0,
int layerMask = Physics2D.AllLayers,
float minDepth = -Mathf.Infinity,
float maxDepth = Mathf.Infinity)
{
var hit = Physics2D.BoxCast(origin, size, angle, direction, distance, layerMask, minDepth, maxDepth);
//Setting up the points to draw the origin box and end box
var points = new Vector2[8];
var width = size.x * 0.5f;
var height = size.y * 0.5f;
points[0] = new Vector2(-width, height); //Upper left corner
points[1] = new Vector2(width, height); //Upper right corner
points[2] = new Vector2(width, -height); //Lower right corner
points[3] = new Vector2(-width, -height); //Lower left corner
//Calculates origin box corners using provided angle and origin point
var q = Quaternion.AngleAxis(angle, new Vector3(0, 0, 1));
for (var i = 0; i < 4; i++)
{
points[i] = q * points[i];
points[i] += origin;
}
//Calculates end points using origin box points and provided distance
var realDistance = direction.normalized * distance;
for (var i = 0; i < 4; i++)
{
points[i + 4] = points[i] + realDistance;
}
//Draw hit normal if a hit was detected
if (hit) Debug.DrawLine(hit.point, hit.point + hit.normal.normalized*0.2f, Color.yellow);
//Draw boxes
var color = hit ? Color.green : Color.red;
for (var i = 0; i < 4; i++)
{
var j = i == 3 ? 0 : i + 1;
//Draws origin box using first 4 points
Debug.DrawLine(points[i],points[j], color);
}
//Exit early if distance is 0, don't need to draw end position or translation if there is no distance
if (distance == 0) return hit;
//Draws end box using last 4 points
for (var i = 0; i < 4; i++)
{
var j = i == 3 ? 0 : i + 1;
Debug.DrawLine(points[i+4],points[j+4], color);
}
//Shows translation from origin box to end box in grey
for (var i = 0; i < 4; i++)
{
var j = i + 4;
Debug.DrawLine(points[i],points[j], Color.grey);
}
return hit;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 749412a4d084e6d43902f628e84d38e7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,14 @@
using System;
namespace Boxfriend.Utils
{
public abstract class Singleton<T> where T : class, new()
{
public static T Instance => _instance;
private static T _instance;
private static T InitializeSingleton (T obj = null) => _instance = obj ?? new T();
public Singleton():this(null){}
public Singleton (T obj) => InitializeSingleton(obj);
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: d5aa066b76ef4b48b79d2921c301f50f
timeCreated: 1640819249

View File

@@ -0,0 +1,40 @@
using UnityEngine;
namespace Boxfriend.Utils
{
public abstract class SingletonBehaviour<T> : MonoBehaviour where T : SingletonBehaviour<T>
{
private static T _instance;
[SerializeField] protected bool _dontDestroy;
public static T Instance
{
get
{
if( _instance == null )
{
var go = new GameObject(typeof(T).Name);
go.AddComponent<T>();
}
return _instance;
}
private set
{
if (_instance == null)
_instance = value;
else if (value != _instance)
Destroy(value.gameObject);
}
}
protected virtual void __internalAwake ()
{
Instance = (T)this;
if(_dontDestroy)
DontDestroyOnLoad(gameObject);
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: a532c8d866cc4ff1a614091cc5e3c80b
timeCreated: 1640820898

View File

@@ -0,0 +1,89 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Boxfriend.Utils
{
/// <summary>
/// Simple timer class that will call an action on timer complete
/// </summary>
public class TimerUtil
{
public static TimerUtil Timer (Action action, float time, string name = "TimerObject")
{
GameObject timerObj = new GameObject(name, typeof(TimerMonoBehaviour));
TimerUtil timerUtil = new TimerUtil(action, time, timerObj);
timerObj.GetComponent<TimerMonoBehaviour>().onUpdate = timerUtil.UpdateTimer;
return timerUtil;
}
private class TimerMonoBehaviour : MonoBehaviour
{
public Action onUpdate;
private void Update ()
{
onUpdate();
}
}
private Action _act;
private float _time;
private GameObject _timerObj;
public bool isEnded { get; private set; }
public bool isPaused { get; set; }
public float TimeRemaining => _time;
private TimerUtil (Action action, float time, GameObject timerObj)
{
_act = action;
_time = time;
_timerObj = timerObj;
//Ensuring the bools are correctly initialized as false
isEnded = false;
isPaused = false;
}
private void UpdateTimer ()
{
if (isEnded || isPaused) return;
_time -= Time.deltaTime;
if (_time <= 0)
{
EndWithAction();
}
}
/// <summary>
/// Ends the timer and destroys associated GameObject. Cannot be undone
/// </summary>
public void EndTimer ()
{
isEnded = true;
UnityEngine.Object.Destroy(_timerObj);
}
/// <summary>
/// Ends the timer and invokes its action. Cannot be undone.
/// </summary>
public void EndWithAction ()
{
_act();
EndTimer();
}
/// <summary>
/// Adds specified time to the currently active timer
/// </summary>
public void AddTime (float time)
{
if (isEnded) return;
_time += time;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2f923888d5435594a9fd44c8ba579913
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,36 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Boxfriend.Utils
{
/// <summary>
/// Random useful methods
/// </summary>
public class Utils
{
/// <summary>
/// Determines if the supplied ints have opposite signs
/// </summary>
public static bool OppositeSigns (int x, int y)
{
return ((x ^ y) < 0);
}
/// <summary>
/// Formats number of bytes to string
/// </summary>
public static string FormatBytes(long bytes)
{
string[] Suffix = {"B", "KB", "MB", "GB", "TB"};
int i;
double dblSByte = bytes;
for (i = 0; i < Suffix.Length && bytes >= 1000; i++, bytes /= 1000)
{
dblSByte = bytes / 1000.0;
}
return $"{dblSByte:0.##} {Suffix[i]}";
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: cca214112e1e41a48b15b4b1e145cbd4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,14 @@
{
"name": "com.boxfriend.utils",
"displayName": "Boxfriend's Utils",
"version": "2.0.0",
"unity": "6000.0",
"author": {
"name": "Boxfriend",
"url": "https://github.com/boxfriend"
},
"publishConfig": {
"registry": "https://package.openupm.com"
},
"_fingerprint": "58cc9986a36bd339d892e23f0bf8d7d08d69b8e5"
}

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: d291b57ec95daa04c81dad42a2f06e7f
PackageManifestImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,16 +1,24 @@
{
"dependencies": {
"com.boxfriend.utils": "2.0.0",
"com.unity.addressables": "2.7.4",
"com.unity.ai.navigation": "2.0.9",
"com.unity.collab-proxy": "2.10.0",
"com.unity.behavior": "1.0.13",
"com.unity.cinemachine": "3.1.5",
"com.unity.ide.rider": "3.0.38",
"com.unity.ide.visualstudio": "2.0.25",
"com.unity.inputsystem": "1.15.0",
"com.unity.multiplayer.center": "1.0.0",
"com.unity.multiplayer.tools": "2.2.6",
"com.unity.netcode.gameobjects": "2.7.0",
"com.unity.project-auditor-rules": "1.0.1",
"com.unity.render-pipelines.universal": "17.4.0",
"com.unity.test-framework": "1.6.0",
"com.unity.timeline": "1.8.9",
"com.unity.ugui": "2.0.0",
"com.unity.visualeffectgraph": "17.4.0",
"com.unity.visualscripting": "1.9.9",
"com.vertx.debugging": "3.0.0",
"com.unity.modules.accessibility": "1.0.0",
"com.unity.modules.adaptiveperformance": "1.0.0",
"com.unity.modules.ai": "1.0.0",
@@ -45,5 +53,15 @@
"com.unity.modules.vr": "1.0.0",
"com.unity.modules.wind": "1.0.0",
"com.unity.modules.xr": "1.0.0"
}
},
"scopedRegistries": [
{
"name": "OpenUPM",
"url": "https://package.openupm.com",
"scopes": [
"com.vertx",
"com.boxfriend"
]
}
]
}

View File

@@ -1,5 +1,27 @@
{
"dependencies": {
"com.boxfriend.utils": {
"version": "file:com.boxfriend.utils@58cc9986a36b",
"depth": 0,
"source": "embedded",
"dependencies": {}
},
"com.unity.addressables": {
"version": "2.7.4",
"depth": 0,
"source": "registry",
"dependencies": {
"com.unity.profiling.core": "1.0.2",
"com.unity.test-framework": "1.4.5",
"com.unity.modules.assetbundle": "1.0.0",
"com.unity.modules.jsonserialize": "1.0.0",
"com.unity.modules.imageconversion": "1.0.0",
"com.unity.modules.unitywebrequest": "1.0.0",
"com.unity.scriptablebuildpipeline": "2.4.3",
"com.unity.modules.unitywebrequestassetbundle": "1.0.0"
},
"url": "https://packages.unity.com"
},
"com.unity.ai.navigation": {
"version": "2.0.9",
"depth": 0,
@@ -9,9 +31,26 @@
},
"url": "https://packages.unity.com"
},
"com.unity.behavior": {
"version": "1.0.13",
"depth": 0,
"source": "registry",
"dependencies": {
"com.unity.burst": "1.7.2",
"com.unity.dt.app-ui": "2.0.0",
"com.unity.modules.ai": "1.0.0",
"com.unity.collections": "2.1.4",
"com.unity.modules.audio": "1.0.0",
"com.unity.modules.animation": "1.0.0",
"com.unity.nuget.newtonsoft-json": "3.2.1",
"com.unity.modules.particlesystem": "1.0.0",
"com.unity.modules.unitywebrequest": "1.0.0"
},
"url": "https://packages.unity.com"
},
"com.unity.burst": {
"version": "1.8.25",
"depth": 2,
"depth": 1,
"source": "registry",
"dependencies": {
"com.unity.mathematics": "1.2.1",
@@ -19,16 +58,19 @@
},
"url": "https://packages.unity.com"
},
"com.unity.collab-proxy": {
"version": "2.10.0",
"com.unity.cinemachine": {
"version": "3.1.5",
"depth": 0,
"source": "registry",
"dependencies": {},
"dependencies": {
"com.unity.splines": "2.0.0",
"com.unity.modules.imgui": "1.0.0"
},
"url": "https://packages.unity.com"
},
"com.unity.collections": {
"version": "6.4.0",
"depth": 2,
"depth": 1,
"source": "builtin",
"dependencies": {
"com.unity.burst": "1.8.23",
@@ -38,6 +80,18 @@
"com.unity.test-framework.performance": "3.0.3"
}
},
"com.unity.dt.app-ui": {
"version": "2.1.1",
"depth": 1,
"source": "registry",
"dependencies": {
"com.unity.modules.physics": "1.0.0",
"com.unity.modules.androidjni": "1.0.0",
"com.unity.modules.uielements": "1.0.0",
"com.unity.modules.screencapture": "1.0.0"
},
"url": "https://packages.unity.com"
},
"com.unity.ext.nunit": {
"version": "2.0.5",
"depth": 1,
@@ -73,7 +127,7 @@
},
"com.unity.mathematics": {
"version": "1.3.3",
"depth": 2,
"depth": 1,
"source": "registry",
"dependencies": {},
"url": "https://packages.unity.com"
@@ -86,9 +140,55 @@
"com.unity.modules.uielements": "1.0.0"
}
},
"com.unity.multiplayer.tools": {
"version": "2.2.6",
"depth": 0,
"source": "registry",
"dependencies": {
"com.unity.burst": "1.8.18",
"com.unity.collections": "2.5.1",
"com.unity.mathematics": "1.3.2",
"com.unity.profiling.core": "1.0.2",
"com.unity.nuget.mono-cecil": "1.11.4",
"com.unity.modules.uielements": "1.0.0",
"com.unity.nuget.newtonsoft-json": "3.2.1"
},
"url": "https://packages.unity.com"
},
"com.unity.netcode.gameobjects": {
"version": "2.7.0",
"depth": 0,
"source": "registry",
"dependencies": {
"com.unity.transport": "2.6.0",
"com.unity.nuget.mono-cecil": "1.11.4"
},
"url": "https://packages.unity.com"
},
"com.unity.nuget.mono-cecil": {
"version": "1.11.6",
"depth": 3,
"depth": 1,
"source": "registry",
"dependencies": {},
"url": "https://packages.unity.com"
},
"com.unity.nuget.newtonsoft-json": {
"version": "3.2.1",
"depth": 1,
"source": "registry",
"dependencies": {},
"url": "https://packages.unity.com"
},
"com.unity.profiling.core": {
"version": "1.0.3",
"depth": 1,
"source": "registry",
"dependencies": {},
"url": "https://packages.unity.com"
},
"com.unity.project-auditor-rules": {
"version": "1.0.1",
"depth": 0,
"source": "registry",
"dependencies": {},
"url": "https://packages.unity.com"
@@ -124,6 +224,16 @@
"com.unity.render-pipelines.core": "17.4.0"
}
},
"com.unity.scriptablebuildpipeline": {
"version": "2.4.3",
"depth": 1,
"source": "registry",
"dependencies": {
"com.unity.test-framework": "1.4.5",
"com.unity.modules.assetbundle": "1.0.0"
},
"url": "https://packages.unity.com"
},
"com.unity.searcher": {
"version": "4.9.4",
"depth": 2,
@@ -131,6 +241,13 @@
"dependencies": {},
"url": "https://packages.unity.com"
},
"com.unity.settings-manager": {
"version": "2.1.1",
"depth": 2,
"source": "registry",
"dependencies": {},
"url": "https://packages.unity.com"
},
"com.unity.shadergraph": {
"version": "17.4.0",
"depth": 1,
@@ -140,6 +257,17 @@
"com.unity.searcher": "4.9.3"
}
},
"com.unity.splines": {
"version": "2.8.2",
"depth": 1,
"source": "registry",
"dependencies": {
"com.unity.mathematics": "1.2.1",
"com.unity.modules.imgui": "1.0.0",
"com.unity.settings-manager": "1.0.3"
},
"url": "https://packages.unity.com"
},
"com.unity.test-framework": {
"version": "1.6.0",
"depth": 0,
@@ -152,7 +280,7 @@
},
"com.unity.test-framework.performance": {
"version": "3.2.0",
"depth": 3,
"depth": 2,
"source": "registry",
"dependencies": {
"com.unity.test-framework": "1.1.33",
@@ -165,13 +293,24 @@
"depth": 0,
"source": "registry",
"dependencies": {
"com.unity.modules.audio": "1.0.0",
"com.unity.modules.director": "1.0.0",
"com.unity.modules.animation": "1.0.0",
"com.unity.modules.audio": "1.0.0",
"com.unity.modules.particlesystem": "1.0.0"
},
"url": "https://packages.unity.com"
},
"com.unity.transport": {
"version": "2.6.0",
"depth": 1,
"source": "registry",
"dependencies": {
"com.unity.burst": "1.8.24",
"com.unity.collections": "2.2.1",
"com.unity.mathematics": "1.3.2"
},
"url": "https://packages.unity.com"
},
"com.unity.ugui": {
"version": "2.0.0",
"depth": 0,
@@ -181,6 +320,15 @@
"com.unity.modules.imgui": "1.0.0"
}
},
"com.unity.visualeffectgraph": {
"version": "17.4.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.shadergraph": "17.4.0",
"com.unity.render-pipelines.core": "17.4.0"
}
},
"com.unity.visualscripting": {
"version": "1.9.9",
"depth": 0,
@@ -191,6 +339,17 @@
},
"url": "https://packages.unity.com"
},
"com.vertx.debugging": {
"version": "3.0.0",
"depth": 0,
"source": "registry",
"dependencies": {
"com.unity.collections": "2.1.0-exp.4",
"com.unity.burst": "1.8.8",
"com.unity.mathematics": "1.3.1"
},
"url": "https://package.openupm.com"
},
"com.unity.modules.accessibility": {
"version": "1.0.0",
"depth": 0,

View File

@@ -30,7 +30,19 @@ MonoBehaviour:
m_Compliance:
m_Status: 0
m_Violations: []
m_UserSelectedRegistryName:
- m_Id: scoped:project:OpenUPM
m_Name: OpenUPM
m_Url: https://package.openupm.com
m_Scopes:
- com.vertx
- com.boxfriend
m_IsDefault: 0
m_Capabilities: 0
m_ConfigSource: 4
m_Compliance:
m_Status: 0
m_Violations: []
m_UserSelectedRegistryName: OpenUPM
m_UserAddingNewScopedRegistry: 0
m_RegistryInfoDraft:
m_Modified: 0

View File

@@ -0,0 +1,53 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &1
MonoBehaviour:
m_ObjectHideFlags: 53
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 0}
m_Name:
m_EditorClassIdentifier: UnityEditor.ProjectAuditorModule:Unity.ProjectAuditor.Editor:ProjectAuditorSettings
Rules:
rules: []
DiagnosticParams:
paramsStack:
- PlatformGroup:
m_String: Unknown
m_SerializedParams:
- Key: StreamingClipThresholdBytes
Value: 218294
- Key: LongDecompressedClipThresholdBytes
Value: 204800
- Key: LongCompressedMobileClipThresholdBytes
Value: 204800
- Key: LoadInBackGroundClipSizeThresholdBytes
Value: 204800
- Key: TextureStreamingMipmapsSizeLimit
Value: 4000
- Key: SpriteAtlasEmptySpaceLimit
Value: 50
- Key: StreamingAssetsFolderSizeLimit
Value: 50
- PlatformGroup:
m_String: Standalone
m_SerializedParams:
- Key: StreamingClipThresholdBytes
Value: 218294
- Key: LongDecompressedClipThresholdBytes
Value: 204800
- Key: LongCompressedMobileClipThresholdBytes
Value: 204800
- Key: LoadInBackGroundClipSizeThresholdBytes
Value: 204800
- Key: TextureStreamingMipmapsSizeLimit
Value: 4000
- Key: SpriteAtlasEmptySpaceLimit
Value: 50
- Key: StreamingAssetsFolderSizeLimit
Value: 50
CurrentParamsIndex: 0