除了模型内部小模型的相关功能,其他基本实现

This commit is contained in:
XgC2961 2025-08-30 17:15:31 +08:00
parent 155ccca1fc
commit 8c369e7875
8 changed files with 969 additions and 203 deletions

View File

@ -410,6 +410,82 @@ CanvasRenderer:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 43981641}
m_CullTransparentMesh: 1
--- !u!1 &48735984
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 48735985}
- component: {fileID: 48735987}
- component: {fileID: 48735986}
m_Layer: 5
m_Name: Image
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &48735985
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 48735984}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 670112917}
m_RootOrder: 2
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: -305.52002, y: 29}
m_SizeDelta: {x: 837.2433, y: 711.0466}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &48735986
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 48735984}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_Sprite: {fileID: 21300000, guid: 06a7925cedc9fb342bba656e0056d2ab, type: 3}
m_Type: 0
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
m_UseSpriteMesh: 0
m_PixelsPerUnitMultiplier: 1
--- !u!222 &48735987
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 48735984}
m_CullTransparentMesh: 1
--- !u!1 &50686162
GameObject:
m_ObjectHideFlags: 0
@ -444,7 +520,7 @@ RectTransform:
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 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_SizeDelta: {x: 10, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
@ -1208,7 +1284,7 @@ RectTransform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: -481, y: 175.8695}
m_AnchoredPosition: {x: -321, y: 208}
m_SizeDelta: {x: 514.5018, y: 206.6469}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &136777286
@ -1744,7 +1820,7 @@ MonoBehaviour:
m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
m_IntArgument: 0
m_FloatArgument: 0
m_StringArgument: SPCET
m_StringArgument: SPECT
m_BoolArgument: 0
m_CallState: 2
--- !u!114 &251007919
@ -1800,7 +1876,7 @@ GameObject:
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
m_IsActive: 0
--- !u!224 &255454897
RectTransform:
m_ObjectHideFlags: 0
@ -1987,6 +2063,7 @@ RectTransform:
m_Children:
- {fileID: 572656642}
- {fileID: 43981642}
- {fileID: 1977217322}
m_Father: {fileID: 918998978}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
@ -2068,7 +2145,7 @@ RectTransform:
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 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_SizeDelta: {x: 64.1366, y: 15.9954}
m_Pivot: {x: 0.5, y: 0.5}
@ -2220,7 +2297,7 @@ RectTransform:
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 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_SizeDelta: {x: 10, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
@ -3827,7 +3904,7 @@ RectTransform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: 363, y: 223}
m_AnchoredPosition: {x: 377, y: 225}
m_SizeDelta: {x: 514.5018, y: 206.6469}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &525806970
@ -4574,6 +4651,7 @@ RectTransform:
m_Children:
- {fileID: 1860432183}
- {fileID: 513613887}
- {fileID: 48735985}
m_Father: {fileID: 1993840782}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
@ -5734,7 +5812,7 @@ RectTransform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: 363, y: 223}
m_AnchoredPosition: {x: 230, y: 117}
m_SizeDelta: {x: 514.5018, y: 206.6469}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &786848181
@ -6503,6 +6581,82 @@ RectTransform:
m_AnchoredPosition: {x: 274, y: 0}
m_SizeDelta: {x: 100, y: 100}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!1 &921334617
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 921334618}
- component: {fileID: 921334620}
- component: {fileID: 921334619}
m_Layer: 5
m_Name: Image
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &921334618
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 921334617}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 925071639}
m_RootOrder: 2
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: -305.52002, y: 29}
m_SizeDelta: {x: 777.6503, y: 711.0466}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &921334619
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 921334617}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_Sprite: {fileID: 21300000, guid: d79738a6c52343b44a55bdf62be39b81, type: 3}
m_Type: 0
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
m_UseSpriteMesh: 0
m_PixelsPerUnitMultiplier: 1
--- !u!222 &921334620
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 921334617}
m_CullTransparentMesh: 1
--- !u!1 &924486752
GameObject:
m_ObjectHideFlags: 0
@ -6609,6 +6763,7 @@ RectTransform:
m_Children:
- {fileID: 1823607146}
- {fileID: 2084109300}
- {fileID: 921334618}
m_Father: {fileID: 265220017}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
@ -6647,6 +6802,7 @@ RectTransform:
m_Children:
- {fileID: 455149566}
- {fileID: 19634140}
- {fileID: 1027992136}
m_Father: {fileID: 2030878213}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
@ -7056,6 +7212,82 @@ CanvasRenderer:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1017476018}
m_CullTransparentMesh: 1
--- !u!1 &1027992135
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1027992136}
- component: {fileID: 1027992138}
- component: {fileID: 1027992137}
m_Layer: 5
m_Name: Image
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &1027992136
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1027992135}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 929441351}
m_RootOrder: 2
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: -305.52002, y: 29}
m_SizeDelta: {x: 770.6393, y: 711.0466}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &1027992137
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1027992135}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_Sprite: {fileID: 21300000, guid: 4128e5be2f7705c4bb89142ba7613763, type: 3}
m_Type: 0
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
m_UseSpriteMesh: 0
m_PixelsPerUnitMultiplier: 1
--- !u!222 &1027992138
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1027992135}
m_CullTransparentMesh: 1
--- !u!1 &1038119848
GameObject:
m_ObjectHideFlags: 0
@ -7389,6 +7621,7 @@ RectTransform:
m_Children:
- {fileID: 377162543}
- {fileID: 1532282807}
- {fileID: 1386227495}
m_Father: {fileID: 103809607}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
@ -8009,7 +8242,7 @@ RectTransform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: -481, y: 175.8695}
m_AnchoredPosition: {x: -129, y: 199.68}
m_SizeDelta: {x: 514.5018, y: 206.6469}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &1241545787
@ -8080,6 +8313,7 @@ RectTransform:
m_Children:
- {fileID: 2141868100}
- {fileID: 133472278}
- {fileID: 1735552335}
m_Father: {fileID: 255454897}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
@ -8122,7 +8356,7 @@ RectTransform:
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 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_SizeDelta: {x: 64.1366, y: 15.9954}
m_Pivot: {x: 0.5, y: 0.5}
@ -8164,6 +8398,82 @@ CanvasRenderer:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1344060740}
m_CullTransparentMesh: 1
--- !u!1 &1386227494
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1386227495}
- component: {fileID: 1386227497}
- component: {fileID: 1386227496}
m_Layer: 5
m_Name: Image
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &1386227495
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1386227494}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 1094783814}
m_RootOrder: 2
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: -305.52002, y: 29}
m_SizeDelta: {x: 784.6608, y: 711.0466}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &1386227496
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1386227494}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_Sprite: {fileID: 21300000, guid: 8dfb019405a9df5458a1ea59f74d69f0, type: 3}
m_Type: 0
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
m_UseSpriteMesh: 0
m_PixelsPerUnitMultiplier: 1
--- !u!222 &1386227497
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1386227494}
m_CullTransparentMesh: 1
--- !u!1 &1404202990
GameObject:
m_ObjectHideFlags: 0
@ -9158,7 +9468,7 @@ RectTransform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: -481, y: -115}
m_AnchoredPosition: {x: -341, y: -88}
m_SizeDelta: {x: 514.5018, y: 206.6469}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &1523039012
@ -10560,6 +10870,82 @@ CanvasRenderer:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1730454321}
m_CullTransparentMesh: 1
--- !u!1 &1735552334
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1735552335}
- component: {fileID: 1735552337}
- component: {fileID: 1735552336}
m_Layer: 5
m_Name: Image
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &1735552335
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1735552334}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 1320089738}
m_RootOrder: 2
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: -305.52, y: 29}
m_SizeDelta: {x: 767.134, y: 711.0466}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &1735552336
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1735552334}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_Sprite: {fileID: 21300000, guid: ff17adbb54a289e49adea8c1ea6d140e, type: 3}
m_Type: 0
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
m_UseSpriteMesh: 0
m_PixelsPerUnitMultiplier: 1
--- !u!222 &1735552337
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1735552334}
m_CullTransparentMesh: 1
--- !u!1 &1760454589
GameObject:
m_ObjectHideFlags: 0
@ -11645,6 +12031,82 @@ RectTransform:
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: -20, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!1 &1977217321
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1977217322}
- component: {fileID: 1977217324}
- component: {fileID: 1977217323}
m_Layer: 5
m_Name: Image
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &1977217322
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1977217321}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 262629455}
m_RootOrder: 2
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: -273, y: 67}
m_SizeDelta: {x: 1070.5859, y: 741.1071}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &1977217323
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1977217321}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_Sprite: {fileID: 21300000, guid: 8fa3ee495f087284b964ab916af72b29, type: 3}
m_Type: 0
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
m_UseSpriteMesh: 0
m_PixelsPerUnitMultiplier: 1
--- !u!222 &1977217324
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1977217321}
m_CullTransparentMesh: 1
--- !u!1 &1993840781
GameObject:
m_ObjectHideFlags: 0
@ -11660,7 +12122,7 @@ GameObject:
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 0
m_IsActive: 1
--- !u!224 &1993840782
RectTransform:
m_ObjectHideFlags: 0
@ -11720,7 +12182,7 @@ RectTransform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: -481, y: -115}
m_AnchoredPosition: {x: -602, y: 172}
m_SizeDelta: {x: 514.5018, y: 206.6469}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &2010142716
@ -12410,7 +12872,7 @@ RectTransform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: 363, y: 223}
m_AnchoredPosition: {x: 485, y: 172}
m_SizeDelta: {x: 514.5018, y: 206.6469}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &2105199687

