Compare commits

...

2 Commits

Author SHA1 Message Date
qup35p
1f5aa09ee3 Merge branch 'main' of https://git.bltcnetwork.com/UNITY-PROJECT/Petition-to-the-Gods-V3
:wq
2025-11-19 19:42:06 +08:00
qup35p
615d8a8f91 <fix6.7.18.30> 2025-11-19 19:30:13 +08:00
8 changed files with 11556 additions and 49 deletions

View File

@ -1,4 +1,4 @@
using System.Collections;
using System.Collections;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
@ -11,6 +11,10 @@ public class ClientGameBackToRealSceneController : MonoBehaviour
public VideoPlayer videoPlayer;
public RawImage videoDisplay;
// --- 【新增變數】用於追蹤兩個條件是否滿足 ---
private bool isVideoFinished = false;
private bool isSignalReceived = false;
private void Awake()
{
Instance = this;
@ -35,7 +39,7 @@ public class ClientGameBackToRealSceneController : MonoBehaviour
// 設置影片結束事件
videoPlayer.loopPointReached += OnVideoFinished;
// 設置影片顯示
// 設置影片顯示 (略)
if (videoDisplay != null)
{
videoPlayer.targetTexture = null;
@ -47,13 +51,43 @@ public class ClientGameBackToRealSceneController : MonoBehaviour
}
}
// 影片播放結束時呼叫
void OnVideoFinished(VideoPlayer vp)
{
Debug.Log("影片播放完成,準備跳轉");
if (!string.IsNullOrEmpty(ClientLastWordsSceneController.words))
Debug.Log("影片播放完成。");
isVideoFinished = true; // 影片結束標記設為 true
CheckAndLoadScene(); // 檢查是否可以跳轉
}
// --- 【新增方法】供 ClientMessageHandler 呼叫,標記訊號已收到 ---
public void ReceiveSignalFromPlayerB()
{
Debug.Log("收到玩家B的訊號 (gameFinalWords)。");
isSignalReceived = true; // 訊號接收標記設為 true
CheckAndLoadScene(); // 檢查是否可以跳轉
}
// --- 【新增方法】核心檢查跳轉邏輯 ---
private void CheckAndLoadScene()
{
// 確保 ClientLastWordsSceneController.words 已經有值
bool hasWords = !string.IsNullOrEmpty(ClientLastWordsSceneController.words);
if (isVideoFinished && isSignalReceived && hasWords)
{
Debug.Log("🎉 影片和訊號條件滿足,準備跳轉到下一場景...");
StartCoroutine(LoadNextScene());
}
else if (isVideoFinished && !isSignalReceived)
{
// 影片已結束,等待訊號
Debug.Log("影片已結束正在等待玩家B訊號...");
}
else if (!isVideoFinished && isSignalReceived)
{
// 訊號已收到,等待影片結束
Debug.Log("已收到玩家B訊號正在等待影片播放完成...");
}
}
public IEnumerator LoadNextScene()
@ -61,4 +95,4 @@ public class ClientGameBackToRealSceneController : MonoBehaviour
yield return new WaitForSeconds(0f);
SceneManager.LoadScene("ClientLastWordsScene");
}
}
}

View File

@ -1,4 +1,4 @@
using UnityEngine;
using UnityEngine;
using Mirror;
using System;
@ -81,10 +81,11 @@ public class ClientMessageHandler : MonoBehaviour
ClientLastWordsSceneController.words = msg.payload;
if (ClientGameBackToRealSceneController.Instance)
{
StartCoroutine( ClientGameBackToRealSceneController.Instance.LoadNextScene());
                                // ✅ 將直接跳轉的程式碼,改為呼叫新的檢查函式
                                ClientGameBackToRealSceneController.Instance.ReceiveSignalFromPlayerB();
}
}
}
break;
case "gameTalkingStart":

View File

