商店除发放和货币扣除,其余部分完毕。加入药水icon免费包
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
using System.Collections;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
public class UI_Panel_Mail : MonoBehaviour
|
||||
@@ -10,17 +12,25 @@ public class UI_Panel_Mail : MonoBehaviour
|
||||
[SerializeField] List<Animator> ui_Anim;
|
||||
|
||||
[Header("paths")]
|
||||
[SerializeField] private string editor_mailSO_Path;
|
||||
[SerializeField] private string runtime_mailSO_Path;
|
||||
[Header("objects")]
|
||||
[SerializeField] private string editor_mailSO_Path = "Assets/Resources/so/mail_so";
|
||||
[SerializeField] private string runtime_mailSO_Path = "so/mail_so";
|
||||
[Header("mail objects")]
|
||||
public GameObject noticeSlotPrefab;
|
||||
[SerializeField] Transform content_Notice_Slot;
|
||||
[Header("rewards objects")]
|
||||
public GameObject rewardSlotPrefab;
|
||||
[SerializeField] Transform content_Reward_Slot;
|
||||
|
||||
[Header("texts")]
|
||||
public Text thisMail_title;
|
||||
public Text thisMail_body;
|
||||
public Text thisMail_time;
|
||||
public Text thisMail_sender;
|
||||
List<mail_so> cachedMails = new List<mail_so>();
|
||||
mailSlotPrefab selectedSlot;
|
||||
|
||||
[Header("buttons")]
|
||||
public Button receive_this_mail;
|
||||
private void Update()
|
||||
{
|
||||
if (Input.GetKeyDown(KeyCode.Escape))
|
||||
@@ -34,7 +44,255 @@ public class UI_Panel_Mail : MonoBehaviour
|
||||
{
|
||||
item.speed = Anim_Speed;
|
||||
}
|
||||
StartCoroutine(C_Slot_Show());
|
||||
BuildMailSlots();
|
||||
}
|
||||
|
||||
void BuildMailSlots()
|
||||
{
|
||||
if (noticeSlotPrefab == null || content_Notice_Slot == null) return;
|
||||
|
||||
for (int i = content_Notice_Slot.childCount - 1; i >= 0; i--)
|
||||
{
|
||||
Destroy(content_Notice_Slot.GetChild(i).gameObject);
|
||||
}
|
||||
|
||||
var mails = LoadMailAssets();
|
||||
if (mails == null || mails.Count == 0) return;
|
||||
cachedMails = mails;
|
||||
ApplySavedState(cachedMails);
|
||||
|
||||
for (int i = 0; i < mails.Count; i++)
|
||||
{
|
||||
var mail = mails[i];
|
||||
if (mail == null) continue;
|
||||
var go = Instantiate(noticeSlotPrefab, content_Notice_Slot);
|
||||
var slot = go.GetComponent<mailSlotPrefab>();
|
||||
if (selectedSlot == null) selectedSlot = slot;
|
||||
if (slot != null)
|
||||
{
|
||||
if (slot.mailTitle != null) slot.mailTitle.text = mail.mail_title;
|
||||
if (slot.mailSender != null) slot.mailSender.text = mail.mail_sender;
|
||||
if (slot.mailTime != null) slot.mailTime.text = mail.mail_date;
|
||||
if (slot.mailImage != null) slot.mailImage.sprite = mail.mail_image;
|
||||
UpdateSlotVisuals(slot, mail);
|
||||
SetSelectedState(slot, false);
|
||||
|
||||
var openButton = slot.openButton != null ? slot.openButton : go.GetComponent<Button>();
|
||||
if (openButton != null)
|
||||
{
|
||||
openButton.onClick.AddListener(() => OnMailOpen(slot, mail));
|
||||
}
|
||||
|
||||
if (slot.receivedButton != null)
|
||||
{
|
||||
slot.receivedButton.onClick.AddListener(() => OnMailReceived(slot, mail));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LayoutRebuilder.ForceRebuildLayoutImmediate(content_Notice_Slot as RectTransform);
|
||||
if (selectedSlot != null && cachedMails != null)
|
||||
{
|
||||
for (int i = 0; i < cachedMails.Count; i++)
|
||||
{
|
||||
var mail = cachedMails[i];
|
||||
if (mail == null) continue;
|
||||
OnMailOpen(selectedSlot, mail);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<mail_so> LoadMailAssets()
|
||||
{
|
||||
var result = new List<mail_so>();
|
||||
#if UNITY_EDITOR
|
||||
if (!Application.isPlaying && !string.IsNullOrEmpty(editor_mailSO_Path))
|
||||
{
|
||||
var guids = UnityEditor.AssetDatabase.FindAssets("t:mail_so", new[] { editor_mailSO_Path });
|
||||
foreach (var guid in guids)
|
||||
{
|
||||
var path = UnityEditor.AssetDatabase.GUIDToAssetPath(guid);
|
||||
var asset = UnityEditor.AssetDatabase.LoadAssetAtPath<mail_so>(path);
|
||||
if (asset != null) result.Add(asset);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
if (!string.IsNullOrEmpty(runtime_mailSO_Path))
|
||||
{
|
||||
var assets = Resources.LoadAll<mail_so>(runtime_mailSO_Path);
|
||||
if (assets != null && assets.Length > 0)
|
||||
{
|
||||
result.AddRange(assets);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void OnMailRead(mailSlotPrefab slot, mail_so mail)
|
||||
{
|
||||
if (mail == null) return;
|
||||
if (!mail.isRead)
|
||||
{
|
||||
mail.isRead = true;
|
||||
UpdateSlotVisuals(slot, mail);
|
||||
SaveMailState();
|
||||
}
|
||||
}
|
||||
|
||||
void OnMailOpen(mailSlotPrefab slot, mail_so mail)
|
||||
{
|
||||
if (mail == null) return;
|
||||
SetSelectedSlot(slot);
|
||||
ShowMailDetails(mail);
|
||||
ShowMailRewards(mail);
|
||||
OnMailRead(slot, mail);
|
||||
}
|
||||
|
||||
void OnMailReceived(mailSlotPrefab slot, mail_so mail)
|
||||
{
|
||||
if (mail == null) return;
|
||||
if (mail.rewardList == null || mail.rewardList.Count == 0) return;
|
||||
if (!mail.isReceived)
|
||||
{
|
||||
mail.isReceived = true;
|
||||
UpdateSlotVisuals(slot, mail);
|
||||
SaveMailState();
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateSlotVisuals(mailSlotPrefab slot, mail_so mail)
|
||||
{
|
||||
if (slot == null || mail == null) return;
|
||||
if (slot.isRead_redDot != null) slot.isRead_redDot.enabled = !mail.isRead;
|
||||
if (slot.hasGift_icon != null)
|
||||
{
|
||||
bool hasReward = mail.rewardList != null && mail.rewardList.Count > 0;
|
||||
slot.hasGift_icon.enabled = hasReward && !mail.isReceived;
|
||||
}
|
||||
}
|
||||
|
||||
void ShowMailDetails(mail_so mail)
|
||||
{
|
||||
if (thisMail_title != null) thisMail_title.text = mail.mail_title;
|
||||
if (thisMail_body != null) thisMail_body.text = mail.mail_body;
|
||||
if (thisMail_time != null) thisMail_time.text = mail.mail_date;
|
||||
if (thisMail_sender != null) thisMail_sender.text = mail.mail_sender;
|
||||
}
|
||||
|
||||
void ShowMailRewards(mail_so mail)
|
||||
{
|
||||
if (content_Reward_Slot == null || rewardSlotPrefab == null) return;
|
||||
for (int i = content_Reward_Slot.childCount - 1; i >= 0; i--)
|
||||
{
|
||||
Destroy(content_Reward_Slot.GetChild(i).gameObject);
|
||||
}
|
||||
|
||||
if (mail == null || mail.rewardList == null || mail.rewardList.Count == 0) return;
|
||||
|
||||
for (int i = 0; i < mail.rewardList.Count; i++)
|
||||
{
|
||||
var reward = mail.rewardList[i];
|
||||
if (reward == null) continue;
|
||||
var go = Instantiate(rewardSlotPrefab, content_Reward_Slot);
|
||||
var slot = go.GetComponent<rewardSlotPrefab>();
|
||||
if (slot == null) continue;
|
||||
if (slot.rewardName != null) slot.rewardName.text = reward.rewardName;
|
||||
if (slot.rewardAmount != null) slot.rewardAmount.text = reward.reward_ammount == 1 ? string.Empty : reward.reward_ammount.ToString();
|
||||
if (slot.rewardIcon != null) slot.rewardIcon.sprite = reward.reward_image;
|
||||
if (slot.detailText != null) slot.detailText.text = reward.reward_description;
|
||||
if (slot.detailBtm != null) slot.detailBtm.SetActive(false);
|
||||
}
|
||||
|
||||
LayoutRebuilder.ForceRebuildLayoutImmediate(content_Reward_Slot as RectTransform);
|
||||
}
|
||||
|
||||
void SetSelectedSlot(mailSlotPrefab slot)
|
||||
{
|
||||
if (content_Notice_Slot == null) return;
|
||||
selectedSlot = slot;
|
||||
for (int i = 0; i < content_Notice_Slot.childCount; i++)
|
||||
{
|
||||
var child = content_Notice_Slot.GetChild(i);
|
||||
var s = child.GetComponent<mailSlotPrefab>();
|
||||
SetSelectedState(s, s == selectedSlot);
|
||||
}
|
||||
}
|
||||
|
||||
void SetSelectedState(mailSlotPrefab slot, bool selected)
|
||||
{
|
||||
if (slot == null || slot.selectedImage == null) return;
|
||||
slot.selectedImage.enabled = selected;
|
||||
}
|
||||
|
||||
void ApplySavedState(List<mail_so> mails)
|
||||
{
|
||||
var data = LoadMailState();
|
||||
if (data == null || data.entries == null) return;
|
||||
var map = new Dictionary<int, MailSaveEntry>();
|
||||
for (int i = 0; i < data.entries.Count; i++)
|
||||
{
|
||||
var e = data.entries[i];
|
||||
map[e.mail_id] = e;
|
||||
}
|
||||
for (int i = 0; i < mails.Count; i++)
|
||||
{
|
||||
var mail = mails[i];
|
||||
if (mail == null) continue;
|
||||
if (map.TryGetValue(mail.mail_id, out var e))
|
||||
{
|
||||
mail.isRead = e.isRead;
|
||||
mail.isReceived = e.isReceived;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SaveMailState()
|
||||
{
|
||||
if (cachedMails == null) return;
|
||||
var data = new MailSaveData();
|
||||
for (int i = 0; i < cachedMails.Count; i++)
|
||||
{
|
||||
var mail = cachedMails[i];
|
||||
if (mail == null) continue;
|
||||
data.entries.Add(new MailSaveEntry
|
||||
{
|
||||
mail_id = mail.mail_id,
|
||||
isRead = mail.isRead,
|
||||
isReceived = mail.isReceived
|
||||
});
|
||||
}
|
||||
var json = JsonUtility.ToJson(data, true);
|
||||
File.WriteAllText(GetSavePath(), json);
|
||||
}
|
||||
|
||||
MailSaveData LoadMailState()
|
||||
{
|
||||
var path = GetSavePath();
|
||||
if (!File.Exists(path)) return null;
|
||||
var json = File.ReadAllText(path);
|
||||
if (string.IsNullOrEmpty(json)) return null;
|
||||
return JsonUtility.FromJson<MailSaveData>(json);
|
||||
}
|
||||
|
||||
string GetSavePath()
|
||||
{
|
||||
return Path.Combine(Application.persistentDataPath, "mail_state.json");
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
class MailSaveData
|
||||
{
|
||||
public List<MailSaveEntry> entries = new List<MailSaveEntry>();
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
class MailSaveEntry
|
||||
{
|
||||
public int mail_id;
|
||||
public bool isRead;
|
||||
public bool isReceived;
|
||||
}
|
||||
IEnumerator C_Slot_Show()
|
||||
{
|
||||
@@ -50,4 +308,4 @@ public class UI_Panel_Mail : MonoBehaviour
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user