1 Commits
main ... Tuan

Author SHA1 Message Date
0e6e763b64 fix di chuyen update maze ui update map 2026-04-22 13:22:42 +07:00
11 changed files with 985 additions and 449 deletions

View File

@@ -5,17 +5,7 @@
</component>
<component name="ChangeListManager">
<list default="true" id="f9183c68-daf0-43b8-be4c-fad79983f91b" name="Changes" comment="">
<change beforePath="$PROJECT_DIR$/.idea/.idea.HALLUCINATE/.idea/indexLayout.xml" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Scenes/Lobby.unity" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Scenes/Lobby.unity" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Scenes/Main Scene.unity" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Scenes/Main Scene.unity" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Scove/DEMO FUSION.unity" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Scove/DEMO FUSION.unity" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Player Controller/PlayerAirDashState.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Scripts/Player Controller/PlayerAirDashState.cs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Player Controller/PlayerDashState.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Scripts/Player Controller/PlayerDashState.cs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Player Controller/PlayerDodgeState.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Scripts/Player Controller/PlayerDodgeState.cs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Player Controller/PlayerFallState.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Scripts/Player Controller/PlayerFallState.cs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Player Controller/PlayerJumpState.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Scripts/Player Controller/PlayerJumpState.cs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Player Controller/PlayerMoveState.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Scripts/Player Controller/PlayerMoveState.cs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Player Controller/PlayerRunState.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Scripts/Player Controller/PlayerRunState.cs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Scripts/GameSetup/Maze/Maze.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Scripts/GameSetup/Maze/Maze.cs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Player Controller/PlayerStateMachine.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Scripts/Player Controller/PlayerStateMachine.cs" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
@@ -47,27 +37,27 @@
<option name="hideEmptyMiddlePackages" value="true" />
<option name="showLibraryContents" value="true" />
</component>
<component name="PropertiesComponent"><![CDATA[{
"keyToString": {
"ModuleVcsDetector.initialDetectionPerformed": "true",
"RunOnceActivity.MCP Project settings loaded": "true",
"RunOnceActivity.ShowReadmeOnStart": "true",
"RunOnceActivity.TerminalTabsStorage.copyFrom.TerminalArrangementManager.252": "true",
"RunOnceActivity.git.unshallow": "true",
"RunOnceActivity.typescript.service.memoryLimit.init": "true",
"com.intellij.ml.llm.matterhorn.ej.ui.settings.DefaultModelSelectionForGA.v1": "true",
"git-widget-placeholder": "Tuan",
"junie.onboarding.icon.badge.shown": "true",
"node.js.detected.package.eslint": "true",
"node.js.detected.package.tslint": "true",
"node.js.selected.package.eslint": "(autodetect)",
"node.js.selected.package.tslint": "(autodetect)",
"nodejs_package_manager_path": "npm",
"settings.editor.selected.configurable": "preferences.pluginManager",
"to.speed.mode.migration.done": "true",
"vue.rearranger.settings.migration": "true"
<component name="PropertiesComponent">{
&quot;keyToString&quot;: {
&quot;ModuleVcsDetector.initialDetectionPerformed&quot;: &quot;true&quot;,
&quot;RunOnceActivity.MCP Project settings loaded&quot;: &quot;true&quot;,
&quot;RunOnceActivity.ShowReadmeOnStart&quot;: &quot;true&quot;,
&quot;RunOnceActivity.TerminalTabsStorage.copyFrom.TerminalArrangementManager.252&quot;: &quot;true&quot;,
&quot;RunOnceActivity.git.unshallow&quot;: &quot;true&quot;,
&quot;RunOnceActivity.typescript.service.memoryLimit.init&quot;: &quot;true&quot;,
&quot;com.intellij.ml.llm.matterhorn.ej.ui.settings.DefaultModelSelectionForGA.v1&quot;: &quot;true&quot;,
&quot;git-widget-placeholder&quot;: &quot;Tuan&quot;,
&quot;junie.onboarding.icon.badge.shown&quot;: &quot;true&quot;,
&quot;node.js.detected.package.eslint&quot;: &quot;true&quot;,
&quot;node.js.detected.package.tslint&quot;: &quot;true&quot;,
&quot;node.js.selected.package.eslint&quot;: &quot;(autodetect)&quot;,
&quot;node.js.selected.package.tslint&quot;: &quot;(autodetect)&quot;,
&quot;nodejs_package_manager_path&quot;: &quot;npm&quot;,
&quot;settings.editor.selected.configurable&quot;: &quot;preferences.pluginManager&quot;,
&quot;to.speed.mode.migration.done&quot;: &quot;true&quot;,
&quot;vue.rearranger.settings.migration&quot;: &quot;true&quot;
}
}]]></component>
}</component>
<component name="RunManager" selected="Attach to Unity Editor.Attach to Unity Editor">
<configuration name="Standalone Player" type="RunUnityExe" factoryName="Unity Executable">
<option name="EXE_PATH" value="$PROJECT_DIR$/../BAI MUTIPLAY\HALLUCINATE.exe" />
@@ -141,6 +131,7 @@
<workItem from="1775313757656" duration="8722000" />
<workItem from="1776130728673" duration="7161000" />
<workItem from="1776255558934" duration="1896000" />
<workItem from="1776734429973" duration="5497000" />
</task>
<servers />
</component>

View File

@@ -137,7 +137,7 @@ GameObject:
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
m_IsActive: 0
--- !u!65 &75539242
BoxCollider:
m_ObjectHideFlags: 0
@@ -326,7 +326,7 @@ GameObject:
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
m_IsActive: 0
--- !u!114 &153890424
MonoBehaviour:
m_ObjectHideFlags: 0
@@ -566,6 +566,143 @@ MonoBehaviour:
m_ShadowLayerMask: 1
m_RenderingLayers: 1
m_ShadowRenderingLayers: 1
--- !u!1 &537584989
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 537584990}
- component: {fileID: 537584991}
- component: {fileID: 537584992}
m_Layer: 5
m_Name: WIN
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &537584990
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 537584989}
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: 2014458575}
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: -37.7702, y: -14.4365}
m_SizeDelta: {x: 333.5404, y: 101.1271}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &537584991
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 537584989}
m_CullTransparentMesh: 1
--- !u!114 &537584992
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 537584989}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3}
m_Name:
m_EditorClassIdentifier: Unity.TextMeshPro::TMPro.TextMeshProUGUI
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_text: New Text
m_isRightToLeft: 0
m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2}
m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2}
m_fontSharedMaterials: []
m_fontMaterial: {fileID: 0}
m_fontMaterials: []
m_fontColor32:
serializedVersion: 2
rgba: 4294967295
m_fontColor: {r: 1, g: 1, b: 1, a: 1}
m_enableVertexGradient: 0
m_colorMode: 3
m_fontColorGradient:
topLeft: {r: 1, g: 1, b: 1, a: 1}
topRight: {r: 1, g: 1, b: 1, a: 1}
bottomLeft: {r: 1, g: 1, b: 1, a: 1}
bottomRight: {r: 1, g: 1, b: 1, a: 1}
m_fontColorGradientPreset: {fileID: 0}
m_spriteAsset: {fileID: 0}
m_tintAllSprites: 0
m_StyleSheet: {fileID: 0}
m_TextStyleHashCode: -1183493901
m_overrideHtmlColors: 0
m_faceColor:
serializedVersion: 2
rgba: 4294967295
m_fontSize: 36
m_fontSizeBase: 36
m_fontWeight: 400
m_enableAutoSizing: 0
m_fontSizeMin: 18
m_fontSizeMax: 72
m_fontStyle: 0
m_HorizontalAlignment: 1
m_VerticalAlignment: 256
m_textAlignment: 65535
m_characterSpacing: 0
m_characterHorizontalScale: 1
m_wordSpacing: 0
m_lineSpacing: 0
m_lineSpacingMax: 0
m_paragraphSpacing: 0
m_charWidthMaxAdj: 0
m_TextWrappingMode: 1
m_wordWrappingRatios: 0.4
m_overflowMode: 0
m_linkedTextComponent: {fileID: 0}
parentLinkedComponent: {fileID: 0}
m_enableKerning: 0
m_ActiveFontFeatures: 6e72656b
m_enableExtraPadding: 0
checkPaddingRequired: 0
m_isRichText: 1
m_EmojiFallbackSupport: 1
m_parseCtrlCharacters: 1
m_isOrthographic: 1
m_isCullingEnabled: 0
m_horizontalMapping: 0
m_verticalMapping: 0
m_uvLineOffset: 0
m_geometrySortingOrder: 0
m_IsTextObjectScaleStatic: 0
m_VertexBufferAutoSizeReduction: 0
m_useMaxVisibleDescender: 1
m_pageToDisplay: 1
m_margin: {x: 0, y: 0, z: 0, w: 0}
m_isUsingLegacyAnimationComponent: 0
m_isVolumetricText: 0
m_hasFontAssetChanged: 0
m_baseMaterial: {fileID: 0}
m_maskOffset: {x: 0, y: 0, z: 0, w: 0}
--- !u!1 &731807201
GameObject:
m_ObjectHideFlags: 0
@@ -584,7 +721,7 @@ GameObject:
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
m_IsActive: 0
--- !u!65 &731807202
BoxCollider:
m_ObjectHideFlags: 0
@@ -678,6 +815,122 @@ Transform:
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &792545169
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 792545173}
- component: {fileID: 792545172}
- component: {fileID: 792545171}
- component: {fileID: 792545170}
- component: {fileID: 792545174}
m_Layer: 0
m_Name: Maze Generator
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &792545170
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 792545169}
m_Enabled: 0
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: f12a5f6746a454e08a295f64a34f5dcf, type: 3}
m_Name:
m_EditorClassIdentifier: Assembly-CSharp::Prims
width: 30
depth: 30
scale: 6
_mapParentObjet: {fileID: 1759410438}
_MazeSeed: 0
wallMaterial: {fileID: 2100000, guid: 57d02ef294a3bd04fa1e148123d97194, type: 2}
floorMaterial: {fileID: 2100000, guid: 57d02ef294a3bd04fa1e148123d97194, type: 2}
goalPrefab: {fileID: 0}
--- !u!114 &792545171
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 792545169}
m_Enabled: 0
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 1039d646c358a4bd5ac697b0446a2f7e, type: 3}
m_Name:
m_EditorClassIdentifier: Assembly-CSharp::Maze
width: 30
depth: 30
scale: 6
_mapParentObjet: {fileID: 1759410438}
_MazeSeed: 0
wallMaterial: {fileID: 2100000, guid: 57d02ef294a3bd04fa1e148123d97194, type: 2}
floorMaterial: {fileID: 2100000, guid: 57d02ef294a3bd04fa1e148123d97194, type: 2}
goalPrefab: {fileID: 0}
--- !u!114 &792545172
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 792545169}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 33bbdb95ccc4b4577a62495732a02d3e, type: 3}
m_Name:
m_EditorClassIdentifier: Assembly-CSharp::Recursive
width: 30
depth: 30
scale: 7
_mapParentObjet: {fileID: 1759410438}
_MazeSeed: 0
wallMaterial: {fileID: 2100000, guid: 57d02ef294a3bd04fa1e148123d97194, type: 2}
floorMaterial: {fileID: 2100000, guid: 57d02ef294a3bd04fa1e148123d97194, type: 2}
goalPrefab: {fileID: 0}
--- !u!4 &792545173
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 792545169}
serializedVersion: 2
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: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &792545174
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 792545169}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: -1552182283, guid: e725a070cec140c4caffb81624c8c787, type: 3}
m_Name:
m_EditorClassIdentifier: Fusion.Runtime.dll::Fusion.NetworkObject
SortKey: 166757071
ObjectInterest: 1
Flags: 262145
NestedObjects: []
NetworkedBehaviours:
- {fileID: 792545172}
- {fileID: 792545171}
- {fileID: 792545170}
ForceRemoteRenderTimeframe: 0
--- !u!1 &830381275 stripped
GameObject:
m_CorrespondingSourceObject: {fileID: 4300131081491030878, guid: 120d7631bf5b4b94f8271411b1868e06, type: 3}
@@ -717,6 +970,119 @@ Light:
m_CorrespondingSourceObject: {fileID: 3593740734441989150, guid: 120d7631bf5b4b94f8271411b1868e06, type: 3}
m_PrefabInstance: {fileID: 1937191200}
m_PrefabAsset: {fileID: 0}
--- !u!1 &856138082
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 856138083}
- component: {fileID: 856138086}
- component: {fileID: 856138085}
- component: {fileID: 856138084}
m_Layer: 6
m_Name: Ground
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &856138083
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 856138082}
serializedVersion: 2
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 50, y: 1, z: 50}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 2050395245}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!64 &856138084
MeshCollider:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 856138082}
m_Material: {fileID: 0}
m_IncludeLayers:
serializedVersion: 2
m_Bits: 0
m_ExcludeLayers:
serializedVersion: 2
m_Bits: 0
m_LayerOverridePriority: 0
m_IsTrigger: 0
m_ProvidesContacts: 0
m_Enabled: 1
serializedVersion: 5
m_Convex: 0
m_CookingOptions: 30
m_Mesh: {fileID: 10209, guid: 0000000000000000e000000000000000, type: 0}
--- !u!23 &856138085
MeshRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 856138082}
m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_StaticShadowCaster: 0
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RayTracingMode: 2
m_RayTraceProcedural: 0
m_RayTracingAccelStructBuildFlagsOverride: 0
m_RayTracingAccelStructBuildFlags: 1
m_SmallMeshCulling: 1
m_ForceMeshLod: -1
m_MeshLodSelectionBias: 0
m_RenderingLayerMask: 1
m_RendererPriority: 0
m_Materials:
- {fileID: 2100000, guid: e2e2684e969402049b87d7f81417c603, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0
subMeshCount: 0
m_StaticBatchRoot: {fileID: 0}
m_ProbeAnchor: {fileID: 0}
m_LightProbeVolumeOverride: {fileID: 0}
m_ScaleInLightmap: 1
m_ReceiveGI: 1
m_PreserveUVs: 0
m_IgnoreNormalsForChartDetection: 0
m_ImportantGI: 0
m_StitchLightmapSeams: 1
m_SelectedEditorRenderState: 3
m_MinimumChartSize: 4
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_GlobalIlluminationMeshLod: 0
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
m_MaskInteraction: 0
m_AdditionalVertexStreams: {fileID: 0}
--- !u!33 &856138086
MeshFilter:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 856138082}
m_Mesh: {fileID: 10209, guid: 0000000000000000e000000000000000, type: 0}
--- !u!1 &874617061 stripped
GameObject:
m_CorrespondingSourceObject: {fileID: 5789896249604009285, guid: 120d7631bf5b4b94f8271411b1868e06, type: 3}
@@ -1091,7 +1457,7 @@ GameObject:
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
m_IsActive: 0
--- !u!64 &1437922949
MeshCollider:
m_ObjectHideFlags: 0
@@ -1186,6 +1552,143 @@ Transform:
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &1476208410
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1476208413}
- component: {fileID: 1476208412}
- component: {fileID: 1476208411}
m_Layer: 5
m_Name: TIME
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &1476208411
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1476208410}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3}
m_Name:
m_EditorClassIdentifier: Unity.TextMeshPro::TMPro.TextMeshProUGUI
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_text: TIME 0:00
m_isRightToLeft: 0
m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2}
m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2}
m_fontSharedMaterials: []
m_fontMaterial: {fileID: 0}
m_fontMaterials: []
m_fontColor32:
serializedVersion: 2
rgba: 4294967295
m_fontColor: {r: 1, g: 1, b: 1, a: 1}
m_enableVertexGradient: 0
m_colorMode: 3
m_fontColorGradient:
topLeft: {r: 1, g: 1, b: 1, a: 1}
topRight: {r: 1, g: 1, b: 1, a: 1}
bottomLeft: {r: 1, g: 1, b: 1, a: 1}
bottomRight: {r: 1, g: 1, b: 1, a: 1}
m_fontColorGradientPreset: {fileID: 0}
m_spriteAsset: {fileID: 0}
m_tintAllSprites: 0
m_StyleSheet: {fileID: 0}
m_TextStyleHashCode: -1183493901
m_overrideHtmlColors: 0
m_faceColor:
serializedVersion: 2
rgba: 4294967295
m_fontSize: 36
m_fontSizeBase: 36
m_fontWeight: 400
m_enableAutoSizing: 0
m_fontSizeMin: 18
m_fontSizeMax: 72
m_fontStyle: 0
m_HorizontalAlignment: 1
m_VerticalAlignment: 256
m_textAlignment: 65535
m_characterSpacing: 0
m_characterHorizontalScale: 1
m_wordSpacing: 0
m_lineSpacing: 0
m_lineSpacingMax: 0
m_paragraphSpacing: 0
m_charWidthMaxAdj: 0
m_TextWrappingMode: 1
m_wordWrappingRatios: 0.4
m_overflowMode: 0
m_linkedTextComponent: {fileID: 0}
parentLinkedComponent: {fileID: 0}
m_enableKerning: 0
m_ActiveFontFeatures: 6e72656b
m_enableExtraPadding: 0
checkPaddingRequired: 0
m_isRichText: 1
m_EmojiFallbackSupport: 1
m_parseCtrlCharacters: 1
m_isOrthographic: 1
m_isCullingEnabled: 0
m_horizontalMapping: 0
m_verticalMapping: 0
m_uvLineOffset: 0
m_geometrySortingOrder: 0
m_IsTextObjectScaleStatic: 0
m_VertexBufferAutoSizeReduction: 0
m_useMaxVisibleDescender: 1
m_pageToDisplay: 1
m_margin: {x: 0, y: 0, z: 0, w: 0}
m_isUsingLegacyAnimationComponent: 0
m_isVolumetricText: 0
m_hasFontAssetChanged: 0
m_baseMaterial: {fileID: 0}
m_maskOffset: {x: 0, y: 0, z: 0, w: 0}
--- !u!222 &1476208412
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1476208410}
m_CullTransparentMesh: 1
--- !u!224 &1476208413
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1476208410}
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: 1579856156}
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: -800, y: 482}
m_SizeDelta: {x: 200, y: 50}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!1 &1493821249
GameObject:
m_ObjectHideFlags: 0
@@ -1315,7 +1818,7 @@ Canvas:
m_OverridePixelPerfect: 0
m_SortingBucketNormalizedSize: 0
m_VertexColorAlwaysGammaSpace: 0
m_AdditionalShaderChannelsFlag: 0
m_AdditionalShaderChannelsFlag: 25
m_UpdateRectTransformForStandalone: 0
m_SortingLayerID: 0
m_SortingOrder: 0
@@ -1333,6 +1836,8 @@ RectTransform:
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 1493821250}
- {fileID: 2014458575}
- {fileID: 1476208413}
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
@@ -1359,7 +1864,7 @@ GameObject:
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
m_IsActive: 0
--- !u!114 &1667007658
MonoBehaviour:
m_ObjectHideFlags: 0
@@ -1487,7 +1992,7 @@ GameObject:
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
m_IsActive: 0
--- !u!65 &1738061768
BoxCollider:
m_ObjectHideFlags: 0
@@ -1581,6 +2086,37 @@ Transform:
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &1759410437
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1759410438}
m_Layer: 0
m_Name: _MapParentObject
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &1759410438
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1759410437}
serializedVersion: 2
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: 2050395245}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &1771364109 stripped
GameObject:
m_CorrespondingSourceObject: {fileID: 1534469393933210, guid: b5a5a17dc3a6d9e47bd468828a2dec34, type: 3}
@@ -1830,6 +2366,131 @@ PrefabInstance:
insertIndex: -1
addedObject: {fileID: 830381277}
m_SourcePrefab: {fileID: 100100000, guid: 120d7631bf5b4b94f8271411b1868e06, type: 3}
--- !u!1 &2014458574
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 2014458575}
- component: {fileID: 2014458577}
- component: {fileID: 2014458576}
m_Layer: 5
m_Name: Panel
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 0
--- !u!224 &2014458575
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2014458574}
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: 537584990}
m_Father: {fileID: 1579856156}
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 &2014458576
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2014458574}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
m_Name:
m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.Image
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 0.392}
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: 10907, guid: 0000000000000000f000000000000000, type: 0}
m_Type: 1
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 &2014458577
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2014458574}
m_CullTransparentMesh: 1
--- !u!1 &2050395244
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 2050395245}
- component: {fileID: 2050395246}
m_Layer: 0
m_Name: _MAP
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &2050395245
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2050395244}
serializedVersion: 2
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: 1759410438}
- {fileID: 856138083}
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &2050395246
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2050395244}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 4d7143f5824569245ae215ae06b6cce1, type: 3}
m_Name:
m_EditorClassIdentifier: Assembly-CSharp::OnlyScove.Scripts.UI.MazeUI
winPanel: {fileID: 2014458574}
winMessageText: {fileID: 537584992}
timerText: {fileID: 1476208411}
--- !u!1001 &3886963620680427248
PrefabInstance:
m_ObjectHideFlags: 0
@@ -1955,3 +2616,5 @@ SceneRoots:
- {fileID: 1579856156}
- {fileID: 153890428}
- {fileID: 1937191200}
- {fileID: 792545173}
- {fileID: 2050395245}