@ -1,18 +1,21 @@
using UnityEngine;
using Mirror;
using Mirror.BouncyCastle.Tls.Crypto.Impl.BC;
using UnityEngine.SceneManagement;
// 注意Mirror.BouncyCastle.Tls.Crypto.Impl.BC; 這個 using 似乎是多餘的,但暫時保留。
public class NetworkMessageHandler : MonoBehaviour
{
public static NetworkMessageHandler Instance;
public static NetworkConnectionToClient CurrentConn;
// ⭐ 新增:用於記錄是否有未處理的 workMessage (跨場景緩存)
public bool hasPendingWorkMessage = false;
void Awake()
{
if (Instance == null)
{
Instance = this;
DontDestroyOnLoad(gameObject);
}
else
@ -44,11 +47,13 @@ public class NetworkMessageHandler : MonoBehaviour
SendMessageToClient("welcome", "hello");
// clean data
GlobalData.ResetGameData();
ServerWorkMessagePanel.cleanData();
ServerWorkMessagePanel.workMessageCount = 0;
}
break;
}
@ -56,37 +61,63 @@ public class NetworkMessageHandler : MonoBehaviour
break;
case "workMessage":
{
GameMessageWork msgObj = JsonUtility.FromJson<GameMessageWork>(msg.payload);
if (msgObj != null)
{
                        // 關鍵修正 1在切換 Panel 之前,先更新所有靜態數據 (保留)
                        ServerWorkMessagePanel.workMessageCount = msgObj.count;
ServerWorkMessagePanel.workMessage = msgObj.message;
ServerWorkMessagePanel.workMessageType = msgObj.type;
ServerWorkMessagePanel.workPresent = msgObj.present;
ServerWorkMessagePanel.workMessageCount = msgObj.count;
if (ServerWorkMessagePanel.workMessageCount != 0)
{
if (ServerWorkSceneController.Instance != null)
{
ServerWorkSceneController.Instance.processStep(2);
                                // 情況 1: ServerWorkScene 已經載入 (正常流程或影片播放完畢後)
                                // 檢查當前是否正在播放 Step 5 影片
                                if (ServerWorkMessageReplyWait1Panel.Instance != null && ServerWorkMessageReplyWait1Panel.Instance.gameObject.activeInHierarchy)
{
                                    // 影片正在播放,暫存訊號 (邏輯保留)
                                    ServerWorkMessageReplyWait1Panel.Instance.ReceiveClientSignal();
Debug.Log("WorkMessage 收到,但 Step 5 影片正在播放,延遲切換。");
}
else
{
                                    // 影片未播放,直接切換到 Step 2 (MessagePanel)
                                    ServerWorkSceneController.Instance.processStep(2);
Debug.Log("WorkMessage 收到,直接切換到 Step 2。");
}
}
else
{
                                // 情況 2: ServerWorkScene 尚未載入 (Server正在 Intro 影片中)
                                // 設置緩存旗標 (保留)
                                hasPendingWorkMessage = true;
Debug.Log("WorkMessage 收到,但 ServerWorkScene 尚未載入,設置緩存旗標。");
}
}
if (ServerWorkMessagePanel.Instance)
{
ServerWorkMessagePanel.Instance.onReceivedData();
}
}
                        // ⭐ 移除此處的 onReceivedData() 呼叫
                        // 因為當場景流程切換到 Step 2 時ServerWorkMessagePanel.OnEnable() 會自行處理。
                        /*
                        if (ServerWorkMessagePanel.Instance)
                        {
                            ServerWorkMessagePanel.Instance.onReceivedData();
                        }
                        */
                    }
