浏览代码

Start faceoff working

Axel Nordh 3 月之前
父节点
当前提交
2d6ff87cc6
共有 36 个文件被更改,包括 2288 次插入63 次删除
  1. 7 0
      Assembly-CSharp.csproj
  2. 64 0
      Assets/Prefab/Player.prefab
  3. 235 3
      Assets/Scenes/SampleScene.unity
  4. 28 0
      Assets/ScriptableObjects/HT_MovementSchema.asset
  5. 8 0
      Assets/ScriptableObjects/HT_MovementSchema.asset.meta
  6. 16 0
      Assets/Scripts/FaceoffManager.cs
  7. 183 0
      Assets/Scripts/GameManager.cs
  8. 2 0
      Assets/Scripts/GameManager.cs.meta
  9. 16 0
      Assets/Scripts/GameState.cs
  10. 2 0
      Assets/Scripts/GameState.cs.meta
  11. 37 8
      Assets/Scripts/MainGameScript.cs
  12. 241 0
      Assets/Scripts/Player/AI/AI_MOVEMENT_GUIDE.md
  13. 7 0
      Assets/Scripts/Player/AI/AI_MOVEMENT_GUIDE.md.meta
  14. 68 0
      Assets/Scripts/Player/AI/MovementSchema.cs
  15. 2 0
      Assets/Scripts/Player/AI/MovementSchema.cs.meta
  16. 634 0
      Assets/Scripts/Player/AI/PlayerAIMovement.cs
  17. 2 0
      Assets/Scripts/Player/AI/PlayerAIMovement.cs.meta
  18. 37 2
      Assets/Scripts/Player/PlayerController.cs
  19. 111 4
      Assets/Scripts/Player/PlayerMovement.cs
  20. 100 0
      Assets/Scripts/UIController.cs
  21. 2 0
      Assets/Scripts/UIController.cs.meta
  22. 8 0
      Assets/UI Toolkit.meta
  23. 8 0
      Assets/UI Toolkit/UnityThemes.meta
  24. 1 0
      Assets/UI Toolkit/UnityThemes/UnityDefaultRuntimeTheme.tss
  25. 11 0
      Assets/UI Toolkit/UnityThemes/UnityDefaultRuntimeTheme.tss.meta
  26. 8 0
      Assets/UI.meta
  27. 75 0
      Assets/UI/GameUI.uss
  28. 11 0
      Assets/UI/GameUI.uss.meta
  29. 19 0
      Assets/UI/GameUI.uxml
  30. 10 0
      Assets/UI/GameUI.uxml.meta
  31. 49 0
      Assets/UI/PanelSettings.asset
  32. 8 0
      Assets/UI/PanelSettings.asset.meta
  33. 224 0
      Assets/UI/SETUP_INSTRUCTIONS.md
  34. 7 0
      Assets/UI/SETUP_INSTRUCTIONS.md.meta
  35. 1 0
      ProjectSettings/TagManager.asset
  36. 46 46
      UserSettings/Layouts/default-6000.dwlt

+ 7 - 0
Assembly-CSharp.csproj

@@ -55,9 +55,12 @@
     <Compile Include="Assets\Scripts\Player\AI\AIStrategy.cs" />
     <Compile Include="Assets\Scripts\FaceoffDebugVisualizer.cs" />
     <Compile Include="Assets\Scripts\Player\PlayerInput.cs" />
+    <Compile Include="Assets\Scripts\Player\AI\PlayerAIMovement.cs" />
     <Compile Include="Assets\Scripts\Player\PlayerMovement.cs" />
+    <Compile Include="Assets\Scripts\Player\AI\MovementSchema.cs" />
     <Compile Include="Assets\Scripts\Player\PlayerController.cs" />
     <Compile Include="Assets\Scripts\FaceoffPositioning.cs" />
+    <Compile Include="Assets\Scripts\UIController.cs" />
     <Compile Include="Assets\Scripts\FaceoffManager.cs" />
     <Compile Include="Assets\Scripts\GameSetup.cs" />
     <Compile Include="Assets\Scripts\Player\AI\PlayerMentality.cs" />
@@ -66,8 +69,10 @@
     <Compile Include="Assets\Scripts\PuckController.cs" />
     <Compile Include="Assets\Scripts\PuckDebugVisualizer.cs" />
     <Compile Include="Assets\Scripts\Player\PlayerAnimationController.cs" />
+    <Compile Include="Assets\Scripts\GameManager.cs" />
     <Compile Include="Assets\Scripts\Player\AI\DefensiveStrategy.cs" />
     <Compile Include="Assets\Scripts\Player\AI\PlayerDecisionMaker.cs" />
+    <Compile Include="Assets\Scripts\GameState.cs" />
     <Compile Include="Assets\Scripts\LayerAssigner.cs" />
   </ItemGroup>
   <ItemGroup>
@@ -87,7 +92,9 @@
     <None Include="Assets\TextMesh Pro\Resources\LineBreaking Leading Characters.txt" />
     <None Include="Assets\TextMesh Pro\Shaders\TMPro_Properties.cginc" />
     <None Include="Assets\TextMesh Pro\Shaders\TMPro_Surface.cginc" />
+    <None Include="Assets\UI\GameUI.uss" />
     <None Include="Assets\TextMesh Pro\Resources\LineBreaking Following Characters.txt" />
+    <None Include="Assets\UI\GameUI.uxml" />
     <None Include="Assets\TextMesh Pro\Shaders\TMP_SDF-Mobile Masking.shader" />
     <None Include="Assets\TextMesh Pro\Shaders\TMP_SDF Overlay.shader" />
     <None Include="Assets\TextMesh Pro\Shaders\TMP_Bitmap-Mobile.shader" />

+ 64 - 0
Assets/Prefab/Player.prefab

@@ -15,6 +15,8 @@ GameObject:
   - component: {fileID: 4675720318839872098}
   - component: {fileID: 27884271605259228}
   - component: {fileID: 4365312241421401184}
+  - component: {fileID: 6960256348343429607}
+  - component: {fileID: 5895347483119069536}
   m_Layer: 0
   m_Name: Player
   m_TagString: Untagged
@@ -134,6 +136,8 @@ MonoBehaviour:
   currentStrategy: {fileID: 0}
   positionLabel: {fileID: 6855596396214686973}
   circleMesh: {fileID: 155091773289725482}
+  possessionIndicator: {fileID: 0}
+  pickupCooldown: 0.5
 --- !u!114 &27884271605259228
 MonoBehaviour:
   m_ObjectHideFlags: 0
@@ -158,8 +162,68 @@ MonoBehaviour:
   m_Script: {fileID: 11500000, guid: 38e6bd2938646304c806b8cbb5c496a0, type: 3}
   m_Name: 
   m_EditorClassIdentifier: Assembly-CSharp::PlayerMovement
+  isPlayerControlled: 0
   moveSpeed: 5
   rotationSpeed: 10
+  maxSpeed: 8
+  acceleration: 15
+  deceleration: 10
+--- !u!114 &6960256348343429607
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 155091773289725482}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 52e16bdebf3d7dc42862c533368c009b, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: Assembly-CSharp::PlayerAIMovement
+  playerController: {fileID: 0}
+  rb: {fileID: 0}
+  puck: {fileID: 0}
+  maxSpeed: 8
+  acceleration: 15
+  deceleration: 10
+  turnSpeed: 5
+  stoppingForce: 20
+  movementSchema: {fileID: 11400000, guid: c9be43d1dfe930c4e98dd3432a255d0e, type: 2}
+  decisionUpdateInterval: 0.2
+  minOpponentDistance: 5
+  passSearchRadius: 20
+  shootingDistance: 15
+  interceptionRadius: 2
+  defensiveBlueLineZ: -18
+  offensiveBlueLineZ: 18
+  neutralZoneCenter: 0
+--- !u!54 &5895347483119069536
+Rigidbody:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 155091773289725482}
+  serializedVersion: 5
+  m_Mass: 1
+  m_LinearDamping: 0
+  m_AngularDamping: 0.05
+  m_CenterOfMass: {x: 0, y: 0, z: 0}
+  m_InertiaTensor: {x: 1, y: 1, z: 1}
+  m_InertiaRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_IncludeLayers:
+    serializedVersion: 2
+    m_Bits: 0
+  m_ExcludeLayers:
+    serializedVersion: 2
+    m_Bits: 0
+  m_ImplicitCom: 1
+  m_ImplicitTensor: 1
+  m_UseGravity: 0
+  m_IsKinematic: 0
+  m_Interpolate: 0
+  m_Constraints: 0
+  m_CollisionDetection: 0
 --- !u!1 &8352231560893359872
 GameObject:
   m_ObjectHideFlags: 0

+ 235 - 3
Assets/Scenes/SampleScene.unity

@@ -162,6 +162,10 @@ PrefabInstance:
       propertyPath: m_Name
       value: AT_RW (1)
       objectReference: {fileID: 0}
+    - target: {fileID: 155091773289725482, guid: e0b7871153e304b4f97664ead27e03fd, type: 3}
+      propertyPath: m_Layer
+      value: 6
+      objectReference: {fileID: 0}
     - target: {fileID: 155091773289725482, guid: e0b7871153e304b4f97664ead27e03fd, type: 3}
       propertyPath: m_TagString
       value: AwayTeam
@@ -186,6 +190,14 @@ PrefabInstance:
       propertyPath: m_margin.z
       value: 9.416066
       objectReference: {fileID: 0}
+    - target: {fileID: 6960256348343429607, guid: e0b7871153e304b4f97664ead27e03fd, type: 3}
+      propertyPath: defensiveBlueLineZ
+      value: -8.3
+      objectReference: {fileID: 0}
+    - target: {fileID: 6960256348343429607, guid: e0b7871153e304b4f97664ead27e03fd, type: 3}
+      propertyPath: offensiveBlueLineZ
+      value: 8.3
+      objectReference: {fileID: 0}
     - target: {fileID: 7628665651271265242, guid: e0b7871153e304b4f97664ead27e03fd, type: 3}
       propertyPath: m_LocalPosition.x
       value: 5.27
@@ -697,6 +709,10 @@ PrefabInstance:
       propertyPath: m_Name
       value: AT_RD (1)
       objectReference: {fileID: 0}
+    - target: {fileID: 155091773289725482, guid: e0b7871153e304b4f97664ead27e03fd, type: 3}
+      propertyPath: m_Layer
+      value: 6
+      objectReference: {fileID: 0}
     - target: {fileID: 155091773289725482, guid: e0b7871153e304b4f97664ead27e03fd, type: 3}
       propertyPath: m_TagString
       value: AwayTeam
@@ -709,6 +725,14 @@ PrefabInstance:
       propertyPath: stats
       value: 
       objectReference: {fileID: 11400000, guid: 8cacc221181f3d64284fed75c6a8ec02, type: 2}
+    - target: {fileID: 6960256348343429607, guid: e0b7871153e304b4f97664ead27e03fd, type: 3}
+      propertyPath: defensiveBlueLineZ
+      value: -8.3
+      objectReference: {fileID: 0}
+    - target: {fileID: 6960256348343429607, guid: e0b7871153e304b4f97664ead27e03fd, type: 3}
+      propertyPath: offensiveBlueLineZ
+      value: 8.3
+      objectReference: {fileID: 0}
     - target: {fileID: 7628665651271265242, guid: e0b7871153e304b4f97664ead27e03fd, type: 3}
       propertyPath: m_LocalPosition.x
       value: 2.57
@@ -809,6 +833,10 @@ PrefabInstance:
       propertyPath: m_Name
       value: SimpleRink
       objectReference: {fileID: 0}
+    - target: {fileID: 919132149155446097, guid: 6145e593b01004c468111c01c6063c84, type: 3}
+      propertyPath: m_Layer
+      value: 8
+      objectReference: {fileID: 0}
     m_RemovedComponents: []
     m_RemovedGameObjects: []
     m_AddedGameObjects: []
@@ -829,6 +857,10 @@ PrefabInstance:
       propertyPath: m_Name
       value: HT_C
       objectReference: {fileID: 0}
+    - target: {fileID: 155091773289725482, guid: e0b7871153e304b4f97664ead27e03fd, type: 3}
+      propertyPath: m_Layer
+      value: 6
+      objectReference: {fileID: 0}
     - target: {fileID: 155091773289725482, guid: e0b7871153e304b4f97664ead27e03fd, type: 3}
       propertyPath: m_TagString
       value: HomeTeam
@@ -837,6 +869,14 @@ PrefabInstance:
       propertyPath: stats
       value: 
       objectReference: {fileID: 11400000, guid: 35fa94fe5e19f1349a2a9fd31be9ea6a, type: 2}
+    - target: {fileID: 6960256348343429607, guid: e0b7871153e304b4f97664ead27e03fd, type: 3}
+      propertyPath: defensiveBlueLineZ
+      value: 8.3
+      objectReference: {fileID: 0}
+    - target: {fileID: 6960256348343429607, guid: e0b7871153e304b4f97664ead27e03fd, type: 3}
+      propertyPath: offensiveBlueLineZ
+      value: -8.3
+      objectReference: {fileID: 0}
     - target: {fileID: 7628665651271265242, guid: e0b7871153e304b4f97664ead27e03fd, type: 3}
       propertyPath: m_LocalPosition.x
       value: 0.017015934
