initial commit

This commit is contained in:
Jo 2025-01-07 02:06:59 +01:00
parent 6715289efe
commit 788c3389af
37645 changed files with 2526849 additions and 80 deletions

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7190f0f4bf89e7941935e6a0f8286a46
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 51e2403142d7ff741bcee103c16da7c1, type: 3}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,58 @@
using Unity.Profiling;
using UnityEngine;
#if UNITY_EDITOR
using Unity.Profiling.Editor;
#endif
namespace SLZ.Marrow.Warehouse
{
public static class AssetWarehouseMetrics
{
public static readonly ProfilerCategory AssetWarehouseCategory = ProfilerCategory.Scripts;
public const string LoadedScannableCountName = "Loaded Scannables";
public static readonly ProfilerCounterValue<int> LoadedScannableCount = new ProfilerCounterValue<int>(AssetWarehouseCategory, LoadedScannableCountName, ProfilerMarkerDataUnit.Count);
public const string LoadedPalletCountName = "Loaded Pallets";
public static readonly ProfilerCounterValue<int> LoadedPalletCount = new ProfilerCounterValue<int>(AssetWarehouseCategory, LoadedPalletCountName, ProfilerMarkerDataUnit.Count);
public const string LoadedCrateCountName = "Loaded Crates";
public static readonly ProfilerCounterValue<int> LoadedCrateCount = new ProfilerCounterValue<int>(AssetWarehouseCategory, LoadedCrateCountName, ProfilerMarkerDataUnit.Count);
public const string LoadedDataCardCountName = "Loaded DataCards";
public static readonly ProfilerCounterValue<int> LoadedDataCardCount = new ProfilerCounterValue<int>(AssetWarehouseCategory, LoadedDataCardCountName, ProfilerMarkerDataUnit.Count);
public const string LoadedMarrowAssetsCountName = "Loaded Marrow Assets";
public static readonly ProfilerCounterValue<int> LoadedMarrowAssetsCount = new ProfilerCounterValue<int>(AssetWarehouseCategory, LoadedMarrowAssetsCountName, ProfilerMarkerDataUnit.Count);
public static void Reset()
{
LoadedScannableCount.Value = 0;
LoadedPalletCount.Value = 0;
LoadedCrateCount.Value = 0;
LoadedDataCardCount.Value = 0;
LoadedMarrowAssetsCount.Value = 0;
}
#if UNITY_EDITOR
[System.Serializable]
[ProfilerModuleMetadata("Asset Warehouse")]
public class AssetWarehouseProfileModule : ProfilerModule
{
static readonly ProfilerCounterDescriptor[] counters = new ProfilerCounterDescriptor[]
{
new ProfilerCounterDescriptor(AssetWarehouseMetrics.LoadedScannableCountName, AssetWarehouseMetrics.AssetWarehouseCategory),
new ProfilerCounterDescriptor(AssetWarehouseMetrics.LoadedPalletCountName, AssetWarehouseMetrics.AssetWarehouseCategory),
new ProfilerCounterDescriptor(AssetWarehouseMetrics.LoadedCrateCountName, AssetWarehouseMetrics.AssetWarehouseCategory),
new ProfilerCounterDescriptor(AssetWarehouseMetrics.LoadedDataCardCountName, AssetWarehouseMetrics.AssetWarehouseCategory),
new ProfilerCounterDescriptor(AssetWarehouseMetrics.LoadedMarrowAssetsCountName, AssetWarehouseMetrics.AssetWarehouseCategory),
};
static readonly string[] autoEnabledCategoryNames = new string[]
{
ProfilerCategory.Scripts.Name
};
public AssetWarehouseProfileModule() : base(counters, autoEnabledCategoryNames: autoEnabledCategoryNames)
{
}
}
#endif
}
}

View file

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

View file

