功能批量实现 优化 服务端 新浮动小游戏框架 新界面UI

This commit is contained in:
FloatGaming
2026-04-24 13:20:16 +08:00
parent e0bc0bbf08
commit 5eec879582
257 changed files with 38481 additions and 1288 deletions
@@ -4,9 +4,10 @@ using UnityEngine.UI;
using System.Collections.Generic;
using TMPro;
public class BeatmapManager : MonoBehaviour
{
public static BeatmapManager Instance { get; private set; }
public class BeatmapManager : MonoBehaviour
{
private const bool VerboseLogs = false;
public static BeatmapManager Instance { get; private set; }
private void Awake()
{
@@ -26,11 +27,11 @@ public class BeatmapManager : MonoBehaviour
/// Called by previous scene to hand over a SongData SO and difficulty to this manager after scene load.
/// This stores the pair in static fields so BeatmapManager.Start can pick them up.
/// </summary>
public static void SetPendingSong(SongData song, int difficulty)
{
pendingSongData = song;
pendingDifficulty = difficulty;
Debug.LogWarning($"BeatmapManager.SetPendingSong called: song={(song==null?"NULL":song.songName)}, difficulty={difficulty}");
public static void SetPendingSong(SongData song, int difficulty)
{
pendingSongData = song;
pendingDifficulty = difficulty;
if (VerboseLogs) Debug.Log($"BeatmapManager.SetPendingSong called: song={(song==null?"NULL":song.songName)}, difficulty={difficulty}");
}
[Header("Assigned SongData (set at runtime from previous scene or via Inspector)")]
@@ -42,12 +43,12 @@ public class BeatmapManager : MonoBehaviour
/// Public API to accept a SongData at runtime (can be called by other scripts after scene load)
/// Also sets inspector-exposed fields so you can visually confirm in Editor during play.
/// </summary>
public void AcceptSongData(SongData song, int difficulty)
{
assignedSongData = song;
assignedDifficulty = difficulty;
Debug.LogWarning($"BeatmapManager.AcceptSongData: accepted song={(song==null?"NULL":song.songName)}, difficulty={difficulty}");
UpdateGameplayUI();
public void AcceptSongData(SongData song, int difficulty)
{
assignedSongData = song;
assignedDifficulty = difficulty;
if (VerboseLogs) Debug.Log($"BeatmapManager.AcceptSongData: accepted song={(song==null?"NULL":song.songName)}, difficulty={difficulty}");
UpdateGameplayUI();
}
public Beatmap beatmap; // Documentation text normalized.
@@ -119,7 +120,7 @@ public class BeatmapManager : MonoBehaviour
if (File.Exists(path))
{
string json = File.ReadAllText(path);
Debug.Log("读取 JSON 路径: " + path);
if (VerboseLogs) Debug.Log("读取 JSON 路径: " + path);
ProcessJsonAndLoad(json);
}
else
@@ -228,7 +229,7 @@ public class BeatmapManager : MonoBehaviour
// NOTE: Do NOT modify parsed.notes here. globalDelaySeconds will be applied to audio playback instead.
beatmap = parsed;
Debug.Log("ParseJsonOnly: parsed beatmap " + beatmap.title);
if (VerboseLogs) Debug.Log("ParseJsonOnly: parsed beatmap " + beatmap.title);
// Documentation text normalized.
SetupEnemiesAndHP();
@@ -244,7 +245,7 @@ public class BeatmapManager : MonoBehaviour
beatmap = loadedBeatmap;
parsedNoteAmount = (beatmap != null && beatmap.notes != null) ? beatmap.notes.Length : 0;
CalculateNoteScores(beatmap);
Debug.Log("谱面加载完成,当前 Beatmap 标题: " + (beatmap != null ? beatmap.title : "null"));
if (VerboseLogs) Debug.Log("谱面加载完成,当前 Beatmap 标题: " + (beatmap != null ? beatmap.title : "null"));
// No globalDelaySeconds available in this path. Call NoteSpawner directly.
noteSpawner.LoadBeatmap(beatmap);
ApplyTrackScoreCaps(beatmap);
@@ -306,7 +307,7 @@ public class BeatmapManager : MonoBehaviour
Debug.LogWarning($"LoadBeatmapFromSongData: chart TextAsset for difficulty {difficulty} is null on song {song.songName}");
return false;
}
Debug.LogWarning($"LoadBeatmapFromSongData: loading chart for song {song.songName}, difficulty {difficulty}, parseOnly={parseOnly}, chartSize={(ta.text != null ? ta.text.Length : 0)}");
if (VerboseLogs) Debug.Log($"LoadBeatmapFromSongData: loading chart for song {song.songName}, difficulty {difficulty}, parseOnly={parseOnly}, chartSize={(ta.text != null ? ta.text.Length : 0)}");
return LoadBeatmapFromTextAsset(ta, parseOnly);
}
@@ -317,7 +318,7 @@ public class BeatmapManager : MonoBehaviour
if (pendingSongData == null && assignedSongData == null)
{
assignedSongData = SongDataHolder.SelectedSongData;
Debug.Log($"[BeatmapManager] No pending song, fallback to SongDataHolder: {(assignedSongData != null ? assignedSongData.songName : "null")}");
if (VerboseLogs) Debug.Log($"[BeatmapManager] No pending song, fallback to SongDataHolder: {(assignedSongData != null ? assignedSongData.songName : "null")}");
}
// 无论如何,在加载谱面前先同步敌人编队到 teamUIController
@@ -325,17 +326,17 @@ public class BeatmapManager : MonoBehaviour
if (pendingSongData != null)
{
Debug.LogWarning($"BeatmapManager.Start: pendingSongData detected: {pendingSongData.songName}, difficulty={pendingDifficulty}");
if (VerboseLogs) Debug.Log($"BeatmapManager.Start: pendingSongData detected: {pendingSongData.songName}, difficulty={pendingDifficulty}");
// Documentation text normalized.
assignedSongData = pendingSongData;
assignedDifficulty = pendingDifficulty;
// Documentation text normalized.
bool ok = LoadBeatmapFromSongData(assignedSongData, assignedDifficulty, true);
if (!ok) Debug.LogWarning("BeatmapManager.Start: LoadBeatmapFromSongData failed");
else
{
Debug.LogWarning("BeatmapManager.Start: chart parsed from SongData, attempting to assign audio and pause system");
if (!ok) Debug.LogWarning("BeatmapManager.Start: LoadBeatmapFromSongData failed");
else
{
if (VerboseLogs) Debug.Log("BeatmapManager.Start: chart parsed from SongData, attempting to assign audio and pause system");
// try to assign audio to GameManager.musicSource
var gm = FindAnyObjectByType<GameManager>();
@@ -345,31 +346,31 @@ public class BeatmapManager : MonoBehaviour
{
gm.musicSource.clip = assignedSongData.audioFile;
gm.musicSource.loop = false;
Debug.LogWarning("Assigned SongData.audioFile to GameManager.musicSource.clip (from SO)");
if (VerboseLogs) Debug.Log("Assigned SongData.audioFile to GameManager.musicSource.clip (from SO)");
}
else if (!string.IsNullOrEmpty(parsedMusicFile))
{
Debug.LogWarning($"Attempting Resources.Load for audio: {parsedMusicFile}");
if (VerboseLogs) Debug.Log($"Attempting Resources.Load for audio: {parsedMusicFile}");
var ac = Resources.Load<AudioClip>(parsedMusicFile);
if (ac != null)
{
gm.musicSource.clip = ac;
gm.musicSource.loop = false;
Debug.LogWarning("Assigned audio via Resources.Load(parsedMusicFile)");
if (VerboseLogs) Debug.Log("Assigned audio via Resources.Load(parsedMusicFile)");
}
else
{
Debug.LogWarning($"Resources.Load failed for '{parsedMusicFile}'");
if (VerboseLogs) Debug.Log($"Resources.Load failed for '{parsedMusicFile}'");
}
}
else
{
Debug.LogWarning("No audio available on SongData and parsedMusicFile empty");
if (VerboseLogs) Debug.Log("No audio available on SongData and parsedMusicFile empty");
}
}
else
{
Debug.LogWarning("GameManager or its musicSource not found; audio not assigned");
if (VerboseLogs) Debug.Log("GameManager or its musicSource not found; audio not assigned");
}
// Assign fullscreen image from SongData to background images if available
@@ -382,13 +383,13 @@ public class BeatmapManager : MonoBehaviour
bgMainImage.sprite = bgSprite;
// ensure fully visible
bgMainImage.color = new Color(bgMainImage.color.r, bgMainImage.color.g, bgMainImage.color.b, 1f);
Debug.LogWarning($"Assigned SongData.fullscreen_songPicture to bgMainImage for song {assignedSongData.songName}");
if (VerboseLogs) Debug.Log($"Assigned SongData.fullscreen_songPicture to bgMainImage for song {assignedSongData.songName}");
}
if (bgSpriteRenderer != null)
{
bgSpriteRenderer.sprite = bgSprite;
Debug.LogWarning($"Assigned SongData.fullscreen_songPicture to bgSpriteRenderer for song {assignedSongData.songName}");
if (VerboseLogs) Debug.Log($"Assigned SongData.fullscreen_songPicture to bgSpriteRenderer for song {assignedSongData.songName}");
// 释放引用以节省内存(按要求:完毕后令 sprite renderer = null
bgSpriteRenderer = null;
}
@@ -396,12 +397,12 @@ public class BeatmapManager : MonoBehaviour
if (startCanvas_image != null)
{
startCanvas_image.sprite = bgSprite;
Debug.LogWarning($"Assigned SongData.fullscreen_songPicture to startCanvas_image for song {assignedSongData.songName}");
if (VerboseLogs) Debug.Log($"Assigned SongData.fullscreen_songPicture to startCanvas_image for song {assignedSongData.songName}");
}
if (bgMainImage == null && startCanvas_image == null)
{
Debug.LogWarning("No background Image targets assigned in BeatmapManager; fullscreen sprite not applied");
if (VerboseLogs) Debug.Log("No background Image targets assigned in BeatmapManager; fullscreen sprite not applied");
}
}
@@ -410,11 +411,11 @@ public class BeatmapManager : MonoBehaviour
if (pauseMgr != null)
{
pauseMgr.Pause(true);
Debug.LogWarning("System paused after loading chart and audio to allow player to start");
if (VerboseLogs) Debug.Log("System paused after loading chart and audio to allow player to start");
}
else
{
Debug.LogWarning("PauseManager not found in scene; cannot pause system automatically");
if (VerboseLogs) Debug.Log("PauseManager not found in scene; cannot pause system automatically");
}
}
@@ -426,13 +427,13 @@ public class BeatmapManager : MonoBehaviour
// Documentation text normalized.
if (GameConfig.testMode)
{
Debug.Log("Test mode active: skipping automatic beatmap load in BeatmapManager.Start");
if (VerboseLogs) Debug.Log("Test mode active: skipping automatic beatmap load in BeatmapManager.Start");
}
else
{
// Documentation text normalized.
// Documentation text normalized.
Debug.LogWarning("Default automatic demo beatmap load is commented out to prioritize SO-provided charts.");
if (VerboseLogs) Debug.Log("Default automatic demo beatmap load is commented out to prioritize SO-provided charts.");
}
UpdateGameplayUI();
@@ -524,7 +525,7 @@ public class BeatmapManager : MonoBehaviour
uiController.enemySlotIds = enemyIds;
uiController.PopulateEnemySOsFromIds();
Debug.Log($"[BeatmapManager] SyncEnemyListToUI: {string.Join(",", enemyIds)}");
if (VerboseLogs) Debug.Log($"[BeatmapManager] SyncEnemyListToUI: {string.Join(",", enemyIds)}");
}
private void SetupEnemiesAndHP()
@@ -553,7 +554,7 @@ public class BeatmapManager : MonoBehaviour
if (config.enemyID != 0) activePercentages.Add(config.hpPercentage);
}
foundInDifficulty = true;
Debug.Log($"[BeatmapManager] Using enemyConfigList from ChartFileEntry (difficulty {assignedDifficulty})");
if (VerboseLogs) Debug.Log($"[BeatmapManager] Using enemyConfigList from ChartFileEntry (difficulty {assignedDifficulty})");
}
break;
}
@@ -564,7 +565,7 @@ public class BeatmapManager : MonoBehaviour
{
foreach (var segment in parsedColorSegments)
{
Debug.Log($"Processing colorSegment: enemyID='{segment.enemyID}', percentage={segment.percentage}");
if (VerboseLogs) Debug.Log($"Processing colorSegment: enemyID='{segment.enemyID}', percentage={segment.percentage}");
int enemyId;
if (!int.TryParse(segment.enemyID, out enemyId))
{
@@ -573,7 +574,7 @@ public class BeatmapManager : MonoBehaviour
}
enemyIds.Add(enemyId);
}
Debug.Log($"[BeatmapManager] Using enemyList from Beatmap JSON: {string.Join(",", enemyIds)}");
if (VerboseLogs) Debug.Log($"[BeatmapManager] Using enemyList from Beatmap JSON: {string.Join(",", enemyIds)}");
}
while (enemyIds.Count < 5) enemyIds.Add(0);
@@ -595,7 +596,7 @@ public class BeatmapManager : MonoBehaviour
if (entry.enemyTotalHP_Multiplier > 0.01f)
{
currentMultiplier = entry.enemyTotalHP_Multiplier;
Debug.Log($"[BeatmapManager] Using override enemyTotalHP_Multiplier from SongData: {currentMultiplier}");
if (VerboseLogs) Debug.Log($"[BeatmapManager] Using override enemyTotalHP_Multiplier from SongData: {currentMultiplier}");
}
break;
}
@@ -647,7 +648,7 @@ public class BeatmapManager : MonoBehaviour
}
for (int i = 0; i < activeEnemyCount; i++) individualHPList.Add(baseHp[i]);
Debug.Log($"[BeatmapManager] HP Calc (Custom Percentages) -> Total: {totalHP}, HPs: {string.Join(",", individualHPList)}");
if (VerboseLogs) Debug.Log($"[BeatmapManager] HP Calc (Custom Percentages) -> Total: {totalHP}, HPs: {string.Join(",", individualHPList)}");
}
else
{
@@ -658,7 +659,7 @@ public class BeatmapManager : MonoBehaviour
int hp = basePer + (i < remainder ? 1 : 0);
individualHPList.Add(hp);
}
Debug.Log($"[BeatmapManager] HP Calc (Equal Dist) -> Total: {totalHP}, Active: {activeEnemyCount}, HPs: {string.Join(",", individualHPList)}");
if (VerboseLogs) Debug.Log($"[BeatmapManager] HP Calc (Equal Dist) -> Total: {totalHP}, Active: {activeEnemyCount}, HPs: {string.Join(",", individualHPList)}");
}
uiController.ApplyCalculatedEnemyHP(individualHPList);
@@ -765,7 +766,7 @@ public class BeatmapManager : MonoBehaviour
CalculateNoteScores(parsed);
beatmap = parsed;
Debug.Log("谱面加载完成: " + beatmap.title);
if (VerboseLogs) Debug.Log("谱面加载完成: " + beatmap.title);
if (noteSpawner != null) noteSpawner.LoadBeatmap(beatmap);
else Debug.LogError("NoteSpawner is null in BeatmapManager.");
@@ -797,7 +798,7 @@ public class BeatmapManager : MonoBehaviour
{
perNoteScore = totalChartScore / noteCount;
leftoverScore = totalChartScore % noteCount;
Debug.Log($"Calculated perNoteScore: {perNoteScore}, leftoverScore: {leftoverScore}, noteCount: {noteCount}");
if (VerboseLogs) Debug.Log($"Calculated perNoteScore: {perNoteScore}, leftoverScore: {leftoverScore}, noteCount: {noteCount}");
}
else
{
File diff suppressed because it is too large Load Diff
@@ -55,6 +55,13 @@ public class GameServerBridge : MonoBehaviour
var nm = NetworkManager.Instance;
if (nm == null) { Debug.LogWarning("[Bridge] NetworkManager 不存在"); return; }
ArenaRoomService arenaRoomService = ArenaRoomService.Instance;
if (arenaRoomService != null && arenaRoomService.IsInRoom)
{
Debug.Log("[Bridge] 当前处于房间模式,跳过世界排行榜提交");
return;
}
_hasSubmitted = true;
try
@@ -49,6 +49,33 @@ namespace GameServer.Client
[JsonProperty("message")] public string message;
}
[Serializable]
public class AvatarUploadResponse
{
[JsonProperty("success")] public bool success;
[JsonProperty("steam_id")] public string steam_id;
[JsonProperty("avatar_url")] public string avatar_url;
[JsonProperty("error_code")] public string error_code;
[JsonProperty("message")] public string message;
}
[Serializable]
public class SteamFriendsImportRequest
{
[JsonProperty("steam_id")] public string steam_id;
[JsonProperty("steam_friends")] public List<string> steam_friends;
}
[Serializable]
public class SteamFriendsImportResponse
{
[JsonProperty("success")] public bool success;
[JsonProperty("added")] public int added;
[JsonProperty("skipped")] public int skipped;
[JsonProperty("error_code")] public string error_code;
[JsonProperty("message")] public string message;
}
[Serializable]
public class ProfileData
{
@@ -56,6 +83,7 @@ namespace GameServer.Client
[JsonProperty("error_code")] public string error_code;
[JsonProperty("message")] public string message;
[JsonProperty("steam_id")] public string steam_id;
[JsonProperty("uid")] public int uid;
[JsonProperty("display_name")] public string display_name;
[JsonProperty("avatar_url")] public string avatar_url;
[JsonProperty("player_level")] public int player_level;
@@ -216,7 +244,9 @@ namespace GameServer.Client
public class ArenaRoomParticipant
{
[JsonProperty("steam_id")] public string steam_id;
[JsonProperty("uid")] public int uid;
[JsonProperty("display_name")] public string display_name;
[JsonProperty("avatar_url")] public string avatar_url;
[JsonProperty("is_host")] public bool is_host;
[JsonProperty("is_ready")] public bool is_ready;
[JsonProperty("join_order")] public int join_order;
@@ -258,4 +288,172 @@ namespace GameServer.Client
[JsonProperty("has_submitted")] public bool has_submitted;
[JsonProperty("join_order")] public int join_order;
}
[Serializable]
public class ArenaRoomChatMessage
{
[JsonProperty("id")] public long id;
[JsonProperty("room_code")] public string room_code;
[JsonProperty("steam_id")] public string steam_id;
[JsonProperty("sender_id")] public string sender_id;
[JsonProperty("receiver_id")] public string receiver_id;
[JsonProperty("uid")] public int uid;
[JsonProperty("display_name")] public string display_name;
[JsonProperty("avatar_url")] public string avatar_url;
[JsonProperty("content")] public string content;
[JsonProperty("created_at")] public string created_at;
[JsonProperty("is_read")] public int is_read;
}
[Serializable]
public class ArenaRoomHistoryData
{
[JsonProperty("room_code")] public string room_code;
[JsonProperty("messages")] public List<ArenaRoomChatMessage> messages;
}
[Serializable]
public class SocialWorldHistoryData
{
[JsonProperty("messages")] public List<ArenaRoomChatMessage> messages;
}
[Serializable]
public class SocialPrivateHistoryData
{
[JsonProperty("partner_id")] public string partner_id;
[JsonProperty("messages")] public List<ArenaRoomChatMessage> messages;
}
[Serializable]
public class SocialFriendEntry
{
[JsonProperty("friend_steam_id")] public string friend_steam_id;
[JsonProperty("uid")] public int uid;
[JsonProperty("friend_name")] public string friend_name;
[JsonProperty("friend_avatar")] public string friend_avatar;
[JsonProperty("online")] public bool online;
[JsonProperty("status")] public string status;
[JsonProperty("since")] public string since;
}
[Serializable]
public class SocialFriendsListData
{
[JsonProperty("friends")] public List<SocialFriendEntry> friends;
}
[Serializable]
public class SocialFriendsApiResponse
{
[JsonProperty("success")] public bool success;
[JsonProperty("friends")] public List<SocialFriendEntry> friends;
[JsonProperty("added")] public int added;
[JsonProperty("skipped")] public int skipped;
[JsonProperty("error_code")] public string error_code;
[JsonProperty("message")] public string message;
}
[Serializable]
public class MailApiRewardEntry
{
[JsonProperty("reward_name")] public string reward_name;
[JsonProperty("reward_type")] public string reward_type;
[JsonProperty("reward_amount")] public int reward_amount;
[JsonProperty("reward_description")] public string reward_description;
[JsonProperty("reward_key")] public string reward_key;
[JsonProperty("reward_store_item_id")] public int reward_store_item_id;
}
[Serializable]
public class MailApiEntry
{
[JsonProperty("mail_id")] public int mail_id;
[JsonProperty("mail_title")] public string mail_title;
[JsonProperty("mail_sender")] public string mail_sender;
[JsonProperty("mail_date")] public string mail_date;
[JsonProperty("mail_body")] public string mail_body;
[JsonProperty("mail_description")] public string mail_description;
[JsonProperty("mail_image_url")] public string mail_image_url;
[JsonProperty("updated_at")] public string updated_at;
[JsonProperty("rewards")] public List<MailApiRewardEntry> rewards;
}
[Serializable]
public class MailApiDeletionEntry
{
[JsonProperty("deletion_id")] public int deletion_id;
[JsonProperty("mail_id")] public int mail_id;
[JsonProperty("title")] public string title;
[JsonProperty("reclaim_rewards")] public bool reclaim_rewards;
[JsonProperty("deleted_at")] public string deleted_at;
[JsonProperty("rewards")] public List<MailApiRewardEntry> rewards;
}
[Serializable]
public class MailApiVersionResponse
{
[JsonProperty("success")] public bool success;
[JsonProperty("revision")] public string revision;
[JsonProperty("count")] public int count;
[JsonProperty("error_code")] public string error_code;
[JsonProperty("message")] public string message;
}
[Serializable]
public class MailApiListResponse
{
[JsonProperty("success")] public bool success;
[JsonProperty("revision")] public string revision;
[JsonProperty("count")] public int count;
[JsonProperty("mails")] public List<MailApiEntry> mails;
[JsonProperty("deletions")] public List<MailApiDeletionEntry> deletions;
[JsonProperty("error_code")] public string error_code;
[JsonProperty("message")] public string message;
}
[Serializable]
public class MailClaimRequest
{
[JsonProperty("steam_id")] public string steam_id;
[JsonProperty("mail_id")] public int mail_id;
}
[Serializable]
public class MailClaimResponse
{
[JsonProperty("success")] public bool success;
[JsonProperty("mail_id")] public int mail_id;
[JsonProperty("steam_id")] public string steam_id;
[JsonProperty("error_code")] public string error_code;
[JsonProperty("message")] public string message;
}
[Serializable]
public class SocialPresenceUpdateData
{
[JsonProperty("steam_id")] public string steam_id;
[JsonProperty("uid")] public int uid;
[JsonProperty("display_name")] public string display_name;
[JsonProperty("avatar_url")] public string avatar_url;
[JsonProperty("status")] public string status;
}
[Serializable]
public class SocialFriendRequestEntry
{
[JsonProperty("id")] public long id;
[JsonProperty("from_steam_id")] public string from_steam_id;
[JsonProperty("uid")] public int uid;
[JsonProperty("from_name")] public string from_name;
[JsonProperty("from_avatar")] public string from_avatar;
[JsonProperty("created_at")] public string created_at;
}
[Serializable]
public class SocialFriendRequestsListData
{
[JsonProperty("requests")] public List<SocialFriendRequestEntry> requests;
}
}
File diff suppressed because it is too large Load Diff
@@ -41,7 +41,10 @@ public class rkPrefab : MonoBehaviour
if (this_username != null)
{
string displayName = string.IsNullOrWhiteSpace(entry.display_name) ? entry.steam_id : entry.display_name;
string displayName = GameServer.Client.NetworkManager.ResolveDisplayName(
entry.display_name,
entry.steam_id,
false);
this_username.text = TruncateToFit(this_username, displayName);
}
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 7dd754b1c97180c49868f4bf10979795
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,70 @@
using UnityEngine;
using UnityEngine.UI;
public class rewardPrefab : MonoBehaviour
{
public enum RewardVisualType
{
Coins,
Material,
PlayerExp,
}
[Header("self UI")]
[SerializeField] Image reward_icon;
[SerializeField] Text reward_name;
[SerializeField] Text reward_count; // +12345
[Header("sprites")]
[SerializeField] Sprite coin_sprite;
[SerializeField] Sprite jiyisuipian;
[SerializeField] Sprite player_exp;
public void Bind(RewardVisualType rewardType, int amount)
{
if (reward_icon != null)
{
reward_icon.sprite = GetSprite(rewardType);
}
if (reward_name != null)
{
reward_name.text = GetDisplayName(rewardType);
}
if (reward_count != null)
{
reward_count.text = amount >= 0 ? $"+{amount}" : amount.ToString();
}
}
private Sprite GetSprite(RewardVisualType rewardType)
{
switch (rewardType)
{
case RewardVisualType.Coins:
return coin_sprite;
case RewardVisualType.Material:
return jiyisuipian;
case RewardVisualType.PlayerExp:
return player_exp;
default:
return null;
}
}
private static string GetDisplayName(RewardVisualType rewardType)
{
switch (rewardType)
{
case RewardVisualType.Coins:
return "金币";
case RewardVisualType.Material:
return "记忆碎片";
case RewardVisualType.PlayerExp:
return "玩家经验";
default:
return string.Empty;
}
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 515746e87847efc4fab2f1fa0f3695a0
@@ -0,0 +1,292 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &118873712428923354
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 3546975410283370972}
- component: {fileID: 9219216993890693327}
- component: {fileID: 6251169732777221245}
m_Layer: 0
m_Name: rwdImage
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &3546975410283370972
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 118873712428923354}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 4266895856353985475}
m_Father: {fileID: 5127964937674371758}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: -60, y: 8.5}
m_SizeDelta: {x: 15, y: 15}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &9219216993890693327
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 118873712428923354}
m_CullTransparentMesh: 1
--- !u!114 &6251169732777221245
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 118873712428923354}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_Sprite: {fileID: 0}
m_Type: 0
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
m_UseSpriteMesh: 0
m_PixelsPerUnitMultiplier: 1
--- !u!1 &1059233533614862680
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 4266895856353985475}
- component: {fileID: 3787018861283084079}
- component: {fileID: 267584174794072845}
m_Layer: 0
m_Name: rwdName
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &4266895856353985475
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1059233533614862680}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 3546975410283370972}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: 64.438, y: 0}
m_SizeDelta: {x: 105.799, y: 15}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &3787018861283084079
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1059233533614862680}
m_CullTransparentMesh: 1
--- !u!114 &267584174794072845
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1059233533614862680}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_FontData:
m_Font: {fileID: 12800000, guid: bd4be44636ad6c24a9b117a7108a75e9, type: 3}
m_FontSize: 15
m_FontStyle: 0
m_BestFit: 0
m_MinSize: 0
m_MaxSize: 40
m_Alignment: 3
m_AlignByGeometry: 0
m_RichText: 1
m_HorizontalOverflow: 0
m_VerticalOverflow: 0
m_LineSpacing: 1
m_Text: "\u54C1\u540D"
--- !u!1 &5437409420464746555
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 5127964937674371758}
- component: {fileID: 8491477728461931688}
m_Layer: 0
m_Name: rewardPrefab
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &5127964937674371758
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5437409420464746555}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 3546975410283370972}
- {fileID: 682261594771255014}
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: 0, y: -26.7554}
m_SizeDelta: {x: 150, y: 35}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &8491477728461931688
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5437409420464746555}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 515746e87847efc4fab2f1fa0f3695a0, type: 3}
m_Name:
m_EditorClassIdentifier:
reward_icon: {fileID: 6251169732777221245}
reward_name: {fileID: 267584174794072845}
reward_count: {fileID: 6866410370984929931}
coin_sprite: {fileID: 21300000, guid: 1836bfb842a045f4f9a4a38b08b395ef, type: 3}
jiyisuipian: {fileID: 21300000, guid: 27adfaee3f8bee14280e634021049f50, type: 3}
player_exp: {fileID: 21300000, guid: af3ce18394be1b448a9e38602526eb80, type: 3}
--- !u!1 &7159171791523732843
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 682261594771255014}
- component: {fileID: 8122003116666225205}
- component: {fileID: 6866410370984929931}
m_Layer: 0
m_Name: rwdACT
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &682261594771255014
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7159171791523732843}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 5127964937674371758}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: -5.157, y: -8.48}
m_SizeDelta: {x: 124.989, y: 18}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &8122003116666225205
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7159171791523732843}
m_CullTransparentMesh: 1
--- !u!114 &6866410370984929931
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7159171791523732843}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_FontData:
m_Font: {fileID: 12800000, guid: bd4be44636ad6c24a9b117a7108a75e9, type: 3}
m_FontSize: 16
m_FontStyle: 0
m_BestFit: 0
m_MinSize: 0
m_MaxSize: 40
m_Alignment: 3
m_AlignByGeometry: 0
m_RichText: 1
m_HorizontalOverflow: 0
m_VerticalOverflow: 0
m_LineSpacing: 1
m_Text: +10086
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 7e80d4de8ab2ff04a9bf1c54e5a064b1
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -137,6 +137,10 @@ public class settlementController : MonoBehaviour
[SerializeField] private Ease introMvpEnterEase = Ease.OutCubic;
[SerializeField] private bool introTweenUseUnscaledTime = true;
[Header("Settle Rewards")]
public GameObject rewardPrefab;
public Transform rewardParent;
private int targetPmScore;
private int targetIdolScore;
private int targetTotalScore;
@@ -159,6 +163,7 @@ public class settlementController : MonoBehaviour
private bool settlementHistoryRecorded;
private bool settlementHeroStatsRecorded;
private bool roomScoreSubmitTriggered;
private bool settlementRewardsGranted;
private void Awake()
{
@@ -202,6 +207,7 @@ public class settlementController : MonoBehaviour
RegisterCurrentLineupDeployCount();
settlementHistoryRecorded = false;
settlementHeroStatsRecorded = false;
settlementRewardsGranted = false;
}
private void Update()
@@ -321,7 +327,7 @@ public class settlementController : MonoBehaviour
return;
}
allHeroes = Resources.LoadAll<AllyHero_SO>(string.Empty);
allHeroes = RuntimeResourcesCache.LoadAllAllyHeroes();
if (allHeroes == null || allHeroes.Length == 0)
{
return;
@@ -487,7 +493,7 @@ public class settlementController : MonoBehaviour
{
if (_cachedAllyHeroSOs == null || _cachedAllyHeroSOs.Length == 0)
{
_cachedAllyHeroSOs = Resources.LoadAll<AllyHero_SO>(string.Empty);
_cachedAllyHeroSOs = RuntimeResourcesCache.LoadAllAllyHeroes();
}
}
@@ -527,6 +533,7 @@ public class settlementController : MonoBehaviour
settlementHistoryRecorded = false;
settlementHeroStatsRecorded = false;
roomScoreSubmitTriggered = false;
settlementRewardsGranted = false;
OnSettlementCompleted?.Invoke();
equipSmelt.NotifySettlementCompleted();
@@ -561,6 +568,7 @@ public class settlementController : MonoBehaviour
targetTotalPercent = (float)targetTotalScore / Mathf.Max(1, _1000000) * 100f;
PlayerSkillService.NotifySettlementCompleted(targetIdolScore);
GrantSettlementRewardsAndDisplay();
finalScore_Text.text = targetTotalScore.ToString();
pmScoreSum_Text.text = targetPmScore.ToString();
@@ -748,6 +756,90 @@ public class settlementController : MonoBehaviour
StartSettlementIntro();
}
private void GrantSettlementRewardsAndDisplay()
{
if (settlementRewardsGranted)
{
return;
}
settlementRewardsGranted = true;
int coinReward = Mathf.CeilToInt((targetTotalScore / 10000f) * 0.75f);
int materialReward = Mathf.CeilToInt((targetTotalScore / 10000f) * 0.20f);
int playerExpReward = Mathf.FloorToInt(targetTotalScore / 100000f);
moneyToGive_thisLevel = coinReward;
Player_SO playerData = LoadDefaultPlayerSo();
if (playerData != null)
{
PlayerEconomyLedger.EnsureInstance().AttachPlayerData(playerData);
PlayerExperienceLedger.EnsureInstance().AttachPlayerData(playerData);
ExpBottleLedger.EnsureInstance().AttachPlayerData(playerData);
DushMaterialLedger.EnsureInstance().AttachPlayerData(playerData);
}
PlayerEconomyLedger.EnsureInstance().AddCoins(coinReward);
PlayerEconomyLedger.EnsureInstance().AddMaterial(materialReward);
PlayerExperienceLedger.EnsureInstance().AddExperience(playerExpReward);
PlayerEconomyLedger.EnsureInstance().SaveNow();
PlayerExperienceLedger.EnsureInstance().SaveNow();
if (reward_money_Text != null)
{
reward_money_Text.text = $"+{coinReward}";
}
if (reward_idolEXP_bottle_Text != null)
{
reward_idolEXP_bottle_Text.text = $"+{materialReward}";
}
if (reward_playerEXP_Text != null)
{
reward_playerEXP_Text.text = $"+{playerExpReward}";
}
RebuildSettlementRewardVisuals(coinReward, materialReward, playerExpReward);
}
private void RebuildSettlementRewardVisuals(int coinReward, int materialReward, int playerExpReward)
{
if (rewardParent != null)
{
for (int i = rewardParent.childCount - 1; i >= 0; i--)
{
Destroy(rewardParent.GetChild(i).gameObject);
}
}
SpawnSettlementReward(global::rewardPrefab.RewardVisualType.Coins, coinReward);
SpawnSettlementReward(global::rewardPrefab.RewardVisualType.Material, materialReward);
SpawnSettlementReward(global::rewardPrefab.RewardVisualType.PlayerExp, playerExpReward);
}
private void SpawnSettlementReward(global::rewardPrefab.RewardVisualType rewardType, int amount)
{
if (rewardPrefab == null || rewardParent == null)
{
return;
}
GameObject go = Instantiate(rewardPrefab, rewardParent);
global::rewardPrefab prefab = go != null ? go.GetComponent<global::rewardPrefab>() : null;
if (prefab != null)
{
prefab.Bind(rewardType, amount);
}
}
private static Player_SO LoadDefaultPlayerSo()
{
return RuntimeResourcesCache.LoadDefaultPlayerSo();
}
private void TryRecordRecentPlayHistory(int noteCountRaw)
{
if (GameConfig.autoPlayEnabled)
@@ -1287,7 +1379,7 @@ public class settlementController : MonoBehaviour
return;
}
dlcData[] allDlcs = Resources.LoadAll<dlcData>("");
dlcData[] allDlcs = RuntimeResourcesCache.LoadAllDlcs();
dlcData foundDlc = null;
for (int i = 0; i < allDlcs.Length; i++)
@@ -2038,7 +2130,7 @@ public class settlementController : MonoBehaviour
{
if (_cachedAllyHeroSOs == null || _cachedAllyHeroSOs.Length == 0)
{
_cachedAllyHeroSOs = Resources.LoadAll<AllyHero_SO>("");
_cachedAllyHeroSOs = RuntimeResourcesCache.LoadAllAllyHeroes();
}
foreach (var a in _cachedAllyHeroSOs)
{
@@ -2054,7 +2146,7 @@ public class settlementController : MonoBehaviour
{
if (_cachedAllyHeroSOs == null || _cachedAllyHeroSOs.Length == 0)
{
_cachedAllyHeroSOs = Resources.LoadAll<AllyHero_SO>("");
_cachedAllyHeroSOs = RuntimeResourcesCache.LoadAllAllyHeroes();
}
if (_cachedAllyHeroSOs != null && _cachedAllyHeroSOs.Length > 0)
{