View File

@ -986,6 +986,7 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: c86ed53e8144b2b4781bab9d7e73c21e, type: 3}
m_Name:
m_EditorClassIdentifier:
defaultAnimName: Take 001
--- !u!1 &478718344
GameObject:
m_ObjectHideFlags: 0
@ -1650,6 +1651,7 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: c86ed53e8144b2b4781bab9d7e73c21e, type: 3}
m_Name:
m_EditorClassIdentifier:
defaultAnimName: Take 001
--- !u!1 &705507993
GameObject:
m_ObjectHideFlags: 0
@ -2150,6 +2152,7 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: c86ed53e8144b2b4781bab9d7e73c21e, type: 3}
m_Name:
m_EditorClassIdentifier:
defaultAnimName: Take 001
--- !u!1 &1146716130
GameObject:
m_ObjectHideFlags: 0
@ -2630,7 +2633,7 @@ MonoBehaviour:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 0
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
@ -2784,6 +2787,7 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: c86ed53e8144b2b4781bab9d7e73c21e, type: 3}
m_Name:
m_EditorClassIdentifier:
defaultAnimName: Take 001
--- !u!1 &1648561990
GameObject:
m_ObjectHideFlags: 0
@ -3291,6 +3295,7 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: c86ed53e8144b2b4781bab9d7e73c21e, type: 3}
m_Name:
m_EditorClassIdentifier:
defaultAnimName: Take 001
--- !u!1 &2116398279
GameObject:
m_ObjectHideFlags: 0

View File