@ -0,0 +1,10 @@
using UnityEngine;
namespace SLZ.Marrow.Warehouse
{
public class AvatarCrate : SpawnableCrate
{
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d26284165bbf1b94dbe4934acd6c0f71
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: f975f535f5112274482e4f912f8a88b2, type: 3}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,310 @@
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Text;
using UnityEngine;
namespace SLZ.Marrow.Warehouse
{
[Serializable]
public class Barcode : IEquatable<Barcode>, ISerializationCallbackReceiver
{
public static bool useShortCode = false;
public static bool useCachedHashCode = false;
[SerializeField]
private string _id = EMPTY;
public string ID
{
get => _id;
private set
{
_id = value;
if (useShortCode)
{
shortCodeGenerated = false;
GenerateShortCode();
cachedHashCode = -1;
}
}
}
private bool shortCodeGenerated = false;
private uint _shortCode = 0;
public uint ShortCode
{
get
{
GenerateShortCode();
return _shortCode;
}
private set => _shortCode = value;
}
public static string separator = ".";
public static readonly string EMPTY = BuildBarcode("null", "empty", "barcode");
private static readonly string EMPTY_OLD = "00000000-0000-0000-0000-000000000000";
public static readonly int MAX_SIZE = 120;
#if UNITY_EDITOR || DEVELOPMENT_BUILD
static readonly Unity.Profiling.ProfilerMarker getHashcodeProfileMarker = new Unity.Profiling.ProfilerMarker("Barcode.GetHashCode");
#endif
private int cachedHashCode = -1;
public static Barcode EmptyBarcode()
{
return new Barcode(EMPTY);
}
public Barcode()
{
}
public Barcode(Barcode other)
{
if (other != null)
{
ID = other.ID;
}
}
public Barcode(string newId)
{
ID = newId;
}
public static string BuildBarcode(params string[] parts)
{
StringBuilder sb = new StringBuilder();
bool first = true;
foreach (var part in parts)
{
if (first)
{
first = false;
}
else
{
sb.Append(separator);
}
sb.Append(MarrowSDK.SanitizeID(part));
}
return sb.ToString();
}
public static bool IsValidSize(Barcode barcode)
{
if (barcode == null)
{
return false;
}
if (string.IsNullOrEmpty(barcode.ID))
{
return true;
}
return barcode.ID.Length <= MAX_SIZE;
}
public static bool IsValidSize(string barcodeString)
{
if (string.IsNullOrEmpty(barcodeString))
{
return true;
}
return barcodeString.Length <= MAX_SIZE;
}
public static bool IsValid(Barcode barcode)
{
bool valid = true;
if (barcode == null)
{
valid = false;
}
else if (string.IsNullOrEmpty(barcode.ID))
{
valid = false;
}
else if (barcode.ID == EMPTY || barcode.ID == EMPTY_OLD)
{
valid = false;
}
return valid;
}
public static bool IsValidString(string barcodeString)
{
bool valid = true;
if (string.IsNullOrEmpty(barcodeString))
{
valid = false;
}
else if (barcodeString == EMPTY || barcodeString == EMPTY_OLD)
{
valid = false;
}
return valid;
}
public void GenerateID(params string[] parts)
{
GenerateID(false, parts);
}
public void GenerateID(bool forceGeneration = false, params string[] parts)
{
if (!this.IsValid() || forceGeneration)
{
ID = BuildBarcode(parts);
}
}
private static Dictionary<string, uint> shortCodeDictionary = new Dictionary<string, uint>();
private void GenerateShortCode()
{
if (!shortCodeGenerated)
{
if (shortCodeDictionary.TryGetValue(ID, out uint cachedShortCode))
{
_shortCode = cachedShortCode;
}
else
{
_shortCode = shortCodeDictionary[ID] = (uint)shortCodeDictionary.Count;
}
shortCodeGenerated = true;
}
}
public override string ToString() => ID;
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj))
return false;
if (ReferenceEquals(this, obj))
return true;
if (obj is Barcode barcode)
return Equals(barcode);
if (obj is string objString)
return Equals(new Barcode(objString));
return false;
}
public bool Equals(Barcode other)
{
if (other is null)
{
return false;
}
if (ReferenceEquals(this, other))
{
return true;
}
if (this.GetType() != other.GetType())
{
return false;
}
if (useShortCode)
return this.ShortCode.Equals(other.ShortCode);
else
return this.ID.Equals(other.ID);
}
public static bool operator ==(Barcode barcode, Barcode otherBarcode)
{
if (barcode is null)
{
if (otherBarcode is null)
{
return true;
}
return false;
}
return barcode.Equals(otherBarcode);
}
public static bool operator !=(Barcode barcode, Barcode otherBarcode)
{
return !(barcode == otherBarcode);
}
public override int GetHashCode()
{
#if UNITY_EDITOR || DEVELOPMENT_BUILD
getHashcodeProfileMarker.Begin();
#endif
int hashCode;
if (useCachedHashCode)
{
if (cachedHashCode == -1)
{
if (useShortCode)
cachedHashCode = hashCode = ShortCode.GetHashCode();
else
cachedHashCode = hashCode = ID.GetHashCode();
}
else
{
hashCode = cachedHashCode;
}
}
else
{
if (useShortCode)
hashCode = ShortCode.GetHashCode();
else
hashCode = ID.GetHashCode();
}
#if UNITY_EDITOR || DEVELOPMENT_BUILD
getHashcodeProfileMarker.End();
#endif
return hashCode;
}
public void OnBeforeSerialize()
{
}
public void OnAfterDeserialize()
{
#if UNITY_EDITOR
if (!this.IsValid())
{
this.ID = EMPTY;
}
if (useShortCode)
{
shortCodeGenerated = false;
GenerateShortCode();
}
cachedHashCode = -1;
#endif
}
public static bool operator true(Barcode barcode) => IsValid(barcode);
public static bool operator false(Barcode barcode) => !IsValid(barcode);
public static implicit operator bool(Barcode barcode) => IsValid(barcode);
}
public static class BarcodeExtensions
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool IsValid(this Barcode barcode) => Barcode.IsValid(barcode);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool IsValidSize(this Barcode barcode) => Barcode.IsValidSize(barcode);
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3d958288cbd2937458b3c135a44924a6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: cfe95c647ba0cee40971123779228bcd, type: 3}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,14 @@
using UnityEngine;
namespace SLZ.Marrow.Warehouse
{
public class BoneTag : DataCard
{
public override bool IsBundledDataCard()
{
return false;
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e4036e0b5b59e2048bc6300b5d5295fe
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: b8d3f19f0141869439be5d29861acb0a, type: 3}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,179 @@
using System;
using System.Collections.Generic;
using Cysharp.Threading.Tasks;
using UnityEngine;
using Newtonsoft.Json.Linq;
using SLZ.Serialize;
using Object = UnityEngine.Object;
namespace SLZ.Marrow.Warehouse
{
public interface ICrate
{
MarrowAsset MainAsset { get; set; }
Type AssetType { get; }
}
public abstract class Crate : Scannable, ICrate
{
public virtual MarrowAsset MainAsset { get; set; }
public virtual Type AssetType
{
get
{
return typeof(UnityEngine.Object);
}
}
[NonSerialized]
private Pallet _pallet = null;
public Pallet Pallet
{
get
{
return _pallet;
}
set
{
_pallet = value;
}
}
[SerializeField]
[Delayed]
private List<string> _tags = new List<string>();
public List<string> Tags
{
get
{
return _tags;
}
set
{
_tags = value;
}
}
[SerializeField]
private TagList _boneTags = new TagList();
public TagList BoneTags { get => _boneTags; set => _boneTags = value; }
private static Dictionary<Type, string> _crateNames = new Dictionary<Type, string>();
public static Dictionary<Type, string> CrateNames
{
get
{
return _crateNames;
}
}
public static string GetCrateName(Type crateType)
{
if (!CrateNames.TryGetValue(crateType, out var crateName))
{
crateName = crateType.Name.Replace("Crate", "");
CrateNames[crateType] = crateName;
}
return crateName;
}
public override void GenerateBarcodeInternal(bool forceGeneration = false)
{
Barcode.GenerateID(forceGeneration, Pallet.Barcode.ID, GetCrateName(this.GetType()), Title.Replace(".", ""));
}
public virtual async UniTask<Object> LoadAssetAsync()
{
return await MainAsset.LoadAssetAsync<Object>();
}
public virtual void LoadAsset(Action<Object> loadCallback)
{
MainAsset.LoadAsset(loadCallback);
}
public override void Pack(ObjectStore store, JObject json)
{
base.Pack(store, json);
json.Add("mainAsset", MainAsset.AssetGUID);
json.Add(new JProperty("tags", new JArray(Tags)));
}
public override void Unpack(ObjectStore store, string objectId)
{
base.Unpack(store, objectId);
if (store.TryGetJSON("mainAsset", objectId, out JToken marrowAssetValue))
{
MainAsset = new MarrowAsset(marrowAssetValue.ToObject<string>());
}
if (store.TryGetJSON("tags", objectId, out JToken tagsValue))
{
JArray arr = (JArray)tagsValue;
Tags = new List<string>();
foreach (var tagValue in arr)
{
Tags.Add(tagValue.ToObject<string>());
}
}
}
public static Crate CreateCrate(System.Type type, Pallet pallet, string title, MarrowAsset marrowAsset, bool generateBarcode = true)
{
Crate crate = null;
if (type == typeof(SpawnableCrate) || type == typeof(LevelCrate) || type == typeof(AvatarCrate) || type == typeof(VFXCrate))
{
crate = (Crate)ScriptableObject.CreateInstance(type);
crate.Title = title;
crate.Pallet = pallet;
crate.MainAsset = marrowAsset;
if (generateBarcode)
{
crate.GenerateBarcode();
}
}
return crate;
}
public static T CreateCrateT<T>(Pallet pallet, string title, MarrowAsset marrowAsset, bool generateBarcode = true)
where T : Crate
{
return (T)CreateCrate(typeof(T), pallet, title, marrowAsset, generateBarcode);
}
}
public abstract class CrateT<T> : Crate where T : UnityEngine.Object
{
public override Type AssetType
{
get
{
return typeof(T);
}
}
public new async UniTask<T> LoadAssetAsync()
{
try
{
return await MainAsset.LoadAssetAsync<T>();
}
catch (Exception e)
{
Debug.LogError($"AssetWarehouse: Failed to load MainAsset from Crate({this.GetType().Name}) \"{Pallet.Title}:{Title}\"");
throw e;
}
}
public void LoadAsset(Action<T> loadCallback)
{
MainAsset.LoadAsset(loadCallback);
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e81099166edc3434c9bc90543a9f177d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 0413773da379515429a601be4dcdcd35, type: 3}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,12 @@
using UnityEngine;
namespace SLZ.Marrow.Warehouse
{
public interface ICrateFilter<in T>
where T : Crate
{
bool Filter(T crate);
}
}

View file

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

View file

@ -0,0 +1,84 @@
using System;
using System.Linq;
using UnityEngine;
using Random = UnityEngine.Random;
namespace SLZ.Marrow.Warehouse
{
[Serializable]
public class CrateQuery : CrateReference
{
[SerializeField]
public string tagFilter;
[SerializeField]
public string titleFilter;
private bool queryRan = false;
Barcode tempBarcode = Barcode.EmptyBarcode();
#if UNITY_EDITOR
public new Barcode Barcode
{
get
{
if (!queryRan)
{
RunQuery();
}
return tempBarcode;
}
set
{
tempBarcode = value;
}
}
private Type _crateType;
public override Type ScannableType => _crateType;
#endif
public void RunQuery()
{
Barcode queryBarcode = Barcode.EmptyBarcode();
if (AssetWarehouse.ready)
{
var crates = AssetWarehouse.Instance.GetCrates(new CrateQueryFilter(tagFilter, titleFilter));
if (crates.Count > 0)
{
if (crates.Count > 1)
{
queryBarcode = crates[Random.Range(0, crates.Count)].Barcode;
}
else
{
queryBarcode = crates[0].Barcode;
}
}
}
if (Barcode.IsValid(queryBarcode))
{
tempBarcode = queryBarcode;
queryRan = true;
}
}
class CrateQueryFilter : ICrateFilter<Crate>
{
private readonly string tagFilter;
private readonly string titleFilter;
public CrateQueryFilter(string tagFilter, string titleFilter)
{
this.tagFilter = tagFilter;
this.titleFilter = titleFilter;
}
public bool Filter(Crate crate)
{
return ((!string.IsNullOrEmpty(tagFilter) && crate.Tags.Contains(tagFilter, StringComparer.OrdinalIgnoreCase))) || ((!string.IsNullOrEmpty(titleFilter) && crate.Title.Contains(titleFilter, StringComparison.OrdinalIgnoreCase)));
}
}
}
}

View file

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

View file

@ -0,0 +1,203 @@
using System;
using UnityEngine;
#if UNITY_EDITOR
#endif
namespace SLZ.Marrow.Warehouse
{
public interface ICrateReference
{
Barcode Barcode { get; set; }
Crate Crate { get; }
bool TryGetCrate(out Crate crate);
#if UNITY_EDITOR
Type CrateType { get; }
#endif
}
[Serializable]
public class CrateReference : ScannableReference<Crate>
{
public CrateReference() : base(Warehouse.Barcode.EmptyBarcode())
{
}
public CrateReference(Barcode barcode) : base(barcode)
{
}
public CrateReference(string barcode) : base(barcode)
{
}
public Crate Crate
{
get
{
TryGetCrate(out var retCrate);
return retCrate;
}
}
public bool TryGetCrate(out Crate crate)
{
crate = null;
bool success = false;
if (AssetWarehouse.ready)
{
success = AssetWarehouse.Instance.TryGetCrate(Barcode, out crate);
}
return success;
}
public static bool IsValid(CrateReference crateReference)
{
return crateReference != null && Barcode.IsValid(crateReference.Barcode);
}
}
[Serializable]
public class CrateReferenceT<T> : ScannableReference<Crate> where T : Crate
{
public CrateReferenceT() : base(Warehouse.Barcode.EmptyBarcode())
{
}
public CrateReferenceT(Barcode barcode) : base(barcode)
{
}
public CrateReferenceT(string barcode) : base(barcode)
{
}
public new T Crate
{
get
{
TryGetCrate(out var retCrate);
return retCrate;
}
}
public bool TryGetCrate(out T crate)
{
crate = null;
bool success = false;
if (AssetWarehouse.ready)
{
success = AssetWarehouse.Instance.TryGetCrate<T>(Barcode, out crate);
}
return success;
}
}
[Serializable]
public class GenericCrateReference : CrateReferenceT<Crate>
{
public GenericCrateReference(Barcode barcode) : base(barcode)
{
}
public GenericCrateReference(string barcode) : base(barcode)
{
}
public GenericCrateReference() : base(Barcode.EmptyBarcode())
{
}
}
[Serializable]
public class GameObjectCrateReference : CrateReferenceT<GameObjectCrate>
{
public GameObjectCrateReference(Barcode barcode) : base(barcode)
{
}
public GameObjectCrateReference(string barcode) : base(barcode)
{
}
public GameObjectCrateReference() : base(Barcode.EmptyBarcode())
{
}
}
[Serializable]
public class SpawnableCrateReference : CrateReferenceT<SpawnableCrate>
{
public SpawnableCrateReference(Barcode barcode) : base(barcode)
{
}
public SpawnableCrateReference(string barcode) : base(barcode)
{
}
public SpawnableCrateReference() : base(Barcode.EmptyBarcode())
{
}
}
[Serializable]
public class AvatarCrateReference : CrateReferenceT<AvatarCrate>
{
public AvatarCrateReference(Barcode barcode) : base(barcode)
{
}
public AvatarCrateReference(string barcode) : base(barcode)
{
}
public AvatarCrateReference() : base(Barcode.EmptyBarcode())
{
}
}
[Serializable]
public class LevelCrateReference : CrateReferenceT<LevelCrate>
{
public LevelCrateReference(Barcode barcode) : base(barcode)
{
}
public LevelCrateReference(string barcode) : base(barcode)
{
}
public LevelCrateReference() : base(Barcode.EmptyBarcode())
{
}
}
[Serializable]
public class VFXCrateReference : CrateReferenceT<VFXCrate>
{
public VFXCrateReference(Barcode barcode) : base(barcode)
{
}
public VFXCrateReference(string barcode) : base(barcode)
{
}
public VFXCrateReference() : base(Barcode.EmptyBarcode())
{
}
}
}

View file

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

View file

@ -0,0 +1,156 @@
using System;
using SLZ.Marrow.Utilities;
using UltEvents;
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace SLZ.Marrow.Warehouse
{
[SelectionBase]
[AddComponentMenu("MarrowSDK/Crate Spawner")]
[HelpURL("https://github.com/StressLevelZero/MarrowSDK/wiki/Spawnables")]
public partial class CrateSpawner : MonoBehaviour
{
[Tooltip("Drag a Spawnable Crate from the Asset Warehouse or use the picker button to the right to select a Spawnable Crate.")]
[SerializeField]
public SpawnableCrateReference spawnableCrateReference = new SpawnableCrateReference(Barcode.EmptyBarcode());
[SerializeField]
public CrateQuery crateQuery = new CrateQuery();
[SerializeField]
public bool useQuery = false;
[Tooltip("With Manual Mode enabled, CrateSpawners will *not* activate when their associated Zone is triggered. Instead, they must be activated through an event, button press or similar action that calls the SpawnSpawnable() method.")]
[SerializeField]
public bool manualMode = false;
[Tooltip("Trigger additional events or actions once the CrateSpawner is activated.")]
[SerializeField]
public OnSpawnEvent onSpawnEvent;
#if UNITY_EDITOR
[NonSerialized]
public bool showPreviewGizmo = true;
public static bool showPreviewMesh = true;
public static bool showColliderBounds = true;
public static bool showLitMaterialPreview = false;
public static Material defaultLitMat = null;
public static float gizmoVisRange = 50f;
#endif
public SpawnableCrateReference GetCrateReference()
{
if (AssetWarehouse.ready)
{
if (useQuery)
{
return new SpawnableCrateReference(crateQuery.Barcode);
}
else
{
return spawnableCrateReference;
}
}
return null;
}
[ContextMenu("Spawn Spawnable")]
public void SpawnSpawnable()
{
UnityEngine.Debug.Log("Hollowed Method: SLZ.Marrow.Warehouse.CrateSpawner.SpawnSpawnable()");
throw new System.NotImplementedException();
}
public void SetSpawnable()
{
UnityEngine.Debug.Log("Hollowed Method: SLZ.Marrow.Warehouse.CrateSpawner.SetSpawnable()");
throw new System.NotImplementedException();
}
#if UNITY_EDITOR
[DrawGizmo(GizmoType.Active | GizmoType.Selected | GizmoType.NonSelected)]
private static void DrawPreviewGizmo(CrateSpawner spawner, GizmoType gizmoType)
{
bool gizmoInRange = Camera.current != null && Vector3.Dot(spawner.transform.position - Camera.current.transform.position, Camera.current.transform.forward) < gizmoVisRange;
if (!Application.isPlaying && spawner.gameObject.scene != default)
{
if (showLitMaterialPreview && defaultLitMat == null)
{
defaultLitMat = AssetDatabase.LoadAssetAtPath<Material>("Packages/com.unity.render-pipelines.universal/Runtime/Materials/Lit.mat");
}
var crateRef = spawner.GetCrateReference();
if (spawner != null && crateRef != null && spawner.showPreviewGizmo)
{
EditorPreviewMeshGizmo.Draw("PreviewMesh", spawner.gameObject, crateRef, showLitMaterialPreview ? defaultLitMat : MarrowSDK.VoidMaterial, !showPreviewMesh, !showColliderBounds || !gizmoInRange, true);
spawner.EditorUpdateName();
}
}
}
private void OnValidate()
{
if (!Application.isPlaying && gameObject.scene != default)
{
EditorUpdateName();
}
}
private void Reset()
{
gameObject.name = "CrateSpawner";
}
[ContextMenu("Reset Name")]
public void ResetName()
{
gameObject.name = "CrateSpawner";
}
public void EditorUpdateName(bool force = false)
{
if ((force || gameObject.name == "CrateSpawner") && AssetWarehouse.ready && !Application.isPlaying && AssetWarehouse.Instance.TryGetCrate(GetCrateReference().Barcode, out var crate))
{
string newName = useQuery ? "CrateSpawner (query)" : $"CrateSpawner ({crate.Title})";
if (gameObject.name != newName)
{
gameObject.name = newName;
GameObjectUtility.EnsureUniqueNameForSibling(gameObject);
EditorUtility.SetDirty(this);
}
}
}
public static GameObject EditorCreateCrateSpawner(SpawnableCrate crate = null, Transform targetTransform = null, Transform parentTransform = null)
{
GameObject go = new GameObject("Auto CrateSpawner", typeof(CrateSpawner));
go.transform.localScale = Vector3.one;
if (parentTransform != null)
go.transform.parent = parentTransform;
if (targetTransform != null)
{
go.transform.localPosition = targetTransform.localPosition;
go.transform.localRotation = targetTransform.localRotation;
}
var spawner = go.GetComponent<CrateSpawner>();
if (crate == null)
spawner.spawnableCrateReference = new SpawnableCrateReference();
else
spawner.spawnableCrateReference = new SpawnableCrateReference(crate.Barcode);
spawner.EditorUpdateName();
Undo.RegisterCreatedObjectUndo(go, $"Create CrateSpawner {(crate != null ? crate.Title : "")}");
return go;
}
#endif
}
[Serializable]
public class OnSpawnEvent : UltEvent<CrateSpawner, GameObject>
{
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 380a92c3490d7f240b2abf1a2a24839a
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 Newtonsoft.Json.Linq;
using UnityEngine;
using SLZ.Serialize;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace SLZ.Marrow.Warehouse
{
public abstract class DataCard : Scannable
{
[NonSerialized]
private Pallet _pallet = null;
public Pallet Pallet
{
get
{
return _pallet;
}
set
{
_pallet = value;
}
}
[SerializeField]
private MarrowAssetT<DataCard> _dataCardAsset;
public MarrowAssetT<DataCard> DataCardAsset
{
get
{
return _dataCardAsset;
}
set
{
_dataCardAsset = value;
}
}
public override void GenerateBarcodeInternal(bool forceGeneration = false)
{
Barcode.GenerateID(forceGeneration, Pallet.Barcode.ID, this.GetType().Name, Title.Replace(".", ""));
}
public virtual bool IsBundledDataCard()
{
return true;
}
public override void ImportPackedAssets(Dictionary<string, PackedAsset> packedAssets)
{
base.ImportPackedAssets(packedAssets);
}
public override List<PackedAsset> ExportPackedAssets()
{
base.ExportPackedAssets();
#if UNITY_EDITOR
SetupDataCardAsset();
#endif
return PackedAssets;
}
#if UNITY_EDITOR
private void SetupDataCardAsset()
{
if (this.IsBundledDataCard() && (DataCardAsset == null || string.IsNullOrEmpty(DataCardAsset.AssetGUID)))
{
var dataCardPath = UnityEditor.AssetDatabase.GetAssetPath(this);
var dataCardGuid = UnityEditor.AssetDatabase.AssetPathToGUID(dataCardPath);
DataCardAsset = new MarrowAssetT<DataCard>(dataCardGuid);
}
}
public override void GeneratePackedAssets(bool saveAsset = true)
{
base.GeneratePackedAssets(saveAsset);
SetupDataCardAsset();
EditorUtility.SetDirty(this);
if (saveAsset)
{
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
}
}
#endif
public override void Pack(ObjectStore store, JObject json)
{
base.Pack(store, json);
#if UNITY_EDITOR
if (this.IsBundledDataCard())
{
SetupDataCardAsset();
}
#endif
if (this.IsBundledDataCard() && DataCardAsset != null && !string.IsNullOrEmpty(DataCardAsset.AssetGUID))
{
json.Add("dataCardAsset", DataCardAsset.AssetGUID);
}
}
public override void Unpack(ObjectStore store, string objectId)
{
base.Unpack(store, objectId);
if (this.IsBundledDataCard())
{
if (store.TryGetJSON("dataCardAsset", objectId, out JToken dataCardAssetValue))
{
DataCardAsset = new MarrowAssetT<DataCard>(dataCardAssetValue.ToString());
}
}
}
public static DataCard CreateDataCard(System.Type type, Pallet pallet, string title, bool generateBarcode = true)
{
DataCard dataCard = null;
if (typeof(DataCard).IsAssignableFrom(type))
{
dataCard = (DataCard)ScriptableObject.CreateInstance(type);
dataCard.Title = title;
dataCard.Pallet = pallet;
if (generateBarcode)
{
dataCard.GenerateBarcode();
}
}
return dataCard;
}
public static T CreateDataCard<T>(Pallet pallet, string title, bool generateBarcode = true)
where T : DataCard
{
return (T)CreateDataCard(typeof(T), pallet, title, generateBarcode);
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: da4f82e85c284154ada59166f85fb9c5
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: b2201a38841a02f439d61c393692b69f, type: 3}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,120 @@
using System;
using UnityEngine;
namespace SLZ.Marrow.Warehouse
{
[Serializable]
public class DataCardReference : ScannableReference<DataCard>
{
public DataCardReference() : base(Warehouse.Barcode.EmptyBarcode())
{
}
public DataCardReference(Barcode barcode) : base(barcode)
{
}
public DataCardReference(string barcode) : base(barcode)
{
}
public DataCard DataCard
{
get
{
TryGetDataCard(out var retDataCard);
return retDataCard;
}
}
public bool TryGetDataCard(out DataCard dataCard)
{
dataCard = null;
bool success = false;
if (AssetWarehouse.ready)
{
success = AssetWarehouse.Instance.TryGetDataCard(Barcode, out dataCard);
}
return success;
}
public static bool IsValid(DataCardReference dataCardReference)
{
return dataCardReference != null && Barcode.IsValid(dataCardReference.Barcode);
}
}
[Serializable]
public class DataCardReference<T> : ScannableReference<DataCard> where T : DataCard
{
public DataCardReference() : base(Warehouse.Barcode.EmptyBarcode())
{
}
public DataCardReference(Barcode barcode) : base(barcode)
{
}
public DataCardReference(string barcode) : base(barcode)
{
}
public new T DataCard
{
get
{
TryGetDataCard(out var retDataCard);
return retDataCard;
}
}
public bool TryGetDataCard(out T dataCard)
{
dataCard = null;
bool success = false;
if (AssetWarehouse.ready)
{
success = AssetWarehouse.Instance.TryGetDataCard<T>(Barcode, out dataCard);
}
return success;
}
}
[Serializable]
public class BoneTagReference : DataCardReference<BoneTag>
{
public BoneTagReference() : base(Warehouse.Barcode.EmptyBarcode())
{
}
public BoneTagReference(Barcode barcode) : base(barcode)
{
}
public BoneTagReference(string barcode) : base(barcode)
{
}
}
[Serializable]
public class MonoDiscReference : DataCardReference<MonoDisc>
{
public MonoDiscReference() : base(Warehouse.Barcode.EmptyBarcode())
{
}
public MonoDiscReference(Barcode barcode) : base(barcode)
{
}
public MonoDiscReference(string barcode) : base(barcode)
{
}
}
}

View file

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

View file

@ -0,0 +1,82 @@
using System.Collections.Generic;
using Newtonsoft.Json.Linq;
using SLZ.Marrow.Interaction;
using SLZ.Serialize;
using UnityEngine;
namespace SLZ.Marrow.Warehouse
{
public class EntityPose : DataCard
{
[SerializeField]
private MarrowEntityPose _poseData;
public MarrowEntityPose PoseData { get => _poseData; set => _poseData = value; }
[SerializeField]
private SpawnableCrateReference _spawnable = new SpawnableCrateReference();
public SpawnableCrateReference Spawnable { get => _spawnable; set => _spawnable = value; }
[SerializeField]
private MarrowAssetT<Mesh> _posePreviewMesh = new MarrowAssetT<Mesh>();
public MarrowAssetT<Mesh> PosePreviewMesh { get => _posePreviewMesh; set => _posePreviewMesh = value; }
[SerializeField]
public Bounds _colliderBounds;
public Bounds ColliderBounds { get => _colliderBounds; set => _colliderBounds = value; }
public override bool IsBundledDataCard()
{
return true;
}
public override void ImportPackedAssets(Dictionary<string, PackedAsset> packedAssets)
{
base.ImportPackedAssets(packedAssets);
if (packedAssets.TryGetValue("PosePreviewMesh", out var packedAsset))
PosePreviewMesh = new MarrowAssetT<Mesh>(packedAsset.marrowAsset.AssetGUID);
}
public override List<PackedAsset> ExportPackedAssets()
{
base.ExportPackedAssets();
PackedAssets.Add(new PackedAsset("PosePreviewMesh", PosePreviewMesh, PosePreviewMesh.AssetType, "_posePreviewMesh"));
return PackedAssets;
}
public override void Pack(ObjectStore store, JObject json)
{
base.Pack(store, json);
json.Add("spawnable", Spawnable.Barcode.ID);
json.Add(new JProperty("colliderBounds", new JObject { { "center", new JObject { { "x", _colliderBounds.center.x }, { "y", _colliderBounds.center.y }, { "z", _colliderBounds.center.z } } }, { "extents", new JObject { { "x", _colliderBounds.extents.x }, { "y", _colliderBounds.extents.y }, { "z", _colliderBounds.extents.z } } } }));
}
public override void Unpack(ObjectStore store, string objectId)
{
base.Unpack(store, objectId);
if (store.TryGetJSON("spawnable", objectId, out JToken spawnableValue))
{
Spawnable = new SpawnableCrateReference(spawnableValue.ToString());
}
if (store.TryGetJSON("colliderBounds", objectId, out JToken colliderBoundsToken))
{
_colliderBounds = colliderBoundsToken.ToObject<Bounds>();
}
}
#if UNITY_EDITOR
public string EntityPoseSpawnableFilter(Scannable scannable)
{
if (scannable != null && scannable is EntityPose entityPose && ScannableReference.IsValid(entityPose.Spawnable))
{
return entityPose.Spawnable.Barcode.ToString();
}
return string.Empty;
}
#endif
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e8fc9e576ff4f9846a081bc47b402e2e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 4060715537733724ba4c4d6f8d94c2c1, type: 3}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,33 @@
using System.Collections.Generic;
using UnityEngine;
namespace SLZ.Marrow.Warehouse
{
public class Fixture : DataCard
{
public override bool IsBundledDataCard()
{
return true;
}
#if UNITY_EDITOR
public override string GetAssetExtension()
{
return "fxt";
}
#endif
[SerializeField]
private SpawnableCrateReference _fixtureSpawnable = new SpawnableCrateReference();
public SpawnableCrateReference FixtureSpawnable { get => _fixtureSpawnable; set => _fixtureSpawnable = value; }
[SerializeField]
private MarrowAssetT<GameObject> _staticFixturePrefab = new MarrowAssetT<GameObject>();
public MarrowAssetT<GameObject> StaticFixturePrefab { get => _staticFixturePrefab; set => _staticFixturePrefab = value; }
[SerializeField]
private List<MarrowMonoScript> _decorators = new List<MarrowMonoScript>();
public List<MarrowMonoScript> Decorators { get => _decorators; set => _decorators = value; }
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ae8433aab5fc4823985818207caf818c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 7bf495326dda3da4ea0bde25eb8c1696, type: 3}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,187 @@
using System;
using System.Collections.Generic;
using Newtonsoft.Json.Linq;
using SLZ.Serialize;
using SLZ.Marrow.Utilities;
using UnityEngine;
using UnityEngine.Serialization;
using Object = UnityEngine.Object;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace SLZ.Marrow.Warehouse
{
public class GameObjectCrate : CrateT<GameObject>
{
[FormerlySerializedAs("_assetReference")]
[SerializeField]
private MarrowGameObject _mainAsset;
public override MarrowAsset MainAsset
{
get => _mainAsset;
set
{
if (value != null && value.GetType() == typeof(MarrowAsset))
{
_mainAsset = new MarrowGameObject(value.AssetGUID);
}
else
{
_mainAsset = (MarrowGameObject)value;
}
}
}
public MarrowGameObject MainGameObject { get => _mainAsset; set => _mainAsset = value; }
[SerializeField]
private MarrowAssetT<Mesh> _previewMesh = new MarrowAssetT<Mesh>();
public MarrowAssetT<Mesh> PreviewMesh { get => _previewMesh; set => _previewMesh = value; }
[SerializeField]
private bool _customQuality = false;
public bool CustomQuality { get => _customQuality; set => _customQuality = value; }
[SerializeField]
[Range(0f, 1f)]
private float _previewMeshQuality = 0.5f;
public float PreviewMeshQuality { get => _previewMeshQuality; set => _previewMeshQuality = value; }
[SerializeField]
[Range(0f, 5f)]
private int _maxLODLevel = 0;
public int MaxLODLevel { get => _maxLODLevel; set => _maxLODLevel = value; }
[SerializeField]
public Bounds _colliderBounds;
public Bounds ColliderBounds { get => _colliderBounds; set => _colliderBounds = value; }
public override void ImportPackedAssets(Dictionary<string, PackedAsset> packedAssets)
{
base.ImportPackedAssets(packedAssets);
if (packedAssets.TryGetValue("PreviewMesh", out var packedAsset))
PreviewMesh = new MarrowMesh(packedAsset.marrowAsset.AssetGUID);
}
public override List<PackedAsset> ExportPackedAssets()
{
base.ExportPackedAssets();
PackedAssets.Add(new PackedAsset("PreviewMesh", PreviewMesh, PreviewMesh.AssetType, "previewMesh"));
return PackedAssets;
}
#if UNITY_EDITOR
public override void GeneratePackedAssets(bool saveAsset = true)
{
base.GeneratePackedAssets();
GenerateColliderBounds();
GeneratePreviewMesh();
EditorUtility.SetDirty(this);
if (saveAsset)
{
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
}
}
protected void GenerateColliderBounds()
{
this.ColliderBounds = GenerateColliderBounds(MainGameObject.EditorAsset);
}
public static Bounds GenerateColliderBounds(GameObject targetGameObject)
{
Bounds bounds = new Bounds();
if (targetGameObject != null)
{
PreviewRenderUtility fakeScene = new PreviewRenderUtility();
var parentGO = new GameObject("root");
fakeScene.AddSingleGO(parentGO);
var go = Object.Instantiate(targetGameObject, Vector3.zero, Quaternion.identity, parentGO.transform);
Collider[] cols = go.GetComponentsInChildren<Collider>();
bool isFirst = true;
for (int j = 0; j < cols.Length; j++)
{
if (cols[j].isTrigger)
continue;
if (isFirst)
bounds = cols[j].bounds;
else
bounds.Encapsulate(cols[j].bounds);
isFirst = false;
}
bounds.center -= go.transform.position;
DestroyImmediate(go);
DestroyImmediate(parentGO);
fakeScene.Cleanup();
}
return bounds;
}
protected virtual void GeneratePreviewMesh()
{
if (MainGameObject.EditorAsset != null)
{
Mesh mesh;
if (CustomQuality)
mesh = MeshCroncher.CronchMesh(MainGameObject.EditorAsset, MaxLODLevel, PreviewMeshQuality, CustomQuality);
else
mesh = MeshCroncher.CronchMesh(MainGameObject.EditorAsset, MaxLODLevel);
if (mesh != null)
{
if (!AssetDatabase.IsValidFolder(MarrowSDK.GetMarrowAssetsPath()))
{
AssetDatabase.CreateFolder("Assets", MarrowSDK.EDITOR_ASSETS_FOLDER);
}
if (!AssetDatabase.IsValidFolder(MarrowSDK.GetMarrowAssetsPath("PackedAssets")))
{
AssetDatabase.CreateFolder(MarrowSDK.GetMarrowAssetsPath(), "PackedAssets");
}
if (!AssetDatabase.IsValidFolder(MarrowSDK.GetMarrowAssetsPath("PackedAssets", Pallet.Barcode.ToString())))
{
AssetDatabase.CreateFolder(MarrowSDK.GetMarrowAssetsPath("PackedAssets"), Pallet.Barcode.ToString());
}
if (!AssetDatabase.IsValidFolder(MarrowSDK.GetMarrowAssetsPath("PackedAssets", Pallet.Barcode.ToString(), "PreviewMesh")))
{
AssetDatabase.CreateFolder(MarrowSDK.GetMarrowAssetsPath("PackedAssets", Pallet.Barcode.ToString()), "PreviewMesh");
}
string path = MarrowSDK.GetMarrowAssetsPath("PackedAssets", Pallet.Barcode.ToString(), "PreviewMesh", $"{MarrowSDK.SanitizeName(Title)} PreviewMesh.mesh");
if (System.IO.File.Exists(path))
AssetDatabase.DeleteAsset(path);
AssetDatabase.Refresh();
AssetDatabase.CreateAsset(mesh, path);
AssetDatabase.Refresh();
var meshAsset = AssetDatabase.LoadAssetAtPath<Mesh>(path);
PreviewMesh.SetEditorAsset(meshAsset);
}
}
}
#endif
public override void Pack(ObjectStore store, JObject json)
{
base.Pack(store, json);
json.Add(new JProperty("colliderBounds", new JObject { { "center", new JObject { { "x", _colliderBounds.center.x }, { "y", _colliderBounds.center.y }, { "z", _colliderBounds.center.z } } }, { "extents", new JObject { { "x", _colliderBounds.extents.x }, { "y", _colliderBounds.extents.y }, { "z", _colliderBounds.extents.z } } } }));
}
public override void Unpack(ObjectStore store, string objectId)
{
base.Unpack(store, objectId);
if (store.TryGetJSON("colliderBounds", objectId, out JToken colliderBoundsToken))
{
_colliderBounds = colliderBoundsToken.ToObject<Bounds>();
}
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d915c5c46e6209b4bacb6a603980fc39
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 0413773da379515429a601be4dcdcd35, type: 3}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,188 @@
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using System;
using Newtonsoft.Json.Linq;
using SLZ.Serialize;
using UnityEngine.Serialization;
#if UNITY_EDITOR
using UnityEditor;
using UnityEditor.SceneManagement;
#endif
namespace SLZ.Marrow.Warehouse
{
public class LevelCrate : Crate
{
[FormerlySerializedAs("_assetReference")]
[SerializeField]
private MarrowScene _mainAsset;
public override MarrowAsset MainAsset
{
get => _mainAsset;
set
{
if (value != null && value.GetType() == typeof(MarrowAsset))
{
_mainAsset = new MarrowScene(value.AssetGUID);
}
else
{
_mainAsset = (MarrowScene)value;
}
}
}
public MarrowScene MainScene { get => _mainAsset; set => _mainAsset = value; }
[SerializeField]
private List<MarrowScene> _additionalAssetReferences = new List<MarrowScene>();
[Tooltip("Level has multiple scenes")]
[SerializeField]
private bool _multiScene = false;
public bool MultiScene { get => _multiScene; set => _multiScene = value; }
[Tooltip("Scenes that also load in when the root scene loads, and will stay always loaded in until level change")]
[SerializeField]
private List<MarrowScene> _persistentScenes = new List<MarrowScene>();
public List<MarrowScene> PersistentScenes => _persistentScenes;
[Tooltip("Scenes that will be loaded dynamically in the level, for example: Chunk scenes loaded through a Chunk Trigger. All chunked scenes must be included here or they will not be included in the build")]
[SerializeField]
private List<MarrowScene> _chunkScenes = new List<MarrowScene>();
public List<MarrowScene> ChunkScenes => _chunkScenes;
[Tooltip("Scenes that will ONLY load in the editor at design time, outside of playmode. They will NOT load in during builds, and will NOT be included in builds")]
[SerializeField]
private List<MarrowScene> _editorScenes = new List<MarrowScene>();
public List<MarrowScene> EditorScenes => _editorScenes;
#if UNITY_EDITOR
private string CURSED_SCENE_GUID = "99c9720ab356a0642a771bea13969a05";
[ContextMenu("Validate Scene Guid")]
public void ValidateSceneGUID()
{
if (!string.IsNullOrEmpty(MainScene.AssetGUID))
{
if (MainScene.AssetGUID == CURSED_SCENE_GUID)
{
var scenePath = AssetDatabase.GUIDToAssetPath(CURSED_SCENE_GUID);
var metaPath = AssetDatabase.GetTextMetaFilePathFromAssetPath(scenePath);
var metaText = System.IO.File.ReadAllText(metaPath);
if (metaText.Contains(CURSED_SCENE_GUID) && metaText.Contains($"guid: {CURSED_SCENE_GUID}"))
{
string newGuid = System.Guid.NewGuid().ToString("N");
metaText = metaText.Replace($"guid: {CURSED_SCENE_GUID}", $"guid: {newGuid}");
System.IO.File.WriteAllText(metaPath, metaText);
MainScene = new MarrowScene(newGuid);
EditorUtility.SetDirty(this);
AssetDatabase.ImportAsset(scenePath);
AssetDatabase.SaveAssetIfDirty(this);
AssetDatabase.Refresh();
}
}
}
}
#endif
#if UNITY_EDITOR
public override System.Type AssetType { get => typeof(SceneAsset); }
#else
#endif
#if UNITY_EDITOR
public SceneSetup[] ToEditorSceneSetups()
{
var allScenesForEditor = new List<MarrowScene>();
allScenesForEditor.Add(MainScene);
allScenesForEditor.AddRange(PersistentScenes.Select(assetRef => assetRef).Where(scene => scene.EditorAsset != null || scene.AssetGUID != string.Empty));
allScenesForEditor.AddRange(ChunkScenes.Select(assetRef => assetRef).Where(scene => scene.EditorAsset != null || scene.AssetGUID != string.Empty));
allScenesForEditor.AddRange(EditorScenes.Select(assetRef => assetRef).Where(scene => scene.EditorAsset != null || scene.AssetGUID != string.Empty));
var ret = new SceneSetup[allScenesForEditor.Count];
bool first = true;
for (var i = 0; i < allScenesForEditor.Count; i++)
{
var sceneAsset = allScenesForEditor[i];
var sceneSetup = new SceneSetup
{
path = AssetDatabase.GUIDToAssetPath(sceneAsset.AssetGUID),
isActive = first,
isLoaded = true
};
if (first)
first = false;
ret[i] = sceneSetup;
}
return ret;
}
#endif
public override void ImportPackedAssets(Dictionary<string, PackedAsset> packedAssets)
{
if (packedAssets.TryGetValue("PersistentScenes", out var packedAsset) && packedAsset.HasSubAssets())
{
foreach (var subAsset in packedAsset.subAssets)
{
PersistentScenes.Add(new MarrowScene(subAsset.subAsset.AssetGUID));
}
}
if (packedAssets.TryGetValue("ChunkScenes", out packedAsset) && packedAsset.HasSubAssets())
{
foreach (var subAsset in packedAsset.subAssets)
{
ChunkScenes.Add(new MarrowScene(subAsset.subAsset.AssetGUID));
}
}
}
public override List<PackedAsset> ExportPackedAssets()
{
base.ExportPackedAssets();
Type sceneAssetType = typeof(UnityEngine.SceneManagement.Scene);
List<PackedSubAsset> subAssets = new List<PackedSubAsset>();
for (var i = 0; i < _persistentScenes.Count; i++)
{
var persistentScene = _persistentScenes[i];
string subTitle = i.ToString();
#if UNITY_EDITOR
subTitle = $"{(persistentScene.EditorAsset != null ? MarrowSDK.SanitizeName(persistentScene.EditorAsset.name) : "")}-{subTitle}";
#endif
subAssets.Add(new PackedSubAsset(subTitle, persistentScene));
}
PackedAssets.Add(new PackedAsset("PersistentScenes", subAssets, sceneAssetType, "_persistentScenes"));
subAssets = new List<PackedSubAsset>();
for (var i = 0; i < _chunkScenes.Count; i++)
{
var chunkScene = _chunkScenes[i];
string subTitle = i.ToString();
#if UNITY_EDITOR
subTitle = $"{(chunkScene.EditorAsset != null ? MarrowSDK.SanitizeName(chunkScene.EditorAsset.name) : "")}-{subTitle}";
#endif
subAssets.Add(new PackedSubAsset(subTitle, chunkScene));
}
PackedAssets.Add(new PackedAsset("ChunkScenes", subAssets, sceneAssetType, "_chunkScenes"));
return PackedAssets;
}
public override void Pack(ObjectStore store, JObject json)
{
base.Pack(store, json);
json.Add("multiscene", MultiScene);
}
public override void Unpack(ObjectStore store, string objectId)
{
base.Unpack(store, objectId);
if (store.TryGetJSON("multiscene", objectId, out JToken barcodeValue))
{
_multiScene = barcodeValue.ToObject<bool>();
}
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2505b25ddfc1ccf418da1689d2daf024
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 0754a1cfdebab1a44853bf8177fb5cb4, type: 3}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,460 @@
using System;
using System.Threading;
using Cysharp.Threading.Tasks;
using UnityEditor;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;
using UnityEngine.ResourceManagement.ResourceProviders;
using UnityEngine.SceneManagement;
using UnityEngine.Serialization;
using Object = UnityEngine.Object;
namespace SLZ.Marrow.Warehouse
{
[Serializable]
public class MarrowAsset
{
[SerializeField]
[FormerlySerializedAs("m_AssetGUID")]
private string _assetGUID = "";
public string AssetGUID { get => _assetGUID ?? string.Empty; }
private AsyncOperationHandle _operationHandle;
public AsyncOperationHandle OperationHandle { get => _operationHandle; }
public virtual Object Asset
{
get
{
if (!_operationHandle.IsValid())
return null;
return _operationHandle.Result as Object;
}
}
protected bool IsLoading { get => OperationHandle.IsValid() && !OperationHandle.IsDone; }
protected bool IsDone { get => OperationHandle.IsValid() && OperationHandle.IsDone; }
protected Type _assetType;
public virtual Type AssetType
{
get
{
if (_assetType == null)
{
_assetType = typeof(Object);
}
return _assetType;
}
}
#if MARROW_ASSET_REFCOUNT
#endif
public virtual UniTask<Object> LoadTask
{
get => default;
protected set
{
}
}
public MarrowAsset()
{
_assetGUID = string.Empty;
}
public MarrowAsset(string guid)
{
_assetGUID = guid;
}
protected virtual void InitialAssetModifications<TObject>(TObject resultResult)
{
}
protected virtual AsyncOperationHandle<TObject> LoadAssetAsyncTask<TObject>()
{
AsyncOperationHandle<TObject> result = default(AsyncOperationHandle<TObject>);
if (!_operationHandle.IsValid())
{
result = Addressables.LoadAssetAsync<TObject>(AssetGUID);
AssetWarehouseMetrics.LoadedMarrowAssetsCount.Value++;
_operationHandle = result;
}
return result;
}
protected virtual AsyncOperationHandle<SceneInstance> LoadSceneAsyncInternal(LoadSceneMode loadMode = LoadSceneMode.Single, bool activateOnLoad = true, int priority = 100)
{
AsyncOperationHandle<SceneInstance> result = default(AsyncOperationHandle<SceneInstance>);
if (!_operationHandle.IsValid())
{
result = Addressables.LoadSceneAsync(AssetGUID, loadMode, activateOnLoad, priority);
_operationHandle = result;
}
return result;
}
protected virtual bool ReleaseAsset()
{
if (!_operationHandle.IsValid())
{
return false;
}
Addressables.Release(_operationHandle);
AssetWarehouseMetrics.LoadedMarrowAssetsCount.Value--;
_operationHandle = default;
return true;
}
public async UniTask<TObject> LoadAssetAsync<TObject>(CancellationToken cancellationToken = default(CancellationToken))
where TObject : Object
{
TObject retObject = null;
if (IsDone || IsLoading)
{
#if MARROW_ASSET_REFCOUNT
#endif
try
{
var returnCompleted = await OperationHandle.Convert<TObject>().ToUniTask();
return returnCompleted;
}
catch (Exception e)
{
return retObject;
}
}
else
{
var task = LoadAssetAsyncTask<TObject>().ToUniTask(cancellationToken: cancellationToken);
retObject = await task;
#if MARROW_ASSET_REFCOUNT
#endif
}
return retObject;
}
public void LoadAsset<TObject>(Action<TObject> loadCallback)
where TObject : Object
{
if (IsDone)
{
#if MARROW_ASSET_REFCOUNT
#endif
loadCallback.Invoke(Asset as TObject);
}
else
{
LoadAssetAsync<TObject>().ContinueWith(loadCallback).Forget();
}
}
public async UniTask<SceneInstance> LoadSceneAsync(LoadSceneMode loadMode = LoadSceneMode.Single, bool activateOnLoad = true, int priority = 100)
{
if (IsDone || IsLoading)
{
#if MARROW_ASSET_REFCOUNT
#endif
return await OperationHandle.Convert<SceneInstance>().ToUniTask();
}
else
{
var task = LoadSceneAsyncInternal(loadMode, activateOnLoad, priority).ToUniTask();
var retObject = await task;
#if MARROW_ASSET_REFCOUNT
#endif
return retObject;
}
}
public bool UnloadAsset(bool forced = false)
{
bool unloaded = false;
if (forced)
{
unloaded = ReleaseAsset();
}
else
{
#if MARROW_ASSET_REFCOUNT
#endif
}
return unloaded;
}
public bool ReleaseAsset(bool forced = false)
{
bool unloaded = false;
if (forced)
{
unloaded = ReleaseAsset();
}
else
{
#if MARROW_ASSET_REFCOUNT
#endif
}
return unloaded;
}
public bool Equals(MarrowAsset other)
{
if (ReferenceEquals(null, other))
return false;
if (ReferenceEquals(this, other))
return true;
return _assetGUID == other._assetGUID;
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj))
return false;
if (ReferenceEquals(this, obj))
return true;
if (obj.GetType() != this.GetType())
return false;
return Equals((MarrowAsset)obj);
}
public override int GetHashCode()
{
return (_assetGUID != null ? _assetGUID.GetHashCode() : 0);
}
public static bool operator ==(MarrowAsset left, MarrowAsset right)
{
return Equals(left, right);
}
public static bool operator !=(MarrowAsset left, MarrowAsset right)
{
return !Equals(left, right);
}
#if UNITY_EDITOR
private Object _cachedAsset;
private string _cachedGUID;
#pragma warning disable CS0414
[SerializeField]
private bool _editorAssetChanged;
#pragma warning restore CS0414
protected Object CachedAsset
{
get
{
if (_cachedGUID != _assetGUID)
{
_cachedAsset = null;
_cachedGUID = "";
}
return _cachedAsset;
}
set
{
_cachedAsset = value;
_cachedGUID = _assetGUID;
}
}
public virtual Object EditorAsset
{
get
{
if (CachedAsset != null || string.IsNullOrEmpty(_assetGUID))
return CachedAsset;
var asset = FetchEditorAsset();
return CachedAsset = asset;
}
}
protected Object FetchEditorAsset()
{
var assetPath = AssetDatabase.GUIDToAssetPath(AssetGUID);
return AssetDatabase.LoadAssetAtPath(assetPath, AssetType);
}
public virtual bool SetEditorAsset(Object obj)
{
if (obj == null)
{
CachedAsset = null;
_assetGUID = string.Empty;
_editorAssetChanged = true;
return true;
}
if (CachedAsset != obj)
{
var path = AssetDatabase.GetAssetOrScenePath(obj);
_assetGUID = AssetDatabase.AssetPathToGUID(path);
Object mainAsset;
if (AssetType != typeof(Object))
{
mainAsset = AssetDatabase.LoadAssetAtPath(path, AssetType);
}
else
{
mainAsset = AssetDatabase.LoadMainAssetAtPath(path);
}
CachedAsset = mainAsset;
}
_editorAssetChanged = true;
return true;
}
#endif
}
[Serializable]
public class MarrowAssetT<TObject> : MarrowAsset where TObject : Object
{
public MarrowAssetT()
{
}
public MarrowAssetT(string guid) : base(guid)
{
#if UNITY_EDITOR
_assetType = typeof(TObject);
#endif
}
public new TObject Asset
{
get
{
if (!OperationHandle.IsValid())
return null;
return OperationHandle.Result as TObject;
}
}
public override Type AssetType
{
get
{
if (_assetType == null)
{
_assetType = typeof(TObject);
}
return _assetType;
}
}
public async UniTask<TObject> LoadAssetAsync()
{
return await LoadAssetAsync<TObject>();
}
public void LoadAsset(Action<TObject> loadCallback)
{
LoadAsset<TObject>(loadCallback);
}
#if UNITY_EDITOR
public new TObject EditorAsset
{
get
{
if (CachedAsset as TObject != null || string.IsNullOrEmpty(AssetGUID))
return CachedAsset as TObject;
return (TObject)(CachedAsset = FetchAsset());
}
}
protected TObject FetchAsset()
{
var assetPath = AssetDatabase.GUIDToAssetPath(AssetGUID);
if (string.IsNullOrEmpty(assetPath))
return null;
return AssetDatabase.LoadAssetAtPath<TObject>(assetPath);
}
#endif
}
[Serializable]
public class MarrowGameObject : MarrowAssetT<GameObject>
{
public MarrowGameObject()
{
}
public MarrowGameObject(string guid) : base(guid)
{
}
protected override void InitialAssetModifications<TObject>(TObject resultResult)
{
base.InitialAssetModifications(resultResult);
}
}
[Serializable]
public class MarrowMesh : MarrowAssetT<Mesh>
{
public MarrowMesh(string guid) : base(guid)
{
}
}
[Serializable]
public class MarrowTexture : MarrowAssetT<Texture>
{
public MarrowTexture(string guid) : base(guid)
{
}
}
[Serializable]
public class MarrowTexture2D : MarrowAssetT<Texture2D>
{
public MarrowTexture2D(string guid) : base(guid)
{
}
}
[Serializable]
public class MarrowScene : MarrowAsset
{
private Type _assetType1;
public MarrowScene(string guid) : base(guid)
{
}
#if UNITY_EDITOR
public new SceneAsset EditorAsset => base.EditorAsset as SceneAsset;
public override Type AssetType => typeof(SceneAsset);
#endif
}
[Serializable]
public class MarrowMonoScript : MarrowAsset
{
private Type _assetType1;
public MarrowMonoScript(string guid) : base(guid)
{
}
#if UNITY_EDITOR
public new MonoScript EditorAsset => base.EditorAsset as MonoScript;
public override Type AssetType => typeof(MonoScript);
#endif
}
}

View file

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

View file

@ -0,0 +1,37 @@
using System;
using System.Collections.Generic;
using UnityEngine;
namespace SLZ.Marrow.Warehouse
{
[Serializable]
public class MarrowQuery
{
[Tooltip("Matches if contains ALL listed tags")]
[SerializeField]
private List<TagQuery> _tags = new List<TagQuery>();
public List<TagQuery> Tags { get => _tags; set => _tags = value; }
[Tooltip("Sets the operator between Tags/Crates")]
[SerializeField]
private LogicOperator _operator = LogicOperator.And;
public LogicOperator TagCrateOperator { get => _operator; set => _operator = value; }
[Tooltip("Matches if is any listed crates")]
[SerializeField]
private List<GenericCrateReference> _crates = new List<GenericCrateReference>();
public List<GenericCrateReference> Crates { get => _crates; set => _crates = value; }
public enum LogicOperator
{
And = 0,
Or = 1
}
}
}

View file

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

View file

@ -0,0 +1,40 @@
using System.Collections.Generic;
using UnityEngine;
namespace SLZ.Marrow.Warehouse
{
public class MonoDisc : DataCard
{
[SerializeField]
private MarrowAssetT<AudioClip> _audioClip = new MarrowAssetT<AudioClip>();
public MarrowAssetT<AudioClip> AudioClip { get => _audioClip; set => _audioClip = value; }
public override bool IsBundledDataCard()
{
return true;
}
public override void ImportPackedAssets(Dictionary<string, PackedAsset> packedAssets)
{
base.ImportPackedAssets(packedAssets);
if (packedAssets.TryGetValue("AudioClip", out var packedAsset))
AudioClip = new MarrowAssetT<AudioClip>(packedAsset.marrowAsset.AssetGUID);
}
public override List<PackedAsset> ExportPackedAssets()
{
base.ExportPackedAssets();
PackedAssets.Add(new PackedAsset("AudioClip", AudioClip, AudioClip.AssetType, "_audioClip"));
return PackedAssets;
}
#if UNITY_EDITOR
public override void GeneratePackedAssets(bool saveAsset = true)
{
base.GeneratePackedAssets(saveAsset);
}
#endif
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 31fee4a281eed89449118a9e046e7890
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 3a76383e9364a854fa1b5f6b947fd6ac, type: 3}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,51 @@
using System;
using System.Collections.Generic;
using UnityEngine;
namespace SLZ.Marrow.Warehouse
{
[Serializable]
public struct PackedAsset
{
public string title;
public MarrowAsset marrowAsset;
public List<PackedSubAsset> subAssets;
public Type assetType;
private string assetFieldName;
public PackedAsset(string title, MarrowAsset marrowAsset, Type assetType, string assetFieldName)
{
this.title = title;
this.marrowAsset = marrowAsset;
this.subAssets = new List<PackedSubAsset>();
this.assetFieldName = assetFieldName;
this.assetType = assetType;
}
public PackedAsset(string title, List<PackedSubAsset> subAssets, Type assetType, string assetFieldName)
{
this.title = title;
this.marrowAsset = null;
this.subAssets = subAssets;
this.assetType = assetType;
this.assetFieldName = assetFieldName;
}
public bool HasSubAssets()
{
return subAssets != null && subAssets.Count > 0;
}
}
[Serializable]
public struct PackedSubAsset
{
public string subTitle;
public MarrowAsset subAsset;
public PackedSubAsset(string subTitle, MarrowAsset subAsset)
{
this.subTitle = subTitle;
this.subAsset = subAsset;
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 40cf1b9d99c054545874cb2c32804800
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 0b6f4007340463e41b211ca1ba9f5f68, type: 3}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,436 @@
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using Newtonsoft.Json.Linq;
using SLZ.Serialize;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace SLZ.Marrow.Warehouse
{
public partial class Pallet : Scannable, ISerializationCallbackReceiver
{
[SerializeField]
private string _author;
public string Author
{
get
{
return _author;
}
set
{
_author = value;
}
}
[SerializeField]
private string _version = "0.0.0";
public string Version
{
get
{
return _version;
}
set
{
_version = value;
}
}
[SerializeField]
private string _sdkVersion = MarrowSDK.SDK_VERSION;
public string SDKVersion
{
get
{
return _sdkVersion;
}
set
{
_sdkVersion = value;
}
}
[SerializeField]
[Tooltip("NO LONGER USED")]
private bool _internal = false;
public bool Internal
{
[Obsolete("Use Pallet.IsInMarrowGame()")]
get
{
return _internal;
}
set
{
_internal = value;
}
}
[SerializeField]
private List<Crate> _crates = new List<Crate>();
public List<Crate> Crates
{
get
{
return _crates;
}
set
{
_crates = value;
}
}
[SerializeField]
private List<DataCard> _dataCards = new List<DataCard>();
public List<DataCard> DataCards
{
get
{
return _dataCards;
}
set
{
_dataCards = value;
}
}
[SerializeField]
private List<string> _tags = new List<string>();
public List<string> Tags
{
get
{
return _tags;
}
set
{
_tags = value;
}
}
[System.Serializable]
public struct ChangeLog
{
public string version;
public string title;
[TextArea(4, 20)]
public string text;
[Newtonsoft.Json.JsonConstructor]
public ChangeLog(string version, string title, string text)
{
this.version = version;
this.title = title;
this.text = text;
}
}
[SerializeField]
private List<ChangeLog> _changeLogs = new List<ChangeLog>();
public List<ChangeLog> ChangeLogs
{
get
{
return _changeLogs;
}
}
#if UNITY_EDITOR
[SerializeField]
private List<string> _crateTitles = new List<string>();
[SerializeField]
private List<string> _datacardTitles = new List<string>();
#endif
public static readonly string PALLET_JSON_FILENAME = "pallet.json";
public override void GenerateBarcodeInternal(bool forceGeneration = false)
{
Barcode.GenerateID(forceGeneration, Author, Title.Replace(".", ""));
foreach (var crate in Crates)
{
crate.GenerateBarcode(true);
}
}
public void GetScannables(ref List<Scannable> scannables)
{
scannables.Clear();
scannables.AddRange(Crates);
scannables.AddRange(DataCards);
}
[SerializeField]
private List<PalletReference> _palletDependencies = new List<PalletReference>();
public List<PalletReference> PalletDependencies
{
get
{
return _palletDependencies;
}
}
public override void Pack(ObjectStore store, JObject json)
{
json.Add("barcode", Barcode.ID);
json.Add("title", Title);
json.Add("description", Description);
json.Add("unlockable", Unlockable);
json.Add("redacted", Redacted);
json.Add("author", Author);
json.Add("version", Version);
json.Add("sdkVersion", SDKVersion);
json.Add("internal", Internal);
var jsonCrateArray = new JArray();
foreach (var crate in Crates)
{
if (crate != null)
{
jsonCrateArray.Add(store.PackReference(crate));
}
}
json.Add(new JProperty("crates", jsonCrateArray));
var jsonDataCardArray = new JArray();
foreach (var dataCard in DataCards)
{
if (dataCard != null)
{
jsonDataCardArray.Add(store.PackReference(dataCard));
}
}
json.Add(new JProperty("dataCards", jsonDataCardArray));
json.Add(new JProperty("tags", new JArray(Tags)));
var changelogArray = new JArray();
foreach (var changelog in ChangeLogs)
{
JObject logObject = new JObject();
logObject.Add("version", changelog.version);
logObject.Add("title", changelog.title);
logObject.Add("text", changelog.text);
changelogArray.Add(logObject);
}
json.Add(new JProperty("changelogs", changelogArray));
}
public override void Unpack(ObjectStore store, string objectId)
{
if (store.TryGetJSON("barcode", objectId, out JToken barcodeValue))
{
Barcode = new Barcode(barcodeValue.ToObject<string>());
}
if (store.TryGetJSON("title", objectId, out JToken titleValue))
{
name = titleValue.ToObject<string>();
Title = titleValue.ToObject<string>();
}
if (store.TryGetJSON("description", objectId, out JToken descValue))
{
Description = descValue.ToObject<string>();
}
if (store.TryGetJSON("unlockable", objectId, out JToken unlockValue))
{
Unlockable = unlockValue.ToObject<bool>();
}
if (store.TryGetJSON("redacted", objectId, out JToken redaValue))
{
Redacted = redaValue.ToObject<bool>();
}
if (store.TryGetJSON("author", objectId, out JToken authorValue))
{
Author = authorValue.ToObject<string>();
}
if (store.TryGetJSON("version", objectId, out JToken versionValue))
{
Version = versionValue.ToObject<string>();
}
if (store.TryGetJSON("sdkVersion", objectId, out JToken sdkVersionValue))
{
SDKVersion = sdkVersionValue.ToObject<string>();
}
if (store.TryGetJSON("internal", objectId, out JToken internalValue))
{
Internal = internalValue.ToObject<bool>();
}
if (store.TryGetJSON("crates", objectId, out JToken cratesValue))
{
JArray arr = (JArray)cratesValue;
Crates = new List<Crate>();
foreach (var crateValue in arr)
{
store.TryCreateFromReference(crateValue, out Crate crate, t => Crate.CreateCrate(t, null, "", new MarrowAsset(), false));
crate.Pallet = this;
Crates.Add(crate);
}
}
if (store.TryGetJSON("dataCards", objectId, out JToken dataCardsValue))
{
JArray arr = (JArray)dataCardsValue;
DataCards = new List<DataCard>();
foreach (var dataCardValue in arr)
{
store.TryCreateFromReference(dataCardValue, out DataCard dataCard, t => DataCard.CreateDataCard(t, null, "", false));
dataCard.Pallet = this;
DataCards.Add(dataCard);
}
}
if (store.TryGetJSON("tags", objectId, out JToken tagsValue))
{
JArray arr = (JArray)tagsValue;
Tags = new List<string>();
foreach (var tagValue in arr)
{
Tags.Add(tagValue.ToObject<string>());
}
}
if (store.TryGetJSON("changelogs", objectId, out JToken changeLogsValue))
{
JArray arr = (JArray)changeLogsValue;
ChangeLogs.Clear();
foreach (var changeLogValue in arr)
{
string version = changeLogValue["version"].ToObject<string>();
string title = changeLogValue["title"].ToObject<string>();
string text = changeLogValue["text"].ToObject<string>();
ChangeLogs.Add(new ChangeLog(version, title, text));
}
}
}
public static Pallet CreatePallet(string title, string author, bool generateBarcode = true)
{
Pallet pallet = ScriptableObject.CreateInstance<Pallet>();
pallet.Title = title;
pallet.Author = author;
if (generateBarcode)
{
pallet.GenerateBarcode();
}
return pallet;
}
public void OnBeforeSerialize()
{
#if UNITY_EDITOR
_crateTitles.Clear();
foreach (var crate in Crates)
{
if (crate != null)
_crateTitles.Add($"{Crate.GetCrateName(crate.GetType())} {crate.Title}");
}
_datacardTitles.Clear();
foreach (var dataCard in DataCards)
{
if (dataCard != null)
_datacardTitles.Add($"{dataCard.GetType().Name} {dataCard.Title}");
}
#endif
}
public void OnAfterDeserialize()
{
#if UNITY_EDITOR
#endif
}
#if UNITY_EDITOR
[ContextMenu("Save Json to File")]
private void SaveJsonToAssetDatabase()
{
string palletPath = AssetDatabase.GetAssetPath(this);
palletPath = System.IO.Path.GetDirectoryName(palletPath);
string palletJsonPath = System.IO.Path.Combine(palletPath, "_Pallet_" + MarrowSDK.SanitizeName(this.Barcode.ToString()) + ".json");
PalletPacker.PackAndSaveToJson(this, palletJsonPath);
AssetDatabase.Refresh();
}
[ContextMenu("Sort Contents")]
public void SortCrates()
{
Crates.RemoveAll(item => item == null);
Crates = Crates.OrderBy(crate => crate.GetType().Name).ThenBy(crate =>
{
var cratePath = AssetDatabase.GetAssetPath(crate);
var crateFilename = System.IO.Path.GetFileName(cratePath);
return crateFilename;
}).ToList();
DataCards.RemoveAll(item => item == null);
DataCards = DataCards.OrderBy(dataCard => dataCard.GetType().Name).ThenBy(dataCard =>
{
var dataCardPath = AssetDatabase.GetAssetPath(dataCard);
var dataCardFilename = System.IO.Path.GetFileName(dataCardPath);
return dataCardFilename;
}).ToList();
EditorUtility.SetDirty(this);
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
}
[ContextMenu("Fix Names")]
public void FixNames()
{
AssetDatabase.StartAssetEditing();
var palletItems = new List<Scannable>();
palletItems.Add(this);
palletItems.AddRange(Crates);
palletItems.AddRange(DataCards);
foreach (var scannable in palletItems)
{
string currentPath = AssetDatabase.GetAssetPath(scannable);
string currentFileName = System.IO.Path.GetFileName(currentPath);
string newFileName = scannable.GetAssetFilename();
if (currentFileName.Substring(0, currentFileName.IndexOf('.')) != scannable.GetAssetFilenameTitle())
newFileName = $"{currentFileName.Substring(0, currentFileName.IndexOf('.'))}.{scannable.GetFullAssetExtension()}";
if (!currentFileName.EndsWith(scannable.GetFullAssetExtension()))
{
AssetDatabase.RenameAsset(currentPath, newFileName);
}
}
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
AssetDatabase.StopAssetEditing();
}
public override string GetAssetExtension()
{
return "pallet";
}
public static string GetAssetExtensionStatic()
{
return "pallet";
}
public override string GetAssetFilename()
{
return $"_{base.GetAssetFilename()}";
}
#endif
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1bffa63f5a19c394b9f0ab757607a9ea
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 529d04aab3b69f245b8d48be6cb87815, type: 3}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,186 @@
using System;
using Newtonsoft.Json.Linq;
using SLZ.Marrow.Forklift.Model;
using SLZ.Serialize;
using UnityEngine;
using UnityEngine.AddressableAssets.ResourceLocators;
namespace SLZ.Marrow.Warehouse
{
public sealed class PalletManifest : IPackable
{
public PalletManifest()
{
}
public PalletManifest(PalletManifest otherManifest)
{
otherManifest.CopyTo(this);
}
private Barcode _palletBarcode;
public Barcode PalletBarcode { get => _palletBarcode; set => _palletBarcode = value; }
private string _palletPath;
public string PalletPath { get => _palletPath; set => _palletPath = value; }
private string _catalogPath;
public string CatalogPath { get => _catalogPath; set => _catalogPath = value; }
private string _version;
public string Version { get => _version; set => _version = value; }
private string _installedDate;
public string InstalledDate { get => _installedDate; set => _installedDate = value; }
private string _updatedDate;
public string UpdatedDate { get => _updatedDate; set => _updatedDate = value; }
private ModListing _modListing;
public ModListing ModListing { get => _modListing; set => _modListing = value; }
private Pallet _pallet;
public Pallet Pallet { get => _pallet; set => _pallet = value; }
private IResourceLocator _catalog;
public IResourceLocator Catalog { get => _catalog; set => _catalog = value; }
private string _manifestPath = String.Empty;
public string ManifestPath
{
get
{
if (string.IsNullOrEmpty(_manifestPath) && Pallet != null)
{
_manifestPath = GetManifestPath(Pallet);
}
return _manifestPath;
}
set => _manifestPath = value;
}
private bool _active = true;
public bool Active { get => _active; set => _active = value; }
public const string EXTENSION_NAME = "manifest";
public void SetInstalledDateToNow()
{
var timeNow = new DateTimeOffset(DateTime.UtcNow);
_installedDate = timeNow.ToUnixTimeMilliseconds().ToString();
}
public void SetUpdateDateToNow()
{
var timeNow = new DateTimeOffset(DateTime.UtcNow);
_updatedDate = timeNow.ToUnixTimeMilliseconds().ToString();
}
public static string GetManifestPath(Pallet pallet)
{
return System.IO.Path.Combine(MarrowSDK.RuntimeModsPath, $"{pallet.Barcode}.{EXTENSION_NAME}");
}
public static PalletManifest CreateManifest(Type manifestType)
{
return new PalletManifest();
}
public void CopyTo(PalletManifest otherManifest)
{
otherManifest.Pallet = this.Pallet;
otherManifest.PalletBarcode = this.PalletBarcode;
otherManifest.PalletPath = this.PalletPath;
otherManifest.CatalogPath = this.CatalogPath;
otherManifest.Version = this.Version;
otherManifest.InstalledDate = this.InstalledDate;
otherManifest.UpdatedDate = this.UpdatedDate;
otherManifest.Catalog = this.Catalog;
otherManifest.ManifestPath = this.ManifestPath;
if (this.ModListing != null)
{
otherManifest.ModListing = new ModListing();
otherManifest.ModListing.Author = this.ModListing.Author;
otherManifest.ModListing.Barcode = this.ModListing.Barcode;
otherManifest.ModListing.Description = this.ModListing.Description;
otherManifest.ModListing.Title = this.ModListing.Title;
otherManifest.ModListing.Version = this.ModListing.Version;
otherManifest.ModListing.ThumbnailUrl = this.ModListing.ThumbnailUrl;
otherManifest.ModListing.Targets = new StringModTargetListingDictionary();
foreach (var entry in this.ModListing.Targets)
{
otherManifest.ModListing.Targets.Add(entry.Key, entry.Value);
}
}
otherManifest.Active = this.Active;
}
public void Pack(ObjectStore store, JObject json)
{
json.Add("palletBarcode", _palletBarcode.ID);
json.Add("palletPath", _palletPath);
json.Add("catalogPath", _catalogPath);
json.Add("version", _version);
json.Add("installedDate", _installedDate);
json.Add("updateDate", _updatedDate);
if (_modListing != null)
json.Add("modListing", store.PackReference(_modListing));
json.Add("active", _active);
}
public void Unpack(ObjectStore store, string objectId)
{
if (store.TryGetJSON("palletBarcode", objectId, out JToken palletBarcodeValue))
{
_palletBarcode = new Barcode(palletBarcodeValue.ToObject<string>());
}
if (store.TryGetJSON("palletPath", objectId, out JToken palletPathValue))
{
_palletPath = palletPathValue.ToObject<string>();
}
if (store.TryGetJSON("catalogPath", objectId, out JToken catalogPathValue))
{
_catalogPath = catalogPathValue.ToObject<string>();
}
if (store.TryGetJSON("version", objectId, out JToken versionValue))
{
_version = versionValue.ToString();
}
if (store.TryGetJSON("installedDate", objectId, out JToken installValue))
{
_installedDate = installValue.ToString();
}
if (store.TryGetJSON("updateDate", objectId, out JToken updateValue))
{
_updatedDate = updateValue.ToString();
}
try
{
if (store.TryGetJSON("modListing", objectId, out JToken modTargetValue))
{
store.TryCreateFromReference(modTargetValue, out _modListing, t => new ModListing());
}
}
catch (Exception)
{
Debug.LogWarning($"PalletManifest: Failed to unpack modListing for pallet {_palletBarcode}");
}
if (store.TryGetJSON("active", objectId, out JToken activeValue))
{
_active = activeValue.ToObject<bool>();
}
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c60394a1cc8883e46850150e27795383
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 6ee7d03dfde254540948b9b49b2c202c, type: 3}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,231 @@
using System.IO;
using Cysharp.Threading.Tasks;
using UnityEngine;
using SLZ.Serialize;
using Newtonsoft.Json.Linq;
using UnityEngine.Networking;
namespace SLZ.Marrow.Warehouse
{
public class PalletPacker
{
public static bool ValidatePallet(Pallet pallet)
{
bool valid = true;
if (pallet == null)
{
valid = false;
Debug.LogWarning("PalletPacker Validate: Failed, pallet is null");
}
if (pallet.Barcode == null)
{
valid = false;
Debug.LogWarning("PalletPacker Validate: Failed, pallet barcode is null");
}
if (string.IsNullOrEmpty(pallet.Title))
{
valid = false;
Debug.LogWarning("PalletPacker Validate: Failed, pallet title is empty");
}
if (string.IsNullOrEmpty(pallet.Author))
{
valid = false;
Debug.LogWarning("PalletPacker Validate: Failed, pallet author is empty");
}
if (!Barcode.IsValid(pallet.Barcode))
{
valid = false;
Debug.LogWarning("PalletPacker Validate: Failed, pallet barcode is empty, generate now");
}
return valid;
}
public static void PackAndSaveToJson(Pallet pallet, string savePath)
{
string json = PackIntoJson(pallet);
string path = savePath;
#if UNITY_EDITOR
if (string.IsNullOrEmpty(path))
{
path = Path.Combine(Directory.GetParent(Application.dataPath).ToString(), MarrowSDK.BUILT_PALLETS_NAME, pallet.Title + ".json");
}
#endif
if (!Directory.Exists(Path.GetDirectoryName(path)))
Directory.CreateDirectory(Path.GetDirectoryName(path));
File.WriteAllText(path, json);
}
public static string PackIntoJson(Pallet pallet)
{
string json = "";
if (ValidatePallet(pallet))
{
var store = ObjectStore.Builder.WithMarrowDefaults().Build();
store.TryPack(pallet, out JObject obj);
json = obj.ToString();
}
return json;
}
public static Pallet UnpackJsonFromFile(string path)
{
Pallet pallet = null;
if (File.Exists(path))
{
string json = File.ReadAllText(path);
pallet = UnpackJson(json);
}
else
{
Debug.LogError("PalletPacker UnpackJsonFromFile: Could not find file " + path);
}
return pallet;
}
public static async UniTask<Pallet> UnpackJsonFromFileAndroid(string path)
{
Pallet pallet = null;
if (path.StartsWith("jar"))
{
try
{
using var webRequest = UnityWebRequest.Get(path);
var download = await webRequest.SendWebRequest();
var json = download.downloadHandler.text;
pallet = UnpackJson(json);
}
catch (System.Exception e)
{
Debug.Log($"PalletPacker UnpackJsonFromFileAndroid: Failed to load pallet json from path: {path}: Exception: {e.Message}");
Debug.LogException(e);
}
}
else
{
pallet = UnpackJsonFromFile(path);
}
return pallet;
}
public static Pallet UnpackJson(string palletJson)
{
Pallet pallet = null;
JObject obj = JObject.Parse(palletJson);
var store = ObjectStore.Builder.WithMarrowDefaults().WithJsonDocument(obj).Build();
store.LoadTypes(obj["types"] as JObject);
pallet = ScriptableObject.CreateInstance<Pallet>();
try
{
pallet.Unpack(store, obj["root"]["ref"].ToObject<string>());
}
catch (System.Exception)
{
UnityEngine.Object.DestroyImmediate(pallet);
return null;
}
return pallet;
}
public static bool TryUnpackManifestJsonFromFile(string path, out PalletManifest palletManifest, out string palletManifestJson)
{
if (File.Exists(path))
{
string json = File.ReadAllText(path);
palletManifest = UnpackManifestJson(json);
palletManifestJson = json;
return true;
}
else
{
palletManifest = null;
palletManifestJson = null;
return false;
}
}
public static PalletManifest UnpackManifestJson(string palletManifestJson)
{
PalletManifest palletManifest = null;
JObject obj = JObject.Parse(palletManifestJson);
var store = ObjectStore.Builder.WithMarrowDefaults().WithJsonDocument(obj).Build();
store.LoadTypes(obj["types"] as JObject);
var root = obj["root"];
store.TryCreateFromReference(root, out palletManifest, PalletManifest.CreateManifest);
return palletManifest;
}
public static bool TryPackManifestAndSaveToJson(PalletManifest palletManifest, string savePath, string palletManifestJson = null)
{
bool success = true;
string json = palletManifestJson;
if (string.IsNullOrEmpty(json))
json = PackManifestIntoJson(palletManifest);
string manifestPath = savePath;
if (string.IsNullOrEmpty(manifestPath))
{
manifestPath = PalletManifest.GetManifestPath(palletManifest.Pallet);
}
try
{
File.WriteAllText(manifestPath, json);
}
catch (System.Exception e)
{
success = false;
Debug.LogError($"PalletPacker TryPackManifestAndSaveToJson: Could not save file to {manifestPath}");
Debug.LogException(e);
}
return success;
}
public static string PackManifestIntoJson(PalletManifest palletManifest)
{
string json = "";
var store = ObjectStore.Builder.WithMarrowDefaults().Build();
store.TryPack(palletManifest, out JObject obj);
json = obj.ToString();
return json;
}
public static bool TryUnpackMarrowGameJsonFromFile(string path, out MarrowSettings marrowGame, out string marrowGameJson)
{
if (File.Exists(path))
{
string json = File.ReadAllText(path);
marrowGame = UnpackMarrowGameJson(json);
marrowGameJson = json;
return true;
}
else
{
marrowGame = null;
marrowGameJson = null;
return false;
}
}
public static MarrowSettings UnpackMarrowGameJson(string marrowGameJson)
{
MarrowSettings marrowGame = null;
JObject obj = JObject.Parse(marrowGameJson);
var store = ObjectStore.Builder.WithMarrowDefaults().WithJsonDocument(obj).Build();
store.LoadTypes(obj["types"] as JObject);
var root = obj["root"];
store.TryCreateFromReference(root, out marrowGame, type => ScriptableObject.CreateInstance<MarrowSettings>());
return marrowGame;
}
}
}

View file

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

View file

@ -0,0 +1,51 @@
using System;
using UnityEngine;
namespace SLZ.Marrow.Warehouse
{
[Serializable]
public class PalletReference : ScannableReference<Pallet>
{
public PalletReference() : base(Warehouse.Barcode.EmptyBarcode())
{
}
public PalletReference(Barcode barcode) : base(barcode)
{
}
public PalletReference(string barcode) : base(barcode)
{
}
public Pallet Pallet
{
get
{
TryGetPallet(out var retPallet);
return retPallet;
}
}
public bool TryGetPallet(out Pallet pallet)
{
pallet = null;
bool success = false;
if (AssetWarehouse.ready)
{
success = AssetWarehouse.Instance.TryGetPallet(Barcode, out pallet);
}
return success;
}
public static bool IsValid(PalletReference palletReference)
{
return palletReference != null && Barcode.IsValid(palletReference.Barcode);
}
}
}

View file

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

View file

@ -0,0 +1,15 @@
using UnityEngine;
using UnityEngine.AddressableAssets.ResourceLocators;
using UnityEngine.ResourceManagement.AsyncOperations;
namespace SLZ.Marrow.Warehouse
{
public class RuntimePallet : Pallet
{
public IResourceLocator catalog;
public AsyncOperationHandle catalogOperationHandle;
public string catalogPath;
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 637567ff8194c0849a2fe1e5a447dfd3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 529d04aab3b69f245b8d48be6cb87815, type: 3}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,315 @@
using System.Collections.Generic;
using System.Linq;
using Cysharp.Threading.Tasks;
using Newtonsoft.Json.Linq;
using SLZ.Serialize;
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace SLZ.Marrow.Warehouse
{
public interface IReadOnlyScannable
{
Barcode Barcode { get; }
string Title { get; }
string Description { get; }
}
public interface IScannable : IReadOnlyScannable, IPackable, IPackedAssets
{
bool Unlockable { get; }
bool Redacted { get; }
void GenerateBarcode(bool forceGeneration = false);
void GenerateBarcodeInternal(bool forceGeneration = false);
}
public interface IPackedAssets
{
public List<PackedAsset> PackedAssets { get; }
void ImportPackedAssets(Dictionary<string, PackedAsset> packedAssets);
List<PackedAsset> ExportPackedAssets();
#if UNITY_EDITOR
void GeneratePackedAssets(bool saveAsset = true);
#endif
}
public abstract class Scannable : ScriptableObject, IScannable
{
[SerializeField]
private Barcode _barcode;
public Barcode Barcode
{
get
{
return _barcode;
}
set
{
_barcode = value;
}
}
[SerializeField]
[Delayed]
private string _title;
public string Title
{
get
{
return _title;
}
set
{
_title = value;
}
}
[SerializeField]
[Delayed]
private string _description = "";
public string Description
{
get
{
return _description;
}
set
{
_description = value;
}
}
[SerializeField]
[Tooltip("Locks the crate from the user until it is unlocked")]
private bool _unlockable = false;
public bool Unlockable
{
get
{
return _unlockable;
}
set
{
_unlockable = value;
}
}
[SerializeField]
[Tooltip("Hides the crate from Menus")]
private bool _redacted = false;
public bool Redacted
{
get
{
return _redacted;
}
set
{
_redacted = value;
}
}
public void GenerateBarcode(bool forceGeneration = false)
{
if (Barcode == null || !Barcode.IsValid())
{
Barcode = new Barcode();
}
GenerateBarcodeInternal(forceGeneration);
}
public abstract void GenerateBarcodeInternal(bool forceGeneration = false);
private List<PackedAsset> _packedAssets = new List<PackedAsset>();
public List<PackedAsset> PackedAssets { get => _packedAssets; }
public virtual void ImportPackedAssets(Dictionary<string, PackedAsset> packedAssets)
{
PackedAssets.Clear();
foreach (var kvp in packedAssets)
{
PackedAssets.Add(kvp.Value);
}
}
public virtual List<PackedAsset> ExportPackedAssets()
{
PackedAssets.Clear();
return PackedAssets;
}
public virtual void Pack(ObjectStore store, JObject json)
{
json.Add("barcode", Barcode.ID);
json.Add("title", Title);
json.Add("description", Description);
json.Add("unlockable", Unlockable);
json.Add("redacted", Redacted);
PackJsonPackedAssets(json);
}
public virtual void Unpack(ObjectStore store, string objectId)
{
if (store.TryGetJSON("barcode", objectId, out JToken barcodeValue))
{
Barcode = new Barcode(barcodeValue.ToObject<string>());
}
if (store.TryGetJSON("title", objectId, out JToken titleValue))
{
name = titleValue.ToObject<string>();
Title = titleValue.ToObject<string>();
}
if (store.TryGetJSON("description", objectId, out JToken descValue))
{
Description = descValue.ToObject<string>();
}
if (store.TryGetJSON("unlockable", objectId, out JToken unlockValue))
{
Unlockable = unlockValue.ToObject<bool>();
}
if (store.TryGetJSON("redacted", objectId, out JToken redaValue))
{
Redacted = redaValue.ToObject<bool>();
}
UnpackJsonPackedAssets(store, objectId);
}
public void PackJsonPackedAssets(JObject json)
{
ExportPackedAssets();
var packedAssetsArray = new JArray();
foreach (var packedAsset in PackedAssets)
{
var packedAssetJObject = new JObject
{
{
"title",
packedAsset.title
},
};
if (packedAsset.marrowAsset != null)
{
packedAssetJObject.Add(new JProperty("guid", packedAsset.marrowAsset.AssetGUID));
}
if (packedAsset.HasSubAssets())
{
packedAssetJObject.Add(new JProperty("subAssets", new JArray(packedAsset.subAssets.Select(p => p.subAsset.AssetGUID))));
}
if (packedAsset.marrowAsset != null || packedAsset.subAssets.Count > 0)
packedAssetsArray.Add(packedAssetJObject);
}
json.Add(new JProperty("packedAssets", packedAssetsArray));
}
public void UnpackJsonPackedAssets(ObjectStore store, string objectId)
{
if (store.TryGetJSON("packedAssets", objectId, out JToken packedAssetsValue))
{
var packedAssets = new Dictionary<string, PackedAsset>();
foreach (var arrayToken in (JArray)packedAssetsValue)
{
if (((JObject)arrayToken).TryGetValue("title", out var titleToken))
{
var packedAsset = new PackedAsset();
packedAsset.title = titleToken.ToObject<string>();
if (((JObject)arrayToken).TryGetValue("guid", out var guidToken))
{
packedAsset.marrowAsset = new MarrowAsset(guidToken.ToObject<string>());
packedAsset.assetType = typeof(UnityEngine.Object);
}
if (((JObject)arrayToken).TryGetValue("subAssets", out var subAssetsToken))
{
List<PackedSubAsset> subAssets = new List<PackedSubAsset>();
for (var i = 0; i < ((JArray)subAssetsToken).Count; i++)
{
var subAssetToken = ((JArray)subAssetsToken)[i];
subAssets.Add(new PackedSubAsset($"{i}", new MarrowAsset(subAssetToken.ToObject<string>())));
}
packedAsset.subAssets = subAssets;
}
if ((packedAsset.marrowAsset != null || packedAsset.HasSubAssets()) && !packedAssets.ContainsKey(packedAsset.title))
{
packedAssets[packedAsset.title] = packedAsset;
}
}
}
ImportPackedAssets(packedAssets);
}
}
#if UNITY_EDITOR
public virtual void GeneratePackedAssets(bool saveAsset = true)
{
}
[ContextMenu("Generate Barcode")]
private void GenerateBarcodeMenuButton()
{
GenerateBarcode(true);
EditorUtility.SetDirty(this);
AssetDatabase.SaveAssetIfDirty(this);
}
public virtual string GetAssetFilename()
{
return $"{GetAssetFilenameTitle()}.{GetFullAssetExtension()}";
}
public virtual string GetAssetFilenameTitle()
{
return Title.Replace(".", "");
}
public virtual string GetAssetExtension()
{
string typeNameShort = string.Empty;
foreach (var c in GetType().Name)
{
if (char.IsUpper(c))
typeNameShort += c;
}
typeNameShort = typeNameShort.ToLower();
return typeNameShort;
}
public string GetFullAssetExtension()
{
return $"{GetAssetExtension()}.asset";
}
public string GetNameNoExtension()
{
return name.Replace($".{GetAssetExtension()}", "");
}
#endif
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b9f8c1e9383dfec4fad0395490dfebcc
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: cfe95c647ba0cee40971123779228bcd, type: 3}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,123 @@
using System;
using UnityEngine;
namespace SLZ.Marrow.Warehouse
{
[Serializable]
public abstract class ScannableReference
{
[SerializeField]
protected Barcode _barcode = Barcode.EmptyBarcode();
public Barcode Barcode
{
get => _barcode;
set
{
_barcode = value;
#if UNITY_EDITOR
_barcode = new Barcode(value);
#endif
}
}
public virtual Type ScannableType { get => typeof(Scannable); }
public ScannableReference()
{
}
public ScannableReference(Barcode barcode)
{
this.Barcode = barcode;
}
public ScannableReference(string barcode)
{
this.Barcode = new Barcode(barcode);
}
public Scannable Scannable
{
get
{
Scannable retScannable = null;
if (AssetWarehouse.ready)
{
AssetWarehouse.Instance.TryGetScannable(Barcode, out retScannable);
}
return retScannable;
}
}
public bool TryGetScannable(out Scannable scannable)
{
scannable = null;
bool success = false;
if (AssetWarehouse.ready)
{
success = AssetWarehouse.Instance.TryGetScannable(Barcode, out scannable);
}
return success;
}
public bool IsValid()
{
return Barcode.IsValid();
}
public static bool IsValid(ScannableReference scannableReference)
{
return scannableReference != null && Barcode.IsValid(scannableReference.Barcode);
}
}
[Serializable]
public class ScannableReference<T> : ScannableReference where T : Scannable
{
public override Type ScannableType { get => typeof(T); }
public ScannableReference() : base()
{
}
public ScannableReference(Barcode barcode) : base(barcode)
{
}
public ScannableReference(string barcode) : base(barcode)
{
}
public new T Scannable
{
get
{
T retScannable = null;
if (AssetWarehouse.ready)
{
AssetWarehouse.Instance.TryGetScannable<T>(Barcode, out retScannable);
}
return retScannable;
}
}
public bool TryGetScannable(out T scannable)
{
scannable = null;
bool success = false;
if (AssetWarehouse.ready)
{
success = AssetWarehouse.Instance.TryGetScannable<T>(Barcode, out scannable);
}
return success;
}
}
}

View file

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

View file

@ -0,0 +1,10 @@
using UnityEngine;
namespace SLZ.Marrow.Warehouse
{
public class SpawnableCrate : GameObjectCrate
{
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 34569ddb84e20304981812b1c448d930
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 7fbe9ce551adfb54c91a36473ba3622d, type: 3}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,50 @@
using System.Collections.Generic;
using UnityEngine;
namespace SLZ.Marrow.Warehouse
{
public class SurfaceDataCard : DataCard
{
[Header("Options")]
[Range(.001f, 1f)]
public float PenetrationResistance = 0.9f;
public float megaPascal = 100f;
[SerializeField]
private MarrowAssetT<PhysicMaterial> _physicsMaterial;
public MarrowAssetT<PhysicMaterial> PhysicsMaterial { get => _physicsMaterial; set => _physicsMaterial = value; }
[SerializeField]
private MarrowAssetT<PhysicMaterial> _physicsMaterialStatic;
public MarrowAssetT<PhysicMaterial> PhysicsMaterialStatic { get => _physicsMaterialStatic; set => _physicsMaterialStatic = value; }
public override bool IsBundledDataCard()
{
return true;
}
public override void ImportPackedAssets(Dictionary<string, PackedAsset> packedAssets)
{
base.ImportPackedAssets(packedAssets);
if (packedAssets.TryGetValue("PhysicsMaterial", out var packedAsset))
PhysicsMaterial = new MarrowAssetT<PhysicMaterial>(packedAsset.marrowAsset.AssetGUID);
if (packedAssets.TryGetValue("PhysicsMaterialStatic", out packedAsset))
PhysicsMaterialStatic = new MarrowAssetT<PhysicMaterial>(packedAsset.marrowAsset.AssetGUID);
#if false
#endif
}
public override List<PackedAsset> ExportPackedAssets()
{
base.ExportPackedAssets();
PackedAssets.Add(new PackedAsset("PhysicsMaterial", PhysicsMaterial, PhysicsMaterial.AssetType, "_physicsMaterial"));
PackedAssets.Add(new PackedAsset("PhysicsMaterialStatic", PhysicsMaterialStatic, PhysicsMaterialStatic.AssetType, "_physicsMaterialStatic"));
#if false
#endif
return PackedAssets;
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4ac6ff899326b8c4ea66ba52f4db5399
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: a52afab4341110f4d95bc00c911aa348, type: 3}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,70 @@
using System;
using System.Collections.Generic;
using UnityEngine;
namespace SLZ.Marrow.Warehouse
{
[Serializable]
public class TagList
{
[SerializeField]
public List<BoneTagReference> _tags = new List<BoneTagReference>();
public List<BoneTagReference> Tags { get => _tags; }
private HashSet<Barcode> _cachedTagBarcodes = new HashSet<Barcode>();
public HashSet<Barcode> CachedTagBarcodes
{
get
{
if (!initialCache)
{
UpdateCache();
}
return _cachedTagBarcodes;
}
set => _cachedTagBarcodes = value;
}
public ITaggable InheritTags { get => _inheritTags; set => _inheritTags = value; }
private ITaggable _inheritTags;
private bool initialCache = false;
public void UpdateCache(bool initializeOnly = false)
{
if (!initializeOnly || !initialCache)
{
initialCache = true;
_cachedTagBarcodes ??= new HashSet<Barcode>();
_cachedTagBarcodes.Clear();
if (_inheritTags != null)
{
_inheritTags.Tags.UpdateCache(true);
foreach (var tag in _inheritTags.Tags.Tags)
{
if (!_tags.Contains(tag))
{
_tags.Add(tag);
}
}
}
foreach (var tag in _tags)
{
if (!_cachedTagBarcodes.Contains(tag.Barcode))
{
_cachedTagBarcodes.Add(tag.Barcode);
}
}
}
}
}
public interface ITaggable
{
public TagList Tags { get; }
}
}

View file

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

View file

@ -0,0 +1,22 @@
using System;
using UnityEngine;
namespace SLZ.Marrow.Warehouse
{
[Serializable]
public class TagQuery
{
[SerializeField]
private BoneTagReference _boneTag;
public BoneTagReference BoneTag { get => _boneTag; set => _boneTag = value; }
[Tooltip("Exclude")]
[SerializeField]
public bool _invert = false;
public bool Invert { get => _invert; set => _invert = value; }
}
}

View file

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

View file

@ -0,0 +1,10 @@
using UnityEngine;
namespace SLZ.Marrow.Warehouse
{
public class VFXCrate : SpawnableCrate
{
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 99205389fc37c2e4e9e5a189355b13c6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: ba5352914a0253747974e3ea9e59b7d4, type: 3}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,116 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.ResourceLocations;
using UnityEngine.ResourceManagement.ResourceProviders;
namespace SLZ.Marrow.Warehouse
{
public static class WarehousePathResolver
{
private static Dictionary<string, string> cache = new Dictionary<string, string>();
private static bool enableLogging = false;
public static void Setup()
{
cache.Clear();
Addressables.InternalIdTransformFunc = ResolvePath;
}
private static void Log(string message)
{
if (enableLogging)
Debug.Log($"WarehousePathResolver: {message}");
}
private static void LogError(string message)
{
if (enableLogging)
Debug.LogError($"WarehousePathResolver: {message}");
}
public static string EnsureValidPath(string path)
{
string returnPath = $"{path}";
EnsureValidPath(ref returnPath);
return returnPath;
}
public static void EnsureValidPath(ref string path)
{
if (path.Contains("\\"))
path = path.Replace("\\", "/");
#if !UNITY_EDITOR && UNITY_ANDROID
#endif
}
static string ResolvePath(IResourceLocation location)
{
Log($"Initial: Path \"{location.InternalId}\"");
try
{
if (location.ResourceType == typeof(IAssetBundleResource))
{
if (cache.TryGetValue(location.InternalId, out var cachedPath))
{
Log($"Use Cached value: InternalId[{location.InternalId}], cachedPath[{cachedPath}]");
return cachedPath;
}
string newLocation = location.InternalId;
if (!newLocation.Contains("settingsassets"))
{
if (newLocation.StartsWith(SLZ.Marrow.MarrowSDK.RuntimeModsPath, System.StringComparison.Ordinal))
{
newLocation = location.InternalId.Replace("\\", "/");
var relativePath = Path.GetRelativePath(SLZ.Marrow.MarrowSDK.RuntimeModsPath, newLocation);
string palletBarcode = relativePath.Split('/')[0];
relativePath = string.Join('/', relativePath.Split('/').Skip(1));
if (AssetWarehouse.Instance.TryGetPalletManifest(new Barcode(palletBarcode), out var palletManifest))
{
var newRoot = Path.GetDirectoryName(palletManifest.CatalogPath);
newLocation = $"{newRoot}/{relativePath}";
}
Log($"Path \"{newLocation}\" from ({location.InternalId})");
}
else if (newLocation.StartsWith("PALLET_BARCODE:"))
{
var arrSplit = newLocation.Split(':');
var palletBarcode = arrSplit[1];
var relativePath = arrSplit[2];
relativePath = relativePath.Substring(1, relativePath.Length - 1);
Log($"Pallet[{palletBarcode}] Path: \"{newLocation}\" \"{location.InternalId}\"");
if (AssetWarehouse.Instance.TryGetPalletManifest(new Barcode(palletBarcode), out var palletManifest))
{
newLocation = $"{Path.GetDirectoryName(palletManifest.CatalogPath)}/{relativePath}";
}
else
{
LogError($"Failed to find Pallet Manifest for {palletBarcode} for path \"{newLocation}\"");
return newLocation;
}
}
}
EnsureValidPath(ref newLocation);
if (newLocation != location.InternalId)
cache[location.InternalId] = newLocation;
Log($"Fixed: Path \"{newLocation}\"");
return newLocation;
}
}
catch
{
return location.InternalId;
}
var locationText = location.InternalId;
EnsureValidPath(ref locationText);
Log($"Untouched: Path \"{locationText}\"");
return locationText;
}
}
}

View file

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