else
{
Debug.LogError("workMessage failed");
}
}
break;
break; // 修正:這個 break 才是結束 case "workMessage" 的地方
case "workProcess":
{
switch(msg.payload)
{
switch (msg.payload)
{
case "exit":
if (ServerWorkSceneController.Instance)
@ -94,6 +125,7 @@ public class NetworkMessageHandler : MonoBehaviour
ServerWorkSceneController.Instance.processStep(9);
}
break;
case "continue":
if (ServerWorkSceneController.Instance)
{
@ -104,7 +136,7 @@ public class NetworkMessageHandler : MonoBehaviour
}
break;
case "gameSurvey":
{
{
GameMessageSurvey msgObj = JsonUtility.FromJson<GameMessageSurvey>(msg.payload);
if (msgObj != null)
@ -148,7 +180,7 @@ public class NetworkMessageHandler : MonoBehaviour
}
break;
case "getWords":
{
{
if (ServerWorkSceneController.Instance)
{
ServerWorkSceneController.Instance.processStep(18);
@ -169,10 +201,12 @@ public class NetworkMessageHandler : MonoBehaviour
{
ServerWorkSceneController.Instance.processStep(19);
}
if (ServerGameFinalSurveyPanel.Instance)
{
ServerGameFinalSurveyPanel.Instance.loadSurveyData();
}
}
}
break;
@ -196,12 +230,10 @@ public class NetworkMessageHandler : MonoBehaviour
break;
case "gameSticksFinish":
{
// 這裡通常是空的 case 區塊
}
break;
}
}
public void SendMessageToClient(string action, string message)

View File

@ -1,4 +1,4 @@
using System;
using System;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
@ -46,13 +46,19 @@ public class ServerWorkMessagePanel : MonoBehaviour
{
replyButton.onClick.AddListener(replyButton_onClicked);
}
onReceivedData();
//onReceivedData();
}
private void OnEnable()
{
        // 如果 Panel 被啟用時,數據已經在 NetworkMessageHandler 設置完成,
        // 這裡會立即執行 onReceivedData 刷新狀態。
        //onReceivedData();
}
public void onReceivedData()
{
if (string.IsNullOrEmpty(workMessageType))
{
if (string.IsNullOrEmpty(workMessageType)) // 如果靜態數據為空
        {
if (messageLoadPanel)
{
messageLoadPanel.SetActive(true);
@ -63,7 +69,8 @@ public class ServerWorkMessagePanel : MonoBehaviour
}
return;
}
if ( messageInfoText)
// 如果 workMessageType 不為空,表示數據已收到,將顯示 messageReceivedPanel
if (messageInfoText)
{
messageInfoText.text = "系統提示:客戶已傳達願望給您,是否要幫助此客戶?請點擊回覆";
}

View File

@ -1,4 +1,4 @@
using System.Collections;
using System.Collections;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
@ -12,20 +12,26 @@ public class ServerWorkMessageReplyExitPanel : MonoBehaviour
public VideoPlayer videoPlayer;
public RawImage videoDisplay;
private bool clientResponseReceived = false; // ✅ 新增
private bool videoHasFinished = false; // ✅ 新增
private void Awake()
{
Instance = this;
}
void Start()
{
SetupVideoPlayer();
}
public void play()
{
if (videoPlayer != null)
{
Debug.Log("SERVER: 開始播放影片");
clientResponseReceived = false; // ✅ 重置狀態
videoHasFinished = false; // ✅ 重置狀態
videoPlayer.Play();
}
}
@ -34,18 +40,36 @@ public class ServerWorkMessageReplyExitPanel : MonoBehaviour
{
if (videoPlayer != null)
{
Debug.Log("SERVER: 停止播放影片");
videoPlayer.Stop();
}
}
// ✅ 新增:當收到 CLIENT 訊號時呼叫此方法
public void OnClientResponseReceived()
{
Debug.Log("SERVER: 收到 CLIENT 訊號");
clientResponseReceived = true;
// 如果影片已經播完,立即跳轉
if (videoHasFinished)
{
Debug.Log("SERVER: 影片已播完,立即跳轉");
ProcessNextStep();
}
else
{
Debug.Log("SERVER: 影片還在播放,等待播放完成...");
}
}
void SetupVideoPlayer()
{
if (videoPlayer != null)
{
// 設置影片結束事件
videoPlayer.loopPointReached += OnVideoFinished;
videoPlayer.loopPointReached += OnVideoFinished; // ✅ 這行現在不會報錯了
videoPlayer.isLooping = false;
// 設置影片顯示
if (videoDisplay != null)
{
videoPlayer.targetTexture = null;
@ -54,13 +78,44 @@ public class ServerWorkMessageReplyExitPanel : MonoBehaviour
videoPlayer.targetTexture = rt;
videoDisplay.texture = rt;
}
Debug.Log("SERVER: VideoPlayer 設置完成");
}
else
{
Debug.LogError("SERVER: VideoPlayer 未指定!");
}
}
// ✅ 新增:影片播放完成的事件處理
void OnVideoFinished(VideoPlayer vp)
{
Debug.Log("影片播放完成");
ServerWorkSceneController.Instance.processStep(10);
Debug.Log("SERVER: 影片播放完成");
videoHasFinished = true;
// 只有當收到 CLIENT 訊號後才跳轉
if (clientResponseReceived)
{
Debug.Log("SERVER: CLIENT 訊號已收到,準備跳轉");
ProcessNextStep();
}
else
{
Debug.Log("SERVER: 影片播完,等待 CLIENT 訊號...");
}
}
}
// ✅ 新增:執行跳轉
void ProcessNextStep()
{
if (ServerWorkSceneController.Instance != null)
{
Debug.Log("SERVER: 跳轉到步驟 10");
ServerWorkSceneController.Instance.processStep(10);
}
else
{
Debug.LogError("SERVER: ServerWorkSceneController.Instance 不存在!無法跳轉");
}
}
}

View File

@ -1,4 +1,4 @@
using System.Collections;
using System.Collections;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
@ -12,14 +12,39 @@ public class ServerWorkMessageReplyWait1Panel : MonoBehaviour
public VideoPlayer videoPlayer;
public RawImage videoDisplay;
// ===============================================
// ✅ 新增的鎖定和訊號追蹤 (保留與上一次修改的內容)
// ===============================================
// 這個旗標指示:在影片播放期間,客戶端是否有發送新願望 (workMessage)
private bool clientSignalReceived = false;
private bool isVideoPlaying = false;
private void Awake()
{
Instance = this;
}
void Start()
{
SetupVideoPlayer();
}
// 接收來自 NetworkMessageHandler 的訊號
// 這個訊號代表有新的 workMessage (新願望) 進來,需要切換到 Step 2。
public void ReceiveClientSignal()
{
if (isVideoPlaying)
{
clientSignalReceived = true;
// 收到新願望,但影片正在播,暫存訊號。
Debug.Log("ServerWorkMessageReplyWait1Panel: 收到客戶端新願望訊號,影片正在播放中,訊號暫存。");
}
else
{
// 影片沒有在播放,理論上這不會發生,但如果發生,代表可以立即切換到 Step 2。
Debug.Log("ServerWorkMessageReplyWait1Panel: 收到客戶端新願望訊號,影片已停止,立即切換到 Step 2。");
ServerWorkSceneController.Instance.processStep(2); // 直接切換到 MessagePanel
}
}
public void play()
@ -27,6 +52,9 @@ public class ServerWorkMessageReplyWait1Panel : MonoBehaviour
if (videoPlayer != null)
{
videoPlayer.Play();
isVideoPlaying = true; // 影片開始播放,鎖定流程
clientSignalReceived = false; // 重置客戶端訊號
Debug.Log("ServerWorkMessageReplyWait1Panel: 影片開始播放,流程鎖定。");
}
}
@ -36,6 +64,8 @@ public class ServerWorkMessageReplyWait1Panel : MonoBehaviour
{
videoPlayer.Stop();
}
isVideoPlaying = false;
clientSignalReceived = false; // 停止時重置所有狀態
}
void SetupVideoPlayer()
@ -45,7 +75,7 @@ public class ServerWorkMessageReplyWait1Panel : MonoBehaviour
// 設置影片結束事件
videoPlayer.loopPointReached += OnVideoFinished;
// 設置影片顯示
// 設置影片顯示 (略)
if (videoDisplay != null)
{
videoPlayer.targetTexture = null;
@ -59,8 +89,23 @@ public class ServerWorkMessageReplyWait1Panel : MonoBehaviour
void OnVideoFinished(VideoPlayer vp)
{
Debug.Log("影片播放完成");
ServerWorkSceneController.Instance.processStep(6);
}
Debug.Log("影片播放完成,流程鎖定解除。");
isVideoPlaying = false; // 影片播放完畢,解除鎖定
}
// ===============================================
// ⭐ 關鍵修正:檢查是否有暫存的客戶端願望訊號
// ===============================================
if (clientSignalReceived)
{
// 如果收到新願望訊號,則優先切換到 MessagePanel (Step 2)
Debug.Log("影片播畢,偵測到暫存的新願望訊號,切換到 Step 2 (MessagePanel)。");
ServerWorkSceneController.Instance.processStep(2);
}
else
{
// 影片播畢,沒有收到新願望,執行原定流程:切換到 Step 6
Debug.Log("影片播畢,沒有收到客戶端訊號,執行預設流程,切換到 Step 6 (Wait1WorkingPanel)。");
ServerWorkSceneController.Instance.processStep(6);
}
}
}

