This commit is contained in:
XgC2961 2025-09-02 08:44:00 +08:00
parent 28fe030475
commit 0e2275635c
26 changed files with 10582 additions and 517413 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +0,0 @@
fileFormatVersion: 2
guid: 432f87c529858f04c99d14284b7e0c80
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +0,0 @@
fileFormatVersion: 2
guid: f75d3e676db2e634e92fedae86563f09
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +0,0 @@
fileFormatVersion: 2
guid: 6865c1237a7183346ba17964f39d0609
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +0,0 @@
fileFormatVersion: 2
guid: 8d7d450574a887b489087ae2aca48e5a
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +0,0 @@
fileFormatVersion: 2
guid: f4b338402f11323408587e037729cc71
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +0,0 @@
fileFormatVersion: 2
guid: be28f7874a758b74a8b0af6d3139c00c
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -710,7 +710,7 @@ GameObject:
- component: {fileID: 67960687} - component: {fileID: 67960687}
- component: {fileID: 67960686} - component: {fileID: 67960686}
m_Layer: 5 m_Layer: 5
m_Name: Button m_Name: "\u52A8\u7269\u4ED3"
m_TagString: Untagged m_TagString: Untagged
m_Icon: {fileID: 0} m_Icon: {fileID: 0}
m_NavMeshLayer: 0 m_NavMeshLayer: 0
@ -967,7 +967,7 @@ GameObject:
m_Icon: {fileID: 0} m_Icon: {fileID: 0}
m_NavMeshLayer: 0 m_NavMeshLayer: 0
m_StaticEditorFlags: 0 m_StaticEditorFlags: 0
m_IsActive: 0 m_IsActive: 1
--- !u!224 &103809607 --- !u!224 &103809607
RectTransform: RectTransform:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
@ -1411,7 +1411,7 @@ MonoBehaviour:
- m_Target: {fileID: 2109707620} - m_Target: {fileID: 2109707620}
m_TargetAssemblyTypeName: TouchClient, Assembly-CSharp m_TargetAssemblyTypeName: TouchClient, Assembly-CSharp
m_MethodName: OnButtonClick_PlayModel m_MethodName: OnButtonClick_PlayModel
m_Mode: 5 m_Mode: 1
m_Arguments: m_Arguments:
m_ObjectArgument: {fileID: 0} m_ObjectArgument: {fileID: 0}
m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
@ -1814,7 +1814,7 @@ MonoBehaviour:
- m_Target: {fileID: 2109707620} - m_Target: {fileID: 2109707620}
m_TargetAssemblyTypeName: TouchClient, Assembly-CSharp m_TargetAssemblyTypeName: TouchClient, Assembly-CSharp
m_MethodName: OnButtonClick_PlayModel m_MethodName: OnButtonClick_PlayModel
m_Mode: 5 m_Mode: 1
m_Arguments: m_Arguments:
m_ObjectArgument: {fileID: 0} m_ObjectArgument: {fileID: 0}
m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
@ -2221,7 +2221,7 @@ RectTransform:
m_RootOrder: 0 m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0} m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 1} m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 0, y: 0.0000019073486} m_AnchoredPosition: {x: 0, y: 0.0000019073486}
m_SizeDelta: {x: 64.1366, y: 15.9954} m_SizeDelta: {x: 64.1366, y: 15.9954}
m_Pivot: {x: 0.5, y: 0.5} m_Pivot: {x: 0.5, y: 0.5}
@ -2297,7 +2297,7 @@ RectTransform:
m_RootOrder: 0 m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0} m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 1}
m_AnchoredPosition: {x: 0, y: 0} m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 10, y: 0} m_SizeDelta: {x: 10, y: 0}
m_Pivot: {x: 0.5, y: 0.5} m_Pivot: {x: 0.5, y: 0.5}
@ -2564,7 +2564,7 @@ RectTransform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: -481, y: 175.86954} m_AnchoredPosition: {x: -404, y: -53.323}
m_SizeDelta: {x: 514.5018, y: 206.6469} m_SizeDelta: {x: 514.5018, y: 206.6469}
m_Pivot: {x: 0.5, y: 0.5} m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &374413652 --- !u!114 &374413652
@ -3095,7 +3095,7 @@ GameObject:
- component: {fileID: 446068281} - component: {fileID: 446068281}
- component: {fileID: 446068280} - component: {fileID: 446068280}
m_Layer: 5 m_Layer: 5
m_Name: Button m_Name: "pet\u5355\u4E2A\u7EC4\u4EF6\u7ED3\u6784"
m_TagString: Untagged m_TagString: Untagged
m_Icon: {fileID: 0} m_Icon: {fileID: 0}
m_NavMeshLayer: 0 m_NavMeshLayer: 0
@ -3165,7 +3165,19 @@ MonoBehaviour:
m_TargetGraphic: {fileID: 446068281} m_TargetGraphic: {fileID: 446068281}
m_OnClick: m_OnClick:
m_PersistentCalls: m_PersistentCalls:
m_Calls: [] m_Calls:
- m_Target: {fileID: 2109707620}
m_TargetAssemblyTypeName: TouchClient, Assembly-CSharp
m_MethodName: OnButtonClick_SingleItem
m_Mode: 5
m_Arguments:
m_ObjectArgument: {fileID: 0}
m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
m_IntArgument: 0
m_FloatArgument: 0
m_StringArgument: "pet\u5355\u4E2A\u7EC4\u4EF6\u7ED3\u6784"
m_BoolArgument: 0
m_CallState: 2
--- !u!114 &446068281 --- !u!114 &446068281
MonoBehaviour: MonoBehaviour:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
@ -4128,7 +4140,7 @@ GameObject:
- component: {fileID: 547606276} - component: {fileID: 547606276}
- component: {fileID: 547606275} - component: {fileID: 547606275}
m_Layer: 5 m_Layer: 5
m_Name: Button m_Name: "SPECT\u63A2\u6D4B\u5668"
m_TagString: Untagged m_TagString: Untagged
m_Icon: {fileID: 0} m_Icon: {fileID: 0}
m_NavMeshLayer: 0 m_NavMeshLayer: 0
@ -4673,7 +4685,7 @@ GameObject:
- component: {fileID: 684509595} - component: {fileID: 684509595}
- component: {fileID: 684509594} - component: {fileID: 684509594}
m_Layer: 5 m_Layer: 5
m_Name: Button m_Name: "\u627F\u91CD\u7ED3\u6784"
m_TagString: Untagged m_TagString: Untagged
m_Icon: {fileID: 0} m_Icon: {fileID: 0}
m_NavMeshLayer: 0 m_NavMeshLayer: 0
@ -5729,7 +5741,7 @@ MonoBehaviour:
- m_Target: {fileID: 2109707620} - m_Target: {fileID: 2109707620}
m_TargetAssemblyTypeName: TouchClient, Assembly-CSharp m_TargetAssemblyTypeName: TouchClient, Assembly-CSharp
m_MethodName: OnButtonClick_PlayModel m_MethodName: OnButtonClick_PlayModel
m_Mode: 5 m_Mode: 1
m_Arguments: m_Arguments:
m_ObjectArgument: {fileID: 0} m_ObjectArgument: {fileID: 0}
m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
@ -6001,7 +6013,7 @@ GameObject:
- component: {fileID: 896665758} - component: {fileID: 896665758}
- component: {fileID: 896665757} - component: {fileID: 896665757}
m_Layer: 5 m_Layer: 5
m_Name: Button m_Name: "\u5E8A\u4F53\u652F\u6491\u7CFB\u7EDF"
m_TagString: Untagged m_TagString: Untagged
m_Icon: {fileID: 0} m_Icon: {fileID: 0}
m_NavMeshLayer: 0 m_NavMeshLayer: 0
@ -6258,7 +6270,7 @@ GameObject:
- component: {fileID: 911858246} - component: {fileID: 911858246}
- component: {fileID: 911858245} - component: {fileID: 911858245}
m_Layer: 5 m_Layer: 5
m_Name: Button m_Name: "PET\u9635\u5217\u5806\u53E0\u6392\u5217"
m_TagString: Untagged m_TagString: Untagged
m_Icon: {fileID: 0} m_Icon: {fileID: 0}
m_NavMeshLayer: 0 m_NavMeshLayer: 0
@ -6328,7 +6340,19 @@ MonoBehaviour:
m_TargetGraphic: {fileID: 911858246} m_TargetGraphic: {fileID: 911858246}
m_OnClick: m_OnClick:
m_PersistentCalls: m_PersistentCalls:
m_Calls: [] m_Calls:
- m_Target: {fileID: 2109707620}
m_TargetAssemblyTypeName: TouchClient, Assembly-CSharp
m_MethodName: OnButtonClick_SingleItem
m_Mode: 5
m_Arguments:
m_ObjectArgument: {fileID: 0}
m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
m_IntArgument: 0
m_FloatArgument: 0
m_StringArgument: "PET\u9635\u5217\u5806\u53E0\u6392\u5217"
m_BoolArgument: 0
m_CallState: 2
--- !u!114 &911858246 --- !u!114 &911858246
MonoBehaviour: MonoBehaviour:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
@ -6691,7 +6715,7 @@ RectTransform:
m_RootOrder: 0 m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0} m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 1} m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 0, y: 0} m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 10, y: 0} m_SizeDelta: {x: 10, y: 0}
m_Pivot: {x: 0.5, y: 0.5} m_Pivot: {x: 0.5, y: 0.5}
@ -7544,7 +7568,7 @@ MonoBehaviour:
- m_Target: {fileID: 2109707620} - m_Target: {fileID: 2109707620}
m_TargetAssemblyTypeName: TouchClient, Assembly-CSharp m_TargetAssemblyTypeName: TouchClient, Assembly-CSharp
m_MethodName: OnButtonClick_PlayModel m_MethodName: OnButtonClick_PlayModel
m_Mode: 5 m_Mode: 1
m_Arguments: m_Arguments:
m_ObjectArgument: {fileID: 0} m_ObjectArgument: {fileID: 0}
m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
@ -7666,7 +7690,7 @@ RectTransform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: -481, y: -115} m_AnchoredPosition: {x: 350, y: 87}
m_SizeDelta: {x: 514.5018, y: 206.6469} m_SizeDelta: {x: 514.5018, y: 206.6469}
m_Pivot: {x: 0.5, y: 0.5} m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &1108370711 --- !u!114 &1108370711
@ -7689,7 +7713,7 @@ MonoBehaviour:
m_OnCullStateChanged: m_OnCullStateChanged:
m_PersistentCalls: m_PersistentCalls:
m_Calls: [] m_Calls: []
m_Sprite: {fileID: 21300000, guid: deb624ce021a69244a5acbd633ee73df, type: 3} m_Sprite: {fileID: 21300000, guid: a611350a87ed4624abca9ae7e9278a6e, type: 3}
m_Type: 0 m_Type: 0
m_PreserveAspect: 0 m_PreserveAspect: 0
m_FillCenter: 1 m_FillCenter: 1
@ -8165,7 +8189,7 @@ RectTransform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: -481, y: 175.8695} m_AnchoredPosition: {x: -365.74, y: 333}
m_SizeDelta: {x: 514.5018, y: 206.6469} m_SizeDelta: {x: 514.5018, y: 206.6469}
m_Pivot: {x: 0.5, y: 0.5} m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &1226287016 --- !u!114 &1226287016
@ -8356,7 +8380,7 @@ RectTransform:
m_RootOrder: 0 m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0} m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 1}
m_AnchoredPosition: {x: 0, y: 0.0000019073486} m_AnchoredPosition: {x: 0, y: 0.0000019073486}
m_SizeDelta: {x: 64.1366, y: 15.9954} m_SizeDelta: {x: 64.1366, y: 15.9954}
m_Pivot: {x: 0.5, y: 0.5} m_Pivot: {x: 0.5, y: 0.5}
@ -8990,7 +9014,7 @@ GameObject:
- component: {fileID: 1476283247} - component: {fileID: 1476283247}
- component: {fileID: 1476283246} - component: {fileID: 1476283246}
m_Layer: 5 m_Layer: 5
m_Name: Button m_Name: "\u653E\u5C04\u6E90"
m_TagString: Untagged m_TagString: Untagged
m_Icon: {fileID: 0} m_Icon: {fileID: 0}
m_NavMeshLayer: 0 m_NavMeshLayer: 0
@ -9014,7 +9038,7 @@ RectTransform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: 104.15062, y: 72.06} m_AnchoredPosition: {x: -104.15, y: 72.06}
m_SizeDelta: {x: 306.2091, y: 62.5272} m_SizeDelta: {x: 306.2091, y: 62.5272}
m_Pivot: {x: 0.5, y: 0.5} m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &1476283246 --- !u!114 &1476283246
@ -9112,7 +9136,7 @@ GameObject:
- component: {fileID: 1486855123} - component: {fileID: 1486855123}
- component: {fileID: 1486855122} - component: {fileID: 1486855122}
m_Layer: 5 m_Layer: 5
m_Name: Button m_Name: "\u7535\u5B50\u5143\u5668\u4EF6"
m_TagString: Untagged m_TagString: Untagged
m_Icon: {fileID: 0} m_Icon: {fileID: 0}
m_NavMeshLayer: 0 m_NavMeshLayer: 0
@ -9747,7 +9771,7 @@ MonoBehaviour:
- m_Target: {fileID: 2109707620} - m_Target: {fileID: 2109707620}
m_TargetAssemblyTypeName: TouchClient, Assembly-CSharp m_TargetAssemblyTypeName: TouchClient, Assembly-CSharp
m_MethodName: OnButtonClick_PlayModel m_MethodName: OnButtonClick_PlayModel
m_Mode: 5 m_Mode: 1
m_Arguments: m_Arguments:
m_ObjectArgument: {fileID: 0} m_ObjectArgument: {fileID: 0}
m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
@ -10524,7 +10548,7 @@ RectTransform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: 363, y: 223} m_AnchoredPosition: {x: 235, y: 250}
m_SizeDelta: {x: 514.5018, y: 206.6469} m_SizeDelta: {x: 514.5018, y: 206.6469}
m_Pivot: {x: 0.5, y: 0.5} m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &1699508422 --- !u!114 &1699508422
@ -11191,7 +11215,7 @@ GameObject:
- component: {fileID: 1813455974} - component: {fileID: 1813455974}
- component: {fileID: 1813455973} - component: {fileID: 1813455973}
m_Layer: 5 m_Layer: 5
m_Name: Button m_Name: "\u5E73\u677F\u63A2\u6D4B\u5668"
m_TagString: Untagged m_TagString: Untagged
m_Icon: {fileID: 0} m_Icon: {fileID: 0}
m_NavMeshLayer: 0 m_NavMeshLayer: 0
@ -11313,7 +11337,7 @@ GameObject:
- component: {fileID: 1820901397} - component: {fileID: 1820901397}
- component: {fileID: 1820901396} - component: {fileID: 1820901396}
m_Layer: 5 m_Layer: 5
m_Name: Button m_Name: "\u5E73\u79FB\u8C03\u7CFB\u7EDF"
m_TagString: Untagged m_TagString: Untagged
m_Icon: {fileID: 0} m_Icon: {fileID: 0}
m_NavMeshLayer: 0 m_NavMeshLayer: 0
@ -11337,7 +11361,7 @@ RectTransform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: -102.64, y: 72.06016} m_AnchoredPosition: {x: 102.64, y: 72.06}
m_SizeDelta: {x: 309.2302, y: 62.5272} m_SizeDelta: {x: 309.2302, y: 62.5272}
m_Pivot: {x: 0.5, y: 0.5} m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &1820901396 --- !u!114 &1820901396
@ -11703,7 +11727,7 @@ MonoBehaviour:
- m_Target: {fileID: 2109707620} - m_Target: {fileID: 2109707620}
m_TargetAssemblyTypeName: TouchClient, Assembly-CSharp m_TargetAssemblyTypeName: TouchClient, Assembly-CSharp
m_MethodName: OnButtonClick_PlayModel m_MethodName: OnButtonClick_PlayModel
m_Mode: 5 m_Mode: 1
m_Arguments: m_Arguments:
m_ObjectArgument: {fileID: 0} m_ObjectArgument: {fileID: 0}
m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
@ -11763,7 +11787,7 @@ GameObject:
- component: {fileID: 1871943555} - component: {fileID: 1871943555}
- component: {fileID: 1871943554} - component: {fileID: 1871943554}
m_Layer: 5 m_Layer: 5
m_Name: Button m_Name: "\u6ED1\u53F0"
m_TagString: Untagged m_TagString: Untagged
m_Icon: {fileID: 0} m_Icon: {fileID: 0}
m_NavMeshLayer: 0 m_NavMeshLayer: 0
@ -11885,7 +11909,7 @@ GameObject:
- component: {fileID: 1892964834} - component: {fileID: 1892964834}
- component: {fileID: 1892964833} - component: {fileID: 1892964833}
m_Layer: 5 m_Layer: 5
m_Name: Button m_Name: "pet\u6676\u4F53\u7ED3\u6784"
m_TagString: Untagged m_TagString: Untagged
m_Icon: {fileID: 0} m_Icon: {fileID: 0}
m_NavMeshLayer: 0 m_NavMeshLayer: 0
@ -12122,7 +12146,7 @@ GameObject:
m_Icon: {fileID: 0} m_Icon: {fileID: 0}
m_NavMeshLayer: 0 m_NavMeshLayer: 0
m_StaticEditorFlags: 0 m_StaticEditorFlags: 0
m_IsActive: 1 m_IsActive: 0
--- !u!224 &1993840782 --- !u!224 &1993840782
RectTransform: RectTransform:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
@ -12848,7 +12872,7 @@ GameObject:
- component: {fileID: 2105199688} - component: {fileID: 2105199688}
- component: {fileID: 2105199687} - component: {fileID: 2105199687}
m_Layer: 5 m_Layer: 5
m_Name: "\u5E8A\u5934\u652F\u6491\u7CFB\u7EDF" m_Name: "\u5E8A\u4F53\u652F\u6491\u7CFB\u7EDF"
m_TagString: Untagged m_TagString: Untagged
m_Icon: {fileID: 0} m_Icon: {fileID: 0}
m_NavMeshLayer: 0 m_NavMeshLayer: 0
@ -12946,6 +12970,55 @@ MonoBehaviour:
m_Name: m_Name:
m_EditorClassIdentifier: m_EditorClassIdentifier:
background: {fileID: 126639093} background: {fileID: 126639093}
pageButtonConfigs:
- pageName: "PET\u7CFB\u7EDF"
singleItemButtons:
- {fileID: 1892964833}
- {fileID: 911858245}
- {fileID: 446068280}
singleItemModelNames:
- "pet\u6676\u4F53\u7ED3\u6784"
- "PET\u9635\u5217\u5806\u53E0\u6392\u5217"
- "pet\u5355\u4E2A\u7EC4\u4EF6\u7ED3\u6784"
defaultModelName: PET
- pageName: "SPECT\u7CFB\u7EDF"
singleItemButtons:
- {fileID: 547606275}
singleItemModelNames:
- "SPECT\u63A2\u6D4B\u5668"
defaultModelName: SPECT
- pageName: "CT\u7CFB\u7EDF"
singleItemButtons:
- {fileID: 1813455973}
- {fileID: 1476283246}
- {fileID: 1820901396}
singleItemModelNames:
- "\u5E73\u677F\u63A2\u6D4B\u5668"
- "\u653E\u5C04\u6E90"
- "\u5E73\u79FB\u8C03\u7CFB\u7EDF"
defaultModelName: "CT\u7CFB\u7EDF"
- pageName: "\u673A\u67B6\u7CFB\u7EDF"
singleItemButtons:
- {fileID: 1486855122}
- {fileID: 684509594}
singleItemModelNames:
- "\u7535\u5B50\u5143\u5668\u4EF6"
- "\u627F\u91CD\u7ED3\u6784"
defaultModelName: "\u673A\u67B6\u7CFB\u7EDF"
- pageName: "\u5E8A\u53F0\u7CFB\u7EDF"
singleItemButtons:
- {fileID: 67960686}
- {fileID: 1871943554}
- {fileID: 896665757}
singleItemModelNames:
- "\u52A8\u7269\u4ED3"
- "\u6ED1\u53F0"
- "\u5E8A\u4F53\u652F\u6491\u7CFB\u7EDF"
defaultModelName: "\u5E8A\u53F0\u7CFB\u7EDF"
udpPort: 9999
tcpPort: 8888
resolutionWidth: 1920
resolutionHeight: 1080
showSprite: {fileID: 21300000, guid: cc008a9708685dd4a91b74ff185ad926, type: 3} showSprite: {fileID: 21300000, guid: cc008a9708685dd4a91b74ff185ad926, type: 3}
hideSprite: {fileID: 21300000, guid: 23990d42656b4bd4191e7b31135c3f75, type: 3} hideSprite: {fileID: 21300000, guid: 23990d42656b4bd4191e7b31135c3f75, type: 3}
--- !u!114 &2109707621 --- !u!114 &2109707621
@ -13043,7 +13116,7 @@ GameObject:
- component: {fileID: 2111609300} - component: {fileID: 2111609300}
- component: {fileID: 2111609299} - component: {fileID: 2111609299}
m_Layer: 5 m_Layer: 5
m_Name: "\u5C04\u7EBF\u6E90" m_Name: "\u653E\u5C04\u6E90"
m_TagString: Untagged m_TagString: Untagged
m_Icon: {fileID: 0} m_Icon: {fileID: 0}
m_NavMeshLayer: 0 m_NavMeshLayer: 0
@ -13067,7 +13140,7 @@ RectTransform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: 363, y: 223} m_AnchoredPosition: {x: -232, y: 0}
m_SizeDelta: {x: 514.5018, y: 206.6469} m_SizeDelta: {x: 514.5018, y: 206.6469}
m_Pivot: {x: 0.5, y: 0.5} m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &2111609299 --- !u!114 &2111609299
@ -13090,7 +13163,7 @@ MonoBehaviour:
m_OnCullStateChanged: m_OnCullStateChanged:
m_PersistentCalls: m_PersistentCalls:
m_Calls: [] m_Calls: []
m_Sprite: {fileID: 21300000, guid: a611350a87ed4624abca9ae7e9278a6e, type: 3} m_Sprite: {fileID: 21300000, guid: deb624ce021a69244a5acbd633ee73df, type: 3}
m_Type: 0 m_Type: 0
m_PreserveAspect: 0 m_PreserveAspect: 0
m_FillCenter: 1 m_FillCenter: 1