@ -15,13 +15,19 @@ public class BroadcastServer : MonoBehaviour
// 脚本启动时调用
void Start()
{
udpClient = new UdpClient();
udpClient.EnableBroadcast = true;
// 启动广播线程
broadcastThread = new Thread(BroadcastIP);
broadcastThread.Start();
Debug.Log("广播服务器已启动");
try
{
udpClient = new UdpClient();
udpClient.EnableBroadcast = true;
// 启动广播线程
broadcastThread = new Thread(BroadcastIP);
broadcastThread.Start();
Debug.Log("广播服务器已启动,端口: 9999");
}
catch (Exception ex)
{
Debug.LogError($"初始化UDP客户端失败: {ex.Message}");
}
}
// 广播显示端服务器的IP地址
@ -30,13 +36,13 @@ public class BroadcastServer : MonoBehaviour
string localIP = GetLocalIPAddress();
if (string.IsNullOrEmpty(localIP))
{
Debug.LogError("无法获取本地IP地址");
Debug.LogError("无法获取本地IP地址,广播停止");
return;
}
string message = $"ServerIP:{localIP}";
byte[] data = Encoding.UTF8.GetBytes(message);
IPEndPoint endPoint = new IPEndPoint(IPAddress.Broadcast, 8887);
IPEndPoint endPoint = new IPEndPoint(IPAddress.Broadcast, 9999); // 修改为9999
while (isRunning)
{
@ -49,34 +55,43 @@ public class BroadcastServer : MonoBehaviour
catch (Exception ex)
{
Debug.LogError($"广播错误: {ex.Message}");
Thread.Sleep(5000); // 出错后等待5秒重试
}
}
}
// 获取本地IP地址
// 获取本地IP地址,排除回环地址
private string GetLocalIPAddress()
{
try
{
foreach (var networkInterface in NetworkInterface.GetAllNetworkInterfaces())
{
if (networkInterface.OperationalStatus == OperationalStatus.Up)
if (networkInterface.OperationalStatus == OperationalStatus.Up &&
networkInterface.NetworkInterfaceType != NetworkInterfaceType.Loopback)
{
foreach (var unicastIPAddress in networkInterface.GetIPProperties().UnicastAddresses)
{
if (unicastIPAddress.Address.AddressFamily == AddressFamily.InterNetwork)
{
return unicastIPAddress.Address.ToString();
string ip = unicastIPAddress.Address.ToString();
if (!ip.StartsWith("127."))
{
Debug.Log($"选择IP: {ip} (接口: {networkInterface.Name})");
return ip;
}
}
}
}
}
Debug.LogError("未找到有效的IPv4地址");
return "";
}
catch (Exception ex)
{
Debug.LogError($"获取IP地址错误: {ex.Message}");
return "";
}
return "";
}
// 应用程序退出时清理资源
@ -88,5 +103,6 @@ public class BroadcastServer : MonoBehaviour
{
broadcastThread.Join(1000); // 等待线程结束
}
Debug.Log("广播服务器已停止");
}
}

View File

