Files
bansonic_beta_main/Assets/scripts/UI/Panel/UI_Panel_Mail.cs
T

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);
}
}
}