File diff suppressed because it is too large Load Diff

View File

@ -12,6 +12,15 @@ public class BroadcastServer : MonoBehaviour
private Thread broadcastThread; // 广播线程 private Thread broadcastThread; // 广播线程
private volatile bool isRunning = true; // 线程安全的运行标志 private volatile bool isRunning = true; // 线程安全的运行标志
[Header("网络配置")]
[SerializeField] private int broadcastPort = 9999; // UDP广播端口
[SerializeField] private float broadcastInterval = 1f; // 广播间隔(秒)
[SerializeField] private string preferredNetworkInterface = ""; // 优先网络接口(可选)
[Header("日志级别")]
[SerializeField] private LogLevel logLevel = LogLevel.Verbose; // 日志级别控制
public enum LogLevel { None, Minimal, Verbose }
// 脚本启动时调用 // 脚本启动时调用
void Start() void Start()
{ {
@ -19,10 +28,12 @@ public class BroadcastServer : MonoBehaviour
{ {
udpClient = new UdpClient(); udpClient = new UdpClient();
udpClient.EnableBroadcast = true; udpClient.EnableBroadcast = true;
// 启动广播线程
broadcastThread = new Thread(BroadcastIP); broadcastThread = new Thread(BroadcastIP);
broadcastThread.Start(); broadcastThread.Start();
Debug.Log("广播服务器已启动,端口: 9999"); if (logLevel != LogLevel.None)
{
Debug.Log($"广播服务器已启动,端口: {broadcastPort}");
}
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -42,20 +53,26 @@ public class BroadcastServer : MonoBehaviour
string message = $"ServerIP:{localIP}"; string message = $"ServerIP:{localIP}";
byte[] data = Encoding.UTF8.GetBytes(message); byte[] data = Encoding.UTF8.GetBytes(message);
IPEndPoint endPoint = new IPEndPoint(IPAddress.Broadcast, 9999); // 修改为9999 IPEndPoint endPoint = new IPEndPoint(IPAddress.Broadcast, broadcastPort);
while (isRunning) while (isRunning)
{ {
try try
{ {
udpClient.Send(data, data.Length, endPoint); udpClient.Send(data, data.Length, endPoint);
Debug.Log($"广播IP: {message}"); if (logLevel == LogLevel.Verbose)
Thread.Sleep(1000); // 每秒广播一次 {
Debug.Log($"广播IP: {message}");
}
Thread.Sleep((int)(broadcastInterval * 1000));
} }
catch (Exception ex) catch (Exception ex)
{ {
Debug.LogError($"广播错误: {ex.Message}"); if (logLevel != LogLevel.None)
Thread.Sleep(5000); // 出错后等待5秒重试 {
Debug.LogError($"广播错误: {ex.Message}");
}
Thread.Sleep(5000);
} }
} }
} }
@ -67,19 +84,25 @@ public class BroadcastServer : MonoBehaviour
{ {
foreach (var networkInterface in NetworkInterface.GetAllNetworkInterfaces()) foreach (var networkInterface in NetworkInterface.GetAllNetworkInterfaces())
{ {
if (networkInterface.OperationalStatus == OperationalStatus.Up && if (networkInterface.OperationalStatus != OperationalStatus.Up ||
networkInterface.NetworkInterfaceType != NetworkInterfaceType.Loopback) networkInterface.NetworkInterfaceType == NetworkInterfaceType.Loopback)
continue;
if (!string.IsNullOrEmpty(preferredNetworkInterface) && networkInterface.Name != preferredNetworkInterface)
continue;
foreach (var unicastIPAddress in networkInterface.GetIPProperties().UnicastAddresses)
{ {
foreach (var unicastIPAddress in networkInterface.GetIPProperties().UnicastAddresses) if (unicastIPAddress.Address.AddressFamily == AddressFamily.InterNetwork)
{ {
if (unicastIPAddress.Address.AddressFamily == AddressFamily.InterNetwork) string ip = unicastIPAddress.Address.ToString();
if (!ip.StartsWith("127."))
{ {
string ip = unicastIPAddress.Address.ToString(); if (logLevel == LogLevel.Verbose)
if (!ip.StartsWith("127."))
{ {
Debug.Log($"选择IP: {ip} (接口: {networkInterface.Name})"); Debug.Log($"选择IP: {ip} (接口: {networkInterface.Name})");
return ip;
} }
return ip;
} }
} }
} }
@ -101,8 +124,17 @@ public class BroadcastServer : MonoBehaviour
udpClient?.Close(); udpClient?.Close();
if (broadcastThread != null && broadcastThread.IsAlive) if (broadcastThread != null && broadcastThread.IsAlive)
{ {
broadcastThread.Join(1000); // 等待线程结束 broadcastThread.Join(1000);
} }
Debug.Log("广播服务器已停止"); if (logLevel != LogLevel.None)
{
Debug.Log("广播服务器已停止");
}
}
// 确保资源在销毁时清理
private void OnDestroy()
{
OnApplicationQuit();
} }
} }

View File

