Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,15 @@ All package updates & migration steps will be listed in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [4.5.0] - 2025-03-18
### Added
- `InfoExists` and `HasAssignedValue` getters added to the `ParameterReference<T>`
- Support for `AssetReferenceGameObject`
- Versioning for code gen.
- Support to pass in infos to the `Error` and `Warn` methods in validators.
### Fixed
- Unclear error message when trying to set an incorrect scriptable object by name in a csv.

## [4.4.0] - 2025-03-11
### Added
- Support for circular references of structs if using a `IReadOnlyList`
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#if ADDRESSABLE_PARAMS
using System.Reflection;
using UnityEngine.AddressableAssets;

namespace PocketGems.Parameters.Common.PropertyTypes.Editor
{
internal class AssetReferenceGameObjectListPropertyType : AssetReferenceListPropertyType
{
public AssetReferenceGameObjectListPropertyType(PropertyInfo propertyInfo) : base(propertyInfo)
{
}

protected override string ClassName => nameof(AssetReferenceGameObject);
}
}
#endif

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#if ADDRESSABLE_PARAMS
using System.Reflection;
using UnityEngine.AddressableAssets;

namespace PocketGems.Parameters.Common.PropertyTypes.Editor
{
internal class AssetReferenceGameObjectPropertyType : AssetReferencePropertyType
{
public AssetReferenceGameObjectPropertyType(PropertyInfo propertyInfo) : base(propertyInfo)
{
}

protected override string ClassName => nameof(AssetReferenceGameObject);
}
}
#endif

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions Editor/Common/PropertyTypes/PropertyTypeFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,10 @@ public static IPropertyType Create(IParameterInterface parameterInterface, Prope
return new AssetReferencePropertyType(propertyInfo);
if (propertyType == typeof(IReadOnlyList<AssetReference>))
return new AssetReferenceListPropertyType(propertyInfo);
if (propertyType == typeof(AssetReferenceGameObject))
return new AssetReferenceGameObjectPropertyType(propertyInfo);
if (propertyType == typeof(IReadOnlyList<AssetReferenceGameObject>))
return new AssetReferenceGameObjectListPropertyType(propertyInfo);
if (propertyType == typeof(AssetReferenceSprite))
return new AssetReferenceSpritePropertyType(propertyInfo);
if (propertyType == typeof(IReadOnlyList<AssetReferenceSprite>))
Expand Down
2 changes: 2 additions & 0 deletions README/InterfacesAndEnums.md
Original file line number Diff line number Diff line change
Expand Up @@ -245,9 +245,11 @@ IReadOnlyList<ParameterStructReference<ITransactionStruct>> Rewards { get; }
Addressable asset & sprite references are supported if the [`com.unity.addressables`](https://docs.unity3d.com/Packages/com.unity.addressables@latest/index.html) package is added to the Unity project.
```C#
AssetReference WorldItemPrefab { get; }
AssetReferenceGameObject Node { get; }
AssetReferenceSprite Icon { get; }
AssetReferenceAtlasedSprite Image { get; }
IReadOnlyList<AssetReference> Doobers { get; }
IReadOnlyList<AssetReferenceGameObject> Nodes { get; }
IReadOnlyList<AssetReferenceSprite> LoadingImages { get; }
IReadOnlyList<AssetReferenceAtlasedSprite> Images { get; }
```
Expand Down
2 changes: 1 addition & 1 deletion Runtime/LocalCSV/CSVValueConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ public static ParameterReference<T> FromString<T>(string value)
if (ScriptableObjectLookupCache.Enabled)
{
var data = ScriptableObjectLookupCache.LookUp(value);
for (int i = 0; i < data.Count; i++)
for (int i = 0; i < data?.Count; i++)
{
var path = data[i].Item2;
var asset = AssetDatabase.LoadAssetAtPath<ScriptableObject>(path);
Expand Down
44 changes: 44 additions & 0 deletions Runtime/LocalCSV/CSVValueConverter_Addressable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,24 @@ public static UnityEngine.AddressableAssets.AssetReference FromString(string val
}
}

public static class AssetReferenceGameObject
{
public static string ToString(UnityEngine.AddressableAssets.AssetReferenceGameObject value)
{
return AssetReference.ToString(value);
}

public static UnityEngine.AddressableAssets.AssetReferenceGameObject FromString(string value,
bool validateGuid = false)
{
(string guid, string subObjectName) = AssetReference.ParseString(value, validateGuid);
var reference = new UnityEngine.AddressableAssets.AssetReferenceGameObject(guid);
if (subObjectName != null)
reference.SubObjectName = subObjectName;
return reference;
}
}

public static class AssetReferenceSprite
{
public static string ToString(UnityEngine.AddressableAssets.AssetReferenceSprite value)
Expand Down Expand Up @@ -120,6 +138,32 @@ public static UnityEngine.AddressableAssets.AssetReference[] FromString(string v
}
}

public static class AssetReferenceGameObjectArray
{
public static string ToString(UnityEngine.AddressableAssets.AssetReferenceGameObject[] value)
{
if (value == null)
return "";
var guids = new string[value.Length];
for (int i = 0; i < value.Length; i++)
guids[i] = AssetReferenceGameObject.ToString(value[i]);
return string.Join(ListDelimiter.ToString(), guids);
}

public static UnityEngine.AddressableAssets.AssetReferenceGameObject[] FromString(string value,
bool validateGuid = false)
{
// must return a non null value so we can detect overriding of properties by checking non null
if (string.IsNullOrWhiteSpace(value))
return Array.Empty<UnityEngine.AddressableAssets.AssetReferenceGameObject>();
var guids = value.Split(ListDelimiter);
var assetRefs = new UnityEngine.AddressableAssets.AssetReferenceGameObject[guids.Length];
for (int i = 0; i < guids.Length; i++)
assetRefs[i] = AssetReferenceGameObject.FromString(guids[i], validateGuid);
return assetRefs;
}
}

public static class AssetReferenceSpriteArray
{
public static string ToString(UnityEngine.AddressableAssets.AssetReferenceSprite[] value)
Expand Down
32 changes: 29 additions & 3 deletions Runtime/ParameterReference.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,16 @@ namespace PocketGems.Parameters
public abstract class ParameterReference
{
[SerializeField] protected string guid;
[NonSerialized] protected string _identifier;

/// <summary>
/// Identifier is only set at runtime (abtesting) and not serialized in the editor.
/// The assigned guid that is set typically from in the editor or when loaded from the parameter manager.
/// </summary>
[NonSerialized] protected string _identifier;

public string AssignedGUID => guid;

/// <summary>
/// Identifier is only set at runtime (abtesting) and not serialized in the editor.
/// </summary>
public string AssignedIdentifier => _identifier;

/// <summary>
Expand Down Expand Up @@ -82,6 +85,9 @@ public int CompareTo(ParameterReference<T> other)
return string.Compare(info.Identifier, otherInfo.Identifier);
}

/// <summary>
/// A getter return the parameter info. Null if it doesn't exist.
/// </summary>
public T Info
{
get
Expand All @@ -104,6 +110,26 @@ public T Info
}
}

/// <summary>
/// Returns true if an info exists for the reference.
///
/// A ParameterReference could have HasAssignedValue be true but InfoExists return false.
/// This could happen if the assigned guid/identifier doesn't exist in the ParameterManager
/// due to an incorrect assignment (validation wasn't ran or the identifier was assigned at
/// runtime and incorrect).
/// </summary>
public bool InfoExists => Info != null;

/// <summary>
/// True if this reference has been assigned a guid/identifier that might exist.
///
/// A ParameterReference could have HasAssignedValue be true but InfoExists return false.
/// This could happen if the assigned guid/identifier doesn't exist in the ParameterManager
/// due to an incorrect assignment (validation wasn't ran or the identifier was assigned at
/// runtime and incorrect).
/// </summary>
public bool HasAssignedValue => !string.IsNullOrWhiteSpace(guid) || !string.IsNullOrWhiteSpace(_identifier);

internal T GetInfo(IParameterManager parameterManager)
{
// parameterManager.GetWithGUID will throw a LogError if it doesn't exist since
Expand Down
48 changes: 48 additions & 0 deletions Runtime/Validation/BaseDataValidator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,18 @@ public abstract class BaseDataValidator<T> : ITypedDataValidator<T> where T : cl
/// <param name="parameterManager">parameter manager to query if needed during validation</param>
protected abstract void ValidateParameters(IParameterManager parameterManager);

/// <summary>
/// Log an error during validation.
/// </summary>
/// <param name="info">the info with the issue</param>
/// <param name="propertyName">property name with the error</param>
/// <param name="message">user facing message about the error</param>
protected void Error(T info, string propertyName, string message)
{
var error = new ValidationError(typeof(T), info.Identifier, propertyName, message);
_errors.Add(error);
}

/// <summary>
/// Log an error during validation.
/// </summary>
Expand All @@ -40,6 +52,17 @@ protected void Error(string propertyName, string message)
_errors.Add(error);
}

/// <summary>
/// Log an error during validation.
/// </summary>
/// <param name="info">the info with the issue</param>
/// <param name="message">user facing message about the error</param>
protected void Error(T info, string message)
{
var error = new ValidationError(typeof(T), info.Identifier, null, message);
_errors.Add(error);
}

/// <summary>
/// General error during validation.
/// </summary>
Expand All @@ -50,6 +73,19 @@ protected void Error(string message)
_errors.Add(error);
}

/// <summary>
/// Log a warning during validation.
/// </summary>
/// <param name="info">the info with the issue</param>
/// <param name="propertyName">property name with the warning</param>
/// <param name="message">user facing message about the warning</param>
protected void Warn(T info, string propertyName, string message)
{
var error = new ValidationError(typeof(T), info.Identifier, propertyName, message,
severity: ValidationError.Severity.Warning);
_errors.Add(error);
}

/// <summary>
/// Log a warning during validation.
/// </summary>
Expand All @@ -62,6 +98,18 @@ protected void Warn(string propertyName, string message)
_errors.Add(error);
}

/// <summary>
/// General warning during validation.
/// </summary>
/// <param name="info">the info with the issue</param>
/// <param name="message">user facing message about the warning</param>
protected void Warn(T info, string message)
{
var error = new ValidationError(typeof(T), info.Identifier, null, message,
severity: ValidationError.Severity.Warning);
_errors.Add(error);
}

/// <summary>
/// General warning during validation.
/// </summary>
Expand Down
4 changes: 4 additions & 0 deletions Tests/Editor/Common/PropertyTypes/PropertyTypesTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,11 @@ private interface ITestInfo : IBaseInfo

#if ADDRESSABLE_PARAMS
AssetReference MyAsset { get; }
AssetReferenceGameObject MyGameObject { get; }
AssetReferenceSprite MyAssetSprite { get; }
AssetReferenceAtlasedSprite MyAssetAltasdSprite { get; }
IReadOnlyList<AssetReference> MyAssets { get; }
IReadOnlyList<AssetReferenceGameObject> MyGameObjects { get; }
IReadOnlyList<AssetReferenceSprite> MyAssetSprites { get; }
IReadOnlyList<AssetReferenceAtlasedSprite> MyAssetAltasdSprites { get; }
#endif
Expand Down Expand Up @@ -228,9 +230,11 @@ public void ValidateIdentifier()
[TestCase(nameof(ITestInfo.MyStructs))]
#if ADDRESSABLE_PARAMS
[TestCase(nameof(ITestInfo.MyAsset))]
[TestCase(nameof(ITestInfo.MyGameObject))]
[TestCase(nameof(ITestInfo.MyAssetSprite))]
[TestCase(nameof(ITestInfo.MyAssetAltasdSprite))]
[TestCase(nameof(ITestInfo.MyAssets))]
[TestCase(nameof(ITestInfo.MyGameObjects))]
[TestCase(nameof(ITestInfo.MyAssetSprites))]
[TestCase(nameof(ITestInfo.MyAssetAltasdSprites))]
#endif
Expand Down
Loading
Loading