312 lines
9.9 KiB
C#
312 lines
9.9 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
public class UI_Panel_Mail : MonoBehaviour
|
|
{
|
|
//1234567890
|
|
[SerializeField] float anim_Time = 0.5f;
|
|
float Anim_Speed => 1f / anim_Time;
|
|
[SerializeField] List<Animator> ui_Anim;
|
|
|
|
[Header("paths")]
|
|
[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))
|
|
{
|
|
gameObject.SetActive(false);
|
|
}
|
|
}
|
|
void Start()
|
|
{
|
|
foreach (var item in ui_Anim)
|
|
{
|
|
item.speed = Anim_Speed;
|
|
}
|
|
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()
|
|
{
|
|
var slots = content_Notice_Slot.GetComponentsInChildren<Button>();
|
|
foreach (var item in slots)
|
|
{
|
|
item.gameObject.SetActive(false);
|
|
}
|
|
foreach (var item in slots)
|
|
{
|
|
yield return new WaitForSeconds(0.1f);
|
|
item.gameObject.SetActive(true);
|
|
}
|
|
|
|
}
|
|
}
|