View File

@ -47,7 +47,30 @@ public class ServerWorkSceneController : MonoBehaviour
void SetupScene()
{
processStep(1);
// ⭐ 關鍵修正 3在場景啟動時檢查是否有緩存的願望訊息
if (NetworkMessageHandler.Instance != null && NetworkMessageHandler.Instance.hasPendingWorkMessage)
{
// 如果有緩存的訊息,直接進入 Step 2 (Message Panel)
Debug.Log("ServerWorkScene 載入完成,發現緩存願望訊息,直接跳到 Step 2。");
processStep(2);
// 【新增修正點 A】強制在流程切換後Panel 讀取最新的靜態資料
// 這可以確保 Panel 不會錯過資料。
if (ServerWorkMessagePanel.Instance != null)
{
ServerWorkMessagePanel.Instance.onReceivedData();
Debug.Log("強制呼叫 ServerWorkMessagePanel.onReceivedData() 來顯示願望內容。");
}
// 清除緩存旗標,防止下次場景重載誤判
NetworkMessageHandler.Instance.hasPendingWorkMessage = false;
}
else
{
// 正常流程:從 Step 1 (Intro Panel) 開始
Debug.Log("ServerWorkScene 正常載入,從 Step 1 (Intro Panel) 開始。");
processStep(1);
}
}
public void processStep(int step)