ShopDone
This commit is contained in:
parent
c15e5ce868
commit
7ed85b882f
154
Assets/GameShop.cs
Normal file
154
Assets/GameShop.cs
Normal file
@ -0,0 +1,154 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using TMPro;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using TPSBR;
|
||||
|
||||
public class GameShop : MonoBehaviour
|
||||
{
|
||||
[Serializable]
|
||||
public class ShopItem
|
||||
{
|
||||
public Button buyButton;
|
||||
public TMP_Text buyLabel;
|
||||
public TMP_Text nameLabel;
|
||||
public Image iconImage;
|
||||
public string id;
|
||||
public int price;
|
||||
}
|
||||
|
||||
public AgentSettings agentSettings;
|
||||
public string shopKey = "Characters";
|
||||
public List<ShopItem> items = new();
|
||||
|
||||
public event Action<string> OnPurchaseSuccess;
|
||||
public event Action<string> OnPurchaseFail;
|
||||
|
||||
string WalletAddress => PlayerPrefs.GetString("WALLET_ADDRESS", "");
|
||||
|
||||
void Start()
|
||||
{
|
||||
ApplyCatalogIfPresent();
|
||||
EnsureFirstUnlocked();
|
||||
RefreshUI();
|
||||
}
|
||||
|
||||
void ApplyCatalogIfPresent()
|
||||
{
|
||||
if (agentSettings == null || agentSettings.Agents == null || agentSettings.Agents.Length == 0)
|
||||
{
|
||||
for (int i = 0; i < items.Count; i++)
|
||||
if (string.IsNullOrWhiteSpace(items[i].id)) items[i].id = $"Item{i + 1}";
|
||||
return;
|
||||
}
|
||||
|
||||
int count = Mathf.Min(items.Count, agentSettings.Agents.Length);
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
var a = agentSettings.Agents[i];
|
||||
var slot = items[i];
|
||||
slot.id = a.ID;
|
||||
slot.price = a.Price;
|
||||
if (slot.nameLabel) slot.nameLabel.text = string.IsNullOrEmpty(a.DisplayName) ? a.ID : a.DisplayName;
|
||||
if (slot.iconImage) slot.iconImage.sprite = a.Icon;
|
||||
}
|
||||
for (int i = count; i < items.Count; i++)
|
||||
if (string.IsNullOrWhiteSpace(items[i].id)) items[i].id = $"Item{i + 1}";
|
||||
}
|
||||
|
||||
void EnsureFirstUnlocked()
|
||||
{
|
||||
if (items.Count == 0) return;
|
||||
var id = string.IsNullOrWhiteSpace(items[0].id) ? "Item1" : items[0].id;
|
||||
ShopUnlocks.EnsureUnlocked(id, shopKey);
|
||||
}
|
||||
|
||||
public void TryBuy(string id)
|
||||
{
|
||||
int idx = items.FindIndex(s => s.id == id);
|
||||
if (idx < 0) return;
|
||||
if (ShopUnlocks.IsUnlocked(id, shopKey)) return;
|
||||
//if (string.IsNullOrEmpty(WalletAddress))
|
||||
//{
|
||||
// OnPurchaseFail?.Invoke(id);
|
||||
// return;
|
||||
//}
|
||||
StartCoroutine(SimPurchase(idx));
|
||||
}
|
||||
long currentPrice;
|
||||
public async void GetCurrency()
|
||||
{
|
||||
try
|
||||
{
|
||||
var rec = await GameDb.GetCurrencyAsync(PlayerPrefs.GetString("WALLET_ADDRESS"));
|
||||
currentPrice = rec;
|
||||
Debug.Log(rec.ToString());
|
||||
}
|
||||
catch (System.Exception e)
|
||||
{
|
||||
Debug.LogError($"[Runtime] ❌ Ensure failed: {e.Message}");
|
||||
}
|
||||
}
|
||||
IEnumerator SimPurchase(int idx)
|
||||
{
|
||||
yield return new WaitForSeconds(0.6f);
|
||||
var id = items[idx].id;
|
||||
bool ok = true;
|
||||
Debug.Log("CurrentPrice: " + currentPrice);
|
||||
if (items[idx].price > currentPrice)
|
||||
{
|
||||
ok = false;
|
||||
}
|
||||
if (ok)
|
||||
{
|
||||
ShopUnlocks.Unlock(id, shopKey);
|
||||
RefreshUI();
|
||||
OnPurchaseSuccess?.Invoke(id);
|
||||
}
|
||||
else
|
||||
{
|
||||
OnPurchaseFail?.Invoke(id);
|
||||
}
|
||||
}
|
||||
|
||||
void RefreshUI()
|
||||
{
|
||||
for (int i = 0; i < items.Count; i++)
|
||||
{
|
||||
var slot = items[i];
|
||||
bool owned = !string.IsNullOrWhiteSpace(slot.id) && ShopUnlocks.IsUnlocked(slot.id, shopKey);
|
||||
|
||||
if (slot.buyButton)
|
||||
{
|
||||
if (i == 0)
|
||||
{
|
||||
slot.buyButton.gameObject.SetActive(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
slot.buyButton.onClick.RemoveAllListeners();
|
||||
slot.buyButton.gameObject.SetActive(!owned);
|
||||
if (!owned)
|
||||
{
|
||||
var label = slot.buyLabel ? slot.buyLabel : slot.buyButton.GetComponentInChildren<TMP_Text>(true);
|
||||
if (label) label.text = $"BUY {slot.price}";
|
||||
string captured = slot.id;
|
||||
slot.buyButton.onClick.AddListener(() => TryBuy(captured));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//if (slot.lockIcon) slot.lockIcon.SetActive(!owned);
|
||||
}
|
||||
}
|
||||
|
||||
[ContextMenu("Reset Unlocks")]
|
||||
void ResetUnlocks()
|
||||
{
|
||||
ShopUnlocks.Reset(shopKey);
|
||||
EnsureFirstUnlocked();
|
||||
RefreshUI();
|
||||
}
|
||||
}
|
2
Assets/GameShop.cs.meta
Normal file
2
Assets/GameShop.cs.meta
Normal file
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1b835a5fa377df241b3fbd1bafa29e3f
|
109
Assets/TPSBR/Resources/Settings/.AgentSettings.asset
Normal file
109
Assets/TPSBR/Resources/Settings/.AgentSettings.asset
Normal file
@ -0,0 +1,109 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!114 &11400000
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 0}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: d671857a3d898af44a6648a7fb09ec93, type: 3}
|
||||
m_Name: AgentSettings
|
||||
m_EditorClassIdentifier:
|
||||
_agents:
|
||||
- _id: Agent.Murica
|
||||
_displayName: Agent Murica
|
||||
_description: Nobody knows where Soldier 66 came from. There are rumors that
|
||||
he was a high profile hitman before undergoing a series of experimental operations
|
||||
to become half human and half machine. He is famous for not following any sort
|
||||
of rules which makes him particularly dangerous... thing.
|
||||
_icon: {fileID: 21300000, guid: de96ec25bc0cde44da577c80ea1f82ba, type: 3}
|
||||
_agentPrefab:
|
||||
RawGuidValue: 25bcc93b9af98714db0c016d73cdf473
|
||||
_menuAgentPrefab: {fileID: 2529299778790674133, guid: c9914cf34da803d49b5e31f50065d2a8, type: 3}
|
||||
<<<<<<< Updated upstream
|
||||
=======
|
||||
_price: 0
|
||||
>>>>>>> Stashed changes
|
||||
- _id: Agent.Chill
|
||||
_displayName: Chill Guy 69
|
||||
_description: Nobody knows where Soldier 66 came from. There are rumors that
|
||||
he was a high profile hitman before undergoing a series of experimental operations
|
||||
to become half human and half machine. He is famous for not following any sort
|
||||
of rules which makes him particularly dangerous... thing.
|
||||
_icon: {fileID: 21300000, guid: 7db05483dc3839c4883ca3e2b66df14d, type: 3}
|
||||
_agentPrefab:
|
||||
RawGuidValue: 93ce630958493824d9666ef32598805a
|
||||
_menuAgentPrefab: {fileID: 2529299778790674133, guid: 4d7cd885811c2de41929ce728130362a, type: 3}
|
||||
<<<<<<< Updated upstream
|
||||
=======
|
||||
_price: 0
|
||||
>>>>>>> Stashed changes
|
||||
- _id: Agent.Giga
|
||||
_displayName: Agent Giga
|
||||
_description: Nobody knows where Soldier 66 came from. There are rumors that
|
||||
he was a high profile hitman before undergoing a series of experimental operations
|
||||
to become half human and half machine. He is famous for not following any sort
|
||||
of rules which makes him particularly dangerous... thing.
|
||||
_icon: {fileID: 21300000, guid: 928a858e2d7bc4240ab755a303f80754, type: 3}
|
||||
_agentPrefab:
|
||||
RawGuidValue: f5e09845b4019b54c8e01d74fb2a0aad
|
||||
_menuAgentPrefab: {fileID: 2529299778790674133, guid: 8aa7b8ab6c55f8c4daf5cd89dbd56ed6, type: 3}
|
||||
_price: 0
|
||||
- _id: Agent.Ibiza
|
||||
_displayName: Agent Ibiza
|
||||
_description: Nobody knows where Soldier 66 came from. There are rumors that
|
||||
he was a high profile hitman before undergoing a series of experimental operations
|
||||
to become half human and half machine. He is famous for not following any sort
|
||||
of rules which makes him particularly dangerous... thing.
|
||||
_icon: {fileID: 21300000, guid: e220f8fe51b977a44b56b8d591031523, type: 3}
|
||||
_agentPrefab:
|
||||
RawGuidValue: 8921d406664cf914cb61b178d44a29f6
|
||||
_menuAgentPrefab: {fileID: 2529299778790674133, guid: b314a16b062b9e344bb98658202d47ea, type: 3}
|
||||
_price: 0
|
||||
- _id: Agent.Pengu
|
||||
_displayName: 'The Pengu '
|
||||
_description: Nobody knows where Soldier 66 came from. There are rumors that
|
||||
he was a high profile hitman before undergoing a series of experimental operations
|
||||
to become half human and half machine. He is famous for not following any sort
|
||||
of rules which makes him particularly dangerous... thing.
|
||||
_icon: {fileID: 21300000, guid: b586dceca1f89ae48b7b20796e2a7efe, type: 3}
|
||||
_agentPrefab:
|
||||
RawGuidValue: 968b88cacf761be438f090ab6c312eeb
|
||||
_menuAgentPrefab: {fileID: 2529299778790674133, guid: f798ef3c64f2c0947ac23690465302d1, type: 3}
|
||||
_price: 0
|
||||
- _id: Agent.Shiba
|
||||
_displayName: Agent.Shiba 69
|
||||
_description: Nobody knows where Soldier 66 came from. There are rumors that
|
||||
he was a high profile hitman before undergoing a series of experimental operations
|
||||
to become half human and half machine. He is famous for not following any sort
|
||||
of rules which makes him particularly dangerous... thing.
|
||||
_icon: {fileID: 21300000, guid: 9c635e9c55e3d9e409cec904852cc362, type: 3}
|
||||
_agentPrefab:
|
||||
RawGuidValue: bc5d02ffcf614c642a5423f0330ab4e7
|
||||
_menuAgentPrefab: {fileID: 2529299778790674133, guid: 70258e6ed9efedf45b2d169ecfee5be7, type: 3}
|
||||
_price: 0
|
||||
- _id: Agent.UFD
|
||||
_displayName: Agent UFD
|
||||
_description: Nobody knows where Soldier 66 came from. There are rumors that
|
||||
he was a high profile hitman before undergoing a series of experimental operations
|
||||
to become half human and half machine. He is famous for not following any sort
|
||||
of rules which makes him particularly dangerous... thing.
|
||||
_icon: {fileID: 21300000, guid: ee947c4b89d84c644ad4523d07e9182a, type: 3}
|
||||
_agentPrefab:
|
||||
RawGuidValue: 926a6549963ce944cad146ee2ff1b35b
|
||||
_menuAgentPrefab: {fileID: 2529299778790674133, guid: be89f8a6c7f67974b9059935e9777637, type: 3}
|
||||
_price: 0
|
||||
- _id: Agent.Labubu
|
||||
_displayName: Agent.Shiba 69
|
||||
_description: Nobody knows where Soldier 66 came from. There are rumors that
|
||||
he was a high profile hitman before undergoing a series of experimental operations
|
||||
to become half human and half machine. He is famous for not following any sort
|
||||
of rules which makes him particularly dangerous... thing.
|
||||
_icon: {fileID: 21300000, guid: 1ba05e07e079e2a449992e3a311da9ea, type: 3}
|
||||
_agentPrefab:
|
||||
RawGuidValue: 7fca5f30246801846aae5cc6618d32d6
|
||||
_menuAgentPrefab: {fileID: 2529299778790674133, guid: 29b91992f24646a478fe434046a51132, type: 3}
|
||||
_price: 0
|
15
Assets/TPSBR/Resources/Settings/.AgentSettings.asset.meta
Normal file
15
Assets/TPSBR/Resources/Settings/.AgentSettings.asset.meta
Normal file
@ -0,0 +1,15 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bc0d3b3598b234945b6595818b535e11
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 11400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 226753
|
||||
packageName: BR200 - Battle Royale Multiplayer - Photon Fusion
|
||||
packageVersion: 2.0.2
|
||||
assetPath: Assets/TPSBR/Resources/Settings/AgentSettings.asset
|
||||
uploadId: 718661
|
@ -23,6 +23,7 @@ MonoBehaviour:
|
||||
_agentPrefab:
|
||||
RawGuidValue: 25bcc93b9af98714db0c016d73cdf473
|
||||
_menuAgentPrefab: {fileID: 2529299778790674133, guid: c9914cf34da803d49b5e31f50065d2a8, type: 3}
|
||||
_price: 0
|
||||
- _id: Agent.Chill
|
||||
_displayName: Chill Guy 69
|
||||
_description: Nobody knows where Soldier 66 came from. There are rumors that
|
||||
@ -33,6 +34,7 @@ MonoBehaviour:
|
||||
_agentPrefab:
|
||||
RawGuidValue: 93ce630958493824d9666ef32598805a
|
||||
_menuAgentPrefab: {fileID: 2529299778790674133, guid: 4d7cd885811c2de41929ce728130362a, type: 3}
|
||||
_price: 0
|
||||
- _id: Agent.Giga
|
||||
_displayName: Agent Giga
|
||||
_description: Nobody knows where Soldier 66 came from. There are rumors that
|
||||
@ -43,6 +45,7 @@ MonoBehaviour:
|
||||
_agentPrefab:
|
||||
RawGuidValue: f5e09845b4019b54c8e01d74fb2a0aad
|
||||
_menuAgentPrefab: {fileID: 2529299778790674133, guid: 8aa7b8ab6c55f8c4daf5cd89dbd56ed6, type: 3}
|
||||
_price: 0
|
||||
- _id: Agent.Ibiza
|
||||
_displayName: Agent Ibiza
|
||||
_description: Nobody knows where Soldier 66 came from. There are rumors that
|
||||
@ -53,6 +56,7 @@ MonoBehaviour:
|
||||
_agentPrefab:
|
||||
RawGuidValue: 8921d406664cf914cb61b178d44a29f6
|
||||
_menuAgentPrefab: {fileID: 2529299778790674133, guid: b314a16b062b9e344bb98658202d47ea, type: 3}
|
||||
_price: 0
|
||||
- _id: Agent.Pengu
|
||||
_displayName: 'The Pengu '
|
||||
_description: Nobody knows where Soldier 66 came from. There are rumors that
|
||||
@ -63,6 +67,7 @@ MonoBehaviour:
|
||||
_agentPrefab:
|
||||
RawGuidValue: 968b88cacf761be438f090ab6c312eeb
|
||||
_menuAgentPrefab: {fileID: 2529299778790674133, guid: f798ef3c64f2c0947ac23690465302d1, type: 3}
|
||||
_price: 0
|
||||
- _id: Agent.Shiba
|
||||
_displayName: Agent.Shiba 69
|
||||
_description: Nobody knows where Soldier 66 came from. There are rumors that
|
||||
@ -73,6 +78,7 @@ MonoBehaviour:
|
||||
_agentPrefab:
|
||||
RawGuidValue: bc5d02ffcf614c642a5423f0330ab4e7
|
||||
_menuAgentPrefab: {fileID: 2529299778790674133, guid: 70258e6ed9efedf45b2d169ecfee5be7, type: 3}
|
||||
_price: 0
|
||||
- _id: Agent.UFD
|
||||
_displayName: Agent UFD
|
||||
_description: Nobody knows where Soldier 66 came from. There are rumors that
|
||||
@ -83,6 +89,7 @@ MonoBehaviour:
|
||||
_agentPrefab:
|
||||
RawGuidValue: 926a6549963ce944cad146ee2ff1b35b
|
||||
_menuAgentPrefab: {fileID: 2529299778790674133, guid: be89f8a6c7f67974b9059935e9777637, type: 3}
|
||||
_price: 0
|
||||
- _id: Agent.Labubu
|
||||
_displayName: Agent.Shiba 69
|
||||
_description: Nobody knows where Soldier 66 came from. There are rumors that
|
||||
@ -93,3 +100,4 @@ MonoBehaviour:
|
||||
_agentPrefab:
|
||||
RawGuidValue: 7fca5f30246801846aae5cc6618d32d6
|
||||
_menuAgentPrefab: {fileID: 2529299778790674133, guid: 29b91992f24646a478fe434046a51132, type: 3}
|
||||
_price: 0
|
||||
|
@ -28,24 +28,23 @@ MonoBehaviour:
|
||||
m_EditorClassIdentifier:
|
||||
debugShaders:
|
||||
debugReplacementPS: {fileID: 4800000, guid: cf852408f2e174538bcd9b7fda1c5ae7, type: 3}
|
||||
hdrDebugViewPS: {fileID: 4800000, guid: 573620ae32aec764abd4d728906d2587, type: 3}
|
||||
probeVolumeSamplingDebugComputeShader: {fileID: 7200000, guid: 53626a513ea68ce47b59dc1299fe3959, type: 3}
|
||||
probeVolumeResources:
|
||||
probeVolumeDebugShader: {fileID: 0}
|
||||
probeVolumeFragmentationDebugShader: {fileID: 0}
|
||||
probeVolumeOffsetDebugShader: {fileID: 0}
|
||||
probeVolumeSamplingDebugShader: {fileID: 0}
|
||||
probeSamplingDebugMesh: {fileID: 0}
|
||||
probeSamplingDebugTexture: {fileID: 0}
|
||||
probeVolumeBlendStatesCS: {fileID: 0}
|
||||
m_RendererFeatures:
|
||||
- {fileID: -1559360831169181237}
|
||||
m_RendererFeatureMap: cbc980fd95095cea
|
||||
m_UseNativeRenderPass: 0
|
||||
xrSystemData: {fileID: 0}
|
||||
postProcessData: {fileID: 11400000, guid: 41439944d30ece34e96484bdb6645b55, type: 2}
|
||||
shaders:
|
||||
blitPS: {fileID: 4800000, guid: c17132b1f77d20942aa75f8429c0f8bc, type: 3}
|
||||
copyDepthPS: {fileID: 4800000, guid: d6dae50ee9e1bfa4db75f19f99355220, type: 3}
|
||||
screenSpaceShadowPS: {fileID: 4800000, guid: 0f854b35a0cf61a429bd5dcfea30eddd, type: 3}
|
||||
samplingPS: {fileID: 4800000, guid: 04c410c9937594faa893a11dceb85f7e, type: 3}
|
||||
stencilDeferredPS: {fileID: 4800000, guid: e9155b26e1bc55942a41e518703fe304, type: 3}
|
||||
fallbackErrorPS: {fileID: 4800000, guid: e6e9a19c3678ded42a3bc431ebef7dbd, type: 3}
|
||||
materialErrorPS: {fileID: 4800000, guid: 5fd9a8feb75a4b5894c241777f519d4e, type: 3}
|
||||
coreBlitPS: {fileID: 4800000, guid: 93446b5c5339d4f00b85c159e1159b7c, type: 3}
|
||||
coreBlitColorAndDepthPS: {fileID: 4800000, guid: d104b2fc1ca6445babb8e90b0758136b, type: 3}
|
||||
cameraMotionVector: {fileID: 4800000, guid: c56b7e0d4c7cb484e959caeeedae9bbf, type: 3}
|
||||
objectMotionVector: {fileID: 4800000, guid: 7b3ede40266cd49a395def176e1bc486, type: 3}
|
||||
m_AssetVersion: 1
|
||||
m_AssetVersion: 2
|
||||
m_OpaqueLayerMask:
|
||||
serializedVersion: 2
|
||||
m_Bits: 4294967295
|
||||
@ -62,7 +61,8 @@ MonoBehaviour:
|
||||
m_ShadowTransparentReceive: 0
|
||||
m_RenderingMode: 0
|
||||
m_DepthPrimingMode: 0
|
||||
m_CopyDepthMode: 0
|
||||
m_DepthAttachmentFormat: 0
|
||||
m_DepthTextureFormat: 0
|
||||
m_AccurateGbufferNormals: 0
|
||||
m_ClusteredRendering: 0
|
||||
m_TileSize: 32
|
||||
m_IntermediateTextureMode: 1
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -67,5 +67,8 @@ namespace TPSBR
|
||||
private NetworkPrefabRef _agentPrefab;
|
||||
[SerializeField]
|
||||
private GameObject _menuAgentPrefab;
|
||||
}
|
||||
[SerializeField]
|
||||
private int _price = 0;
|
||||
public int Price => _price;
|
||||
}
|
||||
}
|
||||
|
@ -4,111 +4,76 @@ using UnityEngine.UI;
|
||||
|
||||
namespace TPSBR.UI
|
||||
{
|
||||
public sealed class UIListItem : UIListItemBase<MonoBehaviour>
|
||||
{
|
||||
}
|
||||
public sealed class UIListItem : UIListItemBase<MonoBehaviour> { }
|
||||
|
||||
public abstract class UIListItemBase<T> : UIBehaviour where T : MonoBehaviour
|
||||
{
|
||||
// PUBLIC MEMBERS
|
||||
public abstract class UIListItemBase<T> : UIBehaviour where T : MonoBehaviour
|
||||
{
|
||||
public int ID { get; set; }
|
||||
public T Content => _content;
|
||||
public bool IsSelectable => _button != null;
|
||||
public bool IsSelected { get { return _isSelected; } set { SetIsSelected(value); } }
|
||||
public bool IsInteractable { get { return GetIsInteractable(); } set { SetIsInteractable(value); } }
|
||||
public Action<int> Clicked;
|
||||
|
||||
public int ID { get; set; }
|
||||
public T Content => _content;
|
||||
public bool IsSelectable => _button != null;
|
||||
public bool IsSelected { get { return _isSelected; } set { SetIsSelected(value); } }
|
||||
public bool IsInteractable { get { return GetIsInteractable(); } set { SetIsInteractable(value); } }
|
||||
[SerializeField] private Button _button;
|
||||
[SerializeField] private Animator _animator;
|
||||
[SerializeField] private T _content;
|
||||
[SerializeField] private string _selectedAnimatorParameter = "IsSelected";
|
||||
[SerializeField] private CanvasGroup _selectedGroup;
|
||||
[SerializeField] private CanvasGroup _deselectedGroup;
|
||||
[SerializeField] private GameObject _lockGO; // <— assign your LockOverlay here
|
||||
|
||||
public Action<int> Clicked;
|
||||
private bool _isSelected;
|
||||
|
||||
// PRIVATE MEMBERS
|
||||
protected virtual void Awake()
|
||||
{
|
||||
SetIsSelected(false, true);
|
||||
if (_button != null) _button.onClick.AddListener(OnClick);
|
||||
if (_button != null && _button.transition == Selectable.Transition.Animation) _animator = _button.animator;
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private Button _button;
|
||||
[SerializeField]
|
||||
private Animator _animator;
|
||||
[SerializeField]
|
||||
private T _content;
|
||||
[SerializeField]
|
||||
private string _selectedAnimatorParameter = "IsSelected";
|
||||
[SerializeField]
|
||||
private CanvasGroup _selectedGroup;
|
||||
[SerializeField]
|
||||
private CanvasGroup _deselectedGroup;
|
||||
protected virtual void OnDestroy()
|
||||
{
|
||||
Clicked = null;
|
||||
if (_button != null) _button.onClick.RemoveListener(OnClick);
|
||||
}
|
||||
|
||||
private bool _isSelected;
|
||||
public void SetLocked(bool locked)
|
||||
{
|
||||
IsInteractable = !locked; // locked => not interactable
|
||||
if (_lockGO) _lockGO.SetActive(locked); // show lock when NOT bought
|
||||
}
|
||||
|
||||
// MONOBEHAVIOR
|
||||
private void SetIsSelected(bool value, bool force = false)
|
||||
{
|
||||
if (_isSelected == value && force == false) return;
|
||||
_isSelected = value;
|
||||
_selectedGroup.SetVisibility(value);
|
||||
_deselectedGroup.SetVisibility(value == false);
|
||||
UpdateAnimator();
|
||||
}
|
||||
|
||||
protected virtual void Awake()
|
||||
{
|
||||
SetIsSelected(false, true);
|
||||
private bool GetIsInteractable()
|
||||
{
|
||||
return _button != null ? _button.interactable : false;
|
||||
}
|
||||
|
||||
if (_button != null)
|
||||
{
|
||||
_button.onClick.AddListener(OnClick);
|
||||
}
|
||||
private void SetIsInteractable(bool value)
|
||||
{
|
||||
if (_button == null) return;
|
||||
_button.interactable = value;
|
||||
}
|
||||
|
||||
if (_button != null && _button.transition == Selectable.Transition.Animation)
|
||||
{
|
||||
_animator = _button.animator;
|
||||
}
|
||||
}
|
||||
private void OnClick()
|
||||
{
|
||||
Clicked?.Invoke(ID);
|
||||
}
|
||||
|
||||
protected virtual void OnDestroy()
|
||||
{
|
||||
Clicked = null;
|
||||
|
||||
if (_button != null)
|
||||
{
|
||||
_button.onClick.RemoveListener(OnClick);
|
||||
}
|
||||
}
|
||||
|
||||
// PRIVATE METHODS
|
||||
|
||||
private void SetIsSelected(bool value, bool force = false)
|
||||
{
|
||||
if (_isSelected == value && force == false)
|
||||
return;
|
||||
|
||||
_isSelected = value;
|
||||
|
||||
_selectedGroup.SetVisibility(value);
|
||||
_deselectedGroup.SetVisibility(value == false);
|
||||
|
||||
UpdateAnimator();
|
||||
}
|
||||
|
||||
private bool GetIsInteractable()
|
||||
{
|
||||
return _button != null ? _button.interactable : false;
|
||||
}
|
||||
|
||||
private void SetIsInteractable(bool value)
|
||||
{
|
||||
if (_button == null)
|
||||
return;
|
||||
|
||||
_button.interactable = value;
|
||||
}
|
||||
|
||||
private void OnClick()
|
||||
{
|
||||
Clicked?.Invoke(ID);
|
||||
}
|
||||
|
||||
private void UpdateAnimator()
|
||||
{
|
||||
if (_animator == null)
|
||||
return;
|
||||
|
||||
if (_selectedAnimatorParameter.HasValue() == false)
|
||||
return;
|
||||
|
||||
if (_animator != null)
|
||||
{
|
||||
_animator.SetBool(_selectedAnimatorParameter, _isSelected);
|
||||
}
|
||||
}
|
||||
}
|
||||
private void UpdateAnimator()
|
||||
{
|
||||
if (_animator == null) return;
|
||||
if (_selectedAnimatorParameter.HasValue() == false) return;
|
||||
_animator.SetBool(_selectedAnimatorParameter, _isSelected);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,146 +2,274 @@ using System;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using Cinemachine;
|
||||
using System.Collections;
|
||||
|
||||
namespace TPSBR.UI
|
||||
{
|
||||
public class UIAgentSelectionView : UICloseView
|
||||
{
|
||||
// PRIVATE MEMBERS
|
||||
public class UIAgentSelectionView : UICloseView
|
||||
{
|
||||
[SerializeField] private CinemachineVirtualCamera _camera;
|
||||
[SerializeField] private UIList _agentList;
|
||||
[SerializeField] private UIButton _selectButton;
|
||||
[SerializeField] private TextMeshProUGUI _agentName;
|
||||
[SerializeField] private TextMeshProUGUI _agentDescription;
|
||||
[SerializeField] private string _agentNameFormat = "{0}";
|
||||
[SerializeField] private UIBehaviour _selectedAgentGroup;
|
||||
[SerializeField] private UIBehaviour _selectedEffect;
|
||||
[SerializeField] private AudioSetup _selectedSound;
|
||||
[SerializeField] private float _closeDelayAfterSelection = 0.5f;
|
||||
|
||||
[SerializeField]
|
||||
private CinemachineVirtualCamera _camera;
|
||||
[SerializeField]
|
||||
private UIList _agentList;
|
||||
[SerializeField]
|
||||
private UIButton _selectButton;
|
||||
[SerializeField]
|
||||
private TextMeshProUGUI _agentName;
|
||||
[SerializeField]
|
||||
private TextMeshProUGUI _agentDescription;
|
||||
[SerializeField]
|
||||
private string _agentNameFormat = "{0}";
|
||||
[SerializeField]
|
||||
private UIBehaviour _selectedAgentGroup;
|
||||
[SerializeField]
|
||||
private UIBehaviour _selectedEffect;
|
||||
[SerializeField]
|
||||
private AudioSetup _selectedSound;
|
||||
[SerializeField]
|
||||
private float _closeDelayAfterSelection = 0.5f;
|
||||
private string _previewAgent;
|
||||
private const string ShopKey = "Characters";
|
||||
|
||||
private string _previewAgent;
|
||||
protected override void OnInitialize()
|
||||
{
|
||||
base.OnInitialize();
|
||||
_agentList.SelectionChanged += OnSelectionChanged;
|
||||
_agentList.UpdateContent += OnListUpdateContent;
|
||||
_selectButton.onClick.AddListener(OnSelectButton);
|
||||
}
|
||||
|
||||
// UIView INTERFACE
|
||||
private void OnListUpdateContent(int index, MonoBehaviour content)
|
||||
{
|
||||
StartCoroutine(OnListUpdateContentRoutine(index,content));
|
||||
}
|
||||
IEnumerator OnListUpdateContentRoutine(int index, MonoBehaviour content)
|
||||
{
|
||||
yield return new WaitForSeconds(0.2f);
|
||||
var behaviour = content as UIBehaviour;
|
||||
var setup = Context.Settings.Agent.Agents[index];
|
||||
behaviour.Image.sprite = setup.Icon;
|
||||
|
||||
protected override void OnInitialize()
|
||||
{
|
||||
base.OnInitialize();
|
||||
bool owned = index == 0 || ShopUnlocks.IsUnlocked(setup.ID, ShopKey);
|
||||
var item = content.GetComponentInParent<UIListItem>();
|
||||
if (item != null) item.SetLocked(!owned); // lockGO active when NOT bought
|
||||
}
|
||||
protected override void OnOpen()
|
||||
{
|
||||
base.OnOpen();
|
||||
_camera.enabled = true;
|
||||
_selectedEffect.SetActive(false);
|
||||
|
||||
_agentList.SelectionChanged += OnSelectionChanged;
|
||||
_agentList.UpdateContent += OnListUpdateContent;
|
||||
var agents = Context.Settings.Agent.Agents;
|
||||
if (agents != null && agents.Length > 0)
|
||||
ShopUnlocks.EnsureUnlocked(agents[0].ID, ShopKey); // first is free
|
||||
|
||||
_selectButton.onClick.AddListener(OnSelectButton);
|
||||
}
|
||||
_previewAgent = Context.PlayerData.AgentID;
|
||||
_agentList.Refresh(agents.Length, false);
|
||||
UpdateAgent();
|
||||
}
|
||||
|
||||
private void OnListUpdateContent(int index, MonoBehaviour content)
|
||||
{
|
||||
var behaviour = content as UIBehaviour;
|
||||
var setup = Context.Settings.Agent.Agents[index];
|
||||
protected override void OnClose()
|
||||
{
|
||||
_camera.enabled = false;
|
||||
Context.PlayerPreview.ShowAgent(Context.PlayerData.AgentID);
|
||||
base.OnClose();
|
||||
}
|
||||
|
||||
behaviour.Image.sprite = setup.Icon;
|
||||
}
|
||||
protected override void OnDeinitialize()
|
||||
{
|
||||
_agentList.SelectionChanged -= OnSelectionChanged;
|
||||
_agentList.UpdateContent -= OnListUpdateContent;
|
||||
_selectButton.onClick.RemoveListener(OnSelectButton);
|
||||
base.OnDeinitialize();
|
||||
}
|
||||
|
||||
protected override void OnOpen()
|
||||
{
|
||||
base.OnOpen();
|
||||
private void OnSelectionChanged(int index)
|
||||
{
|
||||
var setup = Context.Settings.Agent.Agents[index];
|
||||
bool owned = index == 0 || ShopUnlocks.IsUnlocked(setup.ID, ShopKey);
|
||||
if (!owned) return; // block selecting locked
|
||||
_previewAgent = setup.ID;
|
||||
UpdateAgent();
|
||||
}
|
||||
|
||||
_camera.enabled = true;
|
||||
_selectedEffect.SetActive(false);
|
||||
private void OnSelectButton()
|
||||
{
|
||||
bool isSame = Context.PlayerData.AgentID == _previewAgent;
|
||||
if (isSame == false)
|
||||
{
|
||||
Context.PlayerData.AgentID = _previewAgent;
|
||||
_selectedEffect.SetActive(false);
|
||||
_selectedEffect.SetActive(true);
|
||||
PlaySound(_selectedSound);
|
||||
UpdateAgent();
|
||||
Invoke("CloseWithBack", _closeDelayAfterSelection);
|
||||
}
|
||||
else
|
||||
{
|
||||
CloseWithBack();
|
||||
}
|
||||
}
|
||||
|
||||
_previewAgent = Context.PlayerData.AgentID;
|
||||
private void UpdateAgent()
|
||||
{
|
||||
var agentSetups = Context.Settings.Agent.Agents;
|
||||
_agentList.Selection = Array.FindIndex(agentSetups, t => t.ID == _previewAgent);
|
||||
|
||||
_agentList.Refresh(Context.Settings.Agent.Agents.Length, false);
|
||||
|
||||
UpdateAgent();
|
||||
}
|
||||
if (_agentList.Selection < 0)
|
||||
{
|
||||
int firstOwned = Array.FindIndex(agentSetups, t => ShopUnlocks.IsUnlocked(t.ID, ShopKey));
|
||||
_agentList.Selection = firstOwned >= 0 ? firstOwned : 0;
|
||||
_previewAgent = agentSetups[_agentList.Selection].ID;
|
||||
}
|
||||
|
||||
protected override void OnClose()
|
||||
{
|
||||
_camera.enabled = false;
|
||||
if (_previewAgent.HasValue() == false)
|
||||
{
|
||||
Context.PlayerPreview.HideAgent();
|
||||
_agentName.text = string.Empty;
|
||||
_agentDescription.text = string.Empty;
|
||||
_selectButton.interactable = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
var setup = Context.Settings.Agent.GetAgentSetup(_previewAgent);
|
||||
Context.PlayerPreview.ShowAgent(_previewAgent);
|
||||
_agentName.text = string.Format(_agentNameFormat, setup.DisplayName);
|
||||
_agentDescription.text = setup.Description;
|
||||
_selectButton.interactable = ShopUnlocks.IsUnlocked(_previewAgent, ShopKey);
|
||||
}
|
||||
|
||||
Context.PlayerPreview.ShowAgent(Context.PlayerData.AgentID);
|
||||
|
||||
base.OnClose();
|
||||
}
|
||||
|
||||
protected override void OnDeinitialize()
|
||||
{
|
||||
_agentList.SelectionChanged -= OnSelectionChanged;
|
||||
_agentList.UpdateContent -= OnListUpdateContent;
|
||||
|
||||
_selectButton.onClick.RemoveListener(OnSelectButton);
|
||||
|
||||
base.OnDeinitialize();
|
||||
}
|
||||
|
||||
// PRIVATE METHODS
|
||||
|
||||
private void OnSelectionChanged(int index)
|
||||
{
|
||||
_previewAgent = Context.Settings.Agent.Agents[index].ID;
|
||||
UpdateAgent();
|
||||
}
|
||||
|
||||
private void OnSelectButton()
|
||||
{
|
||||
bool isSame = Context.PlayerData.AgentID == _previewAgent;
|
||||
|
||||
if (isSame == false)
|
||||
{
|
||||
Context.PlayerData.AgentID = _previewAgent;
|
||||
|
||||
_selectedEffect.SetActive(false);
|
||||
_selectedEffect.SetActive(true);
|
||||
|
||||
PlaySound(_selectedSound);
|
||||
|
||||
UpdateAgent();
|
||||
Invoke("CloseWithBack", _closeDelayAfterSelection);
|
||||
}
|
||||
else
|
||||
{
|
||||
CloseWithBack();
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateAgent()
|
||||
{
|
||||
var agentSetups = Context.Settings.Agent.Agents;
|
||||
_agentList.Selection = Array.FindIndex(agentSetups, t => t.ID == _previewAgent);
|
||||
|
||||
if (_agentList.Selection < 0)
|
||||
{
|
||||
_agentList.Selection = 0;
|
||||
_previewAgent = agentSetups[_agentList.Selection].ID;
|
||||
}
|
||||
|
||||
if (_previewAgent.HasValue() == false)
|
||||
{
|
||||
Context.PlayerPreview.HideAgent();
|
||||
_agentName.text = string.Empty;
|
||||
_agentDescription.text = string.Empty;
|
||||
}
|
||||
else
|
||||
{
|
||||
var setup = Context.Settings.Agent.GetAgentSetup(_previewAgent);
|
||||
|
||||
Context.PlayerPreview.ShowAgent(_previewAgent);
|
||||
_agentName.text = string.Format(_agentNameFormat, setup.DisplayName);
|
||||
_agentDescription.text = setup.Description;
|
||||
}
|
||||
|
||||
_selectedAgentGroup.SetActive(_previewAgent == Context.PlayerData.AgentID);
|
||||
}
|
||||
}
|
||||
_selectedAgentGroup.SetActive(_previewAgent == Context.PlayerData.AgentID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//using System;
|
||||
//using TMPro;
|
||||
//using UnityEngine;
|
||||
//using Cinemachine;
|
||||
//using System.Collections.Generic;
|
||||
//using System.Collections;
|
||||
|
||||
//namespace TPSBR.UI
|
||||
//{
|
||||
// public class UIAgentSelectionView : UICloseView
|
||||
// {
|
||||
// [SerializeField] private CinemachineVirtualCamera _camera;
|
||||
// [SerializeField] private UIList _agentList;
|
||||
// [SerializeField] private UIButton _selectButton;
|
||||
// [SerializeField] private TextMeshProUGUI _agentName;
|
||||
// [SerializeField] private TextMeshProUGUI _agentDescription;
|
||||
// [SerializeField] private string _agentNameFormat = "{0}";
|
||||
// [SerializeField] private UIBehaviour _selectedAgentGroup;
|
||||
// [SerializeField] private UIBehaviour _selectedEffect;
|
||||
// [SerializeField] private AudioSetup _selectedSound;
|
||||
// [SerializeField] private float _closeDelayAfterSelection = 0.5f;
|
||||
|
||||
// private string _previewAgent;
|
||||
// private const string ShopKey = "Characters";
|
||||
|
||||
// protected override void OnInitialize()
|
||||
// {
|
||||
// base.OnInitialize();
|
||||
// _agentList.SelectionChanged += OnSelectionChanged;
|
||||
// _agentList.UpdateContent += OnListUpdateContent;
|
||||
// _selectButton.onClick.AddListener(OnSelectButton);
|
||||
// }
|
||||
|
||||
// private void OnListUpdateContent(int index, MonoBehaviour content)
|
||||
// {
|
||||
// StartCoroutine(OnListUpdateContentRoutine(index, content));
|
||||
// }
|
||||
// IEnumerator OnListUpdateContentRoutine(int index, MonoBehaviour content)
|
||||
// {
|
||||
// yield return new WaitForSeconds(0.1f);
|
||||
// var behaviour = content as UIBehaviour;
|
||||
// var setup = Context.Settings.Agent.Agents[index];
|
||||
// behaviour.Image.sprite = setup.Icon;
|
||||
|
||||
// bool unlocked = index == 0 || ShopUnlocks.IsUnlocked(setup.ID, ShopKey);
|
||||
// var item = content.GetComponentInParent<UIListItem>();
|
||||
// if (item != null) item.SetLocked(!unlocked);
|
||||
// }
|
||||
// protected override void OnOpen()
|
||||
// {
|
||||
// base.OnOpen();
|
||||
// _camera.enabled = true;
|
||||
// _selectedEffect.SetActive(false);
|
||||
|
||||
// var agents = Context.Settings.Agent.Agents;
|
||||
// if (agents != null && agents.Length > 0)
|
||||
// ShopUnlocks.EnsureUnlocked(agents[0].ID, ShopKey);
|
||||
|
||||
// _previewAgent = Context.PlayerData.AgentID;
|
||||
// _agentList.Refresh(agents.Length, false);
|
||||
// UpdateAgent();
|
||||
// }
|
||||
|
||||
// protected override void OnClose()
|
||||
// {
|
||||
// _camera.enabled = false;
|
||||
// Context.PlayerPreview.ShowAgent(Context.PlayerData.AgentID);
|
||||
// base.OnClose();
|
||||
// }
|
||||
|
||||
// protected override void OnDeinitialize()
|
||||
// {
|
||||
// _agentList.SelectionChanged -= OnSelectionChanged;
|
||||
// _agentList.UpdateContent -= OnListUpdateContent;
|
||||
// _selectButton.onClick.RemoveListener(OnSelectButton);
|
||||
// base.OnDeinitialize();
|
||||
// }
|
||||
|
||||
// private void OnSelectionChanged(int index)
|
||||
// {
|
||||
// var setup = Context.Settings.Agent.Agents[index];
|
||||
// bool unlocked = index == 0 || ShopUnlocks.IsUnlocked(setup.ID, ShopKey);
|
||||
// if (!unlocked) return;
|
||||
// _previewAgent = setup.ID;
|
||||
// UpdateAgent();
|
||||
// }
|
||||
|
||||
// private void OnSelectButton()
|
||||
// {
|
||||
// bool isSame = Context.PlayerData.AgentID == _previewAgent;
|
||||
// if (isSame == false)
|
||||
// {
|
||||
// Context.PlayerData.AgentID = _previewAgent;
|
||||
// _selectedEffect.SetActive(false);
|
||||
// _selectedEffect.SetActive(true);
|
||||
// PlaySound(_selectedSound);
|
||||
// UpdateAgent();
|
||||
// Invoke("CloseWithBack", _closeDelayAfterSelection);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// CloseWithBack();
|
||||
// }
|
||||
// }
|
||||
|
||||
// private void UpdateAgent()
|
||||
// {
|
||||
// var agentSetups = Context.Settings.Agent.Agents;
|
||||
// _agentList.Selection = Array.FindIndex(agentSetups, t => t.ID == _previewAgent);
|
||||
|
||||
// if (_agentList.Selection < 0)
|
||||
// {
|
||||
// int firstUnlocked = Array.FindIndex(agentSetups, t => ShopUnlocks.IsUnlocked(t.ID, ShopKey));
|
||||
// _agentList.Selection = firstUnlocked >= 0 ? firstUnlocked : 0;
|
||||
// _previewAgent = agentSetups[_agentList.Selection].ID;
|
||||
// }
|
||||
|
||||
// if (_previewAgent.HasValue() == false)
|
||||
// {
|
||||
// Context.PlayerPreview.HideAgent();
|
||||
// _agentName.text = string.Empty;
|
||||
// _agentDescription.text = string.Empty;
|
||||
// _selectButton.interactable = false;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// var setup = Context.Settings.Agent.GetAgentSetup(_previewAgent);
|
||||
// Context.PlayerPreview.ShowAgent(_previewAgent);
|
||||
// _agentName.text = string.Format(_agentNameFormat, setup.DisplayName);
|
||||
// _agentDescription.text = setup.Description;
|
||||
// _selectButton.interactable = ShopUnlocks.IsUnlocked(_previewAgent, ShopKey);
|
||||
// }
|
||||
|
||||
// _selectedAgentGroup.SetActive(_previewAgent == Context.PlayerData.AgentID);
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
@ -11,7 +11,9 @@ namespace TPSBR.UI
|
||||
private UIButton _playButton;
|
||||
[SerializeField]
|
||||
private UIButton _settingsButton;
|
||||
[SerializeField]
|
||||
[SerializeField]
|
||||
private UIButton _shopButton;
|
||||
[SerializeField]
|
||||
private UIButton _creditsButton;
|
||||
[SerializeField]
|
||||
private UIButton _changeNicknameButton;
|
||||
@ -47,6 +49,8 @@ namespace TPSBR.UI
|
||||
_settingsButton.onClick.AddListener(OnSettingsButton);
|
||||
_playButton.onClick.AddListener(OnPlayButton);
|
||||
_creditsButton.onClick.AddListener(OnCreditsButton);
|
||||
_shopButton.onClick.AddListener(OnShopButton);
|
||||
|
||||
_changeNicknameButton.onClick.AddListener(OnChangeNicknameButton);
|
||||
_quitButton.onClick.AddListener(OnQuitButton);
|
||||
_playerButton.onClick.AddListener(OnPlayerButton);
|
||||
@ -112,8 +116,11 @@ namespace TPSBR.UI
|
||||
{
|
||||
Open<UICreditsView>();
|
||||
}
|
||||
|
||||
private void OnChangeNicknameButton()
|
||||
private void OnShopButton()
|
||||
{
|
||||
Open<UIShopView>();
|
||||
}
|
||||
private void OnChangeNicknameButton()
|
||||
{
|
||||
var changeNicknameView = Open<UIChangeNicknameView>();
|
||||
changeNicknameView.SetData("CHANGE NICKNAME", false);
|
||||
|
10
Assets/TPSBR/Scripts/UI/MenuViews/UIShopView.cs
Normal file
10
Assets/TPSBR/Scripts/UI/MenuViews/UIShopView.cs
Normal file
@ -0,0 +1,10 @@
|
||||
using TPSBR.UI;
|
||||
using UnityEngine;
|
||||
|
||||
namespace TPSBR
|
||||
{
|
||||
public class UIShopView : UICloseView
|
||||
{
|
||||
|
||||
}
|
||||
}
|
2
Assets/TPSBR/Scripts/UI/MenuViews/UIShopView.cs.meta
Normal file
2
Assets/TPSBR/Scripts/UI/MenuViews/UIShopView.cs.meta
Normal file
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a38625793bc96b64f92f7e92d70cde3d
|
38
Assets/TPSBR/Scripts/Utilities/ShopUnlocks.cs
Normal file
38
Assets/TPSBR/Scripts/Utilities/ShopUnlocks.cs
Normal file
@ -0,0 +1,38 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public static class ShopUnlocks
|
||||
{
|
||||
static string Key(string shop) => $"ShopUnlocks_{shop}";
|
||||
|
||||
public static bool IsUnlocked(string id, string shop)
|
||||
{
|
||||
if (string.IsNullOrEmpty(id)) return false;
|
||||
var data = PlayerPrefs.GetString(Key(shop), "");
|
||||
if (string.IsNullOrEmpty(data)) return false;
|
||||
var parts = data.Split(',');
|
||||
for (int i = 0; i < parts.Length; i++) if (parts[i] == id) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void Unlock(string id, string shop)
|
||||
{
|
||||
if (string.IsNullOrEmpty(id)) return;
|
||||
var list = new List<string>();
|
||||
var data = PlayerPrefs.GetString(Key(shop), "");
|
||||
if (!string.IsNullOrEmpty(data)) list.AddRange(data.Split(','));
|
||||
if (!list.Contains(id)) list.Add(id);
|
||||
PlayerPrefs.SetString(Key(shop), string.Join(",", list));
|
||||
PlayerPrefs.Save();
|
||||
}
|
||||
|
||||
public static void EnsureUnlocked(string id, string shop)
|
||||
{
|
||||
if (!IsUnlocked(id, shop)) Unlock(id, shop);
|
||||
}
|
||||
|
||||
public static void Reset(string shop)
|
||||
{
|
||||
PlayerPrefs.DeleteKey(Key(shop));
|
||||
}
|
||||
}
|
2
Assets/TPSBR/Scripts/Utilities/ShopUnlocks.cs.meta
Normal file
2
Assets/TPSBR/Scripts/Utilities/ShopUnlocks.cs.meta
Normal file
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c66354f2e75f9ba409d04bb335fd6e1c
|
BIN
Assets/UI/lock.png
Normal file
BIN
Assets/UI/lock.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.3 MiB |
156
Assets/UI/lock.png.meta
Normal file
156
Assets/UI/lock.png.meta
Normal file
@ -0,0 +1,156 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f3be0a9c7364a3e40a2a1c19fbf4729c
|
||||
TextureImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 13
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
sRGBTexture: 1
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapsPreserveCoverage: 0
|
||||
alphaTestReferenceValue: 0.5
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
flipGreenChannel: 0
|
||||
isReadable: 0
|
||||
streamingMipmaps: 0
|
||||
streamingMipmapsPriority: 0
|
||||
vTOnly: 0
|
||||
ignoreMipmapLimit: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: 1
|
||||
aniso: 2
|
||||
mipBias: 0
|
||||
wrapU: 1
|
||||
wrapV: 1
|
||||
wrapW: 0
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 1
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spritePixelsToUnits: 100
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spriteGenerateFallbackPhysicsShape: 1
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 8
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
flipbookRows: 1
|
||||
flipbookColumns: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
ignorePngGamma: 0
|
||||
applyGammaDecoding: 0
|
||||
swizzle: 50462976
|
||||
cookieLightType: 0
|
||||
platformSettings:
|
||||
- serializedVersion: 4
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 128
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
ignorePlatformSupport: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 4
|
||||
buildTarget: Standalone
|
||||
maxTextureSize: 8192
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
ignorePlatformSupport: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 4
|
||||
buildTarget: iOS
|
||||
maxTextureSize: 8192
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
ignorePlatformSupport: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 4
|
||||
buildTarget: Android
|
||||
maxTextureSize: 8192
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
ignorePlatformSupport: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 4
|
||||
buildTarget: WindowsStoreApps
|
||||
maxTextureSize: 8192
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
ignorePlatformSupport: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
customData:
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID: 5e97eb03825dee720800000000000000
|
||||
internalID: 0
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
secondaryTextures: []
|
||||
spriteCustomMetadata:
|
||||
entries: []
|
||||
nameFileIdTable: {}
|
||||
mipmapLimitGroupName:
|
||||
pSDRemoveMatte: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Loading…
x
Reference in New Issue
Block a user