View File

@@ -8,7 +8,6 @@ using UnityEngine;
using UnityEngine.SceneManagement;
using Random = UnityEngine.Random;
// Struct input đồng bộ giữa Spawner, Movement và StateMachine
public struct PlayerInputData : INetworkInput
{
public Vector2 Direction;
@@ -25,7 +24,6 @@ public class BasicSpawner : MonoBehaviour, INetworkRunnerCallbacks
[SerializeField] private NetworkPrefabRef _playerPrefab;
private Dictionary<PlayerRef, NetworkObject> _spawnedCharacters = new Dictionary<PlayerRef, NetworkObject>();
// Thông tin profile local
public PlayerProfile LocalPlayerProfile { get; private set; }
public void SetLocalPlayerProfile(PlayerProfile profile)
{
@@ -38,10 +36,9 @@ public class BasicSpawner : MonoBehaviour, INetworkRunnerCallbacks
DontDestroyOnLoad(gameObject);
}
// Khởi tạo Game (Host/Client)
public async Task StartGame(GameMode mode, string sessionName = "TestRoom")
{
Debug.Log($"<color=yellow>Fusion:</color> Đang khởi tạo kết nối với Mode: {mode} | Phòng: {sessionName}");
Debug.Log($"<color=yellow>Fusion:</color> Starting with Mode: {mode} | Room: {sessionName}");
if (_runner == null) _runner = gameObject.AddComponent<NetworkRunner>();
_runner.ProvideInput = true;
@@ -57,18 +54,10 @@ public class BasicSpawner : MonoBehaviour, INetworkRunnerCallbacks
SceneManager = sceneManager
});
if (result.Ok)
if (!result.Ok)
{
Debug.Log($"<color=green>Fusion thành công:</color> Đã vào phòng {sessionName}");
}
else
{
Debug.LogError($"<color=red>Fusion thất bại:</color> Lý do: {result.ShutdownReason}");
if (_runner != null)
{
Destroy(_runner);
_runner = null;
}
Debug.LogError($"<color=red>Fusion failed:</color> {result.ShutdownReason}");
if (_runner != null) { Destroy(_runner); _runner = null; }
}
}
@@ -76,20 +65,12 @@ public class BasicSpawner : MonoBehaviour, INetworkRunnerCallbacks
{
if (_runner == null || !_runner.IsRunning)
{
float width = 400;
float height = 300;
float x = (Screen.width - width) / 2f;
float y = (Screen.height - height) / 2f;
float width = 400; float height = 300;
float x = (Screen.width - width) / 2f; float y = (Screen.height - height) / 2f;
GUI.Box(new Rect(x, y, width, height), "FUSION MULTIPLAYER");
float innerX = x + 20;
float innerY = y + 40;
float contentWidth = width - 40;
GUI.Label(new Rect(innerX, innerY, 100, 30), "Tên phòng:");
float innerX = x + 20; float innerY = y + 40; float contentWidth = width - 40;
GUI.Label(new Rect(innerX, innerY, 100, 30), "Room Name:");
_roomName = GUI.TextField(new Rect(innerX + 100, innerY, contentWidth - 100, 30), _roomName);
if (GUI.Button(new Rect(innerX, innerY + 50, contentWidth, 60), "VÀO PHÒNG\n(Tự động Host/Client)"))
{
_ = StartGame(GameMode.AutoHostOrClient, _roomName);
@@ -127,8 +108,8 @@ public class BasicSpawner : MonoBehaviour, INetworkRunnerCallbacks
{
if (runner.IsServer)
{
Vector3 spawnPosition = new Vector3(Random.Range(-10f, 10f), 2f, Random.Range(-10f, 10f));
spawnPosition += new Vector3(player.RawEncoded % 3, 0, player.RawEncoded % 3);
Maze maze = GameObject.FindAnyObjectByType<Maze>();
Vector3 spawnPosition = (maze != null) ? maze.GetPlayerSpawnPoint() : new Vector3(0, 2f, 0);
var networkPlayerObject = runner.Spawn(_playerPrefab, spawnPosition, Quaternion.identity, player);
runner.SetPlayerObject(player, networkPlayerObject);
@@ -148,8 +129,6 @@ public class BasicSpawner : MonoBehaviour, INetworkRunnerCallbacks
public void OnInput(NetworkRunner runner, NetworkInput input)
{
var data = new PlayerInputData();
// ĐỌC TRỰC TIẾP: Không dùng Buffer để tránh bị trôi phím
data.Direction = new Vector2(Input.GetAxisRaw("Horizontal"), Input.GetAxisRaw("Vertical"));
data.sprint = Input.GetKey(KeyCode.LeftShift);
@@ -159,7 +138,6 @@ public class BasicSpawner : MonoBehaviour, INetworkRunnerCallbacks
if (sm.Cam != null) data.rot = sm.Cam.PlanarRotation;
else data.rot = sm.NetworkedCameraRotation;
}
input.Set(data);
}

View File

@@ -0,0 +1,38 @@
using UnityEngine;
using Fusion;
namespace OnlyScove.Scripts.GameSetup.Maze
{
public class GoalSpot : MonoBehaviour
{
private bool _isActivated = false;
private void OnTriggerEnter(Collider healthcare)
{
if (_isActivated) return;
// Kiểm tra xem đối tượng chạm vào có phải là người chơi không
PlayerStateMachine player = healthcare.GetComponentInParent<PlayerStateMachine>();
if (player != null)
{
bool isOffline = player.Runner == null || !player.Runner.IsRunning;
// Nếu có mạng, kiểm tra quyền điều khiển. Nếu offline, mặc định là người chơi cục bộ.
bool canActivate = isOffline || (player.Object != null && player.Object.HasInputAuthority);
if (canActivate)
{
_isActivated = true;
player.CompleteMaze();
// Hiệu ứng hình ảnh khi chạm đích
var renderer = GetComponent<Renderer>();
if (renderer != null) renderer.material.color = Color.green;
Debug.Log("<color=cyan>Goal reached!</color>");
}
}
}
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: d3b0727dd84fbb046ac472bb1404b363

View File

@@ -1,6 +1,8 @@
using System.Collections;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Fusion;
using OnlyScove.Scripts.GameSetup.Maze;
public class MapLocation
{
@@ -14,7 +16,7 @@ public class MapLocation
}
}
public class Maze : MonoBehaviour
public class Maze : NetworkBehaviour
{
public List<MapLocation> directions = new List<MapLocation>() {
new MapLocation(1,0),
@@ -27,14 +29,52 @@ public class Maze : MonoBehaviour
public int scale = 6;
public Transform _mapParentObjet;
// Start is called before the first frame update
void Start()
[Header("Sync & Materials")]
[Networked] public int MazeSeed { get; set; }
public Material wallMaterial;
public Material floorMaterial;
[Header("Win Condition")]
public GameObject goalPrefab;
public override void Spawned()
{
if (Object.HasStateAuthority)
{
// Nếu chưa có seed thì tạo mới
if (MazeSeed == 0) MazeSeed = Random.Range(1, 99999);
}
GenerateMazeWithSeed(MazeSeed);
}
public void GenerateMazeWithSeed(int seed)
{
if (_mapParentObjet != null)
{
// Dùng list để tránh lỗi modify collection khi đang duyệt
List<GameObject> children = new List<GameObject>();
foreach (Transform child in _mapParentObjet) children.Add(child.gameObject);
foreach (GameObject child in children) Destroy(child);
}
Random.InitState(seed);
InitialiseMap();
Generate();
// Ép ô (1,1) là đường đi cho player spawn
map[1, 1] = 0;
PlaceExit();
DrawMap();
}
public Vector3 GetPlayerSpawnPoint()
{
// Trả về vị trí tại ô (1,1). y = 1.0f cục bộ
return transform.TransformPoint(new Vector3(1 * scale, 1.0f, 1 * scale));
}
void InitialiseMap()
{
map = new byte[width,depth];
@@ -55,18 +95,60 @@ public class Maze : MonoBehaviour
}
}
public virtual void PlaceExit()
{
int x = width - 2;
int z = depth - 2;
map[x, z] = 2;
if (CountSquareNeighbours(x, z) == 0) map[x - 1, z] = 0;
}
void DrawMap()
{
if (_mapParentObjet == null) _mapParentObjet = this.transform;
// Tạo sàn chống rơi và Z-fighting
GameObject floor = GameObject.CreatePrimitive(PrimitiveType.Plane);
floor.name = "Floor";
floor.transform.SetParent(_mapParentObjet);
floor.transform.localPosition = new Vector3((width - 1) * scale / 2f, -0.05f, (depth - 1) * scale / 2f);
floor.transform.localScale = new Vector3(width * scale / 10f, 1, depth * scale / 10f);
if (floorMaterial != null) floor.GetComponent<Renderer>().material = floorMaterial;
for (int z = 0; z < depth; z++)
for (int x = 0; x < width; x++)
{
Vector3 pos = new Vector3(x * scale, scale / 2f, z * scale);
if (map[x, z] == 1)
{
Vector3 pos = new Vector3(x * scale, 0, z * scale);
GameObject wall = GameObject.CreatePrimitive(PrimitiveType.Cube);
wall.name = $"Wall_{x}_{z}";
wall.transform.localScale = new Vector3(scale, scale, scale);
wall.transform.position = pos;
wall.transform.SetParent(_mapParentObjet.transform);
wall.transform.SetParent(_mapParentObjet);
wall.transform.localPosition = pos;
if (wallMaterial != null) wall.GetComponent<Renderer>().material = wallMaterial;
}
else if (map[x, z] == 2)
{
GameObject goalObj;
if (goalPrefab != null)
goalObj = Instantiate(goalPrefab, transform.TransformPoint(pos), Quaternion.identity);
else
{
goalObj = GameObject.CreatePrimitive(PrimitiveType.Cylinder);
goalObj.GetComponent<Renderer>().material.color = Color.yellow;
goalObj.transform.localScale = new Vector3(scale * 0.5f, scale * 0.5f, scale * 0.5f);
}
goalObj.name = "Goal_WinSpot";
goalObj.transform.SetParent(_mapParentObjet);
goalObj.transform.localPosition = pos;
Collider col = goalObj.GetComponent<Collider>();
if (col == null) col = goalObj.AddComponent<CapsuleCollider>();
col.isTrigger = true;
if (goalObj.GetComponent<GoalSpot>() == null) goalObj.AddComponent<GoalSpot>();
}
}
}
@@ -97,4 +179,4 @@ public class Maze : MonoBehaviour
{
return CountSquareNeighbours(x,z) + CountDiagonalNeighbours(x,z);
}
}
}

View File

@@ -48,7 +48,6 @@ namespace OnlyScove.Scripts
[Networked] public Quaternion NetworkedCameraRotation { get; set; }
// Thuộc tính hỗ trợ lấy rotation của Camera an toàn cho cả Online và Offline
public Quaternion CameraRotation
{
get
@@ -65,7 +64,11 @@ namespace OnlyScove.Scripts
[Networked] public Vector2 NetworkedMoveInput { get; set; }
[Networked] public float NetworkedSpeed { get; set; }
[Networked] public Vector3 NetworkedPosition { get; set; }
[Networked] public int StartTick { get; set; }
public float FinishTime { get; set; }
public bool IsFinished { get; set; }
private float startTimeOffline;
public Vector2 MoveInput { get; private set; }
public bool IsSprintHeld { get; private set; }
@@ -82,6 +85,7 @@ namespace OnlyScove.Scripts
private PlayerBaseState currentState;
private bool hasControl = true;
private float localAnimatorSpeed;
private bool hasSpeedParam;
private bool hasVelocityXParam;
@@ -94,9 +98,10 @@ namespace OnlyScove.Scripts
Anim = GetComponentInChildren<Animator>();
Scanner = GetComponent<EnvironmentScanner>();
// Kiểm tra tham số có tồn tại trong Animator không để tránh lỗi log gây Disconnect
if (Anim != null)
{
// Ép tắt Root Motion để tránh lỗi cộng dồn tốc độ
Anim.applyRootMotion = false;
foreach (AnimatorControllerParameter param in Anim.parameters)
{
if (param.name == speedParamName) hasSpeedParam = true;
@@ -112,8 +117,6 @@ namespace OnlyScove.Scripts
private void Start()
{
// Nếu chạy Offline (kéo prefab vào scene), Spawned() sẽ không được gọi.
// Chúng ta khởi tạo tại đây để đảm bảo nhân vật hoạt động.
if (Runner == null || !Runner.IsRunning)
{
InitializePlayer();
@@ -122,11 +125,11 @@ namespace OnlyScove.Scripts
public override void Spawned()
{
// Fusion gọi Spawned khi object được nạp vào mạng.
InitializePlayer();
// Nếu không có quyền điều khiển và đang ở Client, tắt Controller để tránh xung đột
if (Object != null && !Object.HasInputAuthority && Runner.IsClient)
// QUAN TRỌNG: Vô hiệu hóa Controller của người chơi khác để tránh giật hình.
// NetworkTransform sẽ tự lo việc làm mượt vị trí của họ.
if (Object != null && !Object.HasInputAuthority && !Runner.IsServer)
{
if (Controller != null) Controller.enabled = false;
}
@@ -145,6 +148,7 @@ namespace OnlyScove.Scripts
if (isOffline || hasAuthority)
{
Local = this;
startTimeOffline = Time.time;
CameraController cameraController = GameObject.FindAnyObjectByType<CameraController>();
if (cameraController != null)
@@ -157,12 +161,14 @@ namespace OnlyScove.Scripts
Input.OnNextInteractEvent += OnNextInteract;
Input.OnPreviousInteractEvent += OnPreviousInteract;
// Đảm bảo Controller được bật
if (Controller != null) Controller.enabled = true;
}
}
private float localAnimatorSpeed;
if (!isOffline && Object.HasStateAuthority)
{
StartTick = (int)Runner.Tick;
}
}
public void Rotate(Vector3 moveDirection, float deltaTime)
{
@@ -178,20 +184,16 @@ namespace OnlyScove.Scripts
public void Move(Vector3 velocity, float animatorSpeed, float deltaTime)
{
// Cho phép di chuyển nếu:
// 1. Không có mạng (Offline test)
// 2. Có quyền điều khiển (Input Authority)
// 3. Là Server (State Authority)
bool canMove = (Runner == null || !Runner.IsRunning) || Object.HasInputAuthority || Runner.IsServer;
if (!canMove) return;
if (Controller != null && Controller.enabled)
{
Controller.Move(velocity * deltaTime);
// Cập nhật vị trí mạng ngay sau khi di chuyển
if (Object != null && Runner != null && Runner.IsRunning)
// SỬA LỖI CHẠY NHANH: Chỉ thực hiện lệnh Move vật lý trong Forward Tick.
// Điều này ngăn việc cộng dồn vận tốc khi Fusion chạy Re-simulation.
if (Runner == null || !Runner.IsRunning || Runner.IsForward)
{
NetworkedPosition = transform.position;
Controller.Move(velocity * deltaTime);
}
}
@@ -224,7 +226,6 @@ namespace OnlyScove.Scripts
inputVector = NetworkedMoveInput;
}
// Chỉ Set nếu tham số thực sự tồn tại (Tránh lỗi Hash does not exist)
if (hasSpeedParam) Anim.SetFloat(speedHash, speedValue, AnimationDamping, deltaTime);
if (hasVelocityXParam) Anim.SetFloat(velocityXHash, inputVector.x * speedValue, AnimationDamping, deltaTime);
if (hasVelocityZParam) Anim.SetFloat(velocityZHash, inputVector.y * speedValue, AnimationDamping, deltaTime);
@@ -232,33 +233,13 @@ namespace OnlyScove.Scripts
public override void FixedUpdateNetwork()
{
bool isRunning = Runner != null && Runner.IsRunning;
if (Object == null && isRunning) return;
// ĐỒNG BỘ VỊ TRÍ: Ép nhân vật về vị trí mạng trước khi tính toán tick mới
if (isRunning && NetworkedPosition != Vector3.zero)
{
if (Controller != null && !Object.HasInputAuthority)
{
Controller.enabled = false;
transform.position = NetworkedPosition;
Controller.enabled = true;
}
}
if (Object == null || !Runner.IsRunning) return;
if (GetInput(out PlayerInputData data))
{
MoveInput = data.Direction;
IsSprintHeld = data.sprint;
// Chỉ gán biến Networked nếu đang chạy mạng
if (isRunning) NetworkedCameraRotation = data.rot;
}
else if (!isRunning)
{
// FALLBACK INPUT: Nếu không có Fusion, lấy input trực tiếp từ Unity để Test
MoveInput = new Vector2(UnityEngine.Input.GetAxisRaw("Horizontal"), UnityEngine.Input.GetAxisRaw("Vertical"));
IsSprintHeld = UnityEngine.Input.GetKey(KeyCode.LeftShift);
// Ở chế độ offline, chúng ta không gán vào NetworkedCameraRotation nữa
NetworkedCameraRotation = data.rot;
}
else
{
@@ -266,7 +247,8 @@ namespace OnlyScove.Scripts
IsSprintHeld = false;
}
bool isSimulating = !isRunning || Object.HasInputAuthority || Runner.IsServer;
// Chỉ giả lập cho máy có quyền điều khiển hoặc Server
bool isSimulating = Object.HasInputAuthority || Runner.IsServer;
if (!isSimulating)
{
@@ -280,17 +262,19 @@ namespace OnlyScove.Scripts
CheckGround();
UpdateInteractablesList();
float dt = isRunning ? Runner.DeltaTime : Time.fixedDeltaTime;
currentState?.Tick(dt);
currentState?.Tick(Runner.DeltaTime);
}
private void Update()
{
// Nếu không có NetworkRunner, Fusion sẽ không gọi FixedUpdateNetwork.
// Chúng ta gọi thủ công để logic StateMachine vẫn chạy được khi Test Offline.
if (Runner == null || !Runner.IsRunning)
bool isOffline = Runner == null || !Runner.IsRunning;
if (isOffline)
{
FixedUpdateNetwork();
if (!IsFinished && UI.MazeUI.Instance != null)
{
UI.MazeUI.Instance.UpdateTimer(Time.time - startTimeOffline);
}
}
}
@@ -351,5 +335,62 @@ namespace OnlyScove.Scripts
Gizmos.color = new Color(0, 1, 0, 0.5f);
Gizmos.DrawSphere(transform.TransformPoint(GroundCheckOffset), GroundCheckRadius);
}
#region Maze Winning Logic
public void CompleteMaze()
{
if (IsFinished) return;
float duration;
if (Runner != null && Runner.IsRunning)
{
duration = ((int)Runner.Tick - StartTick) * Runner.DeltaTime;
Rpc_BroadcastWin(Object.InputAuthority, duration);
}
else
{
duration = Time.time - startTimeOffline;
if (UI.MazeUI.Instance != null)
{
UI.MazeUI.Instance.ShowWinMessage("YOU (Offline)", duration);
}
}
IsFinished = true;
FinishTime = duration;
}
[Rpc(RpcSources.All, RpcTargets.All)]
public void Rpc_BroadcastWin(PlayerRef player, float time)
{
string playerName = $"Player {player.PlayerId}";
if (Runner != null && player == Runner.LocalPlayer) playerName = "YOU";
Debug.Log($"<color=yellow><b>[WINNER]</b></color> {playerName} reached the goal in <b>{time:F2}s</b>!");
if (UI.MazeUI.Instance != null)
{
UI.MazeUI.Instance.ShowWinMessage(playerName, time);
}
}
public override void Render()
{
bool isOffline = Runner == null || !Runner.IsRunning;
bool hasAuthority = Object != null && Object.HasInputAuthority;
if ((isOffline || hasAuthority) && !IsFinished)
{
float currentTimer = isOffline ? (Time.time - startTimeOffline) : (((int)Runner.Tick - StartTick) * Runner.DeltaTime);
if (UI.MazeUI.Instance != null)
{
UI.MazeUI.Instance.UpdateTimer(currentTimer);
}
}
}
#endregion
}
}

View File

@@ -0,0 +1,51 @@
using UnityEngine;
using TMPro;
using System.Collections;
namespace OnlyScove.Scripts.UI
{
public class MazeUI : MonoBehaviour
{
public static MazeUI Instance { get; private set; }
[Header("References")]
[SerializeField] private GameObject winPanel;
[SerializeField] private TextMeshProUGUI winMessageText;
[SerializeField] private TextMeshProUGUI timerText;
private void Awake()
{
if (Instance == null) Instance = this;
else Destroy(gameObject);
if (winPanel != null) winPanel.SetActive(false);
}
public void UpdateTimer(float time)
{
if (timerText != null)
timerText.text = $"Time: {time:F2}s";
}
public void ShowWinMessage(string playerName, float time)
{
if (winPanel == null) return;
winPanel.SetActive(true);
if (winMessageText != null)
{
winMessageText.text = $"<color=yellow>{playerName}</color>\nREACHED THE GOAL!\n<size=80%>IN {time:F2} SECONDS</size>";
}
// Tự động ẩn sau 5 giây
StopAllCoroutines();
StartCoroutine(HideWinPanel());
}
private IEnumerator HideWinPanel()
{
yield return new WaitForSeconds(5f);
winPanel.SetActive(false);
}
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 4d7143f5824569245ae215ae06b6cce1

View File

@@ -132,7 +132,7 @@ Material:
- _ZWrite: 1
m_Colors:
- _BaseColor: {r: 0.07799999, g: 0.07799999, b: 0.07799999, a: 1}
- _Color: {r: 1, g: 1, b: 1, a: 1}
- _Color: {r: 0.07799996, g: 0.07799996, b: 0.07799996, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1}
m_BuildTextureStacks: []

File diff suppressed because one or more lines are too long