using UnityEngine; using System.Net.Sockets; using System.Net; using System.Text; using System.Threading; using System.Collections.Generic; using System; public class DisplayServer : MonoBehaviour { private TcpListener listener; // 用于接受客户端连接的TCP监听器 private Thread listenThread; // 用于接受客户端连接的线程 private CancellationTokenSource listenCts = new CancellationTokenSource(); // 控制线程取消 private volatile bool isRunning = true; // 线程安全的服务器循环标志 private NetworkStream clientStream; // 当前客户端的网络流,用于发送消息 public Transform background; // UI页面的父级变换 [System.Serializable] public class PageModel { public string pageName; // 页面名称 public GameObject model; // 与页面关联的模型(挂载ModelController) } public List pageModels = new List(); // 页面-模型映射列表 private readonly Queue messageQueue = new Queue(); // 线程安全的消息队列 private readonly object queueLock = new object(); // 消息队列访问锁 private string currentPage = ""; // 跟踪当前显示的页面 private Dictionary pageModelCache; // 页面-模型映射的缓存 // 脚本启动时调用 void Start() { // 设置显示端分辨率为 3328x1352 Screen.SetResolution(3328, 1352, false); // 初始化页面-模型缓存以加快查找 pageModelCache = new Dictionary(); foreach (var pm in pageModels) { if (!string.IsNullOrEmpty(pm.pageName) && pm.model != null) { pageModelCache[pm.pageName] = pm; } } // 在端口8888上启动TCP监听 listener = new TcpListener(IPAddress.Any, 8888); listener.Start(); // 启动线程以监听客户端连接 listenThread = new Thread(() => ListenForClients(listenCts.Token)); listenThread.Start(); Debug.Log("显示端服务器已启动,等待触摸端连接..."); // 显示初始页面 ShowPage("首页"); } // 监听传入的TCP客户端连接 private void ListenForClients(CancellationToken token) { while (!token.IsCancellationRequested && isRunning) { try { TcpClient client = listener.AcceptTcpClient(); Debug.Log("触摸端已连接!"); clientStream = client.GetStream(); // 保存客户端流以发送消息 // 为每个客户端启动新线程处理通信 Thread clientThread = new Thread(() => HandleClientComm(client, token)); clientThread.Start(); } catch (Exception ex) { Debug.LogError($"接受客户端连接错误: {ex.Message}"); } } } // 处理与单个客户端的通信 private void HandleClientComm(TcpClient tcpClient, CancellationToken token) { NetworkStream stream = tcpClient.GetStream(); byte[] message = new byte[4096]; int bytesRead; // 在未取消或未断开连接的情况下持续读取 while (!token.IsCancellationRequested && isRunning) { try { bytesRead = stream.Read(message, 0, 4096); if (bytesRead == 0) break; // 客户端断开连接 string data = Encoding.UTF8.GetString(message, 0, bytesRead); lock (queueLock) { messageQueue.Enqueue(data); // 将消息加入队列以供处理 } } catch (Exception ex) { Debug.LogError($"读取客户端消息错误: {ex.Message}"); break; } } // 清理客户端资源 stream.Close(); tcpClient.Close(); clientStream = null; // 清空客户端流 Debug.Log("客户端断开连接"); } // 在主线程中处理排队的消息并发送动画进度 private void Update() { // 处理接收到的消息 string msg = null; lock (queueLock) { if (messageQueue.Count > 0) { msg = messageQueue.Dequeue(); // 获取下一条消息 } } if (!string.IsNullOrEmpty(msg)) { Debug.Log($"收到消息: {msg}"); if (msg.StartsWith("Page:")) { string pageName = msg.Replace("Page:", ""); ShowPage(pageName); } else if (msg.StartsWith("Model:")) { string modelName = msg.Replace("Model:", ""); PlayModelAnimation(modelName); } else if (msg.StartsWith("Progress:")) { if (float.TryParse(msg.Replace("Progress:", ""), out float progress)) { SetAnimationProgress(progress); Debug.Log($"处理进度消息: Progress:{progress:F2}"); } } } // 每帧发送动画进度到客户端 if (clientStream != null && clientStream.CanWrite) { if (pageModelCache.TryGetValue(currentPage, out PageModel pm) && pm != null && pm.model != null) { ModelController mc = pm.model.GetComponent(); if (mc != null) { float progress = mc.GetAnimationProgress(); try { string progressMsg = $"Progress:{progress:F2}"; byte[] data = Encoding.UTF8.GetBytes(progressMsg); clientStream.Write(data, 0, data.Length); Debug.Log($"发送动画进度: {progressMsg}"); } catch (Exception ex) { Debug.LogError($"发送动画进度失败: {ex.Message}"); clientStream = null; // 标记流失效 } } } } } // 切换激活的UI页面并更新模型 private void ShowPage(string pageName) { foreach (Transform child in background) { child.gameObject.SetActive(child.name == pageName); // 仅激活目标页面 } currentPage = pageName; // 更新模型可见性并重置动画 foreach (var pageModel in pageModels) { if (pageModel.model != null) { bool isActive = pageModel.pageName == pageName; pageModel.model.SetActive(isActive); ModelController mc = pageModel.model.GetComponent(); if (mc != null) { mc.ResetAnimation(); Debug.Log($"模型 {pageModel.model.name} 重置,页面: {pageName}"); } } } Debug.Log($"显示端切换到页面: {pageName}"); } // 为指定模型播放动画 private void PlayModelAnimation(string modelName) { PageModel pm = pageModels.Find(p => p.model != null && p.model.name == modelName); if (pm != null) { ModelController mc = pm.model.GetComponent(); if (mc != null) { mc.PlayAnimation(); Debug.Log($"播放模型动画: {modelName}"); } } } // 设置当前页面模型的动画进度 private void SetAnimationProgress(float progress) { if (pageModelCache.TryGetValue(currentPage, out PageModel pm) && pm != null && pm.model != null) { ModelController mc = pm.model.GetComponent(); if (mc != null) { mc.SetAnimationProgress(progress); Debug.Log($"设置模型 {pm.model.name} 进度: {progress:F2}"); } } else { Debug.LogWarning($"未找到页面 {currentPage} 的模型或ModelController"); } } // 应用程序退出时清理资源 private void OnApplicationQuit() { isRunning = false; listenCts.Cancel(); listener.Stop(); clientStream?.Close(); if (listenThread != null && listenThread.IsAlive) { listenThread.Join(1000); // 等待线程结束 } } }