Skip to content
Open
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
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

### Fixed

- Fixed GameplayTags not loading from StreamingAssets on Android (APK/AAB)
- Fixed GameplayTags not loading from StreamingAssets on WebGL

## [0.1.0-beta.8] - 2025-09-22

### Fixed
Expand Down
51 changes: 49 additions & 2 deletions Runtime/BuildGameplayTagSource.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.IO;
using UnityEngine;
using UnityEngine.Networking;

namespace BandoWare.GameplayTags
{
Expand All @@ -12,8 +13,11 @@ public void RegisterTags(GameplayTagRegistrationContext context)
{
try
{
using FileStream file = File.OpenRead(Path.Combine(Application.streamingAssetsPath, "GameplayTags"));
using BinaryReader reader = new(file);
string path = Path.Combine(Application.streamingAssetsPath, "GameplayTags");
byte[] data = LoadData(path);

using MemoryStream memoryStream = new(data);
using BinaryReader reader = new(memoryStream);

while (reader.BaseStream.Position != reader.BaseStream.Length)
{
Expand All @@ -26,5 +30,48 @@ public void RegisterTags(GameplayTagRegistrationContext context)
Debug.LogError($"Failed to load gameplay tags from StreamingAssets: {e.Message}");
}
}

private byte[] LoadData(string dataPath)
{
return Application.platform switch
{
RuntimePlatform.WebGLPlayer => LoadDataFromWebRequest(dataPath),
RuntimePlatform.Android => LoadDataFromWebRequest(dataPath),
_ => LoadDataFromFile(dataPath),
};
}

private byte[] LoadDataFromWebRequest(string dataPath)
{
using UnityWebRequest request = UnityWebRequest.Get(dataPath);
UnityWebRequestAsyncOperation operation = request.SendWebRequest();
while (!operation.isDone) { }

#if UNITY_2020_2_OR_NEWER
if (request.result != UnityWebRequest.Result.Success)
#else
if (request.isNetworkError || request.isHttpError)
#endif
{
if (request.responseCode == 404)
Debug.LogError($"GameplayTags file not found at path: {dataPath}");
else
Debug.LogError($"Failed to load gameplay tags from StreamingAssets: {request.error}");

return Array.Empty<byte>();
}

return request.downloadHandler.data;
}

private byte[] LoadDataFromFile(string path)
{
if (!File.Exists(path))
{
Debug.LogError($"GameplayTags file not found at path: {path}");
return Array.Empty<byte>();
}
return File.ReadAllBytes(path);
}
}
}
20 changes: 10 additions & 10 deletions Runtime/GameplayTagContainerExtensionMethods.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,24 +47,24 @@ private static bool HasAnyInternal(List<int> tagIndices, List<int> otherTagIndic
end = ~end;

int j = 1;
int i = start + 1;
while (i < end && j < otherTagIndices.Count)
int i = start;
int otherLimit = otherTagIndices.Count - 1;

while (i < end && j < otherLimit)
{
if (otherTagIndices[j] == tagIndices[i])
int tagVal = tagIndices[i];
int otherVal = otherTagIndices[j];

if (tagVal == otherVal)
return true;

if (tagIndices[i] > otherTagIndices[j])
if (tagVal < otherVal)
{
i++;
continue;
}

j++;
while (otherTagIndices[j] < tagIndices[i])
else
{
j++;
if (j == end)
return false;
}
}

Expand Down