@ -5,213 +5,266 @@ using System.Net;
using System.Text; using System.Text;
using System.Threading; using System.Threading;
using System.Collections.Generic; using System.Collections.Generic;
using System; using DG.Tweening;
public class DisplayServer : MonoBehaviour public class DisplayServer : MonoBehaviour
{ {
private TcpListener listener; // 用于接受客户端连接的TCP监听器 private TcpListener listener;
private Thread listenThread; // 用于接受客户端连接的线程 private Thread listenThread;
private CancellationTokenSource listenCts = new CancellationTokenSource(); // 控制线程取消 private CancellationTokenSource listenCts = new CancellationTokenSource();
private volatile bool isRunning = true; // 线程安全的服务器循环标志 private volatile bool isRunning = true;
private NetworkStream clientStream; // 当前客户端的网络流,用于发送消息 private NetworkStream clientStream;
public Transform background; // UI页面的父级变换BG包含Image组件 public Transform background;
[System.Serializable] [System.Serializable]
public class PageModel public class PageModel
{ {
public string pageName; // 页面名称 public string pageName;
public GameObject model; // 与页面关联的模型挂载ModelController public GameObject model;
public Vector3 originalPosition;
public List<GameObject> singleItemModels;
} }
public List<PageModel> pageModels = new List<PageModel>(); // 页面-模型映射列表 public List<PageModel> pageModels = new List<PageModel>();
private readonly Queue<string> messageQueue = new Queue<string>(); // 线程安全的消息队列 private readonly Queue<string> messageQueue = new Queue<string>();
private readonly object queueLock = new object(); // 消息队列访问锁 private readonly object queueLock = new object();
private string currentPage = ""; // 跟踪当前显示的页面 private string currentPage = "";
private Dictionary<string, PageModel> pageModelCache; // 页面-模型映射的缓存 private string currentSingleItemModel = "";
private bool isPlayingAnimation = false; // 跟踪动画播放状态 private Dictionary<string, PageModel> pageModelCache;
private bool isClientDragging = false; // 跟踪客户端是否正在拖动Slider private Dictionary<string, Transform> textPanelCache;
private float lastSendTime = 0f; // 上次发送进度的时间 private Dictionary<string, Slider> sliderCache;
private float sendInterval = 0.05f; // 进度发送间隔(秒) private bool isPlayingAnimation = false;
private float lastSentProgress = 0f; // 记录上次发送的进度 private bool isClientDragging = false;
private float lastSendTime = 0f;
private float lastSentProgress = 0f;
[Header("Background Sprites")] [SerializeField] private int tcpPort = 8888;
public Sprite textBackgroundSprite; // 有文字时的背景Sprite [SerializeField] private float sendInterval = 0.05f;
public Sprite noTextBackgroundSprite; // 无文字时的背景Sprite [SerializeField] private int resolutionWidth = 3328;
[SerializeField] private int resolutionHeight = 1352;
public Sprite textBackgroundSprite;
public Sprite noTextBackgroundSprite;
[SerializeField] private float textHiddenOffset = 33f;
// 脚本启动时调用
void Start() void Start()
{ {
// 设置显示端分辨率为 3328x1352 Screen.SetResolution(resolutionWidth, resolutionHeight, false);
Screen.SetResolution(3328, 1352, false);
// 初始化页面-模型缓存以加快查找
pageModelCache = new Dictionary<string, PageModel>(); pageModelCache = new Dictionary<string, PageModel>();
textPanelCache = new Dictionary<string, Transform>();
sliderCache = new Dictionary<string, Slider>();
foreach (var pm in pageModels) foreach (var pm in pageModels)
{ {
if (!string.IsNullOrEmpty(pm.pageName) && pm.model != null) if (!string.IsNullOrEmpty(pm.pageName) && pm.model != null)
{ {
pm.originalPosition = pm.model.transform.localPosition;
pageModelCache[pm.pageName] = pm; pageModelCache[pm.pageName] = pm;
} if (pm.singleItemModels == null)
else pm.singleItemModels = new List<GameObject>();
{
Debug.LogWarning($"PageModel 配置错误: pageName={pm.pageName}, model={(pm.model != null ? pm.model.name : "null")}");
} }
} }
// 在端口8888上启动TCP监听 CacheUIComponents();
try
if (background == null)
{ {
listener = new TcpListener(IPAddress.Any, 8888); return;
listener.Start();
Debug.Log("TCP监听启动成功端口: 8888");
} }
catch (Exception ex) Image backgroundImage = background.GetComponent<Image>();
if (backgroundImage == null)
{
return;
}
try
{
listener = new TcpListener(IPAddress.Any, tcpPort);
listener.Start();
}
catch
{ {
Debug.LogError($"TCP监听启动失败: {ex.Message}");
return; return;
} }
// 启动线程以监听客户端连接
listenThread = new Thread(() => ListenForClients(listenCts.Token)); listenThread = new Thread(() => ListenForClients(listenCts.Token));
listenThread.Start(); listenThread.Start();
Debug.Log("显示端服务器已启动,等待触摸端连接...");
// 显示初始页面
ShowPage("Ê×Ò³"); ShowPage("Ê×Ò³");
SendHasAnimationStatus();
}
private void CacheUIComponents()
{
foreach (Transform child in background)
{
Transform textPanel = FindDeep(child, "TextPanel");
if (textPanel != null)
{
textPanelCache[child.name] = textPanel;
}
Slider slider = child.GetComponentInChildren<Slider>();
if (slider != null)
{
sliderCache[child.name] = slider;
}
}
} }
// 监听传入的TCP客户端连接
private void ListenForClients(CancellationToken token) private void ListenForClients(CancellationToken token)
{ {
int retryDelayMs = 2000;
while (!token.IsCancellationRequested && isRunning) while (!token.IsCancellationRequested && isRunning)
{ {
try try
{ {
TcpClient client = listener.AcceptTcpClient(); TcpClient client = listener.AcceptTcpClient();
Debug.Log($"触摸端已连接!客户端地址: {((IPEndPoint)client.Client.RemoteEndPoint).Address}"); clientStream = client.GetStream();
clientStream = client.GetStream(); // 保存客户端流以发送消息
// 为每个客户端启动新线程处理通信
Thread clientThread = new Thread(() => HandleClientComm(client, token)); Thread clientThread = new Thread(() => HandleClientComm(client, token));
clientThread.Start(); clientThread.Start();
retryDelayMs = 2000;
} }
catch (Exception ex) catch
{ {
Debug.LogError($"接受客户端连接错误: {ex.Message}"); Thread.Sleep(retryDelayMs);
Thread.Sleep(2000); // 等待2秒重试 retryDelayMs = Mathf.Min(retryDelayMs * 2, 10000);
} }
} }
} }
// 处理与单个客户端的通信
private void HandleClientComm(TcpClient tcpClient, CancellationToken token) private void HandleClientComm(TcpClient tcpClient, CancellationToken token)
{ {
NetworkStream stream = tcpClient.GetStream(); NetworkStream stream = tcpClient.GetStream();
byte[] message = new byte[4096]; byte[] message = new byte[4096];
int bytesRead; int bytesRead;
// 在未取消或未断开连接的情况下持续读取
while (!token.IsCancellationRequested && isRunning) while (!token.IsCancellationRequested && isRunning)
{ {
try try
{ {
bytesRead = stream.Read(message, 0, 4096); bytesRead = stream.Read(message, 0, 4096);
if (bytesRead == 0) break; // 客户端断开连接 if (bytesRead == 0) break;
string data = Encoding.UTF8.GetString(message, 0, bytesRead); string data = Encoding.UTF8.GetString(message, 0, bytesRead);
lock (queueLock) lock (queueLock)
{ {
messageQueue.Enqueue(data); // 将消息加入队列以供处理 messageQueue.Enqueue(data);
} }
} }
catch (Exception ex) catch
{ {
Debug.LogError($"读取客户端消息错误: {ex.Message}");
break; break;
} }
} }
// 清理客户端资源
stream.Close(); stream.Close();
tcpClient.Close(); tcpClient.Close();
clientStream = null; // 清空客户端流 clientStream = null;
Debug.Log("客户端断开连接");
} }
// 在主线程中处理排队的消息并发送动画进度
private void Update() private void Update()
{ {
// 处理接收到的消息
string msg = null; string msg = null;
lock (queueLock) lock (queueLock)
{ {
if (messageQueue.Count > 0) if (messageQueue.Count > 0)
{ {
msg = messageQueue.Dequeue(); // 获取下一条消息 msg = messageQueue.Dequeue();
} }
} }
if (!string.IsNullOrEmpty(msg)) if (!string.IsNullOrEmpty(msg))
{ {
Debug.Log($"收到消息: {msg}");
if (msg.StartsWith("Page:")) if (msg.StartsWith("Page:"))
{ {
string pageName = msg.Replace("Page:", ""); string pageName = msg.Replace("Page:", "");
ShowPage(pageName); ShowPage(pageName);
isPlayingAnimation = false; // 重置播放状态 isPlayingAnimation = false;
isClientDragging = false; // 重置拖动状态 isClientDragging = false;
lastSentProgress = 0f; // 重置进度 lastSentProgress = 0f;
SendHasAnimationStatus();
} }
else if (msg.StartsWith("Model:")) else if (msg.StartsWith("Model:"))
{ {
string modelName = msg.Replace("Model:", ""); string modelName = msg.Replace("Model:", "");
PlayModelAnimation(modelName); PlayModelAnimation(modelName);
lastSentProgress = 0f; // 重置进度 lastSentProgress = 0f;
}
else if (msg.StartsWith("SingleItemModel:"))
{
string modelName = msg.Replace("SingleItemModel:", "");
ShowSingleItemModel(modelName);
isPlayingAnimation = false;
isClientDragging = false;
lastSentProgress = 0f;
SendHasAnimationStatus();
} }
else if (msg.StartsWith("Progress:")) else if (msg.StartsWith("Progress:"))
{ {
if (float.TryParse(msg.Replace("Progress:", ""), out float progress)) if (float.TryParse(msg.Replace("Progress:", ""), out float progress))
{ {
SetAnimationProgress(progress); SetAnimationProgress(progress);
isPlayingAnimation = false; // 拖动时停止播放 isPlayingAnimation = false;
isClientDragging = true; // 标记客户端正在拖动 isClientDragging = true;
lastSentProgress = progress; // 更新最后发送的进度 lastSentProgress = progress;
Debug.Log($"处理进度消息: Progress:{progress:F2}");
} }
} }
else if (msg == "EndDrag") else if (msg == "EndDrag")
{ {
isClientDragging = false; // 客户端拖动结束 isClientDragging = false;
Debug.Log("客户端Slider拖动结束");
} }
else if (msg.StartsWith("TextPanel:")) else if (msg.StartsWith("TextPanel:"))
{ {
string command = msg.Replace("TextPanel:", ""); string command = msg.Replace("TextPanel:", "");
SetTextPanelVisibility(command == "Show"); SetTextPanelVisibility(command == "Show");
Debug.Log($"处理文字面板消息: {msg}");
} }
else if (msg.StartsWith("Background:")) else if (msg.StartsWith("Background:"))
{ {
string command = msg.Replace("Background:", ""); string command = msg.Replace("Background:", "");
SetBackgroundSprite(command == "Text"); SetBackgroundSprite(command == "Text");
Debug.Log($"处理背景消息: {msg}"); }
else if (msg.StartsWith("ModelMove:"))
{
string command = msg.Replace("ModelMove:", "");
if (command == "Reset")
{
ResetModelPosition();
}
else if (float.TryParse(command, out float offset))
{
MoveModel(offset);
}
}
else if (msg == "RequestHasAnimation")
{
SendHasAnimationStatus();
} }
} }
// 仅当动画播放且客户端未拖动时发送进度,且限制发送频率
if (isPlayingAnimation && !isClientDragging && clientStream != null && clientStream.CanWrite) if (isPlayingAnimation && !isClientDragging && clientStream != null && clientStream.CanWrite)
{ {
if (Time.time - lastSendTime >= sendInterval) if (Time.time - lastSendTime >= sendInterval)
{ {
if (pageModelCache.TryGetValue(currentPage, out PageModel pm) && pm != null && pm.model != null) if (pageModelCache.TryGetValue(currentPage, out PageModel pm) && pm != null)
{ {
ModelController mc = pm.model.GetComponent<ModelController>(); ModelController mc = null;
if (!string.IsNullOrEmpty(currentSingleItemModel))
{
GameObject singleItemModel = pm.singleItemModels.Find(m => m != null && m.name == currentSingleItemModel);
if (singleItemModel != null)
{
mc = singleItemModel.GetComponent<ModelController>();
}
}
else if (pm.model != null)
{
mc = pm.model.GetComponent<ModelController>();
}
if (mc != null && mc.IsPlayingAnimation()) if (mc != null && mc.IsPlayingAnimation())
{ {
float progress = mc.GetAnimationProgress(); float progress = mc.GetAnimationProgress();
// 仅当进度有效且变化显著时发送
if (progress > 0f && Mathf.Abs(progress - lastSentProgress) > 0.005f) if (progress > 0f && Mathf.Abs(progress - lastSentProgress) > 0.005f)
{ {
try try
@ -219,20 +272,17 @@ public class DisplayServer : MonoBehaviour
string progressMsg = $"Progress:{progress:F2}"; string progressMsg = $"Progress:{progress:F2}";
byte[] data = Encoding.UTF8.GetBytes(progressMsg); byte[] data = Encoding.UTF8.GetBytes(progressMsg);
clientStream.Write(data, 0, data.Length); clientStream.Write(data, 0, data.Length);
Debug.Log($"发送动画进度: {progressMsg}"); lastSentProgress = progress;
lastSentProgress = progress; // 更新最后发送的进度 lastSendTime = Time.time;
lastSendTime = Time.time; // 更新发送时间
} }
catch (Exception ex) catch
{ {
Debug.LogError($"发送动画进度失败: {ex.Message}"); clientStream = null;
clientStream = null; // 标记流失效
} }
} }
} }
else else
{ {
// 动画已停止,更新状态
isPlayingAnimation = false; isPlayingAnimation = false;
} }
} }
@ -240,12 +290,49 @@ public class DisplayServer : MonoBehaviour
} }
} }
// 切换激活的UI页面并更新模型 private void SendHasAnimationStatus()
{
if (clientStream == null || !clientStream.CanWrite) return;
bool hasAnimation = false;
if (pageModelCache.TryGetValue(currentPage, out PageModel pm) && pm != null)
{
ModelController mc = null;
if (!string.IsNullOrEmpty(currentSingleItemModel))
{
GameObject singleItemModel = pm.singleItemModels.Find(m => m != null && m.name == currentSingleItemModel);
if (singleItemModel != null)
{
mc = singleItemModel.GetComponent<ModelController>();
}
}
else if (pm.model != null)
{
mc = pm.model.GetComponent<ModelController>();
}
if (mc != null)
{
hasAnimation = mc.GetHasAnimation();
}
}
try
{
string msg = $"HasAnimation:{(hasAnimation ? "True" : "False")}";
byte[] data = Encoding.UTF8.GetBytes(msg);
clientStream.Write(data, 0, data.Length);
}
catch
{
clientStream = null;
}
}
private void ShowPage(string pageName) private void ShowPage(string pageName)
{ {
if (background == null) if (background == null)
{ {
Debug.LogError("背景Transform未设置");
return; return;
} }
@ -253,153 +340,266 @@ public class DisplayServer : MonoBehaviour
{ {
bool isActive = child.name == pageName; bool isActive = child.name == pageName;
child.gameObject.SetActive(isActive); child.gameObject.SetActive(isActive);
Debug.Log($"页面 {child.name} 设置为 {(isActive ? "" : "")}");
} }
currentPage = pageName; currentPage = pageName;
currentSingleItemModel = "";
// 更新模型可见性并重置动画
foreach (var pageModel in pageModels) foreach (var pageModel in pageModels)
{ {
bool isActive = pageModel.pageName == pageName;
if (pageModel.model != null) if (pageModel.model != null)
{ {
bool isActive = pageModel.pageName == pageName; pageModel.model.SetActive(isActive && string.IsNullOrEmpty(currentSingleItemModel));
pageModel.model.SetActive(isActive); pageModel.originalPosition = pageModel.model.transform.localPosition;
ModelController mc = pageModel.model.GetComponent<ModelController>(); ModelController mc = pageModel.model.GetComponent<ModelController>();
if (mc != null) if (mc != null)
{ {
// 取消订阅旧事件
mc.OnAnimationFinished -= OnModelAnimationFinished; mc.OnAnimationFinished -= OnModelAnimationFinished;
// 订阅动画结束事件
if (isActive) if (isActive)
{ {
mc.OnAnimationFinished += OnModelAnimationFinished; mc.OnAnimationFinished += OnModelAnimationFinished;
} }
mc.ResetAnimation(); mc.ResetAnimation();
Debug.Log($"模型 {pageModel.model.name} 重置,页面: {pageName}"); mc.ResetModelPosition();
}
}
foreach (var singleItemModel in pageModel.singleItemModels)
{
if (singleItemModel != null)
{
singleItemModel.SetActive(false);
ModelController mc = singleItemModel.GetComponent<ModelController>();
if (mc != null)
{
mc.OnAnimationFinished -= OnModelAnimationFinished;
mc.ResetAnimation();
mc.ResetModelPosition();
}
}
}
}
SetTextPanelVisibility(pageName != "Ê×Ò³");
SetBackgroundSprite(pageName != "Ê×Ò³");
}
private void ShowSingleItemModel(string modelName)
{
if (pageModelCache.TryGetValue(currentPage, out PageModel pm) && pm != null)
{
if (pm.model != null)
{
pm.model.SetActive(false);
ModelController mc = pm.model.GetComponent<ModelController>();
if (mc != null)
{
mc.OnAnimationFinished -= OnModelAnimationFinished;
mc.ResetAnimation();
}
}
bool modelFound = false;
foreach (var singleItemModel in pm.singleItemModels)
{
if (singleItemModel != null)
{
bool isActive = singleItemModel.name == modelName;
singleItemModel.SetActive(isActive);
ModelController mc = singleItemModel.GetComponent<ModelController>();
if (mc != null)
{
mc.OnAnimationFinished -= OnModelAnimationFinished;
if (isActive)
{
mc.OnAnimationFinished += OnModelAnimationFinished;
mc.ResetAnimation();
mc.ResetModelPosition();
currentSingleItemModel = modelName;
modelFound = true;
}
}
else if (isActive)
{
currentSingleItemModel = modelName;
modelFound = true;
}
}
}
SetTextPanelVisibility(currentPage != "Ê×Ò³");
SetBackgroundSprite(currentPage != "Ê×Ò³");
}
}
private void PlayModelAnimation(string modelName)
{
if (string.IsNullOrEmpty(modelName))
{
return;
}
if (pageModelCache.TryGetValue(currentPage, out PageModel pm) && pm != null)
{
ModelController mc = null;
GameObject targetModel = null;
if (!string.IsNullOrEmpty(currentSingleItemModel) && modelName == currentSingleItemModel)
{
targetModel = pm.singleItemModels.Find(m => m != null && m.name == modelName);
if (targetModel != null)
{
mc = targetModel.GetComponent<ModelController>();
}
}
else if (pm.model != null && pm.model.name == modelName)
{
targetModel = pm.model;
mc = pm.model.GetComponent<ModelController>();
}
if (mc != null)
{
Animator animator = mc.GetComponent<Animator>();
if (animator != null && animator.runtimeAnimatorController != null && mc.GetHasAnimation())
{
mc.OnAnimationFinished -= OnModelAnimationFinished;
mc.OnAnimationFinished += OnModelAnimationFinished;
mc.PlayAnimation();
isPlayingAnimation = true;
} }
else else
{ {
Debug.LogWarning($"模型 {pageModel.model.name} 未找到ModelController"); isPlayingAnimation = false;
} }
} }
}
// 初始化文字面板为显示
SetTextPanelVisibility(true);
// 初始化背景为有文字背景
SetBackgroundSprite(true);
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<ModelController>();
if (mc != null)
{
// 取消旧订阅,添加新订阅
mc.OnAnimationFinished -= OnModelAnimationFinished;
mc.OnAnimationFinished += OnModelAnimationFinished;
mc.PlayAnimation();
isPlayingAnimation = true; // 确认动画开始播放
Debug.Log($"播放模型动画: {modelName}");
}
else else
{ {
isPlayingAnimation = false; // 动画未启动 isPlayingAnimation = false;
Debug.LogWarning($"模型 {modelName} 未找到ModelController");
} }
} }
else else
{ {
isPlayingAnimation = false; // 动画未启动 isPlayingAnimation = false;
Debug.LogWarning($"未找到模型 {modelName}");
} }
} }
// 设置当前页面模型的动画进度
private void SetAnimationProgress(float progress) private void SetAnimationProgress(float progress)
{ {
if (pageModelCache.TryGetValue(currentPage, out PageModel pm) && pm != null && pm.model != null) if (pageModelCache.TryGetValue(currentPage, out PageModel pm) && pm != null)
{ {
ModelController mc = pm.model.GetComponent<ModelController>(); ModelController mc = null;
if (!string.IsNullOrEmpty(currentSingleItemModel))
{
GameObject singleItemModel = pm.singleItemModels.Find(m => m != null && m.name == currentSingleItemModel);
if (singleItemModel != null)
{
mc = singleItemModel.GetComponent<ModelController>();
}
}
else if (pm.model != null)
{
mc = pm.model.GetComponent<ModelController>();
}
if (mc != null) if (mc != null)
{ {
mc.SetAnimationProgress(progress); mc.SetAnimationProgress(progress);
Debug.Log($"设置模型 {pm.model.name} 进度: {progress:F2}");
} }
else
{
Debug.LogWarning($"模型 {pm.model.name} 未找到ModelController");
}
}
else
{
Debug.LogWarning($"未找到页面 {currentPage} 的模型或ModelController");
} }
} }
// 设置当前页面文字面板的显隐 private void MoveModel(float xOffset)
{
if (pageModelCache.TryGetValue(currentPage, out PageModel pm) && pm != null)
{
ModelController mc = null;
GameObject targetModel = null;
if (!string.IsNullOrEmpty(currentSingleItemModel))
{
targetModel = pm.singleItemModels.Find(m => m != null && m.name == currentSingleItemModel);
if (targetModel != null)
{
mc = targetModel.GetComponent<ModelController>();
}
}
else if (pm.model != null)
{
targetModel = pm.model;
mc = pm.model.GetComponent<ModelController>();
}
if (mc != null && targetModel.activeSelf)
{
mc.MoveModel(xOffset);
}
else if (targetModel != null && targetModel.activeSelf)
{
Vector3 originalPosition = pm.originalPosition;
Vector3 targetPosition = originalPosition + new Vector3(xOffset, 0f, 0f);
targetModel.transform.DOLocalMoveX(targetPosition.x, 1f).SetEase(Ease.InOutSine);
}
}
}
private void ResetModelPosition()
{
if (pageModelCache.TryGetValue(currentPage, out PageModel pm) && pm != null)
{
ModelController mc = null;
GameObject targetModel = null;
if (!string.IsNullOrEmpty(currentSingleItemModel))
{
targetModel = pm.singleItemModels.Find(m => m != null && m.name == currentSingleItemModel);
if (targetModel != null)
{
mc = targetModel.GetComponent<ModelController>();
}
}
else if (pm.model != null)
{
targetModel = pm.model;
mc = pm.model.GetComponent<ModelController>();
}
if (mc != null && targetModel.activeSelf)
{
mc.ResetModelPosition();
}
else if (targetModel != null && targetModel.activeSelf)
{
Vector3 originalPosition = pm.originalPosition;
targetModel.transform.DOLocalMoveX(originalPosition.x, 1f).SetEase(Ease.InOutSine);
}
}
}
private void SetTextPanelVisibility(bool isVisible) private void SetTextPanelVisibility(bool isVisible)
{ {
if (background == null || string.IsNullOrEmpty(currentPage) || currentPage == "Ê×Ò³") if (background == null || string.IsNullOrEmpty(currentPage) || currentPage == "Ê×Ò³")
{ {
Debug.Log($"跳过文字面板显隐设置: background={(background != null ? "" : "null")}, currentPage={currentPage}");
return; return;
} }
Transform pageTransform = background.Find(currentPage); if (textPanelCache.TryGetValue(currentPage, out Transform textPanel))
if (pageTransform != null)
{ {
Transform textPanel = pageTransform.Find("ItemInfo/TextPanel"); textPanel.gameObject.SetActive(isVisible);
if (textPanel != null) if (isVisible)
{ {
textPanel.gameObject.SetActive(isVisible); ResetModelPosition();
Debug.Log($"设置页面 {currentPage} 文字面板显隐: {isVisible}");
} }
else else
{ {
Debug.LogWarning($"未在页面 {currentPage}/ItemInfo 找到TextPanel"); MoveModel(textHiddenOffset);
// 尝试递归查找
textPanel = FindDeep(pageTransform, "TextPanel");
if (textPanel != null)
{
textPanel.gameObject.SetActive(isVisible);
Debug.Log($"通过递归查找设置页面 {currentPage} 文字面板显隐: {isVisible}");
}
else
{
Debug.LogWarning($"递归查找仍未找到 {currentPage}/TextPanel");
Debug.Log($"页面 {currentPage} 子物体: {string.Join(", ", GetChildNames(pageTransform))}");
Transform itemInfo = pageTransform.Find("ItemInfo");
if (itemInfo != null)
{
Debug.Log($"ItemInfo 子物体: {string.Join(", ", GetChildNames(itemInfo))}");
}
else
{
Debug.LogWarning($"未在页面 {currentPage} 找到ItemInfo");
}
}
} }
} }
else
{
Debug.LogWarning($"未找到页面 {currentPage}背景Transform子物体: {string.Join(", ", GetChildNames(background))}");
}
} }
// 设置公共背景的Sprite
private void SetBackgroundSprite(bool hasText) private void SetBackgroundSprite(bool hasText)
{ {
if (background == null) if (background == null)
{ {
Debug.LogError($"背景Transform未设置无法切换背景");
return; return;
} }
@ -410,32 +610,10 @@ public class DisplayServer : MonoBehaviour
if (newSprite != null) if (newSprite != null)
{ {
backgroundImage.sprite = newSprite; backgroundImage.sprite = newSprite;
Debug.Log($"设置公共背景: {newSprite.name}");
} }
else
{
Debug.LogWarning($"背景Sprite未设置: hasText={hasText}");
}
}
else
{
Debug.LogWarning($"BG GameObject未找到Image组件");
Debug.Log($"BG 子物体: {string.Join(", ", GetChildNames(background))}");
} }
} }
// 辅助方法获取Transform的子物体名称
private string[] GetChildNames(Transform parent)
{
List<string> names = new List<string>();
foreach (Transform child in parent)
{
names.Add(child.name);
}
return names.ToArray();
}
// 辅助方法:递归查找子物体
private Transform FindDeep(Transform parent, string name) private Transform FindDeep(Transform parent, string name)
{ {
Transform result = parent.Find(name); Transform result = parent.Find(name);
@ -451,12 +629,9 @@ public class DisplayServer : MonoBehaviour
return null; return null;
} }
// 处理动画结束事件
private void OnModelAnimationFinished() private void OnModelAnimationFinished()
{ {
isPlayingAnimation = false; isPlayingAnimation = false;
Debug.Log("模型动画播放完成,停止发送进度");
// 发送最终进度 1.0
if (clientStream != null && clientStream.CanWrite) if (clientStream != null && clientStream.CanWrite)
{ {
try try
@ -464,27 +639,23 @@ public class DisplayServer : MonoBehaviour
string progressMsg = "Progress:1.00"; string progressMsg = "Progress:1.00";
byte[] data = Encoding.UTF8.GetBytes(progressMsg); byte[] data = Encoding.UTF8.GetBytes(progressMsg);
clientStream.Write(data, 0, data.Length); clientStream.Write(data, 0, data.Length);
Debug.Log($"发送最终动画进度: {progressMsg}");
lastSentProgress = 1f; lastSentProgress = 1f;
lastSendTime = Time.time; lastSendTime = Time.time;
} }
catch (Exception ex) catch
{ {
Debug.LogError($"发送最终进度失败: {ex.Message}");
clientStream = null; clientStream = null;
} }
} }
} }
// 应用程序退出时清理资源
private void OnApplicationQuit() private void OnApplicationQuit()
{ {
isRunning = false; isRunning = false;
listenCts.Cancel(); listenCts.Cancel();
listener.Stop(); listener?.Stop();
clientStream?.Close(); clientStream?.Close();
// 取消所有动画结束事件订阅
foreach (var pm in pageModels) foreach (var pm in pageModels)
{ {
if (pm.model != null) if (pm.model != null)
@ -495,12 +666,27 @@ public class DisplayServer : MonoBehaviour
mc.OnAnimationFinished -= OnModelAnimationFinished; mc.OnAnimationFinished -= OnModelAnimationFinished;
} }
} }
foreach (var singleItemModel in pm.singleItemModels)
{
if (singleItemModel != null)
{
ModelController mc = singleItemModel.GetComponent<ModelController>();
if (mc != null)
{
mc.OnAnimationFinished -= OnModelAnimationFinished;
}
}
}
} }
if (listenThread != null && listenThread.IsAlive) if (listenThread != null && listenThread.IsAlive)
{ {
listenThread.Join(1000); // 等待线程结束 listenThread.Join(1000);
} }
Debug.Log("显示端服务器已停止"); }
private void OnDestroy()
{
OnApplicationQuit();
} }
} }