@ -1,11 +1,11 @@
using UnityEngine;
using UnityEngine.UI;
using System.Net.Sockets;
using System.Net;
using System.Text;
using System.Threading;
using System.Collections.Generic;
using System;
using UnityEngine.UI;
public class DisplayServer : MonoBehaviour
{
@ -15,7 +15,7 @@ public class DisplayServer : MonoBehaviour
private volatile bool isRunning = true; // 线程安全的服务器循环标志
private NetworkStream clientStream; // 当前客户端的网络流,用于发送消息
public Transform background; // UI页面的父级变换
public Transform background; // UI页面的父级变换BG包含Image组件
[System.Serializable]
public class PageModel
@ -54,11 +54,24 @@ public class DisplayServer : MonoBehaviour
{
pageModelCache[pm.pageName] = pm;
}
else
{
Debug.LogWarning($"PageModel 配置错误: pageName={pm.pageName}, model={(pm.model != null ? pm.model.name : "null")}");
}
}
// 在端口8888上启动TCP监听
listener = new TcpListener(IPAddress.Any, 8888);
listener.Start();
try
{
listener = new TcpListener(IPAddress.Any, 8888);
listener.Start();
Debug.Log("TCP监听启动成功端口: 8888");
}
catch (Exception ex)
{
Debug.LogError($"TCP监听启动失败: {ex.Message}");
return;
}
// 启动线程以监听客户端连接
listenThread = new Thread(() => ListenForClients(listenCts.Token));
@ -78,7 +91,7 @@ public class DisplayServer : MonoBehaviour
try
{
TcpClient client = listener.AcceptTcpClient();
Debug.Log("触摸端已连接!");
Debug.Log($"触摸端已连接!客户端地址: {((IPEndPoint)client.Client.RemoteEndPoint).Address}");
clientStream = client.GetStream(); // 保存客户端流以发送消息
// 为每个客户端启动新线程处理通信
Thread clientThread = new Thread(() => HandleClientComm(client, token));
@ -87,6 +100,7 @@ public class DisplayServer : MonoBehaviour
catch (Exception ex)
{
Debug.LogError($"接受客户端连接错误: {ex.Message}");
Thread.Sleep(2000); // 等待2秒重试
}
}
}
@ -229,9 +243,17 @@ public class DisplayServer : MonoBehaviour
// 切换激活的UI页面并更新模型
private void ShowPage(string pageName)
{
if (background == null)
{
Debug.LogError("背景Transform未设置");
return;
}
foreach (Transform child in background)
{
child.gameObject.SetActive(child.name == pageName); // 仅激活目标页面
bool isActive = child.name == pageName;
child.gameObject.SetActive(isActive);
Debug.Log($"页面 {child.name} 设置为 {(isActive ? "" : "")}");
}
currentPage = pageName;
@ -257,6 +279,10 @@ public class DisplayServer : MonoBehaviour
mc.ResetAnimation();
Debug.Log($"模型 {pageModel.model.name} 重置,页面: {pageName}");
}
else
{
Debug.LogWarning($"模型 {pageModel.model.name} 未找到ModelController");
}
}
}
@ -307,6 +333,10 @@ public class DisplayServer : MonoBehaviour
mc.SetAnimationProgress(progress);
Debug.Log($"设置模型 {pm.model.name} 进度: {progress:F2}");
}
else
{
Debug.LogWarning($"模型 {pm.model.name} 未找到ModelController");
}
}
else
{
@ -317,12 +347,16 @@ public class DisplayServer : MonoBehaviour
// 设置当前页面文字面板的显隐
private void SetTextPanelVisibility(bool isVisible)
{
if (background == null || currentPage == "首页") return;
if (background == null || string.IsNullOrEmpty(currentPage) || currentPage == "首页")
{
Debug.Log($"跳过文字面板显隐设置: background={(background != null ? "" : "null")}, currentPage={currentPage}");
return;
}
Transform pageTransform = background.Find(currentPage);
if (pageTransform != null)
{
Transform textPanel = pageTransform.Find("TextPanel");
Transform textPanel = pageTransform.Find("ItemInfo/TextPanel");
if (textPanel != null)
{
textPanel.gameObject.SetActive(isVisible);
@ -330,49 +364,93 @@ public class DisplayServer : MonoBehaviour
}
else
{
Debug.LogWarning($"未在页面 {currentPage} 找到TextPanel");
}
}
else
{
Debug.LogWarning($"未找到页面 {currentPage}");
}
}
// 设置当前页面背景的Sprite
private void SetBackgroundSprite(bool hasText)
{
if (background == null || currentPage == "首页") return;
Transform pageTransform = background.Find(currentPage);
if (pageTransform != null)
{
Transform backgroundTransform = pageTransform.Find("PageBackground");
if (backgroundTransform != null)
{
Image backgroundImage = backgroundTransform.GetComponent<Image>();
if (backgroundImage != null)
Debug.LogWarning($"未在页面 {currentPage}/ItemInfo 找到TextPanel");
// 尝试递归查找
textPanel = FindDeep(pageTransform, "TextPanel");
if (textPanel != null)
{
Sprite newSprite = hasText ? textBackgroundSprite : noTextBackgroundSprite;
backgroundImage.sprite = newSprite;
Debug.Log($"设置页面 {currentPage} 背景: {(newSprite != null ? newSprite.name : "null")}");
textPanel.gameObject.SetActive(isVisible);
Debug.Log($"通过递归查找设置页面 {currentPage} 文字面板显隐: {isVisible}");
}
else
{
Debug.LogWarning($"页面 {currentPage} 的PageBackground未找到Image组件");
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} 找到PageBackground");
}
}
else
{
Debug.LogWarning($"未找到页面 {currentPage}");
Debug.LogWarning($"未找到页面 {currentPage}背景Transform子物体: {string.Join(", ", GetChildNames(background))}");
}
}
// 设置公共背景的Sprite
private void SetBackgroundSprite(bool hasText)
{
if (background == null)
{
Debug.LogError($"背景Transform未设置无法切换背景");
return;
}
Image backgroundImage = background.GetComponent<Image>();
if (backgroundImage != null)
{
Sprite newSprite = hasText ? textBackgroundSprite : noTextBackgroundSprite;
if (newSprite != null)
{
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)
{
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;
}
// 处理动画结束事件
private void OnModelAnimationFinished()
{
@ -423,5 +501,6 @@ public class DisplayServer : MonoBehaviour
{
listenThread.Join(1000); // 等待线程结束
}
Debug.Log("显示端服务器已停止");
}
}

View File

@ -1,79 +1,190 @@
using UnityEngine;
using System.Collections.Generic;
using System;
public class ModelController : MonoBehaviour
{
private Animator animator; // 用于控制动画
public delegate void AnimationFinished(); // 动画结束事件
public event AnimationFinished OnAnimationFinished; // 动画结束事件
private Animator animator; // 控制动画的Animator组件
private string currentAnim = ""; // 跟踪当前播放的动画
private bool isPlaying = false; // 跟踪动画播放状态
// 脚本启动时调用
void Start()
[Header("默认动画状态名称")]
public string defaultAnimName = "Take 001"; // 默认动画状态名称
private Dictionary<string, int> stateHashes = new Dictionary<string, int>(); // 动画状态哈希缓存
private float lastLoggedProgress = -1f; // 记录上次日志的进度值
private float lastWarningTime = 0f; // 记录上次警告日志时间
private const float warningInterval = 1f; // 警告日志间隔(秒)
// 动画结束事件
public event Action OnAnimationFinished;
// 脚本初始化时调用
void Awake()
{
animator = GetComponent<Animator>();
if (animator == null)
// 缓存默认动画状态的哈希值以提高性能
if (!string.IsNullOrEmpty(defaultAnimName))
{
Debug.LogError($"模型 {gameObject.name} 未找到Animator组件");
stateHashes[defaultAnimName] = Animator.StringToHash(defaultAnimName);
}
}
// 播放动画
// 在Update中更新动画状态
void Update()
{
if (isPlaying && animator != null && !string.IsNullOrEmpty(currentAnim))
{
if (!animator.enabled)
{
animator.enabled = true; // 确保Animator启用
Debug.Log($"重新启用Animator: {currentAnim}");
}
AnimatorStateInfo stateInfo = animator.GetCurrentAnimatorStateInfo(0);
if (stateInfo.IsName(currentAnim) && stateInfo.normalizedTime >= 1f)
{
// 动画播放完成,暂停并标记
animator.enabled = false;
isPlaying = false;
OnAnimationFinished?.Invoke(); // 通知动画结束
Debug.Log($"动画 {currentAnim} 播放完成,暂停");
}
}
}
/// <summary>
/// 从头播放默认动画
/// </summary>
public void PlayAnimation()
{
if (animator != null)
if (animator == null || string.IsNullOrEmpty(defaultAnimName)) return;
if (!AnimatorHasState(defaultAnimName))
{
animator.Play("Base Layer.AnimationName", 0, 0f); // 替换为实际动画名称
Debug.Log($"模型 {gameObject.name} 开始播放动画");
Debug.LogWarning($"Animator上不存在状态: {defaultAnimName}");
return;
}
currentAnim = defaultAnimName;
animator.enabled = true;
animator.Play(currentAnim, 0, 0f); // 从头播放动画
animator.Update(0f); // 强制立即更新
isPlaying = true; // 标记动画正在播放
Debug.Log($"开始播放动画: {currentAnim}");
}
// 设置动画进度
public void SetAnimationProgress(float progress)
/// <summary>
/// 设置动画进度0到1
/// </summary>
public void SetAnimationProgress(float normalizedTime)
{
if (animator != null)
if (animator == null || string.IsNullOrEmpty(defaultAnimName)) return;
if (!gameObject.activeSelf) return;
// 确保currentAnim已设置
if (string.IsNullOrEmpty(currentAnim))
{
animator.Play("Base Layer.AnimationName", 0, progress); // 替换为实际动画名称
animator.speed = 0f; // 暂停动画以保持进度
Debug.Log($"模型 {gameObject.name} 设置动画进度: {progress:F2}");
currentAnim = defaultAnimName;
Debug.Log($"设置动画进度前初始化currentAnim: {currentAnim}");
}
if (!AnimatorHasState(currentAnim))
{
Debug.LogWarning($"Animator上不存在状态: {currentAnim}");
return;
}
// 停止播放状态
isPlaying = false;
animator.enabled = true;
float clampedTime = Mathf.Clamp01(normalizedTime);
animator.Play(currentAnim, 0, clampedTime); // 设置动画到指定时间
animator.Update(0f); // 强制立即更新
animator.enabled = false; // 暂停动画
Debug.Log($"设置动画 {currentAnim} 进度: {clampedTime:F2}");
}
// 重置动画
/// <summary>
/// 重置动画到初始状态
/// </summary>
public void ResetAnimation()
{
if (animator != null)
{
animator.Play("Base Layer.AnimationName", 0, 0f); // 替换为实际动画名称
animator.speed = 1f; // 恢复正常播放速度
Debug.Log($"模型 {gameObject.name} 重置动画");
}
if (animator == null) return;
if (!gameObject.activeSelf) return;
string animToReset = !string.IsNullOrEmpty(defaultAnimName) ? defaultAnimName : "";
if (string.IsNullOrEmpty(animToReset)) return;
currentAnim = animToReset; // 确保currentAnim已设置
animator.enabled = true;
animator.Play(currentAnim, 0, 0f); // 重置到开始
animator.Update(0f); // 强制立即更新
animator.enabled = false; // 暂停动画
isPlaying = false; // 标记动画暂停
Debug.Log($"重置动画: {currentAnim}");
}
// 检查动画是否正在播放
public bool IsPlayingAnimation()
{
if (animator != null)
{
AnimatorStateInfo stateInfo = animator.GetCurrentAnimatorStateInfo(0);
return stateInfo.normalizedTime < 1.0f && animator.speed > 0f;
}
return false;
}
// 获取当前动画进度
/// <summary>
/// 获取当前动画的标准化时间0到1
/// </summary>
/// <returns>当前动画进度若无动画则返回0</returns>
public float GetAnimationProgress()
{
if (animator != null)
if (animator == null || !animator.enabled || string.IsNullOrEmpty(currentAnim) || !gameObject.activeSelf)
{
AnimatorStateInfo stateInfo = animator.GetCurrentAnimatorStateInfo(0);
return Mathf.Clamp01(stateInfo.normalizedTime);
if (Time.time - lastWarningTime >= warningInterval)
{
Debug.LogWarning($"无法获取动画进度: animator={animator}, enabled={animator?.enabled}, currentAnim={currentAnim}, active={gameObject.activeSelf}");
lastWarningTime = Time.time;
}
return 0f;
}
if (!AnimatorHasState(currentAnim))
{
if (Time.time - lastWarningTime >= warningInterval)
{
Debug.LogWarning($"Animator上不存在状态: {currentAnim}");
lastWarningTime = Time.time;
}
return 0f;
}
AnimatorStateInfo stateInfo = animator.GetCurrentAnimatorStateInfo(0);
if (stateInfo.IsName(currentAnim))
{
float progress = Mathf.Clamp01(stateInfo.normalizedTime % 1f);
// 仅当进度变化超过0.01时记录日志
if (Mathf.Abs(progress - lastLoggedProgress) > 0.01f)
{
Debug.Log($"获取动画 {currentAnim} 进度: {progress:F2}");
lastLoggedProgress = progress;
}
return progress;
}
if (Time.time - lastWarningTime >= warningInterval)
{
Debug.LogWarning($"动画状态不匹配: currentAnim={currentAnim}, state={stateInfo.fullPathHash}");
lastWarningTime = Time.time;
}
return 0f;
}
// 动画结束时调用需在Animator中设置
public void OnAnimationEnd()
// 检查指定的动画状态是否存在于Animator中
private bool AnimatorHasState(string stateName)
{
OnAnimationFinished?.Invoke();
Debug.Log($"模型 {gameObject.name} 动画播放完成");
if (stateHashes.TryGetValue(stateName, out int hash))
{
for (int i = 0; i < animator.layerCount; i++)
{
if (animator.HasState(i, hash)) return true;
}
}
return false;
}
// 获取动画播放状态
public bool IsPlayingAnimation()
{
return isPlaying;
}
}

View File

@ -39,12 +39,18 @@ public class TouchClient : MonoBehaviour
// 设置触摸控制端分辨率为 1920x1080
Screen.SetResolution(1920, 1080, false);
// 在端口9999上初始化UDP监听
udpListener = new UdpClient(9999);
udpThread = new Thread(() => ListenForBroadcast(udpCts.Token));
udpThread.Start();
Debug.Log("触摸端等待显示端广播...");
try
{
// 在端口9999上初始化UDP监听
udpListener = new UdpClient(9999);
udpThread = new Thread(() => ListenForBroadcast(udpCts.Token));
udpThread.Start();
Debug.Log("触摸端等待显示端广播,监听端口: 9999");
}
catch (Exception ex)
{
Debug.LogError($"初始化UDP监听失败: {ex.Message}");
}
// 显示初始页面
ShowPage("首页");
@ -55,22 +61,30 @@ public class TouchClient : MonoBehaviour
{
IPEndPoint endPoint = new IPEndPoint(IPAddress.Any, 9999);
// 在未连接或未取消的情况下持续监听
while (!isConnected && !token.IsCancellationRequested)
{
try
{
// 接收广播数据
byte[] data = udpListener.Receive(ref endPoint);
string serverIp = Encoding.UTF8.GetString(data);
string message = Encoding.UTF8.GetString(data);
Debug.Log($"收到UDP广播: {message},来源: {endPoint.Address}:{endPoint.Port}");
Debug.Log("发现显示端IP: " + serverIp);
ConnectToServer(serverIp, 8888); // 尝试连接到服务器
// 提取IP地址
string serverIp = message.StartsWith("ServerIP:") ? message.Replace("ServerIP:", "").Trim() : message.Trim();
if (IPAddress.TryParse(serverIp, out IPAddress ipAddress))
{
Debug.Log($"解析到有效IP: {serverIp}");
ConnectToServer(serverIp, 8888); // 尝试连接到服务器
}
else
{
Debug.LogWarning($"无效IP地址: {serverIp}");
}
}
catch (Exception ex)
{
Debug.LogError($"UDP接收错误: {ex.Message}");
Thread.Sleep(1000); // 避免快速重试
Thread.Sleep(2000); // 等待2秒重试
}
}
}
@ -78,24 +92,41 @@ public class TouchClient : MonoBehaviour
// 通过TCP连接到显示端服务器
private void ConnectToServer(string ip, int port)
{
try
{
client = new TcpClient();
client.Connect(ip, port); // 连接到服务器
stream = client.GetStream();
isConnected = true;
udpCts.Cancel(); // 连接成功后停止UDP监听线程
udpListener?.Close(); // 关闭UDP监听器
Debug.Log("触摸端已连接到显示端: " + ip);
int retryCount = 0;
const int maxRetries = 5;
const int retryDelayMs = 2000;
// 启动接收线程以处理服务器消息
receiveThread = new Thread(() => ReceiveMessages(receiveCts.Token));
receiveThread.Start();
}
catch (Exception ex)
while (!isConnected && retryCount < maxRetries)
{
Debug.LogError($"连接显示端失败: {ex.Message}");
try
{
Debug.Log($"尝试连接显示端: {ip}:{port} (尝试 {retryCount + 1}/{maxRetries})");
client = new TcpClient();
client.Connect(ip, port); // 连接到服务器
stream = client.GetStream();
isConnected = true;
udpCts.Cancel(); // 连接成功后停止UDP监听线程
udpListener?.Close(); // 关闭UDP监听器
Debug.Log($"触摸端已连接到显示端: {ip}:{port}");
// 启动接收线程以处理服务器消息
receiveThread = new Thread(() => ReceiveMessages(receiveCts.Token));
receiveThread.Start();
return;
}
catch (Exception ex)
{
Debug.LogError($"连接显示端失败: {ex.Message}");
retryCount++;
if (retryCount < maxRetries)
{
Debug.Log($"将在{retryDelayMs / 1000f}秒后重试...");
Thread.Sleep(retryDelayMs);
}
}
}
Debug.LogError($"连接显示端失败,已达到最大重试次数 ({maxRetries})");
}
// 接收服务器发送的消息
@ -109,7 +140,11 @@ public class TouchClient : MonoBehaviour
try
{
bytesRead = stream.Read(message, 0, 4096);
if (bytesRead == 0) break; // 服务器断开连接
if (bytesRead == 0)
{
Debug.Log("服务器断开连接");
break;
}
string data = Encoding.UTF8.GetString(message, 0, bytesRead);
if (data.StartsWith("Progress:") && float.TryParse(data.Replace("Progress:", ""), out float progress))
@ -120,6 +155,10 @@ public class TouchClient : MonoBehaviour
Debug.Log($"收到进度: {progress:F2}");
}
}
else
{
Debug.LogWarning($"收到未知消息: {data}");
}
}
catch (Exception ex)
{
@ -128,6 +167,32 @@ public class TouchClient : MonoBehaviour
break;
}
}
// 清理连接
stream?.Close();
client?.Close();
isConnected = false;
Debug.Log("TCP连接已断开将重新启动UDP监听");
// 重启UDP监听
RestartUdpListener();
}
// 重启UDP监听
private void RestartUdpListener()
{
try
{
udpCts = new CancellationTokenSource();
udpListener = new UdpClient(9999);
udpThread = new Thread(() => ListenForBroadcast(udpCts.Token));
udpThread.Start();
Debug.Log("重启UDP监听端口: 9999");
}
catch (Exception ex)
{
Debug.LogError($"重启UDP监听失败: {ex.Message}");
}
}
// 向显示端服务器发送消息
@ -139,14 +204,19 @@ public class TouchClient : MonoBehaviour
{
byte[] data = Encoding.UTF8.GetBytes(msg);
stream.Write(data, 0, data.Length);
Debug.Log("发送指令: " + msg);
Debug.Log($"发送指令: {msg}");
}
catch (Exception ex)
{
Debug.LogError($"发送消息失败: {ex.Message}");
isConnected = false; // 标记连接失效
isConnected = false;
RestartUdpListener();
}
}
else
{
Debug.LogWarning($"无法发送消息,未连接到服务器: {msg}");
}
}
// 页面按钮点击时调用
@ -218,17 +288,19 @@ public class TouchClient : MonoBehaviour
if (toggle == null) return;
bool isTextPanelVisible = toggle.isOn;
Image toggleImage = toggle.graphic as Image; // 使用Toggle的graphic字段
Transform backgroundTransform = toggle.transform.Find("Background");
Image toggleImage = backgroundTransform != null ? backgroundTransform.GetComponent<Image>() : null;
TextMeshProUGUI toggleText = toggle.GetComponentInChildren<TextMeshProUGUI>();
if (toggleImage != null)
{
toggleImage.sprite = isTextPanelVisible ? showSprite : hideSprite;
Debug.Log($"Toggle sprite 切换: {currentPage}, isOn={isTextPanelVisible}, sprite={(isTextPanelVisible ? showSprite : hideSprite).name}");
Sprite newSprite = 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} 未找到graphic Image组件");
Debug.LogWarning($"Toggle {toggle.name} 未找到Background的Image组件");
}
if (toggleText != null)
@ -238,7 +310,17 @@ public class TouchClient : MonoBehaviour
}
else
{
Debug.LogWarning($"Toggle {toggle.name} 未找到TextMeshProUGUI组件");
Debug.LogWarning($"Toggle {toggle.name} 未找到Text(TMP)组件");
}
// 验证Toggle的Graphic字段
if (toggle.graphic != null && toggle.graphic is Image graphicImage)
{
Debug.Log($"Toggle Graphic验证: {currentPage}, graphic sprite={graphicImage.sprite?.name ?? "null"}");
}
else
{
Debug.LogWarning($"Toggle {toggle.name} 的Graphic字段未正确配置或为空");
}
// 发送显隐消息到显示端
@ -339,16 +421,17 @@ public class TouchClient : MonoBehaviour
toggle.isOn = true; // 默认显示文字面板
toggle.interactable = true; // 确保可交互
// 更新Sprite和文本
Image toggleImage = toggle.graphic as Image; // 使用Toggle的graphic字段
Transform backgroundTransform = toggle.transform.Find("Background");
Image toggleImage = backgroundTransform != null ? backgroundTransform.GetComponent<Image>() : null;
TextMeshProUGUI toggleText = toggle.GetComponentInChildren<TextMeshProUGUI>();
if (toggleImage != null)
{
toggleImage.sprite = showSprite;
Debug.Log($"初始化Toggle sprite: {pageName}, sprite={showSprite.name}");
Debug.Log($"初始化Toggle sprite: {pageName}, sprite={(showSprite != null ? showSprite.name : "null")}");
}
else
{
Debug.LogWarning($"Toggle {toggle.name} 未找到graphic Image组件");
Debug.LogWarning($"Toggle {toggle.name} 未找到Background的Image组件");
}
if (toggleText != null)
{
@ -357,7 +440,16 @@ public class TouchClient : MonoBehaviour
}
else
{
Debug.LogWarning($"Toggle {toggle.name} 未找到TextMeshProUGUI组件");
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;
@ -421,5 +513,6 @@ public class TouchClient : MonoBehaviour
udpListener?.Close(); // 关闭UDP监听器
stream?.Close(); // 关闭TCP流
client?.Close(); // 关闭TCP客户端
Debug.Log("触摸端客户端已停止");
}
}

