119 lines
3.7 KiB
C#
119 lines
3.7 KiB
C#
|
|
// CommandBank.cs — ładuje commands.json z StreamingAssets, udostępnia losowe
|
||
|
|
// polecenia per-level. Samoistny MonoBehaviour; podepnij do dowolnego GameObject.
|
||
|
|
//
|
||
|
|
// Plik commands.json generuj offline:
|
||
|
|
// python -m ipin_vr export --per-level 300 --out commands.json
|
||
|
|
// Następnie umieść go w Assets/StreamingAssets/commands.json.
|
||
|
|
|
||
|
|
using System;
|
||
|
|
using System.Collections;
|
||
|
|
using System.Collections.Generic;
|
||
|
|
using System.IO;
|
||
|
|
using UnityEngine;
|
||
|
|
using UnityEngine.Networking;
|
||
|
|
|
||
|
|
namespace IpinVr
|
||
|
|
{
|
||
|
|
[Serializable]
|
||
|
|
public class CommandEntry
|
||
|
|
{
|
||
|
|
public int level;
|
||
|
|
public string text;
|
||
|
|
}
|
||
|
|
|
||
|
|
[Serializable]
|
||
|
|
internal class BankMeta
|
||
|
|
{
|
||
|
|
public string version;
|
||
|
|
public int per_level;
|
||
|
|
}
|
||
|
|
|
||
|
|
[Serializable]
|
||
|
|
internal class BankData
|
||
|
|
{
|
||
|
|
public BankMeta meta;
|
||
|
|
public List<CommandEntry> commands;
|
||
|
|
}
|
||
|
|
|
||
|
|
public class CommandBank : MonoBehaviour
|
||
|
|
{
|
||
|
|
[SerializeField] private string jsonFileName = "commands.json";
|
||
|
|
|
||
|
|
private readonly Dictionary<int, List<string>> _byLevel = new();
|
||
|
|
private bool _loaded;
|
||
|
|
|
||
|
|
public bool IsLoaded => _loaded;
|
||
|
|
|
||
|
|
/// <summary>Wczytaj bank asynchronicznie. onDone wywoływane po załadowaniu.</summary>
|
||
|
|
public void Load(Action onDone = null)
|
||
|
|
{
|
||
|
|
StartCoroutine(LoadCoroutine(onDone));
|
||
|
|
}
|
||
|
|
|
||
|
|
private IEnumerator LoadCoroutine(Action onDone)
|
||
|
|
{
|
||
|
|
string srcPath = Path.Combine(Application.streamingAssetsPath, jsonFileName);
|
||
|
|
string json;
|
||
|
|
|
||
|
|
#if UNITY_ANDROID && !UNITY_EDITOR
|
||
|
|
// Na Androidzie StreamingAssets są wewnątrz APK — czytamy przez WebRequest.
|
||
|
|
using var req = UnityWebRequest.Get(srcPath);
|
||
|
|
yield return req.SendWebRequest();
|
||
|
|
if (req.result != UnityWebRequest.Result.Success)
|
||
|
|
{
|
||
|
|
Debug.LogError($"[CommandBank] Błąd wczytywania {jsonFileName}: {req.error}");
|
||
|
|
yield break;
|
||
|
|
}
|
||
|
|
json = req.downloadHandler.text;
|
||
|
|
#else
|
||
|
|
if (!File.Exists(srcPath))
|
||
|
|
{
|
||
|
|
Debug.LogError($"[CommandBank] Plik nie istnieje: {srcPath}");
|
||
|
|
yield break;
|
||
|
|
}
|
||
|
|
json = File.ReadAllText(srcPath);
|
||
|
|
yield return null;
|
||
|
|
#endif
|
||
|
|
|
||
|
|
var data = JsonUtility.FromJson<BankData>(json);
|
||
|
|
if (data?.commands == null)
|
||
|
|
{
|
||
|
|
Debug.LogError("[CommandBank] Nie można sparsować commands.json");
|
||
|
|
yield break;
|
||
|
|
}
|
||
|
|
|
||
|
|
_byLevel.Clear();
|
||
|
|
foreach (var entry in data.commands)
|
||
|
|
{
|
||
|
|
if (!_byLevel.TryGetValue(entry.level, out var list))
|
||
|
|
_byLevel[entry.level] = list = new List<string>();
|
||
|
|
list.Add(entry.text);
|
||
|
|
}
|
||
|
|
|
||
|
|
int total = data.commands.Count;
|
||
|
|
Debug.Log($"[CommandBank] Wczytano {total} poleceń (v{data.meta?.version})");
|
||
|
|
_loaded = true;
|
||
|
|
onDone?.Invoke();
|
||
|
|
}
|
||
|
|
|
||
|
|
/// <summary>Zwraca losowe polecenie dla danego poziomu, lub null jeśli brak.</summary>
|
||
|
|
public string GetRandom(int level)
|
||
|
|
{
|
||
|
|
if (!_loaded)
|
||
|
|
{
|
||
|
|
Debug.LogWarning("[CommandBank] Bank nie jest jeszcze wczytany");
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
if (!_byLevel.TryGetValue(level, out var list) || list.Count == 0)
|
||
|
|
{
|
||
|
|
Debug.LogWarning($"[CommandBank] Brak poleceń dla poziomu {level}");
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
return list[UnityEngine.Random.Range(0, list.Count)];
|
||
|
|
}
|
||
|
|
|
||
|
|
public int CountForLevel(int level) =>
|
||
|
|
_byLevel.TryGetValue(level, out var l) ? l.Count : 0;
|
||
|
|
}
|
||
|
|
}
|