View File

@ -1,151 +1,229 @@
using UnityEngine; using UnityEngine;
using System.Collections.Generic; using System.Collections.Generic;
using DG.Tweening;
using System; using System;
public class ModelController : MonoBehaviour public class ModelController : MonoBehaviour
{ {
private Animator animator; // 控制动画的Animator组件 private Animator animator;
private string currentAnim = ""; // 跟踪当前播放的动画 private string currentAnim = "";
private bool isPlaying = false; // 跟踪动画播放状态 private bool isPlaying = false;
private Vector3 originalPosition;
private Vector3 originalScale;
[Header("默认动画状态名称")] [SerializeField] private string defaultAnimName = "Take 001";
public string defaultAnimName = "Take 001"; // 默认动画状态名称 [SerializeField] private bool hasAnimation = true;
private Dictionary<string, int> stateHashes = new Dictionary<string, int>(); // 动画状态哈希缓存 private Dictionary<string, int> stateHashes = new Dictionary<string, int>();
private float lastLoggedProgress = -1f; // 记录上次日志的进度值 private float lastLoggedProgress = -1f;
private float lastWarningTime = 0f; // 记录上次警告日志时间 private float lastWarningTime = 0f;
private const float warningInterval = 1f; // 警告日志间隔(秒) private const float warningInterval = 1f;
// 动画结束事件
public event Action OnAnimationFinished; public event Action OnAnimationFinished;
// 脚本初始化时调用
void Awake() void Awake()
{ {
animator = GetComponent<Animator>(); animator = GetComponent<Animator>();
// 缓存默认动画状态的哈希值以提高性能 originalPosition = transform.localPosition;
originalScale = transform.localScale;
if (hasAnimation)
{
if (animator == null)
{
hasAnimation = false;
}
else
{
CacheAnimationStates();
}
}
else
{
if (animator != null)
{
animator.enabled = false;
}
}
}
private void CacheAnimationStates()
{
if (!hasAnimation) return;
stateHashes.Clear();
if (!string.IsNullOrEmpty(defaultAnimName)) if (!string.IsNullOrEmpty(defaultAnimName))
{ {
stateHashes[defaultAnimName] = Animator.StringToHash(defaultAnimName); stateHashes[defaultAnimName] = Animator.StringToHash(defaultAnimName);
} }
} if (animator.runtimeAnimatorController != null)
// 在Update中更新动画状态
void Update()
{
if (isPlaying && animator != null && !string.IsNullOrEmpty(currentAnim))
{ {
if (!animator.enabled) foreach (var clip in animator.runtimeAnimatorController.animationClips)
{ {
animator.enabled = true; // 确保Animator启用 if (!stateHashes.ContainsKey(clip.name))
Debug.Log($"重新启用Animator: {currentAnim}"); {
} stateHashes[clip.name] = Animator.StringToHash(clip.name);
AnimatorStateInfo stateInfo = animator.GetCurrentAnimatorStateInfo(0); }
if (stateInfo.IsName(currentAnim) && stateInfo.normalizedTime >= 1f)
{
// 动画播放完成,暂停并标记
animator.enabled = false;
isPlaying = false;
OnAnimationFinished?.Invoke(); // 通知动画结束
Debug.Log($"动画 {currentAnim} 播放完成,暂停");
} }
} }
else
{
hasAnimation = false;
animator.enabled = false;
}
}
void Update()
{
if (!hasAnimation || !isPlaying || animator == null || string.IsNullOrEmpty(currentAnim)) return;
if (!animator.enabled)
{
animator.enabled = true;
}
transform.localScale = originalScale;
transform.localPosition = originalPosition;
AnimatorStateInfo stateInfo = animator.GetCurrentAnimatorStateInfo(0);
if (stateInfo.IsName(currentAnim) && stateInfo.normalizedTime >= 1f && !animator.IsInTransition(0))
{
isPlaying = false;
animator.enabled = false;
transform.localScale = originalScale;
transform.localPosition = originalPosition;
OnAnimationFinished?.Invoke();
}
} }
/// <summary>
/// 从头播放默认动画
/// </summary>
public void PlayAnimation() public void PlayAnimation()
{ {
if (animator == null || string.IsNullOrEmpty(defaultAnimName)) return; if (!hasAnimation)
{
return;
}
if (animator == null || string.IsNullOrEmpty(defaultAnimName) || !gameObject.activeSelf)
{
return;
}
if (!AnimatorHasState(defaultAnimName)) if (!AnimatorHasState(defaultAnimName))
{ {
Debug.LogWarning($"Animator上不存在状态: {defaultAnimName}");
return; return;
} }
currentAnim = defaultAnimName; currentAnim = defaultAnimName;
animator.enabled = true; animator.enabled = true;
animator.Play(currentAnim, 0, 0f); // 从头播放动画 animator.Play(stateHashes[currentAnim], 0, 0f);
animator.Update(0f); // 强制立即更新 animator.Update(0f);
isPlaying = true; // 标记动画正在播放 isPlaying = true;
Debug.Log($"开始播放动画: {currentAnim}"); transform.localScale = originalScale;
transform.localPosition = originalPosition;
} }
/// <summary>
/// 设置动画进度0到1
/// </summary>
public void SetAnimationProgress(float normalizedTime) public void SetAnimationProgress(float normalizedTime)
{ {
if (animator == null || string.IsNullOrEmpty(defaultAnimName)) return; if (!hasAnimation)
if (!gameObject.activeSelf) return; {
return;
}
if (animator == null || string.IsNullOrEmpty(defaultAnimName) || !gameObject.activeSelf)
{
return;
}
// 确保currentAnim已设置
if (string.IsNullOrEmpty(currentAnim)) if (string.IsNullOrEmpty(currentAnim))
{ {
currentAnim = defaultAnimName; currentAnim = defaultAnimName;
Debug.Log($"设置动画进度前初始化currentAnim: {currentAnim}");
} }
if (!AnimatorHasState(currentAnim)) if (!AnimatorHasState(currentAnim))
{ {
Debug.LogWarning($"Animator上不存在状态: {currentAnim}");
return; return;
} }
// 停止播放状态
isPlaying = false; isPlaying = false;
animator.enabled = true; animator.enabled = true;
float clampedTime = Mathf.Clamp01(normalizedTime); float clampedTime = Mathf.Clamp01(normalizedTime);
animator.Play(currentAnim, 0, clampedTime); // 设置动画到指定时间 animator.Play(stateHashes[currentAnim], 0, clampedTime);
animator.Update(0f); // 强制立即更新 animator.Update(0f);
animator.enabled = false; // 暂停动画 animator.enabled = false;
Debug.Log($"设置动画 {currentAnim} 进度: {clampedTime:F2}"); transform.localScale = originalScale;
transform.localPosition = originalPosition;
} }
/// <summary>
/// 重置动画到初始状态
/// </summary>
public void ResetAnimation() public void ResetAnimation()
{ {
if (animator == null) return; if (!hasAnimation)
if (!gameObject.activeSelf) return; {
return;
}
if (animator == null || !gameObject.activeSelf)
{
return;
}
string animToReset = !string.IsNullOrEmpty(defaultAnimName) ? defaultAnimName : ""; string animToReset = !string.IsNullOrEmpty(defaultAnimName) ? defaultAnimName : "";
if (string.IsNullOrEmpty(animToReset)) return; if (string.IsNullOrEmpty(animToReset))
{
return;
}
currentAnim = animToReset; // 确保currentAnim已设置 if (!AnimatorHasState(animToReset))
{
return;
}
currentAnim = animToReset;
animator.enabled = true; animator.enabled = true;
animator.Play(currentAnim, 0, 0f); // 重置到开始 animator.Play(stateHashes[currentAnim], 0, 0f);
animator.Update(0f); // 强制立即更新 animator.Update(0f);
animator.enabled = false; // 暂停动画 animator.enabled = false;
isPlaying = false; // 标记动画暂停 isPlaying = false;
Debug.Log($"重置动画: {currentAnim}"); transform.localScale = originalScale;
transform.localPosition = originalPosition;
}
public void MoveModel(float xOffset)
{
if (!gameObject.activeSelf)
{
return;
}
Vector3 targetPosition = originalPosition + new Vector3(xOffset, 0f, 0f);
transform.DOLocalMoveX(targetPosition.x, 1f).SetEase(Ease.InOutSine).OnComplete(() =>
{
transform.localScale = originalScale;
});
}
public void ResetModelPosition()
{
if (!gameObject.activeSelf)
{
return;
}
transform.DOLocalMoveX(originalPosition.x, 1f).SetEase(Ease.InOutSine).OnComplete(() =>
{
transform.localScale = originalScale;
});
} }
/// <summary>
/// 获取当前动画的标准化时间0到1
/// </summary>
/// <returns>当前动画进度若无动画则返回0</returns>
public float GetAnimationProgress() public float GetAnimationProgress()
{ {
if (!hasAnimation)
{
return 0f;
}
if (animator == null || !animator.enabled || 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; return 0f;
} }
if (!AnimatorHasState(currentAnim)) if (!AnimatorHasState(currentAnim))
{ {
if (Time.time - lastWarningTime >= warningInterval)
{
Debug.LogWarning($"Animator上不存在状态: {currentAnim}");
lastWarningTime = Time.time;
}
return 0f; return 0f;
} }
@ -153,38 +231,44 @@ public class ModelController : MonoBehaviour
if (stateInfo.IsName(currentAnim)) if (stateInfo.IsName(currentAnim))
{ {
float progress = Mathf.Clamp01(stateInfo.normalizedTime % 1f); 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; return progress;
} }
if (Time.time - lastWarningTime >= warningInterval)
{
Debug.LogWarning($"动画状态不匹配: currentAnim={currentAnim}, state={stateInfo.fullPathHash}");
lastWarningTime = Time.time;
}
return 0f; return 0f;
} }
// 检查指定的动画状态是否存在于Animator中
private bool AnimatorHasState(string stateName) private bool AnimatorHasState(string stateName)
{ {
if (stateHashes.TryGetValue(stateName, out int hash)) if (!hasAnimation)
{ {
for (int i = 0; i < animator.layerCount; i++) return false;
}
if (string.IsNullOrEmpty(stateName) || !stateHashes.TryGetValue(stateName, out int hash))
{
return false;
}
for (int i = 0; i < animator.layerCount; i++)
{
if (animator.HasState(i, hash))
{ {
if (animator.HasState(i, hash)) return true; return true;
} }
} }
return false; return false;
} }
// 获取动画播放状态
public bool IsPlayingAnimation() public bool IsPlayingAnimation()
{ {
if (!hasAnimation)
{
return false;
}
return isPlaying; return isPlaying;
} }
public bool GetHasAnimation()
{
return hasAnimation;
}
} }