View File

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

View File

@ -17,9 +17,9 @@ MonoBehaviour:
x: 0
y: 43.2
width: 1536
height: 772.8
height: 820.8
m_ShowMode: 4
m_Title: Scene
m_Title: Game
m_RootView: {fileID: 2}
m_MinSize: {x: 875, y: 300}
m_MaxSize: {x: 10000, y: 10000}
@ -45,7 +45,7 @@ MonoBehaviour:
x: 0
y: 0
width: 1536
height: 772.8
height: 820.8
m_MinSize: {x: 875, y: 300}
m_MaxSize: {x: 10000, y: 10000}
m_UseTopView: 1
@ -95,7 +95,7 @@ MonoBehaviour:
x: 0
y: 30
width: 1536
height: 722.8
height: 770.8
m_MinSize: {x: 300, y: 200}
m_MaxSize: {x: 24288, y: 16192}
vertical: 0
@ -116,7 +116,7 @@ MonoBehaviour:
m_Position:
serializedVersion: 2
x: 0
y: 752.8
y: 800.8
width: 1536
height: 20
m_MinSize: {x: 0, y: 0}
@ -139,7 +139,7 @@ MonoBehaviour:
x: 0
y: 0
width: 854.4
height: 722.8
height: 770.8
m_MinSize: {x: 201, y: 221}
m_MaxSize: {x: 4001, y: 4021}
m_ActualView: {fileID: 15}
@ -170,11 +170,11 @@ MonoBehaviour:
x: 854.4
y: 0
width: 278.40002
height: 722.8
height: 770.8
m_MinSize: {x: 100, y: 200}
m_MaxSize: {x: 8096, y: 16192}
vertical: 1
controlID: 69
controlID: 55
--- !u!114 &8
MonoBehaviour:
m_ObjectHideFlags: 52
@ -193,7 +193,7 @@ MonoBehaviour:
x: 1132.8
y: 0
width: 403.19995
height: 722.8
height: 770.8
m_MinSize: {x: 275, y: 50}
m_MaxSize: {x: 4000, y: 4000}
m_ActualView: {fileID: 13}
@ -219,9 +219,9 @@ MonoBehaviour:
x: 0
y: 0
width: 278.40002
height: 400.8
m_MinSize: {x: 202, y: 221}
m_MaxSize: {x: 4002, y: 4021}
height: 341.6
m_MinSize: {x: 200, y: 200}
m_MaxSize: {x: 4000, y: 4000}
m_ActualView: {fileID: 16}
m_Panes:
- {fileID: 16}
@ -243,9 +243,9 @@ MonoBehaviour:
m_Position:
serializedVersion: 2
x: 0
y: 400.8
y: 341.6
width: 278.40002
height: 322
height: 429.19998
m_MinSize: {x: 232, y: 271}
m_MaxSize: {x: 10002, y: 10021}
m_ActualView: {fileID: 14}
@ -284,7 +284,7 @@ MonoBehaviour:
m_OverlaysVisible: 1
m_LockTracker:
m_IsLocked: 0
m_LastSelectedObjectID: 540690
m_LastSelectedObjectID: 162098
--- !u!114 &12
MonoBehaviour:
m_ObjectHideFlags: 52
@ -308,7 +308,7 @@ MonoBehaviour:
x: 0
y: 73.6
width: 853.4
height: 701.8
height: 749.8
m_ViewDataDictionary: {fileID: 0}
m_OverlayCanvas:
m_LastAppliedPresetName: Default
@ -441,7 +441,7 @@ MonoBehaviour:
x: 1132.8
y: 73.6
width: 402.19995
height: 701.8
height: 749.8
m_ViewDataDictionary: {fileID: 0}
m_OverlayCanvas:
m_LastAppliedPresetName: Default
@ -481,9 +481,9 @@ MonoBehaviour:
m_Pos:
serializedVersion: 2
x: 854.4
y: 474.4
y: 415.2
width: 276.40002
height: 301
height: 408.19998
m_ViewDataDictionary: {fileID: 0}
m_OverlayCanvas:
m_LastAppliedPresetName: Default
@ -515,7 +515,7 @@ MonoBehaviour:
scrollPos: {x: 0, y: 0}
m_SelectedIDs: 7c780000
m_LastClickedID: 30844
m_ExpandedIDs: 000000005cac01005eac010060ac010062ac010064ac010066ac010068ac01006aac01006cac01006eac010070ac0100
m_ExpandedIDs: 00000000d6ac0100d8ac0100daac0100dcac0100deac0100e0ac0100e2ac0100e4ac0100e6ac0100e8ac0100eaac0100ecac0100eeac0100
m_RenameOverlay:
m_UserAcceptedRename: 0
m_Name:
@ -540,10 +540,10 @@ MonoBehaviour:
m_Icon: {fileID: 0}
m_ResourceFile:
m_AssetTreeState:
scrollPos: {x: 0, y: 465}
scrollPos: {x: 0, y: 0}
m_SelectedIDs:
m_LastClickedID: 0
m_ExpandedIDs: ffffffff000000005cac01005eac010060ac010062ac010064ac010066ac010068ac01006aac01006cac01006eac010070ac0100beac0100
m_ExpandedIDs: ffffffff00000000d6ac0100d8ac0100daac0100dcac0100deac0100e0ac0100e2ac0100e4ac0100eaac0100944d0900
m_RenameOverlay:
m_UserAcceptedRename: 0
m_Name:
@ -622,7 +622,7 @@ MonoBehaviour:
x: 0
y: 73.6
width: 853.4
height: 701.8
height: 749.8
m_ViewDataDictionary: {fileID: 0}
m_OverlayCanvas:
m_LastAppliedPresetName: Default
@ -869,9 +869,9 @@ MonoBehaviour:
m_PlayAudio: 0
m_AudioPlay: 0
m_Position:
m_Target: {x: 941.18176, y: 582.5733, z: 9.363111}
m_Target: {x: 944.95264, y: 582.91113, z: 2.357466}
speed: 2
m_Value: {x: 917.83325, y: 594.0318, z: 8.957989}
m_Value: {x: 944.95264, y: 582.91113, z: 2.357466}
m_RenderMode: 0
m_CameraMode:
drawMode: 0
@ -922,9 +922,9 @@ MonoBehaviour:
speed: 2
m_Value: {x: 0, y: 0, z: 0, w: 1}
m_Size:
m_Target: 859.76056
m_Target: 866.09686
speed: 2
m_Value: 900.2728
m_Value: 866.09686
m_Ortho:
m_Target: 1
speed: 2
@ -972,7 +972,7 @@ MonoBehaviour:
x: 854.4
y: 73.6
width: 276.40002
height: 379.8
height: 320.6
m_ViewDataDictionary: {fileID: 0}
m_OverlayCanvas:
m_LastAppliedPresetName: Default
@ -980,24 +980,24 @@ MonoBehaviour:
m_OverlaysVisible: 1
m_SceneHierarchy:
m_TreeViewState:
scrollPos: {x: 0, y: 5.200012}
m_SelectedIDs:
scrollPos: {x: 0, y: 0}
m_SelectedIDs: 38ad0100
m_LastClickedID: 0
m_ExpandedIDs: 4228ffff08fbffff205900004c59000050590000605900006e590000865900008a59000096590000f2ad0100f6ad010030ae010040ae010014af0100b2af0100b6af0100ecaf010000b001002ab001004cb1010060b1010094b10100
m_ExpandedIDs: 24aef9ff6caef9ff54aff9ffa8aff9ffe0b0f9ff4cb2f9ff5671faffa630fbffa231fbffbcf1fbfff008fcff56cafcffdad6fcffc4e5fcff06e6fcff46e7fcff66ecfcffa8ecfcffecedfcff5cadfdffeaadfdfffc73feff9675fefffc36ffff7a37ffff08fbffff8ab20100c8fb0700ee210800f4340800e6530800a65508003e560800ea4d0900ee4d0900044e0900304e09003c4e0900404e0900064f09001c4f0900ae4f0900ba4f0900be4f0900f44f090032500900c2500900265109005c51090070510900a45109006c5709007057090086570900be570900c25709009e580900f65809004459090048590900865909009a590900c4590900f2590900285a0900c85a0900fe5a0900025b0900125b0900465b09000a6009005260090094600900c06009003a610900d06409001865090094650900dc6509001e6609002666090000680900c06909002a6a0900ec6a0900966b0900de6b0900
m_RenameOverlay:
m_UserAcceptedRename: 0
m_Name:
m_OriginalName:
m_Name: "SPECT\u7CFB\u7EDF"
m_OriginalName: "SPECT\u7CFB\u7EDF"
m_EditFieldRect:
serializedVersion: 2
x: 0
y: 0
width: 0
height: 0
m_UserData: 0
m_UserData: 614482
m_IsWaitingForDelay: 0
m_IsRenaming: 0
m_OriginalEventType: 11
m_OriginalEventType: 0
m_IsRenamingFilename: 0
m_ClientGUIView: {fileID: 9}
m_SearchString:
@ -1030,7 +1030,7 @@ MonoBehaviour:
x: 0
y: 73.6
width: 853.4
height: 701.8
height: 749.8
m_ViewDataDictionary: {fileID: 0}
m_OverlayCanvas:
m_LastAppliedPresetName: Default
@ -1044,7 +1044,7 @@ MonoBehaviour:
m_ShowGizmos: 0
m_TargetDisplay: 0
m_ClearColor: {r: 0, g: 0, b: 0, a: 0}
m_TargetSize: {x: 1920, y: 1080}
m_TargetSize: {x: 3328, y: 1352}
m_TextureFilterMode: 0
m_TextureHideFlags: 61
m_RenderIMGUI: 1
@ -1053,16 +1053,16 @@ MonoBehaviour:
m_VSyncEnabled: 0
m_Gizmos: 0
m_Stats: 0
m_SelectedSizes: 03000000000000000000000012000000000000000000000000000000000000000000000000000000
m_SelectedSizes: 08000000000000000000000012000000000000000000000000000000000000000000000000000000
m_ZoomArea:
m_HRangeLocked: 0
m_VRangeLocked: 0
hZoomLockedByDefault: 0
vZoomLockedByDefault: 0
m_HBaseRangeMin: -768
m_HBaseRangeMax: 768
m_VBaseRangeMin: -432
m_VBaseRangeMax: 432
m_HBaseRangeMin: -1331.2001
m_HBaseRangeMax: 1331.2001
m_VBaseRangeMin: -540.8
m_VBaseRangeMax: 540.8
m_HAllowExceedBaseRangeMin: 1
m_HAllowExceedBaseRangeMax: 1
m_VAllowExceedBaseRangeMin: 1
@ -1071,7 +1071,7 @@ MonoBehaviour:
m_HSlider: 0
m_VSlider: 0
m_IgnoreScrollWheelUntilClicked: 0
m_EnableMouseInput: 1
m_EnableMouseInput: 0
m_EnableSliderZoomHorizontal: 0
m_EnableSliderZoomVertical: 0
m_UniformScale: 1
@ -1081,22 +1081,22 @@ MonoBehaviour:
x: 0
y: 21
width: 853.4
height: 680.8
m_Scale: {x: 0.555599, y: 0.555599}
m_Translation: {x: 426.7, y: 340.4}
height: 728.8
m_Scale: {x: 0.32053787, y: 0.32053787}
m_Translation: {x: 426.70004, y: 364.4}
m_MarginLeft: 0
m_MarginRight: 0
m_MarginTop: 0
m_MarginBottom: 0
m_LastShownAreaInsideMargins:
serializedVersion: 2
x: -768
y: -612.6721
width: 1536
height: 1225.3442
x: -1331.2001
y: -1136.8391
width: 2662.4001
height: 2273.6782
m_MinimalGUI: 1
m_defaultScale: 0.555599
m_LastWindowPixelSize: {x: 1066.75, y: 877.25}
m_defaultScale: 0.32053787
m_LastWindowPixelSize: {x: 1066.75, y: 937.25}
m_ClearInEditMode: 1
m_NoCameraWarning: 1
m_LowResolutionForAspectRatios: 00000000000000000000