阶段备份4

This commit is contained in:
XgC2961 2025-08-30 09:43:08 +08:00
parent 43d7052963
commit c7d2ecea3d
5 changed files with 229 additions and 51 deletions

View File

@ -29,6 +29,11 @@ public class DisplayServer : MonoBehaviour
private string currentPage = ""; // 跟踪当前显示的页面
private Dictionary<string, PageModel> pageModelCache; // 页面-模型映射的缓存
private bool isPlayingAnimation = false; // 跟踪动画播放状态
private bool isClientDragging = false; // 跟踪客户端是否正在拖动Slider
private float lastSendTime = 0f; // 上次发送进度的时间
private float sendInterval = 0.05f; // 进度发送间隔(秒)
private float lastSentProgress = 0f; // 记录上次发送的进度
// 脚本启动时调用
void Start()
@ -136,37 +141,56 @@ public class DisplayServer : MonoBehaviour
{
string pageName = msg.Replace("Page:", "");
ShowPage(pageName);
isPlayingAnimation = false; // 重置播放状态
isClientDragging = false; // 重置拖动状态
lastSentProgress = 0f; // 重置进度
}
else if (msg.StartsWith("Model:"))
{
string modelName = msg.Replace("Model:", "");
PlayModelAnimation(modelName);
lastSentProgress = 0f; // 重置进度
}
else if (msg.StartsWith("Progress:"))
{
if (float.TryParse(msg.Replace("Progress:", ""), out float progress))
{
SetAnimationProgress(progress);
isPlayingAnimation = false; // 拖动时停止播放
isClientDragging = true; // 标记客户端正在拖动
lastSentProgress = progress; // 更新最后发送的进度
Debug.Log($"处理进度消息: Progress:{progress:F2}");
}
}
else if (msg == "EndDrag")
{
isClientDragging = false; // 客户端拖动结束
Debug.Log("客户端Slider拖动结束");
}
}
// 每帧发送动画进度到客户端
if (clientStream != null && clientStream.CanWrite)
// 仅当动画播放且客户端未拖动时发送进度,且限制发送频率
if (isPlayingAnimation && !isClientDragging && clientStream != null && clientStream.CanWrite)
{
if (Time.time - lastSendTime >= sendInterval)
{
if (pageModelCache.TryGetValue(currentPage, out PageModel pm) && pm != null && pm.model != null)
{
ModelController mc = pm.model.GetComponent<ModelController>();
if (mc != null)
if (mc != null && mc.IsPlayingAnimation())
{
float progress = mc.GetAnimationProgress();
// 仅当进度有效且变化显著时发送
if (progress > 0f && Mathf.Abs(progress - lastSentProgress) > 0.005f)
{
try
{
string progressMsg = $"Progress:{progress:F2}";
byte[] data = Encoding.UTF8.GetBytes(progressMsg);
clientStream.Write(data, 0, data.Length);
Debug.Log($"发送动画进度: {progressMsg}");
lastSentProgress = progress; // 更新最后发送的进度
lastSendTime = Time.time; // 更新发送时间
}
catch (Exception ex)
{
@ -175,6 +199,13 @@ public class DisplayServer : MonoBehaviour
}
}
}
else
{
// 动画已停止,更新状态
isPlayingAnimation = false;
}
}
}
}
}
@ -199,6 +230,13 @@ public class DisplayServer : MonoBehaviour
ModelController mc = pageModel.model.GetComponent<ModelController>();
if (mc != null)
{
// 取消订阅旧事件
mc.OnAnimationFinished -= OnModelAnimationFinished;
// 订阅动画结束事件
if (isActive)
{
mc.OnAnimationFinished += OnModelAnimationFinished;
}
mc.ResetAnimation();
Debug.Log($"模型 {pageModel.model.name} 重置,页面: {pageName}");
}
@ -216,9 +254,23 @@ public class DisplayServer : MonoBehaviour
ModelController mc = pm.model.GetComponent<ModelController>();
if (mc != null)
{
// 取消旧订阅,添加新订阅
mc.OnAnimationFinished -= OnModelAnimationFinished;
mc.OnAnimationFinished += OnModelAnimationFinished;
mc.PlayAnimation();
isPlayingAnimation = true; // 确认动画开始播放
Debug.Log($"播放模型动画: {modelName}");
}
else
{
isPlayingAnimation = false; // 动画未启动
Debug.LogWarning($"模型 {modelName} 未找到ModelController");
}
}
else
{
isPlayingAnimation = false; // 动画未启动
Debug.LogWarning($"未找到模型 {modelName}");
}
}
@ -240,6 +292,31 @@ public class DisplayServer : MonoBehaviour
}
}
// 处理动画结束事件
private void OnModelAnimationFinished()
{
isPlayingAnimation = false;
Debug.Log("模型动画播放完成,停止发送进度");
// 发送最终进度 1.0
if (clientStream != null && clientStream.CanWrite)
{
try
{
string progressMsg = "Progress:1.00";
byte[] data = Encoding.UTF8.GetBytes(progressMsg);
clientStream.Write(data, 0, data.Length);
Debug.Log($"发送最终动画进度: {progressMsg}");
lastSentProgress = 1f;
lastSendTime = Time.time;
}
catch (Exception ex)
{
Debug.LogError($"发送最终进度失败: {ex.Message}");
clientStream = null;
}
}
}
// 应用程序退出时清理资源
private void OnApplicationQuit()
{
@ -248,6 +325,19 @@ public class DisplayServer : MonoBehaviour
listener.Stop();
clientStream?.Close();
// 取消所有动画结束事件订阅
foreach (var pm in pageModels)
{
if (pm.model != null)
{
ModelController mc = pm.model.GetComponent<ModelController>();
if (mc != null)
{
mc.OnAnimationFinished -= OnModelAnimationFinished;
}
}
}
if (listenThread != null && listenThread.IsAlive)
{
listenThread.Join(1000); // 等待线程结束

View File

@ -1,5 +1,6 @@
using UnityEngine;
using System.Collections.Generic;
using System;
public class ModelController : MonoBehaviour
{
@ -8,9 +9,15 @@ public class ModelController : MonoBehaviour
private bool isPlaying = false; // 跟踪动画播放状态
[Header("默认动画状态名称")]
public string defaultAnimName = "Idle"; // 默认动画状态名称
public string defaultAnimName = "Take 001"; // 默认动画状态名称
private Dictionary<string, int> stateHashes = new Dictionary<string, int>(); // 动画状态哈希缓存
private float lastLoggedProgress = -1f; // 记录上次日志的进度值
private float lastWarningTime = 0f; // 记录上次警告日志时间
private const float warningInterval = 1f; // 警告日志间隔(秒)
// 动画结束事件
public event Action OnAnimationFinished;
// 脚本初始化时调用
void Awake()
@ -28,12 +35,18 @@ public class ModelController : MonoBehaviour
{
if (isPlaying && animator != null && !string.IsNullOrEmpty(currentAnim))
{
if (!animator.enabled)
{
animator.enabled = true; // 确保Animator启用
Debug.Log($"重新启用Animator: {currentAnim}");
}
AnimatorStateInfo stateInfo = animator.GetCurrentAnimatorStateInfo(0);
if (stateInfo.IsName(currentAnim) && stateInfo.normalizedTime >= 1f)
{
// 动画播放完成,暂停并标记
animator.enabled = false;
isPlaying = false;
OnAnimationFinished?.Invoke(); // 通知动画结束
Debug.Log($"动画 {currentAnim} 播放完成,暂停");
}
}
@ -80,12 +93,13 @@ public class ModelController : MonoBehaviour
return;
}
// 停止播放状态
isPlaying = false;
animator.enabled = true;
float clampedTime = Mathf.Clamp01(normalizedTime);
animator.Play(currentAnim, 0, clampedTime); // 设置动画到指定时间
animator.Update(0f); // 强制立即更新
animator.enabled = false; // 暂停动画
isPlaying = false; // 标记动画暂停
Debug.Log($"设置动画 {currentAnim} 进度: {clampedTime:F2}");
}
@ -115,13 +129,23 @@ public class ModelController : MonoBehaviour
/// <returns>当前动画进度若无动画则返回0</returns>
public float GetAnimationProgress()
{
if (animator == null || string.IsNullOrEmpty(currentAnim) || !gameObject.activeSelf)
if (animator == null || !animator.enabled || string.IsNullOrEmpty(currentAnim) || !gameObject.activeSelf)
{
if (Time.time - lastWarningTime >= warningInterval)
{
Debug.LogWarning($"无法获取动画进度: animator={animator}, enabled={animator?.enabled}, currentAnim={currentAnim}, active={gameObject.activeSelf}");
lastWarningTime = Time.time;
}
return 0f;
}
if (!AnimatorHasState(currentAnim))
{
if (Time.time - lastWarningTime >= warningInterval)
{
Debug.LogWarning($"Animator上不存在状态: {currentAnim}");
lastWarningTime = Time.time;
}
return 0f;
}
@ -129,9 +153,19 @@ public class ModelController : MonoBehaviour
if (stateInfo.IsName(currentAnim))
{
float progress = Mathf.Clamp01(stateInfo.normalizedTime % 1f);
// 仅当进度变化超过0.01时记录日志
if (Mathf.Abs(progress - lastLoggedProgress) > 0.01f)
{
Debug.Log($"获取动画 {currentAnim} 进度: {progress:F2}");
lastLoggedProgress = progress;
}
return progress;
}
if (Time.time - lastWarningTime >= warningInterval)
{
Debug.LogWarning($"动画状态不匹配: currentAnim={currentAnim}, state={stateInfo.fullPathHash}");
lastWarningTime = Time.time;
}
return 0f;
}
@ -147,4 +181,10 @@ public class ModelController : MonoBehaviour
}
return false;
}
// 获取动画播放状态
public bool IsPlayingAnimation()
{
return isPlaying;
}
}