View File

@ -10,56 +10,118 @@ using UnityEngine.UI;
public class TouchClient : MonoBehaviour public class TouchClient : MonoBehaviour
{ {
private TcpClient client; // 用于与显示端通信的TCP客户端 private TcpClient client;
private NetworkStream stream; // 用于发送/接收数据的流 private NetworkStream stream;
private volatile bool isConnected = false; // 线程安全的连接状态标志 private volatile bool isConnected = false;
private UdpClient udpListener; // 用于接收广播IP的UDP客户端 private UdpClient udpListener;
private Thread udpThread; // 监听广播的线程 private Thread udpThread;
private CancellationTokenSource udpCts = new CancellationTokenSource(); // 控制UDP线程取消 private CancellationTokenSource udpCts = new CancellationTokenSource();
private Thread receiveThread; // 接收服务器消息的线程 private Thread receiveThread;
private CancellationTokenSource receiveCts = new CancellationTokenSource(); // 控制接收线程取消 private CancellationTokenSource receiveCts = new CancellationTokenSource();
public Transform background; // UI页面的父级变换 public Transform background;
private string currentPage = "首页"; // 跟踪当前显示的页面 private string currentPage = "Ê×Ò³";
private string currentSingleItemModel = "";
private readonly Queue<float> progressQueue = new Queue<float>(); // 线程安全的进度队列 private readonly Queue<float> progressQueue = new Queue<float>();
private readonly object queueLock = new object(); // 进度队列访问锁 private readonly Queue<bool> hasAnimationQueue = new Queue<bool>();
private bool isDraggingSlider = false; // 标记是否正在拖动Slider private readonly object queueLock = new object();
private float lastSentProgress = 0f; // 记录最后发送的进度 private bool isDraggingSlider = false;
private float lastSentProgress = 0f;
[Header("Text Panel Toggle Sprites")] private Dictionary<string, Slider> sliderCache;
public Sprite showSprite; // 显示状态的Sprite private Dictionary<string, Toggle> toggleCache;
public Sprite hideSprite; // 隐藏状态的Sprite private Dictionary<string, Button> playButtonCache;
private Dictionary<string, List<Button>> singleItemButtonCache;
[System.Serializable]
public class PageButtonConfig
{
public string pageName;
public List<Button> singleItemButtons;
public List<string> singleItemModelNames;
public string defaultModelName;
}
[SerializeField] private List<PageButtonConfig> pageButtonConfigs = new List<PageButtonConfig>();
[SerializeField] private int udpPort = 9999;
[SerializeField] private int tcpPort = 8888;
[SerializeField] private int resolutionWidth = 1920;
[SerializeField] private int resolutionHeight = 1080;
public Sprite showSprite;
public Sprite hideSprite;
// 脚本启动时调用
void Start() void Start()
{ {
// 设置触摸控制端分辨率为 1920x1080 Screen.SetResolution(resolutionWidth, resolutionHeight, false);
Screen.SetResolution(1920, 1080, false);
sliderCache = new Dictionary<string, Slider>();
toggleCache = new Dictionary<string, Toggle>();
playButtonCache = new Dictionary<string, Button>();
singleItemButtonCache = new Dictionary<string, List<Button>>();
CacheUIComponents();
foreach (var config in pageButtonConfigs)
{
if (!string.IsNullOrEmpty(config.pageName) && config.singleItemButtons != null && config.singleItemModelNames != null)
{
if (config.singleItemButtons.Count == config.singleItemModelNames.Count)
{
singleItemButtonCache[config.pageName] = config.singleItemButtons;
for (int i = 0; i < config.singleItemButtons.Count; i++)
{
if (config.singleItemButtons[i] != null)
{
int index = i;
config.singleItemButtons[i].onClick.RemoveAllListeners();
config.singleItemButtons[i].onClick.AddListener(() => OnButtonClick_SingleItemModel(config.pageName, config.singleItemModelNames[index]));
}
}
}
}
}
try try
{ {
// 在端口9999上初始化UDP监听 udpListener = new UdpClient(udpPort);
udpListener = new UdpClient(9999);
udpThread = new Thread(() => ListenForBroadcast(udpCts.Token)); udpThread = new Thread(() => ListenForBroadcast(udpCts.Token));
udpThread.Start(); udpThread.Start();
Debug.Log("触摸端等待显示端广播,监听端口: 9999");
} }
catch (Exception ex) catch
{ {
Debug.LogError($"初始化UDP监听失败: {ex.Message}");
} }
// 显示初始页面
ShowPage("首页"); ShowPage("首页");
} }
// 监听UDP广播以发现显示端IP private void CacheUIComponents()
{
foreach (Transform child in background)
{
Slider slider = child.GetComponentInChildren<Slider>();
if (slider != null)
{
sliderCache[child.name] = slider;
}
Toggle toggle = child.GetComponentInChildren<Toggle>();
if (toggle != null)
{
toggleCache[child.name] = toggle;
}
Button playButton = FindDeep(child, "PlayButton")?.GetComponent<Button>();
if (playButton != null)
{
playButtonCache[child.name] = playButton;
}
}
}
private void ListenForBroadcast(CancellationToken token) private void ListenForBroadcast(CancellationToken token)
{ {
IPEndPoint endPoint = new IPEndPoint(IPAddress.Any, 9999); IPEndPoint endPoint = new IPEndPoint(IPAddress.Any, udpPort);
int retryDelayMs = 2000;
while (!isConnected && !token.IsCancellationRequested) while (!isConnected && !token.IsCancellationRequested)
{ {
@ -67,69 +129,54 @@ public class TouchClient : MonoBehaviour
{ {
byte[] data = udpListener.Receive(ref endPoint); byte[] data = udpListener.Receive(ref endPoint);
string message = Encoding.UTF8.GetString(data); string message = Encoding.UTF8.GetString(data);
Debug.Log($"收到UDP广播: {message},来源: {endPoint.Address}:{endPoint.Port}");
// 提取IP地址
string serverIp = message.StartsWith("ServerIP:") ? message.Replace("ServerIP:", "").Trim() : message.Trim(); string serverIp = message.StartsWith("ServerIP:") ? message.Replace("ServerIP:", "").Trim() : message.Trim();
if (IPAddress.TryParse(serverIp, out IPAddress ipAddress)) if (IPAddress.TryParse(serverIp, out IPAddress ipAddress))
{ {
Debug.Log($"解析到有效IP: {serverIp}"); ConnectToServer(serverIp, tcpPort);
ConnectToServer(serverIp, 8888); // 尝试连接到服务器 retryDelayMs = 2000;
}
else
{
Debug.LogWarning($"无效IP地址: {serverIp}");
} }
} }
catch (Exception ex) catch
{ {
Debug.LogError($"UDP接收错误: {ex.Message}"); Thread.Sleep(retryDelayMs);
Thread.Sleep(2000); // 等待2秒重试 retryDelayMs = Mathf.Min(retryDelayMs * 2, 10000);
} }
} }
} }
// 通过TCP连接到显示端服务器
private void ConnectToServer(string ip, int port) private void ConnectToServer(string ip, int port)
{ {
int retryCount = 0; int retryCount = 0;
const int maxRetries = 5; const int maxRetries = 5;
const int retryDelayMs = 2000; int retryDelayMs = 2000;
while (!isConnected && retryCount < maxRetries) while (!isConnected && retryCount < maxRetries)
{ {
try try
{ {
Debug.Log($"尝试连接显示端: {ip}:{port} (尝试 {retryCount + 1}/{maxRetries})");
client = new TcpClient(); client = new TcpClient();
client.Connect(ip, port); // 连接到服务器 client.Connect(ip, port);
stream = client.GetStream(); stream = client.GetStream();
isConnected = true; isConnected = true;
udpCts.Cancel(); // 连接成功后停止UDP监听线程 udpCts.Cancel();
udpListener?.Close(); // 关闭UDP监听器 udpListener?.Close();
Debug.Log($"触摸端已连接到显示端: {ip}:{port}");
// 启动接收线程以处理服务器消息
receiveThread = new Thread(() => ReceiveMessages(receiveCts.Token)); receiveThread = new Thread(() => ReceiveMessages(receiveCts.Token));
receiveThread.Start(); receiveThread.Start();
return; return;
} }
catch (Exception ex) catch
{ {
Debug.LogError($"连接显示端失败: {ex.Message}");
retryCount++; retryCount++;
if (retryCount < maxRetries) if (retryCount < maxRetries)
{ {
Debug.Log($"将在{retryDelayMs / 1000f}秒后重试...");
Thread.Sleep(retryDelayMs); Thread.Sleep(retryDelayMs);
retryDelayMs = Mathf.Min(retryDelayMs * 2, 10000);
} }
} }
} }
Debug.LogError($"连接显示端失败,已达到最大重试次数 ({maxRetries})");
} }
// 接收服务器发送的消息
private void ReceiveMessages(CancellationToken token) private void ReceiveMessages(CancellationToken token)
{ {
byte[] message = new byte[4096]; byte[] message = new byte[4096];
@ -140,62 +187,48 @@ public class TouchClient : MonoBehaviour
try try
{ {
bytesRead = stream.Read(message, 0, 4096); bytesRead = stream.Read(message, 0, 4096);
if (bytesRead == 0) if (bytesRead == 0) break;
{
Debug.Log("服务器断开连接");
break;
}
string data = Encoding.UTF8.GetString(message, 0, bytesRead); string data = Encoding.UTF8.GetString(message, 0, bytesRead);
if (data.StartsWith("Progress:") && float.TryParse(data.Replace("Progress:", ""), out float progress)) lock (queueLock)
{ {
lock (queueLock) if (data.StartsWith("Progress:") && float.TryParse(data.Replace("Progress:", ""), out float progress))
{ {
progressQueue.Enqueue(progress); // 将进度加入队列 progressQueue.Enqueue(progress);
Debug.Log($"收到进度: {progress:F2}"); }
else if (data.StartsWith("HasAnimation:"))
{
bool hasAnimation = data.Replace("HasAnimation:", "") == "True";
hasAnimationQueue.Enqueue(hasAnimation);
} }
} }
else
{
Debug.LogWarning($"收到未知消息: {data}");
}
} }
catch (Exception ex) catch
{ {
Debug.LogError($"接收服务器消息错误: {ex.Message}");
isConnected = false;
break; break;
} }
} }
// 清理连接
stream?.Close(); stream?.Close();
client?.Close(); client?.Close();
isConnected = false; isConnected = false;
Debug.Log("TCP连接已断开将重新启动UDP监听");
// 重启UDP监听
RestartUdpListener(); RestartUdpListener();
} }
// 重启UDP监听
private void RestartUdpListener() private void RestartUdpListener()
{ {
try try
{ {
udpCts = new CancellationTokenSource(); udpCts = new CancellationTokenSource();
udpListener = new UdpClient(9999); udpListener = new UdpClient(udpPort);
udpThread = new Thread(() => ListenForBroadcast(udpCts.Token)); udpThread = new Thread(() => ListenForBroadcast(udpCts.Token));
udpThread.Start(); udpThread.Start();
Debug.Log("重启UDP监听端口: 9999");
} }
catch (Exception ex) catch
{ {
Debug.LogError($"重启UDP监听失败: {ex.Message}");
} }
} }
// 向显示端服务器发送消息
private void SendMessageToServer(string msg) private void SendMessageToServer(string msg)
{ {
if (isConnected && stream != null) if (isConnected && stream != null)
@ -204,38 +237,28 @@ public class TouchClient : MonoBehaviour
{ {
byte[] data = Encoding.UTF8.GetBytes(msg); byte[] data = Encoding.UTF8.GetBytes(msg);
stream.Write(data, 0, data.Length); stream.Write(data, 0, data.Length);
Debug.Log($"发送指令: {msg}");
} }
catch (Exception ex) catch
{ {
Debug.LogError($"发送消息失败: {ex.Message}");
isConnected = false; isConnected = false;
RestartUdpListener(); RestartUdpListener();
} }
} }
else
{
Debug.LogWarning($"无法发送消息,未连接到服务器: {msg}");
}
} }
// 页面按钮点击时调用
public void OnButtonClick_Page(string pageName) public void OnButtonClick_Page(string pageName)
{ {
ShowPage(pageName); // 切换到指定页面 ShowPage(pageName);
SendMessageToServer("Page:" + pageName); // 通知服务器 SendMessageToServer("Page:" + pageName);
} }
// 模型播放按钮点击时调用 public void OnButtonClick_PlayModel()
public void OnButtonClick_PlayModel(string modelName)
{ {
// 清空进度队列,防止旧进度干扰
lock (queueLock) lock (queueLock)
{ {
progressQueue.Clear(); progressQueue.Clear();
} }
// 重置Slider到0
Slider slider = GetCurrentPageSlider(); Slider slider = GetCurrentPageSlider();
if (slider != null) if (slider != null)
{ {
@ -243,27 +266,64 @@ public class TouchClient : MonoBehaviour
slider.onValueChanged = new Slider.SliderEvent(); slider.onValueChanged = new Slider.SliderEvent();
slider.value = 0f; slider.value = 0f;
slider.onValueChanged = onValueChanged; slider.onValueChanged = onValueChanged;
lastSentProgress = 0f; // 重置最后发送的进度 lastSentProgress = 0f;
Debug.Log($"播放模型 {modelName} 前重置Slider到0");
} }
SendMessageToServer("Model:" + modelName); // 通知服务器播放模型 string modelName = "";
var config = pageButtonConfigs.Find(c => c.pageName == currentPage);
if (config != null && !string.IsNullOrEmpty(config.defaultModelName))
{
modelName = string.IsNullOrEmpty(currentSingleItemModel) ? config.defaultModelName : currentSingleItemModel;
}
else if (currentPage == "Ê×Ò³")
{
modelName = "ÕûÌå½á¹¹Õ¹Ê¾";
}
if (!string.IsNullOrEmpty(modelName))
{
SendMessageToServer("Model:" + modelName);
}
}
public void OnButtonClick_SingleItemModel(string pageName, string modelName)
{
if (pageName != currentPage)
{
ShowPage(pageName);
SendMessageToServer("Page:" + pageName);
}
currentSingleItemModel = modelName;
lock (queueLock)
{
progressQueue.Clear();
}
Slider slider = GetCurrentPageSlider();
if (slider != null)
{
var onValueChanged = slider.onValueChanged;
slider.onValueChanged = new Slider.SliderEvent();
slider.value = 0f;
slider.onValueChanged = onValueChanged;
lastSentProgress = 0f;
}
SendMessageToServer("SingleItemModel:" + modelName);
} }
// 滑块值改变时调用
public void OnSliderChanged(Slider slider) public void OnSliderChanged(Slider slider)
{ {
isDraggingSlider = true; // 标记正在拖动 isDraggingSlider = true;
float progress = slider.value / 100f; // 转换为0-1 float progress = slider.value / 100f;
if (progress > 0.01f) // 忽略接近0的值以避免异常 if (progress > 0.01f)
{ {
SendMessageToServer("Progress:" + progress.ToString("F2")); // 发送进度 SendMessageToServer("Progress:" + progress.ToString("F2"));
lastSentProgress = progress; // 记录最后发送的进度 lastSentProgress = progress;
Debug.Log($"Slider拖动到: {progress:F2}");
} }
} }
// 滑块拖动结束时调用需在Inspector中绑定
public void OnSliderEndDrag() public void OnSliderEndDrag()
{ {
Slider slider = GetCurrentPageSlider(); Slider slider = GetCurrentPageSlider();
@ -272,17 +332,14 @@ public class TouchClient : MonoBehaviour
float progress = slider.value / 100f; float progress = slider.value / 100f;
if (progress > 0.01f) if (progress > 0.01f)
{ {
SendMessageToServer("Progress:" + progress.ToString("F2")); // 发送最终进度 SendMessageToServer("Progress:" + progress.ToString("F2"));
lastSentProgress = progress; // 更新最后发送的进度 lastSentProgress = progress;
Debug.Log($"Slider拖动结束发送最终进度: {progress:F2}");
} }
} }
isDraggingSlider = false; // 结束拖动 isDraggingSlider = false;
SendMessageToServer("EndDrag"); // 通知服务器拖动结束 SendMessageToServer("EndDrag");
Debug.Log("Slider拖动结束");
} }
// 文字面板Toggle状态改变时调用
public void OnTextPanelToggleChanged(Toggle toggle) public void OnTextPanelToggleChanged(Toggle toggle)
{ {
if (toggle == null) return; if (toggle == null) return;
@ -294,186 +351,162 @@ public class TouchClient : MonoBehaviour
if (toggleImage != null) if (toggleImage != null)
{ {
Sprite newSprite = isTextPanelVisible ? showSprite : hideSprite; toggleImage.sprite = isTextPanelVisible ? showSprite : hideSprite;
toggleImage.sprite = newSprite;
Debug.Log($"Toggle sprite 切换: {currentPage}, isOn={isTextPanelVisible}, sprite={(newSprite != null ? newSprite.name : "null")}");
}
else
{
Debug.LogWarning($"Toggle {toggle.name} 未找到Background的Image组件");
} }
if (toggleText != null) if (toggleText != null)
{ {
toggleText.text = isTextPanelVisible ? "显示文字" : "隐藏文字"; toggleText.text = isTextPanelVisible ? "显示文字" : "隐藏文字";
Debug.Log($"Toggle 文本更新: {currentPage}, text={toggleText.text}");
}
else
{
Debug.LogWarning($"Toggle {toggle.name} 未找到Text(TMP)组件");
} }
// 验证Toggle的Graphic字段 string textPanelMessage = isTextPanelVisible ? "TextPanel:Show" : "TextPanel:Hide";
if (toggle.graphic != null && toggle.graphic is Image graphicImage) SendMessageToServer(textPanelMessage);
{
Debug.Log($"Toggle Graphic验证: {currentPage}, graphic sprite={graphicImage.sprite?.name ?? "null"}");
}
else
{
Debug.LogWarning($"Toggle {toggle.name} 的Graphic字段未正确配置或为空");
}
// 发送显隐消息到显示端 string backgroundMessage = isTextPanelVisible ? "Background:Text" : "Background:NoText";
string message = isTextPanelVisible ? "TextPanel:Show" : "TextPanel:Hide"; SendMessageToServer(backgroundMessage);
SendMessageToServer(message);
Debug.Log($"文字面板Toggle切换: {message}"); string modelMoveMessage = isTextPanelVisible ? "ModelMove:Reset" : $"ModelMove:33";
SendMessageToServer(modelMoveMessage);
SendMessageToServer("RequestHasAnimation");
}
private void UpdatePlayButtonVisibility(bool hasAnimation)
{
if (playButtonCache.TryGetValue(currentPage, out Button playButton) && playButton != null)
{
playButton.gameObject.SetActive(hasAnimation);
}
} }
// 获取当前页面的Slider组件
private Slider GetCurrentPageSlider() private Slider GetCurrentPageSlider()
{ {
if (background == null || currentPage == "首页") return null; if (background == null || currentPage == "首页") return null;
Transform pageTransform = background.Find(currentPage); if (sliderCache.TryGetValue(currentPage, out Slider slider))
if (pageTransform != null)
{ {
Slider slider = pageTransform.GetComponentInChildren<Slider>(); if (!slider.interactable)
if (slider != null)
{ {
if (!slider.interactable) slider.interactable = true;
{
slider.interactable = true; // 确保Slider可交互
Debug.Log($"启用Slider交互: {currentPage}");
}
return slider;
} }
Debug.LogWarning($"未在页面 {currentPage} 找到Slider"); return slider;
return null;
} }
Debug.LogWarning($"未找到页面 {currentPage}");
return null; return null;
} }
// 获取当前页面的TextPanelToggle组件
private Toggle GetCurrentPageTextPanelToggle() private Toggle GetCurrentPageTextPanelToggle()
{ {
if (background == null || currentPage == "首页") return null; if (background == null || currentPage == "首页") return null;
Transform pageTransform = background.Find(currentPage); if (toggleCache.TryGetValue(currentPage, out Toggle toggle))
if (pageTransform != null)
{ {
Toggle toggle = pageTransform.GetComponentInChildren<Toggle>(); if (!toggle.interactable)
if (toggle != null)
{ {
if (!toggle.interactable) toggle.interactable = true;
{
toggle.interactable = true; // 确保Toggle可交互
Debug.Log($"启用TextPanelToggle交互: {currentPage}");
}
return toggle;
} }
Debug.LogWarning($"未在页面 {currentPage} 找到TextPanelToggle"); return toggle;
return null;
} }
Debug.LogWarning($"未找到页面 {currentPage}");
return null; return null;
} }
// 切换激活的UI页面
private void ShowPage(string pageName) private void ShowPage(string pageName)
{ {
foreach (Transform child in background) foreach (Transform child in background)
{ {
child.gameObject.SetActive(child.name == pageName); // 仅激活目标页面 child.gameObject.SetActive(child.name == pageName);
} }
currentPage = pageName; currentPage = pageName;
currentSingleItemModel = "";
// 清空进度队列以避免旧页面数据干扰
lock (queueLock) lock (queueLock)
{ {
progressQueue.Clear(); progressQueue.Clear();
hasAnimationQueue.Clear();
} }
// 初始化当前页面的Slider
Slider slider = GetCurrentPageSlider(); Slider slider = GetCurrentPageSlider();
if (slider != null) if (slider != null)
{ {
// 临时禁用OnValueChanged以防止初始化触发
var onValueChanged = slider.onValueChanged; var onValueChanged = slider.onValueChanged;
slider.onValueChanged = new Slider.SliderEvent(); slider.onValueChanged = new Slider.SliderEvent();
slider.value = 0f; // 重置Slider到0 slider.value = 0f;
slider.interactable = true; // 确保可交互 slider.interactable = true;
// 恢复OnValueChanged并绑定
slider.onValueChanged = onValueChanged; slider.onValueChanged = onValueChanged;
slider.onValueChanged.RemoveAllListeners(); slider.onValueChanged.RemoveAllListeners();
slider.onValueChanged.AddListener((value) => OnSliderChanged(slider)); slider.onValueChanged.AddListener((value) => OnSliderChanged(slider));
lastSentProgress = 0f; // 重置最后发送的进度 lastSentProgress = 0f;
Debug.Log($"初始化Slider: {pageName}, 值: {slider.value}");
} }
// 初始化当前页面的TextPanelToggle
Toggle toggle = GetCurrentPageTextPanelToggle(); Toggle toggle = GetCurrentPageTextPanelToggle();
if (toggle != null) if (toggle != null)
{ {
// 临时禁用OnValueChanged以防止初始化触发
var onValueChanged = toggle.onValueChanged; var onValueChanged = toggle.onValueChanged;
toggle.onValueChanged = new Toggle.ToggleEvent(); toggle.onValueChanged = new Toggle.ToggleEvent();
toggle.isOn = true; // 默认显示文字面板 toggle.isOn = true;
toggle.interactable = true; // 确保可交互 toggle.interactable = true;
// 更新Sprite和文本
Transform backgroundTransform = toggle.transform.Find("Background"); Transform backgroundTransform = toggle.transform.Find("Background");
Image toggleImage = backgroundTransform != null ? backgroundTransform.GetComponent<Image>() : null; Image toggleImage = backgroundTransform != null ? backgroundTransform.GetComponent<Image>() : null;
TextMeshProUGUI toggleText = toggle.GetComponentInChildren<TextMeshProUGUI>(); TextMeshProUGUI toggleText = toggle.GetComponentInChildren<TextMeshProUGUI>();
if (toggleImage != null) if (toggleImage != null)
{ {
toggleImage.sprite = showSprite; toggleImage.sprite = showSprite;
Debug.Log($"初始化Toggle sprite: {pageName}, sprite={(showSprite != null ? showSprite.name : "null")}");
}
else
{
Debug.LogWarning($"Toggle {toggle.name} 未找到Background的Image组件");
} }
if (toggleText != null) if (toggleText != null)
{ {
toggleText.text = "显示文字"; toggleText.text = "显示文字";
Debug.Log($"初始化Toggle 文本: {pageName}, text={toggleText.text}");
} }
else
{
Debug.LogWarning($"Toggle {toggle.name} 未找到Text(TMP)组件");
}
// 验证Toggle的Graphic字段
if (toggle.graphic != null && toggle.graphic is Image graphicImage)
{
Debug.Log($"初始化Toggle Graphic验证: {pageName}, graphic sprite={graphicImage.sprite?.name ?? "null"}");
}
else
{
Debug.LogWarning($"Toggle {toggle.name} 的Graphic字段未正确配置或为空");
}
// 恢复OnValueChanged并绑定
toggle.onValueChanged = onValueChanged; toggle.onValueChanged = onValueChanged;
toggle.onValueChanged.RemoveAllListeners(); toggle.onValueChanged.RemoveAllListeners();
toggle.onValueChanged.AddListener((value) => OnTextPanelToggleChanged(toggle)); toggle.onValueChanged.AddListener((value) => OnTextPanelToggleChanged(toggle));
// 发送初始显隐状态
SendMessageToServer("TextPanel:Show"); SendMessageToServer("TextPanel:Show");
Debug.Log($"初始化TextPanelToggle: {pageName}, isOn: {toggle.isOn}"); SendMessageToServer("Background:Text");
SendMessageToServer("ModelMove:Reset");
} }
Debug.Log($"切换到页面: {pageName}, Slider {(slider != null ? "" : "")}, TextPanelToggle {(toggle != null ? "" : "")}"); if (singleItemButtonCache.TryGetValue(pageName, out List<Button> buttons))
{
foreach (var button in buttons)
{
if (button != null)
{
button.interactable = true;
}
}
}
SendMessageToServer("RequestHasAnimation");
}
private Transform FindDeep(Transform parent, string name)
{
Transform result = parent.Find(name);
if (result != null)
return result;
foreach (Transform child in parent)
{
result = FindDeep(child, name);
if (result != null)
return result;
}
return null;
} }
// 在主线程中更新Slider进度
private void Update() private void Update()
{ {
if (isDraggingSlider) return; // 拖动时忽略服务器进度 if (isDraggingSlider) return;
float progress = -1f; float progress = -1f;
bool? hasAnimation = null;
lock (queueLock) lock (queueLock)
{ {
if (progressQueue.Count > 0) if (progressQueue.Count > 0)
{ {
progress = progressQueue.Dequeue(); // 获取最新进度 progress = progressQueue.Dequeue();
}
if (hasAnimationQueue.Count > 0)
{
hasAnimation = hasAnimationQueue.Dequeue();
} }
} }
@ -482,37 +515,42 @@ public class TouchClient : MonoBehaviour
Slider slider = GetCurrentPageSlider(); Slider slider = GetCurrentPageSlider();
if (slider != null) if (slider != null)
{ {
// 仅当进度与当前Slider值差异较大或接近1.0时更新
float currentProgress = slider.value / 100f; float currentProgress = slider.value / 100f;
if (progress > 0f || Mathf.Abs(progress - 1f) < 0.005f) if (progress > 0f || Mathf.Abs(progress - 1f) < 0.005f)
{ {
// 临时禁用OnValueChanged以防止循环触发
var onValueChanged = slider.onValueChanged; var onValueChanged = slider.onValueChanged;
slider.onValueChanged = new Slider.SliderEvent(); slider.onValueChanged = new Slider.SliderEvent();
slider.value = progress * 100f; // 更新Slider值0-100 slider.value = progress * 100f;
slider.onValueChanged = onValueChanged; // 恢复事件 slider.onValueChanged = onValueChanged;
Debug.Log($"更新Slider进度: {progress:F2}, Slider值: {slider.value}");
} }
} }
} }
if (hasAnimation.HasValue)
{
UpdatePlayButtonVisibility(hasAnimation.Value);
}
} }
// 应用程序退出时清理资源
private void OnApplicationQuit() private void OnApplicationQuit()
{ {
udpCts.Cancel(); // 通知UDP线程停止 udpCts.Cancel();
receiveCts.Cancel(); // 通知接收线程停止 receiveCts.Cancel();
if (udpThread != null && udpThread.IsAlive) if (udpThread != null && udpThread.IsAlive)
{ {
udpThread.Join(1000); // 等待UDP线程结束 udpThread.Join(1000);
} }
if (receiveThread != null && receiveThread.IsAlive) if (receiveThread != null && receiveThread.IsAlive)
{ {
receiveThread.Join(1000); // 等待接收线程结束 receiveThread.Join(1000);
} }
udpListener?.Close(); // 关闭UDP监听器 udpListener?.Close();
stream?.Close(); // 关闭TCP流 stream?.Close();
client?.Close(); // 关闭TCP客户端 client?.Close();
Debug.Log("触摸端客户端已停止"); }
private void OnDestroy()
{
OnApplicationQuit();
} }
} }

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,21 +0,0 @@
fileFormatVersion: 2
guid: 1756ec4a744794f49bc384cf92de4f97
TrueTypeFontImporter:
externalObjects: {}
serializedVersion: 4
fontSize: 16
forceTextureCase: -2
characterSpacing: 0
characterPadding: 1
includeFontData: 1
fontNames:
- Alibaba PuHuiTi 2.0
fallbackFontReferences: []
customCharacters:
fontRenderingMode: 0
ascentCalculationMode: 1
useLegacyBoundsCalculation: 0
shouldRoundAdvanceValue: 1
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,21 +0,0 @@
fileFormatVersion: 2
guid: 20729a5f21981634f83cec0f4575d37a
TrueTypeFontImporter:
externalObjects: {}
serializedVersion: 4
fontSize: 16
forceTextureCase: -2
characterSpacing: 0
characterPadding: 1
includeFontData: 1
fontNames:
- Alibaba PuHuiTi 2.0
fallbackFontReferences: []
customCharacters:
fontRenderingMode: 0
ascentCalculationMode: 1
useLegacyBoundsCalculation: 0
shouldRoundAdvanceValue: 1
userData:
assetBundleName:
assetBundleVariant:

