diff --git a/unity/Assets/Light/shaders/IndianOcean_DarknessOverlay.mat b/unity/Assets/Light/shaders/IndianOcean_DarknessOverlay.mat index 93efba6..2abee3a 100644 --- a/unity/Assets/Light/shaders/IndianOcean_DarknessOverlay.mat +++ b/unity/Assets/Light/shaders/IndianOcean_DarknessOverlay.mat @@ -31,7 +31,7 @@ Material: - _EchoRadius: 39.41617 - _EchoWidth: 2.5 - _LightSoftness: 1 - - _MinBrightness: 1 + - _MinBrightness: 0 m_Colors: - _DarknessColor: {r: 0.01, g: 0.01, b: 0.02, a: 1} - _EchoCenter: {r: -2.4399998, g: -1.5000057, b: 0, a: 0} diff --git a/unity/Assets/Scenes/MainMenu.unity b/unity/Assets/Scenes/MainMenu.unity index ecfde39..a6d2abc 100644 --- a/unity/Assets/Scenes/MainMenu.unity +++ b/unity/Assets/Scenes/MainMenu.unity @@ -1361,6 +1361,7 @@ RectTransform: m_Children: - {fileID: 1022684515} - {fileID: 1048541269} + - {fileID: 1479992326} m_Father: {fileID: 1036666439} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} @@ -1921,6 +1922,8 @@ MonoBehaviour: settingsButton: {fileID: 0} creditsButton: {fileID: 995992462} quitButton: {fileID: 0} + storyReplayButton: {fileID: 977847656} + storyPVPlayer: {fileID: 0} settingsPanel: {fileID: 0} settingsBackButton: {fileID: 0} creditsPanel: {fileID: 1048541268} @@ -2346,6 +2349,8 @@ MonoBehaviour: settingsButton: {fileID: 0} creditsButton: {fileID: 0} quitButton: {fileID: 0} + storyReplayButton: {fileID: 0} + storyPVPlayer: {fileID: 0} settingsPanel: {fileID: 2013394273} settingsBackButton: {fileID: 774721830} creditsPanel: {fileID: 0} @@ -2947,6 +2952,128 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 0575607a807dc2d4c83554aa364916e4, type: 3} m_Name: m_EditorClassIdentifier: +--- !u!1 &1365782246 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 7 + m_Component: + - component: {fileID: 1365782247} + - component: {fileID: 1365782250} + - component: {fileID: 1365782249} + - component: {fileID: 1365782248} + m_Layer: 0 + m_HasEditorInfo: 1 + m_Name: SkipButton + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1365782247 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1365782246} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1.3, y: 1.3, z: 1.3} + m_ConstrainProportionsScale: 1 + m_Children: + - {fileID: 1779218691} + m_Father: {fileID: 1479992326} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 1, y: 0} + m_AnchorMax: {x: 1, y: 0} + m_AnchoredPosition: {x: -30, y: 30} + m_SizeDelta: {x: 120, y: 50} + m_Pivot: {x: 1, y: 0} +--- !u!114 &1365782248 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1365782246} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 1365782249} + m_OnClick: + m_PersistentCalls: + m_Calls: [] +--- !u!114 &1365782249 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1365782246} + 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: 0, g: 0, b: 0, a: 0.3} + 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: 0} + 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 &1365782250 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1365782246} + m_CullTransparentMesh: 1 --- !u!1 &1378071327 GameObject: m_ObjectHideFlags: 0 @@ -3150,6 +3277,235 @@ MonoBehaviour: m_EditorClassIdentifier: m_HorizontalFit: 2 m_VerticalFit: 2 +--- !u!1 &1479992325 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 7 + m_Component: + - component: {fileID: 1479992326} + - component: {fileID: 1479992329} + - component: {fileID: 1479992328} + - component: {fileID: 1479992327} + - component: {fileID: 1479992331} + - component: {fileID: 1479992330} + m_Layer: 0 + m_HasEditorInfo: 1 + m_Name: VideoOverlay + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 0 +--- !u!224 &1479992326 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1479992325} + 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: + - {fileID: 1718834982} + - {fileID: 1365782247} + m_Father: {fileID: 897692926} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1479992327 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1479992325} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d51e1907b754a7449b9a571bef4c39db, type: 3} + m_Name: + m_EditorClassIdentifier: + videoOverlay: {fileID: 1479992325} + videoDisplay: {fileID: 0} + skipButton: {fileID: 0} + videoPlayer: {fileID: 1479992329} +--- !u!82 &1479992328 +AudioSource: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1479992325} + m_Enabled: 1 + serializedVersion: 4 + OutputAudioMixerGroup: {fileID: 0} + m_audioClip: {fileID: 0} + m_PlayOnAwake: 1 + m_Volume: 1 + m_Pitch: 1 + Loop: 0 + Mute: 0 + Spatialize: 0 + SpatializePostEffects: 0 + Priority: 128 + DopplerLevel: 1 + MinDistance: 1 + MaxDistance: 500 + Pan2D: 0 + rolloffMode: 0 + BypassEffects: 0 + BypassListenerEffects: 0 + BypassReverbZones: 0 + rolloffCustomCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 3 + time: 0 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + weightedMode: 0 + inWeight: 0.33333334 + outWeight: 0.33333334 + - serializedVersion: 3 + time: 1 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + weightedMode: 0 + inWeight: 0.33333334 + outWeight: 0.33333334 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + panLevelCustomCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 3 + time: 0 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + weightedMode: 0 + inWeight: 0.33333334 + outWeight: 0.33333334 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + spreadCustomCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 3 + time: 0 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + weightedMode: 0 + inWeight: 0.33333334 + outWeight: 0.33333334 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + reverbZoneMixCustomCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 3 + time: 0 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + weightedMode: 0 + inWeight: 0.33333334 + outWeight: 0.33333334 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 +--- !u!328 &1479992329 +VideoPlayer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1479992325} + m_Enabled: 1 + m_VideoClip: {fileID: 32900000, guid: e9ea16258fb7da2499288a67fcdffb2a, type: 3} + m_TargetCameraAlpha: 1 + m_TargetCamera3DLayout: 0 + m_TargetCamera: {fileID: 0} + m_TargetTexture: {fileID: 0} + m_TimeReference: 0 + m_TargetMaterialRenderer: {fileID: 0} + m_TargetMaterialProperty: + m_RenderMode: 2 + m_AspectRatio: 2 + m_DataSource: 0 + m_TimeUpdateMode: 2 + m_PlaybackSpeed: 1 + m_AudioOutputMode: 1 + m_TargetAudioSources: + - {fileID: 1479992328} + m_DirectAudioVolumes: + - 1 + m_Url: + m_EnabledAudioTracks: 01 + m_DirectAudioMutes: 00 + m_ControlledAudioTrackCount: 1 + m_PlayOnAwake: 0 + m_SkipOnDrop: 1 + m_Looping: 0 + m_WaitForFirstFrame: 1 + m_FrameReadyEventEnabled: 0 + m_VideoShaders: [] +--- !u!114 &1479992330 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1479992325} + 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: 0, g: 0, b: 0, 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: 0} + 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 &1479992331 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1479992325} + m_CullTransparentMesh: 1 --- !u!1 &1492109979 GameObject: m_ObjectHideFlags: 0 @@ -3688,6 +4044,159 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 123025e1710a13c46bf4c72b4a69c62d, type: 3} m_Name: m_EditorClassIdentifier: +--- !u!1 &1718834981 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 7 + m_Component: + - component: {fileID: 1718834982} + - component: {fileID: 1718834984} + - component: {fileID: 1718834983} + m_Layer: 0 + m_HasEditorInfo: 1 + m_Name: VideoDisplay + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1718834982 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1718834981} + 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: 1479992326} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1718834983 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1718834981} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 1344c3c82d62a2a41a3576d8abb8e3ea, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 0 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Texture: {fileID: 0} + m_UVRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 1 + height: 1 +--- !u!222 &1718834984 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1718834981} + m_CullTransparentMesh: 1 +--- !u!1 &1779218690 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 7 + m_Component: + - component: {fileID: 1779218691} + - component: {fileID: 1779218693} + - component: {fileID: 1779218692} + m_Layer: 0 + m_HasEditorInfo: 1 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1779218691 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1779218690} + 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: 1365782247} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1779218692 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1779218690} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, 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_FontData: + m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} + m_FontSize: 36 + m_FontStyle: 0 + m_BestFit: 0 + m_MinSize: 3 + m_MaxSize: 40 + m_Alignment: 4 + m_AlignByGeometry: 0 + m_RichText: 1 + m_HorizontalOverflow: 0 + m_VerticalOverflow: 0 + m_LineSpacing: 1 + m_Text: "\u8DF3\u8FC7 >>" +--- !u!222 &1779218693 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1779218690} + m_CullTransparentMesh: 1 --- !u!1 &1801267574 GameObject: m_ObjectHideFlags: 0 diff --git a/unity/Assets/UI/Art/Common/pv.mp4 b/unity/Assets/UI/Art/Common/pv.mp4 new file mode 100644 index 0000000..b9d0a47 Binary files /dev/null and b/unity/Assets/UI/Art/Common/pv.mp4 differ diff --git a/unity/Assets/UI/Art/Common/pv.mp4.meta b/unity/Assets/UI/Art/Common/pv.mp4.meta new file mode 100644 index 0000000..120e1d7 --- /dev/null +++ b/unity/Assets/UI/Art/Common/pv.mp4.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: WnNK5CurUX7eLhb2j9pccpst4FlQvWWo1dIvwTsstWgBgYCFcFKyBGs= +VideoClipImporter: + externalObjects: {} + serializedVersion: 2 + frameRange: 0 + startFrame: -1 + endFrame: -1 + colorSpace: 0 + deinterlace: 0 + encodeAlpha: 0 + flipVertical: 0 + flipHorizontal: 0 + importAudio: 1 + targetSettings: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/unity/Assets/UI/MainMenuUIController.cs b/unity/Assets/UI/MainMenuUIController.cs index f7355fc..4dd9609 100644 --- a/unity/Assets/UI/MainMenuUIController.cs +++ b/unity/Assets/UI/MainMenuUIController.cs @@ -15,6 +15,10 @@ namespace GameFramework [SerializeField] Button settingsButton; [SerializeField] Button creditsButton; [SerializeField] Button quitButton; + [SerializeField] Button storyReplayButton; + + [Header("剧情 PV")] + [SerializeField] StoryPVPlayer storyPVPlayer; [Header("Settings Panel")] [SerializeField] GameObject settingsPanel; @@ -35,6 +39,15 @@ namespace GameFramework creditsButton = FindButton("CreditsButton"); if (quitButton == null) quitButton = FindButton("QuitButton"); + if (storyReplayButton == null) + storyReplayButton = FindButton("StoryReplayButton"); + if (storyPVPlayer == null) + { + // 使用 FindObjectsByType 包含 inactive 对象,避免找不到隐藏的 VideoOverlay + var players = FindObjectsByType(FindObjectsInactive.Include, FindObjectsSortMode.None); + if (players.Length > 0) + storyPVPlayer = players[0]; + } if (settingsPanel == null) settingsPanel = GameObject.Find("SettingsPanel"); @@ -55,6 +68,12 @@ namespace GameFramework creditsButton.onClick.AddListener(OnCreditsClick); if (quitButton != null) quitButton.onClick.AddListener(OnQuitClick); + if (storyReplayButton != null) + { + // 避免 Inspector 中已绑定的事件导致重复触发 + storyReplayButton.onClick.RemoveAllListeners(); + storyReplayButton.onClick.AddListener(OnStoryReplayClick); + } if (settingsBackButton != null) settingsBackButton.onClick.AddListener(OnSettingsBackClick); @@ -119,5 +138,18 @@ namespace GameFramework Application.Quit(); #endif } + + void OnStoryReplayClick() + { + if (storyPVPlayer != null) + { + Debug.Log($"[MainMenu] 播放 PV, StoryPVPlayer on: {storyPVPlayer.gameObject.name}"); + storyPVPlayer.Play(); + } + else + { + Debug.LogWarning("[MainMenu] StoryPVPlayer 未配置!"); + } + } } } diff --git a/unity/Assets/UI/StoryPVPlayer.cs b/unity/Assets/UI/StoryPVPlayer.cs new file mode 100644 index 0000000..6e37d31 --- /dev/null +++ b/unity/Assets/UI/StoryPVPlayer.cs @@ -0,0 +1,251 @@ +using UnityEngine; +using UnityEngine.UI; +using UnityEngine.Video; +using System.Collections; + +namespace GameFramework +{ + /// + /// 剧情 PV 播放器 —— 点击 StoryReplayButton 后弹出全屏视频覆盖层播放 PV。 + /// 播放完毕自动关闭,也可点击"跳过"按钮立即关闭。 + /// + /// 搭建: + /// 1. 在 MainMenu Canvas 下创建 VideoOverlay(初始 SetActive(false)) + /// 2. 子物体:BG (全屏黑色 Image)、VideoDisplay (RawImage)、SkipButton (Button) + /// 3. 挂 VideoPlayer 组件,VideoClip 赋值为 pv.mp4 + /// 4. 挂本脚本,Inspector 中关联各引用 + /// + public class StoryPVPlayer : MonoBehaviour + { + [Header("覆盖层")] + [Tooltip("视频覆盖层根节点(初始隐藏)")] + [SerializeField] private GameObject videoOverlay; + + [Header("视频显示")] + [Tooltip("全屏 RawImage 用于显示视频画面")] + [SerializeField] private RawImage videoDisplay; + + [Header("跳过按钮")] + [Tooltip("右下角跳过按钮")] + [SerializeField] private Button skipButton; + + [Header("视频播放器")] + [Tooltip("VideoPlayer 组件(挂在 VideoOverlay 或自身上)")] + [SerializeField] private VideoPlayer videoPlayer; + + private RenderTexture _renderTexture; + private bool _isPlaying = false; + + + /// + /// 懒加载:确保所有引用都已初始化。 + /// 使用 GetComponentsInChildren(true) 递归搜索(包括 inactive 子物体)。 + /// + private void EnsureReferences() + { + // videoOverlay:默认就是自身(StoryPVPlayer 挂在 VideoOverlay 上) + if (videoOverlay == null) + { + // 递归搜索子物体中名为 "VideoOverlay" 的 GameObject + var transforms = GetComponentsInChildren(true); + foreach (var t in transforms) + { + if (t.name == "VideoOverlay") + { + videoOverlay = t.gameObject; + break; + } + } + // 如果没找到,说明本脚本就挂在 VideoOverlay 上 + if (videoOverlay == null) + videoOverlay = gameObject; + } + + // 查找 RawImage(递归搜索 videoOverlay 的子物体,包括 inactive) + if (videoDisplay == null && videoOverlay != null) + { + var displays = videoOverlay.GetComponentsInChildren(true); + if (displays.Length > 0) + videoDisplay = displays[0]; + } + + // 查找 SkipButton(递归搜索,按名称匹配避免找到其他按钮) + if (skipButton == null && videoOverlay != null) + { + var buttons = videoOverlay.GetComponentsInChildren