View File

@ -26,6 +26,7 @@ public class TouchClient : MonoBehaviour
private readonly Queue<float> progressQueue = new Queue<float>(); // 线程安全的进度队列
private readonly object queueLock = new object(); // 进度队列访问锁
private bool isDraggingSlider = false; // 标记是否正在拖动Slider
private float lastSentProgress = 0f; // 记录最后发送的进度
// 脚本启动时调用
void Start()
@ -110,7 +111,6 @@ public class TouchClient : MonoBehaviour
{
lock (queueLock)
{
progressQueue.Clear(); // 清空队列以确保最新进度
progressQueue.Enqueue(progress); // 将进度加入队列
Debug.Log($"收到进度: {progress:F2}");
}
@ -154,6 +154,24 @@ public class TouchClient : MonoBehaviour
// 模型播放按钮点击时调用
public void OnButtonClick_PlayModel(string modelName)
{
// 清空进度队列,防止旧进度干扰
lock (queueLock)
{
progressQueue.Clear();
}
// 重置Slider到0
Slider slider = GetCurrentPageSlider();
if (slider != null)
{
var onValueChanged = slider.onValueChanged;
slider.onValueChanged = new Slider.SliderEvent();
slider.value = 0f;
slider.onValueChanged = onValueChanged;
lastSentProgress = 0f; // 重置最后发送的进度
Debug.Log($"播放模型 {modelName} 前重置Slider到0");
}
SendMessageToServer("Model:" + modelName); // 通知服务器播放模型
}
@ -162,14 +180,30 @@ public class TouchClient : MonoBehaviour
{
isDraggingSlider = true; // 标记正在拖动
float progress = slider.value / 100f; // 转换为0-1
if (progress > 0.01f) // 忽略接近0的值以避免异常
{
SendMessageToServer("Progress:" + progress.ToString("F2")); // 发送进度
lastSentProgress = progress; // 记录最后发送的进度
Debug.Log($"Slider拖动到: {progress:F2}");
}
}
// 滑块拖动结束时调用需在Inspector中绑定
public void OnSliderEndDrag()
{
Slider slider = GetCurrentPageSlider();
if (slider != null)
{
float progress = slider.value / 100f;
if (progress > 0.01f)
{
SendMessageToServer("Progress:" + progress.ToString("F2")); // 发送最终进度
lastSentProgress = progress; // 更新最后发送的进度
Debug.Log($"Slider拖动结束发送最终进度: {progress:F2}");
}
}
isDraggingSlider = false; // 结束拖动
SendMessageToServer("EndDrag"); // 通知服务器拖动结束
Debug.Log("Slider拖动结束");
}
@ -217,11 +251,16 @@ public class TouchClient : MonoBehaviour
Slider slider = GetCurrentPageSlider();
if (slider != null)
{
// 临时禁用OnValueChanged以防止初始化触发
var onValueChanged = slider.onValueChanged;
slider.onValueChanged = new Slider.SliderEvent();
slider.value = 0f; // 重置Slider到0
slider.interactable = true; // 确保可交互
// 绑定OnValueChanged事件
// 恢复OnValueChanged并绑定
slider.onValueChanged = onValueChanged;
slider.onValueChanged.RemoveAllListeners();
slider.onValueChanged.AddListener((value) => OnSliderChanged(slider));
lastSentProgress = 0f; // 重置最后发送的进度
Debug.Log($"初始化Slider: {pageName}, 值: {slider.value}");
}
@ -233,7 +272,7 @@ public class TouchClient : MonoBehaviour
{
if (isDraggingSlider) return; // 拖动时忽略服务器进度
float progress = 0f;
float progress = -1f;
lock (queueLock)
{
if (progressQueue.Count > 0)
@ -247,11 +286,20 @@ public class TouchClient : MonoBehaviour
Slider slider = GetCurrentPageSlider();
if (slider != null)
{
// 仅当进度与当前Slider值差异较大或接近1.0时更新
float currentProgress = slider.value / 100f;
if (progress > 0f || Mathf.Abs(progress - 1f) < 0.005f)
{
// 临时禁用OnValueChanged以防止循环触发
var onValueChanged = slider.onValueChanged;
slider.onValueChanged = new Slider.SliderEvent();
slider.value = progress * 100f; // 更新Slider值0-100
slider.onValueChanged = onValueChanged; // 恢复事件
Debug.Log($"更新Slider进度: {progress:F2}, Slider值: {slider.value}");
}
}
}
}
// 应用程序退出时清理资源
private void OnApplicationQuit()

View File

@ -12,10 +12,10 @@ EditorUserSettings:
value: 54035756510d5a0c095f0d7414760b4446154b782e7b7063752a1b62e7b5363b
flags: 0
RecentlyUsedSceneGuid-2:
value: 5a5757560101590a5d0c0e24427b5d44434e4c7a7b7a23677f2b4565b7b5353a
value: 5303510050530a0a0e58087140210b44474f1a78742973637a2a4560b5b3656d
flags: 0
RecentlyUsedSceneGuid-3:
value: 5303510050530a0a0e58087140210b44474f1a78742973637a2a4560b5b3656d
value: 5a5757560101590a5d0c0e24427b5d44434e4c7a7b7a23677f2b4565b7b5353a
flags: 0
vcSharedLogLevel:
value: 0d5e400f0650

View File

@ -99,7 +99,7 @@ MonoBehaviour:
m_MinSize: {x: 300, y: 200}
m_MaxSize: {x: 24288, y: 16192}
vertical: 0
controlID: 58
controlID: 70
--- !u!114 &5
MonoBehaviour:
m_ObjectHideFlags: 52
@ -174,7 +174,7 @@ MonoBehaviour:
m_MinSize: {x: 100, y: 200}
m_MaxSize: {x: 8096, y: 16192}
vertical: 1
controlID: 31
controlID: 38
--- !u!114 &8
MonoBehaviour:
m_ObjectHideFlags: 52
@ -194,8 +194,8 @@ MonoBehaviour:
y: 0
width: 403.19995
height: 722.8
m_MinSize: {x: 276, y: 71}
m_MaxSize: {x: 4001, y: 4021}
m_MinSize: {x: 275, y: 50}
m_MaxSize: {x: 4000, y: 4000}
m_ActualView: {fileID: 13}
m_Panes:
- {fileID: 13}
@ -219,7 +219,7 @@ MonoBehaviour:
x: 0
y: 0
width: 242.40002
height: 538.4
height: 400.8
m_MinSize: {x: 202, y: 221}
m_MaxSize: {x: 4002, y: 4021}
m_ActualView: {fileID: 16}
@ -243,9 +243,9 @@ MonoBehaviour:
m_Position:
serializedVersion: 2
x: 0
y: 538.4
y: 400.8
width: 242.40002
height: 184.39996
height: 322
m_MinSize: {x: 232, y: 271}
m_MaxSize: {x: 10002, y: 10021}
m_ActualView: {fileID: 14}
@ -284,7 +284,7 @@ MonoBehaviour:
m_OverlaysVisible: 1
m_LockTracker:
m_IsLocked: 0
m_LastSelectedObjectID: 1946270
m_LastSelectedObjectID: 656666
--- !u!114 &12
MonoBehaviour:
m_ObjectHideFlags: 52
@ -481,9 +481,9 @@ MonoBehaviour:
m_Pos:
serializedVersion: 2
x: 890.4
y: 612
y: 474.4
width: 240.40002
height: 163.39996
height: 301
m_ViewDataDictionary: {fileID: 0}
m_OverlayCanvas:
m_LastAppliedPresetName: Default
@ -515,7 +515,7 @@ MonoBehaviour:
scrollPos: {x: 0, y: 0}
m_SelectedIDs: 7c780000
m_LastClickedID: 30844
m_ExpandedIDs: 0000000024ac010026ac010028ac01002aac01002cac01002eac010030ac0100
m_ExpandedIDs: 00000000745d0000765d0000785d00007a5d00007c5d00007e5d0000805d0000
m_RenameOverlay:
m_UserAcceptedRename: 0
m_Name:
@ -540,10 +540,10 @@ MonoBehaviour:
m_Icon: {fileID: 0}
m_ResourceFile:
m_AssetTreeState:
scrollPos: {x: 0, y: 300}
scrollPos: {x: 0, y: 0}
m_SelectedIDs:
m_LastClickedID: 0
m_ExpandedIDs: ffffffff0000000024ac010026ac010028ac01002aac01002cac01002eac010030ac0100
m_ExpandedIDs: ffffffff00000000745d0000765d0000785d00007a5d00007c5d00007e5d0000805d0000
m_RenameOverlay:
m_UserAcceptedRename: 0
m_Name:
@ -869,9 +869,9 @@ MonoBehaviour:
m_PlayAudio: 0
m_AudioPlay: 0
m_Position:
m_Target: {x: 1664, y: 676, z: 0}
m_Target: {x: 1470.8665, y: 599.2432, z: -36.813965}
speed: 2
m_Value: {x: 1663.9999, y: 675.99994, z: 0.0000059604645}
m_Value: {x: 1470.8665, y: 599.2432, z: -36.813965}
m_RenderMode: 0
m_CameraMode:
drawMode: 0
@ -918,13 +918,13 @@ MonoBehaviour:
m_GridAxis: 1
m_gridOpacity: 0.5
m_Rotation:
m_Target: {x: 0.0725394, y: -0.011645896, z: 0.00085166015, w: 0.99730253}
m_Target: {x: 0.015004154, y: 0.020719247, z: -0.00030632256, w: 0.9996792}
speed: 2
m_Value: {x: -0.072539404, y: 0.011645896, z: -0.00085166015, w: -0.99730253}
m_Value: {x: 0.015004057, y: 0.020719113, z: -0.00030632058, w: 0.9996728}
m_Size:
m_Target: 1564.3491
m_Target: 987.1142
speed: 2
m_Value: 1638.0619
m_Value: 987.1142
m_Ortho:
m_Target: 0
speed: 2
@ -972,7 +972,7 @@ MonoBehaviour:
x: 890.4
y: 73.6
width: 240.40002
height: 517.4
height: 379.8
m_ViewDataDictionary: {fileID: 0}
m_OverlayCanvas:
m_LastAppliedPresetName: Default
@ -981,9 +981,9 @@ MonoBehaviour:
m_SceneHierarchy:
m_TreeViewState:
scrollPos: {x: 0, y: 0}
m_SelectedIDs: 9eb00100
m_LastClickedID: 110750
m_ExpandedIDs: 8e3affff08fbffff
m_SelectedIDs:
m_LastClickedID: 0
m_ExpandedIDs: 9255feffe255feff2857feff7c5afeffcc5afeff165cfeff021ffffff420ffff4821ffff8a22ffff5624ffffc427ffff1428ffff5a29ffffa42cfffff42cffff3a2effffb031ffff0432ffff4e33ffff86f6ffffc2f7ffff12f8ffff54f9ffff08fbffff1271030070c9030022f60700804e080046040a001a070a00ae070a00b6070a00f8070a00
m_RenameOverlay:
m_UserAcceptedRename: 0
m_Name:
@ -1071,7 +1071,7 @@ MonoBehaviour:
m_HSlider: 0
m_VSlider: 0
m_IgnoreScrollWheelUntilClicked: 0
m_EnableMouseInput: 1
m_EnableMouseInput: 0
m_EnableSliderZoomHorizontal: 0
m_EnableSliderZoomVertical: 0
m_UniformScale: 1