View File

@ -12,11 +12,20 @@ EditorUserSettings:
value: 54035756510d5a0c095f0d7414760b4446154b782e7b7063752a1b62e7b5363b value: 54035756510d5a0c095f0d7414760b4446154b782e7b7063752a1b62e7b5363b
flags: 0 flags: 0
RecentlyUsedSceneGuid-2: RecentlyUsedSceneGuid-2:
value: 5303510050530a0a0e58087140210b44474f1a78742973637a2a4560b5b3656d value: 0204525104005f5f5e5d5526117b0b44424e4073752d2536747c1b31e7b3673c
flags: 0 flags: 0
RecentlyUsedSceneGuid-3: RecentlyUsedSceneGuid-3:
value: 02020157070050580c5b582340215c44464f4b297f7d7e64792d1c62b1e16269
flags: 0
RecentlyUsedSceneGuid-4:
value: 5550060701065c085e5c5924162609444f4f4b297e70226674284564b1b8326d
flags: 0
RecentlyUsedSceneGuid-5:
value: 5a5757560101590a5d0c0e24427b5d44434e4c7a7b7a23677f2b4565b7b5353a value: 5a5757560101590a5d0c0e24427b5d44434e4c7a7b7a23677f2b4565b7b5353a
flags: 0 flags: 0
RecentlyUsedSceneGuid-6:
value: 5303510050530a0a0e58087140210b44474f1a78742973637a2a4560b5b3656d
flags: 0
vcSharedLogLevel: vcSharedLogLevel:
value: 0d5e400f0650 value: 0d5e400f0650
flags: 0 flags: 0