@@ -928,6 +968,10 @@ PrefabInstance:
       propertyPath: m_Name
       value: AT_LD (1)
       objectReference: {fileID: 0}
+    - target: {fileID: 155091773289725482, guid: e0b7871153e304b4f97664ead27e03fd, type: 3}
+      propertyPath: m_Layer
+      value: 6
+      objectReference: {fileID: 0}
     - target: {fileID: 155091773289725482, guid: e0b7871153e304b4f97664ead27e03fd, type: 3}
       propertyPath: m_TagString
       value: AwayTeam
@@ -940,6 +984,14 @@ PrefabInstance:
       propertyPath: stats
       value: 
       objectReference: {fileID: 11400000, guid: e5ae97d937455bc42afe7f16b657084e, type: 2}
+    - target: {fileID: 6960256348343429607, guid: e0b7871153e304b4f97664ead27e03fd, type: 3}
+      propertyPath: defensiveBlueLineZ
+      value: -8.3
+      objectReference: {fileID: 0}
+    - target: {fileID: 6960256348343429607, guid: e0b7871153e304b4f97664ead27e03fd, type: 3}
+      propertyPath: offensiveBlueLineZ
+      value: 8.3
+      objectReference: {fileID: 0}
     - target: {fileID: 7628665651271265242, guid: e0b7871153e304b4f97664ead27e03fd, type: 3}
       propertyPath: m_LocalPosition.x
       value: -2.91
@@ -988,6 +1040,61 @@ PrefabInstance:
       insertIndex: -1
       addedObject: {fileID: 0}
   m_SourcePrefab: {fileID: 100100000, guid: e0b7871153e304b4f97664ead27e03fd, type: 3}
+--- !u!1 &892314338
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 892314340}
+  - component: {fileID: 892314339}
+  m_Layer: 0
+  m_Name: UI
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!114 &892314339
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 892314338}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 19102, guid: 0000000000000000e000000000000000, type: 0}
+  m_Name: 
+  m_EditorClassIdentifier: UnityEngine.dll::UnityEngine.UIElements.UIDocument
+  m_PanelSettings: {fileID: 11400000, guid: fc1256bfa188bab458a9fd3db5b366c8, type: 2}
+  m_ParentUI: {fileID: 0}
+  sourceAsset: {fileID: 9197481963319205126, guid: 9cbb0caf6614e0643a6991746a780659, type: 3}
+  m_SortingOrder: 0
+  m_Position: 0
+  m_WorldSpaceSizeMode: 1
+  m_WorldSpaceWidth: 1920
+  m_WorldSpaceHeight: 1080
+  m_PivotReferenceSize: 0
+  m_Pivot: 0
+  m_WorldSpaceCollider: {fileID: 0}
+--- !u!4 &892314340
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 892314338}
+  serializedVersion: 2
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: -1.22082, y: 0, z: 0.06426}
+  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!1 &1116763644
 GameObject:
   m_ObjectHideFlags: 0
@@ -1062,6 +1169,10 @@ PrefabInstance:
       propertyPath: m_Name
       value: HT_LD
       objectReference: {fileID: 0}
+    - target: {fileID: 155091773289725482, guid: e0b7871153e304b4f97664ead27e03fd, type: 3}
+      propertyPath: m_Layer
+      value: 6
+      objectReference: {fileID: 0}
     - target: {fileID: 155091773289725482, guid: e0b7871153e304b4f97664ead27e03fd, type: 3}
       propertyPath: m_TagString
       value: HomeTeam
@@ -1070,6 +1181,14 @@ PrefabInstance:
       propertyPath: stats
       value: 
       objectReference: {fileID: 11400000, guid: e5ae97d937455bc42afe7f16b657084e, type: 2}
+    - target: {fileID: 6960256348343429607, guid: e0b7871153e304b4f97664ead27e03fd, type: 3}
+      propertyPath: defensiveBlueLineZ
+      value: 8.3
+      objectReference: {fileID: 0}
+    - target: {fileID: 6960256348343429607, guid: e0b7871153e304b4f97664ead27e03fd, type: 3}
+      propertyPath: offensiveBlueLineZ
+      value: -8.3
+      objectReference: {fileID: 0}
     - target: {fileID: 7628665651271265242, guid: e0b7871153e304b4f97664ead27e03fd, type: 3}
       propertyPath: m_LocalPosition.x
       value: 2.9824455
@@ -1145,6 +1264,52 @@ MeshCollider:
   m_Convex: 0
   m_CookingOptions: 30
   m_Mesh: {fileID: 2204420629459286600, guid: 6145e593b01004c468111c01c6063c84, type: 3}
+--- !u!1 &1359288801
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 1359288802}
+  - component: {fileID: 1359288803}
+  m_Layer: 0
+  m_Name: GameSetup
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!4 &1359288802
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1359288801}
+  serializedVersion: 2
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: -0.09575, y: -0, z: -0.03513}
+  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 &1359288803
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1359288801}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: ad6fce936a4619748818b1c4df3b1369, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: Assembly-CSharp::GameSetup
+  setupOnAwake: 1
+  createLayersIfMissing: 1
 --- !u!1 &1453121552
 GameObject:
   m_ObjectHideFlags: 0
@@ -1189,7 +1354,7 @@ MonoBehaviour:
   struggleDuration: 3
   struggleChance: 0.3
   winThreshold: 0.7
-  passForce: 8
+  passForce: 12
   struggleLaunchForce: 5
 --- !u!4 &1453121554
 Transform:
@@ -1232,6 +1397,10 @@ PrefabInstance:
       propertyPath: m_Name
       value: AT_LW (1)
       objectReference: {fileID: 0}
+    - target: {fileID: 155091773289725482, guid: e0b7871153e304b4f97664ead27e03fd, type: 3}
+      propertyPath: m_Layer
+      value: 6
+      objectReference: {fileID: 0}
     - target: {fileID: 155091773289725482, guid: e0b7871153e304b4f97664ead27e03fd, type: 3}
       propertyPath: m_TagString
       value: AwayTeam
@@ -1244,6 +1413,14 @@ PrefabInstance:
       propertyPath: stats
       value: 
       objectReference: {fileID: 11400000, guid: 62ee73c2cdb1b9f499897533ea9b73dc, type: 2}
+    - target: {fileID: 6960256348343429607, guid: e0b7871153e304b4f97664ead27e03fd, type: 3}
+      propertyPath: defensiveBlueLineZ
+      value: -8.3
+      objectReference: {fileID: 0}
+    - target: {fileID: 6960256348343429607, guid: e0b7871153e304b4f97664ead27e03fd, type: 3}
+      propertyPath: offensiveBlueLineZ
+      value: 8.3
+      objectReference: {fileID: 0}
     - target: {fileID: 7628665651271265242, guid: e0b7871153e304b4f97664ead27e03fd, type: 3}
       propertyPath: m_LocalPosition.x
       value: -5.42
@@ -1399,9 +1576,9 @@ GameObject:
   - component: {fileID: 2015482864}
   - component: {fileID: 2015482869}
   - component: {fileID: 2015482870}
-  m_Layer: 0
+  m_Layer: 7
   m_Name: Puck
-  m_TagString: Untagged
+  m_TagString: Puck
   m_Icon: {fileID: 0}
   m_NavMeshLayer: 0
   m_StaticEditorFlags: 0
@@ -1525,6 +1702,11 @@ MonoBehaviour:
   carrierOffset: 1
   normalMaterial: {fileID: 0}
   possessedMaterial: {fileID: 0}
+  canBeIntercepted: 1
+  interceptionCheckRadius: 0.5
+  playerLayer:
+    serializedVersion: 2
+    m_Bits: 0
 --- !u!135 &2015482870
 SphereCollider:
   m_ObjectHideFlags: 0
@@ -1558,6 +1740,10 @@ PrefabInstance:
       propertyPath: m_Name
       value: AT_C (1)
       objectReference: {fileID: 0}
+    - target: {fileID: 155091773289725482, guid: e0b7871153e304b4f97664ead27e03fd, type: 3}
+      propertyPath: m_Layer
+      value: 6
+      objectReference: {fileID: 0}
     - target: {fileID: 155091773289725482, guid: e0b7871153e304b4f97664ead27e03fd, type: 3}
       propertyPath: m_TagString
       value: AwayTeam
@@ -1570,6 +1756,14 @@ PrefabInstance:
       propertyPath: stats
       value: 
       objectReference: {fileID: 11400000, guid: 35fa94fe5e19f1349a2a9fd31be9ea6a, type: 2}
+    - target: {fileID: 6960256348343429607, guid: e0b7871153e304b4f97664ead27e03fd, type: 3}
+      propertyPath: defensiveBlueLineZ
+      value: -8.3
+      objectReference: {fileID: 0}
+    - target: {fileID: 6960256348343429607, guid: e0b7871153e304b4f97664ead27e03fd, type: 3}
+      propertyPath: offensiveBlueLineZ
+      value: 8.3
+      objectReference: {fileID: 0}
     - target: {fileID: 7628665651271265242, guid: e0b7871153e304b4f97664ead27e03fd, type: 3}
       propertyPath: m_LocalPosition.x
       value: 0.017015934
@@ -1630,6 +1824,10 @@ PrefabInstance:
       propertyPath: m_Name
       value: HT_RD
       objectReference: {fileID: 0}
+    - target: {fileID: 155091773289725482, guid: e0b7871153e304b4f97664ead27e03fd, type: 3}
+      propertyPath: m_Layer
+      value: 6
+      objectReference: {fileID: 0}
     - target: {fileID: 155091773289725482, guid: e0b7871153e304b4f97664ead27e03fd, type: 3}
       propertyPath: m_TagString
       value: HomeTeam
@@ -1638,6 +1836,14 @@ PrefabInstance:
       propertyPath: stats
       value: 
       objectReference: {fileID: 11400000, guid: 8cacc221181f3d64284fed75c6a8ec02, type: 2}
+    - target: {fileID: 6960256348343429607, guid: e0b7871153e304b4f97664ead27e03fd, type: 3}
+      propertyPath: defensiveBlueLineZ
+      value: 8.3
+      objectReference: {fileID: 0}
+    - target: {fileID: 6960256348343429607, guid: e0b7871153e304b4f97664ead27e03fd, type: 3}
+      propertyPath: offensiveBlueLineZ
+      value: -8.3
+      objectReference: {fileID: 0}
     - target: {fileID: 7628665651271265242, guid: e0b7871153e304b4f97664ead27e03fd, type: 3}
       propertyPath: m_LocalPosition.x
       value: -2.5
@@ -1698,6 +1904,10 @@ PrefabInstance:
       propertyPath: m_Name
       value: HT_LW
       objectReference: {fileID: 0}
+    - target: {fileID: 155091773289725482, guid: e0b7871153e304b4f97664ead27e03fd, type: 3}
+      propertyPath: m_Layer
+      value: 6
+      objectReference: {fileID: 0}
     - target: {fileID: 155091773289725482, guid: e0b7871153e304b4f97664ead27e03fd, type: 3}
       propertyPath: m_TagString
       value: HomeTeam
@@ -1706,6 +1916,14 @@ PrefabInstance:
       propertyPath: stats
       value: 
       objectReference: {fileID: 11400000, guid: 62ee73c2cdb1b9f499897533ea9b73dc, type: 2}
+    - target: {fileID: 6960256348343429607, guid: e0b7871153e304b4f97664ead27e03fd, type: 3}
+      propertyPath: defensiveBlueLineZ
+      value: 8.3
+      objectReference: {fileID: 0}
+    - target: {fileID: 6960256348343429607, guid: e0b7871153e304b4f97664ead27e03fd, type: 3}
+      propertyPath: offensiveBlueLineZ
+      value: -8.3
+      objectReference: {fileID: 0}
     - target: {fileID: 7628665651271265242, guid: e0b7871153e304b4f97664ead27e03fd, type: 3}
       propertyPath: m_LocalPosition.x
       value: 5.24
@@ -1806,6 +2024,10 @@ PrefabInstance:
       propertyPath: m_Name
       value: HT_RW
       objectReference: {fileID: 0}
+    - target: {fileID: 155091773289725482, guid: e0b7871153e304b4f97664ead27e03fd, type: 3}
+      propertyPath: m_Layer
+      value: 6
+      objectReference: {fileID: 0}
     - target: {fileID: 155091773289725482, guid: e0b7871153e304b4f97664ead27e03fd, type: 3}
       propertyPath: m_TagString
       value: HomeTeam
@@ -1826,6 +2048,14 @@ PrefabInstance:
       propertyPath: m_margin.x
       value: 9.44718
       objectReference: {fileID: 0}
