任务系统一半多,商城筛选功能,一些细节和免费包
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using Bansonic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
public class dailyTaskManager : MonoBehaviour
|
||||
@@ -9,16 +8,21 @@ public class dailyTaskManager : MonoBehaviour
|
||||
[Header("任务池so")]
|
||||
public userTasksPool taskPool;
|
||||
|
||||
[Header("player data")]
|
||||
public Player_SO playerData;
|
||||
|
||||
[Header("今日进度")]
|
||||
public Slider todayProgressSlider;
|
||||
public Text todayProgressPercent;
|
||||
public Text todayProgressText;
|
||||
public Text notasksanymore;
|
||||
|
||||
|
||||
[Header("一键领取")]
|
||||
public Button oneKeyRewardBtn;
|
||||
|
||||
[Header("刷新任务")]
|
||||
public Button refreshTaskBtn;
|
||||
|
||||
[Header("任务配置")]
|
||||
[Tooltip("任务列表最大容量")]
|
||||
public int taskMaxSize = 5;
|
||||
@@ -28,4 +32,299 @@ public class dailyTaskManager : MonoBehaviour
|
||||
[Header("prefabs")]
|
||||
public GameObject dailyTaskItemPrefab;
|
||||
public Transform dailyTaskItemParent;
|
||||
|
||||
[Header("reward sprites")]
|
||||
public Sprite coinRewardSprite;
|
||||
|
||||
private readonly List<GameObject> spawnedTaskItems = new List<GameObject>();
|
||||
private readonly Dictionary<int, Sprite> rewardSpriteByItemId = new Dictionary<int, Sprite>();
|
||||
|
||||
private void Start()
|
||||
{
|
||||
CacheRewardSpritesFromStoreItems();
|
||||
|
||||
var taskService = DailyTaskService.EnsureInstance();
|
||||
taskService.Configure(taskPool, taskMaxSize, refreshMaxTimes);
|
||||
taskService.OnTasksChanged += RefreshTaskUi;
|
||||
|
||||
if (oneKeyRewardBtn != null)
|
||||
{
|
||||
oneKeyRewardBtn.onClick.RemoveAllListeners();
|
||||
oneKeyRewardBtn.onClick.AddListener(OnOneKeyRewardClicked);
|
||||
}
|
||||
|
||||
if (refreshTaskBtn != null)
|
||||
{
|
||||
refreshTaskBtn.onClick.RemoveAllListeners();
|
||||
refreshTaskBtn.onClick.AddListener(OnRefreshTaskClicked);
|
||||
}
|
||||
|
||||
RefreshTaskUi();
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
if (DailyTaskService.Instance != null)
|
||||
{
|
||||
DailyTaskService.Instance.OnTasksChanged -= RefreshTaskUi;
|
||||
}
|
||||
}
|
||||
|
||||
private void RefreshTaskUi()
|
||||
{
|
||||
ClearSpawnedItems();
|
||||
|
||||
var tasks = DailyTaskService.EnsureInstance().GetActiveTaskViews();
|
||||
if (notasksanymore != null)
|
||||
{
|
||||
notasksanymore.gameObject.SetActive(tasks.Count == 0);
|
||||
notasksanymore.text = tasks.Count == 0 ? "今日暂无任务" : string.Empty;
|
||||
}
|
||||
|
||||
int completedCount = 0;
|
||||
for (int i = 0; i < tasks.Count; i++)
|
||||
{
|
||||
var taskView = tasks[i];
|
||||
if (taskView == null || taskView.definition == null || taskView.runtimeEntry == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (taskView.runtimeEntry.isCompleted)
|
||||
{
|
||||
completedCount += 1;
|
||||
}
|
||||
|
||||
SpawnTaskItem(i, taskView);
|
||||
}
|
||||
|
||||
UpdateTodayProgress(tasks.Count, completedCount);
|
||||
RefreshOneKeyRewardButtonState(tasks);
|
||||
RefreshTaskButtonState();
|
||||
}
|
||||
|
||||
private void SpawnTaskItem(int index, DailyTaskViewData taskView)
|
||||
{
|
||||
if (dailyTaskItemPrefab == null || dailyTaskItemParent == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var instance = Instantiate(dailyTaskItemPrefab, dailyTaskItemParent);
|
||||
spawnedTaskItems.Add(instance);
|
||||
|
||||
var controller = instance.GetComponent<taskPrefabController>();
|
||||
if (controller == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
controller.Setup(taskView, index + 1, ResolveRewardSprite(taskView.definition), () => OnSingleRewardClicked(taskView.runtimeEntry.taskID));
|
||||
}
|
||||
|
||||
private void UpdateTodayProgress(int totalTaskCount, int completedCount)
|
||||
{
|
||||
float progress = totalTaskCount <= 0 ? 0f : (float)completedCount / totalTaskCount;
|
||||
|
||||
if (todayProgressSlider != null)
|
||||
{
|
||||
todayProgressSlider.value = progress;
|
||||
}
|
||||
|
||||
if (todayProgressPercent != null)
|
||||
{
|
||||
todayProgressPercent.text = (progress * 100f).ToString("F0") + "%";
|
||||
}
|
||||
|
||||
if (todayProgressText != null)
|
||||
{
|
||||
todayProgressText.text = completedCount + "/" + totalTaskCount;
|
||||
}
|
||||
}
|
||||
|
||||
private void ClearSpawnedItems()
|
||||
{
|
||||
for (int i = spawnedTaskItems.Count - 1; i >= 0; i--)
|
||||
{
|
||||
if (spawnedTaskItems[i] != null)
|
||||
{
|
||||
Destroy(spawnedTaskItems[i]);
|
||||
}
|
||||
}
|
||||
|
||||
spawnedTaskItems.Clear();
|
||||
}
|
||||
|
||||
private void OnSingleRewardClicked(string taskID)
|
||||
{
|
||||
string failureMessage;
|
||||
if (!DailyTaskService.EnsureInstance().TryClaimReward(taskID, playerData, out failureMessage))
|
||||
{
|
||||
if (!string.IsNullOrEmpty(failureMessage))
|
||||
{
|
||||
gNotice.warning.display(failureMessage);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
RefreshTaskUi();
|
||||
}
|
||||
|
||||
private void OnOneKeyRewardClicked()
|
||||
{
|
||||
string failureMessage;
|
||||
int claimedCount = DailyTaskService.EnsureInstance().ClaimAllAvailableRewards(playerData, out failureMessage);
|
||||
if (claimedCount <= 0)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(failureMessage))
|
||||
{
|
||||
gNotice.warning.display(failureMessage);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
RefreshTaskUi();
|
||||
}
|
||||
|
||||
private void RefreshOneKeyRewardButtonState(IReadOnlyList<DailyTaskViewData> tasks)
|
||||
{
|
||||
if (oneKeyRewardBtn == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
bool hasClaimableReward = false;
|
||||
for (int i = 0; i < tasks.Count; i++)
|
||||
{
|
||||
var taskView = tasks[i];
|
||||
if (taskView == null || taskView.runtimeEntry == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (taskView.runtimeEntry.isCompleted && !taskView.runtimeEntry.isClaimed)
|
||||
{
|
||||
hasClaimableReward = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
oneKeyRewardBtn.interactable = hasClaimableReward;
|
||||
}
|
||||
|
||||
private void OnRefreshTaskClicked()
|
||||
{
|
||||
if (taskPool == null)
|
||||
{
|
||||
gNotice.warning.display("未配置任务池");
|
||||
return;
|
||||
}
|
||||
|
||||
var taskService = DailyTaskService.EnsureInstance();
|
||||
if (!taskService.TryRefreshTasks())
|
||||
{
|
||||
if (taskService.GetRemainingRefreshCount() <= 0)
|
||||
{
|
||||
gNotice.warning.display("已达到今日刷新上限");
|
||||
}
|
||||
else
|
||||
{
|
||||
gNotice.warning.display("刷新失败");
|
||||
}
|
||||
|
||||
RefreshTaskButtonState();
|
||||
return;
|
||||
}
|
||||
|
||||
RefreshTaskUi();
|
||||
}
|
||||
|
||||
private void RefreshTaskButtonState()
|
||||
{
|
||||
if (refreshTaskBtn == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
refreshTaskBtn.interactable = taskPool != null && DailyTaskService.EnsureInstance().GetRemainingRefreshCount() > 0;
|
||||
}
|
||||
|
||||
private Sprite ResolveRewardSprite(userTasksPool.TaskDefinition definition)
|
||||
{
|
||||
if (definition == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
switch (definition.rewardType)
|
||||
{
|
||||
case userTasksPool.RewardType.coins:
|
||||
return coinRewardSprite;
|
||||
case userTasksPool.RewardType.expBottle:
|
||||
return GetRewardSpriteByItemId(GetExpBottleRewardItemId(definition.rewardExpBottleKind));
|
||||
case userTasksPool.RewardType.dushMaterial:
|
||||
return GetRewardSpriteByItemId(GetDushMaterialRewardItemId(definition.rewardDushMaterialKind));
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private void CacheRewardSpritesFromStoreItems()
|
||||
{
|
||||
rewardSpriteByItemId.Clear();
|
||||
|
||||
var rewardStoreItems = Resources.LoadAll<storeItemSO>("so/storeSO");
|
||||
for (int i = 0; i < rewardStoreItems.Length; i++)
|
||||
{
|
||||
var itemSO = rewardStoreItems[i];
|
||||
if (itemSO == null || itemSO.itemIcon == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
rewardSpriteByItemId[itemSO.itemID] = itemSO.itemIcon;
|
||||
}
|
||||
}
|
||||
|
||||
private Sprite GetRewardSpriteByItemId(int itemId)
|
||||
{
|
||||
if (itemId <= 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
Sprite sprite;
|
||||
return rewardSpriteByItemId.TryGetValue(itemId, out sprite) ? sprite : null;
|
||||
}
|
||||
|
||||
private static int GetExpBottleRewardItemId(ExpBottleKind kind)
|
||||
{
|
||||
switch (kind)
|
||||
{
|
||||
case ExpBottleKind.Common: return 78001;
|
||||
case ExpBottleKind.Medium: return 78002;
|
||||
case ExpBottleKind.Superior: return 78003;
|
||||
case ExpBottleKind.Supreme: return 78004;
|
||||
case ExpBottleKind.Extraordinary: return 78005;
|
||||
case ExpBottleKind.Celestial: return 78006;
|
||||
case ExpBottleKind.RainAll: return 78011;
|
||||
case ExpBottleKind.AdvancedRainAll: return 78012;
|
||||
case ExpBottleKind.SuperRainAll: return 78013;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
private static int GetDushMaterialRewardItemId(DushMaterialKind kind)
|
||||
{
|
||||
switch (kind)
|
||||
{
|
||||
case DushMaterialKind.Material78021: return 78021;
|
||||
case DushMaterialKind.Material78022: return 78022;
|
||||
case DushMaterialKind.Material78023: return 78023;
|
||||
case DushMaterialKind.Material78024: return 78024;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user