View File

@ -17,14 +17,65 @@ MonoBehaviour:
x: 0 x: 0
y: 43.2 y: 43.2
width: 1536 width: 1536
height: 820.8 height: 772.8
m_ShowMode: 4 m_ShowMode: 4
m_Title: Game m_Title: Scene
m_RootView: {fileID: 2} m_RootView: {fileID: 4}
m_MinSize: {x: 875, y: 300} m_MinSize: {x: 875, y: 321}
m_MaxSize: {x: 10000, y: 10000} m_MaxSize: {x: 10000, y: 10000}
m_Maximized: 1 m_Maximized: 1
--- !u!114 &2 --- !u!114 &2
MonoBehaviour:
m_ObjectHideFlags: 52
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 12006, guid: 0000000000000000e000000000000000, type: 0}
m_Name: SceneHierarchyWindow
m_EditorClassIdentifier:
m_Children: []
m_Position:
serializedVersion: 2
x: 0
y: 0
width: 243.19995
height: 340.8
m_MinSize: {x: 202, y: 221}
m_MaxSize: {x: 4002, y: 4021}
m_ActualView: {fileID: 16}
m_Panes:
- {fileID: 16}
m_Selected: 0
m_LastSelected: 0
--- !u!114 &3
MonoBehaviour:
m_ObjectHideFlags: 52
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 12010, guid: 0000000000000000e000000000000000, type: 0}
m_Name:
m_EditorClassIdentifier:
m_Children:
- {fileID: 2}
- {fileID: 10}
m_Position:
serializedVersion: 2
x: 888
y: 0
width: 243.19995
height: 722.8
m_MinSize: {x: 100, y: 200}
m_MaxSize: {x: 8096, y: 16192}
vertical: 1
controlID: 44
--- !u!114 &4
MonoBehaviour: MonoBehaviour:
m_ObjectHideFlags: 52 m_ObjectHideFlags: 52
m_CorrespondingSourceObject: {fileID: 0} m_CorrespondingSourceObject: {fileID: 0}
@ -37,22 +88,22 @@ MonoBehaviour:
m_Name: m_Name:
m_EditorClassIdentifier: m_EditorClassIdentifier:
m_Children: m_Children:
- {fileID: 3}
- {fileID: 4}
- {fileID: 5} - {fileID: 5}
- {fileID: 6}
- {fileID: 7}
m_Position: m_Position:
serializedVersion: 2 serializedVersion: 2
x: 0 x: 0
y: 0 y: 0
width: 1536 width: 1536
height: 820.8 height: 772.8
m_MinSize: {x: 875, y: 300} m_MinSize: {x: 875, y: 300}
m_MaxSize: {x: 10000, y: 10000} m_MaxSize: {x: 10000, y: 10000}
m_UseTopView: 1 m_UseTopView: 1
m_TopViewHeight: 30 m_TopViewHeight: 30
m_UseBottomView: 1 m_UseBottomView: 1
m_BottomViewHeight: 20 m_BottomViewHeight: 20
--- !u!114 &3 --- !u!114 &5
MonoBehaviour: MonoBehaviour:
m_ObjectHideFlags: 52 m_ObjectHideFlags: 52
m_CorrespondingSourceObject: {fileID: 0} m_CorrespondingSourceObject: {fileID: 0}
@ -74,7 +125,7 @@ MonoBehaviour:
m_MinSize: {x: 0, y: 0} m_MinSize: {x: 0, y: 0}
m_MaxSize: {x: 0, y: 0} m_MaxSize: {x: 0, y: 0}
m_LastLoadedLayoutName: m_LastLoadedLayoutName:
--- !u!114 &4 --- !u!114 &6
MonoBehaviour: MonoBehaviour:
m_ObjectHideFlags: 52 m_ObjectHideFlags: 52
m_CorrespondingSourceObject: {fileID: 0} m_CorrespondingSourceObject: {fileID: 0}
@ -87,20 +138,20 @@ MonoBehaviour:
m_Name: m_Name:
m_EditorClassIdentifier: m_EditorClassIdentifier:
m_Children: m_Children:
- {fileID: 6}
- {fileID: 7}
- {fileID: 8} - {fileID: 8}
- {fileID: 3}
- {fileID: 9}
m_Position: m_Position:
serializedVersion: 2 serializedVersion: 2
x: 0 x: 0
y: 30 y: 30
width: 1536 width: 1536
height: 770.8 height: 722.8
m_MinSize: {x: 300, y: 200} m_MinSize: {x: 300, y: 200}
m_MaxSize: {x: 24288, y: 16192} m_MaxSize: {x: 24288, y: 16192}
vertical: 0 vertical: 0
controlID: 17 controlID: 97
--- !u!114 &5 --- !u!114 &7
MonoBehaviour: MonoBehaviour:
m_ObjectHideFlags: 52 m_ObjectHideFlags: 52
m_CorrespondingSourceObject: {fileID: 0} m_CorrespondingSourceObject: {fileID: 0}
@ -116,12 +167,12 @@ MonoBehaviour:
m_Position: m_Position:
serializedVersion: 2 serializedVersion: 2
x: 0 x: 0
y: 800.8 y: 752.8
width: 1536 width: 1536
height: 20 height: 20
m_MinSize: {x: 0, y: 0} m_MinSize: {x: 0, y: 0}
m_MaxSize: {x: 0, y: 0} m_MaxSize: {x: 0, y: 0}
--- !u!114 &6 --- !u!114 &8
MonoBehaviour: MonoBehaviour:
m_ObjectHideFlags: 52 m_ObjectHideFlags: 52
m_CorrespondingSourceObject: {fileID: 0} m_CorrespondingSourceObject: {fileID: 0}
@ -138,8 +189,8 @@ MonoBehaviour:
serializedVersion: 2 serializedVersion: 2
x: 0 x: 0
y: 0 y: 0
width: 854.4 width: 888
height: 770.8 height: 722.8
m_MinSize: {x: 201, y: 221} m_MinSize: {x: 201, y: 221}
m_MaxSize: {x: 4001, y: 4021} m_MaxSize: {x: 4001, y: 4021}
m_ActualView: {fileID: 15} m_ActualView: {fileID: 15}
@ -150,32 +201,7 @@ MonoBehaviour:
- {fileID: 11} - {fileID: 11}
m_Selected: 0 m_Selected: 0
m_LastSelected: 1 m_LastSelected: 1
--- !u!114 &7 --- !u!114 &9
MonoBehaviour:
m_ObjectHideFlags: 52
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 1
m_Script: {fileID: 12010, guid: 0000000000000000e000000000000000, type: 0}
m_Name:
m_EditorClassIdentifier:
m_Children:
- {fileID: 9}
- {fileID: 10}
m_Position:
serializedVersion: 2
x: 854.4
y: 0
width: 278.40002
height: 770.8
m_MinSize: {x: 100, y: 200}
m_MaxSize: {x: 8096, y: 16192}
vertical: 1
controlID: 55
--- !u!114 &8
MonoBehaviour: MonoBehaviour:
m_ObjectHideFlags: 52 m_ObjectHideFlags: 52
m_CorrespondingSourceObject: {fileID: 0} m_CorrespondingSourceObject: {fileID: 0}
@ -190,43 +216,17 @@ MonoBehaviour:
m_Children: [] m_Children: []
m_Position: m_Position:
serializedVersion: 2 serializedVersion: 2
x: 1132.8 x: 1131.2
y: 0 y: 0
width: 403.19995 width: 404.80005
height: 770.8 height: 722.8
m_MinSize: {x: 275, y: 50} m_MinSize: {x: 276, y: 71}
m_MaxSize: {x: 4000, y: 4000} m_MaxSize: {x: 4001, y: 4021}
m_ActualView: {fileID: 13} m_ActualView: {fileID: 13}
m_Panes: m_Panes:
- {fileID: 13} - {fileID: 13}
m_Selected: 0 m_Selected: 0
m_LastSelected: 0 m_LastSelected: 0
--- !u!114 &9
MonoBehaviour:
m_ObjectHideFlags: 52
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 1
m_Script: {fileID: 12006, guid: 0000000000000000e000000000000000, type: 0}
m_Name:
m_EditorClassIdentifier:
m_Children: []
m_Position:
serializedVersion: 2
x: 0
y: 0
width: 278.40002
height: 341.6
m_MinSize: {x: 200, y: 200}
m_MaxSize: {x: 4000, y: 4000}
m_ActualView: {fileID: 16}
m_Panes:
- {fileID: 16}
m_Selected: 0
m_LastSelected: 0
--- !u!114 &10 --- !u!114 &10
MonoBehaviour: MonoBehaviour:
m_ObjectHideFlags: 52 m_ObjectHideFlags: 52
@ -243,9 +243,9 @@ MonoBehaviour:
m_Position: m_Position:
serializedVersion: 2 serializedVersion: 2
x: 0 x: 0
y: 341.6 y: 340.8
width: 278.40002 width: 243.19995
height: 429.19998 height: 382
m_MinSize: {x: 232, y: 271} m_MinSize: {x: 232, y: 271}
m_MaxSize: {x: 10002, y: 10021} m_MaxSize: {x: 10002, y: 10021}
m_ActualView: {fileID: 14} m_ActualView: {fileID: 14}
@ -284,7 +284,7 @@ MonoBehaviour:
m_OverlaysVisible: 1 m_OverlaysVisible: 1
m_LockTracker: m_LockTracker:
m_IsLocked: 0 m_IsLocked: 0
m_LastSelectedObjectID: 162098 m_LastSelectedObjectID: 3226668
--- !u!114 &12 --- !u!114 &12
MonoBehaviour: MonoBehaviour:
m_ObjectHideFlags: 52 m_ObjectHideFlags: 52
@ -307,8 +307,8 @@ MonoBehaviour:
serializedVersion: 2 serializedVersion: 2
x: 0 x: 0
y: 73.6 y: 73.6
width: 853.4 width: 1183
height: 749.8 height: 989.80005
m_ViewDataDictionary: {fileID: 0} m_ViewDataDictionary: {fileID: 0}
m_OverlayCanvas: m_OverlayCanvas:
m_LastAppliedPresetName: Default m_LastAppliedPresetName: Default
@ -321,6 +321,7 @@ MonoBehaviour:
- {fileID: -5493858010228640296, guid: da2d18bdd63eddf4db4344988663132b, type: 2} - {fileID: -5493858010228640296, guid: da2d18bdd63eddf4db4344988663132b, type: 2}
- {fileID: -5073058742846949024, guid: 9a5ed5f9dc25f9b498cfc53347cb4567, type: 2} - {fileID: -5073058742846949024, guid: 9a5ed5f9dc25f9b498cfc53347cb4567, type: 2}
- {fileID: -2230655706508628860, guid: c06c13b013fc9334096e1edcfb15e759, type: 2} - {fileID: -2230655706508628860, guid: c06c13b013fc9334096e1edcfb15e759, type: 2}
- {fileID: 0}
m_ValueSerializationHelper: m_ValueSerializationHelper:
- e00: 1 - e00: 1
e01: 0 e01: 0
@ -402,10 +403,26 @@ MonoBehaviour:
e31: 0 e31: 0
e32: 0 e32: 0
e33: 1 e33: 1
- e00: 1
e01: 0
e02: 0
e03: 0
e10: 0
e11: 1
e12: 0
e13: 0
e20: 0
e21: 0
e22: 1
e23: 0
e30: 0
e31: 0
e32: 0
e33: 1
m_PreviewAnimator: {fileID: 0} m_PreviewAnimator: {fileID: 0}
m_AnimatorController: {fileID: 9100000, guid: c06c13b013fc9334096e1edcfb15e759, type: 2} m_AnimatorController: {fileID: 0}
m_BreadCrumbs: m_BreadCrumbs:
- m_Target: {fileID: -2230655706508628860, guid: c06c13b013fc9334096e1edcfb15e759, type: 2} - m_Target: {fileID: 0}
m_ScrollPosition: {x: 0, y: 0} m_ScrollPosition: {x: 0, y: 0}
stateMachineGraph: {fileID: 0} stateMachineGraph: {fileID: 0}
stateMachineGraphGUI: {fileID: 0} stateMachineGraphGUI: {fileID: 0}
@ -438,10 +455,10 @@ MonoBehaviour:
m_Tooltip: m_Tooltip:
m_Pos: m_Pos:
serializedVersion: 2 serializedVersion: 2
x: 1132.8 x: 1131.2001
y: 73.6 y: 73.6
width: 402.19995 width: 403.80005
height: 749.8 height: 701.8
m_ViewDataDictionary: {fileID: 0} m_ViewDataDictionary: {fileID: 0}
m_OverlayCanvas: m_OverlayCanvas:
m_LastAppliedPresetName: Default m_LastAppliedPresetName: Default
@ -480,10 +497,10 @@ MonoBehaviour:
m_Tooltip: m_Tooltip:
m_Pos: m_Pos:
serializedVersion: 2 serializedVersion: 2
x: 854.4 x: 888
y: 415.2 y: 414.4
width: 276.40002 width: 241.19995
height: 408.19998 height: 361
m_ViewDataDictionary: {fileID: 0} m_ViewDataDictionary: {fileID: 0}
m_OverlayCanvas: m_OverlayCanvas:
m_LastAppliedPresetName: Default m_LastAppliedPresetName: Default
@ -500,7 +517,7 @@ MonoBehaviour:
m_SkipHidden: 0 m_SkipHidden: 0
m_SearchArea: 1 m_SearchArea: 1
m_Folders: m_Folders:
- Assets/Scenes - Assets/Resources
m_Globs: [] m_Globs: []
m_OriginalText: m_OriginalText:
m_FilterByTypeIntersection: 0 m_FilterByTypeIntersection: 0
@ -515,7 +532,7 @@ MonoBehaviour:
scrollPos: {x: 0, y: 0} scrollPos: {x: 0, y: 0}
m_SelectedIDs: 7c780000 m_SelectedIDs: 7c780000
m_LastClickedID: 30844 m_LastClickedID: 30844
m_ExpandedIDs: 00000000d6ac0100d8ac0100daac0100dcac0100deac0100e0ac0100e2ac0100e4ac0100e6ac0100e8ac0100eaac0100ecac0100eeac0100 m_ExpandedIDs: 0000000006b3010008b301000ab301000cb301000eb3010010b3010012b3010014b3010016b3010018b301001ab301001cb301001eb30100
m_RenameOverlay: m_RenameOverlay:
m_UserAcceptedRename: 0 m_UserAcceptedRename: 0
m_Name: m_Name:
@ -540,10 +557,10 @@ MonoBehaviour:
m_Icon: {fileID: 0} m_Icon: {fileID: 0}
m_ResourceFile: m_ResourceFile:
m_AssetTreeState: m_AssetTreeState:
scrollPos: {x: 0, y: 0} scrollPos: {x: 0, y: 369}
m_SelectedIDs: m_SelectedIDs:
m_LastClickedID: 0 m_LastClickedID: 0
m_ExpandedIDs: ffffffff00000000d6ac0100d8ac0100daac0100dcac0100deac0100e0ac0100e2ac0100e4ac0100eaac0100944d0900 m_ExpandedIDs: ffffffff0000000006b3010008b301000ab301000cb301000eb3010010b3010012b3010014b3010016b3010018b301001cb301001eb3010068b3010060b80100
m_RenameOverlay: m_RenameOverlay:
m_UserAcceptedRename: 0 m_UserAcceptedRename: 0
m_Name: m_Name:
@ -621,8 +638,8 @@ MonoBehaviour:
serializedVersion: 2 serializedVersion: 2
x: 0 x: 0
y: 73.6 y: 73.6
width: 853.4 width: 887
height: 749.8 height: 701.8
m_ViewDataDictionary: {fileID: 0} m_ViewDataDictionary: {fileID: 0}
m_OverlayCanvas: m_OverlayCanvas:
m_LastAppliedPresetName: Default m_LastAppliedPresetName: Default
@ -632,8 +649,8 @@ MonoBehaviour:
floating: 0 floating: 0
collapsed: 0 collapsed: 0
displayed: 1 displayed: 1
snapOffset: {x: -100, y: -25.600006} snapOffset: {x: -101, y: -26}
snapOffsetDelta: {x: 0, y: 0.000030517578} snapOffsetDelta: {x: 0, y: 0}
snapCorner: 3 snapCorner: 3
id: Tool Settings id: Tool Settings
index: 0 index: 0
@ -869,9 +886,9 @@ MonoBehaviour:
m_PlayAudio: 0 m_PlayAudio: 0
m_AudioPlay: 0 m_AudioPlay: 0
m_Position: m_Position:
m_Target: {x: 944.95264, y: 582.91113, z: 2.357466} m_Target: {x: 682.3883, y: 647.0643, z: 4.6536684}
speed: 2 speed: 2
m_Value: {x: 944.95264, y: 582.91113, z: 2.357466} m_Value: {x: 706.0194, y: 641.32666, z: 4.927581}
m_RenderMode: 0 m_RenderMode: 0
m_CameraMode: m_CameraMode:
drawMode: 0 drawMode: 0
@ -922,9 +939,9 @@ MonoBehaviour:
speed: 2 speed: 2
m_Value: {x: 0, y: 0, z: 0, w: 1} m_Value: {x: 0, y: 0, z: 0, w: 1}
m_Size: m_Size:
m_Target: 866.09686 m_Target: 636.08655
speed: 2 speed: 2
m_Value: 866.09686 m_Value: 608.69525
m_Ortho: m_Ortho:
m_Target: 1 m_Target: 1
speed: 2 speed: 2
@ -969,10 +986,10 @@ MonoBehaviour:
m_Tooltip: m_Tooltip:
m_Pos: m_Pos:
serializedVersion: 2 serializedVersion: 2
x: 854.4 x: 888
y: 73.6 y: 73.6
width: 276.40002 width: 241.19995
height: 320.6 height: 319.8
m_ViewDataDictionary: {fileID: 0} m_ViewDataDictionary: {fileID: 0}
m_OverlayCanvas: m_OverlayCanvas:
m_LastAppliedPresetName: Default m_LastAppliedPresetName: Default
@ -980,26 +997,26 @@ MonoBehaviour:
m_OverlaysVisible: 1 m_OverlaysVisible: 1
m_SceneHierarchy: m_SceneHierarchy:
m_TreeViewState: m_TreeViewState:
scrollPos: {x: 0, y: 0} scrollPos: {x: 0, y: 53.200012}
m_SelectedIDs: 38ad0100 m_SelectedIDs: ecb50100
m_LastClickedID: 0 m_LastClickedID: 112108
m_ExpandedIDs: 24aef9ff6caef9ff54aff9ffa8aff9ffe0b0f9ff4cb2f9ff5671faffa630fbffa231fbffbcf1fbfff008fcff56cafcffdad6fcffc4e5fcff06e6fcff46e7fcff66ecfcffa8ecfcffecedfcff5cadfdffeaadfdfffc73feff9675fefffc36ffff7a37ffff08fbffff8ab20100c8fb0700ee210800f4340800e6530800a65508003e560800ea4d0900ee4d0900044e0900304e09003c4e0900404e0900064f09001c4f0900ae4f0900ba4f0900be4f0900f44f090032500900c2500900265109005c51090070510900a45109006c5709007057090086570900be570900c25709009e580900f65809004459090048590900865909009a590900c4590900f2590900285a0900c85a0900fe5a0900025b0900125b0900465b09000a6009005260090094600900c06009003a610900d06409001865090094650900dc6509001e6609002666090000680900c06909002a6a0900ec6a0900966b0900de6b0900 m_ExpandedIDs: 8438ffff08fbffffceb30100d2b3010054b40100eab4010084b50100ecb50100b0b70100bcb70100
m_RenameOverlay: m_RenameOverlay:
m_UserAcceptedRename: 0 m_UserAcceptedRename: 0
m_Name: "SPECT\u7CFB\u7EDF" m_Name:
m_OriginalName: "SPECT\u7CFB\u7EDF" m_OriginalName:
m_EditFieldRect: m_EditFieldRect:
serializedVersion: 2 serializedVersion: 2
x: 0 x: 0
y: 0 y: 0
width: 0 width: 0
height: 0 height: 0
m_UserData: 614482 m_UserData: 0
m_IsWaitingForDelay: 0 m_IsWaitingForDelay: 0
m_IsRenaming: 0 m_IsRenaming: 0
m_OriginalEventType: 0 m_OriginalEventType: 11
m_IsRenamingFilename: 0 m_IsRenamingFilename: 0
m_ClientGUIView: {fileID: 9} m_ClientGUIView: {fileID: 2}
m_SearchString: m_SearchString:
m_ExpandedScenes: [] m_ExpandedScenes: []
m_CurrenRootInstanceID: 0 m_CurrenRootInstanceID: 0
@ -1029,8 +1046,8 @@ MonoBehaviour:
serializedVersion: 2 serializedVersion: 2
x: 0 x: 0
y: 73.6 y: 73.6
width: 853.4 width: 887
height: 749.8 height: 701.8
m_ViewDataDictionary: {fileID: 0} m_ViewDataDictionary: {fileID: 0}
m_OverlayCanvas: m_OverlayCanvas:
m_LastAppliedPresetName: Default m_LastAppliedPresetName: Default
@ -1044,7 +1061,7 @@ MonoBehaviour:
m_ShowGizmos: 0 m_ShowGizmos: 0
m_TargetDisplay: 0 m_TargetDisplay: 0
m_ClearColor: {r: 0, g: 0, b: 0, a: 0} m_ClearColor: {r: 0, g: 0, b: 0, a: 0}
m_TargetSize: {x: 3328, y: 1352} m_TargetSize: {x: 1920, y: 1080}
m_TextureFilterMode: 0 m_TextureFilterMode: 0
m_TextureHideFlags: 61 m_TextureHideFlags: 61
m_RenderIMGUI: 1 m_RenderIMGUI: 1
@ -1053,16 +1070,16 @@ MonoBehaviour:
m_VSyncEnabled: 0 m_VSyncEnabled: 0
m_Gizmos: 0 m_Gizmos: 0
m_Stats: 0 m_Stats: 0
m_SelectedSizes: 08000000000000000000000012000000000000000000000000000000000000000000000000000000 m_SelectedSizes: 03000000000000000000000012000000000000000000000000000000000000000000000000000000
m_ZoomArea: m_ZoomArea:
m_HRangeLocked: 0 m_HRangeLocked: 0
m_VRangeLocked: 0 m_VRangeLocked: 0
hZoomLockedByDefault: 0 hZoomLockedByDefault: 0
vZoomLockedByDefault: 0 vZoomLockedByDefault: 0
m_HBaseRangeMin: -1331.2001 m_HBaseRangeMin: -768
m_HBaseRangeMax: 1331.2001 m_HBaseRangeMax: 768
m_VBaseRangeMin: -540.8 m_VBaseRangeMin: -432
m_VBaseRangeMax: 540.8 m_VBaseRangeMax: 432
m_HAllowExceedBaseRangeMin: 1 m_HAllowExceedBaseRangeMin: 1
m_HAllowExceedBaseRangeMax: 1 m_HAllowExceedBaseRangeMax: 1
m_VAllowExceedBaseRangeMin: 1 m_VAllowExceedBaseRangeMin: 1
@ -1071,7 +1088,7 @@ MonoBehaviour:
m_HSlider: 0 m_HSlider: 0
m_VSlider: 0 m_VSlider: 0
m_IgnoreScrollWheelUntilClicked: 0 m_IgnoreScrollWheelUntilClicked: 0
m_EnableMouseInput: 0 m_EnableMouseInput: 1
m_EnableSliderZoomHorizontal: 0 m_EnableSliderZoomHorizontal: 0
m_EnableSliderZoomVertical: 0 m_EnableSliderZoomVertical: 0
m_UniformScale: 1 m_UniformScale: 1
@ -1080,23 +1097,23 @@ MonoBehaviour:
serializedVersion: 2 serializedVersion: 2
x: 0 x: 0
y: 21 y: 21
width: 853.4 width: 887
height: 728.8 height: 680.8
m_Scale: {x: 0.32053787, y: 0.32053787} m_Scale: {x: 0.57747394, y: 0.57747394}
m_Translation: {x: 426.70004, y: 364.4} m_Translation: {x: 443.5, y: 340.4}
m_MarginLeft: 0 m_MarginLeft: 0
m_MarginRight: 0 m_MarginRight: 0
m_MarginTop: 0 m_MarginTop: 0
m_MarginBottom: 0 m_MarginBottom: 0
m_LastShownAreaInsideMargins: m_LastShownAreaInsideMargins:
serializedVersion: 2 serializedVersion: 2
x: -1331.2001 x: -768
y: -1136.8391 y: -589.4638
width: 2662.4001 width: 1536
height: 2273.6782 height: 1178.9276
m_MinimalGUI: 1 m_MinimalGUI: 1
m_defaultScale: 0.32053787 m_defaultScale: 0.57747394
m_LastWindowPixelSize: {x: 1066.75, y: 937.25} m_LastWindowPixelSize: {x: 1108.75, y: 877.25}
m_ClearInEditMode: 1 m_ClearInEditMode: 1
m_NoCameraWarning: 1 m_NoCameraWarning: 1
m_LowResolutionForAspectRatios: 00000000000000000000 m_LowResolutionForAspectRatios: 00000000000000000000