+    - target: {fileID: 6960256348343429607, guid: e0b7871153e304b4f97664ead27e03fd, type: 3}
+      propertyPath: defensiveBlueLineZ
+      value: 8.3
+      objectReference: {fileID: 0}
+    - target: {fileID: 6960256348343429607, guid: e0b7871153e304b4f97664ead27e03fd, type: 3}
+      propertyPath: offensiveBlueLineZ
+      value: -8.3
+      objectReference: {fileID: 0}
     - target: {fileID: 7628665651271265242, guid: e0b7871153e304b4f97664ead27e03fd, type: 3}
       propertyPath: m_LocalPosition.x
       value: -5.36
@@ -1895,3 +2125,5 @@ SceneRoots:
   - {fileID: 2034510359}
   - {fileID: 1453121554}
   - {fileID: 2135607107}
+  - {fileID: 1359288802}
+  - {fileID: 892314340}

+ 28 - 0
Assets/ScriptableObjects/HT_MovementSchema.asset

@@ -0,0 +1,28 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!114 &11400000
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 0}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: a1428175e9ec49d4ea921b2f3b3e165c, type: 3}
+  m_Name: HT_MovementSchema
+  m_EditorClassIdentifier: Assembly-CSharp::MovementSchema
+  schemaName: HT_Default
+  defenderSupportDistance: 5
+  defenderLateralSpread: 4
+  defenderStayAtBlueLine: 0
+  forwardPushDistance: 8
+  forwardLateralSpread: 6
+  forwardAggressiveness: 0.7
+  forwardMinimumSpeed: 3
+  passReceptionDistance: 15
+  favorOffensivePositions: 1
+  defensiveFormationWidth: 0.5
+  defensiveDepth: 0.6
+  forecheckersCount: 1
+  forecheckAggression: 0.5

+ 8 - 0
Assets/ScriptableObjects/HT_MovementSchema.asset.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: c9be43d1dfe930c4e98dd3432a255d0e
+NativeFormatImporter:
+  externalObjects: {}
+  mainObjectFileID: 11400000
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 16 - 0
Assets/Scripts/FaceoffManager.cs

@@ -40,6 +40,9 @@ public class FaceoffManager : MonoBehaviour
     private bool faceoffInProgress = false;
     private FaceoffOutcome currentOutcome;
 
+    // Public property to check if faceoff is in progress
+    public bool IsFaceoffInProgress => faceoffInProgress;
+
     public enum FaceoffOutcome
     {
         None,
@@ -122,6 +125,12 @@ public class FaceoffManager : MonoBehaviour
         faceoffInProgress = true;
         Debug.Log("Faceoff starting...");
 
+        // Stop timer and freeze players during faceoff
+        if (GameManager.Instance != null)
+        {
+            GameManager.Instance.SetPuckInPlay(false);
+        }
+
         // Position puck at faceoff spot
         if (puck != null && currentFaceoffSpot != null)
         {
@@ -156,6 +165,13 @@ public class FaceoffManager : MonoBehaviour
 
         FreezeAllPlayers(false);
         faceoffInProgress = false;
+
+        // Start timer and allow movement after faceoff completes
+        if (GameManager.Instance != null)
+        {
+            GameManager.Instance.SetPuckInPlay(true);
+        }
+
         Debug.Log("Faceoff complete!");
     }
 

+ 183 - 0
Assets/Scripts/GameManager.cs

@@ -0,0 +1,183 @@
+using UnityEngine;
+
+/// <summary>
+/// Central game manager that controls game state, timer, score, and puck in play status.
+/// </summary>
+public class GameManager : MonoBehaviour
+{
+    public static GameManager Instance { get; private set; }
+
+    [Header("Game Settings")]
+    [SerializeField] private float periodDuration = 1200f; // 20:00 in seconds
+    [SerializeField] private int totalPeriods = 3;
+
+    [Header("Game State")]
+    private int homeScore = 0;
+    private int awayScore = 0;
+    private int currentPeriod = 1;
+    private float timeRemaining = 1200f; // Start at 20:00
+    private bool isPuckInPlay = false;
+    private bool isGameRunning = false;
+
+    public bool IsPuckInPlay => isPuckInPlay;
+    public bool IsGameRunning => isGameRunning;
+    public int HomeScore => homeScore;
+    public int AwayScore => awayScore;
+    public int CurrentPeriod => currentPeriod;
+    public float TimeRemaining => timeRemaining;
+
+    // Events for UI updates
+    public delegate void ScoreChangedHandler(int homeScore, int awayScore);
+    public event ScoreChangedHandler OnScoreChanged;
+
+    public delegate void TimeChangedHandler(float timeRemaining);
+    public event TimeChangedHandler OnTimeChanged;
+
+    public delegate void PeriodChangedHandler(int period);
+    public event PeriodChangedHandler OnPeriodChanged;
+
+    public delegate void PuckInPlayChangedHandler(bool inPlay);
+    public event PuckInPlayChangedHandler OnPuckInPlayChanged;
+
+    void Awake()
+    {
+        // Singleton pattern
+        if (Instance == null)
+        {
+            Instance = this;
+        }
+        else
+        {
+            Destroy(gameObject);
+            return;
+        }
+    }
+
+    void Start()
+    {
+        timeRemaining = periodDuration;
+        StartGame();
+        
+        Debug.Log("Game started. All players frozen by default. Press F to start faceoff.");
+    }
+
+    void Update()
+    {
+        if (isGameRunning && isPuckInPlay && timeRemaining > 0)
+        {
+            timeRemaining -= Time.deltaTime;
+            
+            if (timeRemaining <= 0)
+            {
+                timeRemaining = 0;
+                EndPeriod();
+            }
+
+            OnTimeChanged?.Invoke(timeRemaining);
+        }
+    }
+
+    public void StartGame()
+    {
+        isGameRunning = true;
+        currentPeriod = 1;
+        timeRemaining = periodDuration;
+        homeScore = 0;
+        awayScore = 0;
+        
+        OnScoreChanged?.Invoke(homeScore, awayScore);
+        OnTimeChanged?.Invoke(timeRemaining);
+        OnPeriodChanged?.Invoke(currentPeriod);
+        
+        Debug.Log("Game Started!");
+    }
+
+    public void SetPuckInPlay(bool inPlay)
+    {
+        if (isPuckInPlay != inPlay)
+        {
+            isPuckInPlay = inPlay;
+            OnPuckInPlayChanged?.Invoke(isPuckInPlay);
+            Debug.Log($"Puck in play: {isPuckInPlay}");
+        }
+    }
+
+    public void AddHomeScore(int points = 1)
+    {
+        homeScore += points;
+        OnScoreChanged?.Invoke(homeScore, awayScore);
+        Debug.Log($"Home Team scores! {homeScore} - {awayScore}");
+        
+        // Stop play after goal
+        SetPuckInPlay(false);
+    }
+
+    public void AddAwayScore(int points = 1)
+    {
+        awayScore += points;
+        OnScoreChanged?.Invoke(homeScore, awayScore);
+        Debug.Log($"Away Team scores! {homeScore} - {awayScore}");
+        
+        // Stop play after goal
+        SetPuckInPlay(false);
+    }
+
+    private void EndPeriod()
+    {
+        SetPuckInPlay(false);
+        isGameRunning = false;
+        
+        Debug.Log($"End of Period {currentPeriod}");
+
+        if (currentPeriod < totalPeriods)
+        {
+            // Start next period
+            currentPeriod++;
+            timeRemaining = periodDuration;
+            OnPeriodChanged?.Invoke(currentPeriod);
+            OnTimeChanged?.Invoke(timeRemaining);
+            
+            // Game will resume after faceoff
+            isGameRunning = true;
+        }
+        else
+        {
+            EndGame();
+        }
+    }
+
+    private void EndGame()
+    {
+        Debug.Log($"Game Over! Final Score: {homeScore} - {awayScore}");
+        
+        if (homeScore > awayScore)
+        {
+            Debug.Log("Home Team Wins!");
+        }
+        else if (awayScore > homeScore)
+        {
+            Debug.Log("Away Team Wins!");
+        }
+        else
+        {
+            Debug.Log("Game is tied!");
+        }
+    }
+
+    public void PauseGame()
+    {
+        isGameRunning = false;
+    }
+
+    public void ResumeGame()
+    {
+        isGameRunning = true;
+    }
+
+    public string GetFormattedTime()
+    {
+        int minutes = Mathf.FloorToInt(timeRemaining / 60f);
+        int seconds = Mathf.FloorToInt(timeRemaining % 60f);
+        return $"{minutes:00}:{seconds:00}";
+    }
+}

+ 2 - 0
Assets/Scripts/GameManager.cs.meta

@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: 9bbb69e9ccc2c7a4a99f8fac968ae7c7

+ 16 - 0
Assets/Scripts/GameState.cs

@@ -0,0 +1,16 @@
+using UnityEngine;
+
+public class GameState : MonoBehaviour
+{
+    public bool IsFaceoffComplete { get; private set; } = false;
+
+    public void StartFaceoff()
+    {
+        IsFaceoffComplete = false;
+    }
+
+    public void CompleteFaceoff()
+    {
+        IsFaceoffComplete = true;
+    }
+}

+ 2 - 0
Assets/Scripts/GameState.cs.meta

@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: 3888ce28059ccc646ba773476c56f988

+ 37 - 8
Assets/Scripts/MainGameScript.cs

@@ -1,16 +1,45 @@
 using UnityEngine;
 
+/// <summary>
+/// Main game script - currently not used as game logic is distributed across managers.
+/// 
+/// SETUP INSTRUCTIONS FOR UI AND GAME CONTROL:
+/// 
+/// 1. Add GameManager to your scene:
+///    - Create empty GameObject named "GameManager"
+///    - Add GameManager component
+///    
+/// 2. Setup UI:
+///    - Create empty GameObject named "GameUI"
+///    - Add UIDocument component
+///    - In UIDocument:
+///      * Source Asset: Drag GameUI.uxml from Assets/UI folder
+///    - Add UIController component
+///    - Set team names in UIController (optional)
+///    
+/// 3. Setup PanelSettings (if not already):
+///    - Right-click in Project: Create > UI Toolkit > Panel Settings Asset
+///    - Name it "GameUIPanelSettings"
+///    - In UIDocument component, assign this to "Panel Settings"
+///    - Set Scale Mode to "Scale With Screen Size"
+///    - Reference Resolution: 1920x1080
+///    
+/// 4. Verify FaceoffManager:
+///    - Your existing FaceoffManager should now automatically:
+///      * Stop timer during faceoffs
+///      * Freeze players until faceoff resolves
+///      * Start timer when puck is in play
+///      
+/// 5. Test:
+///    - Press F to start a faceoff
+///    - Timer should be frozen until faceoff completes
+///    - Once resolved, timer counts down and players can move
+///    - Score updates when goals are scored
+/// </summary>
 public class MainGameScript : MonoBehaviour
 {
-    // Start is called once before the first execution of Update after the MonoBehaviour is created
     void Start()
     {
-        
-    }
-
-    // Update is called once per frame
-    void Update()
-    {
-        
+        Debug.Log("Hockey Game Ready! Press F to start a faceoff.");
     }
 }

+ 241 - 0
Assets/Scripts/Player/AI/AI_MOVEMENT_GUIDE.md

@@ -0,0 +1,241 @@
+# AI Movement System Setup Guide
+
+## Overview
+
+This AI movement system provides realistic, physics-based hockey player behavior with configurable strategies for different game situations.
+
+## Features
+
+### 1. **Physics-Based Movement**
+- All movement uses forces (no direct position manipulation)
+- Realistic momentum and inertia
+- Hockey-like skating with acceleration/deceleration
+- Cannot instantly change direction - must overcome current velocity
+
+### 2. **Intelligent Behaviors**
+
+#### When Player Has Puck:
+- Maintains distance from opponents (configurable avoidance radius)
+- Moves toward offensive zone
+- Looks for shooting opportunities when in range
+- Finds optimal shooting positions in the slot
+
+#### When Teammate Has Puck:
+- **Defenders**: Position themselves to be open for passes
+  - Support puck-carrying defender
+  - Stay at defensive blue line or push forward (configurable)
+- **Forwards**: Push toward offensive zone with speed
+  - Spread out by position (LW, C, RW)
+  - Maintain minimum speed to support attack
+  - Position for pass reception
+
+#### When Opponent Has Puck:
+- **Closest Player**: Pressures puck carrier, attempts interception
+- **Defenders**: 
+  - Form defensive structure
+  - One plays at blue line, one lower
+  - Protect own goal
+- **Forwards**: Backcheck to support defense
+
+## Setup Instructions
+
+### Step 1: Add Components to Players
+
+Add these components to each AI-controlled player GameObject:
+
+1. **Rigidbody** (if not present)
+   - Mass: 80-100 (kg)
+   - Drag: 1
+   - Angular Drag: 5
+   - Use Gravity: true
+   - Is Kinematic: false
+   - Constraints: Freeze Rotation X, Z, and Freeze Position Y
+
+2. **PlayerController** (existing)
+   - Assign PlayerStats
+   - Assign PlayerMentality
+   - Set team tag ("HomeTeam" or "AwayTeam")
+
+3. **PlayerMovement** (updated)
+   - Set `isPlayerControlled` to `false` for AI players
+   - Set `isPlayerControlled` to `true` for human players
+
+4. **PlayerAIMovement** (new)
+   - Max Speed: 8
+   - Acceleration: 15
+   - Deceleration: 10
+   - Turn Speed: 5
+   - Stopping Force: 20
+   - Min Opponent Distance: 5
+   - Pass Search Radius: 20
+   - Shooting Distance: 15
+   - Assign Movement Schema (optional)
+
+### Step 2: Create Movement Schemas
+
+Right-click in Project window:
+`Create > Hockey > AI > Movement Schema`
+
+Configure the schema:
+
+**Default Balanced Schema:**
+- Defender Support Distance: 5
+- Defender Lateral Spread: 4
+- Forward Push Distance: 8
+- Forward Lateral Spread: 6
+- Forward Aggressiveness: 0.7
+- Forward Minimum Speed: 3
+
+**Aggressive Schema:**
+- Forward Push Distance: 12
+- Forward Aggressiveness: 0.9
+- Forecheck Aggression: 0.8
+- Forecheckers Count: 2
+
+**Defensive Schema:**
+- Defender Stay At Blue Line: true
+- Forward Push Distance: 5
+- Forward Aggressiveness: 0.4
+- Defensive Depth: 0.8
+
+### Step 3: Configure Zone Positions
+
+Adjust these values in PlayerAIMovement to match your rink:
+
+- `defensiveBlueLineZ`: -18 (adjust based on your rink)
+- `offensiveBlueLineZ`: 18 (adjust based on your rink)
+- `neutralZoneCenter`: 0
+
+### Step 4: Set Up Team Tags
+
+Make sure players have correct tags:
+- Home team players: Tag = "HomeTeam"
+- Away team players: Tag = "AwayTeam"
+
+### Step 5: Reference the Puck
+
+The PlayerAIMovement script will automatically find the PuckController in the scene. Make sure:
+- There is exactly one GameObject with a PuckController component
+- The PuckController has proper physics setup
+
+## Customization
+
+### Adjusting Movement Feel
+
+**Faster, More Responsive:**
+```csharp
+acceleration = 20
+turnSpeed = 8
+maxSpeed = 10
+```
+
+**Heavier, More Realistic:**
+```csharp
+acceleration = 12
+deceleration = 8
+turnSpeed = 4
+stoppingForce = 25
+```
+
+### Behavior Tuning
+
+Edit MovementSchema values to change team strategy:
+
+**Run and Gun (Offensive):**
+- High forward aggressiveness
+- Large forward push distance
+- Multiple forecheckers
+
+**Trap Defense:**
+- Defenders stay at blue line
+- Lower forward aggressiveness
+- Tight defensive formation
+
+### Position-Specific Behavior
+
+The system automatically adjusts behavior by position:
+
+- **LW/RW**: Spread wide in offensive zone
+- **C**: Stay center, support both wings
+- **LD/RD**: Play respective sides, defensive responsibilities
+
+## Testing and Debugging
+
+### Debug Visualization
+
+PlayerAIMovement draws Gizmos in Scene view:
+- **Yellow sphere**: Target position
+- **Green ray**: Desired velocity
+- **Blue ray**: Current velocity
+- **Yellow line**: Path to target
+
+### Common Issues
+
+**Players not moving:**
+- Check isPlayerControlled is `false`
+- Verify Rigidbody is not kinematic
+- Ensure PuckController exists in scene
+
+**Players moving too fast/slow:**
+- Adjust maxSpeed and acceleration
+- Check Rigidbody drag settings
+
+**Players colliding:**
+- Verify Collider setup
+- Adjust opponent avoidance distance
+- Check Physics layer collision matrix
+
+**Poor positioning:**
+- Tune MovementSchema values
+- Adjust zone line positions to match rink
+- Verify team tags are correct
+
+## Advanced Usage
+
+### Custom Schemas Per Team
+
+```csharp
+public MovementSchema homeTeamSchema;
+public MovementSchema awayTeamSchema;
+
+void Start()
+{
+    bool isHomeTeam = CompareTag("HomeTeam");
+    movementSchema = isHomeTeam ? homeTeamSchema : awayTeamSchema;
+}
+```
+
+### Dynamic Strategy Changes
+
+```csharp
+// Switch to defensive schema when losing
+if (scoreDeficit > 0)
+{
+    aiMovement.movementSchema = defensiveSchema;
+}
+```
+
+### Individual Player Overrides
+
+```csharp
+// Make one forward more aggressive
+if (stats.position == PlayerPosition.C)
+{
+    aiMovement.shootingDistance = 20f; // Shoots from farther out
+}
+```
+
+## Performance Notes
+
+- Decision making updates every 0.2 seconds (configurable)
+- Physics calculations run every FixedUpdate
+- Suitable for 10-12 AI players simultaneously
+- Minimal GC allocation
+
+## Next Steps
+
+1. Integrate with existing shoot/pass systems in PlayerController
+2. Add line changes and fatigue system
+3. Implement special teams (power play, penalty kill)
+4. Add more complex forechecking systems (1-2-2, 1-1-3, etc.)
+5. Create AI difficulty levels using schema presets

+ 7 - 0
Assets/Scripts/Player/AI/AI_MOVEMENT_GUIDE.md.meta

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

+ 68 - 0
Assets/Scripts/Player/AI/MovementSchema.cs

@@ -0,0 +1,68 @@
+using UnityEngine;
+
+/// <summary>
+/// Configurable movement schema for different AI behaviors when teammate has puck.
+/// Allows customization of positioning and support patterns.
+/// </summary>
+[CreateAssetMenu(fileName = "MovementSchema", menuName = "Hockey/AI/Movement Schema")]
+public class MovementSchema : ScriptableObject
+{
+    [Header("General Settings")]
+    [Tooltip("Name of this movement schema")]
+    public string schemaName = "Default";
+
+    [Header("Defender Behavior When Teammate Has Puck")]
+    [Tooltip("How far ahead of the puck carrier should defenders position")]
+    [Range(0f, 15f)]
+    public float defenderSupportDistance = 5f;
+
+    [Tooltip("How wide should defenders spread (lateral distance)")]
+    [Range(0f, 10f)]
+    public float defenderLateralSpread = 4f;
+
+    [Tooltip("Should defender stay at blue line or push forward")]
+    public bool defenderStayAtBlueLine = false;
+
+    [Header("Forward Behavior When Teammate Has Puck")]
+    [Tooltip("How far ahead should forwards position")]
+    [Range(0f, 20f)]
+    public float forwardPushDistance = 8f;
+
+    [Tooltip("Width of forward spread")]
+    [Range(0f, 15f)]
+    public float forwardLateralSpread = 6f;
+
+    [Tooltip("How aggressively forwards should push into offensive zone")]
+    [Range(0f, 1f)]
+    public float forwardAggressiveness = 0.7f;
+
+    [Tooltip("Minimum speed forwards should maintain when attacking")]
+    [Range(0f, 10f)]
+    public float forwardMinimumSpeed = 3f;
+
+    [Header("Pass Reception")]
+    [Tooltip("How far from puck carrier to look for pass reception positions")]
+    [Range(5f, 30f)]
+    public float passReceptionDistance = 15f;
+
+    [Tooltip("Prefer positions closer to opponent goal")]
+    public bool favorOffensivePositions = true;
+
+    [Header("Defensive Coverage")]
+    [Tooltip("Formation when opponent has puck: Tight = close together, Wide = spread out")]
+    [Range(0f, 1f)]
+    public float defensiveFormationWidth = 0.5f;
+
+    [Tooltip("How deep defenders should play (closer to own goal)")]
+    [Range(0f, 1f)]
+    public float defensiveDepth = 0.6f;
+
+    [Header("Forechecking")]
+    [Tooltip("Number of forwards that should aggressively forecheck")]
+    [Range(0, 3)]
+    public int forecheckersCount = 1;
+
+    [Tooltip("How aggressive the forecheck should be")]
+    [Range(0f, 1f)]
+    public float forecheckAggression = 0.5f;
+}

+ 2 - 0
Assets/Scripts/Player/AI/MovementSchema.cs.meta

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

+ 634 - 0
Assets/Scripts/Player/AI/PlayerAIMovement.cs

@@ -0,0 +1,634 @@
+using UnityEngine;
+using System.Linq;
+
+/// <summary>
+/// AI-controlled movement for hockey players using physics-based forces.
+/// Implements realistic hockey skating with momentum and inertia.
+/// </summary>
+public class PlayerAIMovement : MonoBehaviour
+{
+    [Header("Movement Settings")]
+    [SerializeField] private float maxSpeed = 8f;
+    [SerializeField] private float acceleration = 15f;
+    [SerializeField] private float deceleration = 10f;
+    [SerializeField] private float turnSpeed = 5f;
+    [SerializeField] private float stoppingForce = 20f;
+
+    [Header("AI Behavior Settings")]
+    [SerializeField] private MovementSchema movementSchema;
+    [SerializeField] private float decisionUpdateInterval = 0.2f;
+    [SerializeField] private float minOpponentDistance = 5f;
+    [SerializeField] private float passSearchRadius = 20f;
+    [SerializeField] private float shootingDistance = 15f;
+    [SerializeField] private float interceptionRadius = 2f;
+
+    [Header("Zone Positions")]
+    [SerializeField] private float defensiveBlueLineZ = -18f;
+    [SerializeField] private float offensiveBlueLineZ = 18f;
+    [SerializeField] private float neutralZoneCenter = 0f;
+
+    [Header("Faceoff Control")]
+    [Tooltip("Disable AI movement during faceoffs")]
+    public bool freezeDuringFaceoff = true;
+
+    private Vector3 targetPosition;
+    private Vector3 desiredVelocity;
+    private float nextDecisionTime;
+    private bool isAIControlled = true;
+    private Rigidbody rb;
+    private PlayerController playerController;
+    private PuckController puck;
+    private FaceoffManager faceoffManager;
+
+    public bool IsAIControlled
+    {
+        get => isAIControlled;
+        set => isAIControlled = value;
+    }
+
+    void Awake()
+    {
+        // Get components from same GameObject
+        playerController = GetComponent<PlayerController>();
+        rb = GetComponent<Rigidbody>();
+
+        // Find puck by tag
+        GameObject puckObject = GameObject.FindGameObjectWithTag("Puck");
+        if (puckObject != null)
+        {
+            puck = puckObject.GetComponent<PuckController>();
+        }
+
+        // Find faceoff manager
+        faceoffManager = FindAnyObjectByType<FaceoffManager>();
+    }
+
+    void Start()
+    {
+        // Set rigidbody constraints for hockey movement
+        if (rb != null)
+        {
+            rb.constraints = RigidbodyConstraints.FreezeRotationX |
+                           RigidbodyConstraints.FreezeRotationZ |
+                           RigidbodyConstraints.FreezePositionY;
+            rb.linearDamping = 1f;
+        }
+    }
+
+    void Update()
+    {
+        if (!isAIControlled) return;
+        
+        // Don't make decisions if frozen (during faceoff)
+        if (playerController != null && playerController.IsFrozen())
+        {
+            return;
+        }
+
+        // Don't make decisions if puck is not in play
+        if (GameManager.Instance != null && !GameManager.Instance.IsPuckInPlay)
+        {
+            return;
+        }
+
+        // Make decisions periodically
+        if (Time.time >= nextDecisionTime)
+        {
+            MakeMovementDecision();
+            nextDecisionTime = Time.time + decisionUpdateInterval;
+        }
+    }
+
+    void FixedUpdate()
+    {
+        if (!isAIControlled || rb == null) return;
+        
+        // Stop movement if frozen (during faceoff)
+        if (playerController != null && playerController.IsFrozen())
+        {
+            rb.linearVelocity = Vector3.zero;
+            rb.angularVelocity = Vector3.zero;
+            return;
+        }
+
+        // Stop movement if puck is not in play
+        if (GameManager.Instance != null && !GameManager.Instance.IsPuckInPlay)
+        {
+            rb.linearVelocity = Vector3.Lerp(rb.linearVelocity, Vector3.zero, deceleration * Time.fixedDeltaTime);
+            return;
+        }
+
+        ApplyMovementForces();
+        ApplyRotation();
+    }
+
+    bool IsFaceoffActive()
+    {
+        // Check if faceoff manager exists and has a faceoff in progress
+        // You can also check if players are frozen via FaceoffManager
+        if (faceoffManager != null)
+        {
+            // Access the private field through reflection or add a public property to FaceoffManager
+            // For now, we'll assume if faceoffManager exists and players might be frozen
+            return false; // Placeholder - you'll need to add public property to FaceoffManager
+        }
+        return false;
+    }
+
+    void MakeMovementDecision()
+    {
+        if (playerController == null || puck == null) return;
+
+        bool hasPuck = playerController.HasPuck();
+        bool teammateHasPuck = IsTeammateCarryingPuck(out PlayerController puckCarrier);
+        bool opponentHasPuck = puck.CurrentCarrier != null && IsOpponent(puck.CurrentCarrier);
+
+        if (hasPuck)
+        {
+            DecideMovementWithPuck();
+        }
+        else if (teammateHasPuck)
+        {
+            DecideMovementTeammateHasPuck(puckCarrier);
+        }
+        else if (opponentHasPuck)
+        {
+            DecideMovementOpponentHasPuck();
+        }
+        else
+        {
+            DecideMovementLoosePuck();
+        }
+    }
+
+    #region Movement Behaviors
+
+    void DecideMovementWithPuck()
+    {
+        Vector3 avoidanceVector = CalculateOpponentAvoidance();
+        bool inOffensiveZone = IsInOffensiveZone();
+        Vector3 goalPosition = GetOpponentGoalPosition();
+        float distanceToGoal = Vector3.Distance(transform.position, goalPosition);
+
+        if (inOffensiveZone && distanceToGoal < shootingDistance)
+        {
+            Vector3 shootingPosition = FindBestShootingPosition();
+            targetPosition = shootingPosition + avoidanceVector;
+        }
+        else
+        {
+            Vector3 offensiveDirection = (goalPosition - transform.position).normalized;
+            targetPosition = transform.position + offensiveDirection * 3f + avoidanceVector;
+        }
+
+        float moveDistance = Vector3.Distance(transform.position, targetPosition);
+        if (moveDistance > 5f)
+        {
+            targetPosition = transform.position + (targetPosition - transform.position).normalized * 5f;
+        }
+    }
+
+    void DecideMovementTeammateHasPuck(PlayerController puckCarrier)
+    {
+        if (puckCarrier == null) return;
+
+        if (movementSchema == null)
+        {
+            DefaultTeammateHasPuckBehavior(puckCarrier);
+            return;
+        }
+
+        bool puckCarrierIsDefender = IsDefender(puckCarrier.stats.position);
+        bool thisPlayerIsDefender = IsDefender(playerController.stats.position);
+
+        if (puckCarrierIsDefender && thisPlayerIsDefender)
+        {
+            targetPosition = FindOpenPassReceivingPosition(puckCarrier);
+        }
+        else if (!thisPlayerIsDefender)
+        {
+            targetPosition = FindForwardSupportPosition(puckCarrier);
+        }
+        else
+        {
+            DefaultTeammateHasPuckBehavior(puckCarrier);
+        }
+    }
+
+    void DecideMovementOpponentHasPuck()
+    {
+        PlayerController opponentWithPuck = puck.CurrentCarrier;
+        if (opponentWithPuck == null) return;
+
+        bool isClosest = IsClosestTeammateToOpponent(opponentWithPuck);
+
+        if (isClosest)
+        {
+            targetPosition = opponentWithPuck.transform.position;
+            Vector3 toPuck = (opponentWithPuck.transform.position - transform.position).normalized;
+            targetPosition = opponentWithPuck.transform.position - toPuck * interceptionRadius;
+        }
+        else
+        {
+            if (IsDefender(playerController.stats.position))
+            {
+                targetPosition = GetDefensiveFormationPosition(opponentWithPuck);
+            }
+            else
+            {
+                targetPosition = GetBackcheckPosition(opponentWithPuck);
+            }
+        }
+    }
+
+    void DecideMovementLoosePuck()
+    {
+        if (puck == null) return;
+
+        // Only closest player chases loose puck
+        PlayerController closestTeammate = GetClosestTeammateToPuck();
+        if (closestTeammate == playerController)
+        {
+            targetPosition = puck.transform.position;
+        }
+        else
+        {
+            // Maintain positional structure
+            targetPosition = GetDefaultPosition();
+        }
+    }
+
+    #endregion
+
+    #region Position Finding
+
+    Vector3 CalculateOpponentAvoidance()
+    {
+        PlayerController[] opponents = FindOpponents();
+        Vector3 avoidanceVector = Vector3.zero;
+
+        foreach (PlayerController opponent in opponents)
+        {
+            float distance = Vector3.Distance(transform.position, opponent.transform.position);
+
+            if (distance < minOpponentDistance)
+            {
+                Vector3 awayFromOpponent = (transform.position - opponent.transform.position).normalized;
+                float strength = 1f - (distance / minOpponentDistance);
+                avoidanceVector += awayFromOpponent * strength * 3f;
+            }
+        }
+
+        return avoidanceVector;
+    }
+
+    Vector3 FindBestShootingPosition()
+    {
+        Vector3 goalPosition = GetOpponentGoalPosition();
+        Vector3 directionToGoal = (goalPosition - transform.position).normalized;
+        Vector3 slotPosition = goalPosition - directionToGoal * 8f;
+        slotPosition.x = Mathf.Clamp(slotPosition.x, -3f, 3f);
+        return slotPosition;
+    }
+
+    void DefaultTeammateHasPuckBehavior(PlayerController puckCarrier)
+    {
+        if (IsDefender(playerController.stats.position))
+        {
+            targetPosition = GetDefensivePosition();
+        }
+        else
+        {
+            targetPosition = FindForwardSupportPosition(puckCarrier);
+        }
+    }
+
+    Vector3 FindOpenPassReceivingPosition(PlayerController passer)
+    {
+        Vector3 passerPosition = passer.transform.position;
+        Vector3 goalDirection = (GetOpponentGoalPosition() - passerPosition).normalized;
+
+        float lateralOffset = (playerController.stats.position == PlayerPosition.LD ||
+                              playerController.stats.position == PlayerPosition.LW) ? -4f : 4f;
+
+        Vector3 targetPos = passerPosition + goalDirection * 5f + Vector3.right * lateralOffset;
+
+        float distance = Vector3.Distance(passerPosition, targetPos);
+        if (distance > passSearchRadius * 0.7f)
+        {
+            targetPos = passerPosition + (targetPos - passerPosition).normalized * passSearchRadius * 0.7f;
+        }
+
+        return targetPos;
+    }
+
+    Vector3 FindForwardSupportPosition(PlayerController puckCarrier)
+    {
+        if (movementSchema == null) return transform.position;
+
+        Vector3 goalPosition = GetOpponentGoalPosition();
+        Vector3 puckPosition = puckCarrier.transform.position;
+        Vector3 offensiveDirection = (goalPosition - puckPosition).normalized;
+
+        float lateralSpread = movementSchema.forwardLateralSpread;
+        float lateralOffset = 0f;
+
+        switch (playerController.stats.position)
+        {
+            case PlayerPosition.LW:
+                lateralOffset = -lateralSpread;
+                break;
+            case PlayerPosition.RW:
+                lateralOffset = lateralSpread;
+                break;
+            case PlayerPosition.C:
+                lateralOffset = 0f;
+                break;
+        }
+
+        Vector3 targetPos = puckPosition + offensiveDirection * movementSchema.forwardPushDistance + Vector3.right * lateralOffset;
+
+        if (targetPos.z > offensiveBlueLineZ + 5f)
+        {
+            targetPos.z = offensiveBlueLineZ + 5f;
+        }
+
+        return targetPos;
+    }
+
+    Vector3 GetDefensiveFormationPosition(PlayerController opponentWithPuck)
+    {
+        Vector3 ownGoal = GetOwnGoalPosition();
+        Vector3 puckPosition = opponentWithPuck.transform.position;
+
+        PlayerController[] teammates = FindTeammates();
+        PlayerController otherDefender = teammates.FirstOrDefault(t =>
+            IsDefender(t.stats.position) && t != playerController);
+
+        if (otherDefender != null)
+        {
+            if (playerController.stats.position == PlayerPosition.LD)
+            {
+                return new Vector3(-3f, 0f, defensiveBlueLineZ);
+            }
+            else
+            {
+                Vector3 targetPos = ownGoal + (puckPosition - ownGoal).normalized * 10f;
+                targetPos.x = 3f;
+                return targetPos;
+            }
+        }
+        else
+        {
+            return ownGoal + (puckPosition - ownGoal).normalized * 12f;
+        }
+    }
+
+    Vector3 GetBackcheckPosition(PlayerController opponentWithPuck)
+    {
+        Vector3 ownGoal = GetOwnGoalPosition();
+        Vector3 puckPosition = opponentWithPuck.transform.position;
+        Vector3 targetPos = puckPosition + (ownGoal - puckPosition).normalized * 3f;
+
+        float lateralOffset = 0f;
+        switch (playerController.stats.position)
+        {
+            case PlayerPosition.LW:
+                lateralOffset = -4f;
+                break;
+            case PlayerPosition.RW:
+                lateralOffset = 4f;
+                break;
+        }
+
+        targetPos.x += lateralOffset;
+        return targetPos;
+    }
+
+    Vector3 GetDefensivePosition()
+    {
+        float sideOffset = (playerController.stats.position == PlayerPosition.LD) ? -3f : 3f;
+        bool isHomeTeam = CompareTag("HomeTeam");
+        float zPosition = isHomeTeam ? defensiveBlueLineZ : -defensiveBlueLineZ;
+
+        return new Vector3(sideOffset, 0, zPosition);
+    }
+
+    Vector3 GetDefaultPosition()
+    {
+        // Return a position based on player position and zone
+        float xPos = 0f;
+        float zPos = 0f;
+
+        switch (playerController.stats.position)
+        {
+            case PlayerPosition.LW:
+                xPos = -6f;
+                zPos = offensiveBlueLineZ * 0.5f;
+                break;
+            case PlayerPosition.RW:
+                xPos = 6f;
+                zPos = offensiveBlueLineZ * 0.5f;
+                break;
+            case PlayerPosition.C:
+                xPos = 0f;
+                zPos = neutralZoneCenter;
+                break;
+            case PlayerPosition.LD:
+                xPos = -3f;
+                zPos = defensiveBlueLineZ;
+                break;
+            case PlayerPosition.RD:
+                xPos = 3f;
+                zPos = defensiveBlueLineZ;
+                break;
+        }
+
+        return new Vector3(xPos, 0, zPos);
+    }
+
+    #endregion
+
+    #region Physics Movement
+
+    void ApplyMovementForces()
+    {
+        if (rb == null) return;
+
+        Vector3 currentVelocity = rb.linearVelocity;
+        Vector3 directionToTarget = (targetPosition - transform.position).normalized;
+        float distanceToTarget = Vector3.Distance(transform.position, targetPosition);
+
+        float desiredSpeed = Mathf.Min(maxSpeed, distanceToTarget * 2f);
+        desiredVelocity = directionToTarget * desiredSpeed;
+
+        Vector3 velocityDifference = desiredVelocity - currentVelocity;
+        float forceMultiplier = velocityDifference.magnitude > 0.1f ? acceleration : deceleration;
+
+        float currentSpeed = currentVelocity.magnitude;
+        float dot = Vector3.Dot(currentVelocity.normalized, directionToTarget);
+
+        if (dot < 0 && currentSpeed > 1f)
+        {
+            Vector3 stoppingForceVector = -currentVelocity.normalized * stoppingForce;
+            rb.AddForce(stoppingForceVector, ForceMode.Acceleration);
+        }
+        else
+        {
+            Vector3 force = velocityDifference * forceMultiplier;
+            rb.AddForce(force, ForceMode.Acceleration);
+        }
+
+        if (rb.linearVelocity.magnitude > maxSpeed)
+        {
+            rb.linearVelocity = rb.linearVelocity.normalized * maxSpeed;
+        }
+
+        if (distanceToTarget < 0.5f && currentSpeed < 1f)
+        {
+            rb.linearVelocity = Vector3.zero;
+        }
+    }
+
+    void ApplyRotation()
+    {
+        if (rb == null) return;
+
+        Vector3 velocity = rb.linearVelocity;
+
+        if (velocity.magnitude > 0.5f)
+        {
+            Vector3 lookDirection = new Vector3(velocity.x, 0, velocity.z);
+            Quaternion targetRotation = Quaternion.LookRotation(lookDirection);
+
+            transform.rotation = Quaternion.Slerp(
+                transform.rotation,
+                targetRotation,
+                turnSpeed * Time.fixedDeltaTime
+            );
+        }
+    }
+
+    #endregion
+
+    #region Helper Methods
+
+    bool IsTeammateCarryingPuck(out PlayerController carrier)
+    {
+        carrier = puck?.CurrentCarrier;
+        if (carrier == null) return false;
+
+        return !IsOpponent(carrier) && carrier != playerController;
+    }
+
+    bool IsOpponent(PlayerController other)
+    {
+        if (other == null || playerController == null) return false;
+        return other.CompareTag("HomeTeam") != CompareTag("HomeTeam");
+    }
+
+    bool IsDefender(PlayerPosition position)
+    {
+        return position == PlayerPosition.LD || position == PlayerPosition.RD;
+    }
+
+    bool IsInOffensiveZone()
+    {
+        bool isHomeTeam = CompareTag("HomeTeam");
+        return isHomeTeam ? transform.position.z > offensiveBlueLineZ : transform.position.z < -offensiveBlueLineZ;
+    }
+
+    Vector3 GetOpponentGoalPosition()
+    {
+        bool isHomeTeam = CompareTag("HomeTeam");
+        return isHomeTeam ? new Vector3(0, 1, 30f) : new Vector3(0, 1, -30f);
+    }
+
+    Vector3 GetOwnGoalPosition()
+    {
+        bool isHomeTeam = CompareTag("HomeTeam");
+        return isHomeTeam ? new Vector3(0, 1, -30f) : new Vector3(0, 1, 30f);
+    }
+
+    PlayerController[] FindOpponents()
+    {
+        return FindObjectsByType<PlayerController>(FindObjectsSortMode.None)
+            .Where(p => IsOpponent(p))
+            .ToArray();
+    }
+
+    PlayerController[] FindTeammates()
+    {
+        return FindObjectsByType<PlayerController>(FindObjectsSortMode.None)
+            .Where(p => !IsOpponent(p) && p != playerController)
+            .ToArray();
+    }
+
+    bool IsClosestTeammateToOpponent(PlayerController opponent)
+    {
+        PlayerController[] teammates = FindTeammates();
+        float myDistance = Vector3.Distance(transform.position, opponent.transform.position);
+
+        foreach (PlayerController teammate in teammates)
+        {
+            float teammateDistance = Vector3.Distance(teammate.transform.position, opponent.transform.position);
+            if (teammateDistance < myDistance)
+            {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    PlayerController GetClosestTeammateToPuck()
+    {
+        if (puck == null) return playerController;
+
+        PlayerController[] teammates = FindObjectsByType<PlayerController>(FindObjectsSortMode.None)
+            .Where(p => !IsOpponent(p))
+            .ToArray();
+
+        PlayerController closest = playerController;
+        float closestDistance = Vector3.Distance(transform.position, puck.transform.position);
+
+        foreach (PlayerController teammate in teammates)
+        {
+            float distance = Vector3.Distance(teammate.transform.position, puck.transform.position);
+            if (distance < closestDistance)
+            {
+                closestDistance = distance;
+                closest = teammate;
+            }
+        }
+
+        return closest;
+    }
+
+    #endregion
+
+    #region Debug Visualization
+
+    void OnDrawGizmos()
+    {
+        if (!isAIControlled) return;
+
+        // Draw target position
+        Gizmos.color = Color.yellow;
+        Gizmos.DrawWireSphere(targetPosition, 0.5f);
+        Gizmos.DrawLine(transform.position, targetPosition);
+
+        // Draw desired velocity
+        Gizmos.color = Color.green;
+        Gizmos.DrawRay(transform.position, desiredVelocity);
+
+        // Draw current velocity
+        if (rb != null)
+        {
+            Gizmos.color = Color.blue;
+            Gizmos.DrawRay(transform.position, rb.linearVelocity);
+        }
+    }
+
+    #endregion
+}

+ 2 - 0
Assets/Scripts/Player/AI/PlayerAIMovement.cs.meta

@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: 52e16bdebf3d7dc42862c533368c009b

+ 37 - 2
Assets/Scripts/Player/PlayerController.cs

@@ -20,7 +20,21 @@ public class PlayerController : MonoBehaviour
     private bool hasPuck = false;
     private PuckController controlledPuck;
     private float lastPickupTime = 0f;
-    private bool isFrozen = false;
+    private bool isFrozen = true; // Start frozen - requires faceoff to begin
+    private Rigidbody rb;
+
+    void Awake()
+    {
+        rb = GetComponent<Rigidbody>();
+        
+        // Start frozen - make kinematic immediately
+        if (rb != null)
+        {
+            rb.linearVelocity = Vector3.zero;
+            rb.angularVelocity = Vector3.zero;
+            rb.isKinematic = true;
+        }
+    }
 
     void Start()
     {
@@ -107,7 +121,28 @@ public class PlayerController : MonoBehaviour
     public void SetFrozen(bool frozen)
     {
         isFrozen = frozen;
-        // You can add visual feedback here (e.g., change color, show "frozen" indicator)
+        
+        if (rb != null)
+        {
+            if (frozen)
+            {
+                // Immediately stop all motion
+                rb.linearVelocity = Vector3.zero;
+                rb.angularVelocity = Vector3.zero;
+                // Make kinematic to completely prevent physics interactions
+                rb.isKinematic = true;
+            }
+            else
+            {
+                // Restore physics
+                rb.isKinematic = false;
+            }
+        }
+    }
+    
+    public bool IsFrozen()
+    {
+        return isFrozen;
     }
 
     public void GainPuck(PuckController newPuck)

+ 111 - 4
Assets/Scripts/Player/PlayerMovement.cs

@@ -3,41 +3,117 @@ using UnityEngine.InputSystem;
 
 public class PlayerMovement : MonoBehaviour
 {
+    [Header("Control Mode")]
+    [Tooltip("Is this player controlled by human input or AI?")]
+    public bool isPlayerControlled = false;
+
     [Header("Movement Settings")]
     public float moveSpeed = 5f;
     public float rotationSpeed = 10f;
+    public float maxSpeed = 8f;
+    public float acceleration = 15f;
+    public float deceleration = 10f;
 
     private Vector2 moveInput;
     private PlayerInput playerInput;
     private Rigidbody rb;
+    private PlayerAIMovement aiMovement;
+    private PlayerController playerController;
 
     void Awake()
     {
         playerInput = GetComponent<PlayerInput>();
+        aiMovement = GetComponent<PlayerAIMovement>();
+        playerController = GetComponent<PlayerController>();
     }
 
     void Start()
     {
         rb = GetComponent<Rigidbody>();
+
+        // Configure Rigidbody for hockey physics
+        if (rb != null)
+        {
+            rb.constraints = RigidbodyConstraints.FreezeRotationX |
+                           RigidbodyConstraints.FreezeRotationZ |
+                           RigidbodyConstraints.FreezePositionY;
+            rb.linearDamping = 1f;
+        }
+
+        // Enable/disable AI based on control mode
+        if (aiMovement != null)
+        {
+            aiMovement.IsAIControlled = !isPlayerControlled;
+        }
+
+        // Disable player input if AI controlled
+        if (playerInput != null)
+        {
+            playerInput.enabled = isPlayerControlled;
+        }
     }
 
     public void OnMove(InputAction.CallbackContext context)
     {
+        if (!isPlayerControlled) return;
         moveInput = context.ReadValue<Vector2>();
     }
 
     void FixedUpdate()
     {
-        HandleMovement();
+        if (isPlayerControlled)
+        {
+            HandlePlayerMovement();
+        }
+        // AI movement is handled by PlayerAIMovement component
     }
 
-    void HandleMovement()
+    void HandlePlayerMovement()
     {
+        if (rb == null) return;
+        
+        // Don't allow movement if frozen (during faceoff)
+        if (playerController != null && playerController.IsFrozen())
+        {
+            // Immediately stop all movement when frozen
+            rb.linearVelocity = Vector3.zero;
+            rb.angularVelocity = Vector3.zero;
+            return;
+        }
+
+        // Don't allow movement if puck is not in play
+        if (GameManager.Instance != null && !GameManager.Instance.IsPuckInPlay)
+        {
+            // Apply deceleration when puck is not in play
+            if (rb.linearVelocity.magnitude > 0.1f)
+            {
+                Vector3 decelerationForce = -rb.linearVelocity.normalized * deceleration;
+                rb.AddForce(decelerationForce, ForceMode.Acceleration);
+            }
+            else
+            {
+                rb.linearVelocity = Vector3.zero;
+            }
+            return;
+        }
+
         if (moveInput.magnitude > 0.1f)
         {
-            Vector3 movement = new Vector3(moveInput.x, 0, moveInput.y) * moveSpeed;
-            rb.linearVelocity = new Vector3(movement.x, rb.linearVelocity.y, movement.z);
+            // Use force-based movement for realistic hockey physics
+            Vector3 inputDirection = new Vector3(moveInput.x, 0, moveInput.y).normalized;
+            Vector3 desiredVelocity = inputDirection * moveSpeed;
+            Vector3 velocityDifference = desiredVelocity - rb.linearVelocity;
+
+            // Apply acceleration force
+            rb.AddForce(velocityDifference * acceleration, ForceMode.Acceleration);
+
+            // Clamp velocity to max speed
+            if (rb.linearVelocity.magnitude > maxSpeed)
+            {
+                rb.linearVelocity = rb.linearVelocity.normalized * maxSpeed;
+            }
 
+            // Rotate toward movement direction
             Vector3 lookDirection = new Vector3(moveInput.x, 0, moveInput.y);
             if (lookDirection != Vector3.zero)
             {
@@ -45,5 +121,36 @@ public class PlayerMovement : MonoBehaviour
                 transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, rotationSpeed * Time.fixedDeltaTime);
             }
         }
+        else
+        {
+            // Apply deceleration when no input
+            if (rb.linearVelocity.magnitude > 0.1f)
+            {
+                Vector3 decelerationForce = -rb.linearVelocity.normalized * deceleration;
+                rb.AddForce(decelerationForce, ForceMode.Acceleration);
+            }
+            else
+            {
+                rb.linearVelocity = Vector3.zero;
+            }
+        }
+    }
+
+    /// <summary>
+    /// Switch between player and AI control
+    /// </summary>
+    public void SetControlMode(bool playerControlled)
+    {
+        isPlayerControlled = playerControlled;
+
+        if (aiMovement != null)
+        {
+            aiMovement.IsAIControlled = !playerControlled;
+        }
+
+        if (playerInput != null)
+        {
+            playerInput.enabled = playerControlled;
+        }
     }
 }

+ 100 - 0
Assets/Scripts/UIController.cs

@@ -0,0 +1,100 @@
+using UnityEngine;
+using UnityEngine.UIElements;
+
+/// <summary>
+/// Controls the game UI, updating score and timer displays.
+/// </summary>
+[RequireComponent(typeof(UIDocument))]
+public class UIController : MonoBehaviour
+{
+    private UIDocument uiDocument;
+
+    // UI Elements
+    private Label homeTeamLabel;
+    private Label homeScoreLabel;
+    private Label awayTeamLabel;
+    private Label awayScoreLabel;
+    private Label timerLabel;
+    private Label periodLabel;
+
+    [Header("Team Names")]
+    [SerializeField] private string homeTeamName = "Home Team";
+    [SerializeField] private string awayTeamName = "Away Team";
+
+    void Awake()
+    {
+        uiDocument = GetComponent<UIDocument>();
+    }
+
+    void OnEnable()
+    {
+        // Get root visual element
+        var root = uiDocument.rootVisualElement;
+
+        // Query UI elements
+        homeTeamLabel = root.Q<Label>("HomeTeamLabel");
+        homeScoreLabel = root.Q<Label>("HomeScoreLabel");
+        awayTeamLabel = root.Q<Label>("AwayTeamLabel");
+        awayScoreLabel = root.Q<Label>("AwayScoreLabel");
+        timerLabel = root.Q<Label>("TimerLabel");
+        periodLabel = root.Q<Label>("PeriodLabel");
+
+        // Set team names
+        if (homeTeamLabel != null)
+            homeTeamLabel.text = homeTeamName;
+
+        if (awayTeamLabel != null)
+            awayTeamLabel.text = awayTeamName;
+
+        // Subscribe to GameManager events
+        if (GameManager.Instance != null)
+        {
+            GameManager.Instance.OnScoreChanged += UpdateScore;
+            GameManager.Instance.OnTimeChanged += UpdateTimer;
+            GameManager.Instance.OnPeriodChanged += UpdatePeriod;
+
+            // Initialize display
+            UpdateScore(GameManager.Instance.HomeScore, GameManager.Instance.AwayScore);
+            UpdateTimer(GameManager.Instance.TimeRemaining);
+            UpdatePeriod(GameManager.Instance.CurrentPeriod);
+        }
+    }
+
+    void OnDisable()
+    {
+        // Unsubscribe from events
+        if (GameManager.Instance != null)
+        {
+            GameManager.Instance.OnScoreChanged -= UpdateScore;
+            GameManager.Instance.OnTimeChanged -= UpdateTimer;
+            GameManager.Instance.OnPeriodChanged -= UpdatePeriod;
+        }
+    }
+
+    private void UpdateScore(int homeScore, int awayScore)
+    {
+        if (homeScoreLabel != null)
+            homeScoreLabel.text = homeScore.ToString();
+
+        if (awayScoreLabel != null)
+            awayScoreLabel.text = awayScore.ToString();
+    }
+
+    private void UpdateTimer(float timeRemaining)
+    {
+        if (timerLabel != null)
+        {
+            int minutes = Mathf.FloorToInt(timeRemaining / 60f);
+            int seconds = Mathf.FloorToInt(timeRemaining % 60f);
+            timerLabel.text = $"{minutes:00}:{seconds:00}";
+        }
+    }
+
+    private void UpdatePeriod(int period)
+    {
+        if (periodLabel != null)
+        {
+            periodLabel.text = $"Period {period}";
+        }
+    }
+}

+ 2 - 0
Assets/Scripts/UIController.cs.meta

@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: 467d02f166eab9c4ca29da60a9a2cdf9

+ 8 - 0
Assets/UI Toolkit.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 83587f777ef1728448eca7807705647a
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 8 - 0
Assets/UI Toolkit/UnityThemes.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 06910afd3b1b63144b7e7e6b93e57fc7
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 1 - 0
Assets/UI Toolkit/UnityThemes/UnityDefaultRuntimeTheme.tss

@@ -0,0 +1 @@
+@import url("unity-theme://default");

+ 11 - 0
Assets/UI Toolkit/UnityThemes/UnityDefaultRuntimeTheme.tss.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 3cab36472fc269d4e9b9718fd42136a0
+ScriptedImporter:
+  internalIDToNameTable: []
+  externalObjects: {}
+  serializedVersion: 2
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
+  script: {fileID: 12388, guid: 0000000000000000e000000000000000, type: 0}
+  disableValidation: 0

+ 8 - 0
Assets/UI.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 159a8c71d2d17e44cade10df6c1d66b9
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 75 - 0
Assets/UI/GameUI.uss

@@ -0,0 +1,75 @@
+.scoreboard-container {
+    flex-direction: row;
+    justify-content: center;
+    align-items: center;
+    padding-top: 20px;
+    padding-bottom: 20px;
+    padding-left: 40px;
+    padding-right: 40px;
+    background-color: rgba(0, 0, 0, 0.8);
+    border-bottom-left-radius: 15px;
+    border-bottom-right-radius: 15px;
+    border-top-width: 0;
+    border-bottom-width: 3px;
+    border-left-width: 3px;
+    border-right-width: 3px;
+    border-color: rgb(255, 255, 255);
+    margin-top: 0;
+}
+
+.team-section {
+    flex-direction: row;
+    align-items: center;
+    justify-content: center;
+    padding-left: 20px;
+    padding-right: 20px;
+}
+
+.team-name {
+    font-size: 28px;
+    color: rgb(255, 255, 255);
+    -unity-font-style: bold;
+    padding-left: 10px;
+    padding-right: 10px;
+    text-shadow: 2px 2px 4px rgba(0, 0, 0, 1);
+}
+
+.score-label {
+    font-size: 48px;
+    color: rgb(255, 215, 0);
+    -unity-font-style: bold;
+    padding-left: 15px;
+    padding-right: 15px;
+    text-shadow: 3px 3px 6px rgba(0, 0, 0, 1);
+}
+
+.timer-section {
+    flex-direction: column;
+    align-items: center;
+    justify-content: center;
+    padding-left: 30px;
+    padding-right: 30px;
+    margin-left: 20px;
+    margin-right: 20px;
+    background-color: rgba(255, 255, 255, 0.1);
+    border-radius: 10px;
+    padding-top: 10px;
+    padding-bottom: 10px;
+}
+
+.period-label {
+    font-size: 18px;
+    color: rgb(200, 200, 200);
+    -unity-font-style: bold;
+    margin-bottom: 5px;
+    text-shadow: 1px 1px 2px rgba(0, 0, 0, 1);
+}
+
+.timer-label {
+    font-size: 42px;
+    color: rgb(255, 255, 255);
+    -unity-font-style: bold;
+    font-family: 'monospace';
+    text-shadow: 3px 3px 6px rgba(0, 0, 0, 1);
+    letter-spacing: 2px;
+}

+ 11 - 0
Assets/UI/GameUI.uss.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: fa56cef70bca55749ab2f55f6a15854b
+ScriptedImporter:
+  internalIDToNameTable: []
+  externalObjects: {}
+  serializedVersion: 2
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
+  script: {fileID: 12385, guid: 0000000000000000e000000000000000, type: 0}
+  disableValidation: 0

+ 19 - 0
Assets/UI/GameUI.uxml

@@ -0,0 +1,19 @@
+<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" editor-extension-mode="False">
+    <Style src="project://database/Assets/UI/GameUI.uss?fileID=7433441132597879392&amp;guid=fa56cef70bca55749ab2f55f6a15854b&amp;type=3#GameUI" />
+    <ui:VisualElement name="RootContainer" style="flex-grow: 1; justify-content: flex-start; align-items: center;">
+        <ui:VisualElement name="ScoreboardContainer" class="scoreboard-container">
+            <ui:VisualElement name="HomeSection" class="team-section">
+                <ui:Label text="Home Team" name="HomeTeamLabel" class="team-name" />
+                <ui:Label text="0" name="HomeScoreLabel" class="score-label" />
+            </ui:VisualElement>
+            <ui:VisualElement name="TimerSection" class="timer-section">
+                <ui:Label text="1" name="PeriodLabel" class="period-label" />
+                <ui:Label text="20:00" name="TimerLabel" class="timer-label" />
+            </ui:VisualElement>
+            <ui:VisualElement name="AwaySection" class="team-section">
+                <ui:Label text="0" name="AwayScoreLabel" class="score-label" />
+                <ui:Label text="Away Team" name="AwayTeamLabel" class="team-name" />
+            </ui:VisualElement>
+        </ui:VisualElement>
+    </ui:VisualElement>
+</ui:UXML>

+ 10 - 0
Assets/UI/GameUI.uxml.meta

@@ -0,0 +1,10 @@
+fileFormatVersion: 2
+guid: 9cbb0caf6614e0643a6991746a780659
+ScriptedImporter:
+  internalIDToNameTable: []
+  externalObjects: {}
+  serializedVersion: 2
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
+  script: {fileID: 13804, guid: 0000000000000000e000000000000000, type: 0}

+ 49 - 0
Assets/UI/PanelSettings.asset

@@ -0,0 +1,49 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!114 &11400000
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 0}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 19101, guid: 0000000000000000e000000000000000, type: 0}
+  m_Name: PanelSettings
+  m_EditorClassIdentifier: UnityEngine.dll::UnityEngine.UIElements.PanelSettings
+  themeUss: {fileID: -4733365628477956816, guid: 3cab36472fc269d4e9b9718fd42136a0, type: 3}
+  m_DisableNoThemeWarning: 0
+  m_TargetTexture: {fileID: 0}
+  m_RenderMode: 0
+  m_ColliderUpdateMode: 0
+  m_ColliderIsTrigger: 1
+  m_ScaleMode: 1
+  m_ReferenceSpritePixelsPerUnit: 100
+  m_PixelsPerUnit: 100
+  m_Scale: 1
+  m_ReferenceDpi: 96
+  m_FallbackDpi: 96
+  m_ReferenceResolution: {x: 1200, y: 800}
+  m_ScreenMatchMode: 0
+  m_Match: 0
+  m_SortingOrder: 0
+  m_TargetDisplay: 0
+  m_BindingLogLevel: 0
+  m_ClearDepthStencil: 1
+  m_ClearColor: 0
+  m_ColorClearValue: {r: 0, g: 0, b: 0, a: 0}
+  m_VertexBudget: 0
+  m_DynamicAtlasSettings:
+    m_MinAtlasSize: 64
+    m_MaxAtlasSize: 4096
+    m_MaxSubTextureSize: 64
+    m_ActiveFilters: -1
+  m_AtlasBlitShader: {fileID: 9101, guid: 0000000000000000f000000000000000, type: 0}
+  m_DefaultShader: {fileID: 9100, guid: 0000000000000000f000000000000000, type: 0}
+  m_SDFShader: {fileID: 19011, guid: 0000000000000000f000000000000000, type: 0}
+  m_BitmapShader: {fileID: 9001, guid: 0000000000000000f000000000000000, type: 0}
+  m_SpriteShader: {fileID: 19012, guid: 0000000000000000f000000000000000, type: 0}
+  m_ICUDataAsset: {fileID: 0}
+  forceGammaRendering: 0
+  textSettings: {fileID: 0}

+ 8 - 0
Assets/UI/PanelSettings.asset.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: fc1256bfa188bab458a9fd3db5b366c8
+NativeFormatImporter:
+  externalObjects: {}
+  mainObjectFileID: 11400000
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 224 - 0
Assets/UI/SETUP_INSTRUCTIONS.md

@@ -0,0 +1,224 @@
+# Hockey Game UI and Timer System
+
+This update adds a UI Builder scoreboard with timer control and a "puck in play" system that controls when the timer runs and when players can move.
+
+## Features Implemented
+
+### 1. **GameManager** (Central Game Control)
+- Manages game time (countdown from 20:00)
+- Tracks home/away scores
+- Controls period tracking
+- **Puck In Play Control**: Timer only runs when puck is in play
+- Events system for UI updates
+
+### 2. **UI System** (UI Toolkit/UI Builder)
+- **Scoreboard Layout**: "Home Team" 0 | Timer | 0 "Away Team"
+- Real-time score updates
+- Countdown timer display (MM:SS format)
+- Period indicator
+- Styled with professional hockey scoreboard look
+
+### 3. **Faceoff Integration**
+- Timer stops during faceoffs
+- Players are frozen until faceoff resolves to:
+  - HomeWin
+  - AwayWin  
+  - Struggle
+- Timer starts automatically when puck is in play
+
+### 4. **Player Movement Control**
+- Both human and AI players respect "puck in play" state
+- No movement during faceoffs
+- Smooth deceleration when frozen
+
+## Setup Instructions
+
+### Step 1: Add GameManager
+1. In your scene, create an empty GameObject
+2. Name it "GameManager"
+3. Add the `GameManager` component
+4. Configure settings (optional):
+   - Period Duration: 1200 seconds (20:00)
+   - Total Periods: 3
+
+### Step 2: Setup UI
+1. Create an empty GameObject named "GameUI"
+2. Add `UIDocument` component
+3. Configure UIDocument:
+   - **Source Asset**: Select `Assets/UI/GameUI.uxml`
+   - **Panel Settings**: Create or use existing Panel Settings (see Step 3)
+4. Add `UIController` component to the same GameObject
+5. In UIController, set:
+   - Home Team Name: "Home Team" (or your team name)
+   - Away Team Name: "Away Team" (or your team name)
+
+### Step 3: Create Panel Settings (if needed)
+1. Right-click in Project window
+2. Select: **Create > UI Toolkit > Panel Settings Asset**
+3. Name it "GameUIPanelSettings"
+4. Configure:
+   - **Scale Mode**: Scale With Screen Size
+   - **Reference Resolution**: 1920 x 1080
+   - **Screen Match Mode**: Match Width Or Height
+   - **Match**: 0.5 (balance between width and height)
+5. Assign this Panel Settings to your UIDocument component
+
+### Step 4: Link FaceoffManager (if not already linked)
+Your existing FaceoffManager is already updated to work with the new system. It will automatically:
+- Set puck in play to false when faceoff starts
+- Set puck in play to true when faceoff completes
+- Freeze all players during faceoffs
+
+### Step 5: Test the System
+1. Press Play in Unity
+2. Press **F** to trigger a faceoff at center ice
+3. Observe:
+   - Timer stops
+   - Players freeze
+   - Faceoff resolves after ~2 seconds
+   - Timer starts counting down
+   - Players can move
+
+## How It Works
+
+### Puck In Play Flow
+```
+Game Starts
+    ↓
+Timer: 20:00, Puck In Play: FALSE
+    ↓
+Press F (Faceoff Starts)
+    ↓
+Freeze Players, Timer Stays Paused
+    ↓
+Faceoff Resolves (HomeWin/AwayWin/Struggle)
+    ↓
+Puck In Play: TRUE
+    ↓
+Timer Counts Down, Players Can Move
+    ↓
+Goal Scored
+    ↓
+Puck In Play: FALSE (new faceoff needed)
+```
+
+### Key Scripts
+
+#### GameManager.cs
+- Singleton pattern
+- Controls game state
+- Manages timer countdown
+- Score tracking
+- Event broadcasting
+
+#### UIController.cs
+- Subscribes to GameManager events
+- Updates UI labels in real-time
+- Formats time display
+
+#### FaceoffManager.cs (Updated)
+- Signals GameManager when faceoff starts/ends
+- Controls puck in play state
+
+#### PlayerMovement.cs (Updated)
+- Checks `GameManager.Instance.IsPuckInPlay`
+- Stops player input when false
+- Applies deceleration
+
+#### PlayerAIMovement.cs (Updated)
+- Checks `GameManager.Instance.IsPuckInPlay`
+- Stops AI decisions when false
+- Stops AI movement when false
+
+## Testing Checklist
+
+- [ ] GameManager exists in scene
+- [ ] UI displays correctly at top of screen
+- [ ] Timer shows "20:00" at start
+- [ ] Period shows "Period 1"
+- [ ] Scores show "0 - 0"
+- [ ] Press F to start faceoff
+- [ ] Timer remains at 20:00 during faceoff
+- [ ] Players cannot move during faceoff
+- [ ] After faceoff completes, timer counts down
+- [ ] Players can move after faceoff
+- [ ] Score updates work (test manually via GameManager.Instance.AddHomeScore(1))
+
+## Customization
+
+### Change Team Names
+In UIController component:
+- Home Team Name: Enter your home team name
+- Away Team Name: Enter your away team name
+
+### Change Period Duration
+In GameManager component:
+- Period Duration: Set in seconds (1200 = 20:00)
+
+### Style Modifications
+Edit `Assets/UI/GameUI.uss` to customize:
+- Colors (background, text, scores)
+- Font sizes
+- Spacing and padding
+- Border styles
+
+### Add Goal Detection
+To automatically trigger scoring when puck enters net:
+```csharp
+// In your goal detection script:
+if (GameManager.Instance != null)
+{
+    if (isHomeGoal)
+        GameManager.Instance.AddAwayScore();
+    else
+        GameManager.Instance.AddHomeScore();
+}
+```
+
+## Files Created/Modified
+
+### New Files
+- `Assets/Scripts/GameManager.cs` - Main game controller
+- `Assets/Scripts/UIController.cs` - UI manager
+- `Assets/UI/GameUI.uxml` - UI layout
+- `Assets/UI/GameUI.uss` - UI styles
+- `Assets/UI/SETUP_INSTRUCTIONS.md` - This file
+
+### Modified Files
+- `Assets/Scripts/FaceoffManager.cs` - Added GameManager integration
+- `Assets/Scripts/Player/PlayerMovement.cs` - Added puck in play check
+- `Assets/Scripts/Player/AI/PlayerAIMovement.cs` - Added puck in play check
+- `Assets/Scripts/MainGameScript.cs` - Added setup documentation
+
+## Troubleshooting
+
+### Timer not counting down
+- Check GameManager exists in scene
+- Verify faceoff has completed (press F and wait)
+- Check Console for "Puck in play: True" message
+
+### UI not showing
+- Verify UIDocument has GameUI.uxml assigned
+- Check Panel Settings is assigned
+- Ensure UIDocument has UIController component
+- Check Canvas scale mode
+
+### Players still moving during faceoff
+- Verify GameManager.Instance is not null
+- Check FaceoffManager is calling SetPuckInPlay
+- Verify PlayerMovement/PlayerAIMovement have been updated
+
+### Events not firing
+- Ensure only ONE GameManager exists in scene
+- Check UIController OnEnable is subscribing to events
+- Verify GameManager.Instance is accessible
+
+## Future Enhancements
+
+Possible additions:
+- Pause menu integration
+- Overtime periods
+- Shot clock
+- Penalty timer display
+- Replay last goal
+- Game statistics

+ 7 - 0
Assets/UI/SETUP_INSTRUCTIONS.md.meta

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

+ 1 - 0
ProjectSettings/TagManager.asset

@@ -6,6 +6,7 @@ TagManager:
   tags:
   - HomeTeam
   - AwayTeam
+  - Puck
   layers:
   - Default
   - TransparentFX

+ 46 - 46
UserSettings/Layouts/default-6000.dwlt

@@ -39,7 +39,7 @@ MonoBehaviour:
   m_Children: []
   m_Position:
     serializedVersion: 2
-    x: 1674
+    x: 1675
     y: 0
     width: 1089
     height: 439
@@ -69,12 +69,12 @@ MonoBehaviour:
     serializedVersion: 2
     x: 0
     y: 854
-    width: 2763
+    width: 2764
     height: 439
   m_MinSize: {x: 200, y: 50}
   m_MaxSize: {x: 16192, y: 8096}
   vertical: 0
-  controlID: 118
+  controlID: 121
   draggingID: 0
 --- !u!114 &4
 MonoBehaviour:
@@ -91,9 +91,9 @@ MonoBehaviour:
   m_Children: []
   m_Position:
     serializedVersion: 2
-    x: 1673
+    x: 1671
     y: 0
-    width: 1090
+    width: 1093
     height: 854
   m_MinSize: {x: 52, y: 76}
   m_MaxSize: {x: 4002, y: 4026}
@@ -198,7 +198,7 @@ MonoBehaviour:
   m_MinSize: {x: 400, y: 100}
   m_MaxSize: {x: 32384, y: 16192}
   vertical: 0
-  controlID: 47
+  controlID: 48
   draggingID: 0
 --- !u!114 &9
 MonoBehaviour:
@@ -219,12 +219,12 @@ MonoBehaviour:
     serializedVersion: 2
     x: 0
     y: 0
-    width: 2763
+    width: 2764
     height: 1293
   m_MinSize: {x: 300, y: 100}
   m_MaxSize: {x: 24288, y: 16192}
   vertical: 1
-  controlID: 48
+  controlID: 49
   draggingID: 0
 --- !u!114 &10
 MonoBehaviour:
@@ -246,12 +246,12 @@ MonoBehaviour:
     serializedVersion: 2
     x: 0
     y: 0
-    width: 2763
+    width: 2764
     height: 854
   m_MinSize: {x: 300, y: 50}
   m_MaxSize: {x: 24288, y: 8096}
   vertical: 0
-  controlID: 49
+  controlID: 50
   draggingID: 0
 --- !u!114 &11
 MonoBehaviour:
@@ -270,7 +270,7 @@ MonoBehaviour:
     serializedVersion: 2
     x: 0
     y: 0
-    width: 619
+    width: 618
     height: 854
   m_MinSize: {x: 201, y: 226}
   m_MaxSize: {x: 4001, y: 4026}
@@ -294,9 +294,9 @@ MonoBehaviour:
   m_Children: []
   m_Position:
     serializedVersion: 2
-    x: 619
+    x: 618
     y: 0
-    width: 1054
+    width: 1053
     height: 854
   m_MinSize: {x: 202, y: 226}
   m_MaxSize: {x: 4002, y: 4026}
@@ -324,7 +324,7 @@ MonoBehaviour:
     serializedVersion: 2
     x: 0
     y: 0
-    width: 1674
+    width: 1675
     height: 439
   m_MinSize: {x: 231, y: 276}
   m_MaxSize: {x: 10001, y: 10026}
@@ -348,9 +348,9 @@ MonoBehaviour:
   m_Children: []
   m_Position:
     serializedVersion: 2
-    x: 2763
+    x: 2764
     y: 0
-    width: 677
+    width: 676
     height: 1293
   m_MinSize: {x: 276, y: 76}
   m_MaxSize: {x: 4001, y: 4026}
@@ -416,9 +416,9 @@ MonoBehaviour:
     m_TextWithWhitespace: "Game\u200B"
   m_Pos:
     serializedVersion: 2
-    x: 1674
+    x: 1672
     y: 24
-    width: 1088
+    width: 1091
     height: 828
   m_SerializedDataModeController:
     m_DataMode: 0
@@ -437,7 +437,7 @@ MonoBehaviour:
   m_ShowGizmos: 0
   m_TargetDisplay: 0
   m_ClearColor: {r: 0, g: 0, b: 0, a: 0}
-  m_TargetSize: {x: 1088, y: 807}
+  m_TargetSize: {x: 1091, y: 807}
   m_TextureFilterMode: 0
   m_TextureHideFlags: 61
   m_RenderIMGUI: 1
@@ -452,8 +452,8 @@ MonoBehaviour:
     m_VRangeLocked: 0
     hZoomLockedByDefault: 0
     vZoomLockedByDefault: 0
-    m_HBaseRangeMin: -544
-    m_HBaseRangeMax: 544
+    m_HBaseRangeMin: -545.5
+    m_HBaseRangeMax: 545.5
     m_VBaseRangeMin: -403.5
     m_VBaseRangeMax: 403.5
     m_HAllowExceedBaseRangeMin: 1
@@ -473,23 +473,23 @@ MonoBehaviour:
       serializedVersion: 2
       x: 0
       y: 21
-      width: 1088
+      width: 1091
       height: 807
     m_Scale: {x: 1, y: 1}
-    m_Translation: {x: 544, y: 403.5}
+    m_Translation: {x: 545.5, y: 403.5}
     m_MarginLeft: 0
     m_MarginRight: 0
     m_MarginTop: 0
     m_MarginBottom: 0
     m_LastShownAreaInsideMargins:
       serializedVersion: 2
-      x: -544
+      x: -545.5
       y: -403.5
-      width: 1088
+      width: 1091
       height: 807
     m_MinimalGUI: 1
   m_defaultScale: 1
-  m_LastWindowPixelSize: {x: 1088, y: 828}
+  m_LastWindowPixelSize: {x: 1091, y: 828}
   m_ClearInEditMode: 1
   m_NoCameraWarning: 1
   m_LowResolutionForAspectRatios: 01000000000000000000
@@ -534,7 +534,7 @@ MonoBehaviour:
     m_OverlaysVisible: 1
   m_LockTracker:
     m_IsLocked: 0
-  m_LastSelectedObjectID: -61036
+  m_LastSelectedObjectID: 46776
 --- !u!114 &18
 MonoBehaviour:
   m_ObjectHideFlags: 52
@@ -558,7 +558,7 @@ MonoBehaviour:
     serializedVersion: 2
     x: 0
     y: 24
-    width: 618
+    width: 617
     height: 828
   m_SerializedDataModeController:
     m_DataMode: 0
@@ -576,7 +576,7 @@ MonoBehaviour:
       scrollPos: {x: 0, y: 0}
       m_SelectedIDs: 
       m_LastClickedID: 0
-      m_ExpandedIDs: 46f8feff9411ffff9421ffff9226ffff2e1c0100
+      m_ExpandedIDs: 367fffff82d2ffff86d2ffff8ad2ffff8ed2ffff92d2ffffbef3ffff32f4ffffa6f4ffff2ef5fffffcfaffffa8b60000b8b60000
       m_RenameOverlay:
         m_UserAcceptedRename: 0
         m_Name: 
@@ -622,9 +622,9 @@ MonoBehaviour:
     m_TextWithWhitespace: "Scene\u200B"
   m_Pos:
     serializedVersion: 2
-    x: 620
+    x: 619
     y: 24
-    width: 1052
+    width: 1051
     height: 828
   m_SerializedDataModeController:
     m_DataMode: 0
@@ -1208,9 +1208,9 @@ MonoBehaviour:
   m_AudioPlay: 0
   m_DebugDrawModesUseInteractiveLightBakingData: 0
   m_Position:
-    m_Target: {x: -4.956815, y: 0.027747154, z: 1.8365153}
+    m_Target: {x: 2.0623045, y: -3.054058, z: 6.2507105}
     speed: 2
-    m_Value: {x: -4.956815, y: 0.027747154, z: 1.8365153}
+    m_Value: {x: 2.0623045, y: -3.054058, z: 6.2507105}
   m_RenderMode: 0
   m_CameraMode:
     drawMode: 0
@@ -1256,13 +1256,13 @@ MonoBehaviour:
     m_GridAxis: 1
     m_gridOpacity: 0.5
   m_Rotation:
-    m_Target: {x: 0.00021285702, y: 0.7064628, z: -0.7077522, w: 0.00021435508}
+    m_Target: {x: 0.0023394478, y: 0.7053961, z: -0.7088077, w: 0.0023293737}
     speed: 2
     m_Value: {x: 0, y: 0, z: 0, w: 1}
   m_Size:
-    m_Target: 2.9883866
+    m_Target: 15.90295
     speed: 2
-    m_Value: 2.9883866
+    m_Value: 15.90295
   m_Ortho:
     m_Target: 0
     speed: 2
@@ -1372,7 +1372,7 @@ MonoBehaviour:
     serializedVersion: 2
     x: 0
     y: 24
-    width: 1673
+    width: 1674
     height: 413
   m_SerializedDataModeController:
     m_DataMode: 0
@@ -1396,7 +1396,7 @@ MonoBehaviour:
     m_SkipHidden: 0
     m_SearchArea: 1
     m_Folders:
-    - Assets/ScriptableObjects
+    - Assets/Prefab
     m_Globs: []
     m_ProductIds: 
     m_AnyWithAssetOrigin: 0
@@ -1406,16 +1406,16 @@ MonoBehaviour:
   m_ViewMode: 1
   m_StartGridSize: 67
   m_LastFolders:
-  - Assets/ScriptableObjects
+  - Assets/Prefab
   m_LastFoldersGridSize: 67
   m_LastProjectPath: C:\Users\Axel-PC\Hockey
   m_LockTracker:
     m_IsLocked: 0
   m_FolderTreeState:
     scrollPos: {x: 0, y: 0}
-    m_SelectedIDs: ee1e0100
-    m_LastClickedID: 73454
-    m_ExpandedIDs: 00000000f4b70000f6b70000f8b70000fab70000fcb70000feb7000000b80000
+    m_SelectedIDs: a6b80000
+    m_LastClickedID: 47270
+    m_ExpandedIDs: 0000000088b800008ab800008cb800008eb8000090b8000092b8000094b80000
     m_RenameOverlay:
       m_UserAcceptedRename: 0
       m_Name: 
@@ -1444,7 +1444,7 @@ MonoBehaviour:
     scrollPos: {x: 0, y: 0}
     m_SelectedIDs: 
     m_LastClickedID: 0
-    m_ExpandedIDs: 00000000f4b70000f6b70000f8b70000fab70000fcb70000feb7000000b80000
+    m_ExpandedIDs: 0000000088b800008ab800008cb800008eb8000090b8000092b8000094b80000
     m_RenameOverlay:
       m_UserAcceptedRename: 0
       m_Name: 
@@ -1523,7 +1523,7 @@ MonoBehaviour:
     m_TextWithWhitespace: "Console\u200B"
   m_Pos:
     serializedVersion: 2
-    x: 1675
+    x: 1676
     y: 24
     width: 1087
     height: 413
@@ -1559,9 +1559,9 @@ MonoBehaviour:
     m_TextWithWhitespace: "Inspector\u200B"
   m_Pos:
     serializedVersion: 2
-    x: 2764
+    x: 2765
     y: 24
-    width: 676
+    width: 675
     height: 1267
   m_SerializedDataModeController:
     m_DataMode: 0