Axel Nordh 8 місяців тому
батько
коміт
6228bdc67a
100 змінених файлів з 25718 додано та 0 видалено
  1. 26 0
      .gitignore
  2. 5 0
      .vscode/extensions.json
  3. 16 0
      .vscode/launch.json
  4. 61 0
      .vscode/settings.json
  5. 17 0
      .vscode/tasks.json
  6. 131 0
      ADVANCED_TRAVEL_SYSTEM.md
  7. 1057 0
      Assets/InputSystem_Actions.inputactions
  8. 138 0
      Assets/Material/ArrowMaterial.mat
  9. 136 0
      Assets/Material/EnemyMaterial.mat
  10. 140 0
      Assets/Material/EnemySpawnBoxMaterial.mat
  11. 136 0
      Assets/Material/PlayerMaterial.mat
  12. 140 0
      Assets/Material/PlayerSpawnBoxMaterial.mat
  13. 136 0
      Assets/Material/Terrain/Forest.mat
  14. 136 0
      Assets/Material/Terrain/Mountain.mat
  15. 136 0
      Assets/Material/Terrain/Plain.mat
  16. 745 0
      Assets/Prefabs/Characters/Enemies/EnemyCharacter.prefab
  17. 718 0
      Assets/Prefabs/Characters/Players/PlayerCharacter.prefab
  18. 0 0
      Assets/Prefabs/Terrain/TerrainTile.prefab
  19. 125 0
      Assets/Prefabs/Weapons/Arrow.prefab
  20. 99 0
      Assets/Prefabs/Weapons/SimpleBow.prefab
  21. 102 0
      Assets/Prefabs/Weapons/SimpleSword.prefab
  22. BIN
      Assets/Prefabs/Weapons/bow.fbx
  23. BIN
      Assets/Prefabs/Weapons/sword.fbx
  24. 34 0
      Assets/Readme.asset
  25. 351 0
      Assets/Resources/UI/Map/TravelUI.uss
  26. 24 0
      Assets/Resources/UI/Map/TravelUI.uxml
  27. 100 0
      Assets/Resources/UI/MapLegend.uss
  28. 50 0
      Assets/Resources/UI/MapLegend.uxml
  29. 113 0
      Assets/Resources/UI/MapScene/AdvancedTravelOptions.uss
  30. 51 0
      Assets/Resources/UI/MapScene/AdvancedTravelOptions.uxml
  31. 199 0
      Assets/Resources/UI/MapScene/TeamOverview.uss
  32. 33 0
      Assets/Resources/UI/MapScene/TeamOverview.uxml
  33. 20 0
      Assets/Resources/UI/TravelPanelSettings.asset
  34. BIN
      Assets/SceneTemplateAssets/Common/Models/UnityMaterialBall.fbx
  35. 1545 0
      Assets/Scenes/BattleScene.unity
  36. BIN
      Assets/Scenes/BattleScene/NavMesh-GroundPlane.asset
  37. 451 0
      Assets/Scenes/BattleSetupMenu.unity
  38. 665 0
      Assets/Scenes/MainTeamSelectScene.unity
  39. 683 0
      Assets/Scenes/MapScene2.unity
  40. 405 0
      Assets/Scenes/TitleScreenScene.unity
  41. 84 0
      Assets/Scripts/BattleFieldMaker/BFMTerrainGenerator.cs
  42. 6 0
      Assets/Scripts/BattleFieldMaker/BFMTerrainType.cs
  43. 110 0
      Assets/Scripts/BattleFieldMaker/BattleFieldMaker.cs
  44. 180 0
      Assets/Scripts/BattleFieldMaker/FantasyNameGenerator.cs
  45. 112 0
      Assets/Scripts/BattleFieldMaker/MapCameraController.cs
  46. 93 0
      Assets/Scripts/BattleFieldMaker/MapLegendUI.cs
  47. 21 0
      Assets/Scripts/BattleFieldMaker/NavMeshGenerator.cs
  48. 139 0
      Assets/Scripts/BattleFieldMaker/README_FantasyNaming.md
  49. 44 0
      Assets/Scripts/BattleFieldMaker/SeasonManager.cs
  50. 137 0
      Assets/Scripts/BattleFieldMaker/TooltipSystem.cs
  51. 21 0
      Assets/Scripts/BattleFieldMaker/Utils/MathHelper.cs
  52. 68 0
      Assets/Scripts/BattleFieldMaker/Visual_Names_Instructions.md
  53. 398 0
      Assets/Scripts/BattleScene/BattleSetup.cs
  54. 152 0
      Assets/Scripts/BattleScene/BattleUiScript.cs
  55. 184 0
      Assets/Scripts/BattleScene/Controls.inputActions
  56. 661 0
      Assets/Scripts/BattleScene/GameManager.cs
  57. 373 0
      Assets/Scripts/BattleScene/PlayerDecisionController .cs
  58. 56 0
      Assets/Scripts/BattleScene/TargetingLine.cs
  59. 6 0
      Assets/Scripts/BattleScene/TurnManager.cs
  60. 16 0
      Assets/Scripts/BattleSetup/BattleSetupData.cs
  61. 92 0
      Assets/Scripts/BattleSetup/BattleSetupMenu.cs
  62. 56 0
      Assets/Scripts/Characters/Enemies/SkeletonCharacter.cs
  63. 51 0
      Assets/Scripts/Characters/HumanCharacter.cs
  64. 84 0
      Assets/Scripts/Controllers/CameraController.cs
  65. 198 0
      Assets/Scripts/Controllers/CinemachineCameraController.cs
  66. 0 0
      Assets/Scripts/Debug/FixTravelUISetup.cs
  67. 78 0
      Assets/Scripts/Debug/MapAreaVisualizer.cs
  68. 95 0
      Assets/Scripts/Debug/QuickTravelSystemSetup.cs
  69. 193 0
      Assets/Scripts/Debug/TravelSystemDebugger.cs
  70. 148 0
      Assets/Scripts/Documentation/ShopInventorySystem.md
  71. 0 0
      Assets/Scripts/MainTeamSelect/Character.cs
  72. 2040 0
      Assets/Scripts/MainTeamSelect/MainTeamSelectScript.cs
  73. 47 0
      Assets/Scripts/Managers/GameInitializer.cs
  74. 388 0
      Assets/Scripts/Managers/GameStateManager.cs
  75. 0 0
      Assets/Scripts/Managers/MapSceneManager.cs
  76. 173 0
      Assets/Scripts/Managers/SceneNavigationManager.cs
  77. 0 0
      Assets/Scripts/Map/MapDebugHelper.cs
  78. 0 0
      Assets/Scripts/Map/MapSystemTransition.cs
  79. 0 0
      Assets/Scripts/Map/NewTeamLocationManager.cs
  80. 655 0
      Assets/Scripts/Map/SimpleTeamPlacement.cs
  81. 0 0
      Assets/Scripts/Map/TeamLocationManager.cs
  82. 2010 0
      Assets/Scripts/Map/TeamTravelSystem.cs
  83. 264 0
      Assets/Scripts/Map/TravelSystemSetup.cs
  84. 395 0
      Assets/Scripts/Map/TravelUIController.cs
  85. 188 0
      Assets/Scripts/MapMaker2/Data/MapData.cs
  86. 23 0
      Assets/Scripts/MapMaker2/Data/TerrainType.cs
  87. 36 0
      Assets/Scripts/MapMaker2/Data/Tile.cs
  88. 1041 0
      Assets/Scripts/MapMaker2/Expansion/ExpansionManager.cs
  89. 1919 0
      Assets/Scripts/MapMaker2/Exploration/ExplorationManager.cs
  90. 103 0
      Assets/Scripts/MapMaker2/Features/FeatureGenerator.cs
  91. 238 0
      Assets/Scripts/MapMaker2/Features/RiverGenerator.cs
  92. 883 0
      Assets/Scripts/MapMaker2/Features/RoadGenerator.cs
  93. 141 0
      Assets/Scripts/MapMaker2/Features/SettlementGenerator.cs
  94. 88 0
      Assets/Scripts/MapMaker2/MapMaker.cs
  95. 918 0
      Assets/Scripts/MapMaker2/MapMaker2.cs
  96. 163 0
      Assets/Scripts/MapMaker2/MapMaker2Controller.cs
  97. 0 0
      Assets/Scripts/MapMaker2/SimpleMapClickHandler.cs
  98. 506 0
      Assets/Scripts/MapMaker2/SimpleMapMaker2.cs
  99. 682 0
      Assets/Scripts/MapMaker2/Terrain/TerrainGenerator.cs
  100. 37 0
      Assets/Scripts/MapMaker2/Utils/NoiseGenerator.cs

+ 26 - 0
.gitignore

@@ -0,0 +1,26 @@
+# ---> Unity
+/[Ll]ibrary/
+/[Tt]emp/
+/[Oo]bj/
+/[Bb]uild/
+
+# Autogenerated VS/MD solution and project files
+*.csproj
+*.unityproj
+*.sln
+*.suo
+*.tmp
+*.user
+*.userprefs
+*.pidb
+*.booproj
+
+# Unity3D generated meta files
+*.pidb.meta
+
+# Unity3D Generated File On Crash Reports
+sysinfo.txt
+
+# Egna addons
+*.log
+*.meta

+ 5 - 0
.vscode/extensions.json

@@ -0,0 +1,5 @@
+{
+    "recommendations": [
+      "visualstudiotoolsforunity.vstuc"
+    ]
+}

+ 16 - 0
.vscode/launch.json

@@ -0,0 +1,16 @@
+{
+    "version": "0.2.0",
+    "configurations": [
+        {
+            "name": "Attach to Unity",
+            "type": "coreclr",
+            "request": "attach",
+            "processId": "${command:pickProcess}"
+        },
+        {
+            "name": "Attach to Unity 2",
+            "type": "vstuc",
+            "request": "attach"
+        }
+    ]
+}

+ 61 - 0
.vscode/settings.json

@@ -0,0 +1,61 @@
+{
+    "files.exclude": {
+        "**/.DS_Store": true,
+        "**/.git": true,
+        "**/.vs": true,
+        "**/.gitmodules": true,
+        "**/.vsconfig": true,
+        "**/*.booproj": true,
+        "**/*.pidb": true,
+        "**/*.suo": true,
+        "**/*.user": true,
+        "**/*.userprefs": true,
+        "**/*.unityproj": true,
+        "**/*.dll": true,
+        "**/*.exe": true,
+        "**/*.pdf": true,
+        "**/*.mid": true,
+        "**/*.midi": true,
+        "**/*.wav": true,
+        "**/*.gif": true,
+        "**/*.ico": true,
+        "**/*.jpg": true,
+        "**/*.jpeg": true,
+        "**/*.png": true,
+        "**/*.psd": true,
+        "**/*.tga": true,
+        "**/*.tif": true,
+        "**/*.tiff": true,
+        "**/*.3ds": true,
+        "**/*.3DS": true,
+        "**/*.fbx": true,
+        "**/*.FBX": true,
+        "**/*.lxo": true,
+        "**/*.LXO": true,
+        "**/*.ma": true,
+        "**/*.MA": true,
+        "**/*.obj": true,
+        "**/*.OBJ": true,
+        "**/*.asset": true,
+        "**/*.cubemap": true,
+        "**/*.flare": true,
+        "**/*.mat": true,
+        "**/*.meta": true,
+        "**/*.prefab": true,
+        "**/*.unity": true,
+        "build/": true,
+        "Build/": true,
+        "Library/": true,
+        "library/": true,
+        "obj/": true,
+        "Obj/": true,
+        "Logs/": true,
+        "logs/": true,
+        "ProjectSettings/": true,
+        "UserSettings/": true,
+        "temp/": true,
+        "Temp/": true
+    },
+    "dotnet.defaultSolution": "RPG-RougeLiteBatteler.sln",
+    "chat.agent.maxRequests": 50
+}

+ 17 - 0
.vscode/tasks.json

@@ -0,0 +1,17 @@
+{
+	"version": "2.0.0",
+	"tasks": [
+		{
+			"label": "Open Unity Project",
+			"type": "shell",
+			"command": "start",
+			"args": [
+				".",
+				"/B"
+			],
+			"group": "build",
+			"isBackground": true,
+			"problemMatcher": []
+		}
+	]
+}

+ 131 - 0
ADVANCED_TRAVEL_SYSTEM.md

@@ -0,0 +1,131 @@
+# Advanced Travel System: Tunnels and Ferry Crossings
+
+## Overview
+The advanced travel system adds strategic depth to journey planning by introducing special travel options that require player decisions and resources.
+
+## Tunnel System
+
+### Detection
+- **Automatic Recognition**: Roads passing through mountain regions are identified as potential tunnels
+- **Mountain Threshold**: 3+ adjacent mountain tiles indicate tunnel conditions
+- **Pathfinding Integration**: Tunnels appear as special segments in calculated routes
+
+### Travel Options
+1. **With Torches** (Recommended)
+   - **Speed**: 0.8x cost (20% faster than normal roads)
+   - **Cost**: 10 gold per torch required
+   - **Safety**: Safe and well-lit travel
+   - **Detection**: Player inventory checked for available torches
+
+2. **Without Torches** (Risky)
+   - **Speed**: 3.0x cost (200% slower than plains!)
+   - **Cost**: Free but dangerous
+   - **Risk**: Very slow, potential for getting lost
+   - **Experience**: Atmospheric but inefficient
+
+### Player Experience
+```
+Special Travel Options Available:
+Tunnel detected from (15,20) to (18,20)
+
+Options:
+☐ Use Tunnel (with torches) - 10 gold, fast travel
+☐ Use Tunnel (without torches) - Free, very slow
+☐ Use Standard Route - Go around mountains
+
+Would you like to purchase torches for 10 gold?
+```
+
+## Ferry System
+
+### Detection
+- **Dock Proximity**: Searches for dock tiles within 8 tiles of route endpoints
+- **Water Validation**: Ensures 70%+ water between dock points
+- **Distance Limits**: 3-15 tile range for viable ferry routes
+- **Cost Calculation**: 25 gold per tile + 50 gold minimum
+
+### Ferry Options
+- **Speed Advantage**: 0.7x cost (30% faster than going around)
+- **Cost Structure**: Distance-based pricing
+- **Route Planning**: Automatically suggests ferry when beneficial
+
+### Player Experience
+```
+Special Travel Options Available:
+Ferry crossing available from Port Anchor (12,8) to Harbor Bay (18,15)
+
+Ferry Details:
+- Distance: 8 leagues across water
+- Cost: 250 gold (25 gold per league + 50 base fee)
+- Time Saved: 30% faster than overland route
+- Alternative: 18 tile detour through plains and forests
+
+Accept ferry crossing for 250 gold?
+```
+
+## Integration Features
+
+### Smart Route Planning
+- **Cost-Benefit Analysis**: Compares special options with standard routes
+- **Resource Awareness**: Checks player inventory and gold
+- **Time Efficiency**: Highlights faster options
+- **Player Choice**: Always offers standard route alternative
+
+### UI Components
+- **Option Selection**: Radio button interface for travel choices
+- **Cost Display**: Clear pricing and resource requirements
+- **Inventory Check**: Shows available torches and gold
+- **Route Comparison**: Standard vs special route information
+
+### Debug Information
+```
+=== SPECIAL TRAVEL OPTIONS ===
+Tunnel detected from (15,20) to (18,20)
+Ferry crossing available from (12,8) to (18,15)
+==============================
+```
+
+## Terrain Integration
+
+### Updated Movement Costs
+| Terrain | Base Cost | With Special Options |
+|---------|-----------|---------------------|
+| Tunnel (with torches) | 0.8x | Recommended route |
+| Tunnel (without torches) | 3.0x | Emergency option |
+| Ferry | 0.7x | Water crossing |
+| Dock | 0.8x | Port infrastructure |
+
+### Pathfinding Enhancements
+- **Multi-Option Routes**: Single destination, multiple travel methods
+- **Resource-Aware**: Considers available inventory items
+- **Economic Planning**: Balances speed vs cost
+- **Player Agency**: Never forces expensive options
+
+## Technical Implementation
+
+### Key Methods
+- `CheckForSpecialTravelOptions()`: Analyzes calculated path for opportunities
+- `IsTunnelSegment()`: Detects road segments through mountains
+- `HasFerryOption()`: Identifies viable water crossings
+- `ShowSpecialTravelOptionsUI()`: Presents choices to player
+
+### Resource Management
+- **Torch Tracking**: Inventory integration for tunnel travel
+- **Gold Management**: Cost verification before travel
+- **Alternative Routes**: Always provides free standard option
+
+## Strategic Gameplay
+
+### Decision Making
+- **Resource Management**: Spend gold for convenience vs save money
+- **Time vs Cost**: Fast expensive routes vs slow free routes
+- **Risk Assessment**: Dark tunnels vs safe but longer routes
+- **Exploration Rewards**: Finding efficient travel networks
+
+### Economic Impact
+- **Trade Routes**: Efficient paths become valuable
+- **Resource Trading**: Torches gain strategic value
+- **Port Towns**: Ferry access increases settlement importance
+- **Mountain Passes**: Tunnel routes create chokepoints
+
+This system transforms travel from simple pathfinding into strategic resource management with meaningful player choices!

+ 1057 - 0
Assets/InputSystem_Actions.inputactions

@@ -0,0 +1,1057 @@
+{
+    "name": "InputSystem_Actions",
+    "maps": [
+        {
+            "name": "Player",
+            "id": "df70fa95-8a34-4494-b137-73ab6b9c7d37",
+            "actions": [
+                {
+                    "name": "Move",
+                    "type": "Value",
+                    "id": "351f2ccd-1f9f-44bf-9bec-d62ac5c5f408",
+                    "expectedControlType": "Vector2",
+                    "processors": "",
+                    "interactions": "",
+                    "initialStateCheck": true
+                },
+                {
+                    "name": "Look",
+                    "type": "Value",
+                    "id": "6b444451-8a00-4d00-a97e-f47457f736a8",
+                    "expectedControlType": "Vector2",
+                    "processors": "",
+                    "interactions": "",
+                    "initialStateCheck": true
+                },
+                {
+                    "name": "Attack",
+                    "type": "Button",
+                    "id": "6c2ab1b8-8984-453a-af3d-a3c78ae1679a",
+                    "expectedControlType": "Button",
+                    "processors": "",
+                    "interactions": "",
+                    "initialStateCheck": false
+                },
+                {
+                    "name": "Interact",
+                    "type": "Button",
+                    "id": "852140f2-7766-474d-8707-702459ba45f3",
+                    "expectedControlType": "Button",
+                    "processors": "",
+                    "interactions": "Hold",
+                    "initialStateCheck": false
+                },
+                {
+                    "name": "Crouch",
+                    "type": "Button",
+                    "id": "27c5f898-bc57-4ee1-8800-db469aca5fe3",
+                    "expectedControlType": "Button",
+                    "processors": "",
+                    "interactions": "",
+                    "initialStateCheck": false
+                },
+                {
+                    "name": "Jump",
+                    "type": "Button",
+                    "id": "f1ba0d36-48eb-4cd5-b651-1c94a6531f70",
+                    "expectedControlType": "Button",
+                    "processors": "",
+                    "interactions": "",
+                    "initialStateCheck": false
+                },
+                {
+                    "name": "Previous",
+                    "type": "Button",
+                    "id": "2776c80d-3c14-4091-8c56-d04ced07a2b0",
+                    "expectedControlType": "Button",
+                    "processors": "",
+                    "interactions": "",
+                    "initialStateCheck": false
+                },
+                {
+                    "name": "Next",
+                    "type": "Button",
+                    "id": "b7230bb6-fc9b-4f52-8b25-f5e19cb2c2ba",
+                    "expectedControlType": "Button",
+                    "processors": "",
+                    "interactions": "",
+                    "initialStateCheck": false
+                },
+                {
+                    "name": "Sprint",
+                    "type": "Button",
+                    "id": "641cd816-40e6-41b4-8c3d-04687c349290",
+                    "expectedControlType": "Button",
+                    "processors": "",
+                    "interactions": "",
+                    "initialStateCheck": false
+                }
+            ],
+            "bindings": [
+                {
+                    "name": "",
+                    "id": "978bfe49-cc26-4a3d-ab7b-7d7a29327403",
+                    "path": "<Gamepad>/leftStick",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": ";Gamepad",
+                    "action": "Move",
+                    "isComposite": false,
+                    "isPartOfComposite": false
+                },
+                {
+                    "name": "WASD",
+                    "id": "00ca640b-d935-4593-8157-c05846ea39b3",
+                    "path": "Dpad",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": "",
+                    "action": "Move",
+                    "isComposite": true,
+                    "isPartOfComposite": false
+                },
+                {
+                    "name": "up",
+                    "id": "e2062cb9-1b15-46a2-838c-2f8d72a0bdd9",
+                    "path": "<Keyboard>/w",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": ";Keyboard&Mouse",
+                    "action": "Move",
+                    "isComposite": false,
+                    "isPartOfComposite": true
+                },
+                {
+                    "name": "up",
+                    "id": "8180e8bd-4097-4f4e-ab88-4523101a6ce9",
+                    "path": "<Keyboard>/upArrow",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": ";Keyboard&Mouse",
+                    "action": "Move",
+                    "isComposite": false,
+                    "isPartOfComposite": true
+                },
+                {
+                    "name": "down",
+                    "id": "320bffee-a40b-4347-ac70-c210eb8bc73a",
+                    "path": "<Keyboard>/s",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": ";Keyboard&Mouse",
+                    "action": "Move",
+                    "isComposite": false,
+                    "isPartOfComposite": true
+                },
+                {
+                    "name": "down",
+                    "id": "1c5327b5-f71c-4f60-99c7-4e737386f1d1",
+                    "path": "<Keyboard>/downArrow",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": ";Keyboard&Mouse",
+                    "action": "Move",
+                    "isComposite": false,
+                    "isPartOfComposite": true
+                },
+                {
+                    "name": "left",
+                    "id": "d2581a9b-1d11-4566-b27d-b92aff5fabbc",
+                    "path": "<Keyboard>/a",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": ";Keyboard&Mouse",
+                    "action": "Move",
+                    "isComposite": false,
+                    "isPartOfComposite": true
+                },
+                {
+                    "name": "left",
+                    "id": "2e46982e-44cc-431b-9f0b-c11910bf467a",
+                    "path": "<Keyboard>/leftArrow",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": ";Keyboard&Mouse",
+                    "action": "Move",
+                    "isComposite": false,
+                    "isPartOfComposite": true
+                },
+                {
+                    "name": "right",
+                    "id": "fcfe95b8-67b9-4526-84b5-5d0bc98d6400",
+                    "path": "<Keyboard>/d",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": ";Keyboard&Mouse",
+                    "action": "Move",
+                    "isComposite": false,
+                    "isPartOfComposite": true
+                },
+                {
+                    "name": "right",
+                    "id": "77bff152-3580-4b21-b6de-dcd0c7e41164",
+                    "path": "<Keyboard>/rightArrow",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": ";Keyboard&Mouse",
+                    "action": "Move",
+                    "isComposite": false,
+                    "isPartOfComposite": true
+                },
+                {
+                    "name": "",
+                    "id": "1635d3fe-58b6-4ba9-a4e2-f4b964f6b5c8",
+                    "path": "<XRController>/{Primary2DAxis}",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": "XR",
+                    "action": "Move",
+                    "isComposite": false,
+                    "isPartOfComposite": false
+                },
+                {
+                    "name": "",
+                    "id": "3ea4d645-4504-4529-b061-ab81934c3752",
+                    "path": "<Joystick>/stick",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": "Joystick",
+                    "action": "Move",
+                    "isComposite": false,
+                    "isPartOfComposite": false
+                },
+                {
+                    "name": "",
+                    "id": "c1f7a91b-d0fd-4a62-997e-7fb9b69bf235",
+                    "path": "<Gamepad>/rightStick",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": ";Gamepad",
+                    "action": "Look",
+                    "isComposite": false,
+                    "isPartOfComposite": false
+                },
+                {
+                    "name": "",
+                    "id": "8c8e490b-c610-4785-884f-f04217b23ca4",
+                    "path": "<Pointer>/delta",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": ";Keyboard&Mouse;Touch",
+                    "action": "Look",
+                    "isComposite": false,
+                    "isPartOfComposite": false
+                },
+                {
+                    "name": "",
+                    "id": "3e5f5442-8668-4b27-a940-df99bad7e831",
+                    "path": "<Joystick>/{Hatswitch}",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": "Joystick",
+                    "action": "Look",
+                    "isComposite": false,
+                    "isPartOfComposite": false
+                },
+                {
+                    "name": "",
+                    "id": "143bb1cd-cc10-4eca-a2f0-a3664166fe91",
+                    "path": "<Gamepad>/buttonWest",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": ";Gamepad",
+                    "action": "Attack",
+                    "isComposite": false,
+                    "isPartOfComposite": false
+                },
+                {
+                    "name": "",
+                    "id": "05f6913d-c316-48b2-a6bb-e225f14c7960",
+                    "path": "<Mouse>/leftButton",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": ";Keyboard&Mouse",
+                    "action": "Attack",
+                    "isComposite": false,
+                    "isPartOfComposite": false
+                },
+                {
+                    "name": "",
+                    "id": "886e731e-7071-4ae4-95c0-e61739dad6fd",
+                    "path": "<Touchscreen>/primaryTouch/tap",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": ";Touch",
+                    "action": "Attack",
+                    "isComposite": false,
+                    "isPartOfComposite": false
+                },
+                {
+                    "name": "",
+                    "id": "ee3d0cd2-254e-47a7-a8cb-bc94d9658c54",
+                    "path": "<Joystick>/trigger",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": "Joystick",
+                    "action": "Attack",
+                    "isComposite": false,
+                    "isPartOfComposite": false
+                },
+                {
+                    "name": "",
+                    "id": "8255d333-5683-4943-a58a-ccb207ff1dce",
+                    "path": "<XRController>/{PrimaryAction}",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": "XR",
+                    "action": "Attack",
+                    "isComposite": false,
+                    "isPartOfComposite": false
+                },
+                {
+                    "name": "",
+                    "id": "b3c1c7f0-bd20-4ee7-a0f1-899b24bca6d7",
+                    "path": "<Keyboard>/enter",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": "Keyboard&Mouse",
+                    "action": "Attack",
+                    "isComposite": false,
+                    "isPartOfComposite": false
+                },
+                {
+                    "name": "",
+                    "id": "cbac6039-9c09-46a1-b5f2-4e5124ccb5ed",
+                    "path": "<Keyboard>/2",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": "Keyboard&Mouse",
+                    "action": "Next",
+                    "isComposite": false,
+                    "isPartOfComposite": false
+                },
+                {
+                    "name": "",
+                    "id": "e15ca19d-e649-4852-97d5-7fe8ccc44e94",
+                    "path": "<Gamepad>/dpad/right",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": "Gamepad",
+                    "action": "Next",
+                    "isComposite": false,
+                    "isPartOfComposite": false
+                },
+                {
+                    "name": "",
+                    "id": "f2e9ba44-c423-42a7-ad56-f20975884794",
+                    "path": "<Keyboard>/leftShift",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": "Keyboard&Mouse",
+                    "action": "Sprint",
+                    "isComposite": false,
+                    "isPartOfComposite": false
+                },
+                {
+                    "name": "",
+                    "id": "8cbb2f4b-a784-49cc-8d5e-c010b8c7f4e6",
+                    "path": "<Gamepad>/leftStickPress",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": "Gamepad",
+                    "action": "Sprint",
+                    "isComposite": false,
+                    "isPartOfComposite": false
+                },
+                {
+                    "name": "",
+                    "id": "d8bf24bf-3f2f-4160-a97c-38ec1eb520ba",
+                    "path": "<XRController>/trigger",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": "XR",
+                    "action": "Sprint",
+                    "isComposite": false,
+                    "isPartOfComposite": false
+                },
+                {
+                    "name": "",
+                    "id": "eb40bb66-4559-4dfa-9a2f-820438abb426",
+                    "path": "<Keyboard>/space",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": "Keyboard&Mouse",
+                    "action": "Jump",
+                    "isComposite": false,
+                    "isPartOfComposite": false
+                },
+                {
+                    "name": "",
+                    "id": "daba33a1-ad0c-4742-a909-43ad1cdfbeb6",
+                    "path": "<Gamepad>/buttonSouth",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": "Gamepad",
+                    "action": "Jump",
+                    "isComposite": false,
+                    "isPartOfComposite": false
+                },
+                {
+                    "name": "",
+                    "id": "603f3daf-40bd-4854-8724-93e8017f59e3",
+                    "path": "<XRController>/secondaryButton",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": "XR",
+                    "action": "Jump",
+                    "isComposite": false,
+                    "isPartOfComposite": false
+                },
+                {
+                    "name": "",
+                    "id": "1534dc16-a6aa-499d-9c3a-22b47347b52a",
+                    "path": "<Keyboard>/1",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": "Keyboard&Mouse",
+                    "action": "Previous",
+                    "isComposite": false,
+                    "isPartOfComposite": false
+                },
+                {
+                    "name": "",
+                    "id": "25060bbd-a3a6-476e-8fba-45ae484aad05",
+                    "path": "<Gamepad>/dpad/left",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": "Gamepad",
+                    "action": "Previous",
+                    "isComposite": false,
+                    "isPartOfComposite": false
+                },
+                {
+                    "name": "",
+                    "id": "1c04ea5f-b012-41d1-a6f7-02e963b52893",
+                    "path": "<Keyboard>/e",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": "Keyboard&Mouse",
+                    "action": "Interact",
+                    "isComposite": false,
+                    "isPartOfComposite": false
+                },
+                {
+                    "name": "",
+                    "id": "b3f66d0b-7751-423f-908b-a11c5bd95930",
+                    "path": "<Gamepad>/buttonNorth",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": "Gamepad",
+                    "action": "Interact",
+                    "isComposite": false,
+                    "isPartOfComposite": false
+                },
+                {
+                    "name": "",
+                    "id": "4f4649ac-64a8-4a73-af11-b3faef356a4d",
+                    "path": "<Gamepad>/buttonEast",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": "Gamepad",
+                    "action": "Crouch",
+                    "isComposite": false,
+                    "isPartOfComposite": false
+                },
+                {
+                    "name": "",
+                    "id": "36e52cba-0905-478e-a818-f4bfcb9f3b9a",
+                    "path": "<Keyboard>/c",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": "Keyboard&Mouse",
+                    "action": "Crouch",
+                    "isComposite": false,
+                    "isPartOfComposite": false
+                }
+            ]
+        },
+        {
+            "name": "UI",
+            "id": "272f6d14-89ba-496f-b7ff-215263d3219f",
+            "actions": [
+                {
+                    "name": "Navigate",
+                    "type": "PassThrough",
+                    "id": "c95b2375-e6d9-4b88-9c4c-c5e76515df4b",
+                    "expectedControlType": "Vector2",
+                    "processors": "",
+                    "interactions": "",
+                    "initialStateCheck": false
+                },
+                {
+                    "name": "Submit",
+                    "type": "Button",
+                    "id": "7607c7b6-cd76-4816-beef-bd0341cfe950",
+                    "expectedControlType": "Button",
+                    "processors": "",
+                    "interactions": "",
+                    "initialStateCheck": false
+                },
+                {
+                    "name": "Cancel",
+                    "type": "Button",
+                    "id": "15cef263-9014-4fd5-94d9-4e4a6234a6ef",
+                    "expectedControlType": "Button",
+                    "processors": "",
+                    "interactions": "",
+                    "initialStateCheck": false
+                },
+                {
+                    "name": "Point",
+                    "type": "PassThrough",
+                    "id": "32b35790-4ed0-4e9a-aa41-69ac6d629449",
+                    "expectedControlType": "Vector2",
+                    "processors": "",
+                    "interactions": "",
+                    "initialStateCheck": true
+                },
+                {
+                    "name": "Click",
+                    "type": "PassThrough",
+                    "id": "3c7022bf-7922-4f7c-a998-c437916075ad",
+                    "expectedControlType": "Button",
+                    "processors": "",
+                    "interactions": "",
+                    "initialStateCheck": true
+                },
+                {
+                    "name": "RightClick",
+                    "type": "PassThrough",
+                    "id": "44b200b1-1557-4083-816c-b22cbdf77ddf",
+                    "expectedControlType": "Button",
+                    "processors": "",
+                    "interactions": "",
+                    "initialStateCheck": false
+                },
+                {
+                    "name": "MiddleClick",
+                    "type": "PassThrough",
+                    "id": "dad70c86-b58c-4b17-88ad-f5e53adf419e",
+                    "expectedControlType": "Button",
+                    "processors": "",
+                    "interactions": "",
+                    "initialStateCheck": false
+                },
+                {
+                    "name": "ScrollWheel",
+                    "type": "PassThrough",
+                    "id": "0489e84a-4833-4c40-bfae-cea84b696689",
+                    "expectedControlType": "Vector2",
+                    "processors": "",
+                    "interactions": "",
+                    "initialStateCheck": false
+                },
+                {
+                    "name": "TrackedDevicePosition",
+                    "type": "PassThrough",
+                    "id": "24908448-c609-4bc3-a128-ea258674378a",
+                    "expectedControlType": "Vector3",
+                    "processors": "",
+                    "interactions": "",
+                    "initialStateCheck": false
+                },
+                {
+                    "name": "TrackedDeviceOrientation",
+                    "type": "PassThrough",
+                    "id": "9caa3d8a-6b2f-4e8e-8bad-6ede561bd9be",
+                    "expectedControlType": "Quaternion",
+                    "processors": "",
+                    "interactions": "",
+                    "initialStateCheck": false
+                }
+            ],
+            "bindings": [
+                {
+                    "name": "Gamepad",
+                    "id": "809f371f-c5e2-4e7a-83a1-d867598f40dd",
+                    "path": "2DVector",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": "",
+                    "action": "Navigate",
+                    "isComposite": true,
+                    "isPartOfComposite": false
+                },
+                {
+                    "name": "up",
+                    "id": "14a5d6e8-4aaf-4119-a9ef-34b8c2c548bf",
+                    "path": "<Gamepad>/leftStick/up",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": ";Gamepad",
+                    "action": "Navigate",
+                    "isComposite": false,
+                    "isPartOfComposite": true
+                },
+                {
+                    "name": "up",
+                    "id": "9144cbe6-05e1-4687-a6d7-24f99d23dd81",
+                    "path": "<Gamepad>/rightStick/up",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": ";Gamepad",
+                    "action": "Navigate",
+                    "isComposite": false,
+                    "isPartOfComposite": true
+                },
+                {
+                    "name": "down",
+                    "id": "2db08d65-c5fb-421b-983f-c71163608d67",
+                    "path": "<Gamepad>/leftStick/down",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": ";Gamepad",
+                    "action": "Navigate",
+                    "isComposite": false,
+                    "isPartOfComposite": true
+                },
+                {
+                    "name": "down",
+                    "id": "58748904-2ea9-4a80-8579-b500e6a76df8",
+                    "path": "<Gamepad>/rightStick/down",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": ";Gamepad",
+                    "action": "Navigate",
+                    "isComposite": false,
+                    "isPartOfComposite": true
+                },
+                {
+                    "name": "left",
+                    "id": "8ba04515-75aa-45de-966d-393d9bbd1c14",
+                    "path": "<Gamepad>/leftStick/left",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": ";Gamepad",
+                    "action": "Navigate",
+                    "isComposite": false,
+                    "isPartOfComposite": true
+                },
+                {
+                    "name": "left",
+                    "id": "712e721c-bdfb-4b23-a86c-a0d9fcfea921",
+                    "path": "<Gamepad>/rightStick/left",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": ";Gamepad",
+                    "action": "Navigate",
+                    "isComposite": false,
+                    "isPartOfComposite": true
+                },
+                {
+                    "name": "right",
+                    "id": "fcd248ae-a788-4676-a12e-f4d81205600b",
+                    "path": "<Gamepad>/leftStick/right",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": ";Gamepad",
+                    "action": "Navigate",
+                    "isComposite": false,
+                    "isPartOfComposite": true
+                },
+                {
+                    "name": "right",
+                    "id": "1f04d9bc-c50b-41a1-bfcc-afb75475ec20",
+                    "path": "<Gamepad>/rightStick/right",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": ";Gamepad",
+                    "action": "Navigate",
+                    "isComposite": false,
+                    "isPartOfComposite": true
+                },
+                {
+                    "name": "",
+                    "id": "fb8277d4-c5cd-4663-9dc7-ee3f0b506d90",
+                    "path": "<Gamepad>/dpad",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": ";Gamepad",
+                    "action": "Navigate",
+                    "isComposite": false,
+                    "isPartOfComposite": false
+                },
+                {
+                    "name": "Joystick",
+                    "id": "e25d9774-381c-4a61-b47c-7b6b299ad9f9",
+                    "path": "2DVector",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": "",
+                    "action": "Navigate",
+                    "isComposite": true,
+                    "isPartOfComposite": false
+                },
+                {
+                    "name": "up",
+                    "id": "3db53b26-6601-41be-9887-63ac74e79d19",
+                    "path": "<Joystick>/stick/up",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": "Joystick",
+                    "action": "Navigate",
+                    "isComposite": false,
+                    "isPartOfComposite": true
+                },
+                {
+                    "name": "down",
+                    "id": "0cb3e13e-3d90-4178-8ae6-d9c5501d653f",
+                    "path": "<Joystick>/stick/down",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": "Joystick",
+                    "action": "Navigate",
+                    "isComposite": false,
+                    "isPartOfComposite": true
+                },
+                {
+                    "name": "left",
+                    "id": "0392d399-f6dd-4c82-8062-c1e9c0d34835",
+                    "path": "<Joystick>/stick/left",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": "Joystick",
+                    "action": "Navigate",
+                    "isComposite": false,
+                    "isPartOfComposite": true
+                },
+                {
+                    "name": "right",
+                    "id": "942a66d9-d42f-43d6-8d70-ecb4ba5363bc",
+                    "path": "<Joystick>/stick/right",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": "Joystick",
+                    "action": "Navigate",
+                    "isComposite": false,
+                    "isPartOfComposite": true
+                },
+                {
+                    "name": "Keyboard",
+                    "id": "ff527021-f211-4c02-933e-5976594c46ed",
+                    "path": "2DVector",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": "",
+                    "action": "Navigate",
+                    "isComposite": true,
+                    "isPartOfComposite": false
+                },
+                {
+                    "name": "up",
+                    "id": "563fbfdd-0f09-408d-aa75-8642c4f08ef0",
+                    "path": "<Keyboard>/w",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": "Keyboard&Mouse",
+                    "action": "Navigate",
+                    "isComposite": false,
+                    "isPartOfComposite": true
+                },
+                {
+                    "name": "up",
+                    "id": "eb480147-c587-4a33-85ed-eb0ab9942c43",
+                    "path": "<Keyboard>/upArrow",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": "Keyboard&Mouse",
+                    "action": "Navigate",
+                    "isComposite": false,
+                    "isPartOfComposite": true
+                },
+                {
+                    "name": "down",
+                    "id": "2bf42165-60bc-42ca-8072-8c13ab40239b",
+                    "path": "<Keyboard>/s",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": "Keyboard&Mouse",
+                    "action": "Navigate",
+                    "isComposite": false,
+                    "isPartOfComposite": true
+                },
+                {
+                    "name": "down",
+                    "id": "85d264ad-e0a0-4565-b7ff-1a37edde51ac",
+                    "path": "<Keyboard>/downArrow",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": "Keyboard&Mouse",
+                    "action": "Navigate",
+                    "isComposite": false,
+                    "isPartOfComposite": true
+                },
+                {
+                    "name": "left",
+                    "id": "74214943-c580-44e4-98eb-ad7eebe17902",
+                    "path": "<Keyboard>/a",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": "Keyboard&Mouse",
+                    "action": "Navigate",
+                    "isComposite": false,
+                    "isPartOfComposite": true
+                },
+                {
+                    "name": "left",
+                    "id": "cea9b045-a000-445b-95b8-0c171af70a3b",
+                    "path": "<Keyboard>/leftArrow",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": "Keyboard&Mouse",
+                    "action": "Navigate",
+                    "isComposite": false,
+                    "isPartOfComposite": true
+                },
+                {
+                    "name": "right",
+                    "id": "8607c725-d935-4808-84b1-8354e29bab63",
+                    "path": "<Keyboard>/d",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": "Keyboard&Mouse",
+                    "action": "Navigate",
+                    "isComposite": false,
+                    "isPartOfComposite": true
+                },
+                {
+                    "name": "right",
+                    "id": "4cda81dc-9edd-4e03-9d7c-a71a14345d0b",
+                    "path": "<Keyboard>/rightArrow",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": "Keyboard&Mouse",
+                    "action": "Navigate",
+                    "isComposite": false,
+                    "isPartOfComposite": true
+                },
+                {
+                    "name": "",
+                    "id": "9e92bb26-7e3b-4ec4-b06b-3c8f8e498ddc",
+                    "path": "*/{Submit}",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": "Keyboard&Mouse;Gamepad;Touch;Joystick;XR",
+                    "action": "Submit",
+                    "isComposite": false,
+                    "isPartOfComposite": false
+                },
+                {
+                    "name": "",
+                    "id": "82627dcc-3b13-4ba9-841d-e4b746d6553e",
+                    "path": "*/{Cancel}",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": "Keyboard&Mouse;Gamepad;Touch;Joystick;XR",
+                    "action": "Cancel",
+                    "isComposite": false,
+                    "isPartOfComposite": false
+                },
+                {
+                    "name": "",
+                    "id": "c52c8e0b-8179-41d3-b8a1-d149033bbe86",
+                    "path": "<Mouse>/position",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": "Keyboard&Mouse",
+                    "action": "Point",
+                    "isComposite": false,
+                    "isPartOfComposite": false
+                },
+                {
+                    "name": "",
+                    "id": "e1394cbc-336e-44ce-9ea8-6007ed6193f7",
+                    "path": "<Pen>/position",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": "Keyboard&Mouse",
+                    "action": "Point",
+                    "isComposite": false,
+                    "isPartOfComposite": false
+                },
+                {
+                    "name": "",
+                    "id": "5693e57a-238a-46ed-b5ae-e64e6e574302",
+                    "path": "<Touchscreen>/touch*/position",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": "Touch",
+                    "action": "Point",
+                    "isComposite": false,
+                    "isPartOfComposite": false
+                },
+                {
+                    "name": "",
+                    "id": "4faf7dc9-b979-4210-aa8c-e808e1ef89f5",
+                    "path": "<Mouse>/leftButton",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": ";Keyboard&Mouse",
+                    "action": "Click",
+                    "isComposite": false,
+                    "isPartOfComposite": false
+                },
+                {
+                    "name": "",
+                    "id": "8d66d5ba-88d7-48e6-b1cd-198bbfef7ace",
+                    "path": "<Pen>/tip",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": ";Keyboard&Mouse",
+                    "action": "Click",
+                    "isComposite": false,
+                    "isPartOfComposite": false
+                },
+                {
+                    "name": "",
+                    "id": "47c2a644-3ebc-4dae-a106-589b7ca75b59",
+                    "path": "<Touchscreen>/touch*/press",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": "Touch",
+                    "action": "Click",
+                    "isComposite": false,
+                    "isPartOfComposite": false
+                },
+                {
+                    "name": "",
+                    "id": "bb9e6b34-44bf-4381-ac63-5aa15d19f677",
+                    "path": "<XRController>/trigger",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": "XR",
+                    "action": "Click",
+                    "isComposite": false,
+                    "isPartOfComposite": false
+                },
+                {
+                    "name": "",
+                    "id": "38c99815-14ea-4617-8627-164d27641299",
+                    "path": "<Mouse>/scroll",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": ";Keyboard&Mouse",
+                    "action": "ScrollWheel",
+                    "isComposite": false,
+                    "isPartOfComposite": false
+                },
+                {
+                    "name": "",
+                    "id": "4c191405-5738-4d4b-a523-c6a301dbf754",
+                    "path": "<Mouse>/rightButton",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": "Keyboard&Mouse",
+                    "action": "RightClick",
+                    "isComposite": false,
+                    "isPartOfComposite": false
+                },
+                {
+                    "name": "",
+                    "id": "24066f69-da47-44f3-a07e-0015fb02eb2e",
+                    "path": "<Mouse>/middleButton",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": "Keyboard&Mouse",
+                    "action": "MiddleClick",
+                    "isComposite": false,
+                    "isPartOfComposite": false
+                },
+                {
+                    "name": "",
+                    "id": "7236c0d9-6ca3-47cf-a6ee-a97f5b59ea77",
+                    "path": "<XRController>/devicePosition",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": "XR",
+                    "action": "TrackedDevicePosition",
+                    "isComposite": false,
+                    "isPartOfComposite": false
+                },
+                {
+                    "name": "",
+                    "id": "23e01e3a-f935-4948-8d8b-9bcac77714fb",
+                    "path": "<XRController>/deviceRotation",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": "XR",
+                    "action": "TrackedDeviceOrientation",
+                    "isComposite": false,
+                    "isPartOfComposite": false
+                }
+            ]
+        }
+    ],
+    "controlSchemes": [
+        {
+            "name": "Keyboard&Mouse",
+            "bindingGroup": "Keyboard&Mouse",
+            "devices": [
+                {
+                    "devicePath": "<Keyboard>",
+                    "isOptional": false,
+                    "isOR": false
+                },
+                {
+                    "devicePath": "<Mouse>",
+                    "isOptional": false,
+                    "isOR": false
+                }
+            ]
+        },
+        {
+            "name": "Gamepad",
+            "bindingGroup": "Gamepad",
+            "devices": [
+                {
+                    "devicePath": "<Gamepad>",
+                    "isOptional": false,
+                    "isOR": false
+                }
+            ]
+        },
+        {
+            "name": "Touch",
+            "bindingGroup": "Touch",
+            "devices": [
+                {
+                    "devicePath": "<Touchscreen>",
+                    "isOptional": false,
+                    "isOR": false
+                }
+            ]
+        },
+        {
+            "name": "Joystick",
+            "bindingGroup": "Joystick",
+            "devices": [
+                {
+                    "devicePath": "<Joystick>",
+                    "isOptional": false,
+                    "isOR": false
+                }
+            ]
+        },
+        {
+            "name": "XR",
+            "bindingGroup": "XR",
+            "devices": [
+                {
+                    "devicePath": "<XRController>",
+                    "isOptional": false,
+                    "isOR": false
+                }
+            ]
+        }
+    ]
+}

+ 138 - 0
Assets/Material/ArrowMaterial.mat

@@ -0,0 +1,138 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!114 &-5318210274668056353
+MonoBehaviour:
+  m_ObjectHideFlags: 11
+  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: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  version: 9
+--- !u!21 &2100000
+Material:
+  serializedVersion: 8
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_Name: ArrowMaterial
+  m_Shader: {fileID: 4800000, guid: 933532a4fcc9baf4fa0491de14d08ed7, type: 3}
+  m_Parent: {fileID: 0}
+  m_ModifiedSerializedProperties: 0
+  m_ValidKeywords:
+  - _RECEIVE_SHADOWS_OFF
+  - _SPECULAR_SETUP
+  m_InvalidKeywords: []
+  m_LightmapFlags: 4
+  m_EnableInstancingVariants: 0
+  m_DoubleSidedGI: 0
+  m_CustomRenderQueue: -1
+  stringTagMap:
+    RenderType: Opaque
+  disabledShaderPasses:
+  - MOTIONVECTORS
+  m_LockedProperties: 
+  m_SavedProperties:
+    serializedVersion: 3
+    m_TexEnvs:
+    - _BaseMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _BumpMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _DetailAlbedoMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _DetailMask:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _DetailNormalMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _EmissionMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _MainTex:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _MetallicGlossMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _OcclusionMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _ParallaxMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _SpecGlossMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - unity_Lightmaps:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - unity_LightmapsInd:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - unity_ShadowMasks:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    m_Ints: []
+    m_Floats:
+    - _AddPrecomputedVelocity: 0
+    - _AlphaClip: 0
+    - _AlphaToMask: 0
+    - _Blend: 0
+    - _BlendModePreserveSpecular: 1
+    - _BumpScale: 1
+    - _ClearCoatMask: 0
+    - _ClearCoatSmoothness: 0
+    - _Cull: 2
+    - _Cutoff: 0.5
+    - _DetailAlbedoMapScale: 1
+    - _DetailNormalMapScale: 1
+    - _DstBlend: 0
+    - _DstBlendAlpha: 0
+    - _EnvironmentReflections: 1
+    - _GlossMapScale: 0
+    - _Glossiness: 0
+    - _GlossyReflections: 0
+    - _Metallic: 0
+    - _OcclusionStrength: 1
+    - _Parallax: 0.005
+    - _QueueOffset: 0
+    - _ReceiveShadows: 0
+    - _Smoothness: 0.5
+    - _SmoothnessTextureChannel: 0
+    - _SpecularHighlights: 1
+    - _SrcBlend: 1
+    - _SrcBlendAlpha: 1
+    - _Surface: 0
+    - _WorkflowMode: 0
+    - _ZWrite: 1
+    m_Colors:
+    - _BaseColor: {r: 0.3018868, g: 0.22380199, b: 0.021359911, a: 1}
+    - _Color: {r: 0.30188674, g: 0.22380194, b: 0.021359911, a: 1}
+    - _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
+    - _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1}
+  m_BuildTextureStacks: []
+  m_AllowLocking: 1

+ 136 - 0
Assets/Material/EnemyMaterial.mat

@@ -0,0 +1,136 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!21 &2100000
+Material:
+  serializedVersion: 8
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_Name: EnemyMaterial
+  m_Shader: {fileID: 4800000, guid: 933532a4fcc9baf4fa0491de14d08ed7, type: 3}
+  m_Parent: {fileID: 0}
+  m_ModifiedSerializedProperties: 0
+  m_ValidKeywords: []
+  m_InvalidKeywords: []
+  m_LightmapFlags: 4
+  m_EnableInstancingVariants: 0
+  m_DoubleSidedGI: 0
+  m_CustomRenderQueue: -1
+  stringTagMap:
+    RenderType: Opaque
+  disabledShaderPasses:
+  - MOTIONVECTORS
+  m_LockedProperties: 
+  m_SavedProperties:
+    serializedVersion: 3
+    m_TexEnvs:
+    - _BaseMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _BumpMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _DetailAlbedoMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _DetailMask:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _DetailNormalMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _EmissionMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _MainTex:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _MetallicGlossMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _OcclusionMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _ParallaxMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _SpecGlossMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - unity_Lightmaps:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - unity_LightmapsInd:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - unity_ShadowMasks:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    m_Ints: []
+    m_Floats:
+    - _AddPrecomputedVelocity: 0
+    - _AlphaClip: 0
+    - _AlphaToMask: 0
+    - _Blend: 0
+    - _BlendModePreserveSpecular: 1
+    - _BumpScale: 1
+    - _ClearCoatMask: 0
+    - _ClearCoatSmoothness: 0
+    - _Cull: 2
+    - _Cutoff: 0.5
+    - _DetailAlbedoMapScale: 1
+    - _DetailNormalMapScale: 1
+    - _DstBlend: 0
+    - _DstBlendAlpha: 0
+    - _EnvironmentReflections: 1
+    - _GlossMapScale: 0
+    - _Glossiness: 0
+    - _GlossyReflections: 0
+    - _Metallic: 0
+    - _OcclusionStrength: 1
+    - _Parallax: 0.005
+    - _QueueOffset: 0
+    - _ReceiveShadows: 1
+    - _Smoothness: 0.5
+    - _SmoothnessTextureChannel: 0
+    - _SpecularHighlights: 1
+    - _SrcBlend: 1
+    - _SrcBlendAlpha: 1
+    - _Surface: 0
+    - _WorkflowMode: 1
+    - _ZWrite: 1
+    m_Colors:
+    - _BaseColor: {r: 0.7294118, g: 0.2509804, b: 0.27843136, a: 0.78431374}
+    - _Color: {r: 0.7294118, g: 0.25098038, b: 0.27843133, a: 0.78431374}
+    - _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
+    - _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1}
+  m_BuildTextureStacks: []
+  m_AllowLocking: 1
+--- !u!114 &5490896063819486916
+MonoBehaviour:
+  m_ObjectHideFlags: 11
+  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: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  version: 9

+ 140 - 0
Assets/Material/EnemySpawnBoxMaterial.mat

@@ -0,0 +1,140 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!21 &2100000
+Material:
+  serializedVersion: 8
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_Name: EnemySpawnBoxMaterial
+  m_Shader: {fileID: 4800000, guid: 933532a4fcc9baf4fa0491de14d08ed7, type: 3}
+  m_Parent: {fileID: 0}
+  m_ModifiedSerializedProperties: 0
+  m_ValidKeywords:
+  - _ALPHAPREMULTIPLY_ON
+  - _SURFACE_TYPE_TRANSPARENT
+  m_InvalidKeywords: []
+  m_LightmapFlags: 4
+  m_EnableInstancingVariants: 0
+  m_DoubleSidedGI: 0
+  m_CustomRenderQueue: 3000
+  stringTagMap:
+    RenderType: Transparent
+  disabledShaderPasses:
+  - MOTIONVECTORS
+  - DepthOnly
+  - SHADOWCASTER
+  m_LockedProperties: 
+  m_SavedProperties:
+    serializedVersion: 3
+    m_TexEnvs:
+    - _BaseMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _BumpMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _DetailAlbedoMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _DetailMask:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _DetailNormalMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _EmissionMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _MainTex:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _MetallicGlossMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _OcclusionMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _ParallaxMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _SpecGlossMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - unity_Lightmaps:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - unity_LightmapsInd:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - unity_ShadowMasks:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    m_Ints: []
+    m_Floats:
+    - _AddPrecomputedVelocity: 0
+    - _AlphaClip: 0
+    - _AlphaToMask: 0
+    - _Blend: 0
+    - _BlendModePreserveSpecular: 1
+    - _BumpScale: 1
+    - _ClearCoatMask: 0
+    - _ClearCoatSmoothness: 0
+    - _Cull: 2
+    - _Cutoff: 0.5
+    - _DetailAlbedoMapScale: 1
+    - _DetailNormalMapScale: 1
+    - _DstBlend: 10
+    - _DstBlendAlpha: 10
+    - _EnvironmentReflections: 1
+    - _GlossMapScale: 0
+    - _Glossiness: 0
+    - _GlossyReflections: 0
+    - _Metallic: 0
+    - _OcclusionStrength: 1
+    - _Parallax: 0.005
+    - _QueueOffset: 0
+    - _ReceiveShadows: 1
+    - _Smoothness: 0.5
+    - _SmoothnessTextureChannel: 0
+    - _SpecularHighlights: 1
+    - _SrcBlend: 1
+    - _SrcBlendAlpha: 1
+    - _Surface: 1
+    - _WorkflowMode: 1
+    - _ZWrite: 0
+    m_Colors:
+    - _BaseColor: {r: 0.7254902, g: 0.2509804, b: 0.29122788, a: 0.39215687}
+    - _Color: {r: 0.7254902, g: 0.25098038, b: 0.29122785, a: 0.39215687}
+    - _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
+    - _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1}
+  m_BuildTextureStacks: []
+  m_AllowLocking: 1
+--- !u!114 &5651368926005467454
+MonoBehaviour:
+  m_ObjectHideFlags: 11
+  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: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  version: 9

+ 136 - 0
Assets/Material/PlayerMaterial.mat

@@ -0,0 +1,136 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!21 &2100000
+Material:
+  serializedVersion: 8
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_Name: PlayerMaterial
+  m_Shader: {fileID: 4800000, guid: 933532a4fcc9baf4fa0491de14d08ed7, type: 3}
+  m_Parent: {fileID: 0}
+  m_ModifiedSerializedProperties: 0
+  m_ValidKeywords: []
+  m_InvalidKeywords: []
+  m_LightmapFlags: 4
+  m_EnableInstancingVariants: 0
+  m_DoubleSidedGI: 0
+  m_CustomRenderQueue: -1
+  stringTagMap:
+    RenderType: Opaque
+  disabledShaderPasses:
+  - MOTIONVECTORS
+  m_LockedProperties: 
+  m_SavedProperties:
+    serializedVersion: 3
+    m_TexEnvs:
+    - _BaseMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _BumpMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _DetailAlbedoMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _DetailMask:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _DetailNormalMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _EmissionMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _MainTex:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _MetallicGlossMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _OcclusionMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _ParallaxMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _SpecGlossMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - unity_Lightmaps:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - unity_LightmapsInd:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - unity_ShadowMasks:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    m_Ints: []
+    m_Floats:
+    - _AddPrecomputedVelocity: 0
+    - _AlphaClip: 0
+    - _AlphaToMask: 0
+    - _Blend: 0
+    - _BlendModePreserveSpecular: 1
+    - _BumpScale: 1
+    - _ClearCoatMask: 0
+    - _ClearCoatSmoothness: 0
+    - _Cull: 2
+    - _Cutoff: 0.5
+    - _DetailAlbedoMapScale: 1
+    - _DetailNormalMapScale: 1
+    - _DstBlend: 0
+    - _DstBlendAlpha: 0
+    - _EnvironmentReflections: 1
+    - _GlossMapScale: 0
+    - _Glossiness: 0
+    - _GlossyReflections: 0
+    - _Metallic: 0
+    - _OcclusionStrength: 1
+    - _Parallax: 0.005
+    - _QueueOffset: 0
+    - _ReceiveShadows: 1
+    - _Smoothness: 0.5
+    - _SmoothnessTextureChannel: 0
+    - _SpecularHighlights: 1
+    - _SrcBlend: 1
+    - _SrcBlendAlpha: 1
+    - _Surface: 0
+    - _WorkflowMode: 1
+    - _ZWrite: 1
+    m_Colors:
+    - _BaseColor: {r: 0.2509804, g: 0.7294118, b: 0.2784314, a: 0.78431374}
+    - _Color: {r: 0.25098038, g: 0.7294118, b: 0.27843136, a: 0.78431374}
+    - _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
+    - _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1}
+  m_BuildTextureStacks: []
+  m_AllowLocking: 1
+--- !u!114 &5490896063819486916
+MonoBehaviour:
+  m_ObjectHideFlags: 11
+  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: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  version: 9

+ 140 - 0
Assets/Material/PlayerSpawnBoxMaterial.mat

@@ -0,0 +1,140 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!21 &2100000
+Material:
+  serializedVersion: 8
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_Name: PlayerSpawnBoxMaterial
+  m_Shader: {fileID: 4800000, guid: 933532a4fcc9baf4fa0491de14d08ed7, type: 3}
+  m_Parent: {fileID: 0}
+  m_ModifiedSerializedProperties: 0
+  m_ValidKeywords:
+  - _ALPHAPREMULTIPLY_ON
+  - _SURFACE_TYPE_TRANSPARENT
+  m_InvalidKeywords: []
+  m_LightmapFlags: 4
+  m_EnableInstancingVariants: 0
+  m_DoubleSidedGI: 0
+  m_CustomRenderQueue: 3000
+  stringTagMap:
+    RenderType: Transparent
+  disabledShaderPasses:
+  - MOTIONVECTORS
+  - DepthOnly
+  - SHADOWCASTER
+  m_LockedProperties: 
+  m_SavedProperties:
+    serializedVersion: 3
+    m_TexEnvs:
+    - _BaseMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _BumpMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _DetailAlbedoMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _DetailMask:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _DetailNormalMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _EmissionMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _MainTex:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _MetallicGlossMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _OcclusionMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _ParallaxMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _SpecGlossMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - unity_Lightmaps:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - unity_LightmapsInd:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - unity_ShadowMasks:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    m_Ints: []
+    m_Floats:
+    - _AddPrecomputedVelocity: 0
+    - _AlphaClip: 0
+    - _AlphaToMask: 0
+    - _Blend: 0
+    - _BlendModePreserveSpecular: 1
+    - _BumpScale: 1
+    - _ClearCoatMask: 0
+    - _ClearCoatSmoothness: 0
+    - _Cull: 2
+    - _Cutoff: 0.5
+    - _DetailAlbedoMapScale: 1
+    - _DetailNormalMapScale: 1
+    - _DstBlend: 10
+    - _DstBlendAlpha: 10
+    - _EnvironmentReflections: 1
+    - _GlossMapScale: 0
+    - _Glossiness: 0
+    - _GlossyReflections: 0
+    - _Metallic: 0
+    - _OcclusionStrength: 1
+    - _Parallax: 0.005
+    - _QueueOffset: 0
+    - _ReceiveShadows: 1
+    - _Smoothness: 0.5
+    - _SmoothnessTextureChannel: 0
+    - _SpecularHighlights: 1
+    - _SrcBlend: 1
+    - _SrcBlendAlpha: 1
+    - _Surface: 1
+    - _WorkflowMode: 1
+    - _ZWrite: 0
+    m_Colors:
+    - _BaseColor: {r: 0.25013348, g: 0.7264151, b: 0.2912279, a: 0.39215687}
+    - _Color: {r: 0.25013345, g: 0.7264151, b: 0.29122788, a: 0.39215687}
+    - _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
+    - _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1}
+  m_BuildTextureStacks: []
+  m_AllowLocking: 1
+--- !u!114 &5651368926005467454
+MonoBehaviour:
+  m_ObjectHideFlags: 11
+  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: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  version: 9

+ 136 - 0
Assets/Material/Terrain/Forest.mat

@@ -0,0 +1,136 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!21 &2100000
+Material:
+  serializedVersion: 8
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_Name: Forest
+  m_Shader: {fileID: 4800000, guid: 933532a4fcc9baf4fa0491de14d08ed7, type: 3}
+  m_Parent: {fileID: 0}
+  m_ModifiedSerializedProperties: 0
+  m_ValidKeywords: []
+  m_InvalidKeywords: []
+  m_LightmapFlags: 4
+  m_EnableInstancingVariants: 0
+  m_DoubleSidedGI: 0
+  m_CustomRenderQueue: -1
+  stringTagMap:
+    RenderType: Opaque
+  disabledShaderPasses:
+  - MOTIONVECTORS
+  m_LockedProperties: 
+  m_SavedProperties:
+    serializedVersion: 3
+    m_TexEnvs:
+    - _BaseMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _BumpMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _DetailAlbedoMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _DetailMask:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _DetailNormalMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _EmissionMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _MainTex:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _MetallicGlossMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _OcclusionMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _ParallaxMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _SpecGlossMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - unity_Lightmaps:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - unity_LightmapsInd:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - unity_ShadowMasks:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    m_Ints: []
+    m_Floats:
+    - _AddPrecomputedVelocity: 0
+    - _AlphaClip: 0
+    - _AlphaToMask: 0
+    - _Blend: 0
+    - _BlendModePreserveSpecular: 1
+    - _BumpScale: 1
+    - _ClearCoatMask: 0
+    - _ClearCoatSmoothness: 0
+    - _Cull: 2
+    - _Cutoff: 0.5
+    - _DetailAlbedoMapScale: 1
+    - _DetailNormalMapScale: 1
+    - _DstBlend: 0
+    - _DstBlendAlpha: 0
+    - _EnvironmentReflections: 1
+    - _GlossMapScale: 0
+    - _Glossiness: 0
+    - _GlossyReflections: 0
+    - _Metallic: 0
+    - _OcclusionStrength: 1
+    - _Parallax: 0.005
+    - _QueueOffset: 0
+    - _ReceiveShadows: 1
+    - _Smoothness: 0.15
+    - _SmoothnessTextureChannel: 0
+    - _SpecularHighlights: 1
+    - _SrcBlend: 1
+    - _SrcBlendAlpha: 1
+    - _Surface: 0
+    - _WorkflowMode: 1
+    - _ZWrite: 1
+    m_Colors:
+    - _BaseColor: {r: 0.18039216, g: 0.4392157, b: 0.19215687, a: 1}
+    - _Color: {r: 0.18039212, g: 0.43921566, b: 0.19215682, a: 1}
+    - _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
+    - _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1}
+  m_BuildTextureStacks: []
+  m_AllowLocking: 1
+--- !u!114 &1340549418501680075
+MonoBehaviour:
+  m_ObjectHideFlags: 11
+  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: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  version: 9

+ 136 - 0
Assets/Material/Terrain/Mountain.mat

@@ -0,0 +1,136 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!21 &2100000
+Material:
+  serializedVersion: 8
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_Name: Mountain
+  m_Shader: {fileID: 4800000, guid: 933532a4fcc9baf4fa0491de14d08ed7, type: 3}
+  m_Parent: {fileID: 0}
+  m_ModifiedSerializedProperties: 0
+  m_ValidKeywords: []
+  m_InvalidKeywords: []
+  m_LightmapFlags: 4
+  m_EnableInstancingVariants: 0
+  m_DoubleSidedGI: 0
+  m_CustomRenderQueue: -1
+  stringTagMap:
+    RenderType: Opaque
+  disabledShaderPasses:
+  - MOTIONVECTORS
+  m_LockedProperties: 
+  m_SavedProperties:
+    serializedVersion: 3
+    m_TexEnvs:
+    - _BaseMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _BumpMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _DetailAlbedoMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _DetailMask:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _DetailNormalMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _EmissionMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _MainTex:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _MetallicGlossMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _OcclusionMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _ParallaxMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _SpecGlossMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - unity_Lightmaps:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - unity_LightmapsInd:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - unity_ShadowMasks:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    m_Ints: []
+    m_Floats:
+    - _AddPrecomputedVelocity: 0
+    - _AlphaClip: 0
+    - _AlphaToMask: 0
+    - _Blend: 0
+    - _BlendModePreserveSpecular: 1
+    - _BumpScale: 1
+    - _ClearCoatMask: 0
+    - _ClearCoatSmoothness: 0
+    - _Cull: 2
+    - _Cutoff: 0.5
+    - _DetailAlbedoMapScale: 1
+    - _DetailNormalMapScale: 1
+    - _DstBlend: 0
+    - _DstBlendAlpha: 0
+    - _EnvironmentReflections: 1
+    - _GlossMapScale: 0
+    - _Glossiness: 0
+    - _GlossyReflections: 0
+    - _Metallic: 0
+    - _OcclusionStrength: 1
+    - _Parallax: 0.005
+    - _QueueOffset: 0
+    - _ReceiveShadows: 1
+    - _Smoothness: 0.15
+    - _SmoothnessTextureChannel: 0
+    - _SpecularHighlights: 1
+    - _SrcBlend: 1
+    - _SrcBlendAlpha: 1
+    - _Surface: 0
+    - _WorkflowMode: 1
+    - _ZWrite: 1
+    m_Colors:
+    - _BaseColor: {r: 0.54509807, g: 0.54509807, b: 0.5137255, a: 1}
+    - _Color: {r: 0.545098, g: 0.545098, b: 0.5137254, a: 1}
+    - _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
+    - _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1}
+  m_BuildTextureStacks: []
+  m_AllowLocking: 1
+--- !u!114 &5929481328377405642
+MonoBehaviour:
+  m_ObjectHideFlags: 11
+  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: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  version: 9

+ 136 - 0
Assets/Material/Terrain/Plain.mat

@@ -0,0 +1,136 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!21 &2100000
+Material:
+  serializedVersion: 8
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_Name: Plain
+  m_Shader: {fileID: 4800000, guid: 933532a4fcc9baf4fa0491de14d08ed7, type: 3}
+  m_Parent: {fileID: 0}
+  m_ModifiedSerializedProperties: 0
+  m_ValidKeywords: []
+  m_InvalidKeywords: []
+  m_LightmapFlags: 4
+  m_EnableInstancingVariants: 0
+  m_DoubleSidedGI: 0
+  m_CustomRenderQueue: -1
+  stringTagMap:
+    RenderType: Opaque
+  disabledShaderPasses:
+  - MOTIONVECTORS
+  m_LockedProperties: 
+  m_SavedProperties:
+    serializedVersion: 3
+    m_TexEnvs:
+    - _BaseMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _BumpMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _DetailAlbedoMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _DetailMask:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _DetailNormalMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _EmissionMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _MainTex:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _MetallicGlossMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _OcclusionMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _ParallaxMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _SpecGlossMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - unity_Lightmaps:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - unity_LightmapsInd:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - unity_ShadowMasks:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    m_Ints: []
+    m_Floats:
+    - _AddPrecomputedVelocity: 0
+    - _AlphaClip: 0
+    - _AlphaToMask: 0
+    - _Blend: 0
+    - _BlendModePreserveSpecular: 1
+    - _BumpScale: 1
+    - _ClearCoatMask: 0
+    - _ClearCoatSmoothness: 0
+    - _Cull: 2
+    - _Cutoff: 0.5
+    - _DetailAlbedoMapScale: 1
+    - _DetailNormalMapScale: 1
+    - _DstBlend: 0
+    - _DstBlendAlpha: 0
+    - _EnvironmentReflections: 1
+    - _GlossMapScale: 0
+    - _Glossiness: 0
+    - _GlossyReflections: 0
+    - _Metallic: 0
+    - _OcclusionStrength: 1
+    - _Parallax: 0.005
+    - _QueueOffset: 0
+    - _ReceiveShadows: 1
+    - _Smoothness: 0.15
+    - _SmoothnessTextureChannel: 0
+    - _SpecularHighlights: 1
+    - _SrcBlend: 1
+    - _SrcBlendAlpha: 1
+    - _Surface: 0
+    - _WorkflowMode: 1
+    - _ZWrite: 1
+    m_Colors:
+    - _BaseColor: {r: 0.49411765, g: 0.78431374, b: 0.3137255, a: 1}
+    - _Color: {r: 0.49411762, g: 0.78431374, b: 0.31372547, a: 1}
+    - _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
+    - _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1}
+  m_BuildTextureStacks: []
+  m_AllowLocking: 1
+--- !u!114 &7795313328069162580
+MonoBehaviour:
+  m_ObjectHideFlags: 11
+  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: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  version: 9

+ 745 - 0
Assets/Prefabs/Characters/Enemies/EnemyCharacter.prefab

@@ -0,0 +1,745 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!1 &90196244266908224
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 4134188022434810517}
+  m_Layer: 9
+  m_Name: Fill Area
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &4134188022434810517
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 90196244266908224}
+  m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_ConstrainProportionsScale: 0
+  m_Children:
+  - {fileID: 3460715561665505408}
+  m_Father: {fileID: 8676034777589567790}
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0, y: 0.25}
+  m_AnchorMax: {x: 1, y: 0.75}
+  m_AnchoredPosition: {x: 0, y: 0}
+  m_SizeDelta: {x: 0, y: 0}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!1 &1325548310229482701
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 2663901868150895737}
+  - component: {fileID: 3433433673605365265}
+  - component: {fileID: 5739242701541476005}
+  m_Layer: 9
+  m_Name: CharacterName TMP-Text
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &2663901868150895737
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1325548310229482701}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_ConstrainProportionsScale: 0
+  m_Children: []
+  m_Father: {fileID: 7584233212867726354}
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0, y: 0}
+  m_AnchorMax: {x: 0, y: 0}
+  m_AnchoredPosition: {x: 0, y: 0}
+  m_SizeDelta: {x: 200, y: 25}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!222 &3433433673605365265
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1325548310229482701}
+  m_CullTransparentMesh: 1
+--- !u!114 &5739242701541476005
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1325548310229482701}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 1, g: 1, b: 1, a: 1}
+  m_RaycastTarget: 1
+  m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
+  m_Maskable: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+  m_text: Character name
+  m_isRightToLeft: 0
+  m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2}
+  m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2}
+  m_fontSharedMaterials: []
+  m_fontMaterial: {fileID: 0}
+  m_fontMaterials: []
+  m_fontColor32:
+    serializedVersion: 2
+    rgba: 4294967295
+  m_fontColor: {r: 1, g: 1, b: 1, a: 1}
+  m_enableVertexGradient: 0
+  m_colorMode: 3
+  m_fontColorGradient:
+    topLeft: {r: 1, g: 1, b: 1, a: 1}
+    topRight: {r: 1, g: 1, b: 1, a: 1}
+    bottomLeft: {r: 1, g: 1, b: 1, a: 1}
+    bottomRight: {r: 1, g: 1, b: 1, a: 1}
+  m_fontColorGradientPreset: {fileID: 0}
+  m_spriteAsset: {fileID: 0}
+  m_tintAllSprites: 0
+  m_StyleSheet: {fileID: 0}
+  m_TextStyleHashCode: -1183493901
+  m_overrideHtmlColors: 0
+  m_faceColor:
+    serializedVersion: 2
+    rgba: 4294967295
+  m_fontSize: 12
+  m_fontSizeBase: 12
+  m_fontWeight: 400
+  m_enableAutoSizing: 0
+  m_fontSizeMin: 18
+  m_fontSizeMax: 72
+  m_fontStyle: 0
+  m_HorizontalAlignment: 1
+  m_VerticalAlignment: 256
+  m_textAlignment: 65535
+  m_characterSpacing: 0
+  m_wordSpacing: 0
+  m_lineSpacing: 0
+  m_lineSpacingMax: 0
+  m_paragraphSpacing: 0
+  m_charWidthMaxAdj: 0
+  m_TextWrappingMode: 1
+  m_wordWrappingRatios: 0.4
+  m_overflowMode: 0
+  m_linkedTextComponent: {fileID: 0}
+  parentLinkedComponent: {fileID: 0}
+  m_enableKerning: 0
+  m_ActiveFontFeatures: 6e72656b
+  m_enableExtraPadding: 0
+  checkPaddingRequired: 0
+  m_isRichText: 1
+  m_EmojiFallbackSupport: 1
+  m_parseCtrlCharacters: 1
+  m_isOrthographic: 1
+  m_isCullingEnabled: 0
+  m_horizontalMapping: 0
+  m_verticalMapping: 0
+  m_uvLineOffset: 0
+  m_geometrySortingOrder: 0
+  m_IsTextObjectScaleStatic: 0
+  m_VertexBufferAutoSizeReduction: 0
+  m_useMaxVisibleDescender: 1
+  m_pageToDisplay: 1
+  m_margin: {x: 0, y: 0, z: 0, w: 0}
+  m_isUsingLegacyAnimationComponent: 0
+  m_isVolumetricText: 0
+  m_hasFontAssetChanged: 0
+  m_baseMaterial: {fileID: 0}
+  m_maskOffset: {x: 0, y: 0, z: 0, w: 0}
+--- !u!1 &1880288660700002030
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 8222440902877783359}
+  - component: {fileID: 678806874848795652}
+  - component: {fileID: 4256398796908895143}
+  - component: {fileID: 6756429073287060337}
+  - component: {fileID: 266027584797096022}
+  - component: {fileID: 8467809808244036817}
+  m_Layer: 10
+  m_Name: EnemyCharacter
+  m_TagString: EnemyCharacter
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!4 &8222440902877783359
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1880288660700002030}
+  serializedVersion: 2
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 1.74, y: 1, z: -3.7}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_ConstrainProportionsScale: 0
+  m_Children:
+  - {fileID: 7584233212867726354}
+  - {fileID: 4674330156700351085}
+  m_Father: {fileID: 0}
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!33 &678806874848795652
+MeshFilter:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1880288660700002030}
+  m_Mesh: {fileID: 10208, guid: 0000000000000000e000000000000000, type: 0}
+--- !u!23 &4256398796908895143
+MeshRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1880288660700002030}
+  m_Enabled: 1
+  m_CastShadows: 1
+  m_ReceiveShadows: 1
+  m_DynamicOccludee: 1
+  m_StaticShadowCaster: 0
+  m_MotionVectors: 1
+  m_LightProbeUsage: 1
+  m_ReflectionProbeUsage: 1
+  m_RayTracingMode: 2
+  m_RayTraceProcedural: 0
+  m_RayTracingAccelStructBuildFlagsOverride: 0
+  m_RayTracingAccelStructBuildFlags: 1
+  m_SmallMeshCulling: 1
+  m_RenderingLayerMask: 1
+  m_RendererPriority: 0
+  m_Materials:
+  - {fileID: 2100000, guid: 21552248c82c56240bd21db0ed83171c, type: 2}
+  m_StaticBatchInfo:
+    firstSubMesh: 0
+    subMeshCount: 0
+  m_StaticBatchRoot: {fileID: 0}
+  m_ProbeAnchor: {fileID: 0}
+  m_LightProbeVolumeOverride: {fileID: 0}
+  m_ScaleInLightmap: 1
+  m_ReceiveGI: 1
+  m_PreserveUVs: 0
+  m_IgnoreNormalsForChartDetection: 0
+  m_ImportantGI: 0
+  m_StitchLightmapSeams: 1
+  m_SelectedEditorRenderState: 3
+  m_MinimumChartSize: 4
+  m_AutoUVMaxDistance: 0.5
+  m_AutoUVMaxAngle: 89
+  m_LightmapParameters: {fileID: 0}
+  m_SortingLayerID: 0
+  m_SortingLayer: 0
+  m_SortingOrder: 0
+  m_AdditionalVertexStreams: {fileID: 0}
+--- !u!136 &6756429073287060337
+CapsuleCollider:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1880288660700002030}
+  m_Material: {fileID: 0}
+  m_IncludeLayers:
+    serializedVersion: 2
+    m_Bits: 0
+  m_ExcludeLayers:
+    serializedVersion: 2
+    m_Bits: 0
+  m_LayerOverridePriority: 0
+  m_IsTrigger: 0
+  m_ProvidesContacts: 0
+  m_Enabled: 1
+  serializedVersion: 2
+  m_Radius: 0.5
+  m_Height: 2
+  m_Direction: 1
+  m_Center: {x: 0, y: 0, z: 0}
+--- !u!195 &266027584797096022
+NavMeshAgent:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1880288660700002030}
+  m_Enabled: 1
+  m_AgentTypeID: 0
+  m_Radius: 0.5
+  m_Speed: 3.5
+  m_Acceleration: 8
+  avoidancePriority: 50
+  m_AngularSpeed: 120
+  m_StoppingDistance: 0
+  m_AutoTraverseOffMeshLink: 1
+  m_AutoBraking: 1
+  m_AutoRepath: 1
+  m_Height: 2
+  m_BaseOffset: 1
+  m_WalkableMask: 4294967295
+  m_ObstacleAvoidanceType: 4
+--- !u!114 &8467809808244036817
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1880288660700002030}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 744b7fb664a812a468471c3fe1cd824b, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  actionData:
+    state: 0
+    targetPosition: {x: 0, y: 0, z: 0}
+    targetEnemy: {fileID: 0}
+  noActionColor: {r: 1, g: 0.92156863, b: 0.015686275, a: 1}
+  actionSelectedColor: {r: 0, g: 1, b: 0, a: 1}
+  normalColor: {r: 1, g: 1, b: 1, a: 1}
+  outlineWidth: 0.1
+  weaponPrefab: {fileID: 5119410349525231767, guid: e0447dc7b412ede4b9090f9a3cf4fdd4, type: 3}
+  arrowPrefab: {fileID: 6456274890147168025, guid: 74d688b6c70543e46a9b3ea3c4c8e787, type: 3}
+--- !u!1 &4237176983391759442
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 4204981447206346347}
+  - component: {fileID: 3898927396620426018}
+  - component: {fileID: 3666511402947699776}
+  m_Layer: 9
+  m_Name: Background
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &4204981447206346347
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 4237176983391759442}
+  m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_ConstrainProportionsScale: 0
+  m_Children: []
+  m_Father: {fileID: 8676034777589567790}
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0, y: 0.25}
+  m_AnchorMax: {x: 1, y: 0.75}
+  m_AnchoredPosition: {x: 0, y: 0}
+  m_SizeDelta: {x: 0, y: 0}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!222 &3898927396620426018
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 4237176983391759442}
+  m_CullTransparentMesh: 1
+--- !u!114 &3666511402947699776
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 4237176983391759442}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 1, g: 0, b: 0, a: 1}
+  m_RaycastTarget: 1
+  m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
+  m_Maskable: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+  m_Sprite: {fileID: 10907, guid: 0000000000000000f000000000000000, type: 0}
+  m_Type: 1
+  m_PreserveAspect: 0
+  m_FillCenter: 1
+  m_FillMethod: 4
+  m_FillAmount: 1
+  m_FillClockwise: 1
+  m_FillOrigin: 0
+  m_UseSpriteMesh: 0
+  m_PixelsPerUnitMultiplier: 1
+--- !u!1 &4408034549710997902
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 3460715561665505408}
+  - component: {fileID: 7435169562613006848}
+  - component: {fileID: 8622844255574138999}
+  m_Layer: 9
+  m_Name: Fill
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &3460715561665505408
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 4408034549710997902}
+  m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_ConstrainProportionsScale: 0
+  m_Children: []
+  m_Father: {fileID: 4134188022434810517}
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0, y: 0}
+  m_AnchorMax: {x: 0, y: 0}
+  m_AnchoredPosition: {x: 0, y: 0}
+  m_SizeDelta: {x: 0, y: 0}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!222 &7435169562613006848
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 4408034549710997902}
+  m_CullTransparentMesh: 1
+--- !u!114 &8622844255574138999
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 4408034549710997902}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 0.0034264945, g: 0.7264151, b: 0.07056751, a: 1}
+  m_RaycastTarget: 1
+  m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
+  m_Maskable: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+  m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0}
+  m_Type: 1
+  m_PreserveAspect: 0
+  m_FillCenter: 1
+  m_FillMethod: 4
+  m_FillAmount: 1
+  m_FillClockwise: 1
+  m_FillOrigin: 0
+  m_UseSpriteMesh: 0
+  m_PixelsPerUnitMultiplier: 1
+--- !u!1 &6203222348350653753
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 8676034777589567790}
+  - component: {fileID: 5005144547074019496}
+  m_Layer: 9
+  m_Name: Health
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &8676034777589567790
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 6203222348350653753}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_ConstrainProportionsScale: 0
+  m_Children:
+  - {fileID: 4204981447206346347}
+  - {fileID: 4134188022434810517}
+  m_Father: {fileID: 7584233212867726354}
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0, y: 0}
+  m_AnchorMax: {x: 0, y: 0}
+  m_AnchoredPosition: {x: 0, y: 0}
+  m_SizeDelta: {x: 200, y: 25}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!114 &5005144547074019496
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 6203222348350653753}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 67db9e8f0e2ae9c40bc1e2b64352a6b4, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Navigation:
+    m_Mode: 3
+    m_WrapAround: 0
+    m_SelectOnUp: {fileID: 0}
+    m_SelectOnDown: {fileID: 0}
+    m_SelectOnLeft: {fileID: 0}
+    m_SelectOnRight: {fileID: 0}
+  m_Transition: 0
+  m_Colors:
+    m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
+    m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
+    m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
+    m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
+    m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
+    m_ColorMultiplier: 1
+    m_FadeDuration: 0.1
+  m_SpriteState:
+    m_HighlightedSprite: {fileID: 0}
+    m_PressedSprite: {fileID: 0}
+    m_SelectedSprite: {fileID: 0}
+    m_DisabledSprite: {fileID: 0}
+  m_AnimationTriggers:
+    m_NormalTrigger: Normal
+    m_HighlightedTrigger: Highlighted
+    m_PressedTrigger: Pressed
+    m_SelectedTrigger: Selected
+    m_DisabledTrigger: Disabled
+  m_Interactable: 1
+  m_TargetGraphic: {fileID: 0}
+  m_FillRect: {fileID: 3460715561665505408}
+  m_HandleRect: {fileID: 0}
+  m_Direction: 0
+  m_MinValue: 0
+  m_MaxValue: 20
+  m_WholeNumbers: 1
+  m_Value: 20
+  m_OnValueChanged:
+    m_PersistentCalls:
+      m_Calls: []
+--- !u!1 &8051333480538093929
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 4674330156700351085}
+  m_Layer: 0
+  m_Name: WeaponAttachPoint
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!4 &4674330156700351085
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 8051333480538093929}
+  serializedVersion: 2
+  m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
+  m_LocalPosition: {x: -0.5, y: 0, z: 0.275}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_ConstrainProportionsScale: 0
+  m_Children: []
+  m_Father: {fileID: 8222440902877783359}
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!1 &9181928968973203627
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 7584233212867726354}
+  - component: {fileID: 818270576441242720}
+  - component: {fileID: 1413373450084827671}
+  - component: {fileID: 5217605622037727730}
+  - component: {fileID: 3943534464428508553}
+  - component: {fileID: 8873018028281516270}
+  m_Layer: 9
+  m_Name: CharacterInfo
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &7584233212867726354
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 9181928968973203627}
+  m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 0.01, y: 0.01, z: 1}
+  m_ConstrainProportionsScale: 0
+  m_Children:
+  - {fileID: 2663901868150895737}
+  - {fileID: 8676034777589567790}
+  m_Father: {fileID: 8222440902877783359}
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0, y: 0}
+  m_AnchorMax: {x: 0, y: 0}
+  m_AnchoredPosition: {x: 0, y: 1.5279999}
+  m_SizeDelta: {x: 200, y: 50}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!223 &818270576441242720
+Canvas:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 9181928968973203627}
+  m_Enabled: 1
+  serializedVersion: 3
+  m_RenderMode: 2
+  m_Camera: {fileID: 0}
+  m_PlaneDistance: 100
+  m_PixelPerfect: 0
+  m_ReceivesEvents: 1
+  m_OverrideSorting: 0
+  m_OverridePixelPerfect: 0
+  m_SortingBucketNormalizedSize: 0
+  m_VertexColorAlwaysGammaSpace: 1
+  m_AdditionalShaderChannelsFlag: 25
+  m_UpdateRectTransformForStandalone: 0
+  m_SortingLayerID: 0
+  m_SortingOrder: 0
+  m_TargetDisplay: 0
+--- !u!114 &1413373450084827671
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 9181928968973203627}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 0cd44c1031e13a943bb63640046fad76, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_UiScaleMode: 0
+  m_ReferencePixelsPerUnit: 100
+  m_ScaleFactor: 1
+  m_ReferenceResolution: {x: 800, y: 600}
+  m_ScreenMatchMode: 0
+  m_MatchWidthOrHeight: 0
+  m_PhysicalUnit: 3
+  m_FallbackScreenDPI: 96
+  m_DefaultSpriteDPI: 96
+  m_DynamicPixelsPerUnit: 1
+  m_PresetInfoIsWorld: 1
+--- !u!114 &5217605622037727730
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 9181928968973203627}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: dc42784cf147c0c48a680349fa168899, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_IgnoreReversedGraphics: 1
+  m_BlockingObjects: 0
+  m_BlockingMask:
+    serializedVersion: 2
+    m_Bits: 4294967295
+--- !u!114 &3943534464428508553
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 9181928968973203627}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 15851daa7a9e9af4b885de2c9878dbfa, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+--- !u!114 &8873018028281516270
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 9181928968973203627}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 59f8146938fff824cb5fd77236b75775, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Padding:
+    m_Left: 0
+    m_Right: 0
+    m_Top: 0
+    m_Bottom: 0
+  m_ChildAlignment: 0
+  m_Spacing: 0
+  m_ChildForceExpandWidth: 1
+  m_ChildForceExpandHeight: 1
+  m_ChildControlWidth: 0
+  m_ChildControlHeight: 0
+  m_ChildScaleWidth: 0
+  m_ChildScaleHeight: 0
+  m_ReverseArrangement: 0

+ 718 - 0
Assets/Prefabs/Characters/Players/PlayerCharacter.prefab

@@ -0,0 +1,718 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!1 &1077306538408355598
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 9091362845718053452}
+  - component: {fileID: 1960887524973747695}
+  m_Layer: 9
+  m_Name: Health
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &9091362845718053452
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1077306538408355598}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_ConstrainProportionsScale: 0
+  m_Children:
+  - {fileID: 4561396166327944902}
+  - {fileID: 1428279582768190532}
+  m_Father: {fileID: 5222116419892524772}
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0.5, y: 0.5}
+  m_AnchorMax: {x: 0.5, y: 0.5}
+  m_AnchoredPosition: {x: 0, y: 0}
+  m_SizeDelta: {x: 160, y: 20}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!114 &1960887524973747695
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1077306538408355598}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 67db9e8f0e2ae9c40bc1e2b64352a6b4, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Navigation:
+    m_Mode: 3
+    m_WrapAround: 0
+    m_SelectOnUp: {fileID: 0}
+    m_SelectOnDown: {fileID: 0}
+    m_SelectOnLeft: {fileID: 0}
+    m_SelectOnRight: {fileID: 0}
+  m_Transition: 0
+  m_Colors:
+    m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
+    m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
+    m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
+    m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
+    m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
+    m_ColorMultiplier: 1
+    m_FadeDuration: 0.1
+  m_SpriteState:
+    m_HighlightedSprite: {fileID: 0}
+    m_PressedSprite: {fileID: 0}
+    m_SelectedSprite: {fileID: 0}
+    m_DisabledSprite: {fileID: 0}
+  m_AnimationTriggers:
+    m_NormalTrigger: Normal
+    m_HighlightedTrigger: Highlighted
+    m_PressedTrigger: Pressed
+    m_SelectedTrigger: Selected
+    m_DisabledTrigger: Disabled
+  m_Interactable: 1
+  m_TargetGraphic: {fileID: 0}
+  m_FillRect: {fileID: 7405259244441291236}
+  m_HandleRect: {fileID: 0}
+  m_Direction: 0
+  m_MinValue: 0
+  m_MaxValue: 20
+  m_WholeNumbers: 1
+  m_Value: 20
+  m_OnValueChanged:
+    m_PersistentCalls:
+      m_Calls: []
+--- !u!1 &1880288660700002030
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 8222440902877783359}
+  - component: {fileID: 678806874848795652}
+  - component: {fileID: 4256398796908895143}
+  - component: {fileID: 6756429073287060337}
+  - component: {fileID: 4826876197298231325}
+  - component: {fileID: 270211646132433615}
+  m_Layer: 9
+  m_Name: PlayerCharacter
+  m_TagString: PlayerCharacter
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!4 &8222440902877783359
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1880288660700002030}
+  serializedVersion: 2
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 1.74, y: 1, z: -3.7}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_ConstrainProportionsScale: 0
+  m_Children:
+  - {fileID: 5222116419892524772}
+  - {fileID: 4867918334518225106}
+  m_Father: {fileID: 0}
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!33 &678806874848795652
+MeshFilter:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1880288660700002030}
+  m_Mesh: {fileID: 10208, guid: 0000000000000000e000000000000000, type: 0}
+--- !u!23 &4256398796908895143
+MeshRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1880288660700002030}
+  m_Enabled: 1
+  m_CastShadows: 1
+  m_ReceiveShadows: 1
+  m_DynamicOccludee: 1
+  m_StaticShadowCaster: 0
+  m_MotionVectors: 1
+  m_LightProbeUsage: 1
+  m_ReflectionProbeUsage: 1
+  m_RayTracingMode: 2
+  m_RayTraceProcedural: 0
+  m_RayTracingAccelStructBuildFlagsOverride: 0
+  m_RayTracingAccelStructBuildFlags: 1
+  m_SmallMeshCulling: 1
+  m_RenderingLayerMask: 1
+  m_RendererPriority: 0
+  m_Materials:
+  - {fileID: 2100000, guid: ef7abe4507c12b3449a4171c7cb62740, type: 2}
+  m_StaticBatchInfo:
+    firstSubMesh: 0
+    subMeshCount: 0
+  m_StaticBatchRoot: {fileID: 0}
+  m_ProbeAnchor: {fileID: 0}
+  m_LightProbeVolumeOverride: {fileID: 0}
+  m_ScaleInLightmap: 1
+  m_ReceiveGI: 1
+  m_PreserveUVs: 0
+  m_IgnoreNormalsForChartDetection: 0
+  m_ImportantGI: 0
+  m_StitchLightmapSeams: 1
+  m_SelectedEditorRenderState: 3
+  m_MinimumChartSize: 4
+  m_AutoUVMaxDistance: 0.5
+  m_AutoUVMaxAngle: 89
+  m_LightmapParameters: {fileID: 0}
+  m_SortingLayerID: 0
+  m_SortingLayer: 0
+  m_SortingOrder: 0
+  m_AdditionalVertexStreams: {fileID: 0}
+--- !u!136 &6756429073287060337
+CapsuleCollider:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1880288660700002030}
+  m_Material: {fileID: 0}
+  m_IncludeLayers:
+    serializedVersion: 2
+    m_Bits: 0
+  m_ExcludeLayers:
+    serializedVersion: 2
+    m_Bits: 0
+  m_LayerOverridePriority: 0
+  m_IsTrigger: 0
+  m_ProvidesContacts: 0
+  m_Enabled: 1
+  serializedVersion: 2
+  m_Radius: 0.5
+  m_Height: 2
+  m_Direction: 1
+  m_Center: {x: 0, y: 0, z: 0}
+--- !u!195 &4826876197298231325
+NavMeshAgent:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1880288660700002030}
+  m_Enabled: 1
+  m_AgentTypeID: 0
+  m_Radius: 0.5
+  m_Speed: 3.5
+  m_Acceleration: 8
+  avoidancePriority: 50
+  m_AngularSpeed: 120
+  m_StoppingDistance: 0
+  m_AutoTraverseOffMeshLink: 1
+  m_AutoBraking: 1
+  m_AutoRepath: 1
+  m_Height: 2
+  m_BaseOffset: 1
+  m_WalkableMask: 4294967295
+  m_ObstacleAvoidanceType: 4
+--- !u!114 &270211646132433615
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1880288660700002030}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 8a44ebdeb75f6474f83499644dae0c9d, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  actionData:
+    state: 0
+    targetPosition: {x: 0, y: 0, z: 0}
+    targetEnemy: {fileID: 0}
+  noActionColor: {r: 1, g: 0.92156863, b: 0.015686275, a: 1}
+  actionSelectedColor: {r: 0, g: 1, b: 0, a: 1}
+  normalColor: {r: 1, g: 1, b: 1, a: 1}
+  outlineWidth: 0.1
+  weaponPrefab: {fileID: 3381517991582171355, guid: 2e07955f8c531dc4ea65c9d6a521f306, type: 3}
+  arrowPrefab: {fileID: 0}
+--- !u!1 &3787963050092748655
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 4561396166327944902}
+  - component: {fileID: 7279411533838708688}
+  - component: {fileID: 964870940568872478}
+  m_Layer: 9
+  m_Name: Background
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &4561396166327944902
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 3787963050092748655}
+  m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_ConstrainProportionsScale: 0
+  m_Children: []
+  m_Father: {fileID: 9091362845718053452}
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0, y: 0.25}
+  m_AnchorMax: {x: 1, y: 0.75}
+  m_AnchoredPosition: {x: 0, y: 0}
+  m_SizeDelta: {x: 0, y: 0}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!222 &7279411533838708688
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 3787963050092748655}
+  m_CullTransparentMesh: 1
+--- !u!114 &964870940568872478
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 3787963050092748655}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 1, g: 0, b: 0, a: 1}
+  m_RaycastTarget: 1
+  m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
+  m_Maskable: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+  m_Sprite: {fileID: 10907, guid: 0000000000000000f000000000000000, type: 0}
+  m_Type: 1
+  m_PreserveAspect: 0
+  m_FillCenter: 1
+  m_FillMethod: 4
+  m_FillAmount: 1
+  m_FillClockwise: 1
+  m_FillOrigin: 0
+  m_UseSpriteMesh: 0
+  m_PixelsPerUnitMultiplier: 1
+--- !u!1 &4230993899452292024
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 7405259244441291236}
+  - component: {fileID: 5205212828535020761}
+  - component: {fileID: 8756857319034235752}
+  m_Layer: 9
+  m_Name: Fill
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &7405259244441291236
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 4230993899452292024}
+  m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_ConstrainProportionsScale: 0
+  m_Children: []
+  m_Father: {fileID: 1428279582768190532}
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0, y: 0}
+  m_AnchorMax: {x: 0, y: 0}
+  m_AnchoredPosition: {x: 0, y: 0}
+  m_SizeDelta: {x: 0, y: 0}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!222 &5205212828535020761
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 4230993899452292024}
+  m_CullTransparentMesh: 1
+--- !u!114 &8756857319034235752
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 4230993899452292024}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 0.0034264945, g: 0.7264151, b: 0.07056751, a: 1}
+  m_RaycastTarget: 1
+  m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
+  m_Maskable: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+  m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0}
+  m_Type: 1
+  m_PreserveAspect: 0
+  m_FillCenter: 1
+  m_FillMethod: 4
+  m_FillAmount: 1
+  m_FillClockwise: 1
+  m_FillOrigin: 0
+  m_UseSpriteMesh: 0
+  m_PixelsPerUnitMultiplier: 1
+--- !u!1 &4682808290816563979
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 4867918334518225106}
+  m_Layer: 9
+  m_Name: WeaponAttachPoint
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!4 &4867918334518225106
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 4682808290816563979}
+  serializedVersion: 2
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0.5, y: 0, z: 0.315}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_ConstrainProportionsScale: 0
+  m_Children: []
+  m_Father: {fileID: 8222440902877783359}
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!1 &7685494030878873200
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 1428279582768190532}
+  m_Layer: 9
+  m_Name: Fill Area
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &1428279582768190532
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 7685494030878873200}
+  m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_ConstrainProportionsScale: 0
+  m_Children:
+  - {fileID: 7405259244441291236}
+  m_Father: {fileID: 9091362845718053452}
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0, y: 0.25}
+  m_AnchorMax: {x: 1, y: 0.75}
+  m_AnchoredPosition: {x: 0, y: 0}
+  m_SizeDelta: {x: 0, y: 0}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!1 &8526328889348735856
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 8717921420350973522}
+  - component: {fileID: 8441842861090635085}
+  - component: {fileID: 7108188719169854090}
+  m_Layer: 9
+  m_Name: CharacterName
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &8717921420350973522
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 8526328889348735856}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_ConstrainProportionsScale: 0
+  m_Children: []
+  m_Father: {fileID: 5222116419892524772}
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0, y: 0}
+  m_AnchorMax: {x: 0.9, y: 1}
+  m_AnchoredPosition: {x: 0, y: 0}
+  m_SizeDelta: {x: 0, y: 0}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!222 &8441842861090635085
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 8526328889348735856}
+  m_CullTransparentMesh: 1
+--- !u!114 &7108188719169854090
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 8526328889348735856}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 1, g: 1, b: 1, a: 1}
+  m_RaycastTarget: 1
+  m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
+  m_Maskable: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+  m_text: Character name
+  m_isRightToLeft: 0
+  m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2}
+  m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2}
+  m_fontSharedMaterials: []
+  m_fontMaterial: {fileID: 0}
+  m_fontMaterials: []
+  m_fontColor32:
+    serializedVersion: 2
+    rgba: 4294967295
+  m_fontColor: {r: 1, g: 1, b: 1, a: 1}
+  m_enableVertexGradient: 0
+  m_colorMode: 3
+  m_fontColorGradient:
+    topLeft: {r: 1, g: 1, b: 1, a: 1}
+    topRight: {r: 1, g: 1, b: 1, a: 1}
+    bottomLeft: {r: 1, g: 1, b: 1, a: 1}
+    bottomRight: {r: 1, g: 1, b: 1, a: 1}
+  m_fontColorGradientPreset: {fileID: 0}
+  m_spriteAsset: {fileID: 0}
+  m_tintAllSprites: 0
+  m_StyleSheet: {fileID: 0}
+  m_TextStyleHashCode: -1183493901
+  m_overrideHtmlColors: 0
+  m_faceColor:
+    serializedVersion: 2
+    rgba: 4294967295
+  m_fontSize: 12
+  m_fontSizeBase: 12
+  m_fontWeight: 400
+  m_enableAutoSizing: 0
+  m_fontSizeMin: 18
+  m_fontSizeMax: 72
+  m_fontStyle: 0
+  m_HorizontalAlignment: 1
+  m_VerticalAlignment: 256
+  m_textAlignment: 65535
+  m_characterSpacing: 0
+  m_wordSpacing: 0
+  m_lineSpacing: 0
+  m_lineSpacingMax: 0
+  m_paragraphSpacing: 0
+  m_charWidthMaxAdj: 0
+  m_TextWrappingMode: 1
+  m_wordWrappingRatios: 0.4
+  m_overflowMode: 0
+  m_linkedTextComponent: {fileID: 0}
+  parentLinkedComponent: {fileID: 0}
+  m_enableKerning: 0
+  m_ActiveFontFeatures: 6e72656b
+  m_enableExtraPadding: 0
+  checkPaddingRequired: 0
+  m_isRichText: 1
+  m_EmojiFallbackSupport: 1
+  m_parseCtrlCharacters: 1
+  m_isOrthographic: 1
+  m_isCullingEnabled: 0
+  m_horizontalMapping: 0
+  m_verticalMapping: 0
+  m_uvLineOffset: 0
+  m_geometrySortingOrder: 0
+  m_IsTextObjectScaleStatic: 0
+  m_VertexBufferAutoSizeReduction: 0
+  m_useMaxVisibleDescender: 1
+  m_pageToDisplay: 1
+  m_margin: {x: 0, y: 0, z: 0, w: 0}
+  m_isUsingLegacyAnimationComponent: 0
+  m_isVolumetricText: 0
+  m_hasFontAssetChanged: 0
+  m_baseMaterial: {fileID: 0}
+  m_maskOffset: {x: 0, y: 0, z: 0, w: 0}
+--- !u!1 &8771063781492461925
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 5222116419892524772}
+  - component: {fileID: 8522494244707328200}
+  - component: {fileID: 368002052232264507}
+  - component: {fileID: 8515649944761107884}
+  - component: {fileID: 1978644637143878758}
+  m_Layer: 9
+  m_Name: CharacterInfo
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &5222116419892524772
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 8771063781492461925}
+  m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 0.01, y: 0.01, z: 1}
+  m_ConstrainProportionsScale: 0
+  m_Children:
+  - {fileID: 8717921420350973522}
+  - {fileID: 9091362845718053452}
+  m_Father: {fileID: 8222440902877783359}
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0, y: 0}
+  m_AnchorMax: {x: 0, y: 0}
+  m_AnchoredPosition: {x: 0, y: 1.528}
+  m_SizeDelta: {x: 200, y: 50}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!223 &8522494244707328200
+Canvas:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 8771063781492461925}
+  m_Enabled: 1
+  serializedVersion: 3
+  m_RenderMode: 2
+  m_Camera: {fileID: 0}
+  m_PlaneDistance: 100
+  m_PixelPerfect: 0
+  m_ReceivesEvents: 1
+  m_OverrideSorting: 0
+  m_OverridePixelPerfect: 0
+  m_SortingBucketNormalizedSize: 0
+  m_VertexColorAlwaysGammaSpace: 1
+  m_AdditionalShaderChannelsFlag: 25
+  m_UpdateRectTransformForStandalone: 0
+  m_SortingLayerID: 0
+  m_SortingOrder: 0
+  m_TargetDisplay: 0
+--- !u!114 &368002052232264507
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 8771063781492461925}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 0cd44c1031e13a943bb63640046fad76, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_UiScaleMode: 0
+  m_ReferencePixelsPerUnit: 100
+  m_ScaleFactor: 1
+  m_ReferenceResolution: {x: 800, y: 600}
+  m_ScreenMatchMode: 0
+  m_MatchWidthOrHeight: 0
+  m_PhysicalUnit: 3
+  m_FallbackScreenDPI: 96
+  m_DefaultSpriteDPI: 96
+  m_DynamicPixelsPerUnit: 1
+  m_PresetInfoIsWorld: 1
+--- !u!114 &8515649944761107884
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 8771063781492461925}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: dc42784cf147c0c48a680349fa168899, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_IgnoreReversedGraphics: 1
+  m_BlockingObjects: 0
+  m_BlockingMask:
+    serializedVersion: 2
+    m_Bits: 4294967295
+--- !u!114 &1978644637143878758
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 8771063781492461925}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 15851daa7a9e9af4b885de2c9878dbfa, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 

+ 0 - 0
Assets/Prefabs/Terrain/TerrainTile.prefab


+ 125 - 0
Assets/Prefabs/Weapons/Arrow.prefab

@@ -0,0 +1,125 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!1 &6456274890147168025
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 4869228124223339730}
+  - component: {fileID: 5906620936144954211}
+  - component: {fileID: 3837627623050726763}
+  - component: {fileID: 109489937266574060}
+  - component: {fileID: 7791489003214561061}
+  m_Layer: 0
+  m_Name: Arrow
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!4 &4869228124223339730
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 6456274890147168025}
+  serializedVersion: 2
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 0.01, y: 0.01, z: 0.2}
+  m_ConstrainProportionsScale: 0
+  m_Children: []
+  m_Father: {fileID: 0}
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!33 &5906620936144954211
+MeshFilter:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 6456274890147168025}
+  m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
+--- !u!23 &3837627623050726763
+MeshRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 6456274890147168025}
+  m_Enabled: 1
+  m_CastShadows: 1
+  m_ReceiveShadows: 1
+  m_DynamicOccludee: 1
+  m_StaticShadowCaster: 0
+  m_MotionVectors: 1
+  m_LightProbeUsage: 1
+  m_ReflectionProbeUsage: 1
+  m_RayTracingMode: 2
+  m_RayTraceProcedural: 0
+  m_RayTracingAccelStructBuildFlagsOverride: 0
+  m_RayTracingAccelStructBuildFlags: 1
+  m_SmallMeshCulling: 1
+  m_RenderingLayerMask: 1
+  m_RendererPriority: 0
+  m_Materials:
+  - {fileID: 2100000, guid: ff25e31165aeb974296c13bf22b24e5a, type: 2}
+  m_StaticBatchInfo:
+    firstSubMesh: 0
+    subMeshCount: 0
+  m_StaticBatchRoot: {fileID: 0}
+  m_ProbeAnchor: {fileID: 0}
+  m_LightProbeVolumeOverride: {fileID: 0}
+  m_ScaleInLightmap: 1
+  m_ReceiveGI: 1
+  m_PreserveUVs: 0
+  m_IgnoreNormalsForChartDetection: 0
+  m_ImportantGI: 0
+  m_StitchLightmapSeams: 1
+  m_SelectedEditorRenderState: 3
+  m_MinimumChartSize: 4
+  m_AutoUVMaxDistance: 0.5
+  m_AutoUVMaxAngle: 89
+  m_LightmapParameters: {fileID: 0}
+  m_SortingLayerID: 0
+  m_SortingLayer: 0
+  m_SortingOrder: 0
+  m_AdditionalVertexStreams: {fileID: 0}
+--- !u!65 &109489937266574060
+BoxCollider:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 6456274890147168025}
+  m_Material: {fileID: 0}
+  m_IncludeLayers:
+    serializedVersion: 2
+    m_Bits: 0
+  m_ExcludeLayers:
+    serializedVersion: 2
+    m_Bits: 0
+  m_LayerOverridePriority: 0
+  m_IsTrigger: 0
+  m_ProvidesContacts: 0
+  m_Enabled: 1
+  serializedVersion: 3
+  m_Size: {x: 1, y: 1, z: 1}
+  m_Center: {x: 0, y: 0, z: 0}
+--- !u!114 &7791489003214561061
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 6456274890147168025}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 942d2872905bab5409e7bf237564742d, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  flightSpeed: 20
+  arrowModel: {fileID: 6456274890147168025}

+ 99 - 0
Assets/Prefabs/Weapons/SimpleBow.prefab

@@ -0,0 +1,99 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!1 &5410050047777400374
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 6075843574453798914}
+  - component: {fileID: 5119410349525231767}
+  m_Layer: 0
+  m_Name: SimpleBow
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!4 &6075843574453798914
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 5410050047777400374}
+  serializedVersion: 2
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_ConstrainProportionsScale: 0
+  m_Children:
+  - {fileID: 7691587364710236018}
+  m_Father: {fileID: 0}
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!114 &5119410349525231767
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 5410050047777400374}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 3334963525b3b0948aaf9a98ef43ec21, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  weaponName: Simple Bow
+  description: A basic bow for shooting arrows.
+  damage: 0
+  attackSpeed: 2
+  weaponModel: {fileID: 919132149155446097, guid: e9b3df05d59a68b4aa24f21951394f4c, type: 3}
+  arrowPrefab: {fileID: 6456274890147168025, guid: 74d688b6c70543e46a9b3ea3c4c8e787, type: 3}
+--- !u!1001 &7869117350271965337
+PrefabInstance:
+  m_ObjectHideFlags: 0
+  serializedVersion: 2
+  m_Modification:
+    serializedVersion: 3
+    m_TransformParent: {fileID: 6075843574453798914}
+    m_Modifications:
+    - target: {fileID: -8679921383154817045, guid: e9b3df05d59a68b4aa24f21951394f4c, type: 3}
+      propertyPath: m_LocalRotation.w
+      value: 0.7071068
+      objectReference: {fileID: 0}
+    - target: {fileID: -8679921383154817045, guid: e9b3df05d59a68b4aa24f21951394f4c, type: 3}
+      propertyPath: m_LocalRotation.x
+      value: 0.7071068
+      objectReference: {fileID: 0}
+    - target: {fileID: -8679921383154817045, guid: e9b3df05d59a68b4aa24f21951394f4c, type: 3}
+      propertyPath: m_LocalRotation.z
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: -8679921383154817045, guid: e9b3df05d59a68b4aa24f21951394f4c, type: 3}
+      propertyPath: m_LocalEulerAnglesHint.x
+      value: 90
+      objectReference: {fileID: 0}
+    - target: {fileID: -8679921383154817045, guid: e9b3df05d59a68b4aa24f21951394f4c, type: 3}
+      propertyPath: m_LocalEulerAnglesHint.y
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: -8679921383154817045, guid: e9b3df05d59a68b4aa24f21951394f4c, type: 3}
+      propertyPath: m_LocalEulerAnglesHint.z
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 919132149155446097, guid: e9b3df05d59a68b4aa24f21951394f4c, type: 3}
+      propertyPath: m_Name
+      value: bow
+      objectReference: {fileID: 0}
+    m_RemovedComponents: []
+    m_RemovedGameObjects: []
+    m_AddedGameObjects: []
+    m_AddedComponents: []
+  m_SourcePrefab: {fileID: 100100000, guid: e9b3df05d59a68b4aa24f21951394f4c, type: 3}
+--- !u!4 &7691587364710236018 stripped
+Transform:
+  m_CorrespondingSourceObject: {fileID: -8679921383154817045, guid: e9b3df05d59a68b4aa24f21951394f4c, type: 3}
+  m_PrefabInstance: {fileID: 7869117350271965337}
+  m_PrefabAsset: {fileID: 0}

+ 102 - 0
Assets/Prefabs/Weapons/SimpleSword.prefab

@@ -0,0 +1,102 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!1 &5410050047777400374
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 6075843574453798914}
+  - component: {fileID: 3381517991582171355}
+  m_Layer: 0
+  m_Name: SimpleSword
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!4 &6075843574453798914
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 5410050047777400374}
+  serializedVersion: 2
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_ConstrainProportionsScale: 0
+  m_Children:
+  - {fileID: 4661967836180822070}
+  m_Father: {fileID: 0}
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!114 &3381517991582171355
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 5410050047777400374}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 41eab6dd3b237b64e91c4138ed473b91, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  weaponName: Simple Sword
+  description: A basic sword.
+  damage: 0
+  attackSpeed: 1
+  weaponModel: {fileID: 919132149155446097, guid: aab98e2abfc89e5419884ca40e3c996d, type: 3}
+--- !u!1001 &5131880871701766109
+PrefabInstance:
+  m_ObjectHideFlags: 0
+  serializedVersion: 2
+  m_Modification:
+    serializedVersion: 3
+    m_TransformParent: {fileID: 6075843574453798914}
+    m_Modifications:
+    - target: {fileID: -8679921383154817045, guid: aab98e2abfc89e5419884ca40e3c996d, type: 3}
+      propertyPath: m_LocalRotation.w
+      value: 1
+      objectReference: {fileID: 0}
+    - target: {fileID: -8679921383154817045, guid: aab98e2abfc89e5419884ca40e3c996d, type: 3}
+      propertyPath: m_LocalRotation.x
+      value: -0
+      objectReference: {fileID: 0}
+    - target: {fileID: -8679921383154817045, guid: aab98e2abfc89e5419884ca40e3c996d, type: 3}
+      propertyPath: m_LocalRotation.y
+      value: -0
+      objectReference: {fileID: 0}
+    - target: {fileID: -8679921383154817045, guid: aab98e2abfc89e5419884ca40e3c996d, type: 3}
+      propertyPath: m_LocalRotation.z
+      value: -0
+      objectReference: {fileID: 0}
+    - target: {fileID: -8679921383154817045, guid: aab98e2abfc89e5419884ca40e3c996d, type: 3}
+      propertyPath: m_LocalEulerAnglesHint.x
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: -8679921383154817045, guid: aab98e2abfc89e5419884ca40e3c996d, type: 3}
+      propertyPath: m_LocalEulerAnglesHint.y
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: -8679921383154817045, guid: aab98e2abfc89e5419884ca40e3c996d, type: 3}
+      propertyPath: m_LocalEulerAnglesHint.z
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 919132149155446097, guid: aab98e2abfc89e5419884ca40e3c996d, type: 3}
+      propertyPath: m_Name
+      value: sword
+      objectReference: {fileID: 0}
+    m_RemovedComponents: []
+    m_RemovedGameObjects: []
+    m_AddedGameObjects: []
+    m_AddedComponents: []
+  m_SourcePrefab: {fileID: 100100000, guid: aab98e2abfc89e5419884ca40e3c996d, type: 3}
+--- !u!4 &4661967836180822070 stripped
+Transform:
+  m_CorrespondingSourceObject: {fileID: -8679921383154817045, guid: aab98e2abfc89e5419884ca40e3c996d, type: 3}
+  m_PrefabInstance: {fileID: 5131880871701766109}
+  m_PrefabAsset: {fileID: 0}

BIN
Assets/Prefabs/Weapons/bow.fbx


BIN
Assets/Prefabs/Weapons/sword.fbx


+ 34 - 0
Assets/Readme.asset

@@ -0,0 +1,34 @@
+%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: fcf7219bab7fe46a1ad266029b2fee19, type: 3}
+  m_Name: Readme
+  m_EditorClassIdentifier: 
+  icon: {fileID: 2800000, guid: 727a75301c3d24613a3ebcec4a24c2c8, type: 3}
+  title: URP Empty Template
+  sections:
+  - heading: Welcome to the Universal Render Pipeline
+    text: This template includes the settings and assets you need to start creating with the Universal Render Pipeline.
+    linkText: 
+    url:
+  - heading: URP Documentation
+    text:
+    linkText: Read more about URP
+    url: https://docs.unity3d.com/Packages/com.unity.render-pipelines.universal@latest
+  - heading: Forums
+    text:
+    linkText: Get answers and support
+    url: https://forum.unity.com/forums/universal-render-pipeline.383/
+  - heading: Report bugs
+    text:
+    linkText: Submit a report
+    url: https://unity3d.com/unity/qa/bug-reporting
+  loadedLayout: 1

+ 351 - 0
Assets/Resources/UI/Map/TravelUI.uss

@@ -0,0 +1,351 @@
+/* Travel UI Styles */
+.travel-container {
+    /* Position to the right side instead of center */
+    position: absolute !important;
+    top: 20px !important;
+    right: 20px !important;
+    left: auto !important;
+    bottom: auto !important;
+    width: auto !important;
+    height: auto !important;
+    background-color: transparent !important;
+    justify-content: flex-start !important;
+    align-items: flex-start !important;
+    display: none;
+}
+
+.travel-panel {
+    background-color: rgba(45, 45, 45, 0.95) !important;
+    border-width: 2px !important;
+    border-color: rgb(80, 80, 80) !important;
+    border-radius: 8px !important;
+    padding: 15px !important;
+    width: 320px !important;
+    min-height: 420px !important;
+    max-height: 600px !important;
+    flex-direction: column;
+    flex-shrink: 0;
+    cursor: move;
+}
+
+.travel-header {
+    flex-direction: row !important;
+    justify-content: space-between !important;
+    align-items: center !important;
+    margin-bottom: 10px !important;
+    background-color: rgba(60, 60, 60, 0.8) !important;
+    margin: -20px -20px 10px -20px !important;
+    padding: 10px 20px !important;
+    border-top-left-radius: 6px !important;
+    border-top-right-radius: 6px !important;
+}
+
+.travel-title {
+    font-size: 14px !important;
+    -unity-font-style: bold !important;
+    color: rgb(220, 220, 220) !important;
+    margin: 0 !important;
+    flex-grow: 1 !important;
+}
+
+.close-button {
+    width: 24px !important;
+    height: 24px !important;
+    margin: 0 !important;
+    padding: 0 !important;
+    background-color: transparent !important;
+    border-width: 0 !important;
+    color: rgb(200, 200, 200) !important;
+    font-size: 16px !important;
+    -unity-font-style: bold !important;
+}
+
+.close-button:hover {
+    background-color: rgba(200, 50, 50, 0.7) !important;
+    color: white !important;
+}
+
+.travel-info {
+    flex-direction: column;
+    margin-bottom: 10px;
+    padding: 10px;
+    background-color: rgba(30, 30, 30, 0.8);
+    border-radius: 5px;
+    border-width: 1px;
+    border-color: rgba(100, 100, 100, 0.5);
+    height: 120px;
+    flex-shrink: 0;
+    overflow: hidden;
+}
+
+.info-label {
+    font-size: 14px;
+    color: rgb(240, 240, 240) !important;
+    margin-bottom: 3px;
+    -unity-font-style: normal;
+    height: auto;
+    min-height: 18px;
+    flex-shrink: 0;
+}
+
+.button-container {
+    flex-direction: row;
+    justify-content: space-between;
+    margin-top: auto;
+    /* Note: gap not supported in Unity, use margins on children instead */
+}
+
+.travel-button {
+    flex: 1;
+    padding: 8px 12px;
+    font-size: 12px;
+    -unity-font-style: bold;
+    border-width: 0;
+    border-radius: 5px;
+    min-height: 35px;
+    white-space: normal;
+    -unity-text-align: middle-center;
+    margin-left: 4px;
+    margin-right: 4px;
+}
+
+.primary-button {
+    background-color: rgb(34, 139, 34);
+    color: rgb(255, 255, 255);
+}
+
+.primary-button:hover {
+    background-color: rgb(50, 180, 50);
+}
+
+.primary-button:disabled {
+    background-color: rgb(80, 80, 80) !important;
+    color: rgb(150, 150, 150) !important;
+}
+
+.primary-button:disabled:hover {
+    background-color: rgb(80, 80, 80) !important;
+    color: rgb(150, 150, 150) !important;
+}
+
+.secondary-button {
+    background-color: rgb(180, 50, 50);
+    color: rgb(255, 255, 255);
+}
+
+.secondary-button:hover {
+    background-color: rgb(220, 70, 70);
+}
+
+/* Route Options Section */
+.route-options {
+    flex-direction: column;
+    margin-bottom: 15px;
+    padding: 10px;
+    background-color: rgba(25, 25, 35, 0.8);
+    border-radius: 5px;
+    border-width: 1px;
+    border-color: rgba(100, 100, 120, 0.5);
+    flex-grow: 1;
+    min-height: 200px;
+    max-height: 300px;
+    flex-shrink: 0;
+    overflow: hidden;
+}
+
+.section-title {
+    font-size: 14px;
+    -unity-font-style: bold;
+    color: rgb(220, 220, 255) !important;
+    margin-bottom: 8px;
+}
+
+.toggle-container {
+    flex-direction: column;
+    flex-grow: 1;
+    /* Note: gap not supported in Unity, using margin-bottom on children instead */
+}
+
+.route-toggle {
+    color: rgb(240, 240, 240) !important;
+    font-size: 13px;
+    margin-bottom: 5px;
+}
+
+.route-toggle > .unity-toggle__checkmark {
+    background-color: rgba(50, 50, 50, 0.9) !important;
+    border-color: rgb(120, 120, 120) !important;
+    border-width: 1px !important;
+    border-radius: 3px !important;
+}
+
+.route-toggle:checked > .unity-toggle__checkmark {
+    background-color: rgb(34, 139, 34) !important;
+    border-color: rgb(50, 180, 50) !important;
+}
+
+.route-toggle > .unity-toggle__text {
+    color: rgb(240, 240, 240) !important;
+}
+
+.special-costs {
+    color: rgb(255, 200, 100);
+    -unity-font-style: bold;
+    white-space: normal;
+    -unity-text-align: upper-left;
+    overflow: visible;
+    flex-shrink: 0;
+    min-height: 20px;
+    max-height: 60px;
+}
+
+.warning-section {
+    flex-direction: column;
+    margin-bottom: 10px;
+    height: 20px;
+    flex-shrink: 0;
+}
+
+.insufficient-funds {
+    color: rgb(255, 100, 100) !important;
+    -unity-font-style: bold !important;
+    font-size: 12px !important;
+    -unity-text-align: middle-center;
+    background-color: rgba(150, 30, 30, 0.3);
+    border-radius: 3px;
+    padding: 3px;
+    border-width: 1px;
+    border-color: rgba(255, 100, 100, 0.5);
+    height: 18px;
+    flex-shrink: 0;
+}
+
+.alternative-button {
+    background-color: rgb(100, 100, 150);
+    color: rgb(255, 255, 255);
+    margin-top: auto;
+    margin-bottom: 2px;
+    font-size: 11px;
+    padding: 6px 8px;
+    min-height: 28px;
+}
+
+.alternative-button:hover {
+    background-color: rgb(130, 130, 180);
+}
+
+/* Responsive adjustments */
+@media (max-width: 800px) {
+    .travel-container {
+        left: 10px;
+        right: 10px;
+        max-width: none;
+    }
+    
+    .travel-panel {
+        padding: 15px;
+    }
+    
+    .button-container {
+        flex-direction: column;
+        /* Note: gap not supported, using margin on children */
+    }
+    
+    .travel-button {
+        min-height: 35px;
+        font-size: 13px;
+        margin-bottom: 8px;
+        margin-left: 0;
+        margin-right: 0;
+    }
+}
+
+/* Route List Styles */
+.route-list {
+    flex-direction: column;
+    flex-grow: 1;
+    margin-top: 5px;
+    overflow: scroll;
+    max-height: 250px;
+}
+
+.route-option {
+    flex-direction: row;
+    background-color: rgba(40, 40, 40, 0.8);
+    border-width: 1px;
+    border-color: rgba(80, 80, 80, 0.5);
+    border-radius: 4px;
+    margin-bottom: 4px;
+    padding: 8px;
+    min-height: 70px;
+    cursor: link;
+    overflow: hidden;
+}
+
+.route-option:hover {
+    background-color: rgba(60, 60, 60, 0.9);
+    border-color: rgba(120, 120, 120, 0.8);
+}
+
+.route-selected {
+    background-color: rgba(34, 139, 34, 0.3) !important;
+    border-color: rgb(50, 180, 50) !important;
+    border-width: 2px !important;
+}
+
+.route-color-indicator {
+    width: 8px;
+    min-width: 8px;
+    margin-right: 10px;
+    border-radius: 4px;
+    background-color: rgb(100, 100, 100);
+    flex-shrink: 0;
+}
+
+.route-details {
+    flex-direction: column;
+    flex-grow: 1;
+    justify-content: flex-start;
+    overflow: hidden;
+}
+
+.route-header {
+    font-size: 13px;
+    -unity-font-style: bold;
+    color: rgb(220, 220, 220);
+    margin-bottom: 3px;
+    white-space: nowrap;
+    overflow: hidden;
+    text-overflow: ellipsis;
+}
+
+.route-time {
+    font-size: 11px;
+    color: rgb(180, 220, 180);
+    margin-bottom: 2px;
+    white-space: nowrap;
+}
+
+.route-cost {
+    font-size: 11px;
+    color: rgb(220, 180, 180);
+    margin-bottom: 2px;
+    white-space: nowrap;
+}
+
+.route-special {
+    font-size: 10px;
+    color: rgb(255, 200, 100);
+    -unity-font-style: italic;
+    white-space: normal;
+    overflow: hidden;
+}
+
+.route-debug {
+    font-size: 9px;
+    color: rgb(150, 150, 150);
+    -unity-font-style: italic;
+    margin-top: 2px;
+    white-space: nowrap;
+    overflow: hidden;
+}

+ 24 - 0
Assets/Resources/UI/Map/TravelUI.uxml

@@ -0,0 +1,24 @@
+<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" editor-extension-mode="False">
+    <Style src="project://database/Assets/UI/Map/TravelUI.uss?fileID=7433441132597879392&amp;guid=1e7ef30c959791b42ae6ef3a6741c9bd&amp;type=3#TravelUI" />
+    <ui:VisualElement name="TravelContainer" class="travel-container" style="display: none; visibility: visible;">
+        <ui:VisualElement name="TravelPanel" class="travel-panel">
+            <ui:VisualElement name="TravelHeader" class="travel-header">
+                <ui:Label text="Travel Planning" class="travel-title" />
+                <ui:Button text="×" name="CloseButton" class="close-button" />
+            </ui:VisualElement>
+            <ui:VisualElement name="TravelInfo" class="travel-info">
+                <ui:Label text="Distance: -- leagues" name="DistanceLabel" class="info-label" />
+                <ui:Label text="Travel Time: -- hours" name="TimeLabel" class="info-label" />
+                <ui:Label text="Special Costs: None" name="SpecialCostsLabel" class="info-label special-costs" />
+            </ui:VisualElement>
+            <ui:VisualElement name="RouteOptions" class="route-options">
+                <ui:Label text="Available Routes:" class="section-title" />
+                <ui:VisualElement name="RouteList" class="route-list" />
+            </ui:VisualElement>
+            <ui:VisualElement name="ButtonContainer" class="button-container">
+                <ui:Button text="Start Journey" name="StartTravelButton" class="travel-button primary-button" />
+                <ui:Button text="Cancel" name="CancelTravelButton" class="travel-button secondary-button" />
+            </ui:VisualElement>
+        </ui:VisualElement>
+    </ui:VisualElement>
+</ui:UXML>

+ 100 - 0
Assets/Resources/UI/MapLegend.uss

@@ -0,0 +1,100 @@
+.legend-container {
+    position: absolute;
+    top: 20px;
+    left: 20px;
+    background-color: rgba(0, 0, 0, 0.8);
+    border-radius: 10px;
+    padding: 15px;
+    min-width: 250px;
+    border-width: 2px;
+    border-color: rgba(255, 255, 255, 0.3);
+}
+
+.legend-title {
+    font-size: 18px;
+    color: white;
+    font-style: bold;
+    margin-bottom: 10px;
+    text-align: center;
+}
+
+.legend-items {
+    margin-bottom: 15px;
+}
+
+.legend-item {
+    flex-direction: row;
+    align-items: center;
+    margin-bottom: 5px;
+}
+
+.color-box {
+    width: 20px;
+    height: 20px;
+    margin-right: 10px;
+    border-radius: 3px;
+    border-width: 1px;
+    border-color: rgba(255, 255, 255, 0.5);
+}
+
+.legend-text {
+    color: white;
+    font-size: 14px;
+    flex-grow: 1;
+}
+
+.controls-info {
+    border-top-width: 1px;
+    border-top-color: rgba(255, 255, 255, 0.3);
+    padding-top: 10px;
+}
+
+.controls-title {
+    font-size: 16px;
+    color: white;
+    font-style: bold;
+    margin-bottom: 5px;
+}
+
+.controls-text {
+    color: rgba(255, 255, 255, 0.8);
+    font-size: 12px;
+    margin-bottom: 2px;
+}
+
+/* Color definitions matching your WorldMapGenerator colors */
+.ocean-color {
+    background-color: rgb(0, 0, 255); /* Blue */
+}
+
+.river-color {
+    background-color: rgb(0, 255, 255); /* Cyan */
+}
+
+.plain-color {
+    background-color: rgb(0, 128, 0); /* Green */
+}
+
+.forest-color {
+    background-color: rgb(51, 179, 51); /* Dark green (0.2, 0.7, 0.2) */
+}
+
+.mountain-color {
+    background-color: rgb(128, 128, 128); /* Gray */
+}
+
+.town-color {
+    background-color: rgb(204, 102, 51); /* Orange-brown (0.8, 0.4, 0.2) */
+}
+
+.village-color {
+    background-color: rgb(230, 179, 102); /* Light brown (0.9, 0.7, 0.4) */
+}
+
+.road-color {
+    background-color: rgb(153, 128, 77); /* Brown (0.6, 0.5, 0.3) */
+}
+
+.dock-color {
+    background-color: rgb(102, 77, 51); /* Dark brown (0.4, 0.3, 0.2) */
+}

+ 50 - 0
Assets/Resources/UI/MapLegend.uxml

@@ -0,0 +1,50 @@
+<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" editor-extension-mode="False">
+    <ui:VisualElement name="MapLegend" class="legend-container">
+        <ui:Label text="Map Legend" class="legend-title" />
+        <ui:VisualElement class="legend-items">
+            <ui:VisualElement class="legend-item">
+                <ui:VisualElement class="color-box ocean-color" />
+                <ui:Label text="Ocean / Large Water Bodies" class="legend-text" />
+            </ui:VisualElement>
+            <ui:VisualElement class="legend-item">
+                <ui:VisualElement class="color-box river-color" />
+                <ui:Label text="Rivers / Lakes" class="legend-text" />
+            </ui:VisualElement>
+            <ui:VisualElement class="legend-item">
+                <ui:VisualElement class="color-box plain-color" />
+                <ui:Label text="Plains / Grasslands" class="legend-text" />
+            </ui:VisualElement>
+            <ui:VisualElement class="legend-item">
+                <ui:VisualElement class="color-box forest-color" />
+                <ui:Label text="Forests" class="legend-text" />
+            </ui:VisualElement>
+            <ui:VisualElement class="legend-item">
+                <ui:VisualElement class="color-box mountain-color" />
+                <ui:Label text="Mountains" class="legend-text" />
+            </ui:VisualElement>
+            <ui:VisualElement class="legend-item">
+                <ui:VisualElement class="color-box town-color" />
+                <ui:Label text="Towns / Cities" class="legend-text" />
+            </ui:VisualElement>
+            <ui:VisualElement class="legend-item">
+                <ui:VisualElement class="color-box village-color" />
+                <ui:Label text="Villages" class="legend-text" />
+            </ui:VisualElement>
+            <ui:VisualElement class="legend-item">
+                <ui:VisualElement class="color-box road-color" />
+                <ui:Label text="Roads" class="legend-text" />
+            </ui:VisualElement>
+            <ui:VisualElement class="legend-item">
+                <ui:VisualElement class="color-box dock-color" />
+                <ui:Label text="Docks / Ports" class="legend-text" />
+            </ui:VisualElement>
+        </ui:VisualElement>
+        <ui:VisualElement class="controls-info">
+            <ui:Label text="Controls:" class="controls-title" />
+            <ui:Label text="WASD / Arrow Keys: Move Camera" class="controls-text" />
+            <ui:Label text="Mouse Wheel: Zoom In/Out" class="controls-text" />
+            <ui:Label text="N: Toggle Name Labels" class="controls-text" />
+            <ui:Label text="Mouse Hover: Show Tooltips" class="controls-text" />
+        </ui:VisualElement>
+    </ui:VisualElement>
+</ui:UXML>

+ 113 - 0
Assets/Resources/UI/MapScene/AdvancedTravelOptions.uss

@@ -0,0 +1,113 @@
+/* Advanced Travel Options Dialog Styles */
+
+.travel-option-item {
+    background-color: rgba(255, 255, 255, 0.9);
+    border-width: 1px;
+    border-color: rgb(200, 200, 200);
+    border-radius: 8px;
+    margin-bottom: 10px;
+    padding: 12px;
+    flex-direction: row;
+    align-items: center;
+    transition: background-color 0.2s;
+}
+
+.travel-option-item:hover {
+    background-color: rgba(230, 240, 255, 0.9);
+    border-color: rgb(100, 150, 200);
+}
+
+.travel-option-item.selected {
+    background-color: rgba(180, 220, 255, 0.9);
+    border-color: rgb(70, 130, 180);
+    border-width: 2px;
+}
+
+.option-radio {
+    width: 16px;
+    height: 16px;
+    border-width: 2px;
+    border-color: rgb(120, 120, 120);
+    border-radius: 50%;
+    margin-right: 12px;
+    background-color: white;
+}
+
+.option-radio.selected {
+    background-color: rgb(70, 130, 180);
+    border-color: rgb(70, 130, 180);
+}
+
+.option-details {
+    flex: 1;
+    flex-direction: column;
+}
+
+.option-name {
+    font-size: 16px;
+    font-weight: bold;
+    color: rgb(30, 30, 30);
+    margin-bottom: 4px;
+}
+
+.option-description {
+    font-size: 13px;
+    color: rgb(80, 80, 80);
+    white-space: normal;
+    margin-bottom: 6px;
+}
+
+.option-cost {
+    font-size: 14px;
+    font-weight: bold;
+    color: rgb(150, 100, 0);
+    text-align: right;
+    min-width: 100px;
+}
+
+.option-cost.affordable {
+    color: rgb(0, 120, 0);
+}
+
+.option-cost.expensive {
+    color: rgb(180, 70, 70);
+}
+
+.option-requirements {
+    font-size: 12px;
+    color: rgb(100, 100, 100);
+    font-style: italic;
+}
+
+.option-requirements.missing {
+    color: rgb(180, 70, 70);
+    font-weight: bold;
+}
+
+/* Tunnel specific styling */
+.tunnel-option {
+    border-left-width: 4px;
+    border-left-color: rgb(139, 69, 19);
+}
+
+/* Ferry specific styling */
+.ferry-option {
+    border-left-width: 4px;
+    border-left-color: rgb(65, 105, 225);
+}
+
+/* Standard route styling */
+.standard-option {
+    border-left-width: 4px;
+    border-left-color: rgb(34, 139, 34);
+}
+
+/* Animation for selection */
+.travel-option-item {
+    transition-property: background-color, border-color, transform;
+    transition-duration: 0.15s;
+}
+
+.travel-option-item:active {
+    transform: scale(0.98);
+}

+ 51 - 0
Assets/Resources/UI/MapScene/AdvancedTravelOptions.uxml

@@ -0,0 +1,51 @@
+<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" editor-extension-mode="False">
+    <ui:VisualElement name="advanced-travel-container" style="position: absolute; top: 100px; left: 300px; width: 500px; height: 400px; background-color: rgba(240, 240, 240, 0.95); border-width: 2px; border-color: rgb(100, 100, 100); padding: 20px;">
+        
+        <ui:VisualElement name="header-bar" style="flex-direction: row; margin-bottom: 15px;">
+            <ui:Label text="Special Travel Options" name="travel-options-title" style="font-size: 16px; flex-grow: 1;" />
+            <ui:Button text="X" name="close-button" style="width: 20px; height: 20px;" />
+        </ui:VisualElement>
+        
+        <ui:VisualElement name="route-comparison" style="background-color: rgba(200, 200, 200, 0.5); padding: 10px; margin-bottom: 15px;">
+            <ui:Label text="Route Comparison" style="font-size: 14px; margin-bottom: 10px;" />
+            <ui:VisualElement style="flex-direction: row;">
+                <ui:VisualElement style="flex: 1; margin-right: 10px;">
+                    <ui:Label text="Standard Route" style="font-size: 12px; margin-bottom: 5px;" />
+                    <ui:Label text="Distance: --" name="standard-distance" style="font-size: 11px;" />
+                    <ui:Label text="Time: --" name="standard-time" style="font-size: 11px;" />
+                    <ui:Label text="Cost: Free" name="standard-cost" style="font-size: 11px;" />
+                </ui:VisualElement>
+                <ui:VisualElement style="flex: 1; margin-left: 10px;">
+                    <ui:Label text="Special Route" style="font-size: 12px; margin-bottom: 5px;" />
+                    <ui:Label text="Distance: --" name="special-distance" style="font-size: 11px;" />
+                    <ui:Label text="Time: --" name="special-time" style="font-size: 11px;" />
+                    <ui:Label text="Cost: --" name="special-cost" style="font-size: 11px;" />
+                </ui:VisualElement>
+            </ui:VisualElement>
+            <ui:Label text="Time Saved: --" name="time-savings" style="font-size: 12px; margin-top: 10px;" />
+        </ui:VisualElement>
+        
+        <ui:VisualElement name="options-scroll" style="flex-grow: 1; margin-bottom: 15px; background-color: rgba(255, 255, 255, 0.8); padding: 10px;">
+            <ui:Label text="Available Options:" style="font-size: 12px; margin-bottom: 8px;" />
+            <ui:VisualElement name="options-container" style="flex-direction: column;">
+            </ui:VisualElement>
+        </ui:VisualElement>
+        
+        <ui:VisualElement name="resource-status" style="background-color: rgba(220, 220, 220, 0.8); padding: 10px; margin-bottom: 15px;">
+            <ui:Label text="Current Resources" style="font-size: 12px; margin-bottom: 8px;" />
+            <ui:VisualElement style="flex-direction: row;">
+                <ui:Label text="Gold: --" name="gold-label" style="font-size: 11px; flex: 1;" />
+                <ui:Label text="Torches: --" name="torch-label" style="font-size: 11px; flex: 1;" />
+                <ui:Label text="Status: --" name="affordability-label" style="font-size: 11px; flex: 1;" />
+            </ui:VisualElement>
+        </ui:VisualElement>
+        
+        <ui:VisualElement name="button-container" style="flex-direction: row;">
+            <ui:Button text="Use Special Route" name="confirm-button" style="flex: 1; margin-right: 5px;" />
+            <ui:Button text="Standard Route" name="standard-button" style="flex: 1; margin-left: 5px; margin-right: 5px;" />
+            <ui:Button text="Cancel" name="cancel-button" style="margin-left: 5px;" />
+        </ui:VisualElement>
+    </ui:VisualElement>
+</ui:UXML>
+    </ui:VisualElement>
+</ui:UXML>

+ 199 - 0
Assets/Resources/UI/MapScene/TeamOverview.uss

@@ -0,0 +1,199 @@
+/* Team Overview Panel Styles */
+.team-overview-container {
+    position: absolute;
+    top: 20px;
+    right: 20px;
+    bottom: 20px;
+    width: 350px;
+    max-width: 25%;
+    min-width: 300px;
+    background-color: rgba(240, 240, 240, 0.95);
+    border-width: 2px;
+    border-color: rgb(100, 100, 100);
+    border-radius: 10px;
+    padding: 15px;
+    flex-direction: column;
+    overflow: hidden;
+}
+
+.team-header {
+    flex-direction: column;
+    justify-content: flex-start;
+    align-items: stretch;
+    margin-bottom: 15px;
+    padding-bottom: 10px;
+    border-bottom-width: 1px;
+    border-bottom-color: rgb(180, 180, 180);
+    flex-shrink: 0;
+}
+
+.header-buttons {
+    flex-direction: row;
+    justify-content: space-between;
+    margin-top: 8px;
+    gap: 8px;
+}
+
+.team-title {
+    font-size: 18px;
+    font-weight: bold;
+    color: rgb(50, 50, 50);
+    margin-bottom: 5px;
+}
+
+.nav-button {
+    background-color: rgb(70, 130, 180);
+    color: white;
+    border-width: 0;
+    border-radius: 5px;
+    padding: 6px 10px;
+    font-size: 11px;
+    flex: 1;
+    margin: 0 2px;
+}
+
+.nav-button:hover {
+    background-color: rgb(90, 150, 200);
+}
+
+.team-members-scroll {
+    flex-grow: 1;
+    flex-shrink: 1;
+    margin-bottom: 15px;
+    min-height: 200px;
+    overflow: hidden;
+}
+
+.team-stats {
+    background-color: rgba(250, 250, 250, 0.9);
+    border-width: 1px;
+    border-color: rgb(180, 180, 180);
+    border-radius: 6px;
+    padding: 10px;
+    flex-shrink: 0;
+    margin-top: auto;
+}
+
+.team-member-card {
+    background-color: rgba(255, 255, 255, 0.8);
+    border-width: 1px;
+    border-color: rgb(200, 200, 200);
+    border-radius: 8px;
+    margin-bottom: 10px;
+    padding: 12px;
+    flex-direction: column;
+}
+
+.member-name {
+    font-size: 16px;
+    font-weight: bold;
+    color: rgb(30, 30, 30);
+    margin-bottom: 8px;
+}
+
+.member-stats {
+    flex-direction: row;
+    flex-wrap: wrap;
+    justify-content: space-between;
+}
+
+.stat-item {
+    flex-direction: row;
+    margin-bottom: 4px;
+    min-width: 80px;
+}
+
+.stat-name {
+    font-size: 12px;
+    color: rgb(80, 80, 80);
+    min-width: 40px;
+}
+
+.stat-value {
+    font-size: 12px;
+    font-weight: bold;
+    color: rgb(20, 20, 20);
+}
+
+.member-equipment {
+    margin-top: 8px;
+    padding-top: 8px;
+    border-top-width: 1px;
+    border-top-color: rgb(220, 220, 220);
+}
+
+.equipment-title {
+    font-size: 12px;
+    font-weight: bold;
+    color: rgb(60, 60, 60);
+    margin-bottom: 4px;
+}
+
+.equipment-list {
+    font-size: 11px;
+    color: rgb(100, 100, 100);
+    white-space: normal;
+}
+
+.stats-title {
+    font-size: 14px;
+    font-weight: bold;
+    color: rgb(40, 40, 40);
+    margin-bottom: 8px;
+}
+
+.stats-row {
+    flex-direction: row;
+    justify-content: space-between;
+    margin-bottom: 4px;
+}
+
+.stat-label {
+    font-size: 12px;
+    color: rgb(80, 80, 80);
+}
+
+.stat-value {
+    font-size: 12px;
+    font-weight: bold;
+    color: rgb(20, 20, 20);
+}
+
+/* Responsive adjustments */
+@media (max-height: 600px) {
+    .team-overview-container {
+        top: 10px;
+        bottom: 10px;
+        right: 10px;
+        width: 300px;
+        min-width: 280px;
+        font-size: 90%;
+        padding: 10px;
+    }
+    
+    .team-members-scroll {
+        min-height: 150px;
+    }
+    
+    .nav-button {
+        font-size: 10px;
+        padding: 4px 8px;
+    }
+}
+
+@media (max-width: 1200px) {
+    .team-overview-container {
+        width: 280px;
+        min-width: 260px;
+        right: 10px;
+    }
+}
+
+/* Ensure proper scrolling behavior */
+.team-members-scroll > .unity-scroll-view__content-container {
+    flex-grow: 1;
+}
+
+.team-members-scroll .unity-scroller--vertical {
+    width: 10px;
+}

+ 33 - 0
Assets/Resources/UI/MapScene/TeamOverview.uxml

@@ -0,0 +1,33 @@
+<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" editor-extension-mode="False">
+    <Style src="project://database/Assets/UI/MapScene/TeamOverview.uss?fileID=7433441132597879392&amp;guid=PLACEHOLDER&amp;type=3#TeamOverview" />
+    
+    <ui:VisualElement name="TeamOverviewPanel" class="team-overview-container">
+        <ui:VisualElement name="Header" class="team-header">
+            <ui:Label text="Your Team" class="team-title" />
+            <ui:VisualElement name="HeaderButtons" class="header-buttons">
+                <ui:Button text="Manage Team" name="ManageTeamButton" class="nav-button secondary-button" />
+                <ui:Button text="Save Game" name="SaveGameButton" class="nav-button primary-button" />
+            </ui:VisualElement>
+        </ui:VisualElement>
+        
+        <ui:ScrollView name="TeamMembersList" class="team-members-scroll">
+            <!-- Team members will be added dynamically -->
+        </ui:ScrollView>
+        
+        <ui:VisualElement name="TeamStats" class="team-stats">
+            <ui:Label text="Team Summary" class="stats-title" />
+            <ui:VisualElement class="stats-row">
+                <ui:Label text="Members: " class="stat-label" />
+                <ui:Label text="0" name="MemberCountLabel" class="stat-value" />
+            </ui:VisualElement>
+            <ui:VisualElement class="stats-row">
+                <ui:Label text="Total Gold: " class="stat-label" />
+                <ui:Label text="0" name="TotalGoldLabel" class="stat-value" />
+            </ui:VisualElement>
+            <ui:VisualElement class="stats-row">
+                <ui:Label text="Avg Level: " class="stat-label" />
+                <ui:Label text="1" name="AverageLevelLabel" class="stat-value" />
+            </ui:VisualElement>
+        </ui:VisualElement>
+    </ui:VisualElement>
+</ui:UXML>

+ 20 - 0
Assets/Resources/UI/TravelPanelSettings.asset

@@ -0,0 +1,20 @@
+%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: 19102, guid: 0000000000000000e000000000000000, type: 0}
+  m_Name: TravelPanelSettings
+  themeUss: {fileID: -4733365628477956816, guid: 0000000000000000f000000000000000, type: 0}
+  targetTexture: {fileID: 0}
+  scaleMode: 1
+  scale: 1
+  fallbackDpi: 96
+  referenceDpi: 96
+  sortingOrder: 0

BIN
Assets/SceneTemplateAssets/Common/Models/UnityMaterialBall.fbx


+ 1545 - 0
Assets/Scenes/BattleScene.unity

@@ -0,0 +1,1545 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!29 &1
+OcclusionCullingSettings:
+  m_ObjectHideFlags: 0
+  serializedVersion: 2
+  m_OcclusionBakeSettings:
+    smallestOccluder: 5
+    smallestHole: 0.25
+    backfaceThreshold: 100
+  m_SceneGUID: 00000000000000000000000000000000
+  m_OcclusionCullingData: {fileID: 0}
+--- !u!104 &2
+RenderSettings:
+  m_ObjectHideFlags: 0
+  serializedVersion: 10
+  m_Fog: 0
+  m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1}
+  m_FogMode: 3
+  m_FogDensity: 0.01
+  m_LinearFogStart: 0
+  m_LinearFogEnd: 300
+  m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1}
+  m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1}
+  m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1}
+  m_AmbientIntensity: 1
+  m_AmbientMode: 0
+  m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1}
+  m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0}
+  m_HaloStrength: 0.5
+  m_FlareStrength: 1
+  m_FlareFadeSpeed: 3
+  m_HaloTexture: {fileID: 0}
+  m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0}
+  m_DefaultReflectionMode: 0
+  m_DefaultReflectionResolution: 128
+  m_ReflectionBounces: 1
+  m_ReflectionIntensity: 1
+  m_CustomReflection: {fileID: 0}
+  m_Sun: {fileID: 0}
+  m_UseRadianceAmbientProbe: 0
+--- !u!157 &3
+LightmapSettings:
+  m_ObjectHideFlags: 0
+  serializedVersion: 13
+  m_BakeOnSceneLoad: 0
+  m_GISettings:
+    serializedVersion: 2
+    m_BounceScale: 1
+    m_IndirectOutputScale: 1
+    m_AlbedoBoost: 1
+    m_EnvironmentLightingMode: 0
+    m_EnableBakedLightmaps: 1
+    m_EnableRealtimeLightmaps: 0
+  m_LightmapEditorSettings:
+    serializedVersion: 12
+    m_Resolution: 2
+    m_BakeResolution: 40
+    m_AtlasSize: 1024
+    m_AO: 0
+    m_AOMaxDistance: 1
+    m_CompAOExponent: 1
+    m_CompAOExponentDirect: 0
+    m_ExtractAmbientOcclusion: 0
+    m_Padding: 2
+    m_LightmapParameters: {fileID: 0}
+    m_LightmapsBakeMode: 1
+    m_TextureCompression: 1
+    m_ReflectionCompression: 2
+    m_MixedBakeMode: 2
+    m_BakeBackend: 1
+    m_PVRSampling: 1
+    m_PVRDirectSampleCount: 32
+    m_PVRSampleCount: 512
+    m_PVRBounces: 2
+    m_PVREnvironmentSampleCount: 256
+    m_PVREnvironmentReferencePointCount: 2048
+    m_PVRFilteringMode: 1
+    m_PVRDenoiserTypeDirect: 1
+    m_PVRDenoiserTypeIndirect: 1
+    m_PVRDenoiserTypeAO: 1
+    m_PVRFilterTypeDirect: 0
+    m_PVRFilterTypeIndirect: 0
+    m_PVRFilterTypeAO: 0
+    m_PVREnvironmentMIS: 1
+    m_PVRCulling: 1
+    m_PVRFilteringGaussRadiusDirect: 1
+    m_PVRFilteringGaussRadiusIndirect: 5
+    m_PVRFilteringGaussRadiusAO: 2
+    m_PVRFilteringAtrousPositionSigmaDirect: 0.5
+    m_PVRFilteringAtrousPositionSigmaIndirect: 2
+    m_PVRFilteringAtrousPositionSigmaAO: 1
+    m_ExportTrainingData: 0
+    m_TrainingDataDestination: TrainingData
+    m_LightProbeSampleCountMultiplier: 4
+  m_LightingDataAsset: {fileID: 20201, guid: 0000000000000000f000000000000000, type: 0}
+  m_LightingSettings: {fileID: 0}
+--- !u!196 &4
+NavMeshSettings:
+  serializedVersion: 2
+  m_ObjectHideFlags: 0
+  m_BuildSettings:
+    serializedVersion: 3
+    agentTypeID: 0
+    agentRadius: 0.5
+    agentHeight: 2
+    agentSlope: 45
+    agentClimb: 0.4
+    ledgeDropHeight: 0
+    maxJumpAcrossDistance: 0
+    minRegionArea: 2
+    manualCellSize: 0
+    cellSize: 0.16666667
+    manualTileSize: 0
+    tileSize: 256
+    buildHeightMesh: 0
+    maxJobWorkers: 0
+    preserveTilesOutsideBounds: 0
+    debug:
+      m_Flags: 0
+  m_NavMeshData: {fileID: 0}
+--- !u!1 &330585543
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 330585546}
+  - component: {fileID: 330585545}
+  - component: {fileID: 330585544}
+  - component: {fileID: 330585547}
+  - component: {fileID: 330585548}
+  m_Layer: 0
+  m_Name: Main Camera
+  m_TagString: MainCamera
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!81 &330585544
+AudioListener:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 330585543}
+  m_Enabled: 1
+--- !u!20 &330585545
+Camera:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 330585543}
+  m_Enabled: 1
+  serializedVersion: 2
+  m_ClearFlags: 1
+  m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0}
+  m_projectionMatrixMode: 1
+  m_GateFitMode: 2
+  m_FOVAxisMode: 0
+  m_Iso: 200
+  m_ShutterSpeed: 0.005
+  m_Aperture: 16
+  m_FocusDistance: 10
+  m_FocalLength: 50
+  m_BladeCount: 5
+  m_Curvature: {x: 2, y: 11}
+  m_BarrelClipping: 0.25
+  m_Anamorphism: 0
+  m_SensorSize: {x: 36, y: 24}
+  m_LensShift: {x: 0, y: 0}
+  m_NormalizedViewPortRect:
+    serializedVersion: 2
+    x: 0
+    y: 0
+    width: 1
+    height: 1
+  near clip plane: 0.3
+  far clip plane: 1000
+  field of view: 71.193375
+  orthographic: 0
+  orthographic size: 5
+  m_Depth: -1
+  m_CullingMask:
+    serializedVersion: 2
+    m_Bits: 4294967295
+  m_RenderingPath: -1
+  m_TargetTexture: {fileID: 0}
+  m_TargetDisplay: 0
+  m_TargetEye: 3
+  m_HDR: 1
+  m_AllowMSAA: 1
+  m_AllowDynamicResolution: 0
+  m_ForceIntoRT: 0
+  m_OcclusionCulling: 1
+  m_StereoConvergence: 10
+  m_StereoSeparation: 0.022
+--- !u!4 &330585546
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 330585543}
+  serializedVersion: 2
+  m_LocalRotation: {x: 0.38268343, y: 0, z: 0, w: 0.92387956}
+  m_LocalPosition: {x: -25.424297, y: 20.747517, z: -31.685192}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_ConstrainProportionsScale: 0
+  m_Children: []
+  m_Father: {fileID: 1429499005}
+  m_LocalEulerAnglesHint: {x: 45, y: 0, z: 0}
+--- !u!114 &330585547
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 330585543}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: a79441f348de89743a2939f4d699eac1, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_RenderShadows: 1
+  m_RequiresDepthTextureOption: 2
+  m_RequiresOpaqueTextureOption: 2
+  m_CameraType: 0
+  m_Cameras: []
+  m_RendererIndex: -1
+  m_VolumeLayerMask:
+    serializedVersion: 2
+    m_Bits: 1
+  m_VolumeTrigger: {fileID: 0}
+  m_VolumeFrameworkUpdateModeOption: 2
+  m_RenderPostProcessing: 1
+  m_Antialiasing: 0
+  m_AntialiasingQuality: 2
+  m_StopNaN: 0
+  m_Dithering: 0
+  m_ClearDepth: 1
+  m_AllowXRRendering: 1
+  m_AllowHDROutput: 1
+  m_UseScreenCoordOverride: 0
+  m_ScreenSizeOverride: {x: 0, y: 0, z: 0, w: 0}
+  m_ScreenCoordScaleBias: {x: 0, y: 0, z: 0, w: 0}
+  m_RequiresDepthTexture: 0
+  m_RequiresColorTexture: 0
+  m_Version: 2
+  m_TaaSettings:
+    m_Quality: 3
+    m_FrameInfluence: 0.1
+    m_JitterScale: 1
+    m_MipBias: 0
+    m_VarianceClampScale: 0.9
+    m_ContrastAdaptiveSharpening: 0
+--- !u!114 &330585548
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 330585543}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 72ece51f2901e7445ab60da3685d6b5f, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  ShowDebugText: 0
+  ShowCameraFrustum: 1
+  IgnoreTimeScale: 0
+  WorldUpOverride: {fileID: 0}
+  ChannelMask: -1
+  UpdateMethod: 2
+  BlendUpdateMethod: 1
+  LensModeOverride:
+    Enabled: 0
+    DefaultMode: 2
+  DefaultBlend:
+    Style: 1
+    Time: 2
+    CustomCurve:
+      serializedVersion: 2
+      m_Curve: []
+      m_PreInfinity: 2
+      m_PostInfinity: 2
+      m_RotationOrder: 4
+  CustomBlends: {fileID: 0}
+--- !u!1 &398559097
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 398559099}
+  - component: {fileID: 398559100}
+  m_Layer: 0
+  m_Name: TurnManager
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!4 &398559099
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 398559097}
+  serializedVersion: 2
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: -0.76332283, y: 1.7029114, z: -0.2880888}
+  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 &398559100
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 398559097}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 4bb06d7192968c74fa9f5c4f48c9ba37, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+--- !u!1 &410087039
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 410087041}
+  - component: {fileID: 410087040}
+  - component: {fileID: 410087042}
+  m_Layer: 0
+  m_Name: Directional Light
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!108 &410087040
+Light:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 410087039}
+  m_Enabled: 1
+  serializedVersion: 11
+  m_Type: 1
+  m_Color: {r: 1, g: 1, b: 1, a: 1}
+  m_Intensity: 2
+  m_Range: 10
+  m_SpotAngle: 30
+  m_InnerSpotAngle: 21.80208
+  m_CookieSize: 10
+  m_Shadows:
+    m_Type: 2
+    m_Resolution: -1
+    m_CustomResolution: -1
+    m_Strength: 1
+    m_Bias: 0.05
+    m_NormalBias: 0.4
+    m_NearPlane: 0.2
+    m_CullingMatrixOverride:
+      e00: 1
+      e01: 0
+      e02: 0
+      e03: 0
+      e10: 0
+      e11: 1
+      e12: 0
+      e13: 0
+      e20: 0
+      e21: 0
+      e22: 1
+      e23: 0
+      e30: 0
+      e31: 0
+      e32: 0
+      e33: 1
+    m_UseCullingMatrixOverride: 0
+  m_Cookie: {fileID: 0}
+  m_DrawHalo: 0
+  m_Flare: {fileID: 0}
+  m_RenderMode: 0
+  m_CullingMask:
+    serializedVersion: 2
+    m_Bits: 4294967295
+  m_RenderingLayerMask: 1
+  m_Lightmapping: 4
+  m_LightShadowCasterMode: 0
+  m_AreaSize: {x: 1, y: 1}
+  m_BounceIntensity: 1
+  m_ColorTemperature: 5000
+  m_UseColorTemperature: 1
+  m_BoundingSphereOverride: {x: 0, y: 0, z: 0, w: 0}
+  m_UseBoundingSphereOverride: 0
+  m_UseViewFrustumForShadowCasterCull: 1
+  m_ForceVisible: 0
+  m_ShadowRadius: 0
+  m_ShadowAngle: 0
+  m_LightUnit: 1
+  m_LuxAtDistance: 1
+  m_EnableSpotReflector: 1
+--- !u!4 &410087041
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 410087039}
+  serializedVersion: 2
+  m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261}
+  m_LocalPosition: {x: 0, y: 3, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_ConstrainProportionsScale: 0
+  m_Children: []
+  m_Father: {fileID: 0}
+  m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0}
+--- !u!114 &410087042
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 410087039}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 474bcb49853aa07438625e644c072ee6, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Version: 3
+  m_UsePipelineSettings: 1
+  m_AdditionalLightsShadowResolutionTier: 2
+  m_LightLayerMask: 1
+  m_RenderingLayers: 1
+  m_CustomShadowLayers: 0
+  m_ShadowLayerMask: 1
+  m_ShadowRenderingLayers: 1
+  m_LightCookieSize: {x: 1, y: 1}
+  m_LightCookieOffset: {x: 0, y: 0}
+  m_SoftShadowQuality: 1
+--- !u!1 &457742899
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 457742904}
+  - component: {fileID: 457742903}
+  - component: {fileID: 457742902}
+  - component: {fileID: 457742901}
+  - component: {fileID: 457742900}
+  - component: {fileID: 457742905}
+  m_Layer: 5
+  m_Name: MainUiCanvas
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!114 &457742900
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 457742899}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 19102, guid: 0000000000000000e000000000000000, type: 0}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_PanelSettings: {fileID: 11400000, guid: 0d7125098b341c74d868b72a1bacddf4, type: 2}
+  m_ParentUI: {fileID: 0}
+  sourceAsset: {fileID: 9197481963319205126, guid: e4fa942782ed98d43af21b5e5ca2c48a, type: 3}
+  m_SortingOrder: 0
+  m_WorldSpaceSizeMode: 1
+  m_WorldSpaceWidth: 1920
+  m_WorldSpaceHeight: 1080
+--- !u!114 &457742901
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 457742899}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: dc42784cf147c0c48a680349fa168899, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_IgnoreReversedGraphics: 1
+  m_BlockingObjects: 0
+  m_BlockingMask:
+    serializedVersion: 2
+    m_Bits: 4294967295
+--- !u!114 &457742902
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 457742899}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 0cd44c1031e13a943bb63640046fad76, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_UiScaleMode: 0
+  m_ReferencePixelsPerUnit: 100
+  m_ScaleFactor: 1
+  m_ReferenceResolution: {x: 800, y: 600}
+  m_ScreenMatchMode: 0
+  m_MatchWidthOrHeight: 0
+  m_PhysicalUnit: 3
+  m_FallbackScreenDPI: 96
+  m_DefaultSpriteDPI: 96
+  m_DynamicPixelsPerUnit: 1
+  m_PresetInfoIsWorld: 0
+--- !u!223 &457742903
+Canvas:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 457742899}
+  m_Enabled: 1
+  serializedVersion: 3
+  m_RenderMode: 1
+  m_Camera: {fileID: 330585545}
+  m_PlaneDistance: 100
+  m_PixelPerfect: 0
+  m_ReceivesEvents: 1
+  m_OverrideSorting: 0
+  m_OverridePixelPerfect: 0
+  m_SortingBucketNormalizedSize: 0
+  m_VertexColorAlwaysGammaSpace: 1
+  m_AdditionalShaderChannelsFlag: 0
+  m_UpdateRectTransformForStandalone: 0
+  m_SortingLayerID: 0
+  m_SortingOrder: 0
+  m_TargetDisplay: 0
+--- !u!224 &457742904
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 457742899}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 0, y: 0, z: 0}
+  m_ConstrainProportionsScale: 0
+  m_Children: []
+  m_Father: {fileID: 0}
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0, y: 0}
+  m_AnchorMax: {x: 0, y: 0}
+  m_AnchoredPosition: {x: 0, y: 0}
+  m_SizeDelta: {x: 0, y: 0}
+  m_Pivot: {x: 0, y: 0}
+--- !u!114 &457742905
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 457742899}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: e406ef1698b9b164bbd0a0617db3a6ca, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  uiDocument: {fileID: 457742900}
+--- !u!1 &631973767
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 631973769}
+  - component: {fileID: 631973768}
+  m_Layer: 0
+  m_Name: GameManager
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!114 &631973768
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 631973767}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 3c7e0c6e79705ce4090a432ced54ad1c, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  playerCharacters: []
+  enemyCharacters: []
+  playerDecisionController: {fileID: 0}
+  isContinuousRunActive: 0
+--- !u!4 &631973769
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 631973767}
+  serializedVersion: 2
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_ConstrainProportionsScale: 0
+  m_Children: []
+  m_Father: {fileID: 0}
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!1 &754193781
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 754193783}
+  - component: {fileID: 754193782}
+  m_Layer: 0
+  m_Name: BattleSetupManager
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!114 &754193782
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 754193781}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: be1e294acd4e3794c9f5881de5ea0530, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  playerCharacters:
+  - {fileID: 1880288660700002030, guid: 38ed18f91946ed64494b472036469aa6, type: 3}
+  - {fileID: 1880288660700002030, guid: 38ed18f91946ed64494b472036469aa6, type: 3}
+  enemyCharacters:
+  - {fileID: 1880288660700002030, guid: 99900445755b7ea45b9e778888a1023c, type: 3}
+  - {fileID: 1880288660700002030, guid: 99900445755b7ea45b9e778888a1023c, type: 3}
+  groundLayerMask:
+    serializedVersion: 2
+    m_Bits: 256
+  playerPrefab: {fileID: 1880288660700002030, guid: 38ed18f91946ed64494b472036469aa6, type: 3}
+  enemyPrefab: {fileID: 1880288660700002030, guid: 99900445755b7ea45b9e778888a1023c, type: 3}
+  SwordPrefab: {fileID: 5410050047777400374, guid: 2e07955f8c531dc4ea65c9d6a521f306, type: 3}
+  BowPrefab: {fileID: 5410050047777400374, guid: e0447dc7b412ede4b9090f9a3cf4fdd4, type: 3}
+--- !u!4 &754193783
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 754193781}
+  serializedVersion: 2
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_ConstrainProportionsScale: 0
+  m_Children: []
+  m_Father: {fileID: 0}
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!1 &832575517
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 832575519}
+  - component: {fileID: 832575518}
+  m_Layer: 0
+  m_Name: Global Volume
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!114 &832575518
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 832575517}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 172515602e62fb746b5d573b38a5fe58, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_IsGlobal: 1
+  priority: 0
+  blendDistance: 0
+  weight: 1
+  sharedProfile: {fileID: 11400000, guid: 10fc4df2da32a41aaa32d77bc913491c, type: 2}
+--- !u!4 &832575519
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 832575517}
+  serializedVersion: 2
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_ConstrainProportionsScale: 0
+  m_Children: []
+  m_Father: {fileID: 0}
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!1 &848956332
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 848956333}
+  - component: {fileID: 848956336}
+  - component: {fileID: 848956335}
+  - component: {fileID: 848956334}
+  m_Layer: 0
+  m_Name: EnemySpawnArea
+  m_TagString: EnemySpawnArea
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!4 &848956333
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 848956332}
+  serializedVersion: 2
+  m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 10.54}
+  m_LocalScale: {x: 25.0416, y: 3.1302, z: 6}
+  m_ConstrainProportionsScale: 0
+  m_Children: []
+  m_Father: {fileID: 0}
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!65 &848956334
+BoxCollider:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 848956332}
+  m_Material: {fileID: 0}
+  m_IncludeLayers:
+    serializedVersion: 2
+    m_Bits: 0
+  m_ExcludeLayers:
+    serializedVersion: 2
+    m_Bits: 0
+  m_LayerOverridePriority: 0
+  m_IsTrigger: 0
+  m_ProvidesContacts: 0
+  m_Enabled: 1
+  serializedVersion: 3
+  m_Size: {x: 1, y: 1, z: 1}
+  m_Center: {x: 0, y: 0, z: 0}
+--- !u!23 &848956335
+MeshRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 848956332}
+  m_Enabled: 1
+  m_CastShadows: 1
+  m_ReceiveShadows: 1
+  m_DynamicOccludee: 1
+  m_StaticShadowCaster: 0
+  m_MotionVectors: 1
+  m_LightProbeUsage: 1
+  m_ReflectionProbeUsage: 1
+  m_RayTracingMode: 2
+  m_RayTraceProcedural: 0
+  m_RayTracingAccelStructBuildFlagsOverride: 0
+  m_RayTracingAccelStructBuildFlags: 1
+  m_SmallMeshCulling: 1
+  m_RenderingLayerMask: 1
+  m_RendererPriority: 0
+  m_Materials:
+  - {fileID: 2100000, guid: cf0ec6ceb5308b141bfc478928b72231, type: 2}
+  m_StaticBatchInfo:
+    firstSubMesh: 0
+    subMeshCount: 0
+  m_StaticBatchRoot: {fileID: 0}
+  m_ProbeAnchor: {fileID: 0}
+  m_LightProbeVolumeOverride: {fileID: 0}
+  m_ScaleInLightmap: 1
+  m_ReceiveGI: 1
+  m_PreserveUVs: 0
+  m_IgnoreNormalsForChartDetection: 0
+  m_ImportantGI: 0
+  m_StitchLightmapSeams: 1
+  m_SelectedEditorRenderState: 3
+  m_MinimumChartSize: 4
+  m_AutoUVMaxDistance: 0.5
+  m_AutoUVMaxAngle: 89
+  m_LightmapParameters: {fileID: 0}
+  m_SortingLayerID: 0
+  m_SortingLayer: 0
+  m_SortingOrder: 0
+  m_AdditionalVertexStreams: {fileID: 0}
+--- !u!33 &848956336
+MeshFilter:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 848956332}
+  m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
+--- !u!1 &864824015
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 864824021}
+  - component: {fileID: 864824016}
+  - component: {fileID: 864824020}
+  - component: {fileID: 864824019}
+  - component: {fileID: 864824018}
+  - component: {fileID: 864824017}
+  m_Layer: 0
+  m_Name: ActionCam
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!114 &864824016
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 864824015}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: f9dfa5b682dcd46bda6128250e975f58, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  Priority:
+    Enabled: 0
+    m_Value: 0
+  OutputChannel: 1
+  StandbyUpdate: 2
+  m_StreamingVersion: 20241001
+  m_LegacyPriority: 0
+  Target:
+    TrackingTarget: {fileID: 0}
+    LookAtTarget: {fileID: 0}
+    CustomLookAtTarget: 0
+  Lens:
+    FieldOfView: 71.193375
+    OrthographicSize: 5
+    NearClipPlane: 0.3
+    FarClipPlane: 1000
+    Dutch: 0
+    ModeOverride: 0
+    PhysicalProperties:
+      GateFit: 2
+      SensorSize: {x: 21.946, y: 16.002}
+      LensShift: {x: 0, y: 0}
+      FocusDistance: 10
+      Iso: 200
+      ShutterSpeed: 0.005
+      Aperture: 16
+      BladeCount: 5
+      Curvature: {x: 2, y: 11}
+      BarrelClipping: 0.25
+      Anamorphism: 0
+  BlendHint: 0
+--- !u!114 &864824017
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 864824015}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 89875cdc57c54474a8a74efd9b2a3b5d, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  ScanRecursively: 1
+  SuppressInputWhileBlending: 1
+  IgnoreTimeScale: 0
+  m_ControllerManager:
+    Controllers:
+    - Name: Look Orbit X
+      Owner: {fileID: 864824020}
+      Enabled: 1
+      Input:
+        InputAction: {fileID: -5630151704836100654, guid: 1d6e640e716dc4ff6989b73d02023f2b, type: 3}
+        Gain: 1
+        LegacyInput: 
+        LegacyGain: 1
+        CancelDeltaTime: 0
+      InputValue: 0
+      Driver:
+        AccelTime: 0.2
+        DecelTime: 0.2
+    - Name: Look Orbit Y
+      Owner: {fileID: 864824020}
+      Enabled: 1
+      Input:
+        InputAction: {fileID: -5630151704836100654, guid: 1d6e640e716dc4ff6989b73d02023f2b, type: 3}
+        Gain: -1
+        LegacyInput: 
+        LegacyGain: 1
+        CancelDeltaTime: 0
+      InputValue: 0
+      Driver:
+        AccelTime: 0.2
+        DecelTime: 0.2
+    - Name: Orbit Scale
+      Owner: {fileID: 864824020}
+      Enabled: 1
+      Input:
+        InputAction: {fileID: 5082991133974614888, guid: 1d6e640e716dc4ff6989b73d02023f2b, type: 3}
+        Gain: -1
+        LegacyInput: 
+        LegacyGain: 1
+        CancelDeltaTime: 0
+      InputValue: 0
+      Driver:
+        AccelTime: 0
+        DecelTime: 0
+  PlayerIndex: -1
+  AutoEnableInputs: 1
+--- !u!114 &864824018
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 864824015}
+  m_Enabled: 0
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: a076c17fe76165e4f8ed21498b877bf9, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  Easing: 0
+  Modifiers: []
+  references:
+    version: 2
+    RefIds: []
+--- !u!114 &864824019
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 864824015}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: f38bda98361e1de48a4ca2bd86ea3c17, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  Composition:
+    ScreenPosition: {x: 0, y: 0}
+    DeadZone:
+      Enabled: 0
+      Size: {x: 0.2, y: 0.2}
+    HardLimits:
+      Enabled: 0
+      Size: {x: 0.8, y: 0.8}
+      Offset: {x: 0, y: 0}
+  CenterOnActivate: 1
+  TargetOffset: {x: 0, y: 0, z: 0}
+  Damping: {x: 0.5, y: 0.5}
+  Lookahead:
+    Enabled: 0
+    Time: 0
+    Smoothing: 0
+    IgnoreY: 0
+--- !u!114 &864824020
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 864824015}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 3b5d7c088409d9a40b7b09aa707777f8, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  TargetOffset: {x: 0, y: 0, z: 0}
+  TrackerSettings:
+    BindingMode: 4
+    PositionDamping: {x: 1, y: 1, z: 1}
+    AngularDampingMode: 0
+    RotationDamping: {x: 1, y: 1, z: 1}
+    QuaternionDamping: 1
+  OrbitStyle: 1
+  Radius: 10
+  Orbits:
+    Top:
+      Radius: 2
+      Height: 5
+    Center:
+      Radius: 4
+      Height: 2.25
+    Bottom:
+      Radius: 2.5
+      Height: 0.1
+    SplineCurvature: 0.5
+  RecenteringTarget: 2
+  HorizontalAxis:
+    Value: 0
+    Center: 0
+    Range: {x: -180, y: 180}
+    Wrap: 1
+    Recentering:
+      Enabled: 0
+      Wait: 1
+      Time: 2
+    Restrictions: 0
+  VerticalAxis:
+    Value: 17.5
+    Center: 17.5
+    Range: {x: -10, y: 45}
+    Wrap: 0
+    Recentering:
+      Enabled: 0
+      Wait: 1
+      Time: 2
+    Restrictions: 0
+  RadialAxis:
+    Value: 1
+    Center: 1
+    Range: {x: 1, y: 1}
+    Wrap: 0
+    Recentering:
+      Enabled: 0
+      Wait: 1
+      Time: 2
+    Restrictions: 0
+--- !u!4 &864824021
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 864824015}
+  serializedVersion: 2
+  m_LocalRotation: {x: 0.38268343, y: 0, z: 0, w: 0.92387956}
+  m_LocalPosition: {x: 0, y: 25, z: -20.8}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_ConstrainProportionsScale: 0
+  m_Children: []
+  m_Father: {fileID: 0}
+  m_LocalEulerAnglesHint: {x: 45, y: 0, z: 0}
+--- !u!1 &865903346
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 865903348}
+  - component: {fileID: 865903347}
+  m_Layer: 0
+  m_Name: CameraManager
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!114 &865903347
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 865903346}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: b00315647cc819348b58a947689d798b, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  actionCam: {fileID: 864824016}
+  groundPlane: {fileID: 1052169193}
+  minZoom: 15
+  maxZoom: 80
+  zoomSpeed: 10
+  panSpeed: 30
+  cameraAngle: 60
+--- !u!4 &865903348
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 865903346}
+  serializedVersion: 2
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_ConstrainProportionsScale: 0
+  m_Children: []
+  m_Father: {fileID: 0}
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!1 &1052169193
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 1052169197}
+  - component: {fileID: 1052169196}
+  - component: {fileID: 1052169195}
+  - component: {fileID: 1052169198}
+  - component: {fileID: 1052169199}
+  m_Layer: 8
+  m_Name: GroundPlane
+  m_TagString: ground
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!23 &1052169195
+MeshRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1052169193}
+  m_Enabled: 1
+  m_CastShadows: 1
+  m_ReceiveShadows: 1
+  m_DynamicOccludee: 1
+  m_StaticShadowCaster: 0
+  m_MotionVectors: 1
+  m_LightProbeUsage: 1
+  m_ReflectionProbeUsage: 1
+  m_RayTracingMode: 2
+  m_RayTraceProcedural: 0
+  m_RayTracingAccelStructBuildFlagsOverride: 0
+  m_RayTracingAccelStructBuildFlags: 1
+  m_SmallMeshCulling: 1
+  m_RenderingLayerMask: 1
+  m_RendererPriority: 0
+  m_Materials:
+  - {fileID: 2100000, guid: 31321ba15b8f8eb4c954353edc038b1d, type: 2}
+  m_StaticBatchInfo:
+    firstSubMesh: 0
+    subMeshCount: 0
+  m_StaticBatchRoot: {fileID: 0}
+  m_ProbeAnchor: {fileID: 0}
+  m_LightProbeVolumeOverride: {fileID: 0}
+  m_ScaleInLightmap: 1
+  m_ReceiveGI: 1
+  m_PreserveUVs: 0
+  m_IgnoreNormalsForChartDetection: 0
+  m_ImportantGI: 0
+  m_StitchLightmapSeams: 1
+  m_SelectedEditorRenderState: 3
+  m_MinimumChartSize: 4
+  m_AutoUVMaxDistance: 0.5
+  m_AutoUVMaxAngle: 89
+  m_LightmapParameters: {fileID: 0}
+  m_SortingLayerID: 0
+  m_SortingLayer: 0
+  m_SortingOrder: 0
+  m_AdditionalVertexStreams: {fileID: 0}
+--- !u!33 &1052169196
+MeshFilter:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1052169193}
+  m_Mesh: {fileID: 10209, guid: 0000000000000000e000000000000000, type: 0}
+--- !u!4 &1052169197
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1052169193}
+  serializedVersion: 2
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 3.1302, y: 3.1302, z: 3.1302}
+  m_ConstrainProportionsScale: 0
+  m_Children: []
+  m_Father: {fileID: 0}
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!65 &1052169198
+BoxCollider:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1052169193}
+  m_Material: {fileID: 0}
+  m_IncludeLayers:
+    serializedVersion: 2
+    m_Bits: 0
+  m_ExcludeLayers:
+    serializedVersion: 2
+    m_Bits: 0
+  m_LayerOverridePriority: 0
+  m_IsTrigger: 0
+  m_ProvidesContacts: 0
+  m_Enabled: 1
+  serializedVersion: 3
+  m_Size: {x: 10, y: 0, z: 10}
+  m_Center: {x: 0, y: 0, z: 0}
+--- !u!114 &1052169199
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1052169193}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 7a5ac11cc976e418e8d13136b07e1f52, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_SerializedVersion: 0
+  m_AgentTypeID: 0
+  m_CollectObjects: 0
+  m_Size: {x: 10, y: 10, z: 10}
+  m_Center: {x: 0, y: 2, z: 0}
+  m_LayerMask:
+    serializedVersion: 2
+    m_Bits: 256
+  m_UseGeometry: 1
+  m_DefaultArea: 0
+  m_GenerateLinks: 0
+  m_IgnoreNavMeshAgent: 1
+  m_IgnoreNavMeshObstacle: 1
+  m_OverrideTileSize: 0
+  m_TileSize: 256
+  m_OverrideVoxelSize: 0
+  m_VoxelSize: 0.16666667
+  m_MinRegionArea: 2
+  m_NavMeshData: {fileID: 23800000, guid: 2e448e60c8fca6545a415c9086e125ca, type: 2}
+  m_BuildHeightMesh: 0
+--- !u!1 &1429499003
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 1429499005}
+  - component: {fileID: 1429499004}
+  m_Layer: 0
+  m_Name: CameraRig
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!114 &1429499004
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1429499003}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: c95309e585c5a084e882ebdba89308ee, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  moveSpeed: 10
+  rotationSpeed: 100
+  zoomSpeed: 10
+  minZoom: 5
+  maxZoom: 50
+--- !u!4 &1429499005
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1429499003}
+  serializedVersion: 2
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 25.424297, y: 4.2524834, z: 10.885193}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_ConstrainProportionsScale: 0
+  m_Children:
+  - {fileID: 330585546}
+  m_Father: {fileID: 0}
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!1 &1940765008
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 1940765009}
+  - component: {fileID: 1940765012}
+  - component: {fileID: 1940765011}
+  - component: {fileID: 1940765010}
+  m_Layer: 0
+  m_Name: PlayerSpawnArea
+  m_TagString: PlayerSpawnArea
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!4 &1940765009
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1940765008}
+  serializedVersion: 2
+  m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: -9.54}
+  m_LocalScale: {x: 25.0416, y: 3.1302, z: 6}
+  m_ConstrainProportionsScale: 0
+  m_Children: []
+  m_Father: {fileID: 0}
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!65 &1940765010
+BoxCollider:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1940765008}
+  m_Material: {fileID: 0}
+  m_IncludeLayers:
+    serializedVersion: 2
+    m_Bits: 0
+  m_ExcludeLayers:
+    serializedVersion: 2
+    m_Bits: 0
+  m_LayerOverridePriority: 0
+  m_IsTrigger: 0
+  m_ProvidesContacts: 0
+  m_Enabled: 1
+  serializedVersion: 3
+  m_Size: {x: 1, y: 1, z: 1}
+  m_Center: {x: 0, y: 0, z: 0}
+--- !u!23 &1940765011
+MeshRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1940765008}
+  m_Enabled: 1
+  m_CastShadows: 1
+  m_ReceiveShadows: 1
+  m_DynamicOccludee: 1
+  m_StaticShadowCaster: 0
+  m_MotionVectors: 1
+  m_LightProbeUsage: 1
+  m_ReflectionProbeUsage: 1
+  m_RayTracingMode: 2
+  m_RayTraceProcedural: 0
+  m_RayTracingAccelStructBuildFlagsOverride: 0
+  m_RayTracingAccelStructBuildFlags: 1
+  m_SmallMeshCulling: 1
+  m_RenderingLayerMask: 1
+  m_RendererPriority: 0
+  m_Materials:
+  - {fileID: 2100000, guid: 17fcc35a7292ec147b767dff0e951197, type: 2}
+  m_StaticBatchInfo:
+    firstSubMesh: 0
+    subMeshCount: 0
+  m_StaticBatchRoot: {fileID: 0}
+  m_ProbeAnchor: {fileID: 0}
+  m_LightProbeVolumeOverride: {fileID: 0}
+  m_ScaleInLightmap: 1
+  m_ReceiveGI: 1
+  m_PreserveUVs: 0
+  m_IgnoreNormalsForChartDetection: 0
+  m_ImportantGI: 0
+  m_StitchLightmapSeams: 1
+  m_SelectedEditorRenderState: 3
+  m_MinimumChartSize: 4
+  m_AutoUVMaxDistance: 0.5
+  m_AutoUVMaxAngle: 89
+  m_LightmapParameters: {fileID: 0}
+  m_SortingLayerID: 0
+  m_SortingLayer: 0
+  m_SortingOrder: 0
+  m_AdditionalVertexStreams: {fileID: 0}
+--- !u!33 &1940765012
+MeshFilter:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1940765008}
+  m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
+--- !u!1 &1957154045
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 1957154048}
+  - component: {fileID: 1957154047}
+  - component: {fileID: 1957154046}
+  m_Layer: 0
+  m_Name: EventSystem
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!114 &1957154046
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1957154045}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 01614664b831546d2ae94a42149d80ac, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_SendPointerHoverToParent: 1
+  m_MoveRepeatDelay: 0.5
+  m_MoveRepeatRate: 0.1
+  m_XRTrackingOrigin: {fileID: 0}
+  m_ActionsAsset: {fileID: -944628639613478452, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
+  m_PointAction: {fileID: -1654692200621890270, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
+  m_MoveAction: {fileID: -8784545083839296357, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
+  m_SubmitAction: {fileID: 392368643174621059, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
+  m_CancelAction: {fileID: 7727032971491509709, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
+  m_LeftClickAction: {fileID: 3001919216989983466, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
+  m_MiddleClickAction: {fileID: -2185481485913320682, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
+  m_RightClickAction: {fileID: -4090225696740746782, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
+  m_ScrollWheelAction: {fileID: 6240969308177333660, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
+  m_TrackedDevicePositionAction: {fileID: 6564999863303420839, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
+  m_TrackedDeviceOrientationAction: {fileID: 7970375526676320489, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
+  m_DeselectOnBackgroundClick: 1
+  m_PointerBehavior: 0
+  m_CursorLockBehavior: 0
+  m_ScrollDeltaPerTick: 6
+--- !u!114 &1957154047
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1957154045}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 76c392e42b5098c458856cdf6ecaaaa1, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_FirstSelected: {fileID: 0}
+  m_sendNavigationEvents: 1
+  m_DragThreshold: 10
+--- !u!4 &1957154048
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1957154045}
+  serializedVersion: 2
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_ConstrainProportionsScale: 0
+  m_Children: []
+  m_Father: {fileID: 0}
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!1660057539 &9223372036854775807
+SceneRoots:
+  m_ObjectHideFlags: 0
+  m_Roots:
+  - {fileID: 410087041}
+  - {fileID: 832575519}
+  - {fileID: 1940765009}
+  - {fileID: 848956333}
+  - {fileID: 1052169197}
+  - {fileID: 398559099}
+  - {fileID: 754193783}
+  - {fileID: 631973769}
+  - {fileID: 457742904}
+  - {fileID: 1957154048}
+  - {fileID: 1429499005}
+  - {fileID: 864824021}
+  - {fileID: 865903348}

BIN
Assets/Scenes/BattleScene/NavMesh-GroundPlane.asset


+ 451 - 0
Assets/Scenes/BattleSetupMenu.unity

@@ -0,0 +1,451 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!29 &1
+OcclusionCullingSettings:
+  m_ObjectHideFlags: 0
+  serializedVersion: 2
+  m_OcclusionBakeSettings:
+    smallestOccluder: 5
+    smallestHole: 0.25
+    backfaceThreshold: 100
+  m_SceneGUID: 00000000000000000000000000000000
+  m_OcclusionCullingData: {fileID: 0}
+--- !u!104 &2
+RenderSettings:
+  m_ObjectHideFlags: 0
+  serializedVersion: 10
+  m_Fog: 0
+  m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1}
+  m_FogMode: 3
+  m_FogDensity: 0.01
+  m_LinearFogStart: 0
+  m_LinearFogEnd: 300
+  m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1}
+  m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1}
+  m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1}
+  m_AmbientIntensity: 1
+  m_AmbientMode: 0
+  m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1}
+  m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0}
+  m_HaloStrength: 0.5
+  m_FlareStrength: 1
+  m_FlareFadeSpeed: 3
+  m_HaloTexture: {fileID: 0}
+  m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0}
+  m_DefaultReflectionMode: 0
+  m_DefaultReflectionResolution: 128
+  m_ReflectionBounces: 1
+  m_ReflectionIntensity: 1
+  m_CustomReflection: {fileID: 0}
+  m_Sun: {fileID: 0}
+  m_UseRadianceAmbientProbe: 0
+--- !u!157 &3
+LightmapSettings:
+  m_ObjectHideFlags: 0
+  serializedVersion: 13
+  m_BakeOnSceneLoad: 0
+  m_GISettings:
+    serializedVersion: 2
+    m_BounceScale: 1
+    m_IndirectOutputScale: 1
+    m_AlbedoBoost: 1
+    m_EnvironmentLightingMode: 0
+    m_EnableBakedLightmaps: 1
+    m_EnableRealtimeLightmaps: 0
+  m_LightmapEditorSettings:
+    serializedVersion: 12
+    m_Resolution: 2
+    m_BakeResolution: 40
+    m_AtlasSize: 1024
+    m_AO: 0
+    m_AOMaxDistance: 1
+    m_CompAOExponent: 1
+    m_CompAOExponentDirect: 0
+    m_ExtractAmbientOcclusion: 0
+    m_Padding: 2
+    m_LightmapParameters: {fileID: 0}
+    m_LightmapsBakeMode: 1
+    m_TextureCompression: 1
+    m_ReflectionCompression: 2
+    m_MixedBakeMode: 2
+    m_BakeBackend: 1
+    m_PVRSampling: 1
+    m_PVRDirectSampleCount: 32
+    m_PVRSampleCount: 512
+    m_PVRBounces: 2
+    m_PVREnvironmentSampleCount: 256
+    m_PVREnvironmentReferencePointCount: 2048
+    m_PVRFilteringMode: 1
+    m_PVRDenoiserTypeDirect: 1
+    m_PVRDenoiserTypeIndirect: 1
+    m_PVRDenoiserTypeAO: 1
+    m_PVRFilterTypeDirect: 0
+    m_PVRFilterTypeIndirect: 0
+    m_PVRFilterTypeAO: 0
+    m_PVREnvironmentMIS: 1
+    m_PVRCulling: 1
+    m_PVRFilteringGaussRadiusDirect: 1
+    m_PVRFilteringGaussRadiusIndirect: 1
+    m_PVRFilteringGaussRadiusAO: 1
+    m_PVRFilteringAtrousPositionSigmaDirect: 0.5
+    m_PVRFilteringAtrousPositionSigmaIndirect: 2
+    m_PVRFilteringAtrousPositionSigmaAO: 1
+    m_ExportTrainingData: 0
+    m_TrainingDataDestination: TrainingData
+    m_LightProbeSampleCountMultiplier: 4
+  m_LightingDataAsset: {fileID: 20201, guid: 0000000000000000f000000000000000, type: 0}
+  m_LightingSettings: {fileID: 0}
+--- !u!196 &4
+NavMeshSettings:
+  serializedVersion: 2
+  m_ObjectHideFlags: 0
+  m_BuildSettings:
+    serializedVersion: 3
+    agentTypeID: 0
+    agentRadius: 0.5
+    agentHeight: 2
+    agentSlope: 45
+    agentClimb: 0.4
+    ledgeDropHeight: 0
+    maxJumpAcrossDistance: 0
+    minRegionArea: 2
+    manualCellSize: 0
+    cellSize: 0.16666667
+    manualTileSize: 0
+    tileSize: 256
+    buildHeightMesh: 0
+    maxJobWorkers: 0
+    preserveTilesOutsideBounds: 0
+    debug:
+      m_Flags: 0
+  m_NavMeshData: {fileID: 0}
+--- !u!1 &228618678
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 228618681}
+  - component: {fileID: 228618680}
+  - component: {fileID: 228618679}
+  - component: {fileID: 228618682}
+  m_Layer: 0
+  m_Name: Main Camera
+  m_TagString: MainCamera
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!81 &228618679
+AudioListener:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 228618678}
+  m_Enabled: 1
+--- !u!20 &228618680
+Camera:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 228618678}
+  m_Enabled: 1
+  serializedVersion: 2
+  m_ClearFlags: 1
+  m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0}
+  m_projectionMatrixMode: 1
+  m_GateFitMode: 2
+  m_FOVAxisMode: 0
+  m_Iso: 200
+  m_ShutterSpeed: 0.005
+  m_Aperture: 16
+  m_FocusDistance: 10
+  m_FocalLength: 50
+  m_BladeCount: 5
+  m_Curvature: {x: 2, y: 11}
+  m_BarrelClipping: 0.25
+  m_Anamorphism: 0
+  m_SensorSize: {x: 36, y: 24}
+  m_LensShift: {x: 0, y: 0}
+  m_NormalizedViewPortRect:
+    serializedVersion: 2
+    x: 0
+    y: 0
+    width: 1
+    height: 1
+  near clip plane: 0.3
+  far clip plane: 1000
+  field of view: 60
+  orthographic: 0
+  orthographic size: 5
+  m_Depth: -1
+  m_CullingMask:
+    serializedVersion: 2
+    m_Bits: 4294967295
+  m_RenderingPath: -1
+  m_TargetTexture: {fileID: 0}
+  m_TargetDisplay: 0
+  m_TargetEye: 3
+  m_HDR: 1
+  m_AllowMSAA: 1
+  m_AllowDynamicResolution: 0
+  m_ForceIntoRT: 0
+  m_OcclusionCulling: 1
+  m_StereoConvergence: 10
+  m_StereoSeparation: 0.022
+--- !u!4 &228618681
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 228618678}
+  serializedVersion: 2
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 1, z: -10}
+  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 &228618682
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 228618678}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: a79441f348de89743a2939f4d699eac1, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_RenderShadows: 1
+  m_RequiresDepthTextureOption: 2
+  m_RequiresOpaqueTextureOption: 2
+  m_CameraType: 0
+  m_Cameras: []
+  m_RendererIndex: -1
+  m_VolumeLayerMask:
+    serializedVersion: 2
+    m_Bits: 1
+  m_VolumeTrigger: {fileID: 0}
+  m_VolumeFrameworkUpdateModeOption: 2
+  m_RenderPostProcessing: 0
+  m_Antialiasing: 0
+  m_AntialiasingQuality: 2
+  m_StopNaN: 0
+  m_Dithering: 0
+  m_ClearDepth: 1
+  m_AllowXRRendering: 1
+  m_AllowHDROutput: 1
+  m_UseScreenCoordOverride: 0
+  m_ScreenSizeOverride: {x: 0, y: 0, z: 0, w: 0}
+  m_ScreenCoordScaleBias: {x: 0, y: 0, z: 0, w: 0}
+  m_RequiresDepthTexture: 0
+  m_RequiresColorTexture: 0
+  m_Version: 2
+  m_TaaSettings:
+    m_Quality: 3
+    m_FrameInfluence: 0.1
+    m_JitterScale: 1
+    m_MipBias: 0
+    m_VarianceClampScale: 0.9
+    m_ContrastAdaptiveSharpening: 0
+--- !u!1 &766504855
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 766504857}
+  - component: {fileID: 766504856}
+  - component: {fileID: 766504858}
+  m_Layer: 0
+  m_Name: Directional Light
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!108 &766504856
+Light:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 766504855}
+  m_Enabled: 1
+  serializedVersion: 11
+  m_Type: 1
+  m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1}
+  m_Intensity: 1
+  m_Range: 10
+  m_SpotAngle: 30
+  m_InnerSpotAngle: 21.80208
+  m_CookieSize: 10
+  m_Shadows:
+    m_Type: 2
+    m_Resolution: -1
+    m_CustomResolution: -1
+    m_Strength: 1
+    m_Bias: 0.05
+    m_NormalBias: 0.4
+    m_NearPlane: 0.2
+    m_CullingMatrixOverride:
+      e00: 1
+      e01: 0
+      e02: 0
+      e03: 0
+      e10: 0
+      e11: 1
+      e12: 0
+      e13: 0
+      e20: 0
+      e21: 0
+      e22: 1
+      e23: 0
+      e30: 0
+      e31: 0
+      e32: 0
+      e33: 1
+    m_UseCullingMatrixOverride: 0
+  m_Cookie: {fileID: 0}
+  m_DrawHalo: 0
+  m_Flare: {fileID: 0}
+  m_RenderMode: 0
+  m_CullingMask:
+    serializedVersion: 2
+    m_Bits: 4294967295
+  m_RenderingLayerMask: 1
+  m_Lightmapping: 4
+  m_LightShadowCasterMode: 0
+  m_AreaSize: {x: 1, y: 1}
+  m_BounceIntensity: 1
+  m_ColorTemperature: 6570
+  m_UseColorTemperature: 0
+  m_BoundingSphereOverride: {x: 0, y: 0, z: 0, w: 0}
+  m_UseBoundingSphereOverride: 0
+  m_UseViewFrustumForShadowCasterCull: 1
+  m_ForceVisible: 0
+  m_ShadowRadius: 0
+  m_ShadowAngle: 0
+  m_LightUnit: 1
+  m_LuxAtDistance: 1
+  m_EnableSpotReflector: 1
+--- !u!4 &766504857
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 766504855}
+  serializedVersion: 2
+  m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261}
+  m_LocalPosition: {x: 0, y: 3, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_ConstrainProportionsScale: 0
+  m_Children: []
+  m_Father: {fileID: 0}
+  m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0}
+--- !u!114 &766504858
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 766504855}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 474bcb49853aa07438625e644c072ee6, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Version: 3
+  m_UsePipelineSettings: 1
+  m_AdditionalLightsShadowResolutionTier: 2
+  m_LightLayerMask: 1
+  m_RenderingLayers: 1
+  m_CustomShadowLayers: 0
+  m_ShadowLayerMask: 1
+  m_ShadowRenderingLayers: 1
+  m_LightCookieSize: {x: 1, y: 1}
+  m_LightCookieOffset: {x: 0, y: 0}
+  m_SoftShadowQuality: 0
+--- !u!1 &1218317617
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 1218317619}
+  - component: {fileID: 1218317618}
+  - component: {fileID: 1218317620}
+  m_Layer: 0
+  m_Name: BattleSetupUI
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!114 &1218317618
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1218317617}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 9d82c7b9b1cf8064c94bdf8fc88a1e8c, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  characterEntryTemplate: {fileID: 9197481963319205126, guid: 3de0358ec249646419604006b1dfaa92, type: 3}
+--- !u!4 &1218317619
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1218317617}
+  serializedVersion: 2
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_ConstrainProportionsScale: 0
+  m_Children: []
+  m_Father: {fileID: 0}
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!114 &1218317620
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1218317617}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 19102, guid: 0000000000000000e000000000000000, type: 0}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_PanelSettings: {fileID: 11400000, guid: 0d7125098b341c74d868b72a1bacddf4, type: 2}
+  m_ParentUI: {fileID: 0}
+  sourceAsset: {fileID: 9197481963319205126, guid: a6b898953dcb9094f85bd66b73ff92ec, type: 3}
+  m_SortingOrder: 0
+  m_WorldSpaceSizeMode: 1
+  m_WorldSpaceWidth: 1920
+  m_WorldSpaceHeight: 1080
+--- !u!1660057539 &9223372036854775807
+SceneRoots:
+  m_ObjectHideFlags: 0
+  m_Roots:
+  - {fileID: 228618681}
+  - {fileID: 766504857}
+  - {fileID: 1218317619}

+ 665 - 0
Assets/Scenes/MainTeamSelectScene.unity

@@ -0,0 +1,665 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!29 &1
+OcclusionCullingSettings:
+  m_ObjectHideFlags: 0
+  serializedVersion: 2
+  m_OcclusionBakeSettings:
+    smallestOccluder: 5
+    smallestHole: 0.25
+    backfaceThreshold: 100
+  m_SceneGUID: 00000000000000000000000000000000
+  m_OcclusionCullingData: {fileID: 0}
+--- !u!104 &2
+RenderSettings:
+  m_ObjectHideFlags: 0
+  serializedVersion: 10
+  m_Fog: 0
+  m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1}
+  m_FogMode: 3
+  m_FogDensity: 0.01
+  m_LinearFogStart: 0
+  m_LinearFogEnd: 300
+  m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1}
+  m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1}
+  m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1}
+  m_AmbientIntensity: 1
+  m_AmbientMode: 0
+  m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1}
+  m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0}
+  m_HaloStrength: 0.5
+  m_FlareStrength: 1
+  m_FlareFadeSpeed: 3
+  m_HaloTexture: {fileID: 0}
+  m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0}
+  m_DefaultReflectionMode: 0
+  m_DefaultReflectionResolution: 128
+  m_ReflectionBounces: 1
+  m_ReflectionIntensity: 1
+  m_CustomReflection: {fileID: 0}
+  m_Sun: {fileID: 0}
+  m_UseRadianceAmbientProbe: 0
+--- !u!157 &3
+LightmapSettings:
+  m_ObjectHideFlags: 0
+  serializedVersion: 13
+  m_BakeOnSceneLoad: 0
+  m_GISettings:
+    serializedVersion: 2
+    m_BounceScale: 1
+    m_IndirectOutputScale: 1
+    m_AlbedoBoost: 1
+    m_EnvironmentLightingMode: 0
+    m_EnableBakedLightmaps: 1
+    m_EnableRealtimeLightmaps: 0
+  m_LightmapEditorSettings:
+    serializedVersion: 12
+    m_Resolution: 2
+    m_BakeResolution: 40
+    m_AtlasSize: 1024
+    m_AO: 0
+    m_AOMaxDistance: 1
+    m_CompAOExponent: 1
+    m_CompAOExponentDirect: 0
+    m_ExtractAmbientOcclusion: 0
+    m_Padding: 2
+    m_LightmapParameters: {fileID: 0}
+    m_LightmapsBakeMode: 1
+    m_TextureCompression: 1
+    m_ReflectionCompression: 2
+    m_MixedBakeMode: 2
+    m_BakeBackend: 1
+    m_PVRSampling: 1
+    m_PVRDirectSampleCount: 32
+    m_PVRSampleCount: 512
+    m_PVRBounces: 2
+    m_PVREnvironmentSampleCount: 256
+    m_PVREnvironmentReferencePointCount: 2048
+    m_PVRFilteringMode: 1
+    m_PVRDenoiserTypeDirect: 1
+    m_PVRDenoiserTypeIndirect: 1
+    m_PVRDenoiserTypeAO: 1
+    m_PVRFilterTypeDirect: 0
+    m_PVRFilterTypeIndirect: 0
+    m_PVRFilterTypeAO: 0
+    m_PVREnvironmentMIS: 1
+    m_PVRCulling: 1
+    m_PVRFilteringGaussRadiusDirect: 1
+    m_PVRFilteringGaussRadiusIndirect: 1
+    m_PVRFilteringGaussRadiusAO: 1
+    m_PVRFilteringAtrousPositionSigmaDirect: 0.5
+    m_PVRFilteringAtrousPositionSigmaIndirect: 2
+    m_PVRFilteringAtrousPositionSigmaAO: 1
+    m_ExportTrainingData: 0
+    m_TrainingDataDestination: TrainingData
+    m_LightProbeSampleCountMultiplier: 4
+  m_LightingDataAsset: {fileID: 20201, guid: 0000000000000000f000000000000000, type: 0}
+  m_LightingSettings: {fileID: 0}
+--- !u!196 &4
+NavMeshSettings:
+  serializedVersion: 2
+  m_ObjectHideFlags: 0
+  m_BuildSettings:
+    serializedVersion: 3
+    agentTypeID: 0
+    agentRadius: 0.5
+    agentHeight: 2
+    agentSlope: 45
+    agentClimb: 0.4
+    ledgeDropHeight: 0
+    maxJumpAcrossDistance: 0
+    minRegionArea: 2
+    manualCellSize: 0
+    cellSize: 0.16666667
+    manualTileSize: 0
+    tileSize: 256
+    buildHeightMesh: 0
+    maxJobWorkers: 0
+    preserveTilesOutsideBounds: 0
+    debug:
+      m_Flags: 0
+  m_NavMeshData: {fileID: 0}
+--- !u!1 &547676641
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 547676645}
+  - component: {fileID: 547676644}
+  - component: {fileID: 547676643}
+  - component: {fileID: 547676642}
+  m_Layer: 0
+  m_Name: Main Camera
+  m_TagString: MainCamera
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!114 &547676642
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 547676641}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: a79441f348de89743a2939f4d699eac1, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_RenderShadows: 1
+  m_RequiresDepthTextureOption: 2
+  m_RequiresOpaqueTextureOption: 2
+  m_CameraType: 0
+  m_Cameras: []
+  m_RendererIndex: -1
+  m_VolumeLayerMask:
+    serializedVersion: 2
+    m_Bits: 1
+  m_VolumeTrigger: {fileID: 0}
+  m_VolumeFrameworkUpdateModeOption: 2
+  m_RenderPostProcessing: 0
+  m_Antialiasing: 0
+  m_AntialiasingQuality: 2
+  m_StopNaN: 0
+  m_Dithering: 0
+  m_ClearDepth: 1
+  m_AllowXRRendering: 1
+  m_AllowHDROutput: 1
+  m_UseScreenCoordOverride: 0
+  m_ScreenSizeOverride: {x: 0, y: 0, z: 0, w: 0}
+  m_ScreenCoordScaleBias: {x: 0, y: 0, z: 0, w: 0}
+  m_RequiresDepthTexture: 0
+  m_RequiresColorTexture: 0
+  m_Version: 2
+  m_TaaSettings:
+    m_Quality: 3
+    m_FrameInfluence: 0.1
+    m_JitterScale: 1
+    m_MipBias: 0
+    m_VarianceClampScale: 0.9
+    m_ContrastAdaptiveSharpening: 0
+--- !u!81 &547676643
+AudioListener:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 547676641}
+  m_Enabled: 1
+--- !u!20 &547676644
+Camera:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 547676641}
+  m_Enabled: 1
+  serializedVersion: 2
+  m_ClearFlags: 1
+  m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0}
+  m_projectionMatrixMode: 1
+  m_GateFitMode: 2
+  m_FOVAxisMode: 0
+  m_Iso: 200
+  m_ShutterSpeed: 0.005
+  m_Aperture: 16
+  m_FocusDistance: 10
+  m_FocalLength: 50
+  m_BladeCount: 5
+  m_Curvature: {x: 2, y: 11}
+  m_BarrelClipping: 0.25
+  m_Anamorphism: 0
+  m_SensorSize: {x: 36, y: 24}
+  m_LensShift: {x: 0, y: 0}
+  m_NormalizedViewPortRect:
+    serializedVersion: 2
+    x: 0
+    y: 0
+    width: 1
+    height: 1
+  near clip plane: 0.3
+  far clip plane: 1000
+  field of view: 60
+  orthographic: 0
+  orthographic size: 5
+  m_Depth: -1
+  m_CullingMask:
+    serializedVersion: 2
+    m_Bits: 4294967295
+  m_RenderingPath: -1
+  m_TargetTexture: {fileID: 0}
+  m_TargetDisplay: 0
+  m_TargetEye: 3
+  m_HDR: 1
+  m_AllowMSAA: 1
+  m_AllowDynamicResolution: 0
+  m_ForceIntoRT: 0
+  m_OcclusionCulling: 1
+  m_StereoConvergence: 10
+  m_StereoSeparation: 0.022
+--- !u!4 &547676645
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 547676641}
+  serializedVersion: 2
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 1, z: -10}
+  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 &954736249
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 954736252}
+  - component: {fileID: 954736251}
+  - component: {fileID: 954736250}
+  m_Layer: 0
+  m_Name: Directional Light
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!114 &954736250
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 954736249}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 474bcb49853aa07438625e644c072ee6, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Version: 3
+  m_UsePipelineSettings: 1
+  m_AdditionalLightsShadowResolutionTier: 2
+  m_LightLayerMask: 1
+  m_RenderingLayers: 1
+  m_CustomShadowLayers: 0
+  m_ShadowLayerMask: 1
+  m_ShadowRenderingLayers: 1
+  m_LightCookieSize: {x: 1, y: 1}
+  m_LightCookieOffset: {x: 0, y: 0}
+  m_SoftShadowQuality: 0
+--- !u!108 &954736251
+Light:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 954736249}
+  m_Enabled: 1
+  serializedVersion: 11
+  m_Type: 1
+  m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1}
+  m_Intensity: 1
+  m_Range: 10
+  m_SpotAngle: 30
+  m_InnerSpotAngle: 21.80208
+  m_CookieSize: 10
+  m_Shadows:
+    m_Type: 2
+    m_Resolution: -1
+    m_CustomResolution: -1
+    m_Strength: 1
+    m_Bias: 0.05
+    m_NormalBias: 0.4
+    m_NearPlane: 0.2
+    m_CullingMatrixOverride:
+      e00: 1
+      e01: 0
+      e02: 0
+      e03: 0
+      e10: 0
+      e11: 1
+      e12: 0
+      e13: 0
+      e20: 0
+      e21: 0
+      e22: 1
+      e23: 0
+      e30: 0
+      e31: 0
+      e32: 0
+      e33: 1
+    m_UseCullingMatrixOverride: 0
+  m_Cookie: {fileID: 0}
+  m_DrawHalo: 0
+  m_Flare: {fileID: 0}
+  m_RenderMode: 0
+  m_CullingMask:
+    serializedVersion: 2
+    m_Bits: 4294967295
+  m_RenderingLayerMask: 1
+  m_Lightmapping: 4
+  m_LightShadowCasterMode: 0
+  m_AreaSize: {x: 1, y: 1}
+  m_BounceIntensity: 1
+  m_ColorTemperature: 6570
+  m_UseColorTemperature: 0
+  m_BoundingSphereOverride: {x: 0, y: 0, z: 0, w: 0}
+  m_UseBoundingSphereOverride: 0
+  m_UseViewFrustumForShadowCasterCull: 1
+  m_ForceVisible: 0
+  m_ShadowRadius: 0
+  m_ShadowAngle: 0
+  m_LightUnit: 1
+  m_LuxAtDistance: 1
+  m_EnableSpotReflector: 1
+--- !u!4 &954736252
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 954736249}
+  serializedVersion: 2
+  m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261}
+  m_LocalPosition: {x: 0, y: 3, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_ConstrainProportionsScale: 0
+  m_Children: []
+  m_Father: {fileID: 0}
+  m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0}
+--- !u!1 &1336314989
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 1336314991}
+  - component: {fileID: 1336314990}
+  m_Layer: 0
+  m_Name: ShopSystem
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!114 &1336314990
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1336314989}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 62411056f4a14d64a9984b57c1e91667, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  instructions: 'Setup Instructions:
+
+    1. Create a GameObject and attach SimpleShopManager
+    script
+
+    2. Create a UI Document with ShopUI.uxml as the Visual Tree Asset
+
+    3.
+    Attach the UI Document to the same GameObject as SimpleShopManager
+
+    4. The
+    shop will automatically populate with default items
+
+    5. Click ''Add Weapon'',
+    ''Add Armor'', or ''Add Misc'' buttons in character inventory to open shop'
+  createShopGameObject: 1
+  shopUIAsset: {fileID: 9197481963319205126, guid: 9c5235cf7904a254cb37c229e549e15d, type: 3}
+  testShopSystem: 0
+  debugShopSetup: 0
+  createPanelSettings: 0
+--- !u!4 &1336314991
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1336314989}
+  serializedVersion: 2
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_ConstrainProportionsScale: 0
+  m_Children: []
+  m_Father: {fileID: 0}
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!1 &1379964092
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 1379964095}
+  - component: {fileID: 1379964094}
+  - component: {fileID: 1379964093}
+  m_Layer: 0
+  m_Name: EventSystem
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!114 &1379964093
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1379964092}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 01614664b831546d2ae94a42149d80ac, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_SendPointerHoverToParent: 1
+  m_MoveRepeatDelay: 0.5
+  m_MoveRepeatRate: 0.1
+  m_XRTrackingOrigin: {fileID: 0}
+  m_ActionsAsset: {fileID: -944628639613478452, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
+  m_PointAction: {fileID: -1654692200621890270, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
+  m_MoveAction: {fileID: -8784545083839296357, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
+  m_SubmitAction: {fileID: 392368643174621059, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
+  m_CancelAction: {fileID: 7727032971491509709, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
+  m_LeftClickAction: {fileID: 3001919216989983466, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
+  m_MiddleClickAction: {fileID: -2185481485913320682, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
+  m_RightClickAction: {fileID: -4090225696740746782, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
+  m_ScrollWheelAction: {fileID: 6240969308177333660, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
+  m_TrackedDevicePositionAction: {fileID: 6564999863303420839, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
+  m_TrackedDeviceOrientationAction: {fileID: 7970375526676320489, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
+  m_DeselectOnBackgroundClick: 1
+  m_PointerBehavior: 0
+  m_CursorLockBehavior: 0
+  m_ScrollDeltaPerTick: 6
+--- !u!114 &1379964094
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1379964092}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 76c392e42b5098c458856cdf6ecaaaa1, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_FirstSelected: {fileID: 0}
+  m_sendNavigationEvents: 1
+  m_DragThreshold: 10
+--- !u!4 &1379964095
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1379964092}
+  serializedVersion: 2
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_ConstrainProportionsScale: 0
+  m_Children: []
+  m_Father: {fileID: 0}
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!1 &1776509872
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 1776509877}
+  - component: {fileID: 1776509876}
+  - component: {fileID: 1776509875}
+  - component: {fileID: 1776509874}
+  - component: {fileID: 1776509873}
+  - component: {fileID: 1776509878}
+  m_Layer: 5
+  m_Name: UiCanvas
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!114 &1776509873
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1776509872}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 19102, guid: 0000000000000000e000000000000000, type: 0}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_PanelSettings: {fileID: 11400000, guid: 0d7125098b341c74d868b72a1bacddf4, type: 2}
+  m_ParentUI: {fileID: 0}
+  sourceAsset: {fileID: 9197481963319205126, guid: ab8cfd0df301fbb4195e7386d0d96287, type: 3}
+  m_SortingOrder: 2
+  m_WorldSpaceSizeMode: 1
+  m_WorldSpaceWidth: 1920
+  m_WorldSpaceHeight: 1080
+--- !u!114 &1776509874
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1776509872}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: dc42784cf147c0c48a680349fa168899, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_IgnoreReversedGraphics: 1
+  m_BlockingObjects: 0
+  m_BlockingMask:
+    serializedVersion: 2
+    m_Bits: 4294967295
+--- !u!114 &1776509875
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1776509872}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 0cd44c1031e13a943bb63640046fad76, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_UiScaleMode: 0
+  m_ReferencePixelsPerUnit: 100
+  m_ScaleFactor: 1
+  m_ReferenceResolution: {x: 800, y: 600}
+  m_ScreenMatchMode: 0
+  m_MatchWidthOrHeight: 0
+  m_PhysicalUnit: 3
+  m_FallbackScreenDPI: 96
+  m_DefaultSpriteDPI: 96
+  m_DynamicPixelsPerUnit: 1
+  m_PresetInfoIsWorld: 1
+--- !u!223 &1776509876
+Canvas:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1776509872}
+  m_Enabled: 1
+  serializedVersion: 3
+  m_RenderMode: 2
+  m_Camera: {fileID: 547676644}
+  m_PlaneDistance: 100
+  m_PixelPerfect: 0
+  m_ReceivesEvents: 1
+  m_OverrideSorting: 0
+  m_OverridePixelPerfect: 0
+  m_SortingBucketNormalizedSize: 0
+  m_VertexColorAlwaysGammaSpace: 0
+  m_AdditionalShaderChannelsFlag: 0
+  m_UpdateRectTransformForStandalone: 0
+  m_SortingLayerID: 0
+  m_SortingOrder: 0
+  m_TargetDisplay: 0
+--- !u!224 &1776509877
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1776509872}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_ConstrainProportionsScale: 0
+  m_Children: []
+  m_Father: {fileID: 0}
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0, y: 0}
+  m_AnchorMax: {x: 0, y: 0}
+  m_AnchoredPosition: {x: 254, y: 254}
+  m_SizeDelta: {x: 508, y: 508}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!114 &1776509878
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1776509872}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: d3bdbc15654b72e41aa9ecec833643f9, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+--- !u!1660057539 &9223372036854775807
+SceneRoots:
+  m_ObjectHideFlags: 0
+  m_Roots:
+  - {fileID: 547676645}
+  - {fileID: 954736252}
+  - {fileID: 1776509877}
+  - {fileID: 1379964095}
+  - {fileID: 1336314991}

+ 683 - 0
Assets/Scenes/MapScene2.unity

@@ -0,0 +1,683 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!29 &1
+OcclusionCullingSettings:
+  m_ObjectHideFlags: 0
+  serializedVersion: 2
+  m_OcclusionBakeSettings:
+    smallestOccluder: 5
+    smallestHole: 0.25
+    backfaceThreshold: 100
+  m_SceneGUID: 00000000000000000000000000000000
+  m_OcclusionCullingData: {fileID: 0}
+--- !u!104 &2
+RenderSettings:
+  m_ObjectHideFlags: 0
+  serializedVersion: 10
+  m_Fog: 0
+  m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1}
+  m_FogMode: 3
+  m_FogDensity: 0.01
+  m_LinearFogStart: 0
+  m_LinearFogEnd: 300
+  m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1}
+  m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1}
+  m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1}
+  m_AmbientIntensity: 1
+  m_AmbientMode: 0
+  m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1}
+  m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0}
+  m_HaloStrength: 0.5
+  m_FlareStrength: 1
+  m_FlareFadeSpeed: 3
+  m_HaloTexture: {fileID: 0}
+  m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0}
+  m_DefaultReflectionMode: 0
+  m_DefaultReflectionResolution: 128
+  m_ReflectionBounces: 1
+  m_ReflectionIntensity: 1
+  m_CustomReflection: {fileID: 0}
+  m_Sun: {fileID: 0}
+  m_UseRadianceAmbientProbe: 0
+--- !u!157 &3
+LightmapSettings:
+  m_ObjectHideFlags: 0
+  serializedVersion: 13
+  m_BakeOnSceneLoad: 0
+  m_GISettings:
+    serializedVersion: 2
+    m_BounceScale: 1
+    m_IndirectOutputScale: 1
+    m_AlbedoBoost: 1
+    m_EnvironmentLightingMode: 0
+    m_EnableBakedLightmaps: 1
+    m_EnableRealtimeLightmaps: 0
+  m_LightmapEditorSettings:
+    serializedVersion: 12
+    m_Resolution: 2
+    m_BakeResolution: 40
+    m_AtlasSize: 1024
+    m_AO: 0
+    m_AOMaxDistance: 1
+    m_CompAOExponent: 1
+    m_CompAOExponentDirect: 0
+    m_ExtractAmbientOcclusion: 0
+    m_Padding: 2
+    m_LightmapParameters: {fileID: 0}
+    m_LightmapsBakeMode: 1
+    m_TextureCompression: 1
+    m_ReflectionCompression: 2
+    m_MixedBakeMode: 2
+    m_BakeBackend: 1
+    m_PVRSampling: 1
+    m_PVRDirectSampleCount: 32
+    m_PVRSampleCount: 512
+    m_PVRBounces: 2
+    m_PVREnvironmentSampleCount: 256
+    m_PVREnvironmentReferencePointCount: 2048
+    m_PVRFilteringMode: 1
+    m_PVRDenoiserTypeDirect: 1
+    m_PVRDenoiserTypeIndirect: 1
+    m_PVRDenoiserTypeAO: 1
+    m_PVRFilterTypeDirect: 0
+    m_PVRFilterTypeIndirect: 0
+    m_PVRFilterTypeAO: 0
+    m_PVREnvironmentMIS: 1
+    m_PVRCulling: 1
+    m_PVRFilteringGaussRadiusDirect: 1
+    m_PVRFilteringGaussRadiusIndirect: 1
+    m_PVRFilteringGaussRadiusAO: 1
+    m_PVRFilteringAtrousPositionSigmaDirect: 0.5
+    m_PVRFilteringAtrousPositionSigmaIndirect: 2
+    m_PVRFilteringAtrousPositionSigmaAO: 1
+    m_ExportTrainingData: 0
+    m_TrainingDataDestination: TrainingData
+    m_LightProbeSampleCountMultiplier: 4
+  m_LightingDataAsset: {fileID: 20201, guid: 0000000000000000f000000000000000, type: 0}
+  m_LightingSettings: {fileID: 0}
+--- !u!196 &4
+NavMeshSettings:
+  serializedVersion: 2
+  m_ObjectHideFlags: 0
+  m_BuildSettings:
+    serializedVersion: 3
+    agentTypeID: 0
+    agentRadius: 0.5
+    agentHeight: 2
+    agentSlope: 45
+    agentClimb: 0.4
+    ledgeDropHeight: 0
+    maxJumpAcrossDistance: 0
+    minRegionArea: 2
+    manualCellSize: 0
+    cellSize: 0.16666667
+    manualTileSize: 0
+    tileSize: 256
+    buildHeightMesh: 0
+    maxJobWorkers: 0
+    preserveTilesOutsideBounds: 0
+    debug:
+      m_Flags: 0
+  m_NavMeshData: {fileID: 0}
+--- !u!1 &345809422
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 345809425}
+  - component: {fileID: 345809424}
+  - component: {fileID: 345809423}
+  m_Layer: 0
+  m_Name: MapGenerator
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!114 &345809423
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 345809422}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 3c9e68b49e8f0b84ea8b00ad0ca2106a, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  defaultSprite: {fileID: 0}
+  plainsSprite: {fileID: 0}
+  forestSprite: {fileID: 0}
+  oceanSprite: {fileID: 0}
+  lakeSprite: {fileID: 0}
+  shoreSprite: {fileID: 0}
+  riverSprite: {fileID: 0}
+  mountainSprite: {fileID: 0}
+  forestRiverSprite: {fileID: 0}
+  roadSprite: {fileID: 0}
+  bridgeSprite: {fileID: 0}
+  tunnelSprite: {fileID: 0}
+  harbourSprite: {fileID: 0}
+  townSprite: {fileID: 0}
+  villageSprite: {fileID: 0}
+  tileSize: 1
+  mapParent: {fileID: 0}
+--- !u!114 &345809424
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 345809422}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 4a2f49db72b4a8641ba22b2c06bafe72, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  initialMapSize: 300
+  expansionSize: 50
+  playerDistanceThreshold: 20
+  useSimpleMode: 1
+  useExplorationSystem: 0
+  explorationMapSize: 300
+  explorationInitialVisible: 80
+  expansionCooldown: 5
+  terrainContinuityChance: 0.7
+  seed: 456
+  mapVisualizer: {fileID: 0}
+--- !u!4 &345809425
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 345809422}
+  serializedVersion: 2
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: -16.14033, y: -53.668198, z: -23.65402}
+  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 &591284416
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 591284419}
+  - component: {fileID: 591284418}
+  - component: {fileID: 591284417}
+  m_Layer: 0
+  m_Name: TravelUI
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!114 &591284417
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 591284416}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 19102, guid: 0000000000000000e000000000000000, type: 0}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_PanelSettings: {fileID: 11400000, guid: 0d7125098b341c74d868b72a1bacddf4, type: 2}
+  m_ParentUI: {fileID: 0}
+  sourceAsset: {fileID: 9197481963319205126, guid: 96f33e5984486024ab0e8e40b263662f, type: 3}
+  m_SortingOrder: 0
+  m_WorldSpaceSizeMode: 1
+  m_WorldSpaceWidth: 1920
+  m_WorldSpaceHeight: 1080
+--- !u!114 &591284418
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 591284416}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 4c85ea6c3f39f054dabaa1f1fb4cbeff, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  uiDocument: {fileID: 591284417}
+  travelUIAsset: {fileID: 9197481963319205126, guid: 96f33e5984486024ab0e8e40b263662f, type: 3}
+  travelUIStyleSheet: {fileID: 0}
+--- !u!4 &591284419
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 591284416}
+  serializedVersion: 2
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_ConstrainProportionsScale: 0
+  m_Children: []
+  m_Father: {fileID: 0}
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!1 &1243674619
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 1243674621}
+  - component: {fileID: 1243674620}
+  m_Layer: 0
+  m_Name: TeamPlacement
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!114 &1243674620
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1243674619}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 05c12afd7c0593d44bb8767964415c12, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  teamMarkerPrefab: {fileID: 0}
+  teamMarkerMaterial: {fileID: 0}
+  markerSize: 1.5
+  markerZOffset: -2
+  markerColor: {r: 0, g: 1, b: 0, a: 1}
+  enableBlinking: 1
+  blinkSpeed: 0.5
+--- !u!4 &1243674621
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1243674619}
+  serializedVersion: 2
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 193.64886, y: 61.02466, z: 154.21207}
+  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 &1299661707
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 1299661709}
+  - component: {fileID: 1299661708}
+  - component: {fileID: 1299661710}
+  m_Layer: 0
+  m_Name: Directional Light
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!108 &1299661708
+Light:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1299661707}
+  m_Enabled: 1
+  serializedVersion: 11
+  m_Type: 1
+  m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1}
+  m_Intensity: 1
+  m_Range: 10
+  m_SpotAngle: 30
+  m_InnerSpotAngle: 21.80208
+  m_CookieSize: 10
+  m_Shadows:
+    m_Type: 2
+    m_Resolution: -1
+    m_CustomResolution: -1
+    m_Strength: 1
+    m_Bias: 0.05
+    m_NormalBias: 0.4
+    m_NearPlane: 0.2
+    m_CullingMatrixOverride:
+      e00: 1
+      e01: 0
+      e02: 0
+      e03: 0
+      e10: 0
+      e11: 1
+      e12: 0
+      e13: 0
+      e20: 0
+      e21: 0
+      e22: 1
+      e23: 0
+      e30: 0
+      e31: 0
+      e32: 0
+      e33: 1
+    m_UseCullingMatrixOverride: 0
+  m_Cookie: {fileID: 0}
+  m_DrawHalo: 0
+  m_Flare: {fileID: 0}
+  m_RenderMode: 0
+  m_CullingMask:
+    serializedVersion: 2
+    m_Bits: 4294967295
+  m_RenderingLayerMask: 1
+  m_Lightmapping: 4
+  m_LightShadowCasterMode: 0
+  m_AreaSize: {x: 1, y: 1}
+  m_BounceIntensity: 1
+  m_ColorTemperature: 6570
+  m_UseColorTemperature: 0
+  m_BoundingSphereOverride: {x: 0, y: 0, z: 0, w: 0}
+  m_UseBoundingSphereOverride: 0
+  m_UseViewFrustumForShadowCasterCull: 1
+  m_ForceVisible: 0
+  m_ShadowRadius: 0
+  m_ShadowAngle: 0
+  m_LightUnit: 1
+  m_LuxAtDistance: 1
+  m_EnableSpotReflector: 1
+--- !u!4 &1299661709
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1299661707}
+  serializedVersion: 2
+  m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261}
+  m_LocalPosition: {x: 0, y: 3, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_ConstrainProportionsScale: 0
+  m_Children: []
+  m_Father: {fileID: 0}
+  m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0}
+--- !u!114 &1299661710
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1299661707}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 474bcb49853aa07438625e644c072ee6, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Version: 3
+  m_UsePipelineSettings: 1
+  m_AdditionalLightsShadowResolutionTier: 2
+  m_LightLayerMask: 1
+  m_RenderingLayers: 1
+  m_CustomShadowLayers: 0
+  m_ShadowLayerMask: 1
+  m_ShadowRenderingLayers: 1
+  m_LightCookieSize: {x: 1, y: 1}
+  m_LightCookieOffset: {x: 0, y: 0}
+  m_SoftShadowQuality: 0
+--- !u!1 &1581552013
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 1581552015}
+  - component: {fileID: 1581552014}
+  m_Layer: 0
+  m_Name: TravelSystemSetup
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!114 &1581552014
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1581552013}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 2d597432c954f7c478b113c9c2a51f76, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  plainsMovementCost: 1
+  forestMovementCost: 2
+  mountainMovementCost: 4
+  roadMovementCost: 0.5
+  townMovementCost: 0.1
+  bridgeMovementCost: 0.6
+  ferryBaseCost: 25
+  ferryMovementCost: 0.7
+  tunnelTorchCost: 10
+  tunnelWithTorchCost: 0.8
+  tunnelWithoutTorchCost: 3
+  bridgeTollCost: 5
+  mountainPassCost: 15
+  riverCrossingCost: 6
+  lakeCrossingCost: 4
+  oceanCrossingCost: 10
+  pathLineMaterial: {fileID: 0}
+  standardPathColor: {r: 0, g: 0, b: 1, a: 1}
+  expensivePathColor: {r: 1, g: 0, b: 0, a: 1}
+  alternativePathColor: {r: 1, g: 0.92156863, b: 0.015686275, a: 1}
+  pathLineWidth: 0.2
+  pathLineZOffset: -1
+  showDebugLogs: 0
+  showMovementCosts: 0
+  timeMultiplier: 1
+  timeSpeedOptions:
+  - 1
+  - 2
+  - 4
+  - 8
+--- !u!4 &1581552015
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1581552013}
+  serializedVersion: 2
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 53.011864, y: 95.75804, z: 41.62294}
+  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 &1953346056
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 1953346059}
+  - component: {fileID: 1953346058}
+  - component: {fileID: 1953346057}
+  - component: {fileID: 1953346061}
+  - component: {fileID: 1953346060}
+  m_Layer: 0
+  m_Name: Main Camera
+  m_TagString: MainCamera
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!81 &1953346057
+AudioListener:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1953346056}
+  m_Enabled: 1
+--- !u!20 &1953346058
+Camera:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1953346056}
+  m_Enabled: 1
+  serializedVersion: 2
+  m_ClearFlags: 1
+  m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0}
+  m_projectionMatrixMode: 1
+  m_GateFitMode: 2
+  m_FOVAxisMode: 0
+  m_Iso: 200
+  m_ShutterSpeed: 0.005
+  m_Aperture: 16
+  m_FocusDistance: 10
+  m_FocalLength: 50
+  m_BladeCount: 5
+  m_Curvature: {x: 2, y: 11}
+  m_BarrelClipping: 0.25
+  m_Anamorphism: 0
+  m_SensorSize: {x: 36, y: 24}
+  m_LensShift: {x: 0, y: 0}
+  m_NormalizedViewPortRect:
+    serializedVersion: 2
+    x: 0
+    y: 0
+    width: 1
+    height: 1
+  near clip plane: 0.3
+  far clip plane: 1000
+  field of view: 60
+  orthographic: 1
+  orthographic size: 80
+  m_Depth: -1
+  m_CullingMask:
+    serializedVersion: 2
+    m_Bits: 4294967295
+  m_RenderingPath: -1
+  m_TargetTexture: {fileID: 0}
+  m_TargetDisplay: 0
+  m_TargetEye: 3
+  m_HDR: 1
+  m_AllowMSAA: 1
+  m_AllowDynamicResolution: 0
+  m_ForceIntoRT: 0
+  m_OcclusionCulling: 1
+  m_StereoConvergence: 10
+  m_StereoSeparation: 0.022
+--- !u!4 &1953346059
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1953346056}
+  serializedVersion: 2
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 75, y: 75, z: -10}
+  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 &1953346060
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1953346056}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 3f906efd7980b6347b614af9bda65c97, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  moveSpeed: 10
+  zoomSpeed: 5
+  minZoom: 2
+  maxZoom: 80
+--- !u!114 &1953346061
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1953346056}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: a79441f348de89743a2939f4d699eac1, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_RenderShadows: 1
+  m_RequiresDepthTextureOption: 2
+  m_RequiresOpaqueTextureOption: 2
+  m_CameraType: 0
+  m_Cameras: []
+  m_RendererIndex: -1
+  m_VolumeLayerMask:
+    serializedVersion: 2
+    m_Bits: 1
+  m_VolumeTrigger: {fileID: 0}
+  m_VolumeFrameworkUpdateModeOption: 2
+  m_RenderPostProcessing: 0
+  m_Antialiasing: 0
+  m_AntialiasingQuality: 2
+  m_StopNaN: 0
+  m_Dithering: 0
+  m_ClearDepth: 1
+  m_AllowXRRendering: 1
+  m_AllowHDROutput: 1
+  m_UseScreenCoordOverride: 0
+  m_ScreenSizeOverride: {x: 0, y: 0, z: 0, w: 0}
+  m_ScreenCoordScaleBias: {x: 0, y: 0, z: 0, w: 0}
+  m_RequiresDepthTexture: 0
+  m_RequiresColorTexture: 0
+  m_Version: 2
+  m_TaaSettings:
+    m_Quality: 3
+    m_FrameInfluence: 0.1
+    m_JitterScale: 1
+    m_MipBias: 0
+    m_VarianceClampScale: 0.9
+    m_ContrastAdaptiveSharpening: 0
+--- !u!1660057539 &9223372036854775807
+SceneRoots:
+  m_ObjectHideFlags: 0
+  m_Roots:
+  - {fileID: 1953346059}
+  - {fileID: 1299661709}
+  - {fileID: 345809425}
+  - {fileID: 1243674621}
+  - {fileID: 1581552015}
+  - {fileID: 591284419}

+ 405 - 0
Assets/Scenes/TitleScreenScene.unity

@@ -0,0 +1,405 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!29 &1
+OcclusionCullingSettings:
+  m_ObjectHideFlags: 0
+  serializedVersion: 2
+  m_OcclusionBakeSettings:
+    smallestOccluder: 5
+    smallestHole: 0.25
+    backfaceThreshold: 100
+  m_SceneGUID: 00000000000000000000000000000000
+  m_OcclusionCullingData: {fileID: 0}
+--- !u!104 &2
+RenderSettings:
+  m_ObjectHideFlags: 0
+  serializedVersion: 10
+  m_Fog: 0
+  m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1}
+  m_FogMode: 3
+  m_FogDensity: 0.01
+  m_LinearFogStart: 0
+  m_LinearFogEnd: 300
+  m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1}
+  m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1}
+  m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1}
+  m_AmbientIntensity: 1
+  m_AmbientMode: 0
+  m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1}
+  m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0}
+  m_HaloStrength: 0.5
+  m_FlareStrength: 1
+  m_FlareFadeSpeed: 3
+  m_HaloTexture: {fileID: 0}
+  m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0}
+  m_DefaultReflectionMode: 0
+  m_DefaultReflectionResolution: 128
+  m_ReflectionBounces: 1
+  m_ReflectionIntensity: 1
+  m_CustomReflection: {fileID: 0}
+  m_Sun: {fileID: 0}
+  m_UseRadianceAmbientProbe: 0
+--- !u!157 &3
+LightmapSettings:
+  m_ObjectHideFlags: 0
+  serializedVersion: 13
+  m_BakeOnSceneLoad: 0
+  m_GISettings:
+    serializedVersion: 2
+    m_BounceScale: 1
+    m_IndirectOutputScale: 1
+    m_AlbedoBoost: 1
+    m_EnvironmentLightingMode: 0
+    m_EnableBakedLightmaps: 1
+    m_EnableRealtimeLightmaps: 0
+  m_LightmapEditorSettings:
+    serializedVersion: 12
+    m_Resolution: 2
+    m_BakeResolution: 40
+    m_AtlasSize: 1024
+    m_AO: 0
+    m_AOMaxDistance: 1
+    m_CompAOExponent: 1
+    m_CompAOExponentDirect: 0
+    m_ExtractAmbientOcclusion: 0
+    m_Padding: 2
+    m_LightmapParameters: {fileID: 0}
+    m_LightmapsBakeMode: 1
+    m_TextureCompression: 1
+    m_ReflectionCompression: 2
+    m_MixedBakeMode: 2
+    m_BakeBackend: 1
+    m_PVRSampling: 1
+    m_PVRDirectSampleCount: 32
+    m_PVRSampleCount: 512
+    m_PVRBounces: 2
+    m_PVREnvironmentSampleCount: 256
+    m_PVREnvironmentReferencePointCount: 2048
+    m_PVRFilteringMode: 1
+    m_PVRDenoiserTypeDirect: 1
+    m_PVRDenoiserTypeIndirect: 1
+    m_PVRDenoiserTypeAO: 1
+    m_PVRFilterTypeDirect: 0
+    m_PVRFilterTypeIndirect: 0
+    m_PVRFilterTypeAO: 0
+    m_PVREnvironmentMIS: 1
+    m_PVRCulling: 1
+    m_PVRFilteringGaussRadiusDirect: 1
+    m_PVRFilteringGaussRadiusIndirect: 1
+    m_PVRFilteringGaussRadiusAO: 1
+    m_PVRFilteringAtrousPositionSigmaDirect: 0.5
+    m_PVRFilteringAtrousPositionSigmaIndirect: 2
+    m_PVRFilteringAtrousPositionSigmaAO: 1
+    m_ExportTrainingData: 0
+    m_TrainingDataDestination: TrainingData
+    m_LightProbeSampleCountMultiplier: 4
+  m_LightingDataAsset: {fileID: 20201, guid: 0000000000000000f000000000000000, type: 0}
+  m_LightingSettings: {fileID: 0}
+--- !u!196 &4
+NavMeshSettings:
+  serializedVersion: 2
+  m_ObjectHideFlags: 0
+  m_BuildSettings:
+    serializedVersion: 3
+    agentTypeID: 0
+    agentRadius: 0.5
+    agentHeight: 2
+    agentSlope: 45
+    agentClimb: 0.4
+    ledgeDropHeight: 0
+    maxJumpAcrossDistance: 0
+    minRegionArea: 2
+    manualCellSize: 0
+    cellSize: 0.16666667
+    manualTileSize: 0
+    tileSize: 256
+    buildHeightMesh: 0
+    maxJobWorkers: 0
+    preserveTilesOutsideBounds: 0
+    debug:
+      m_Flags: 0
+  m_NavMeshData: {fileID: 0}
+--- !u!1 &593071131
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 593071133}
+  - component: {fileID: 593071132}
+  - component: {fileID: 593071134}
+  m_Layer: 0
+  m_Name: UI
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!114 &593071132
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 593071131}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 19102, guid: 0000000000000000e000000000000000, type: 0}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_PanelSettings: {fileID: 11400000, guid: 0d7125098b341c74d868b72a1bacddf4, type: 2}
+  m_ParentUI: {fileID: 0}
+  sourceAsset: {fileID: 9197481963319205126, guid: 36bb0291e91398a4eb5292a944c1a564, type: 3}
+  m_SortingOrder: 0
+  m_WorldSpaceSizeMode: 1
+  m_WorldSpaceWidth: 1920
+  m_WorldSpaceHeight: 1080
+--- !u!4 &593071133
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 593071131}
+  serializedVersion: 2
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_ConstrainProportionsScale: 0
+  m_Children: []
+  m_Father: {fileID: 0}
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!114 &593071134
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 593071131}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 0f010025db7f850459585f88d184a50f, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+--- !u!1 &2030722889
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 2030722892}
+  - component: {fileID: 2030722891}
+  - component: {fileID: 2030722890}
+  m_Layer: 0
+  m_Name: Main Camera
+  m_TagString: MainCamera
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!81 &2030722890
+AudioListener:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 2030722889}
+  m_Enabled: 1
+--- !u!20 &2030722891
+Camera:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 2030722889}
+  m_Enabled: 1
+  serializedVersion: 2
+  m_ClearFlags: 1
+  m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0}
+  m_projectionMatrixMode: 1
+  m_GateFitMode: 2
+  m_FOVAxisMode: 0
+  m_Iso: 200
+  m_ShutterSpeed: 0.005
+  m_Aperture: 16
+  m_FocusDistance: 10
+  m_FocalLength: 50
+  m_BladeCount: 5
+  m_Curvature: {x: 2, y: 11}
+  m_BarrelClipping: 0.25
+  m_Anamorphism: 0
+  m_SensorSize: {x: 36, y: 24}
+  m_LensShift: {x: 0, y: 0}
+  m_NormalizedViewPortRect:
+    serializedVersion: 2
+    x: 0
+    y: 0
+    width: 1
+    height: 1
+  near clip plane: 0.3
+  far clip plane: 1000
+  field of view: 60
+  orthographic: 0
+  orthographic size: 5
+  m_Depth: -1
+  m_CullingMask:
+    serializedVersion: 2
+    m_Bits: 4294967295
+  m_RenderingPath: -1
+  m_TargetTexture: {fileID: 0}
+  m_TargetDisplay: 0
+  m_TargetEye: 3
+  m_HDR: 1
+  m_AllowMSAA: 1
+  m_AllowDynamicResolution: 0
+  m_ForceIntoRT: 0
+  m_OcclusionCulling: 1
+  m_StereoConvergence: 10
+  m_StereoSeparation: 0.022
+--- !u!4 &2030722892
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 2030722889}
+  serializedVersion: 2
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 1, z: -10}
+  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 &2039182133
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 2039182135}
+  - component: {fileID: 2039182134}
+  - component: {fileID: 2039182136}
+  m_Layer: 0
+  m_Name: Directional Light
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!108 &2039182134
+Light:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 2039182133}
+  m_Enabled: 1
+  serializedVersion: 11
+  m_Type: 1
+  m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1}
+  m_Intensity: 1
+  m_Range: 10
+  m_SpotAngle: 30
+  m_InnerSpotAngle: 21.80208
+  m_CookieSize: 10
+  m_Shadows:
+    m_Type: 2
+    m_Resolution: -1
+    m_CustomResolution: -1
+    m_Strength: 1
+    m_Bias: 0.05
+    m_NormalBias: 0.4
+    m_NearPlane: 0.2
+    m_CullingMatrixOverride:
+      e00: 1
+      e01: 0
+      e02: 0
+      e03: 0
+      e10: 0
+      e11: 1
+      e12: 0
+      e13: 0
+      e20: 0
+      e21: 0
+      e22: 1
+      e23: 0
+      e30: 0
+      e31: 0
+      e32: 0
+      e33: 1
+    m_UseCullingMatrixOverride: 0
+  m_Cookie: {fileID: 0}
+  m_DrawHalo: 0
+  m_Flare: {fileID: 0}
+  m_RenderMode: 0
+  m_CullingMask:
+    serializedVersion: 2
+    m_Bits: 4294967295
+  m_RenderingLayerMask: 1
+  m_Lightmapping: 4
+  m_LightShadowCasterMode: 0
+  m_AreaSize: {x: 1, y: 1}
+  m_BounceIntensity: 1
+  m_ColorTemperature: 6570
+  m_UseColorTemperature: 0
+  m_BoundingSphereOverride: {x: 0, y: 0, z: 0, w: 0}
+  m_UseBoundingSphereOverride: 0
+  m_UseViewFrustumForShadowCasterCull: 1
+  m_ForceVisible: 0
+  m_ShadowRadius: 0
+  m_ShadowAngle: 0
+  m_LightUnit: 1
+  m_LuxAtDistance: 1
+  m_EnableSpotReflector: 1
+--- !u!4 &2039182135
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 2039182133}
+  serializedVersion: 2
+  m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261}
+  m_LocalPosition: {x: 0, y: 3, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_ConstrainProportionsScale: 0
+  m_Children: []
+  m_Father: {fileID: 0}
+  m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0}
+--- !u!114 &2039182136
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 2039182133}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 474bcb49853aa07438625e644c072ee6, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Version: 3
+  m_UsePipelineSettings: 1
+  m_AdditionalLightsShadowResolutionTier: 2
+  m_LightLayerMask: 1
+  m_RenderingLayers: 1
+  m_CustomShadowLayers: 0
+  m_ShadowLayerMask: 1
+  m_ShadowRenderingLayers: 1
+  m_LightCookieSize: {x: 1, y: 1}
+  m_LightCookieOffset: {x: 0, y: 0}
+  m_SoftShadowQuality: 0
+--- !u!1660057539 &9223372036854775807
+SceneRoots:
+  m_ObjectHideFlags: 0
+  m_Roots:
+  - {fileID: 2030722892}
+  - {fileID: 2039182135}
+  - {fileID: 593071133}

+ 84 - 0
Assets/Scripts/BattleFieldMaker/BFMTerrainGenerator.cs

@@ -0,0 +1,84 @@
+using Unity.VisualScripting;
+using Unity.VisualScripting.Antlr3.Runtime.Tree;
+using UnityEngine;
+
+public class BFMTerrainGenerator : MonoBehaviour
+{
+    [Header("Terrain Settings")]
+    public float terrainMaxHeight = 20f;
+    public float hilliness = 1.0f;
+    public float noiseScale = 20f;
+    public BFMTerrainType terrainType;
+
+    public Terrain GenerateTerrain(int width, int height)
+    {
+        TerrainData terrainData = new TerrainData();
+
+        int heightmapResolution = width + 1;
+        terrainData.heightmapResolution = heightmapResolution;
+        terrainData.size = new Vector3(width, terrainMaxHeight, height);
+
+        // Generate heightmap
+        float[,] heights = GenerateHeights(heightmapResolution, heightmapResolution);
+        terrainData.SetHeights(0, 0, heights);
+
+        // Create terrain GameObject
+        GameObject terrainObject = Terrain.CreateTerrainGameObject(terrainData);
+        if (terrainObject == null)
+        {
+            Debug.LogError("Failed to create terrain object. Check if the terrain width and height are a power of two (e.g., 128, 256, 512).");
+            return null;
+        }
+        terrainObject.transform.parent = transform;
+
+        // Add a Terrain Collider
+        terrainObject.GetComponent<TerrainCollider>().terrainData = terrainData;
+
+        return terrainObject.GetComponent<Terrain>();
+    }
+
+    private float[,] GenerateHeights(int mapWidth, int mapHeight)
+    {
+        float[,] heights = new float[mapWidth, mapHeight];
+        float seed = Random.Range(0, 10000);
+
+        // adjust noise parameters based on terrain type
+        float currentNoiseScale = noiseScale;
+        float currentHilliness = hilliness;
+
+        switch (terrainType)
+        {
+            case BFMTerrainType.Forest:
+                currentHilliness *= 0.5f;
+                break;
+            case BFMTerrainType.Mountain:
+                currentNoiseScale *= 0.5f; // more frequent peaks
+                currentHilliness *= 2.0f;
+                break;
+            case BFMTerrainType.Plain:
+                currentHilliness *= 0.1f;
+                break;
+        }
+
+        for (int x = 0; x < mapWidth; x++)
+        {
+            for (int y = 0; y < mapHeight; y++)
+            {
+                float xCoord = (float)x / mapWidth * currentNoiseScale + seed;
+                float yCoord = (float)y / mapHeight * currentNoiseScale + seed;
+
+                // Generate height using Perlin noise
+                heights[x, y] = Mathf.PerlinNoise(xCoord, yCoord) * currentHilliness;
+            }
+        }
+        return heights;
+    }
+
+    public void SetTerrainType(BFMTerrainType type)
+    {
+        terrainType = type;
+        // To see the changes, the terrain needs to be regenerated.
+    }
+
+    // Additional methods for generating specific terrain features can be added here
+}

+ 6 - 0
Assets/Scripts/BattleFieldMaker/BFMTerrainType.cs

@@ -0,0 +1,6 @@
+public enum BFMTerrainType
+{
+    Plain,
+    Forest,
+    Mountain
+}

+ 110 - 0
Assets/Scripts/BattleFieldMaker/BattleFieldMaker.cs

@@ -0,0 +1,110 @@
+using System.Runtime.CompilerServices;
+using UnityEngine;
+
+public class MapMakerMain : MonoBehaviour
+{
+
+    // Terrain width and height must be a power of two (e.g., 64, 128, 256)
+    // for a valid heightmap resolution (power of two + 1).
+    [SerializeField] private int mapWidth = 128;
+    [SerializeField] private int mapHeight = 128;
+    [SerializeField] private BFMTerrainType initialTerrainType = BFMTerrainType.Plain;
+    [SerializeField][Range(0.1f, 5.0f)] private float hilliness = 1.0f;
+    [SerializeField][Range(1f, 20f)] private float noiseScale = 10f;
+    [SerializeField][Range(10f, 200f)] private float terrainMaxHeight = 20f;
+
+    private BFMTerrainGenerator terrainGenerator;
+    private NavMeshGenerator navMeshGenerator;
+    private Terrain currentTerrain;
+
+    void Start()
+    {
+        terrainGenerator = gameObject.AddComponent<BFMTerrainGenerator>();
+        navMeshGenerator = gameObject.AddComponent<NavMeshGenerator>();
+
+        // Initialize the map with specified dimensions
+        InitializeComponents();
+        GenerateMap(mapWidth, mapHeight);
+    }
+
+
+
+#if UNITY_EDITOR
+    private bool m_DelayedUpdateScheduled = false;
+    private void OnValidate()
+    {
+        if (m_DelayedUpdateScheduled) return;
+
+        UnityEditor.EditorApplication.delayCall += () =>
+        {
+            m_DelayedUpdateScheduled = false;
+
+            // OnValidate can be called on prefabs, or when the component is not fully initialized.
+            // We only want to run this on scene objects that are not being destroyed.
+            if (this == null || !gameObject.scene.IsValid())
+            {
+                return;
+            }
+
+            InitializeComponents();
+            GenerateMap(mapWidth, mapHeight);
+        };
+
+        m_DelayedUpdateScheduled = true;
+    }
+#endif
+
+    private void InitializeComponents()
+    {
+        // Use GetComponent first to avoid adding multiple components if they already exist
+        if (terrainGenerator == null)
+        {
+            terrainGenerator = GetComponent<BFMTerrainGenerator>();
+            if (terrainGenerator == null)
+            {
+                terrainGenerator = gameObject.AddComponent<BFMTerrainGenerator>();
+            }
+
+            navMeshGenerator = GetComponent<NavMeshGenerator>();
+            if (navMeshGenerator == null)
+            {
+                navMeshGenerator = gameObject.AddComponent<NavMeshGenerator>();
+            }
+
+        }
+    }
+
+    private void GenerateMap(int width, int height)
+    {
+        // Cleanup old terrain if it exists
+        if (currentTerrain != null)
+        {
+            if (Application.isPlaying)
+            {
+                Destroy(currentTerrain.gameObject);
+            }
+            else
+            {
+                // Use DestroyImmediate when in the editor and not in play mode.
+                DestroyImmediate(currentTerrain.gameObject);
+            }
+        }
+
+        // Configure TerrainGenerator from MapMakerMain settings
+        terrainGenerator.terrainType = initialTerrainType;
+        terrainGenerator.hilliness = hilliness;
+        terrainGenerator.noiseScale = noiseScale;
+        terrainGenerator.terrainMaxHeight = terrainMaxHeight;
+
+        // Generate terrain and NavMesh based on specified dimensions
+        // Adjust the arguments below to match the correct overload of GenerateTerrain
+        currentTerrain = terrainGenerator.GenerateTerrain(width, height);
+        if (currentTerrain == null)
+        {
+            Debug.LogError("Terrain generation failed. Aborting map generation.");
+            return;
+        }
+        navMeshGenerator.terrain = currentTerrain;
+        navMeshGenerator.GenerateNavMesh();
+    }
+}

+ 180 - 0
Assets/Scripts/BattleFieldMaker/FantasyNameGenerator.cs

@@ -0,0 +1,180 @@
+using UnityEngine;
+using System.Collections.Generic;
+
+public static class FantasyNameGenerator
+{
+    // Town name components
+    private static readonly string[] townPrefixes = {
+        "North", "South", "East", "West", "Upper", "Lower", "Old", "New", "High", "Deep",
+        "Iron", "Gold", "Silver", "Stone", "Wood", "Green", "Red", "White", "Black", "Blue",
+        "Dragon", "Eagle", "Wolf", "Bear", "Lion", "Oak", "Pine", "Ash", "Elm", "Willow",
+        "Storm", "Wind", "Sun", "Moon", "Star", "Shadow", "Light", "Dark", "Bright", "Swift"
+    };
+
+    private static readonly string[] townSuffixes = {
+        "haven", "ford", "bridge", "gate", "hill", "dale", "vale", "moor", "field", "wood",
+        "burg", "ton", "ham", "wick", "thorpe", "by", "stead", "hurst", "marsh", "brook",
+        "glen", "ridge", "peak", "crest", "hollow", "bend", "crossing", "falls", "rapids", "port",
+        "watch", "guard", "hold", "keep", "tower", "wall", "stone", "rock", "cliff", "shore"
+    };
+
+    // Village name components (smaller, more rural)
+    private static readonly string[] villagePrefixes = {
+        "Little", "Small", "Quiet", "Peaceful", "Hidden", "Lost", "Forgotten", "Ancient", "Humble", "Simple",
+        "Moss", "Fern", "Ivy", "Rose", "Lily", "Daisy", "Thistle", "Heather", "Sage", "Mint",
+        "Rabbit", "Fox", "Deer", "Sheep", "Goat", "Duck", "Goose", "Crow", "Sparrow", "Robin",
+        "Brook", "Creek", "Stream", "Pond", "Spring", "Well", "Mill", "Farm", "Orchard", "Garden"
+    };
+
+    private static readonly string[] villageSuffixes = {
+        "hollow", "grove", "glen", "meadow", "vale", "dell", "nook", "corner", "bend", "twist",
+        "green", "common", "field", "yard", "patch", "plot", "clearing", "glade", "thicket", "copse",
+        "end", "side", "edge", "rim", "foot", "base", "rest", "peace", "quiet", "still"
+    };
+
+    // Forest name components
+    private static readonly string[] forestPrefixes = {
+        "Ancient", "Dark", "Deep", "Wild", "Mystic", "Enchanted", "Whispering", "Silent", "Sacred", "Forbidden",
+        "Elder", "Old", "Primeval", "Twisted", "Tangled", "Dense", "Thick", "Shadowy", "Moonlit", "Sunlit",
+        "Emerald", "Verdant", "Lush", "Green", "Golden", "Amber", "Crimson", "Silver", "Misty", "Foggy"
+    };
+
+    private static readonly string[] forestSuffixes = {
+        "Wood", "Woods", "Forest", "Grove", "Thicket", "Copse", "Brake", "Weald", "Wildwood", "Greenwood",
+        "Timberland", "Woodland", "Glade", "Dell", "Hollow", "Vale", "Glen", "Chase", "Park", "Reserve"
+    };
+
+    // Water body name components
+    private static readonly string[] waterPrefixes = {
+        "Crystal", "Clear", "Deep", "Blue", "Azure", "Sapphire", "Emerald", "Silver", "Golden", "Mirror",
+        "Calm", "Still", "Peaceful", "Serene", "Tranquil", "Misty", "Foggy", "Hidden", "Secret", "Lost",
+        "Dragon", "Serpent", "Swan", "Eagle", "Raven", "Heron", "Crane", "Trout", "Salmon", "Pike"
+    };
+
+    private static readonly string[] lakeSuffixes = {
+        "Lake", "Pond", "Pool", "Mere", "Tarn", "Loch", "Water", "Waters", "Basin", "Reservoir"
+    };
+
+    private static readonly string[] oceanSuffixes = {
+        "Sea", "Ocean", "Bay", "Gulf", "Sound", "Strait", "Channel", "Depths", "Expanse", "Waters"
+    };
+
+    // Male character name components
+    private static readonly string[] maleFirstNames = {
+        "Aedric", "Aldwin", "Baelor", "Cedric", "Dorian", "Edmund", "Gareth", "Henrik", "Ivar", "Jasper",
+        "Kieran", "Leoric", "Magnus", "Nolan", "Osric", "Percival", "Quinton", "Roderick", "Soren", "Theron",
+        "Ulric", "Victor", "Willem", "Xavier", "Yorick", "Zander", "Alaric", "Bastian", "Caspian", "Darius",
+        "Elias", "Felix", "Gideon", "Hadrian", "Ivan", "Joren", "Kael", "Lucian", "Matthias", "Nikolai",
+        "Orion", "Phoenix", "Quin", "Raphael", "Sebastian", "Tristan", "Uther", "Varian", "Warden", "Xander"
+    };
+
+    private static readonly string[] maleLastNames = {
+        "Ironforge", "Stormwind", "Blackwater", "Goldleaf", "Silverstone", "Redmane", "Whitehawk", "Greycloak",
+        "Dragonbane", "Wolfheart", "Bearclaw", "Lionmane", "Eaglefeather", "Ravencrest", "Swiftarrow", "Steelborn",
+        "Frostbeard", "Fireborn", "Shadowbane", "Lightbringer", "Darkblade", "Brightshield", "Strongarm", "Swiftstrike",
+        "Stonehammer", "Ironwill", "Goldenshield", "Silverwind", "Blackthorne", "Whitestone", "Redguard", "Greenvale",
+        "Nightfall", "Dawnbreaker", "Moonwhisper", "Sunblade", "Stargazer", "Stormcaller", "Windrunner", "Earthshaker"
+    };
+
+    // Female character name components
+    private static readonly string[] femaleFirstNames = {
+        "Aria", "Brenna", "Celeste", "Diana", "Elara", "Fiona", "Gwendolyn", "Helena", "Iris", "Jasmine",
+        "Kira", "Luna", "Mira", "Nora", "Ophelia", "Penelope", "Quinn", "Rosalind", "Sera", "Thalia",
+        "Una", "Vera", "Willow", "Xara", "Yara", "Zara", "Adelina", "Beatrice", "Cordelia", "Delphine",
+        "Evangeline", "Freya", "Guinevere", "Hazel", "Isolde", "Josephine", "Katarina", "Lyanna", "Morgana", "Natasha",
+        "Octavia", "Persephone", "Quintessa", "Raven", "Selene", "Titania", "Ursula", "Vivienne", "Winifred", "Xylia"
+    };
+
+    private static readonly string[] femaleLastNames = {
+        "Moonwhisper", "Starweaver", "Roseheart", "Silverleaf", "Goldenbraid", "Whitedove", "Redrose", "Greenvine",
+        "Nightsong", "Dawnlight", "Shadowdancer", "Lightweaver", "Brightmoon", "Darkrose", "Swiftwind", "Gentleheart",
+        "Silverblossom", "Goldenpetal", "Crystalbrook", "Pearlwater", "Sapphiregaze", "Emeraldwing", "Rubyflame", "Amberlight",
+        "Ivythorn", "Willowbend", "Oakenshield", "Birchwood", "Elmshade", "Ashbloom", "Thornwick", "Briarrose",
+        "Mistwalker", "Cloudwhisper", "Rainbringer", "Snowfall", "Frostbloom", "Iceheart", "Flamekeeper", "Embersong"
+    };
+
+    public static string GenerateTownName()
+    {
+        string prefix = townPrefixes[Random.Range(0, townPrefixes.Length)];
+        string suffix = townSuffixes[Random.Range(0, townSuffixes.Length)];
+        return prefix + suffix;
+    }
+
+    public static string GenerateVillageName()
+    {
+        string prefix = villagePrefixes[Random.Range(0, villagePrefixes.Length)];
+        string suffix = villageSuffixes[Random.Range(0, villageSuffixes.Length)];
+        return prefix + suffix;
+    }
+
+    public static string GenerateForestName()
+    {
+        string prefix = forestPrefixes[Random.Range(0, forestPrefixes.Length)];
+        string suffix = forestSuffixes[Random.Range(0, forestSuffixes.Length)];
+        return prefix + " " + suffix;
+    }
+
+    public static string GenerateLakeName()
+    {
+        string prefix = waterPrefixes[Random.Range(0, waterPrefixes.Length)];
+        string suffix = lakeSuffixes[Random.Range(0, lakeSuffixes.Length)];
+        return prefix + " " + suffix;
+    }
+
+    public static string GenerateOceanName()
+    {
+        string prefix = waterPrefixes[Random.Range(0, waterPrefixes.Length)];
+        string suffix = oceanSuffixes[Random.Range(0, oceanSuffixes.Length)];
+        return prefix + " " + suffix;
+    }
+
+    public static string GenerateMaleCharacterName()
+    {
+        string firstName = maleFirstNames[Random.Range(0, maleFirstNames.Length)];
+        string lastName = maleLastNames[Random.Range(0, maleLastNames.Length)];
+        return firstName + " " + lastName;
+    }
+
+    public static string GenerateFemaleCharacterName()
+    {
+        string firstName = femaleFirstNames[Random.Range(0, femaleFirstNames.Length)];
+        string lastName = femaleLastNames[Random.Range(0, femaleLastNames.Length)];
+        return firstName + " " + lastName;
+    }
+
+    public static string GenerateCharacterName(bool isMale = true)
+    {
+        return isMale ? GenerateMaleCharacterName() : GenerateFemaleCharacterName();
+    }
+
+    // Generate multiple names for different regions/clusters
+    public static List<string> GenerateMultipleNames(int count, System.Func<string> generator)
+    {
+        List<string> names = new List<string>();
+        HashSet<string> usedNames = new HashSet<string>();
+
+        for (int i = 0; i < count; i++)
+        {
+            string name;
+            int attempts = 0;
+            do
+            {
+                name = generator();
+                attempts++;
+            } while (usedNames.Contains(name) && attempts < 50);
+
+            if (!usedNames.Contains(name))
+            {
+                names.Add(name);
+                usedNames.Add(name);
+            }
+            else
+            {
+                // If we can't generate a unique name, add a number
+                names.Add(name + " " + (i + 1));
+            }
+        }
+
+        return names;
+    }
+}

+ 112 - 0
Assets/Scripts/BattleFieldMaker/MapCameraController.cs

@@ -0,0 +1,112 @@
+using UnityEngine;
+using UnityEngine.EventSystems;
+
+public class MapCameraController : MonoBehaviour
+{
+    [Header("Camera Movement")]
+    public float moveSpeed = 10f;
+    public float zoomSpeed = 5f;
+    public float minZoom = 5f;
+    public float maxZoom = 50f;
+    public float initialZoom = 35f; // Starting zoom level to see more of the map
+
+    private Camera cam;
+    private Vector3 targetPosition;
+    private float targetSize;
+
+    void Start()
+    {
+        cam = GetComponent<Camera>();
+        if (cam == null)
+            cam = Camera.main;
+
+        // Set camera to look straight down
+        transform.rotation = Quaternion.Euler(90f, 0f, 0f);
+
+        // Position camera above the center of the map (assuming 100x100 map)
+        transform.position = new Vector3(50f, 30f, 50f);
+
+        targetPosition = transform.position;
+        targetSize = initialZoom;
+        cam.orthographicSize = initialZoom;
+
+        // Ensure camera is orthographic for top-down view
+        cam.orthographic = true;
+    }
+
+    void Update()
+    {
+        // Only handle camera input if mouse is within the map area
+        if (IsMouseInMapArea())
+        {
+            HandleMovement();
+            HandleZoom();
+        }
+
+        // Always smooth camera movement (even if input is disabled)
+        transform.position = Vector3.Lerp(transform.position, targetPosition, Time.deltaTime * 5f);
+        cam.orthographicSize = Mathf.Lerp(cam.orthographicSize, targetSize, Time.deltaTime * 5f);
+    }
+
+    void HandleMovement()
+    {
+        Vector3 moveDirection = Vector3.zero;
+
+        // WASD or Arrow Keys movement
+        if (Input.GetKey(KeyCode.W) || Input.GetKey(KeyCode.UpArrow))
+            moveDirection.z += 1f;
+        if (Input.GetKey(KeyCode.S) || Input.GetKey(KeyCode.DownArrow))
+            moveDirection.z -= 1f;
+        if (Input.GetKey(KeyCode.A) || Input.GetKey(KeyCode.LeftArrow))
+            moveDirection.x -= 1f;
+        if (Input.GetKey(KeyCode.D) || Input.GetKey(KeyCode.RightArrow))
+            moveDirection.x += 1f;
+
+        // Apply movement
+        targetPosition += moveDirection.normalized * moveSpeed * Time.deltaTime;
+
+        // Keep camera within reasonable bounds (adjust based on your map size)
+        targetPosition.x = Mathf.Clamp(targetPosition.x, -20f, 120f);
+        targetPosition.z = Mathf.Clamp(targetPosition.z, -20f, 120f);
+    }
+
+    void HandleZoom()
+    {
+        float scroll = Input.GetAxis("Mouse ScrollWheel");
+        if (scroll != 0f)
+        {
+            targetSize -= scroll * zoomSpeed;
+            targetSize = Mathf.Clamp(targetSize, minZoom, maxZoom);
+        }
+    }
+
+    /// <summary>
+    /// Check if the mouse is currently within the map area (not in UI panels)
+    /// </summary>
+    /// <returns>True if mouse is in the map area, false if in UI areas</returns>
+    private bool IsMouseInMapArea()
+    {
+        Vector2 mousePosition = Input.mousePosition;
+
+        // Define the map area bounds (adjust these values based on your UI layout)
+        // These values represent the approximate red square area from your image
+        float leftUIWidth = 150f;      // Map Legend panel width
+        float rightUIWidth = 300f;     // Your Team panel width
+        float topUIHeight = 0f;        // No top UI currently
+        float bottomUIHeight = 0f;     // No bottom UI currently
+
+        // Calculate the actual map area
+        float mapLeft = leftUIWidth;
+        float mapRight = Screen.width - rightUIWidth;
+        float mapTop = Screen.height - topUIHeight;
+        float mapBottom = bottomUIHeight;
+
+        // Check if mouse is within the map area
+        bool inMapArea = mousePosition.x >= mapLeft &&
+                        mousePosition.x <= mapRight &&
+                        mousePosition.y >= mapBottom &&
+                        mousePosition.y <= mapTop;
+
+        return inMapArea;
+    }
+}

+ 93 - 0
Assets/Scripts/BattleFieldMaker/MapLegendUI.cs

@@ -0,0 +1,93 @@
+using UnityEngine;
+using UnityEngine.UIElements;
+
+public class MapLegendUI : MonoBehaviour
+{
+    [Header("UI References")]
+    public UIDocument uiDocument;
+    public VisualTreeAsset legendTemplate;
+    public StyleSheet legendStyleSheet;
+
+    private VisualElement root;
+
+    void Start()
+    {
+        SetupUI();
+    }
+
+    void SetupUI()
+    {
+        Debug.Log("SetupUI called");
+        // Get the UI Document component
+        if (uiDocument == null)
+            uiDocument = GetComponent<UIDocument>();
+
+        if (uiDocument == null)
+        {
+            Debug.LogError("UIDocument component not found on MapLegendUI GameObject!");
+            return;
+        }
+
+        Debug.Log("UIDocument found");
+
+        // Load the UXML template if not assigned
+        if (legendTemplate == null)
+        {
+            // Try multiple paths to find the UXML file
+            legendTemplate = Resources.Load<VisualTreeAsset>("UI/MapLegend");
+            if (legendTemplate == null)
+            {
+                legendTemplate = Resources.Load<VisualTreeAsset>("MapLegend");
+                if (legendTemplate == null)
+                {
+                    Debug.LogError("MapLegend.uxml not found! Make sure it's in a Resources folder.");
+                    return;
+                }
+            }
+        }
+
+        Debug.Log("UXML template loaded");
+
+        // Load the USS stylesheet if not assigned
+        if (legendStyleSheet == null)
+        {
+            // Try multiple paths to find the USS file
+            legendStyleSheet = Resources.Load<StyleSheet>("UI/MapLegend");
+            if (legendStyleSheet == null)
+            {
+                legendStyleSheet = Resources.Load<StyleSheet>("MapLegend");
+                if (legendStyleSheet == null)
+                {
+                    Debug.LogWarning("MapLegend.uss not found - using default styling");
+                }
+            }
+        }
+
+        Debug.Log("USS stylesheet loaded");
+
+        // Clone the template and add it to the document
+        root = uiDocument.rootVisualElement;
+        var legendElement = legendTemplate.Instantiate();
+
+        Debug.Log("Template instantiated");
+
+        // Add the stylesheet if available
+        if (legendStyleSheet != null)
+        {
+            root.styleSheets.Add(legendStyleSheet);
+        }
+
+        // Add the legend to the root
+        root.Add(legendElement);
+
+        // Initialize legend as visible
+        var legend = root.Q("MapLegend");
+        if (legend != null)
+        {
+            legend.style.display = DisplayStyle.Flex;
+            Debug.Log("Legend initialized as visible");
+        }
+
+        Debug.Log("Legend UI setup complete");
+    }
+}

+ 21 - 0
Assets/Scripts/BattleFieldMaker/NavMeshGenerator.cs

@@ -0,0 +1,21 @@
+using Unity.AI.Navigation;
+using UnityEngine;
+using UnityEngine.AI;
+
+public class NavMeshGenerator : MonoBehaviour
+{
+    public Terrain terrain;
+
+    public void GenerateNavMesh()
+    {
+        if (terrain == null) return;
+
+
+        NavMeshSurface surface = GetComponent<NavMeshSurface>();
+        if (surface == null)
+        {
+            surface = gameObject.AddComponent<NavMeshSurface>();
+        }
+        surface.BuildNavMesh();
+    }
+}

+ 139 - 0
Assets/Scripts/BattleFieldMaker/README_FantasyNaming.md

@@ -0,0 +1,139 @@
+# World Map Fantasy Naming & Hover System
+
+This system adds fantasy-style names to your procedurally generated world map and provides interactive hover tooltips with highlighting.
+
+## Features
+
+### 🏰 Fantasy Names
+- **Towns**: Names like "Ironhaven", "Dragonbridge", "Stormhold"
+- **Villages**: Names like "Littlehollow", "Peaceful meadow", "Rabbit's end"
+- **Forests**: Names like "Ancient Wildwood", "Whispering Grove", "Dark Thicket"
+- **Water Bodies**: Names like "Crystal Lake", "Dragon Sea", "Silver Waters"
+
+### 🖱️ Interactive Hover System
+- **Tooltips**: Hover over named locations to see their names
+- **Highlighting**: Primary highlight on hovered tile, secondary highlight on connected tiles
+- **Smart Grouping**: Related tiles (like 3x3 towns) are grouped under one name
+
+## Setup Instructions
+
+### Automatic Setup (Recommended)
+1. Add the `MapSceneSetup` component to any GameObject in your scene
+2. Check "Auto Setup On Start" (enabled by default)
+3. Play the scene - everything will be set up automatically!
+
+### Manual Setup
+1. Ensure your scene has a `WorldMapGenerator` component
+2. Add a Camera with `MapCameraController` component
+3. Create a GameObject with `TooltipSystem` and `UIDocument` components
+4. Create a GameObject with `TileHoverHandler` component
+
+## Components Overview
+
+### 🎯 Core Components
+
+#### `FantasyNameGenerator`
+- Static class with name generation methods
+- Generates unique fantasy names for different location types
+- Prevents duplicate names within regions
+
+#### `TileHoverHandler`
+- Detects mouse hover over map tiles
+- Groups tiles into named regions using flood-fill algorithms
+- Handles highlighting of tiles and connected regions
+- Manages name assignment to tiles
+
+#### `TooltipSystem`
+- Singleton pattern for global tooltip management
+- Creates and positions tooltips dynamically
+- Follows mouse cursor with smart positioning
+
+#### `MapSceneSetup`
+- Helper component for easy scene setup
+- Context menu options for setup and map regeneration
+- Automatically configures all required components
+
+## Usage
+
+### In Play Mode
+1. **Move Camera**: Use WASD keys to move around the map
+2. **Zoom**: Use mouse scroll wheel to zoom in/out
+3. **View Names**: Hover mouse over towns, villages, forests, or water bodies
+4. **See Connections**: Notice how related tiles (like town areas) highlight together
+
+### Name Generation Rules
+- **Towns**: Get 3x3 tile areas, all tiles share the same name
+- **Villages**: Single tiles with individual names
+- **Forests**: Connected forest regions share names (minimum 5 tiles)
+- **Water Bodies**: Connected water areas share names (minimum 3 tiles)
+
+### Highlighting System
+- **Primary**: Yellow highlight on the exact tile you're hovering
+- **Secondary**: Lighter yellow on connected tiles of the same named region
+- **Materials**: Automatically created if not assigned in inspector
+
+## Customization
+
+### Name Lists
+Edit the arrays in `FantasyNameGenerator.cs` to customize:
+- `townPrefixes` / `townSuffixes` for town names
+- `villagePrefixes` / `villageSuffixes` for village names
+- `forestPrefixes` / `forestSuffixes` for forest names
+- `waterPrefixes` / `lakeSuffixes` / `oceanSuffixes` for water names
+
+### Highlight Materials
+In the `TileHoverHandler` component inspector:
+- `Highlight Material`: Primary highlight (default: yellow)
+- `Secondary Highlight Material`: Connected tiles (default: light yellow)
+
+### Minimum Region Sizes
+In `TileHoverHandler.cs`, adjust these values:
+- Forest regions: Change `>= 5` in `NameForests()` method
+- Water regions: Change `>= 3` in `NameWaterBodies()` method
+
+## Debugging
+
+### Context Menu Options
+Right-click on `MapSceneSetup` component:
+- **Setup Scene**: Manually set up all required components
+- **Regenerate Map**: Create a new map with new names
+
+### Console Logs
+The system provides debug output for:
+- Scene setup progress
+- Name generation statistics
+- Component creation confirmations
+
+### Public Methods
+- `TileHoverHandler.GetTileName(int x, int y)`: Get the name of a specific tile
+- `MapSceneSetup.RegenerateMap()`: Generate a new map programmatically
+
+## Performance Notes
+
+- Names are generated once when the map is created
+- Hover detection uses Unity's physics raycast system
+- Materials are cached to avoid creating duplicates
+- Flood-fill algorithms run once during name assignment
+
+## Troubleshooting
+
+### No Tooltips Appearing
+- Ensure `TooltipSystem` exists in scene with `UIDocument` component
+- Check that tiles have colliders (auto-added by `WorldMapGenerator`)
+
+### No Highlighting
+- Verify `TileHoverHandler` component exists in scene
+- Check that highlight materials are created/assigned
+
+### Names Not Showing
+- Ensure map generation completed before hovering
+- Check console for name generation debug messages
+
+## Future Enhancements
+
+Potential additions you could implement:
+- Road and river names
+- Mountain range names
+- Cultural/regional naming themes
+- Name persistence between sessions
+- Custom name import from files

+ 44 - 0
Assets/Scripts/BattleFieldMaker/SeasonManager.cs

@@ -0,0 +1,44 @@
+using UnityEngine;
+
+public class SeasonManager : MonoBehaviour
+{
+    public enum Season
+    {
+        Spring,
+        Summer,
+        Autumn,
+        Winter
+    }
+
+    [SerializeField] private Season currentSeason;
+
+    private void Start()
+    {
+        UpdateTerrainForSeason();
+    }
+
+    public void ChangeSeason(Season newSeason)
+    {
+        currentSeason = newSeason;
+        UpdateTerrainForSeason();
+    }
+
+    private void UpdateTerrainForSeason()
+    {
+        switch (currentSeason)
+        {
+            case Season.Spring:
+                // Logic to update terrain for Spring
+                break;
+            case Season.Summer:
+                // Logic to update terrain for Summer
+                break;
+            case Season.Autumn:
+                // Logic to update terrain for Autumn
+                break;
+            case Season.Winter:
+                // Logic to update terrain for Winter
+                break;
+        }
+    }
+}

+ 137 - 0
Assets/Scripts/BattleFieldMaker/TooltipSystem.cs

@@ -0,0 +1,137 @@
+using UnityEngine;
+using UnityEngine.UIElements;
+
+public class TooltipSystem : MonoBehaviour
+{
+    [Header("UI References")]
+    public UIDocument uiDocument;
+
+    [Header("Debug")]
+    public bool debugMode = true;
+
+    private VisualElement tooltipContainer;
+    private Label tooltipLabel;
+    private static TooltipSystem instance;
+    private bool isSetup = false;
+
+    public static TooltipSystem Instance => instance; void Awake()
+    {
+        if (instance == null)
+        {
+            instance = this;
+            DontDestroyOnLoad(gameObject);
+        }
+        else
+        {
+            Destroy(gameObject);
+        }
+    }
+
+    void Start()
+    {
+        if (debugMode) Debug.Log("TooltipSystem Start() called");
+        SetupTooltip();
+    }
+
+    void SetupTooltip()
+    {
+        if (debugMode) Debug.Log("Setting up tooltip system...");
+
+        if (uiDocument == null)
+            uiDocument = GetComponent<UIDocument>();
+
+        if (uiDocument == null)
+        {
+            Debug.LogError("UIDocument component not found on TooltipSystem!");
+            return;
+        }
+
+        if (debugMode) Debug.Log("UIDocument found, creating tooltip UI...");
+
+        // Create tooltip UI programmatically
+        var root = uiDocument.rootVisualElement;
+
+        tooltipContainer = new VisualElement();
+        tooltipContainer.name = "tooltip-container";
+        tooltipContainer.style.position = Position.Absolute;
+        tooltipContainer.style.backgroundColor = new Color(0, 0, 0, 0.8f);
+        tooltipContainer.style.borderTopWidth = 2;
+        tooltipContainer.style.borderBottomWidth = 2;
+        tooltipContainer.style.borderLeftWidth = 2;
+        tooltipContainer.style.borderRightWidth = 2;
+        tooltipContainer.style.borderTopColor = Color.white;
+        tooltipContainer.style.borderBottomColor = Color.white;
+        tooltipContainer.style.borderLeftColor = Color.white;
+        tooltipContainer.style.borderRightColor = Color.white;
+        tooltipContainer.style.borderTopLeftRadius = 5;
+        tooltipContainer.style.borderTopRightRadius = 5;
+        tooltipContainer.style.borderBottomLeftRadius = 5;
+        tooltipContainer.style.borderBottomRightRadius = 5;
+        tooltipContainer.style.paddingTop = 8;
+        tooltipContainer.style.paddingBottom = 8;
+        tooltipContainer.style.paddingLeft = 12;
+        tooltipContainer.style.paddingRight = 12;
+        tooltipContainer.style.display = DisplayStyle.None;
+
+        tooltipLabel = new Label();
+        tooltipLabel.style.color = Color.white;
+        tooltipLabel.style.fontSize = 14;
+        tooltipLabel.style.whiteSpace = WhiteSpace.NoWrap;
+
+        tooltipContainer.Add(tooltipLabel);
+        root.Add(tooltipContainer);
+
+        isSetup = true;
+        if (debugMode) Debug.Log("Tooltip system setup complete!");
+    }
+
+    public void ShowTooltip(string text, Vector2 screenPosition)
+    {
+        if (!isSetup || tooltipContainer == null || tooltipLabel == null)
+        {
+            if (debugMode) Debug.LogWarning("Tooltip system not setup properly!");
+            return;
+        }
+
+        tooltipLabel.text = text;
+        tooltipContainer.style.display = DisplayStyle.Flex;
+
+        // Position tooltip near mouse but keep it on screen
+        var containerRect = tooltipContainer.parent.contentRect;
+        float tooltipWidth = 200; // Estimated width
+        float tooltipHeight = 30; // Estimated height
+
+        float x = screenPosition.x + 10;
+        float y = screenPosition.y - 30;
+
+        // Keep tooltip on screen
+        if (x + tooltipWidth > containerRect.width)
+            x = screenPosition.x - tooltipWidth - 10;
+        if (y < 0)
+            y = screenPosition.y + 10;
+        if (y + tooltipHeight > containerRect.height)
+            y = containerRect.height - tooltipHeight;
+
+        tooltipContainer.style.left = x;
+        tooltipContainer.style.top = y;
+    }
+
+    public void HideTooltip()
+    {
+        if (tooltipContainer != null)
+        {
+            tooltipContainer.style.display = DisplayStyle.None;
+        }
+    }
+
+    void Update()
+    {
+        // Update tooltip position if it's visible
+        if (tooltipContainer != null && tooltipContainer.style.display == DisplayStyle.Flex)
+        {
+            Vector2 mousePos = Input.mousePosition;
+            mousePos.y = Screen.height - mousePos.y; // Flip Y coordinate for UI
+            ShowTooltip(tooltipLabel.text, mousePos);
+        }
+    }
+}

+ 21 - 0
Assets/Scripts/BattleFieldMaker/Utils/MathHelper.cs

@@ -0,0 +1,21 @@
+using UnityEngine;
+
+public static class MathHelpers
+{
+    public static float PerlinNoise2D(float x, float y, float scale)
+    {
+        return Mathf.PerlinNoise(x / scale, y / scale);
+    }
+
+    public static float CalculateSlope(Vector3 pointA, Vector3 pointB)
+    {
+        return Mathf.Abs(pointB.y - pointA.y) / Vector3.Distance(pointA, pointB);
+    }
+
+    public static Vector3 GetRandomPointInRange(Vector3 center, float range)
+    {
+        float x = Random.Range(center.x - range, center.x + range);
+        float z = Random.Range(center.z - range, center.z + range);
+        return new Vector3(x, center.y, z);
+    }
+}

+ 68 - 0
Assets/Scripts/BattleFieldMaker/Visual_Names_Instructions.md

@@ -0,0 +1,68 @@
+# How to Use the Visual Map Names System
+
+## Quick Setup
+
+1. **Make sure you have the MapSceneSetup script** attached to any GameObject in your scene
+2. **Play the scene** - it will automatically set up all components
+3. **Names will appear on the map** by default as white text labels
+4. **Press N key** to toggle names on/off
+5. **Hover over locations** to see tooltips and highlighting
+
+## What You'll See
+
+### Visual Names on Map
+- **Towns**: Large names at the center of 3x3 town areas
+- **Villages**: Names above single village tiles  
+- **Forests**: Names at the center of connected forest regions
+- **Lakes/Waters**: Names at the center of water bodies
+
+### Interactive Features
+- **Hover tooltips**: Move mouse over named areas to see tooltips
+- **Region highlighting**: Primary (yellow) on hovered tile, secondary (light yellow) on connected tiles
+- **Toggle display**: Press **N key** to show/hide all names
+- **Road naming removed**: Roads no longer get names (as requested)
+
+## Controls
+
+- **WASD**: Move camera around map
+- **Mouse Scroll**: Zoom in/out
+- **Mouse Hover**: Show tooltips and highlighting  
+- **N Key**: Toggle permanent name display on/off
+
+## Customization
+
+### In MapNameDisplay Component Inspector:
+- **Text Font**: Assign a custom font (optional)
+- **Font Size**: Adjust text size (default: 14)
+- **Text Color**: Change text color (default: white)
+- **Text Outline Color**: Change outline color (default: black)
+- **Text Height**: How high above tiles the text appears
+- **Show Names On Start**: Whether names show immediately when scene loads
+- **Toggle Display Key**: Which key toggles names (default: N)
+
+### Debugging
+- Set **Debug Mode** to true in both TileHoverHandler and MapNameDisplay
+- Check console for name generation and display messages
+
+## Troubleshooting
+
+### No Names Visible
+1. Make sure MapSceneSetup script is on a GameObject in the scene
+2. Check that MapNameDisplay component was created (look in hierarchy)
+3. Try pressing N key to toggle names
+4. Check console for error messages
+
+### Names Don't Update After Map Regeneration
+- Use the "Regenerate Map" context menu on MapSceneSetup component
+- Or manually call nameDisplay.RefreshLabels() in code
+
+### Names Not Facing Camera
+- Make sure camera is tagged as "MainCamera"
+- Check that MapNameDisplay found the camera (debug messages)
+
+## Technical Notes
+
+- Names are generated once when the map creates
+- Text uses Unity's TextMesh component for 3D world-space rendering
+- Reflection is used to access name data from TileHoverHandler
+- Labels automatically face the camera and include black outlines for readability

+ 398 - 0
Assets/Scripts/BattleScene/BattleSetup.cs

@@ -0,0 +1,398 @@
+using System.Collections.Generic;
+using UnityEngine;
+using UnityEngine.AI;
+
+public class BattleSetup : MonoBehaviour
+{
+    List<GameObject> unplacedEnemyCharacters = new List<GameObject>();
+    List<GameObject> placedPlayerCharacters = new List<GameObject>();
+    List<GameObject> placedEnemyCharacters = new List<GameObject>();
+    private List<GameObject> playerCharacters = new List<GameObject>();
+    private List<GameObject> enemyCharacters = new List<GameObject>();
+    private List<CharacterSelection> playerSelections = new List<CharacterSelection>();
+    private List<CharacterSelection> enemySelections = new List<CharacterSelection>();
+
+    [Tooltip("Select the layer(s) that represent the ground for raycasting.")]
+    public LayerMask groundLayerMask;
+
+    public GameObject playerPrefab; // Assign in the inspector or through GameManager
+    public GameObject enemyPrefab; // Assign in the inspector or through GameManager
+    public GameObject SwordPrefab; // Assign in the inspector or through GameManager
+    public GameObject BowPrefab; // Assign in the inspector or through GameManager
+
+
+    GameObject playerSpawnArea;
+    GameObject enemySpawnArea;
+    Bounds playerSpawnBounds;
+
+    private Camera mainCamera;
+    private GameObject currentPlacingCharacterInstance;
+    private int nextPlayerCharacterPrefabIndex = 0;
+    private bool isPlacingPlayerCharacters = false;
+    void Awake()
+    {
+        mainCamera = Camera.main;
+        if (mainCamera == null)
+        {
+            Debug.LogError("Main camera not found. Please ensure there is a camera tagged as 'MainCamera' in the scene.");
+            enabled = false;
+            return;
+        }
+
+        playerCharacters.Clear();
+        enemyCharacters.Clear();
+
+        // Store the selections for use during placement
+        playerSelections = new List<CharacterSelection>(BattleSetupData.playerSelections);
+        enemySelections = new List<CharacterSelection>(BattleSetupData.enemySelections);
+
+        // Initialize the lists with characters from the game manager or other sources
+        playerSpawnArea = GameObject.Find("PlayerSpawnArea");
+        enemySpawnArea = GameObject.Find("EnemySpawnArea");
+
+        if (playerSpawnArea == null)
+        {
+            Debug.LogError("PlayerSpawnArea GameObject not found in scene. Please ensure there is a GameObject named 'PlayerSpawnArea' in the scene.");
+            enabled = false;
+            return;
+        }
+        Collider playerSpawnAreaCollider = playerSpawnArea.GetComponent<Collider>();
+        if (playerSpawnAreaCollider == null)
+        {
+            Debug.LogError("PlayerSpawnArea does not have a collider component.");
+            enabled = false;
+            return;
+        }
+        playerSpawnBounds = playerSpawnAreaCollider.bounds;
+        if (enemySpawnArea == null)
+        {
+            // Enemy placement might still work if unplacedEnemyCharacters is empty
+            Debug.LogWarning("EnemySpawnArea GameObject not found in the scene. Enemy placement might be affected.");
+        }
+
+        // Call the setup methods to place characters
+        PlaceEnemyCharacters();
+        InitiatePlayerCharacterPlacement();
+    }
+
+    void EquipWeapon(Character character, string weaponType)
+    {
+        Weapon weapon = null;
+        if (weaponType == "Sword")
+        {
+            var weaponObj = Instantiate(SwordPrefab, character.transform);
+            weapon = weaponObj.GetComponent<Weapon>();
+        }
+        else if (weaponType == "Bow")
+        {
+            var weaponObj = Instantiate(BowPrefab, character.transform);
+            weapon = weaponObj.GetComponent<Weapon>();
+        }
+        else
+        {
+            Debug.LogWarning($"Unknown weapon type: {weaponType}. No weapon equipped.");
+        }
+
+        if (weapon != null)
+        {
+            Transform attachPoint = character.transform.Find("WeaponAttachPoint");
+            if (attachPoint != null)
+            {
+                weapon.transform.SetParent(attachPoint, false);
+                weapon.transform.localPosition = Vector3.zero;
+                weapon.transform.localRotation = Quaternion.identity;
+            }
+            else
+            {
+                weapon.transform.SetParent(character.transform, false);
+                weapon.transform.localPosition = new Vector3(0.5f, 0, 0);
+            }
+
+            character.Weapon = weapon;
+            weapon.SetWielder(character);
+        }
+    }
+
+    void Update()
+    {
+        if (!isPlacingPlayerCharacters || currentPlacingCharacterInstance == null)
+        {
+            return;
+        }
+        HandleCharacterPlacement();
+    }
+
+    private void InitiatePlayerCharacterPlacement()
+    {
+        if (playerSelections.Count == 0)
+        {
+
+            return;
+        }
+        isPlacingPlayerCharacters = true;
+        nextPlayerCharacterPrefabIndex = 0;
+        SpawnNextPlayerCharacterForPlacement();
+    }
+
+    private void SpawnNextPlayerCharacterForPlacement()
+    {
+        if (currentPlacingCharacterInstance != null)
+        {
+            // This case should ideally not happen if logic flows correctly,
+            // but as a safeguard if a previous instance wasn't cleaned up.
+            Destroy(currentPlacingCharacterInstance);
+            currentPlacingCharacterInstance = null;
+        }
+
+        if (nextPlayerCharacterPrefabIndex < playerSelections.Count)
+        {
+            var selection = playerSelections[nextPlayerCharacterPrefabIndex];
+            currentPlacingCharacterInstance = Instantiate(playerPrefab);
+            currentPlacingCharacterInstance.name = selection.characterName;
+
+            var character = currentPlacingCharacterInstance.GetComponent<Character>();
+            if (character != null)
+            {
+                EquipWeapon(character, selection.weaponType);
+                character.CharacterName = selection.characterName + " " + (nextPlayerCharacterPrefabIndex + 1);
+            }
+            currentPlacingCharacterInstance.GetComponent<NavMeshAgent>().enabled = false;
+            // Optionally disable AI or other components that might interfere with placement
+            // e.g., currentPlacingCharacterInstance.GetComponent<AIController>()?.enabled = false;
+
+        }
+        else
+        {
+            FinalizePlayerPlacement();
+        }
+    }
+
+    private void HandleCharacterPlacement()
+    {
+        Ray ray = mainCamera.ScreenPointToRay(Input.mousePosition);
+        Debug.DrawRay(ray.origin, ray.direction * 200f, Color.yellow); // Visualize the ray
+        if (Physics.Raycast(ray, out RaycastHit hit, 200f, groundLayerMask))
+        {
+            Vector3 targetPosition = hit.point;
+            // Clamp position to playerSpawnArea bound (X and Z axis)
+            targetPosition.x = Mathf.Clamp(targetPosition.x, playerSpawnBounds.min.x, playerSpawnBounds.max.x);
+            targetPosition.z = Mathf.Clamp(targetPosition.z, playerSpawnBounds.min.z, playerSpawnBounds.max.z);
+            // Y is determined by the raycast hit on the ground
+
+            // --- Direct Y Position Calculation for Mouse-Following Character ---
+            // This approach was found to be more stable than repeatedly calling AdjustCharacterOnGround.
+            // It assumes a standard Unity CapsuleCollider where the pivot is at the center.
+            Vector3 finalCharacterPosition = targetPosition; // targetPosition.y is from the ground hit (hit.point.y)
+
+            CapsuleCollider capCollider = currentPlacingCharacterInstance.GetComponent<CapsuleCollider>();
+            if (capCollider != null)
+            {
+                // For a capsule, its pivot is typically at its center.
+                // To place its bottom on targetPosition.y (ground level),
+                // its center (pivot) needs to be at targetPosition.y + (height / 2).
+                // We also account for the character's local scale.
+                finalCharacterPosition.y = targetPosition.y + (capCollider.height * currentPlacingCharacterInstance.transform.localScale.y / 2f);
+            }
+            else
+            {
+                // Fallback if not a capsule or if a different pivot is used.
+                // This might need adjustment based on your character's actual pivot and collider.
+                Debug.LogWarning($"'{currentPlacingCharacterInstance.name}' does not have a CapsuleCollider. Using default Y offset for placement. Adjust if incorrect.");
+                finalCharacterPosition.y = targetPosition.y + 0.5f; // Example offset, adjust as needed
+            }
+            currentPlacingCharacterInstance.transform.position = finalCharacterPosition;
+            // AdjustCharacterOnGround(currentPlacingCharacterInstance); // No longer called every frame for mouse-follow
+        }
+        else
+        {
+
+        }
+        // Else mouse is not over valid ground, character stays at last valid position or initial spawn
+
+        if (Input.GetMouseButtonDown(0))
+        { // Left-click to place character
+            // Check if the current position is valid (within bounds and not overlapping)
+            // The position is already clamped and on ground due to the logic above.
+            // We primarily need to check for overlaps.
+            if (!IsOverlappingOtherCharacters(currentPlacingCharacterInstance))
+            {
+                PlaceCurrentCharacter();
+            }
+            else
+            {
+                Debug.LogWarning("Cannot place character: Overlapping with another character.");
+                // Optionally, you could provide feedback to the player about the overlap (e.g. change color?).
+            }
+        }
+        if (Input.GetMouseButtonDown(1))
+        { // Right-click to cancel placement
+            if (placedPlayerCharacters.Count > 0)
+            {
+                FinalizePlayerPlacement();
+            }
+            else
+            {
+
+            }
+        }
+    }
+
+    private void PlaceCurrentCharacter()
+    {
+
+        placedPlayerCharacters.Add(currentPlacingCharacterInstance);
+        currentPlacingCharacterInstance = null;
+        nextPlayerCharacterPrefabIndex++;
+        SpawnNextPlayerCharacterForPlacement(); // Spawn next character for placement
+    }
+
+    private void AdjustCharacterOnGround(GameObject character)
+    {
+        if (character == null)
+        {
+            return;
+        }
+        Collider charCollider = character.GetComponent<Collider>();
+        if (charCollider != null)
+        {
+            // This ensured the lowest point of the collider is at character.transform.position.y
+            // (which should be the ground hit point)
+            // currentY is the Y-coordinate of the character's pivot.
+            // We want the character's collider bottom (feet) to be at this Y-level.
+            float currentY = character.transform.position.y;
+            float colliderMinYWorld = charCollider.bounds.min.y;
+            float verticalOffset = currentY - colliderMinYWorld;
+            const float tolerance = 0.001f; // Small tolerance to avoid floating point issues
+            if (Mathf.Abs(verticalOffset) > tolerance)
+            {
+                character.transform.position += Vector3.up * verticalOffset;
+            }
+        }
+        else
+        {
+            Debug.LogWarning($"Character: {character.name} has no collider. Cannot accurately adjust to ground.");
+        }
+    }
+
+    private bool IsOverlappingOtherCharacters(GameObject character)
+    {
+        Collider newCharCollider = character.GetComponent<Collider>();
+        if (newCharCollider == null)
+        {
+            Debug.LogWarning($"Character: {character.name} has no collider. Cannot check for overlaps.");
+            return false; // Or true to precent placement if no collider
+        }
+        Bounds newCharBounds = newCharCollider.bounds;
+        foreach (GameObject placedCharacter in placedPlayerCharacters)
+        {
+            Collider otherCollider = placedCharacter.GetComponent<Collider>();
+            if (otherCollider != null && newCharBounds.Intersects(otherCollider.bounds))
+            {
+                return true;
+            }
+        }
+
+        foreach (GameObject placedEnemy in placedEnemyCharacters)
+        {
+            Collider otherCollider = placedEnemy.GetComponent<Collider>();
+            if (otherCollider != null && newCharBounds.Intersects(otherCollider.bounds))
+            {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private void FinalizePlayerPlacement()
+    {
+        isPlacingPlayerCharacters = false;
+        if (currentPlacingCharacterInstance != null)
+        {
+            Destroy(currentPlacingCharacterInstance); // Destroy the preview instance if it wasn't placed
+            currentPlacingCharacterInstance = null;
+        }
+
+
+        EndPlacementPhase();
+
+        // Here you might want to trigger the next phase of your game, e.g., start the battle.
+        GameManager.Instance.StartBattle(placedPlayerCharacters, placedEnemyCharacters);
+        Destroy(playerSpawnArea);
+        Destroy(enemySpawnArea);
+        playerSpawnArea = null;
+        enemySpawnArea = null;
+
+    }
+
+    private void EndPlacementPhase()
+    {
+        // This method can be used to clean up or finalize the placement phase.
+        // For example, you might want to enable AI, re-enable NavMeshAgents, etc.
+        foreach (GameObject character in placedPlayerCharacters)
+        {
+            NavMeshAgent agent = character.GetComponent<NavMeshAgent>();
+            if (agent != null)
+            {
+                agent.enabled = true; // Re-enable NavMeshAgent
+            }
+            // Enable AI or other components as needed
+            // e.g., character.GetComponent<AIController>()?.enabled = true;
+        }
+
+        foreach (GameObject character in enemyCharacters)
+        {
+            NavMeshAgent agent = character.GetComponent<NavMeshAgent>();
+            if (agent != null)
+            {
+                agent.enabled = true; // Re-enable NavMeshAgent
+            }
+            // Enable AI or other components as needed
+            // e.g., character.GetComponent<AIController>()?.enabled = true;
+        }
+
+    }
+
+    private void PlaceEnemyCharacters()
+    {
+        Collider spawnAreaCollider = enemySpawnArea.GetComponent<Collider>();
+        if (spawnAreaCollider == null)
+        {
+            Debug.LogError("Enemy spawn area does not have a collider component.");
+            return;
+        }
+        Bounds spawnBounds = spawnAreaCollider.bounds;
+
+        for (int i = enemySelections.Count - 1; i >= 0; i--)
+        {
+            var selection = enemySelections[i];
+
+            float randomX = UnityEngine.Random.Range(spawnBounds.min.x, spawnBounds.max.x);
+            float randomZ = UnityEngine.Random.Range(spawnBounds.min.z, spawnBounds.max.z);
+
+            Vector3 rayOrigin = new Vector3(randomX, enemySpawnArea.transform.position.y + 10f, randomZ);
+            Vector3 spawnPosition = new Vector3(randomX, enemySpawnArea.transform.position.y, randomZ);
+
+            // Raycast to find the ground
+            if (Physics.Raycast(rayOrigin, Vector3.down, out RaycastHit hit, 200f, groundLayerMask))
+            {
+                spawnPosition = hit.point;
+            }
+            else
+            {
+                Debug.LogWarning($"Raycast did not hit ground below ({randomX}, {randomZ}). Placing enemy at spawn area Y level.");
+            }
+
+            GameObject placedEnemy = Instantiate(enemyPrefab, spawnPosition, Quaternion.identity);
+            Character character = placedEnemy.GetComponent<Character>();
+            if (character != null)
+            {
+                EquipWeapon(character, selection.weaponType);
+                character.CharacterName = selection.characterName + "_" + (i + 1);
+            }
+
+            AdjustCharacterOnGround(placedEnemy); // Adjust the enemy to the ground
+
+            placedEnemyCharacters.Add(placedEnemy);
+        }
+    }
+}

+ 152 - 0
Assets/Scripts/BattleScene/BattleUiScript.cs

@@ -0,0 +1,152 @@
+using UnityEngine;
+using UnityEngine.UIElements; // Changed from UnityEngine.UI
+using System.Collections;
+using System;
+
+public class BattleUIManager : MonoBehaviour
+{
+    public static BattleUIManager Instance { get; private set; }
+
+    [Header("UI Toolkit References")]
+    [Tooltip("Assign the UIDocument component from the scene.")]
+    public UIDocument uiDocument;
+
+    // UI Toolkit Element references
+    private Button runPauseButtonElement;
+    private Button advanceButtonElement;
+
+    // Coroutine handle for the advance action
+    private Coroutine advanceCoroutineHandle;
+
+    void Awake()
+    {
+        if (Instance == null)
+        {
+            Instance = this;
+        }
+        else
+        {
+            Debug.LogWarning("Multiple instances of BattleUIManager found. Destroying this one.");
+            Destroy(gameObject);
+            return;
+        }
+    }
+
+    void Start()
+    {
+        uiDocument = GetComponent<UIDocument>();
+        if (uiDocument == null)
+        {
+            Debug.LogError("BattleUIManager: UIDocument is not assigned in the Inspector. Please assign it.");
+            SetButtonsInteractable(false); // Attempt to disable if elements were somehow found
+            enabled = false;
+            return;
+        }
+
+        var rootVisualElement = uiDocument.rootVisualElement;
+        if (rootVisualElement == null)
+        {
+            Debug.LogError("BattleUIManager: UIDocument has no rootVisualElement. Ensure UXML is correctly set up.");
+            enabled = false;
+            return;
+        }
+
+        // Query for the buttons by their names defined in UXML
+        runPauseButtonElement = rootVisualElement.Q<Button>("RunPauseButton");
+        advanceButtonElement = rootVisualElement.Q<Button>("AdvanceActionButton");
+
+        if (runPauseButtonElement == null || advanceButtonElement == null)
+        {
+            Debug.LogError("BattleUIManager: Could not find 'RunPauseButton' or 'AdvanceActionButton' in the UXML. Check names.");
+            SetButtonsInteractable(false);
+            enabled = false;
+            return;
+        }
+
+        if (GameManager.Instance == null)
+        {
+            Debug.LogError("BattleUIManager: GameManager.Instance is null. Ensure GameManager is in the scene and initialized.");
+            SetButtonsInteractable(false);
+            enabled = false;
+            return;
+        }
+
+        // Initialize UI based on GameManager's expected initial state
+        runPauseButtonElement.text = "Run";
+        advanceButtonElement.SetEnabled(true); // Can advance from initial paused state
+        runPauseButtonElement.SetEnabled(true);
+
+        runPauseButtonElement.RegisterCallback<ClickEvent>(evt => OnRunPauseButtonPressed());
+        advanceButtonElement.RegisterCallback<ClickEvent>(evt => OnAdvanceActionButtonPressed());
+    }
+
+    public void OnRunPauseButtonPressed()
+    {
+        if (GameManager.Instance == null) return;
+
+        if (GameManager.Instance.isContinuousRunActive) // Was running continuously, now pause
+        {
+            GameManager.Instance.isContinuousRunActive = false;
+            GameManager.Instance.PauseGame();
+            runPauseButtonElement.text = "Run";
+            advanceButtonElement.SetEnabled(true); // Allow advance when paused
+        }
+        else // Was paused or not in continuous run, now run continuously
+        {
+            if (advanceCoroutineHandle != null) // Stop any pending "Advance" action
+            {
+                StopCoroutine(advanceCoroutineHandle);
+                advanceCoroutineHandle = null;
+            }
+            GameManager.Instance.isContinuousRunActive = true;
+            GameManager.Instance.ResumeGame();
+            runPauseButtonElement.text = "Pause";
+            advanceButtonElement.SetEnabled(false); // Disable advance when in continuous run
+        }
+    }
+
+    public void OnAdvanceActionButtonPressed()
+    {
+        // 
+        if (GameManager.Instance == null) return;
+
+        if (GameManager.Instance.isContinuousRunActive)
+        {
+            return;
+        }
+
+        // Distable advance button immediately
+        SetButtonsInteractable(false);
+
+        CinemachineCameraController.Instance.FrameAllCharacters(GameManager.Instance.GetAllCharacters());
+
+        // If already advancing, stop the current coroutine
+        GameManager.Instance.AdvanceAction();
+
+    }
+
+    public void SetButtonsInteractable(bool interactable)
+    {
+        runPauseButtonElement?.SetEnabled(interactable);
+        advanceButtonElement?.SetEnabled(interactable);
+    }
+
+    // Call this from GameManager when the battle ends
+    public void DisableBattleControls()
+    {
+
+        SetButtonsInteractable(false);
+        if (runPauseButtonElement != null) runPauseButtonElement.text = "Battle Over";
+    }
+
+    void OnDestroy()
+    {
+        // Clean up listeners if the object is destroyed
+        // For UI Toolkit, callbacks are typically managed well by the system, but explicit unregistering can be done if needed.
+        // runPauseButtonElement?.UnregisterCallback<ClickEvent>(...); // if you stored the exact lambda or method
+        if (Instance == this) // Singleton cleanup
+        {
+            Instance = null;
+        }
+    }
+}

+ 184 - 0
Assets/Scripts/BattleScene/Controls.inputActions

@@ -0,0 +1,184 @@
+{
+    "name": "Controls",
+    "maps": [
+        {
+            "name": "Camera",
+            "id": "10af34cb-cc1c-4182-af12-aee9e81c48f9",
+            "actions": [
+                {
+                    "name": "Zoom",
+                    "type": "Value",
+                    "id": "262efc1b-a23d-4c20-b471-430e31bb8fa8",
+                    "expectedControlType": "",
+                    "processors": "",
+                    "interactions": "",
+                    "initialStateCheck": true
+                },
+                {
+                    "name": "Move",
+                    "type": "Value",
+                    "id": "b6a4fed8-e66b-427b-bab4-7c6211e1f0a6",
+                    "expectedControlType": "",
+                    "processors": "",
+                    "interactions": "",
+                    "initialStateCheck": true
+                },
+                {
+                    "name": "Rotate",
+                    "type": "Value",
+                    "id": "6b5f7e8d-2646-4af8-9392-8a4b2266c0cf",
+                    "expectedControlType": "",
+                    "processors": "",
+                    "interactions": "",
+                    "initialStateCheck": true
+                }
+            ],
+            "bindings": [
+                {
+                    "name": "1D Axis",
+                    "id": "d0adae84-9e05-4b38-8bd6-aef421fd55ed",
+                    "path": "1DAxis",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": "",
+                    "action": "Zoom",
+                    "isComposite": true,
+                    "isPartOfComposite": false
+                },
+                {
+                    "name": "negative",
+                    "id": "356bfea4-8bd3-4961-ab70-b106bd83514d",
+                    "path": "<Mouse>/scroll/down",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": "",
+                    "action": "Zoom",
+                    "isComposite": false,
+                    "isPartOfComposite": true
+                },
+                {
+                    "name": "positive",
+                    "id": "4d17c393-c3f0-4e2a-ad65-b26ee97b9249",
+                    "path": "<Mouse>/scroll/up",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": "",
+                    "action": "Zoom",
+                    "isComposite": false,
+                    "isPartOfComposite": true
+                },
+                {
+                    "name": "",
+                    "id": "49e26e38-e6fa-48e3-bdb1-8c0a0943dae6",
+                    "path": "<Keyboard>/w",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": "",
+                    "action": "Move",
+                    "isComposite": false,
+                    "isPartOfComposite": false
+                },
+                {
+                    "name": "",
+                    "id": "276bcef4-eec2-4c90-be97-cebf41957872",
+                    "path": "<Keyboard>/s",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": "",
+                    "action": "Move",
+                    "isComposite": false,
+                    "isPartOfComposite": false
+                },
+                {
+                    "name": "",
+                    "id": "d7cfa40d-8a92-4fe0-a7b5-bfd27dbcb4ba",
+                    "path": "<Keyboard>/a",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": "",
+                    "action": "Move",
+                    "isComposite": false,
+                    "isPartOfComposite": false
+                },
+                {
+                    "name": "",
+                    "id": "8c2d44b4-6f60-484c-ad9b-61432618ff36",
+                    "path": "<Keyboard>/d",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": "",
+                    "action": "Move",
+                    "isComposite": false,
+                    "isPartOfComposite": false
+                },
+                {
+                    "name": "",
+                    "id": "0583a717-18fc-481c-9408-3d50f49874ee",
+                    "path": "<Keyboard>/rightArrow",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": "",
+                    "action": "Move",
+                    "isComposite": false,
+                    "isPartOfComposite": false
+                },
+                {
+                    "name": "",
+                    "id": "95759656-7706-4a82-9876-7ddec323cbd8",
+                    "path": "<Keyboard>/upArrow",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": "",
+                    "action": "Move",
+                    "isComposite": false,
+                    "isPartOfComposite": false
+                },
+                {
+                    "name": "",
+                    "id": "df8d5333-4b89-4ac0-a70a-130fb5e00c11",
+                    "path": "<Keyboard>/downArrow",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": "",
+                    "action": "Move",
+                    "isComposite": false,
+                    "isPartOfComposite": false
+                },
+                {
+                    "name": "",
+                    "id": "3817237c-0793-4ba9-a1ba-b0e079f5745f",
+                    "path": "<Keyboard>/leftArrow",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": "",
+                    "action": "Move",
+                    "isComposite": false,
+                    "isPartOfComposite": false
+                },
+                {
+                    "name": "",
+                    "id": "d861d37b-aa1f-4523-8991-af9ff5d95b32",
+                    "path": "<Keyboard>/q",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": "",
+                    "action": "Rotate",
+                    "isComposite": false,
+                    "isPartOfComposite": false
+                },
+                {
+                    "name": "",
+                    "id": "8031760d-048b-4f6d-923a-c894f08e6760",
+                    "path": "<Keyboard>/e",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": "",
+                    "action": "Rotate",
+                    "isComposite": false,
+                    "isPartOfComposite": false
+                }
+            ]
+        }
+    ],
+    "controlSchemes": []
+}

+ 661 - 0
Assets/Scripts/BattleScene/GameManager.cs

@@ -0,0 +1,661 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+using Unity.VisualScripting;
+using UnityEngine;
+using UnityEngine.AI;
+using UnityEngine.Rendering.UI;
+
+public class GameManager : MonoBehaviour
+{
+    public static GameManager Instance { get; private set; }
+    public List<GameObject> playerCharacters = new List<GameObject>();
+    public List<GameObject> enemyCharacters = new List<GameObject>();
+
+    [Header("Decision Controller")]
+    public PlayerDecisionController playerDecisionController;
+
+    private Dictionary<GameObject, GameObject> enemySelectedTargets = new Dictionary<GameObject, GameObject>();
+    public bool isContinuousRunActive = false; // Indicates if the game is in continuous run mode
+
+    private const string ENEMY_LAYER_NAME = "Enemies";
+    private int enemyLayerMask;
+    private bool isActionExecutionPhaseActive;
+    private bool waitingForAdvanceInput = false;
+
+    private void Awake()
+    {
+        if (Instance == null)
+        {
+            Instance = this;
+            DontDestroyOnLoad(gameObject);
+
+            // Initialize PlayerDecisionController if not set
+            if (playerDecisionController == null)
+            {
+                playerDecisionController = FindFirstObjectByType<PlayerDecisionController>();
+                if (playerDecisionController == null)
+                {
+                    GameObject pdcGO = new GameObject("PlayerDecisionController");
+                    playerDecisionController = pdcGO.AddComponent<PlayerDecisionController>();
+
+                }
+            }
+
+            int enemyLayer = LayerMask.NameToLayer(ENEMY_LAYER_NAME);
+            if (enemyLayer == -1)
+            {
+                Debug.LogError($"Layer '{ENEMY_LAYER_NAME}' not found. Please create it in Project Settings > Tags and Layers, and assign your enemy prefabs to it.");
+                // Disable functionality or handle error appropriately
+            }
+            else
+            {
+                enemyLayerMask = 1 << enemyLayer;
+            }
+        }
+        else
+        {
+            Destroy(gameObject);
+            return; // Avoid further initialization if this is not the singleton instance
+        }
+    }
+
+    internal void StartBattle(List<GameObject> placedPlayerCharacters, List<GameObject> placedEnemyCharacters)
+    {
+        playerCharacters = placedPlayerCharacters;
+        enemyCharacters = placedEnemyCharacters;
+
+        // Refresh PlayerDecisionController with current player characters
+        if (playerDecisionController != null)
+        {
+            playerDecisionController.RefreshPlayerCharacters();
+            playerDecisionController.SetEnabled(false); // Disable initially until decision phase
+        }
+
+        // Start the battle logic here
+
+
+        EnemiesDecideAction();
+        StartCoroutine(MainBattleLoopCoroutine());
+    }
+
+    private IEnumerator MainBattleLoopCoroutine()
+    {
+        while (true) // Main battle loop
+        {
+            // --- Player Decision Phase ---
+            Time.timeScale = 1f; // Ensure normal time scale for player decision phase
+
+
+            // Check for completed movements before turn starts
+            CheckAndResetCompletedMovements();
+
+            // Keep existing actions, only allow new decisions for characters with no action
+            playerDecisionController.UpdateVisualStates(); // Update colors: pink for no action, green for incomplete
+            playerDecisionController.SetEnabled(true);
+
+            // Show lines for any existing incomplete actions
+            playerDecisionController.ShowActiveActionLines();
+
+            // Wait for all players to make their initial decisions (only needed at turn start)
+            while (!playerDecisionController.AllCharactersHaveActions())
+            {
+                yield return null; // Wait for player input through PlayerDecisionController
+            }
+
+            // Disable input during execution phase and hide action lines
+            playerDecisionController.SetEnabled(false);
+            playerDecisionController.HideActiveActionLines();
+
+
+            // --- Pause point after decision (if not in continuous run mode) ---
+            if (!isContinuousRunActive)
+            {
+
+                PauseGame();
+                yield return new WaitUntil(() => Time.timeScale > 0 || isContinuousRunActive);
+            }
+
+            if (Time.timeScale == 0 && isContinuousRunActive)
+            {
+                ResumeGame();
+            }
+
+            // --- Action execution phase ---
+
+            // yield return StartCoroutine(ExecutePlayerActionsCoroutine());
+            yield return StartCoroutine(ExecuteAllActionsSimultaneously());
+            // TODO: add ement action execution here for a full turn
+
+
+            if (BattleUIManager.Instance != null)
+            {
+                BattleUIManager.Instance.SetButtonsInteractable(true);
+            }
+
+            EnemiesDecideAction(); // Enemies decide their actions after players have executed their actions
+            // --- Post-Actions: Loop or Pause ---
+            if (isContinuousRunActive)
+            {
+
+                if (Time.timeScale > 0)
+                {
+                    yield return new WaitForSeconds(0.5f); // Brief delay if running
+                }
+            }
+            else
+            {
+
+                PauseGame();
+            }
+
+            // Check for battle end conditions
+            if (playerCharacters.Count == 0 || enemyCharacters.Count == 0)
+            {
+
+                PauseGame();
+                if (BattleUIManager.Instance != null)
+                {
+                    BattleUIManager.Instance.DisableBattleControls(); // Disable UI controls
+                }
+                // Handle battle end logic here (e.g., show results, reset game state, etc.)
+                break; // Exit the loop if battle is over
+            }
+        }
+    }
+
+    public List<GameObject> GetAllCharacters()
+    {
+        return playerCharacters.Concat(enemyCharacters).ToList();
+    }
+
+    private IEnumerator ExecuteAllActionsSimultaneously()
+    {
+
+        isActionExecutionPhaseActive = true;
+
+        var allActions = new Dictionary<GameObject, GameObject>();
+        var movementActions = new Dictionary<GameObject, Vector3>();
+
+        // Collect player actions from Character components
+        foreach (GameObject playerGO in playerCharacters)
+        {
+            Character character = playerGO.GetComponent<Character>();
+            if (character != null && character.actionData.hasTarget)
+            {
+                if (character.actionData.targetEnemy != null)
+                {
+                    allActions[playerGO] = character.actionData.targetEnemy;
+                }
+                else if (character.actionData.targetPosition != Vector3.zero)
+                {
+                    movementActions[playerGO] = character.actionData.targetPosition;
+                }
+            }
+        }
+
+        foreach (var action in enemySelectedTargets)
+        {
+            allActions[action.Key] = action.Value;
+        }
+
+        int playerActionsCount = allActions.Count - enemySelectedTargets.Count + movementActions.Count;
+
+
+        enemySelectedTargets.Clear(); // Clear enemy targets as well
+
+        if (allActions.Count == 0 && movementActions.Count == 0)
+        {
+
+            isActionExecutionPhaseActive = false;
+            yield break;
+        }
+
+        // Configure All NavMeshAgents before starting movement
+        foreach (var action in allActions)
+        {
+            GameObject actor = action.Key;
+            if (actor == null)
+            {
+                continue;
+            }
+
+            Character character = actor.GetComponent<Character>();
+            float attackRange = character != null ? character.GetAttackRange() : 2.0f;
+
+            NavMeshAgent agent = actor.GetComponent<NavMeshAgent>();
+            if (agent != null)
+            {
+                // For melee weapons (range <= 2), get much closer. For ranged, stay back more.
+                float stoppingDistance = attackRange <= 2 ? 0.2f : Mathf.Max(0.5f, attackRange - 1.0f);
+                agent.stoppingDistance = stoppingDistance;
+
+                // 
+                agent.obstacleAvoidanceType = ObstacleAvoidanceType.HighQualityObstacleAvoidance;
+                agent.avoidancePriority = UnityEngine.Random.Range(0, 100);
+
+                // Start movement
+                GameObject target = action.Value;
+                if (target != null)
+                {
+                    agent.SetDestination(target.transform.position);
+                    agent.isStopped = false;
+
+                }
+            }
+            else
+            {
+                Debug.LogWarning($"NavMeshAgent not found or disabled on {actor.name}. Cannot move towards target.");
+            }
+        }
+
+        // Handle pure movement actions (no enemy target)
+        foreach (var movement in movementActions)
+        {
+            GameObject playerGO = movement.Key;
+            Vector3 targetPosition = movement.Value;
+
+            NavMeshAgent agent = playerGO.GetComponent<NavMeshAgent>();
+            if (agent != null)
+            {
+                agent.SetDestination(targetPosition);
+                agent.isStopped = false;
+
+            }
+        }
+
+        // handle movement duration based on mode
+        // 
+        if (allActions.Count > 0 || movementActions.Count > 0)
+        {
+            yield return StartCoroutine(MovementPhaseWithTargetTracking(allActions, movementActions, 1.0f));
+        }
+        // else
+        // {
+        //     // If there are only attacks (no movement), still wait for 1 second
+        //     yield return new WaitForSeconds(1.0f);
+        // }
+
+        if (!isContinuousRunActive)
+        {
+            // 
+            // 
+
+            // Check for completed movement actions before showing lines
+            CheckAndResetCompletedMovements();
+
+            // Enable input and show lines for actions during pause - allow re-picking actions
+            playerDecisionController.UpdateVisualStates(); // Update colors
+            playerDecisionController.SetEnabled(true); // Allow action changes
+            playerDecisionController.ShowActiveActionLines();
+
+            PauseGame();
+            waitingForAdvanceInput = true;
+            yield return new WaitUntil(() => !waitingForAdvanceInput);
+
+            // Disable input when advancing
+            playerDecisionController.SetEnabled(false);
+            ResumeGame();
+            yield return new WaitForSeconds(1.0f);
+        }
+
+        foreach (var action in allActions)
+        {
+            GameObject actor = action.Key;
+            GameObject target = action.Value;
+
+            if (actor == null || target == null) continue;
+            Character character = actor.GetComponent<Character>();
+            float attackRange = character != null ? character.GetAttackRange() : 2.0f;
+
+            float distance = Vector3.Distance(actor.transform.position, target.transform.position);
+            if (distance <= attackRange)
+            {
+
+
+                // Execute the character's attack action
+                character.ExecuteAction();
+            }
+            else
+            {
+
+            }
+        }
+
+        // Check movement completion and reset action if reached (movement actions are one-time)
+        foreach (var movement in movementActions)
+        {
+            GameObject actor = movement.Key;
+            Vector3 targetPosition = movement.Value;
+
+            if (actor == null) continue;
+
+            Character character = actor.GetComponent<Character>();
+            if (character != null)
+            {
+                // Use horizontal distance only, ignore Y differences
+                Vector3 actorPos = actor.transform.position;
+                Vector2 actorPos2D = new Vector2(actorPos.x, actorPos.z);
+                Vector2 targetPos2D = new Vector2(targetPosition.x, targetPosition.z);
+                float horizontalDistance = Vector2.Distance(actorPos2D, targetPos2D);
+
+                if (horizontalDistance <= 1.2f) // Movement completion threshold
+                {
+
+                    character.actionData.Reset();
+                    character.SetVisualState(ActionDecisionState.NoAction);
+                }
+            }
+        }
+
+        isActionExecutionPhaseActive = false;
+
+        BattleUIManager.Instance.SetButtonsInteractable(true);
+    }
+
+    private IEnumerator MovementPhaseWithTargetTracking(Dictionary<GameObject, GameObject> allActions, Dictionary<GameObject, Vector3> movementActions, float movementDuration)
+    {
+        float elapsedTime = 0f;
+
+        // Store witch agents are still moving (not in attack range)
+        Dictionary<NavMeshAgent, GameObject> activeMovements = new Dictionary<NavMeshAgent, GameObject>();
+        Dictionary<NavMeshAgent, float> agentAttackRanges = new Dictionary<NavMeshAgent, float>();
+
+        // Initialize active movements for attack actions
+        foreach (var action in allActions)
+        {
+            GameObject actor = action.Key;
+            GameObject target = action.Value;
+
+            if (actor == null || target == null) continue;
+
+            NavMeshAgent agent = actor.GetComponent<NavMeshAgent>();
+            if (agent != null && agent.enabled)
+            {
+                // Get the character's attack range
+                Character character = actor.GetComponent<Character>();
+                float attackRange = character != null ? character.GetAttackRange() : 2.0f;
+
+                // Configure agent for proper pathfinding around obstacles
+                agent.obstacleAvoidanceType = ObstacleAvoidanceType.HighQualityObstacleAvoidance;
+                agent.avoidancePriority = UnityEngine.Random.Range(0, 100); // Random priority to avoid clustering
+
+                activeMovements[agent] = target;
+                agentAttackRanges[agent] = attackRange;
+            }
+        }
+
+        // Initialize active movements for pure movement actions
+        foreach (var movement in movementActions)
+        {
+            GameObject actor = movement.Key;
+            Vector3 targetPosition = movement.Value;
+
+            if (actor == null) continue;
+
+            NavMeshAgent agent = actor.GetComponent<NavMeshAgent>();
+            if (agent != null && agent.enabled)
+            {
+                // For movement actions, use a small stopping distance to get closer
+                float arrivalRange = 1.2f;
+
+                // Configure agent for proper pathfinding around obstacles
+                agent.obstacleAvoidanceType = ObstacleAvoidanceType.HighQualityObstacleAvoidance;
+                agent.avoidancePriority = UnityEngine.Random.Range(0, 100);
+                agent.stoppingDistance = 0.1f; // Get very close to the target
+
+                // Create a dummy target GameObject at the position for consistency with the tracking system
+                GameObject dummyTarget = new GameObject("MovementTarget");
+                dummyTarget.transform.position = targetPosition;
+
+                activeMovements[agent] = dummyTarget;
+                agentAttackRanges[agent] = arrivalRange;
+            }
+        }
+
+        while (elapsedTime < movementDuration && Time.timeScale > 0 && activeMovements.Count > 0)
+        {
+            var agentsToRemove = new List<NavMeshAgent>();
+
+            foreach (var movement in activeMovements)
+            {
+                NavMeshAgent agent = movement.Key;
+                GameObject target = movement.Value;
+                float attackRange = agentAttackRanges[agent];
+
+                if (agent == null || target == null || agent.gameObject == null)
+                {
+                    agentsToRemove.Add(agent);
+                    continue;
+                }
+
+                float distanceToTarget = Vector3.Distance(agent.transform.position, target.transform.position);
+
+                if (distanceToTarget <= attackRange)
+                {
+                    agent.isStopped = true;
+                    agent.velocity = Vector3.zero;
+                    agentsToRemove.Add(agent);
+
+
+                    // If this is a movement target (dummy), check if we should reset the action
+                    if (target.name == "MovementTarget")
+                    {
+                        Character character = agent.GetComponent<Character>();
+                        if (character != null && character.actionData.targetPosition != Vector3.zero)
+                        {
+
+                            character.actionData.Reset();
+                            character.SetVisualState(ActionDecisionState.NoAction);
+                        }
+                    }
+
+                }
+                else if (!agent.isStopped)
+                {
+                    // For movement targets, go directly to the position
+                    if (target.name == "MovementTarget")
+                    {
+                        agent.SetDestination(target.transform.position);
+
+                        // Check if agent has reached destination or is very close but stopped moving
+                        if (agent.pathStatus == NavMeshPathStatus.PathComplete &&
+                            (!agent.hasPath || agent.remainingDistance < 0.1f))
+                        {
+                            Character character = agent.GetComponent<Character>();
+                            if (character != null)
+                            {
+                                Vector3 actorPos = agent.transform.position;
+                                Vector3 targetPos = character.actionData.targetPosition;
+                                Vector2 actorPos2D = new Vector2(actorPos.x, actorPos.z);
+                                Vector2 targetPos2D = new Vector2(targetPos.x, targetPos.z);
+                                float horizontalDistance = Vector2.Distance(actorPos2D, targetPos2D);
+
+                                if (horizontalDistance <= 1.2f)
+                                {
+                                    agent.isStopped = true;
+                                    agentsToRemove.Add(agent);
+
+                                    character.actionData.Reset();
+                                    character.SetVisualState(ActionDecisionState.NoAction);
+                                }
+                            }
+                        }
+                    }
+                    else
+                    {
+                        // Update destination to track moving target, but stop just outside attack range
+                        Vector3 directionToTarget = (target.transform.position - agent.transform.position).normalized;
+                        Vector3 stoppingPosition = target.transform.position - directionToTarget * (attackRange * 0.9f);
+                        agent.SetDestination(stoppingPosition);
+                    }
+
+                    // Check if agent is stuck or can't reach destination
+                    if (agent.pathStatus == NavMeshPathStatus.PathInvalid)
+                    {
+                        Debug.LogWarning($"{agent.gameObject.name} cannot find path to {target.name}");
+                        agent.SetDestination(target.transform.position);
+                    }
+                }
+            }
+
+            foreach (var agent in agentsToRemove)
+            {
+                activeMovements.Remove(agent);
+                agentAttackRanges.Remove(agent);
+            }
+
+            yield return null; // wait one frame
+            elapsedTime += Time.deltaTime;
+        }
+        // Stop any remaining moving agents and clean up dummy targets
+        foreach (var movement in activeMovements)
+        {
+            if (movement.Key != null && movement.Key.enabled)
+            {
+                movement.Key.isStopped = true;
+                movement.Key.velocity = Vector3.zero;
+            }
+
+            // Clean up dummy movement targets
+            if (movement.Value != null && movement.Value.name == "MovementTarget")
+            {
+                Destroy(movement.Value);
+            }
+        }
+
+
+    }
+
+
+
+    public void AdvanceAction()
+    {
+
+
+        // Hide action lines when advancing
+        if (playerDecisionController != null)
+        {
+            playerDecisionController.HideActiveActionLines();
+        }
+
+        if (waitingForAdvanceInput)
+        {
+
+            waitingForAdvanceInput = false;
+        }
+        else if (Time.timeScale == 0 && !isActionExecutionPhaseActive)
+        {
+
+            ResumeGame();
+        }
+        else
+        {
+
+
+        }
+    }
+
+    public void PauseGame()
+    {
+        Time.timeScale = 0f; // Pause the game
+
+        BattleUIManager.Instance.SetButtonsInteractable(true);
+    }
+
+    public void ResumeGame()
+    {
+        Time.timeScale = 1f; // Resume the game
+
+    }
+
+    private void EnemiesDecideAction()
+    {
+
+
+        enemySelectedTargets.Clear();
+
+        foreach (var enemy in enemyCharacters)
+        {
+            if (enemy == null)
+            {
+                Debug.LogWarning("Found null enemy in enemyCharacters list");
+                continue;
+            }
+            if (playerCharacters.Count == 0)
+            {
+                Debug.LogWarning("No player characters available for enemies to target");
+                continue;
+            }
+            // Logic for enemy action decision
+
+
+            GameObject closestPlayer = null;
+            float minDistance = float.MaxValue;
+            List<GameObject> alivePlayers = playerCharacters.Where(player => !player.GetComponent<Character>().IsDead).ToList();
+            foreach (var player in alivePlayers)
+            {
+                if (player == null) continue; // Safety check
+                float distance = Vector3.Distance(enemy.transform.position, player.transform.position);
+                if (distance < minDistance)
+                {
+                    minDistance = distance;
+                    closestPlayer = player;
+                }
+            }
+            if (closestPlayer != null)
+            {
+
+
+                // Set the enemy's action data to attack the target
+                Character enemyCharacter = enemy.GetComponent<Character>();
+                if (enemyCharacter != null)
+                {
+                    enemyCharacter.actionData.SetAttackTarget(closestPlayer);
+
+                }
+
+                enemySelectedTargets[enemy] = closestPlayer; // Assign the closest player as the target
+            }
+            else
+            {
+                Debug.LogWarning($"{enemy.name} could not find a valid target");
+            }
+
+            enemy.GetComponent<Character>().SetVisualState(ActionDecisionState.EnemyAction);
+        }
+
+
+    }
+
+    private void CheckAndResetCompletedMovements()
+    {
+        foreach (GameObject playerGO in playerCharacters)
+        {
+            Character character = playerGO.GetComponent<Character>();
+            if (character != null && character.actionData.targetPosition != Vector3.zero && character.actionData.targetEnemy == null)
+            {
+                // This is a movement action, check if completed using horizontal distance only
+                Vector3 playerPos = playerGO.transform.position;
+                Vector3 targetPos = character.actionData.targetPosition;
+
+                // Use only X and Z coordinates (ignore Y differences)
+                Vector2 playerPos2D = new Vector2(playerPos.x, playerPos.z);
+                Vector2 targetPos2D = new Vector2(targetPos.x, targetPos.z);
+                float horizontalDistance = Vector2.Distance(playerPos2D, targetPos2D);
+
+
+
+                if (horizontalDistance <= 1.2f) // Threshold for "close enough"
+                {
+
+                    character.actionData.Reset();
+                    character.SetVisualState(ActionDecisionState.NoAction);
+                }
+            }
+        }
+    }
+
+
+}

+ 373 - 0
Assets/Scripts/BattleScene/PlayerDecisionController .cs

@@ -0,0 +1,373 @@
+using System.Collections.Generic;
+using Unity.VisualScripting;
+using UnityEngine;
+
+public class PlayerDecisionController : MonoBehaviour
+{
+    [Header("References")]
+    public LayerMask enemyLayerMask = 1 << 10; // Enemies are on layer 10
+    public LayerMask playerLayerMask = 1 << 9; // Players are on layer 9
+
+    [Header("Settings")]
+    public float enemySnapDistance = 1f;
+
+    private List<Character> playerCharacters = new List<Character>();
+    private Character selectedCharacter;
+    private TargetingLine targetingLine;
+    private Camera mainCamera;
+    private bool isDragging = false;
+    private Vector3 dragStartPosition;
+    private bool isEnabled = true;
+    private List<TargetingLine> activeActionLines = new List<TargetingLine>();
+
+    void Awake()
+    {
+        mainCamera = Camera.main;
+        targetingLine = GetComponent<TargetingLine>();
+        if (targetingLine == null)
+        {
+            targetingLine = gameObject.AddComponent<TargetingLine>();
+        }
+    }
+
+    void Start()
+    {
+
+        InitializePlayerCharacters();
+
+    }
+
+    void Update()
+    {
+        HandleInput();
+    }
+
+    private void InitializePlayerCharacters()
+    {
+        // Get player characters from GameManager if available
+        if (GameManager.Instance != null)
+        {
+            playerCharacters.Clear();
+            foreach (GameObject playerGO in GameManager.Instance.playerCharacters)
+            {
+                Character character = playerGO.GetComponent<Character>();
+                if (character != null)
+                {
+                    playerCharacters.Add(character);
+                }
+            }
+        }
+        else
+        {
+            // Fallback: find all characters (for testing without GameManager)
+            Character[] characters = FindObjectsByType<Character>(FindObjectsSortMode.None);
+            playerCharacters.AddRange(characters);
+        }
+
+        foreach (Character character in playerCharacters)
+        {
+            character.actionData.Reset();
+            character.SetVisualState(ActionDecisionState.NoAction);
+
+        }
+    }
+
+    private void HandleInput()
+    {
+        if (!isEnabled) return;
+
+        if (Input.GetMouseButtonDown(0)) // Left click
+        {
+            HandleLeftClickDown();
+        }
+        else if (Input.GetMouseButton(0) && isDragging) // Left drag
+        {
+            HandleLeftDrag();
+        }
+        else if (Input.GetMouseButtonUp(0)) // Left release
+        {
+            HandleLeftClickUp();
+        }
+        else if (Input.GetMouseButtonDown(1)) // Right click
+        {
+            HandleRightClick();
+        }
+    }
+
+    private void HandleLeftClickDown()
+    {
+        Vector3 mouseWorldPosition = GetMouseWorldPosition();
+        Character clickedCharacter = GetPlayerCharacterAtPosition(mouseWorldPosition);
+
+
+
+        if (clickedCharacter != null)
+        {
+            selectedCharacter = clickedCharacter;
+            isDragging = true;
+            dragStartPosition = clickedCharacter.transform.position;
+
+            // Clear any existing action lines before starting new targeting
+            ClearActionLineForCharacter(clickedCharacter);
+
+            targetingLine.StartTargeting(dragStartPosition);
+
+
+            // CinemachineCameraController.Instance.FocusOnCharacter(clickedCharacter.transform);
+        }
+    }
+    private void HandleLeftDrag()
+    {
+        if (selectedCharacter == null) return;
+
+        Vector3 mouseWorldPos = GetMouseWorldPosition();
+        GameObject enemyAtMouse = GetEnemyAtPosition(mouseWorldPos);
+
+
+        if (enemyAtMouse != null)
+        {
+            // Snap to enemy
+            Vector3 enemyPos = enemyAtMouse.transform.position;
+            targetingLine.UpdateTargeting(dragStartPosition, enemyPos, true);
+        }
+        else
+        {
+            // Follow mouse
+            targetingLine.UpdateTargeting(dragStartPosition, mouseWorldPos, false);
+        }
+    }
+
+    private void HandleLeftClickUp()
+    {
+        if (!isDragging || selectedCharacter == null) return;
+
+        Vector3 mouseWorldPos = GetMouseWorldPosition();
+        GameObject enemyAtMouse = GetEnemyAtPosition(mouseWorldPos);
+
+        if (enemyAtMouse != null)
+        {
+            // Set attack target
+            selectedCharacter.actionData.SetAttackTarget(enemyAtMouse);
+
+        }
+        else
+        {
+            // Set move target
+            selectedCharacter.actionData.SetMoveTarget(mouseWorldPos);
+
+        }
+
+        selectedCharacter.SetVisualState(selectedCharacter.actionData.state);
+
+        // Cleanup
+        targetingLine.StopTargeting();
+        selectedCharacter = null;
+        isDragging = false;
+    }
+
+    private void HandleRightClick()
+    {
+        if (isDragging && selectedCharacter != null)
+        {
+            // Cancel current action
+            selectedCharacter.actionData.Reset();
+            selectedCharacter.SetVisualState(ActionDecisionState.NoAction);
+
+            targetingLine.StopTargeting();
+            selectedCharacter = null;
+            isDragging = false;
+        }
+        else
+        {
+            // Right click on character to reset their action
+            Vector3 mouseWorldPos = GetMouseWorldPosition();
+            Character clickedCharacter = GetPlayerCharacterAtPosition(mouseWorldPos);
+
+            if (clickedCharacter != null)
+            {
+                clickedCharacter.actionData.Reset();
+                clickedCharacter.SetVisualState(ActionDecisionState.NoAction);
+            }
+        }
+    }
+
+    private Vector3 GetMouseWorldPosition()
+    {
+        Ray ray = mainCamera.ScreenPointToRay(Input.mousePosition);
+        RaycastHit hit;
+
+        // Raycast against a ground plane or existing colliders
+        if (Physics.Raycast(ray, out hit, 200f))
+        {
+            return hit.point;
+        }
+
+        // Fallback: project onto a horizontal plane at y=0
+        Plane groundPlane = new Plane(Vector3.up, Vector3.zero);
+        if (groundPlane.Raycast(ray, out float distance))
+        {
+            return ray.GetPoint(distance);
+        }
+
+        return Vector3.zero;
+    }
+
+    private Character GetPlayerCharacterAtPosition(Vector3 worldPosition)
+    {
+        Ray ray = mainCamera.ScreenPointToRay(Input.mousePosition);
+        RaycastHit hit;
+
+
+
+        if (Physics.Raycast(ray, out hit, 200f, playerLayerMask))
+        {
+
+            return hit.collider.GetComponent<Character>();
+        }
+
+        // Try raycast without layer mask to see what we're hitting
+        if (Physics.Raycast(ray, out hit, 200f))
+        {
+
+        }
+        else
+        {
+
+        }
+
+        return null;
+    }
+
+    private GameObject GetEnemyAtPosition(Vector3 worldPosition)
+    {
+        Ray ray = mainCamera.ScreenPointToRay(Input.mousePosition);
+        RaycastHit hit;
+
+        if (Physics.Raycast(ray, out hit, 200f, enemyLayerMask))
+        {
+            return hit.collider.gameObject;
+        }
+        return null;
+    }
+
+    public bool AllCharactersHaveActions()
+    {
+        foreach (var character in playerCharacters)
+        {
+            // Characters need actions if they have no action set
+            if (character.actionData.state == ActionDecisionState.NoAction)
+                return false;
+        }
+        return true;
+    }
+
+    public void ResetAllCharacterActions()
+    {
+        foreach (var character in playerCharacters)
+        {
+            character.actionData.Reset();
+            character.SetVisualState(ActionDecisionState.NoAction);
+        }
+    }
+
+    public void UpdateVisualStates()
+    {
+        foreach (var character in playerCharacters)
+        {
+            // Update visual states based on current action status
+            if (character.actionData.state == ActionDecisionState.NoAction)
+            {
+                character.SetVisualState(ActionDecisionState.NoAction); // Pink
+
+            }
+            else if (character.HasActionSelected())
+            {
+                character.SetVisualState(ActionDecisionState.ActionSelected); // Green
+
+            }
+        }
+    }
+
+    public void RefreshPlayerCharacters()
+    {
+        InitializePlayerCharacters();
+    }
+
+    public void SetEnabled(bool enabled)
+    {
+        isEnabled = enabled;
+        if (!enabled)
+        {
+            if (isDragging)
+            {
+                // Cancel any current dragging operation
+                targetingLine.StopTargeting();
+                selectedCharacter = null;
+                isDragging = false;
+            }
+            // Don't automatically hide action lines when disabling - let caller decide
+        }
+
+    }
+
+    public void ShowActiveActionLines()
+    {
+        HideActiveActionLines(); // Clear any existing lines first
+
+        foreach (var character in playerCharacters)
+        {
+            if (character.HasActionSelected() && !character.IsActionComplete())
+            {
+                GameObject lineObject = new GameObject($"ActionLine_{character.name}");
+                TargetingLine line = lineObject.AddComponent<TargetingLine>();
+                activeActionLines.Add(line);
+
+                Vector3 startPos = character.transform.position + Vector3.up * 0.5f;
+
+                if (character.actionData.targetEnemy != null)
+                {
+                    Vector3 endPos = character.actionData.targetEnemy.transform.position + Vector3.up * 0.5f;
+                    line.StartTargeting(startPos);
+                    line.UpdateTargeting(startPos, endPos, true); // true for enemy target (red line)
+
+                }
+                else if (character.actionData.targetPosition != Vector3.zero)
+                {
+                    line.StartTargeting(startPos);
+                    line.UpdateTargeting(startPos, character.actionData.targetPosition, false); // false for movement (blue line)
+
+                }
+            }
+        }
+    }
+
+    public void HideActiveActionLines()
+    {
+        foreach (var line in activeActionLines)
+        {
+            if (line != null)
+            {
+                line.StopTargeting();
+                Destroy(line.gameObject);
+            }
+        }
+        activeActionLines.Clear();
+
+    }
+
+    public void ClearActionLineForCharacter(Character character)
+    {
+        for (int i = activeActionLines.Count - 1; i >= 0; i--)
+        {
+            var line = activeActionLines[i];
+            if (line != null && line.gameObject.name == $"ActionLine_{character.name}")
+            {
+                line.StopTargeting();
+                Destroy(line.gameObject);
+                activeActionLines.RemoveAt(i);
+
+                break;
+            }
+        }
+    }
+}

+ 56 - 0
Assets/Scripts/BattleScene/TargetingLine.cs

@@ -0,0 +1,56 @@
+using UnityEngine;
+
+public class TargetingLine : MonoBehaviour
+{
+    [Header("Line Settings")]
+    public Material lineMaterial;
+    public Color moveLineColor = Color.blue;
+    public Color attackLineColor = Color.red;
+    public float lineWidth = 0.1f;
+
+    private LineRenderer lineRenderer;
+    private bool isActive = false;
+
+    void Awake()
+    {
+        SetupLineRenderer();
+    }
+
+    private void SetupLineRenderer()
+    {
+        lineRenderer = gameObject.AddComponent<LineRenderer>();
+        lineRenderer.material = lineMaterial;
+        lineRenderer.startWidth = lineWidth;
+        lineRenderer.endWidth = lineWidth;
+        lineRenderer.positionCount = 2;
+        lineRenderer.enabled = false; // Initially hidden
+        lineRenderer.sortingOrder = 10; // Ensure it renders above other objects
+
+    }
+
+    public void StartTargeting(Vector3 startPosition)
+    {
+        isActive = true;
+        lineRenderer.enabled = true;
+        lineRenderer.SetPosition(0, startPosition);
+        lineRenderer.SetPosition(1, startPosition);
+    }
+
+    public void UpdateTargeting(Vector3 startPosition, Vector3 endPosition, bool isEnemyTarget)
+    {
+        if (!isActive) return;
+
+        lineRenderer.SetPosition(0, startPosition);
+        lineRenderer.SetPosition(1, endPosition);
+        lineRenderer.startColor = isEnemyTarget ? attackLineColor : moveLineColor;
+        lineRenderer.endColor = isEnemyTarget ? attackLineColor : moveLineColor;
+    }
+
+    public void StopTargeting()
+    {
+        isActive = false;
+        lineRenderer.enabled = false;
+    }
+
+    public bool IsActive => isActive;
+}

+ 6 - 0
Assets/Scripts/BattleScene/TurnManager.cs

@@ -0,0 +1,6 @@
+using UnityEngine;
+
+public class TurnManager : MonoBehaviour
+{
+
+}

+ 16 - 0
Assets/Scripts/BattleSetup/BattleSetupData.cs

@@ -0,0 +1,16 @@
+using System.Collections.Generic;
+using UnityEngine;
+
+public static class BattleSetupData
+{
+    public static List<CharacterSelection> playerSelections = new List<CharacterSelection>();
+    public static List<CharacterSelection> enemySelections = new List<CharacterSelection>();
+
+
+}
+[System.Serializable]
+public class CharacterSelection
+{
+    public string characterName;
+    public string weaponType; // "Sword", "Bow", etc.
+}

+ 92 - 0
Assets/Scripts/BattleSetup/BattleSetupMenu.cs

@@ -0,0 +1,92 @@
+using UnityEngine;
+using UnityEngine.UI;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using UnityEngine.SceneManagement;
+
+public class BattleSetupMenu : MonoBehaviour
+{
+    public Transform playerListParent;
+    public Transform enemyListParent;
+    public GameObject characterEntryPrefab; // Prefab dropdown for Weapon, remove button etc.
+    public Button addPlayerButton;
+    public Button addEnemyButton;
+    public Button startBattleButton;
+    public Button backToTeamSelectButton; // New back button
+
+    private List<GameObject> playerEntries = new List<GameObject>();
+    private List<GameObject> enemyEntries = new List<GameObject>();
+
+    void Start()
+    {
+        addPlayerButton.onClick.AddListener(() => AddCharacterEntry(true));
+        addEnemyButton.onClick.AddListener(() => AddCharacterEntry(false));
+        startBattleButton.onClick.AddListener(StartBattle);
+
+        // Add back button listener
+        if (backToTeamSelectButton != null)
+        {
+            backToTeamSelectButton.onClick.AddListener(BackToTeamSelect);
+        }
+
+        UpdateStartButton();
+    }
+
+    void AddCharacterEntry(bool isPlayer)
+    {
+        var entry = Instantiate(characterEntryPrefab, isPlayer ? playerListParent : enemyListParent);
+        var entryScript = entry.GetComponent<CharacterEntryUI>();
+        entryScript.Setup(isPlayer, RemoveEntry, UpdateStartButton);
+        if (isPlayer)
+        {
+            playerEntries.Add(entry);
+        }
+        else
+        {
+            enemyEntries.Add(entry);
+        }
+        UpdateStartButton();
+    }
+
+    void RemoveEntry(GameObject entry, bool isPlayer)
+    {
+        if (isPlayer)
+        {
+            playerEntries.Remove(entry);
+        }
+        else
+        {
+            enemyEntries.Remove(entry);
+        }
+        Destroy(entry);
+        UpdateStartButton();
+    }
+
+    void UpdateStartButton()
+    {
+        startBattleButton.interactable = playerEntries.Count > 0 && enemyEntries.Count > 0;
+    }
+
+    void StartBattle()
+    {
+        BattleSetupData.playerSelections.Clear();
+        BattleSetupData.enemySelections.Clear();
+        foreach (var entry in playerEntries)
+        {
+            BattleSetupData.playerSelections.Add(entry.GetComponent<CharacterEntryUI>().GetSelection());
+        }
+        foreach (var entry in enemyEntries)
+        {
+            BattleSetupData.enemySelections.Add(entry.GetComponent<CharacterEntryUI>().GetSelection());
+        }
+
+        SceneManager.LoadScene("BattleScene");
+    }
+
+    void BackToTeamSelect()
+    {
+        Debug.Log("Returning to team selection...");
+        SceneManager.LoadScene("MainTeamSelectScene");
+    }
+
+}

+ 56 - 0
Assets/Scripts/Characters/Enemies/SkeletonCharacter.cs

@@ -0,0 +1,56 @@
+using UnityEngine;
+
+public class SkeletonCharacter : Character
+{
+
+    public Weapon weaponPrefab; // Assign the weapon prefab in the inspector
+    public GameObject arrowPrefab; // Assign the arrow prefab in the inspector
+    protected override void InitializeStats()
+    {
+        MaxHealth = 10;
+        CurrentHealth = MaxHealth;
+        Attack = 8;
+        Constitution = 5;
+        Dexterity = 3;
+        Wisdom = 2;
+
+        InitModifier = -2;
+        DamageModifier = 0;
+        SpellModifier = 0;
+        MovementSpeed = 10;
+        ArmorClass = 6;
+    }
+
+    public override Character Spawn(int count)
+    {
+        name = "Skeleton";
+        CharacterName = "Skeleton";
+        if (count > 1)
+        {
+            name += " " + count;
+            CharacterName += " " + count;
+        }
+
+        return this;
+    }
+
+    public override Weapon GetWeapon()
+    {
+        // Return null to trigger direct weapon creation in SpawnAndEquipWeapon
+        return weaponPrefab == null ? CreateDirectWeapon() : weaponPrefab;
+    }
+
+    protected override Weapon CreateDirectWeapon()
+    {
+        // Create weapon directly without prefab system
+        GameObject bowObject = new GameObject("Simple Bow");
+        bowObject.transform.SetParent(this.transform, false);
+
+        SimpleBow bowComponent = bowObject.AddComponent<SimpleBow>();
+        bowComponent.arrowPrefab = this.arrowPrefab;
+        spawnedWeapon = bowComponent;
+
+        spawnedWeapon.SetWielder(this);
+        return spawnedWeapon;
+    }
+}

+ 51 - 0
Assets/Scripts/Characters/HumanCharacter.cs

@@ -0,0 +1,51 @@
+using UnityEngine;
+
+public class HumanCharacter : Character
+{
+    public Weapon weaponPrefab; // Assign the weapon prefab in the inspector
+    public GameObject arrowPrefab; // Assign the arrow prefab in the inspector
+    protected override void InitializeStats()
+    {
+        MaxHealth = 20;
+        CurrentHealth = MaxHealth;
+        Attack = 8;
+        Constitution = 5;
+        Dexterity = 3;
+        Wisdom = 2;
+
+        InitModifier = -2;
+        DamageModifier = 0;
+        SpellModifier = 0;
+        MovementSpeed = 10;
+        ArmorClass = 10;
+    }
+
+    public override Weapon GetWeapon()
+    {
+        // Return null to trigger direct weapon creation in SpawnAndEquipWeapon
+        return weaponPrefab == null ? CreateDirectWeapon() : weaponPrefab;
+    }
+
+    protected override Weapon CreateDirectWeapon()
+    {
+        // Create weapon directly without prefab system
+        GameObject swordObject = new GameObject("Simple Sword");
+        swordObject.transform.SetParent(this.transform, false);
+        spawnedWeapon = swordObject.AddComponent<SimpleSword>();
+        spawnedWeapon.SetWielder(this);
+        return spawnedWeapon;
+    }
+
+    public override Character Spawn(int count)
+    {
+        name = "Human";
+        CharacterName = "Human";
+        if (count > 1)
+        {
+            name += " " + count;
+            CharacterName += " " + count;
+        }
+
+        return this;
+    }
+}

+ 84 - 0
Assets/Scripts/Controllers/CameraController.cs

@@ -0,0 +1,84 @@
+using UnityEngine;
+using UnityEngine.EventSystems;
+
+public class CameraController : MonoBehaviour
+{
+
+    public float moveSpeed = 10f;
+    public float rotationSpeed = 100f;
+    public float zoomSpeed = 10f;
+    public float minZoom = 5f;
+    public float maxZoom = 50f;
+
+    private Transform cam;
+    void Start()
+    {
+        cam = Camera.main.transform;
+    }
+
+    void Update()
+    {
+        // Only handle camera input if mouse is within the map area
+        if (IsMouseInMapArea())
+        {
+            float h = Input.GetAxis("Horizontal");
+            float v = Input.GetAxis("Vertical");
+            transform.Translate(new Vector3(h, 0, v) * moveSpeed * Time.unscaledDeltaTime, Space.World);
+            float moveX = 0, moveZ = 0;
+            if (Input.GetKey(KeyCode.W)) moveZ += 1;
+            if (Input.GetKey(KeyCode.S)) moveZ -= 1;
+            if (Input.GetKey(KeyCode.A)) moveX -= 1;
+            if (Input.GetKey(KeyCode.D)) moveX += 1;
+            transform.Translate(new Vector3(moveX, 0, moveZ) * moveSpeed * Time.unscaledDeltaTime, Space.World);
+
+            if (Input.GetKey(KeyCode.Q))
+            {
+                transform.Rotate(Vector3.up, -rotationSpeed * Time.unscaledDeltaTime);
+            }
+            if (Input.GetKey(KeyCode.E))
+            {
+                transform.Rotate(Vector3.up, rotationSpeed * Time.unscaledDeltaTime);
+            }
+
+            float scroll = Input.GetAxis("Mouse ScrollWheel");
+            if (scroll != 0f)
+            {
+                Vector3 pos = cam.localPosition;
+                pos += cam.forward * scroll * zoomSpeed;
+                pos = Vector3.ClampMagnitude(pos, maxZoom);
+                pos.y = Mathf.Clamp(pos.y, minZoom, maxZoom);
+                cam.localPosition = pos;
+            }
+        }
+    }
+
+    /// <summary>
+    /// Check if the mouse is currently within the map area (not in UI panels)
+    /// </summary>
+    /// <returns>True if mouse is in the map area, false if in UI areas</returns>
+    private bool IsMouseInMapArea()
+    {
+        Vector2 mousePosition = Input.mousePosition;
+
+        // Define the map area bounds (adjust these values based on your UI layout)
+        // These values represent the approximate red square area from your image
+        float leftUIWidth = 150f;      // Map Legend panel width
+        float rightUIWidth = 300f;     // Your Team panel width
+        float topUIHeight = 0f;        // No top UI currently
+        float bottomUIHeight = 0f;     // No bottom UI currently
+
+        // Calculate the actual map area
+        float mapLeft = leftUIWidth;
+        float mapRight = Screen.width - rightUIWidth;
+        float mapTop = Screen.height - topUIHeight;
+        float mapBottom = bottomUIHeight;
+
+        // Check if mouse is within the map area
+        bool inMapArea = mousePosition.x >= mapLeft &&
+                        mousePosition.x <= mapRight &&
+                        mousePosition.y >= mapBottom &&
+                        mousePosition.y <= mapTop;
+
+        return inMapArea;
+    }
+}

+ 198 - 0
Assets/Scripts/Controllers/CinemachineCameraController.cs

@@ -0,0 +1,198 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using Unity.Cinemachine;
+using Unity.VisualScripting;
+using UnityEngine;
+using UnityEngine.EventSystems;
+
+public class CinemachineCameraController : MonoBehaviour
+{
+    public static CinemachineCameraController Instance { get; private set; }
+    public CinemachineCamera actionCam;
+    public GameObject groundPlane;
+
+    [Header("Camera Controls")]
+    public float minZoom = 15f;
+    public float maxZoom = 80f;
+    public float zoomSpeed = 10f;
+    public float panSpeed = 30f;
+    public float cameraAngle = 60f; // degrees
+    private Vector3 framingPosition;
+    private float framingHeight;
+    private float framingDistance;
+    private float zoomLevel;
+    private Coroutine cameraMoveCoroutine;
+    private Vector3 panOffset = Vector3.zero;
+    private float yaw = 0f; // Add this field at the top with your other private fields
+
+
+    private void Awake()
+    {
+        Instance = this;
+    }
+
+    private void Start()
+    {
+        FrameGroundPlane();
+    }
+
+    private void Update()
+    {
+        HandleCameraInput();
+    }
+
+    private void HandleCameraInput()
+    {
+        Rect gameArea = new Rect(0, 0, Screen.width, Screen.height);
+        // Zoom
+        if (Application.isFocused && !EventSystem.current.IsPointerOverGameObject() && gameArea.Contains(Input.mousePosition))
+        {
+            float scroll = Input.GetAxisRaw("Mouse ScrollWheel");
+            if (Mathf.Abs(scroll) > 0.01f)
+            {
+                zoomLevel -= scroll * zoomSpeed;
+                zoomLevel = Mathf.Clamp(zoomLevel, minZoom, maxZoom);
+                FrameGroundPlane();
+            }
+        }
+
+
+        // Pan (WASD or Arrow keys) - works even when paused
+        Vector3 move = Vector3.zero;
+        if (Input.GetKey(KeyCode.A) || Input.GetKey(KeyCode.LeftArrow))
+            move.x -= 1f;
+        if (Input.GetKey(KeyCode.D) || Input.GetKey(KeyCode.RightArrow))
+            move.x += 1f;
+        if (Input.GetKey(KeyCode.W) || Input.GetKey(KeyCode.UpArrow))
+            move.z += 1f;
+        if (Input.GetKey(KeyCode.S) || Input.GetKey(KeyCode.DownArrow))
+            move.z -= 1f;
+
+        if (move != Vector3.zero)
+        {
+            panOffset += move.normalized * panSpeed * Time.unscaledDeltaTime;
+            FrameGroundPlane();
+        }
+
+        // Rotate with middle mouse button
+        if (Input.GetMouseButton(2))
+        {
+            float mouseX = Input.GetAxisRaw("Mouse X");
+            yaw += mouseX * 3f;
+
+            FrameGroundPlane();
+        }
+
+    }
+
+    private void FrameGroundPlane()
+    {
+        if (groundPlane == null)
+        {
+            Debug.LogError("Ground plane is not assigned in CinemachineCameraController.");
+            return;
+        }
+
+        // Use collider bounds to frame the ground plane
+        Collider col = groundPlane.GetComponent<Collider>();
+        if (col == null)
+        {
+            Debug.LogError("Ground plane does not have a collider to frame.");
+            return;
+        }
+
+        Bounds bounds = col.bounds;
+        Vector3 center = bounds.center + panOffset;
+        float size = Mathf.Max(bounds.size.x, bounds.size.z);
+
+        if (zoomLevel < 0.01f)
+        {
+            zoomLevel = size + 5f; // Ensure zoom level is not negative
+        }
+
+        float angleRadians = cameraAngle * Mathf.Deg2Rad;
+        float y = Mathf.Sin(angleRadians) * zoomLevel;
+        float z = -Mathf.Cos(angleRadians) * zoomLevel;
+
+        Quaternion rotation = Quaternion.Euler(0, yaw, 0); // Apply yaw rotation
+        Vector3 offset = rotation * new Vector3(0, y, z);
+
+        framingPosition = center + offset;
+        actionCam.transform.position = framingPosition;
+        actionCam.transform.LookAt(center);
+        actionCam.Follow = null;
+        actionCam.LookAt = null;
+
+        framingHeight = y;
+        framingDistance = Mathf.Abs(z);
+    }
+
+    public void FocusOnCharacter(Transform character)
+    {
+        actionCam.Follow = character;
+        actionCam.LookAt = character;
+    }
+
+    public void FollowTargetingLine(Vector3 mouseWorldPosition)
+    {
+        Vector3 target = new Vector3(mouseWorldPosition.x, 0, mouseWorldPosition.z) + panOffset;
+        float angleRadians = cameraAngle * Mathf.Deg2Rad;
+        float y = Mathf.Sin(angleRadians) * zoomLevel;
+        float z = -Mathf.Cos(angleRadians) * zoomLevel;
+        Vector3 camPos = target + new Vector3(0, y, z);
+        actionCam.transform.position = camPos;
+        actionCam.transform.LookAt(target);
+        actionCam.Follow = null;
+        actionCam.LookAt = null;
+    }
+
+    public void FrameAllCharacters(List<GameObject> characters)
+    {
+        if (characters == null || characters.Count == 0) return;
+        Bounds bounds = new Bounds(characters[0].transform.position, Vector3.zero);
+        foreach (var go in characters)
+            bounds.Encapsulate(go.transform.position);
+
+        Vector3 center = bounds.center + panOffset;
+        float size = Mathf.Max(bounds.size.x, bounds.size.z);
+
+        // Keep current zoomLevel, but allow zoom out if needed to fit all
+        float requiredZoom = size + 5f;
+        if (zoomLevel < requiredZoom)
+        {
+            zoomLevel = requiredZoom;
+        }
+
+        float angleRadians = cameraAngle * Mathf.Deg2Rad;
+        float y = Mathf.Sin(angleRadians) * zoomLevel;
+        float z = -Mathf.Cos(angleRadians) * zoomLevel;
+        Vector3 camPos = center + new Vector3(0, y, z);
+
+        // Start smooth movement
+        if (cameraMoveCoroutine != null)
+            StopCoroutine(cameraMoveCoroutine);
+        cameraMoveCoroutine = StartCoroutine(SmoothMoveCamera(camPos, center, 0.7f));
+    }
+
+    private IEnumerator SmoothMoveCamera(Vector3 targetPosition, Vector3 lookAtTarget, float duration)
+    {
+        Vector3 startPos = actionCam.transform.position;
+        Quaternion startRot = actionCam.transform.rotation;
+        Quaternion endRot = Quaternion.LookRotation(lookAtTarget - targetPosition, Vector3.up);
+
+        float elapsed = 0f;
+        while (elapsed < duration)
+        {
+            float t = elapsed / duration;
+            actionCam.transform.position = Vector3.Lerp(startPos, targetPosition, t);
+            actionCam.transform.rotation = Quaternion.Slerp(startRot, endRot, t);
+            elapsed += Time.deltaTime;
+            yield return null;
+        }
+        actionCam.transform.position = targetPosition;
+        actionCam.transform.rotation = endRot;
+        actionCam.Follow = null;
+        actionCam.LookAt = null;
+    }
+}

+ 0 - 0
Assets/Scripts/Debug/FixTravelUISetup.cs


+ 78 - 0
Assets/Scripts/Debug/MapAreaVisualizer.cs

@@ -0,0 +1,78 @@
+using UnityEngine;
+
+/// <summary>
+/// Helper script to visualize the map area boundaries in the Unity editor
+/// Attach this to any GameObject in the scene to see the map area outlined
+/// </summary>
+public class MapAreaVisualizer : MonoBehaviour
+{
+    [Header("Map Area Settings")]
+    [Tooltip("Width of the left UI panel (Map Legend)")]
+    public float leftUIWidth = 150f;
+
+    [Tooltip("Width of the right UI panel (Your Team)")]
+    public float rightUIWidth = 300f;
+
+    [Tooltip("Height of top UI panels")]
+    public float topUIHeight = 0f;
+
+    [Tooltip("Height of bottom UI panels")]
+    public float bottomUIHeight = 0f;
+
+    [Header("Visualization")]
+    public bool showDebugInfo = true;
+    public Color mapAreaColor = Color.green;
+    public Color uiAreaColor = Color.red;
+
+    void OnGUI()
+    {
+        if (!showDebugInfo) return;
+
+        // Calculate map area bounds
+        float mapLeft = leftUIWidth;
+        float mapRight = Screen.width - rightUIWidth;
+        float mapTop = Screen.height - topUIHeight;
+        float mapBottom = bottomUIHeight;
+
+        // Draw map area outline
+        GUI.color = mapAreaColor;
+        DrawRect(new Rect(mapLeft, mapBottom, mapRight - mapLeft, mapTop - mapBottom), 2);
+
+        // Draw UI areas
+        GUI.color = uiAreaColor;
+        // Left UI area
+        DrawRect(new Rect(0, 0, leftUIWidth, Screen.height), 2);
+        // Right UI area  
+        DrawRect(new Rect(mapRight, 0, rightUIWidth, Screen.height), 2);
+
+        // Reset color
+        GUI.color = Color.white;
+
+        // Show mouse position and status
+        Vector2 mousePos = Input.mousePosition;
+        mousePos.y = Screen.height - mousePos.y; // Flip Y for GUI coordinates
+
+        bool inMapArea = mousePos.x >= mapLeft &&
+                        mousePos.x <= mapRight &&
+                        mousePos.y >= mapBottom &&
+                        mousePos.y <= mapTop;
+
+        string status = inMapArea ? "IN MAP AREA" : "IN UI AREA";
+        GUI.color = inMapArea ? Color.green : Color.red;
+        GUI.Label(new Rect(10, 10, 200, 20), $"Mouse: {status}");
+        GUI.Label(new Rect(10, 30, 200, 20), $"Position: {Input.mousePosition.x:F0}, {Input.mousePosition.y:F0}");
+        GUI.color = Color.white;
+    }
+
+    void DrawRect(Rect rect, float thickness)
+    {
+        // Top
+        GUI.DrawTexture(new Rect(rect.x, rect.y, rect.width, thickness), Texture2D.whiteTexture);
+        // Bottom
+        GUI.DrawTexture(new Rect(rect.x, rect.y + rect.height - thickness, rect.width, thickness), Texture2D.whiteTexture);
+        // Left
+        GUI.DrawTexture(new Rect(rect.x, rect.y, thickness, rect.height), Texture2D.whiteTexture);
+        // Right
+        GUI.DrawTexture(new Rect(rect.x + rect.width - thickness, rect.y, thickness, rect.height), Texture2D.whiteTexture);
+    }
+}

+ 95 - 0
Assets/Scripts/Debug/QuickTravelSystemSetup.cs

@@ -0,0 +1,95 @@
+using UnityEngine;
+
+/// <summary>
+/// Quick setup script to add all necessary travel system components to the current scene.
+/// Run this from the context menu or attach it to a GameObject.
+/// </summary>
+public class QuickTravelSystemSetup : MonoBehaviour
+{
+    [ContextMenu("Setup Travel System")]
+    public void SetupTravelSystem()
+    {
+        Debug.Log("🔧 Setting up Travel System...");
+
+        // Find or create main components
+        SetupTeamTravelSystem();
+        SetupTravelDebugger();
+
+        Debug.Log("✅ Travel System setup complete!");
+        Debug.Log("💡 Use F8 to toggle travel system debug logs");
+        Debug.Log("💡 Use F9 to toggle debug overlay");
+        Debug.Log("💡 Click on the map to plan travel routes");
+    }
+
+    private void SetupTeamTravelSystem()
+    {
+        TeamTravelSystem travelSystem = FindFirstObjectByType<TeamTravelSystem>();
+
+        if (travelSystem == null)
+        {
+            GameObject travelObj = new GameObject("TeamTravelSystem");
+            travelSystem = travelObj.AddComponent<TeamTravelSystem>();
+            Debug.Log("✅ Created TeamTravelSystem");
+        }
+        else
+        {
+            Debug.Log("🔍 Found existing TeamTravelSystem");
+        }
+
+        // Enable debug logs by default
+        travelSystem.showDebugLogs = true;
+        Debug.Log("✅ Enabled travel system debug logs");
+    }
+
+    private void SetupTravelDebugger()
+    {
+        TravelSystemDebugger debugger = FindFirstObjectByType<TravelSystemDebugger>();
+
+        if (debugger == null)
+        {
+            GameObject debugObj = new GameObject("TravelSystemDebugger");
+            debugger = debugObj.AddComponent<TravelSystemDebugger>();
+            Debug.Log("✅ Created TravelSystemDebugger");
+        }
+        else
+        {
+            Debug.Log("🔍 Found existing TravelSystemDebugger");
+        }
+
+        // Enable debug overlay by default
+        debugger.enableDebugOverlay = true;
+        Debug.Log("✅ Enabled debug overlay");
+    }
+
+    [ContextMenu("Test Travel System")]
+    public void TestTravelSystem()
+    {
+        Debug.Log("🧪 Testing Travel System Components...");
+
+        var mapMaker = FindFirstObjectByType<MapMaker2>();
+        var teamPlacement = FindFirstObjectByType<SimpleTeamPlacement>();
+        var travelSystem = FindFirstObjectByType<TeamTravelSystem>();
+
+        Debug.Log($"MapMaker2: {(mapMaker != null ? "✅ Found" : "❌ Missing")}");
+        Debug.Log($"SimpleTeamPlacement: {(teamPlacement != null ? "✅ Found" : "❌ Missing")}");
+        Debug.Log($"TeamTravelSystem: {(travelSystem != null ? "✅ Found" : "❌ Missing")}");
+
+        if (teamPlacement != null)
+        {
+            Debug.Log($"Team Placed: {(teamPlacement.IsTeamPlaced() ? "✅ Yes" : "❌ No")}");
+            if (teamPlacement.IsTeamPlaced())
+            {
+                Debug.Log($"Team Position: {teamPlacement.GetTeamPosition()}");
+            }
+        }
+
+        if (mapMaker?.GetMapData() != null)
+        {
+            var mapData = mapMaker.GetMapData();
+            Debug.Log($"Map Size: {mapData.Width}x{mapData.Height}");
+            Debug.Log($"Tile Size: {mapMaker.mapVisualizer?.tileSize ?? 1f}");
+        }
+
+        Debug.Log("🧪 Test complete");
+    }
+}

+ 193 - 0
Assets/Scripts/Debug/TravelSystemDebugger.cs

@@ -0,0 +1,193 @@
+using UnityEngine;
+
+/// <summary>
+/// Debug helper for the travel system - helps troubleshoot coordinate issues
+/// </summary>
+public class TravelSystemDebugger : MonoBehaviour
+{
+    [Header("Debug Settings")]
+    public bool enableDebugOverlay = true;
+    public bool showCoordinates = true;
+    public bool showCameraInfo = true;
+    public KeyCode toggleKey = KeyCode.F9;
+
+    [Header("Visual Debug")]
+    public Color guiTextColor = Color.yellow;
+    public int fontSize = 16;
+
+    private Camera mapCamera;
+    private MapMaker2 mapMaker;
+    private SimpleTeamPlacement teamPlacement;
+    private TeamTravelSystem travelSystem;
+
+    void Start()
+    {
+        mapCamera = Camera.main;
+        mapMaker = FindFirstObjectByType<MapMaker2>();
+        teamPlacement = FindFirstObjectByType<SimpleTeamPlacement>();
+        travelSystem = FindFirstObjectByType<TeamTravelSystem>();
+    }
+
+    void Update()
+    {
+        if (Input.GetKeyDown(toggleKey))
+        {
+            enableDebugOverlay = !enableDebugOverlay;
+            Debug.Log($"🔧 Travel System Debug Overlay: {(enableDebugOverlay ? "ENABLED" : "DISABLED")}");
+        }
+
+        // Log mouse clicks for debugging
+        if (Input.GetMouseButtonDown(0))
+        {
+            LogMouseClickInfo();
+        }
+    }
+
+    void OnGUI()
+    {
+        if (!enableDebugOverlay) return;
+
+        GUI.color = guiTextColor;
+        GUIStyle style = new GUIStyle(GUI.skin.label);
+        style.fontSize = fontSize;
+
+        float yPos = 50f;
+        float lineHeight = 25f;
+
+        // Mouse position info
+        if (showCoordinates)
+        {
+            Vector3 mousePos = Input.mousePosition;
+            GUI.Label(new Rect(10, yPos, 400, lineHeight), $"Screen Mouse: {mousePos.x:F0}, {mousePos.y:F0}", style);
+            yPos += lineHeight;
+
+            if (mapCamera != null)
+            {
+                Vector3 worldPos = GetMouseWorldPosition();
+                GUI.Label(new Rect(10, yPos, 400, lineHeight), $"World Mouse: {worldPos.x:F2}, {worldPos.y:F2}, {worldPos.z:F2}", style);
+                yPos += lineHeight;
+
+                Vector2Int tilePos = WorldToTilePosition(worldPos);
+                GUI.Label(new Rect(10, yPos, 400, lineHeight), $"Tile Position: {tilePos.x}, {tilePos.y}", style);
+                yPos += lineHeight;
+            }
+        }
+
+        // Camera info
+        if (showCameraInfo && mapCamera != null)
+        {
+            GUI.Label(new Rect(10, yPos, 400, lineHeight), $"Camera Pos: {mapCamera.transform.position.x:F1}, {mapCamera.transform.position.y:F1}, {mapCamera.transform.position.z:F1}", style);
+            yPos += lineHeight;
+            GUI.Label(new Rect(10, yPos, 400, lineHeight), $"Camera Size: {mapCamera.orthographicSize:F1}", style);
+            yPos += lineHeight;
+        }
+
+        // System status
+        yPos += lineHeight;
+        GUI.Label(new Rect(10, yPos, 400, lineHeight), "=== SYSTEM STATUS ===", style);
+        yPos += lineHeight;
+
+        bool mapMakerOK = mapMaker != null;
+        bool teamPlacementOK = teamPlacement != null && teamPlacement.IsTeamPlaced();
+        bool travelSystemOK = travelSystem != null;
+
+        GUI.color = mapMakerOK ? Color.green : Color.red;
+        GUI.Label(new Rect(10, yPos, 400, lineHeight), $"MapMaker2: {(mapMakerOK ? "✅ OK" : "❌ Missing")}", style);
+        yPos += lineHeight;
+
+        GUI.color = teamPlacementOK ? Color.green : Color.red;
+        GUI.Label(new Rect(10, yPos, 400, lineHeight), $"Team Placement: {(teamPlacementOK ? "✅ OK" : "❌ Missing/Not Placed")}", style);
+        yPos += lineHeight;
+
+        GUI.color = travelSystemOK ? Color.green : Color.red;
+        GUI.Label(new Rect(10, yPos, 400, lineHeight), $"Travel System: {(travelSystemOK ? "✅ OK" : "❌ Missing")}", style);
+        yPos += lineHeight;
+
+        if (teamPlacementOK)
+        {
+            GUI.color = Color.cyan;
+            Vector2Int teamPos = teamPlacement.GetTeamPosition();
+            GUI.Label(new Rect(10, yPos, 400, lineHeight), $"Team Position: {teamPos.x}, {teamPos.y}", style);
+            yPos += lineHeight;
+        }
+
+        if (mapMakerOK && mapMaker.GetMapData() != null)
+        {
+            GUI.color = Color.cyan;
+            var mapData = mapMaker.GetMapData();
+            GUI.Label(new Rect(10, yPos, 400, lineHeight), $"Map Size: {mapData.Width}x{mapData.Height}", style);
+            yPos += lineHeight;
+
+            float tileSize = mapMaker.mapVisualizer?.tileSize ?? 1f;
+            GUI.Label(new Rect(10, yPos, 400, lineHeight), $"Tile Size: {tileSize}", style);
+            yPos += lineHeight;
+        }
+
+        GUI.color = Color.white;
+    }
+
+    private void LogMouseClickInfo()
+    {
+        Debug.Log("=== MOUSE CLICK DEBUG ===");
+        Debug.Log($"Screen Position: {Input.mousePosition}");
+
+        if (mapCamera != null)
+        {
+            Vector3 worldPos = GetMouseWorldPosition();
+            Debug.Log($"World Position: {worldPos}");
+
+            Vector2Int tilePos = WorldToTilePosition(worldPos);
+            Debug.Log($"Tile Position: {tilePos}");
+
+            if (mapMaker?.GetMapData() != null)
+            {
+                var mapData = mapMaker.GetMapData();
+                bool isValid = mapData.IsValidPosition(tilePos.x, tilePos.y);
+                Debug.Log($"Valid Tile: {isValid}");
+
+                if (isValid)
+                {
+                    var tile = mapData.GetTile(tilePos.x, tilePos.y);
+                    Debug.Log($"Tile Info: {tile.terrainType}, {tile.featureType}");
+                }
+            }
+        }
+        else
+        {
+            Debug.LogWarning("No camera found for world position calculation");
+        }
+
+        Debug.Log("========================");
+    }
+
+    private Vector3 GetMouseWorldPosition()
+    {
+        if (mapCamera == null) return Vector3.zero;
+
+        Ray ray = mapCamera.ScreenPointToRay(Input.mousePosition);
+
+        // Try raycast first
+        if (Physics.Raycast(ray, out RaycastHit hit, 1000f))
+        {
+            return hit.point;
+        }
+
+        // Fallback: use camera plane projection at Z=0 (map level)
+        Plane mapPlane = new Plane(Vector3.back, Vector3.zero);
+        if (mapPlane.Raycast(ray, out float distance))
+        {
+            return ray.GetPoint(distance);
+        }
+
+        return Vector3.zero;
+    }
+
+    private Vector2Int WorldToTilePosition(Vector3 worldPos)
+    {
+        float tileSize = mapMaker?.mapVisualizer?.tileSize ?? 1f;
+        return new Vector2Int(
+            Mathf.RoundToInt(worldPos.x / tileSize),
+            Mathf.RoundToInt(worldPos.y / tileSize)
+        );
+    }
+}

+ 148 - 0
Assets/Scripts/Documentation/ShopInventorySystem.md

@@ -0,0 +1,148 @@
+# Shop/Inventory System Documentation
+
+## Overview
+This system provides a comprehensive shop and inventory management solution for your RPG game. It includes:
+- Filterable and searchable shop interface
+- Currency system (Gold, Silver, Copper)
+- Inventory management for weapons, armor, and miscellaneous items
+- Integration with the existing team character creation system
+
+## Components Created
+
+### Core Item System
+- **Item.cs**: Base class for all items with cost, search functionality
+- **WeaponItem.cs**: ScriptableObject for weapon data
+- **ArmorItem.cs**: ScriptableObject for armor data  
+- **MiscellaneousItem.cs**: ScriptableObject for consumables and misc items
+
+### Shop System
+- **Shop.cs**: ScriptableObject shop configuration
+- **ShopUI.cs**: Advanced shop UI controller (full featured)
+- **SimpleShopManager.cs**: Basic shop implementation that works with existing system
+
+### Inventory System
+- **Inventory.cs**: Character inventory management
+- **Bank.cs**: Enhanced currency system
+
+### Integration
+- **MainTeamSelectScript.cs**: Updated to include shop/inventory functionality
+- **SimpleSword.cs** & **SimpleBow.cs**: Updated to work with item system
+
+### UI Files
+- **ShopUI.uxml**: Shop interface layout
+- **ShopUI.uss**: Shop styling
+- **InventorySheet.uxml**: Already existed, now fully functional
+
+## Quick Setup Guide
+
+### 1. Basic Setup
+1. Create a GameObject in your scene called "ShopManager"
+2. Attach the `SimpleShopManager` script to it
+3. Add a `UIDocument` component to the same GameObject
+4. Assign `ShopUI.uxml` as the Visual Tree Asset in the UIDocument
+
+### 2. Alternative: Use Setup Script
+1. Add the `ShopSystemSetup` script to any GameObject
+2. Check "Create Shop GameObject" in the inspector
+3. The shop system will be automatically set up
+
+### 3. Test the System
+1. Open the Team Select scene
+2. Create a character
+3. Click "Add Weapon", "Add Armor", or "Add Misc" buttons
+4. The shop will open with filterable/searchable items
+
+## Features
+
+### Shop Features
+- **Search**: Type to find items by name, description, or tags
+- **Filtering**: Filter by category (All, Weapons, Armor, Miscellaneous)
+- **Affordability**: Items you can't afford are grayed out
+- **Dynamic Pricing**: Gold/Silver/Copper conversion system
+
+### Inventory Features
+- **Currency Management**: Gold, Silver, Copper with automatic conversion
+- **Item Lists**: Separate lists for weapons, armor, and misc items
+- **Add/Remove**: Easy item management through UI buttons
+- **Persistence**: Items are saved with character data
+
+### Sample Items Included
+The system comes with sample items:
+
+**Weapons:**
+- Simple Sword (10g)
+- Simple Bow (15g) 
+- Iron Sword (25g)
+- Composite Bow (35g)
+
+**Armor:**
+- Leather Helmet (5g)
+- Leather Vest (12g)
+- Iron Chainmail (30g)
+
+**Miscellaneous:**
+- Health Potion (3g)
+- Hemp Rope (8s)
+- Torch (2s)
+
+## Currency System
+- **1 Gold = 10 Silver = 100 Copper**
+- Characters start with 50 gold
+- Automatic conversion when making purchases
+- Bank fields in inventory are editable for testing
+
+## Extending the System
+
+### Adding New Items
+1. Create ScriptableObject assets using the "RPG/Items/" menu
+2. Configure item properties (name, description, cost, stats)
+3. Add search tags for better discoverability
+4. Add to shop's available items list
+
+### Adding New Weapon Types
+1. Create a new weapon script inheriting from `Weapon`
+2. Add an `InitializeFromItem(WeaponItem)` method
+3. Update `WeaponItem.CreateWeaponInstance()` to handle the new type
+
+### Customizing Shop
+- Modify `SimpleShopManager.InitializeDefaultItems()` for different starting inventory
+- Create multiple shop GameObjects with different item sets
+- Customize shop appearance by editing `ShopUI.uss` styles
+
+## Integration with Existing Weapon System
+
+The new system is backward compatible with your existing weapon system:
+- `SimpleSword` and `SimpleBow` classes updated to work with `WeaponItem` data
+- Characters can still use weapons without the shop system
+- Weapon creation can use either old direct instantiation or new item-based creation
+
+## Troubleshooting
+
+### Shop Not Opening
+- Check that `SimpleShopManager` exists in scene
+- Verify `UIDocument` has `ShopUI.uxml` assigned
+- Look for error messages in console
+
+### Items Not Showing
+- Check `InitializeDefaultItems()` method is populating lists
+- Verify filter/search settings aren't hiding items
+- Check item costs aren't higher than character's money
+
+### Inventory Not Updating
+- Ensure `UpdateInventoryUI()` is called after character changes
+- Check that character has the new currency fields initialized
+- Verify UI elements are properly connected in `GetUIElementReferences()`
+
+## Performance Notes
+- Items are created dynamically in UI for better performance
+- Character data uses simple string lists for basic compatibility
+- Full ScriptableObject system available for more complex item management
+
+## Future Enhancements
+This system provides a solid foundation that can be extended with:
+- Item tooltips with detailed stats
+- Equipment slots and stat bonuses
+- Item rarity and visual effects
+- Shop keeper NPCs and dialogue
+- Item crafting and upgrades
+- Save/load integration

+ 0 - 0
Assets/Scripts/MainTeamSelect/Character.cs


+ 2040 - 0
Assets/Scripts/MainTeamSelect/MainTeamSelectScript.cs

@@ -0,0 +1,2040 @@
+using UnityEngine;
+using UnityEngine.UIElements; // Make sure you have this using directive
+using UnityEngine.SceneManagement; // Added for scene management
+using System.Collections.Generic; // Needed for List<>
+using System.Linq; // Needed for LINQ operations
+using System.Collections; // Needed for coroutines
+
+public class MainTeamSelectScript : MonoBehaviour
+{
+    private UIDocument uiDocument;
+    private TeamCharacter currentCharacter;
+    private List<Button> characterSlotButtons = new List<Button>();
+    private List<Button> createNewCharacterButtons = new List<Button>();
+
+    // Character slot management
+    private TeamCharacter[] characterSlots = new TeamCharacter[4]; // 4 character slots
+    private int currentSlotIndex = -1; // -1 means no slot selected
+
+    // UI elements
+    private TextField characterNameField;
+    private Button randomizeNameButton;
+    private DropdownField genderDropdown;
+    private IntegerField strengthField, dexterityField, constitutionField, wisdomField;
+    private IntegerField initField, damageField, spellCastingField, movementSpeedField, hpField, acField;
+
+    // Attribute management UI
+    private Button randomizeAttributesButton;
+    private Button resetToPointBuyButton;
+    private Label availablePointsLabel;
+    private Label creationModeLabel;
+
+    // Inventory/Shop UI elements
+    private Button addWeaponButton;
+    private Button addArmorButton;
+    private Button addMiscButton;
+    private IntegerField goldField;
+    private IntegerField silverField;
+    private IntegerField copperField;
+    private VisualElement weaponsList;
+    private VisualElement armorList;
+    private VisualElement miscList;
+
+    // Shop reference
+    private SimpleShopManager shopManager;
+
+    // Navigation buttons
+    private Button backToTitleButton;
+    private Button proceedToBattleButton;
+
+    void Awake()
+    {
+        uiDocument = GetComponent<UIDocument>();
+        if (uiDocument == null)
+        {
+            Debug.LogError("UIDocument component not found on this GameObject.", this);
+            return; // Exit if no UIDocument is found
+        }
+
+        // Initialize character slots array
+        characterSlots = new TeamCharacter[4];
+
+        // Clear all existing character equipment to ensure shop-only acquisition
+        ClearAllCharacterEquipment();
+
+        // Start with no character selected (empty character sheet)
+        currentCharacter = null;
+        currentSlotIndex = -1;
+
+        // Check if team has been finalized (proceeded to map)
+        bool teamFinalized = IsTeamFinalized();
+
+        // Load saved team if available
+        LoadSavedTeamData();
+
+        // Get UI element references
+        GetUIElementReferences();
+
+        // Set up event listeners
+        SetupEventListeners();
+
+        // Try to find missing UI elements one more time after everything is set up
+        ValidateUIElements();
+
+        // If team is finalized, disable editing and show message
+        if (teamFinalized)
+        {
+            SetTeamFinalizedMode();
+        }
+
+        // Initialize UI with character data
+        UpdateCharacterUI();
+        UpdateSlotVisualStates();
+        UpdateNavigationButtons();
+    }
+
+    private void ValidateUIElements()
+    {
+        // Final attempt to find critical UI elements that might have been missed
+        if (proceedToBattleButton == null && uiDocument != null)
+        {
+            var root = uiDocument.rootVisualElement;
+            Debug.LogWarning("Final attempt to find proceedToBattleButton...");
+
+            // Try searching with different approaches
+            proceedToBattleButton = root.Q<Button>("ProceedToBattleButton") ??
+                                  root.Q<Button>("ProceedButton") ??
+                                  root.Q<Button>("StartButton") ??
+                                  root.Q<Button>(className: "proceed-button");
+
+            // If still not found, search through all buttons for text matches
+            if (proceedToBattleButton == null)
+            {
+                var allButtons = root.Query<Button>().ToList();
+                foreach (var button in allButtons)
+                {
+                    if (button.text.ToLower().Contains("proceed") ||
+                        button.text.ToLower().Contains("start") ||
+                        button.text.ToLower().Contains("battle"))
+                    {
+                        proceedToBattleButton = button;
+
+                        break;
+                    }
+                }
+            }
+
+            if (proceedToBattleButton != null)
+            {
+
+                // Set up the event listener since we found it late
+                proceedToBattleButton.clicked += OnProceedToBattleClicked;
+            }
+            else
+            {
+                Debug.LogError("CRITICAL: Could not find proceed button in UI! Please check the UI Document.");
+            }
+        }
+    }
+
+    private void GetUIElementReferences()
+    {
+        var root = uiDocument.rootVisualElement;
+
+        // Character info fields
+        characterNameField = root.Q<TextField>("CharacterNameField");
+        randomizeNameButton = root.Q<Button>("RandomizeNameButton");
+        genderDropdown = root.Q<DropdownField>("GenderDropdown");
+
+        // Stat fields
+        strengthField = root.Q<IntegerField>("StrengthValue");
+        dexterityField = root.Q<IntegerField>("DexterityValue");
+        constitutionField = root.Q<IntegerField>("ConstitutionValue");
+        wisdomField = root.Q<IntegerField>("WisdomValue");
+
+        // Derived stat fields
+        initField = root.Q<IntegerField>("InitValue");
+        damageField = root.Q<IntegerField>("DamageValue");
+        spellCastingField = root.Q<IntegerField>("SpellCastingValue");
+        movementSpeedField = root.Q<IntegerField>("MovementSpeedValue");
+        hpField = root.Q<IntegerField>("HPValue");
+        acField = root.Q<IntegerField>("ACValue");
+
+        // Attribute management UI
+        randomizeAttributesButton = root.Q<Button>("RandomizeAttributesButton");
+        resetToPointBuyButton = root.Q<Button>("ResetToPointBuyButton");
+        availablePointsLabel = root.Q<Label>("AvailablePointsLabel");
+        creationModeLabel = root.Q<Label>("CreationModeLabel");
+
+        // Find all buttons with the name "CreateNewCharacterButton"
+        createNewCharacterButtons = uiDocument.rootVisualElement.Query<Button>("CreateNewCharacterButton").ToList();
+
+        // Find all ViewCharacterButton buttons
+        characterSlotButtons = uiDocument.rootVisualElement.Query<Button>("ViewCharacterButton").ToList();
+
+        // Inventory/Shop UI elements
+        addWeaponButton = root.Q<Button>("AddWeaponButton");
+        addArmorButton = root.Q<Button>("AddArmourButton");
+        addMiscButton = root.Q<Button>("AddMiscButton");
+        goldField = root.Q<IntegerField>("GoldValue");
+        silverField = root.Q<IntegerField>("SilverValue");
+        copperField = root.Q<IntegerField>("CopperValue");
+        weaponsList = root.Q<VisualElement>("WeaponsList");
+        armorList = root.Q<VisualElement>("ArmourList");
+        miscList = root.Q<VisualElement>("MiscList");
+
+        // Navigation buttons
+        backToTitleButton = root.Q<Button>("BackToTitleButton");
+        proceedToBattleButton = root.Q<Button>("ProceedToBattleButton");
+
+        // Debug and fallback for Back to Title button
+        if (backToTitleButton == null)
+        {
+            Debug.LogWarning("BackToTitleButton not found! Creating fallback button...");
+
+            // Create a simple fallback button
+            backToTitleButton = new Button();
+            backToTitleButton.text = "Back to Title";
+            backToTitleButton.name = "BackToTitleButton_Fallback";
+            backToTitleButton.style.position = Position.Absolute;
+            backToTitleButton.style.top = 10;
+            backToTitleButton.style.left = 10;
+            backToTitleButton.style.width = 120;
+            backToTitleButton.style.height = 30;
+            root.Add(backToTitleButton);
+
+        }
+
+        // Find shop manager in scene
+        shopManager = FindFirstObjectByType<SimpleShopManager>();
+        if (shopManager == null)
+        {
+            Debug.LogWarning("No SimpleShopManager found in scene. Shop functionality will be limited.");
+            Debug.LogWarning("Trying to refresh shop manager reference...");
+
+            // Try again after a short delay to allow for potential late initialization
+            StartCoroutine(RefreshShopManagerReference());
+        }
+        else
+        {
+
+            SetupShopManagerCallbacks();
+        }
+
+        // Check if any buttons were found
+        if (createNewCharacterButtons.Count == 0)
+        {
+            Debug.LogWarning("No buttons with the name 'CreateNewCharacterButton' found in the UI Document.");
+        }
+        else
+        {
+            // Add a click listener to each button found
+            foreach (Button button in createNewCharacterButtons)
+            {
+                // Example of passing data (requires adjusting the handler method):
+                int characterIndex = createNewCharacterButtons.IndexOf(button); // Example data
+                button.clicked += () => OnCreateNewCharacterButtonClicked(characterIndex);
+            }
+
+        }
+
+        // Add click listeners to ViewCharacterButton buttons
+        for (int i = 0; i < characterSlotButtons.Count; i++)
+        {
+            int index = i; // Capture the index for the closure
+            characterSlotButtons[i].clicked += () => OnViewCharacterButtonClicked(index);
+        }
+    }
+
+    private void SetupEventListeners()
+    {
+        // Name randomization
+        if (randomizeNameButton != null)
+        {
+            randomizeNameButton.clicked += OnRandomizeNameClicked;
+        }
+
+        // Character name change
+        if (characterNameField != null)
+        {
+            characterNameField.RegisterValueChangedCallback(OnCharacterNameChanged);
+        }
+
+        // Gender change
+        if (genderDropdown != null)
+        {
+            genderDropdown.RegisterValueChangedCallback(OnGenderChanged);
+        }
+
+        // Stat changes
+        if (strengthField != null)
+            strengthField.RegisterValueChangedCallback(evt => OnStatChanged());
+        if (dexterityField != null)
+            dexterityField.RegisterValueChangedCallback(evt => OnStatChanged());
+        if (constitutionField != null)
+            constitutionField.RegisterValueChangedCallback(evt => OnStatChanged());
+        if (wisdomField != null)
+            wisdomField.RegisterValueChangedCallback(evt => OnStatChanged());
+
+        // Attribute management
+        if (randomizeAttributesButton != null)
+            randomizeAttributesButton.clicked += OnRandomizeAttributesClicked;
+        if (resetToPointBuyButton != null)
+            resetToPointBuyButton.clicked += OnResetToPointBuyClicked;
+
+        // Inventory/Shop management
+        if (addWeaponButton != null)
+            addWeaponButton.clicked += OnAddWeaponClicked;
+        if (addArmorButton != null)
+            addArmorButton.clicked += OnAddArmorClicked;
+        if (addMiscButton != null)
+            addMiscButton.clicked += OnAddMiscClicked;
+
+        // Bank field changes
+        if (goldField != null)
+            goldField.RegisterValueChangedCallback(evt => OnBankChanged());
+        if (silverField != null)
+            silverField.RegisterValueChangedCallback(evt => OnBankChanged());
+        if (copperField != null)
+            copperField.RegisterValueChangedCallback(evt => OnBankChanged());
+
+        // Navigation buttons
+        if (backToTitleButton != null)
+            backToTitleButton.clicked += OnBackToTitleClicked;
+        if (proceedToBattleButton != null)
+            proceedToBattleButton.clicked += OnProceedToBattleClicked;
+        else
+            Debug.LogWarning("proceedToBattleButton is null during SetupEventListeners - will try to set up event listener later");
+    }
+
+    private void OnRandomizeNameClicked()
+    {
+        if (currentCharacter == null) return;
+
+        currentCharacter.GenerateRandomName();
+        characterNameField.value = currentCharacter.name;
+
+        // Update the slot button and save to slot
+        UpdateCurrentSlotButton();
+        SaveCurrentCharacterToSlot();
+    }
+
+    private void OnCharacterNameChanged(ChangeEvent<string> evt)
+    {
+        if (currentCharacter == null) return;
+
+        currentCharacter.name = evt.newValue;
+
+        // Update the slot button and save to slot
+        UpdateCurrentSlotButton();
+        SaveCurrentCharacterToSlot();
+
+        // Update the character card if we have a current slot
+        if (currentSlotIndex >= 0)
+        {
+            UpdateCharacterCard(currentSlotIndex, currentCharacter);
+        }
+    }
+
+    private void OnGenderChanged(ChangeEvent<string> evt)
+    {
+        if (currentCharacter == null) return;
+
+        currentCharacter.SetGender(evt.newValue == "Male");
+        // Optionally regenerate name when gender changes
+        // You can remove this if you don't want automatic name regeneration
+        currentCharacter.GenerateRandomName();
+        characterNameField.value = currentCharacter.name;
+
+        // Update the slot button and save to slot
+        UpdateCurrentSlotButton();
+        SaveCurrentCharacterToSlot();
+
+        // Update the character card if we have a current slot
+        if (currentSlotIndex >= 0)
+        {
+            UpdateCharacterCard(currentSlotIndex, currentCharacter);
+        }
+    }
+
+    private void OnStatChanged()
+    {
+        if (currentCharacter == null) return;
+
+        // Validate point-buy constraints
+        int newStr = strengthField?.value ?? currentCharacter.strength;
+        int newDex = dexterityField?.value ?? currentCharacter.dexterity;
+        int newCon = constitutionField?.value ?? currentCharacter.constitution;
+        int newWis = wisdomField?.value ?? currentCharacter.wisdom;
+
+        // Clamp values to valid range (4-18)
+        newStr = Mathf.Clamp(newStr, 4, 18);
+        newDex = Mathf.Clamp(newDex, 4, 18);
+        newCon = Mathf.Clamp(newCon, 4, 18);
+        newWis = Mathf.Clamp(newWis, 4, 18);
+
+        // Check if the new combination is affordable
+        int totalCost = TeamCharacter.GetStatCost(newStr) + TeamCharacter.GetStatCost(newDex) +
+                       TeamCharacter.GetStatCost(newCon) + TeamCharacter.GetStatCost(newWis);
+
+        if (totalCost <= 18) // Changed from 27 to 18 for 4-stat system
+        {
+            // Update character stats from UI
+            currentCharacter.strength = newStr;
+            currentCharacter.dexterity = newDex;
+            currentCharacter.constitution = newCon;
+            currentCharacter.wisdom = newWis;
+            currentCharacter.UpdateAvailablePoints();
+        }
+        else
+        {
+            // Reset to previous valid values
+            if (strengthField != null) strengthField.value = currentCharacter.strength;
+            if (dexterityField != null) dexterityField.value = currentCharacter.dexterity;
+            if (constitutionField != null) constitutionField.value = currentCharacter.constitution;
+            if (wisdomField != null) wisdomField.value = currentCharacter.wisdom;
+        }
+
+        // Update derived stats and point display
+        UpdateDerivedStats();
+        UpdateAttributeUI();
+        SaveCurrentCharacterToSlot();
+        UpdateNavigationButtons();
+
+        // Update the character card if we have a current slot
+        if (currentSlotIndex >= 0)
+        {
+            UpdateCharacterCard(currentSlotIndex, currentCharacter);
+        }
+    }
+    private void OnRandomizeAttributesClicked()
+    {
+        if (currentCharacter == null) return;
+
+        currentCharacter.RandomizeAttributes();
+        UpdateCharacterUI();
+        UpdateAttributeUI();
+        SaveCurrentCharacterToSlot();
+        UpdateNavigationButtons();
+
+        // Update the character card if we have a current slot
+        if (currentSlotIndex >= 0)
+        {
+            UpdateCharacterCard(currentSlotIndex, currentCharacter);
+        }
+    }
+
+    private void OnResetToPointBuyClicked()
+    {
+        if (currentCharacter == null) return;
+
+        currentCharacter.ResetToPointBuy();
+        UpdateCharacterUI();
+        UpdateAttributeUI();
+        SaveCurrentCharacterToSlot();
+        UpdateNavigationButtons();
+
+        // Update the character card if we have a current slot
+        if (currentSlotIndex >= 0)
+        {
+            UpdateCharacterCard(currentSlotIndex, currentCharacter);
+        }
+    }
+
+    private void OnAddWeaponClicked()
+    {
+        if (currentCharacter == null)
+        {
+            Debug.LogWarning("OnAddWeaponClicked: No current character selected");
+            return;
+        }
+
+        // Open weapon shop for this character
+        OpenWeaponShop();
+    }
+
+    private void OpenWeaponShop()
+    {
+        if (shopManager != null)
+        {
+            shopManager.OpenShop(currentCharacter);
+        }
+        else
+        {
+            Debug.LogWarning("No shop manager found - cannot open shop");
+        }
+    }
+
+    private void AddWeaponToCharacter(string weaponType)
+    {
+        // Add weapon to character's inventory (would integrate with real shop/inventory system)
+        if (currentCharacter.weapons == null)
+        {
+            currentCharacter.weapons = new System.Collections.Generic.List<string>();
+        }
+
+        currentCharacter.weapons.Add(weaponType);
+        SaveCurrentCharacterToSlot();
+    }
+
+    private void OnAddArmorClicked()
+    {
+        if (currentCharacter == null) return;
+
+        if (shopManager != null)
+        {
+            shopManager.OpenShop(currentCharacter);
+        }
+        else
+        {
+            Debug.LogWarning("No shop manager found - cannot open shop");
+        }
+    }
+
+    private void OnAddMiscClicked()
+    {
+        if (currentCharacter == null) return;
+
+        if (shopManager != null)
+        {
+            shopManager.OpenShop(currentCharacter);
+        }
+        else
+        {
+            Debug.LogWarning("No shop manager found - cannot open shop");
+        }
+    }
+
+    private void AddArmorToCharacter(string armorType)
+    {
+        if (currentCharacter.armor == null)
+        {
+            currentCharacter.armor = new System.Collections.Generic.List<string>();
+        }
+
+        currentCharacter.armor.Add(armorType);
+        SaveCurrentCharacterToSlot();
+        UpdateInventoryUI();
+    }
+
+    private void AddMiscItemToCharacter(string itemType)
+    {
+        if (currentCharacter.miscItems == null)
+        {
+            currentCharacter.miscItems = new System.Collections.Generic.List<string>();
+        }
+
+        currentCharacter.miscItems.Add(itemType);
+        SaveCurrentCharacterToSlot();
+        UpdateInventoryUI();
+    }
+
+    private void OnBankChanged()
+    {
+        if (currentCharacter == null) return;
+
+        currentCharacter.gold = goldField?.value ?? currentCharacter.gold;
+        currentCharacter.silver = silverField?.value ?? currentCharacter.silver;
+        currentCharacter.copper = copperField?.value ?? currentCharacter.copper;
+
+        SaveCurrentCharacterToSlot();
+    }
+
+    private void UpdateInventoryUI()
+    {
+        if (currentCharacter == null) return;
+
+        // Update bank fields
+        if (goldField != null) goldField.value = currentCharacter.gold;
+        if (silverField != null) silverField.value = currentCharacter.silver;
+        if (copperField != null) copperField.value = currentCharacter.copper;
+
+        // Update weapon list
+        UpdateItemList(weaponsList, currentCharacter.weapons, "WeaponItemRow", OnRemoveWeapon);
+
+        // Update armor list  
+        UpdateItemList(armorList, currentCharacter.armor, "ArmorItemRow", OnRemoveArmor);
+
+        // Update misc list
+        UpdateItemList(miscList, currentCharacter.miscItems, "MiscItemRow", OnRemoveMisc);
+    }
+
+    private void UpdateItemList(VisualElement container, System.Collections.Generic.List<string> items, string rowClassName, System.Action<string> removeAction)
+    {
+        if (container == null || items == null) return;
+
+        // Clear existing items (except example rows)
+        var itemsToRemove = container.Query<VisualElement>(className: "inventory-item-row").ToList()
+            .Where(item => !item.name.Contains("Example")).ToList();
+
+        foreach (var item in itemsToRemove)
+        {
+            container.Remove(item);
+        }
+
+        // Add current items
+        foreach (var itemName in items)
+        {
+            var itemRow = new VisualElement();
+            itemRow.AddToClassList("inventory-item-row");
+            itemRow.AddToClassList(rowClassName);
+
+            var nameLabel = new Label(itemName);
+            nameLabel.AddToClassList("item-name-label");
+            itemRow.Add(nameLabel);
+
+            var removeButton = new Button(() => removeAction(itemName));
+            removeButton.text = "Remove (Refund)";
+            removeButton.AddToClassList("remove-item-button");
+
+            // Add tooltip or title to show refund information
+            string itemType = GetItemTypeFromClassName(rowClassName);
+            string refundInfo = GetRefundInfo(itemName, itemType);
+            if (!string.IsNullOrEmpty(refundInfo))
+            {
+                removeButton.tooltip = $"Remove and refund: {refundInfo}";
+            }
+
+            itemRow.Add(removeButton);
+
+            container.Add(itemRow);
+        }
+    }
+
+    private string GetItemTypeFromClassName(string className)
+    {
+        if (className.Contains("Weapon")) return "weapon";
+        if (className.Contains("Armor")) return "armor";
+        if (className.Contains("Misc")) return "misc";
+        return "";
+    }
+
+    private string GetRefundInfo(string itemName, string itemType)
+    {
+        if (shopManager == null) return "";
+
+        System.Collections.Generic.List<SimpleShopItem> itemList = null;
+
+        switch (itemType.ToLower())
+        {
+            case "weapon":
+                itemList = shopManager.weapons;
+                break;
+            case "armor":
+                itemList = shopManager.armor;
+                break;
+            case "misc":
+                itemList = shopManager.miscItems;
+                break;
+        }
+
+        if (itemList != null)
+        {
+            var shopItem = itemList.Find(item => item.name == itemName);
+            if (shopItem != null)
+            {
+                return shopItem.GetCostString();
+            }
+        }
+
+        return "";
+    }
+
+    private void RefundItemPrice(string itemName, string itemType)
+    {
+        if (shopManager == null || currentCharacter == null)
+        {
+            Debug.LogWarning($"Cannot refund {itemName}: shop manager or current character is null");
+            return;
+        }
+
+        // Find the item price from the shop manager
+        int goldRefund = 0;
+        int silverRefund = 0;
+        int copperRefund = 0;
+
+        // Check the appropriate list based on item type
+        System.Collections.Generic.List<SimpleShopItem> itemList = null;
+
+        switch (itemType.ToLower())
+        {
+            case "weapon":
+                itemList = shopManager.weapons;
+                break;
+            case "armor":
+                itemList = shopManager.armor;
+                break;
+            case "misc":
+                itemList = shopManager.miscItems;
+                break;
+        }
+
+        if (itemList != null)
+        {
+            // Find the item in the shop list
+            var shopItem = itemList.Find(item => item.name == itemName);
+            if (shopItem != null)
+            {
+                goldRefund = shopItem.goldCost;
+                silverRefund = shopItem.silverCost;
+                copperRefund = shopItem.copperCost;
+
+                // Add the refund to the character's money
+                currentCharacter.gold += goldRefund;
+                currentCharacter.silver += silverRefund;
+                currentCharacter.copper += copperRefund;
+            }
+            else
+            {
+                Debug.LogWarning($"Could not find {itemName} in shop {itemType} list for refund");
+            }
+        }
+        else
+        {
+            Debug.LogWarning($"Could not access shop {itemType} list for refund");
+        }
+    }
+
+    private void OnRemoveWeapon(string weaponName)
+    {
+        if (currentCharacter?.weapons != null)
+        {
+            currentCharacter.weapons.Remove(weaponName);
+
+            // Refund the weapon price
+            RefundItemPrice(weaponName, "weapon");
+
+            SaveCurrentCharacterToSlot();
+            UpdateInventoryUI();
+        }
+    }
+
+    private void OnRemoveArmor(string armorName)
+    {
+        if (currentCharacter?.armor != null)
+        {
+            currentCharacter.armor.Remove(armorName);
+
+            // Refund the armor price
+            RefundItemPrice(armorName, "armor");
+
+            SaveCurrentCharacterToSlot();
+            UpdateInventoryUI();
+        }
+    }
+
+    private void OnRemoveMisc(string itemName)
+    {
+        if (currentCharacter?.miscItems != null)
+        {
+            currentCharacter.miscItems.Remove(itemName);
+
+            // Refund the misc item price
+            RefundItemPrice(itemName, "misc");
+
+            SaveCurrentCharacterToSlot();
+            UpdateInventoryUI();
+        }
+    }
+
+    private void UpdateCharacterUI()
+    {
+        if (currentCharacter == null)
+        {
+            // Clear the UI when no character is selected
+            if (characterNameField != null) characterNameField.value = "";
+            if (genderDropdown != null) genderDropdown.value = "Male";
+            if (strengthField != null) strengthField.value = 10;
+            if (dexterityField != null) dexterityField.value = 10;
+            if (constitutionField != null) constitutionField.value = 10;
+            if (wisdomField != null) wisdomField.value = 10;
+
+            // Clear derived stats
+            if (initField != null) initField.value = 0;
+            if (damageField != null) damageField.value = 0;
+            if (spellCastingField != null) spellCastingField.value = 0;
+            if (movementSpeedField != null) movementSpeedField.value = 30;
+            if (hpField != null) hpField.value = 10;
+            if (acField != null) acField.value = 0;
+
+            // Clear attribute UI
+            if (creationModeLabel != null) creationModeLabel.text = "Mode: None";
+            if (availablePointsLabel != null) availablePointsLabel.text = "Available Points: 0";
+            return;
+        }
+
+        // Update UI with current character data
+        if (characterNameField != null)
+            characterNameField.value = currentCharacter.name;
+
+        if (genderDropdown != null)
+            genderDropdown.value = currentCharacter.isMale ? "Male" : "Female";
+
+        if (strengthField != null) strengthField.value = currentCharacter.strength;
+        if (dexterityField != null) dexterityField.value = currentCharacter.dexterity;
+        if (constitutionField != null) constitutionField.value = currentCharacter.constitution;
+        if (wisdomField != null) wisdomField.value = currentCharacter.wisdom;
+
+        // Recalculate equipment bonuses from inventory
+        currentCharacter.RecalculateEquipmentBonuses();
+
+        UpdateDerivedStats();
+        UpdateAttributeUI();
+        UpdateInventoryUI();
+    }
+
+    private void UpdateAttributeUI()
+    {
+        if (currentCharacter == null) return;
+
+        // Update creation mode display
+        if (creationModeLabel != null)
+        {
+            creationModeLabel.text = "Mode: Point Buy";
+        }
+
+        // Update available points display
+        if (availablePointsLabel != null)
+        {
+            availablePointsLabel.text = $"Available Points: {currentCharacter.availablePoints}";
+        }
+
+        // All stat fields are always editable in the new system
+        if (strengthField != null) strengthField.SetEnabled(true);
+        if (dexterityField != null) dexterityField.SetEnabled(true);
+        if (constitutionField != null) constitutionField.SetEnabled(true);
+        if (wisdomField != null) wisdomField.SetEnabled(true);
+    }
+
+    private void UpdateDerivedStats()
+    {
+        if (currentCharacter == null) return;
+
+        // Update the read-only derived stats (uses final stats including equipment modifiers)
+        if (initField != null) initField.value = currentCharacter.Initiative;
+        if (damageField != null) damageField.value = currentCharacter.DamageBonus;
+        if (spellCastingField != null) spellCastingField.value = currentCharacter.SpellAC;
+        if (movementSpeedField != null) movementSpeedField.value = currentCharacter.MovementSpeed;
+        if (hpField != null) hpField.value = currentCharacter.HitPoints;
+        if (acField != null) acField.value = currentCharacter.ArmorClass;
+    }
+
+    private void UpdateCurrentSlotButton()
+    {
+        // Update the character card information if we have a current slot selected
+        if (currentSlotIndex >= 0 && currentSlotIndex < characterSlotButtons.Count && currentCharacter != null)
+        {
+            UpdateCharacterCard(currentSlotIndex, currentCharacter);
+        }
+    }
+
+    private void UpdateCharacterCard(int slotIndex, TeamCharacter character)
+    {
+        if (slotIndex < 0 || slotIndex >= 4 || character == null) return;
+
+        var root = uiDocument.rootVisualElement;
+
+        // Find the character slot instance based on index
+        string[] slotNames = { "Character1", "Character2", "Character3", "Character4" };
+        var characterSlot = root.Q<VisualElement>(slotNames[slotIndex]);
+
+        if (characterSlot == null) return;
+
+        // Find the character card button within this slot
+        var characterCard = characterSlot.Q<Button>("ViewCharacterButton");
+
+        if (characterCard == null) return;
+
+        // Update character name
+        var nameLabel = characterCard.Q<Label>("CharacterNameLabel");
+        if (nameLabel != null)
+        {
+            nameLabel.text = character.name;
+        }
+
+        // Update stats
+        var strengthLabel = characterCard.Q<Label>("StrengthLabel");
+        if (strengthLabel != null) strengthLabel.text = character.strength.ToString();
+
+        var dexterityLabel = characterCard.Q<Label>("DexterityLabel");
+        if (dexterityLabel != null) dexterityLabel.text = character.dexterity.ToString();
+
+        var constitutionLabel = characterCard.Q<Label>("ConstitutionLabel");
+        if (constitutionLabel != null) constitutionLabel.text = character.constitution.ToString();
+
+        var wisdomLabel = characterCard.Q<Label>("WisdomLabel");
+        if (wisdomLabel != null) wisdomLabel.text = character.wisdom.ToString();
+
+        // Update HP and AC
+        var hpLabel = characterCard.Q<Label>("HPLabel");
+        if (hpLabel != null) hpLabel.text = $"HP: {character.HitPoints}";
+
+        var acLabel = characterCard.Q<Label>("ACLabel");
+        if (acLabel != null) acLabel.text = $"AC: {character.ArmorClass}";
+
+        // Show the character card and hide the create button
+        var createButton = characterSlot.Q<Button>("CreateNewCharacterButton");
+        if (createButton != null)
+        {
+            createButton.style.display = DisplayStyle.None;
+        }
+
+        characterCard.RemoveFromClassList("disabled-card");
+        characterCard.style.display = DisplayStyle.Flex;
+        characterCard.SetEnabled(true);
+    }
+
+    private void SaveCurrentCharacterToSlot()
+    {
+        // Save the current character data back to its slot
+        if (currentSlotIndex >= 0 && currentSlotIndex < characterSlots.Length && currentCharacter != null)
+        {
+            characterSlots[currentSlotIndex] = currentCharacter.CreateCopy();
+        }
+    }
+
+    private void UpdateSlotVisualStates()
+    {
+        var root = uiDocument.rootVisualElement;
+        string[] slotNames = { "Character1", "Character2", "Character3", "Character4" };
+
+        // Update visual states of all character slots
+        for (int i = 0; i < slotNames.Length; i++)
+        {
+            var characterSlot = root.Q<VisualElement>(slotNames[i]);
+            if (characterSlot == null) continue;
+
+            // Remove all visual state classes first
+            characterSlot.RemoveFromClassList("selected-slot");
+
+            // Add selected state if this is the current slot
+            if (i == currentSlotIndex)
+            {
+                characterSlot.AddToClassList("selected-slot");
+            }
+
+            // Update character card visibility and data
+            if (characterSlots[i] != null)
+            {
+                // Character exists in this slot
+                UpdateCharacterCard(i, characterSlots[i]);
+            }
+            else
+            {
+                // No character in this slot - show create button
+                var createButton = characterSlot.Q<Button>("CreateNewCharacterButton");
+                var characterCard = characterSlot.Q<Button>("ViewCharacterButton");
+
+                if (createButton != null)
+                {
+                    createButton.style.display = DisplayStyle.Flex;
+                }
+
+                if (characterCard != null)
+                {
+                    characterCard.style.display = DisplayStyle.None;
+                    characterCard.AddToClassList("disabled-card");
+                    characterCard.SetEnabled(false);
+                }
+            }
+        }
+    }
+
+    // Example handler if you need to pass data (like an index)
+    private void OnCreateNewCharacterButtonClicked(int index)
+    {
+        // Create a new character with random name
+        currentCharacter = new TeamCharacter();
+        // Generate name after construction to avoid serialization issues
+        currentCharacter.GenerateRandomName();
+
+        // Save character to the slot (create a proper copy)
+        characterSlots[index] = currentCharacter.CreateCopy();
+        currentSlotIndex = index;
+
+
+
+        UpdateCharacterUI();
+        UpdateSlotVisualStates();
+
+        // Update navigation buttons immediately after character creation
+        UpdateNavigationButtons();
+
+        // Update the character card for this slot
+        UpdateCharacterCard(index, currentCharacter);
+
+        // Call UpdateNavigationButtons again after UI updates
+        UpdateNavigationButtons();
+    }
+
+    private void OnViewCharacterButtonClicked(int index)
+    {
+        // Check if there's a character in this slot
+        if (characterSlots[index] != null)
+        {
+            // Create a working copy of the character from the slot
+            currentCharacter = characterSlots[index].CreateCopy();
+            currentSlotIndex = index;
+            UpdateCharacterUI();
+            UpdateSlotVisualStates();
+            UpdateNavigationButtons();
+        }
+        else
+        {
+            // Slot is empty, save current character to this slot if we have one
+            if (currentCharacter != null)
+            {
+                // Create a proper copy of the current character data
+                characterSlots[index] = currentCharacter.CreateCopy();
+                currentSlotIndex = index;
+
+                // Update the character card for this slot
+                UpdateCharacterCard(index, currentCharacter);
+
+                UpdateSlotVisualStates();
+                UpdateNavigationButtons();
+            }
+        }
+    }
+
+    // Start is called once before the first execution of Update after the MonoBehaviour is created
+    void Start()
+    {
+        // You can keep Start if needed for other initialization
+    }
+
+    // Update is called once per frame
+    void Update()
+    {
+        // Debug keys for testing
+        if (Input.GetKeyDown(KeyCode.F5))
+        {
+
+            DebugCurrentCharacterSlots();
+        }
+
+        if (Input.GetKeyDown(KeyCode.F6))
+        {
+
+            SaveTeamToGameState();
+        }
+
+        if (Input.GetKeyDown(KeyCode.F7))
+        {
+
+            TestPlayerPrefsData();
+        }
+    }
+
+    private void DebugCurrentCharacterSlots()
+    {
+
+        for (int i = 0; i < characterSlots.Length; i++)
+        {
+            if (characterSlots[i] != null)
+            {
+                var character = characterSlots[i];
+
+            }
+            else
+            {
+
+            }
+        }
+
+    }
+
+    private void TestPlayerPrefsData()
+    {
+
+        for (int i = 0; i < 4; i++)
+        {
+            string existsKey = $"Character{i}_Exists";
+            if (PlayerPrefs.HasKey(existsKey))
+            {
+                int exists = PlayerPrefs.GetInt(existsKey);
+
+
+                if (exists == 1)
+                {
+                    string prefix = $"Character{i}_";
+                    string name = PlayerPrefs.GetString(prefix + "Name", "UNKNOWN");
+                    int str = PlayerPrefs.GetInt(prefix + "Strength", 0);
+                    int dex = PlayerPrefs.GetInt(prefix + "Dexterity", 0);
+                    int con = PlayerPrefs.GetInt(prefix + "Constitution", 0);
+                    int wis = PlayerPrefs.GetInt(prefix + "Wisdom", 0);
+
+                }
+            }
+            else
+            {
+
+            }
+        }
+
+    }
+
+    void OnDestroy()
+    {
+        // Clean up shop manager callbacks to prevent memory leaks
+        if (shopManager != null)
+        {
+            shopManager.OnCharacterDataChanged -= OnShopCharacterDataChanged;
+        }
+    }
+
+    #region Navigation Methods
+
+    private void OnBackToTitleClicked()
+    {
+        // Check if team is finalized and this is acting as "New Game" button
+        if (IsTeamFinalized())
+        {
+            // Show confirmation dialog for starting new game
+#if UNITY_EDITOR
+            bool confirmed = UnityEditor.EditorUtility.DisplayDialog(
+                "Start New Game",
+                "This will start a completely new game and overwrite your current progress.\n\nAre you sure you want to continue?",
+                "Start New Game",
+                "Cancel"
+            );
+
+            if (confirmed)
+            {
+                StartNewGame();
+            }
+#else
+            // In builds, we'll assume user confirms for now
+            // In a real game, implement a proper UI dialog system
+            Debug.LogWarning("Starting new game - implement proper dialog for builds");
+            StartNewGame();
+#endif
+        }
+        else
+        {
+            // Normal back to title behavior
+
+            SceneManager.LoadScene("TitleScreenScene");
+        }
+    }
+
+    private void StartNewGame()
+    {
+
+
+        // Initialize GameStateManager for new game
+        if (GameStateManager.Instance != null)
+        {
+            GameStateManager.Instance.StartNewGame();
+        }
+
+        // Clear all save data
+        ClearAllSaveData();
+
+        // Reload the scene to start fresh
+        SceneManager.LoadScene("MainTeamSelectScene");
+    }
+
+    private void ClearAllSaveData()
+    {
+        // Clear GameStateManager data
+        if (GameStateManager.Instance != null)
+        {
+            GameStateManager.Instance.teamSetupComplete = false;
+            GameStateManager.Instance.hasGeneratedMap = false;
+        }
+
+        // Clear PlayerPrefs data
+        for (int i = 0; i < 4; i++)
+        {
+            string prefix = $"Character{i}_";
+            PlayerPrefs.DeleteKey($"Character{i}_Exists");
+            PlayerPrefs.DeleteKey(prefix + "Name");
+            PlayerPrefs.DeleteKey(prefix + "IsMale");
+            PlayerPrefs.DeleteKey(prefix + "Strength");
+            PlayerPrefs.DeleteKey(prefix + "Dexterity");
+            PlayerPrefs.DeleteKey(prefix + "Constitution");
+            PlayerPrefs.DeleteKey(prefix + "Wisdom");
+            PlayerPrefs.DeleteKey(prefix + "Gold");
+            PlayerPrefs.DeleteKey(prefix + "Silver");
+            PlayerPrefs.DeleteKey(prefix + "Copper");
+        }
+
+        // Clear map data
+        PlayerPrefs.DeleteKey("HasGeneratedMap");
+        PlayerPrefs.DeleteKey("MapSeed");
+        PlayerPrefs.DeleteKey("TeamSize");
+        PlayerPrefs.DeleteKey("TeamSetupComplete");
+        PlayerPrefs.DeleteKey("GameSaved");
+
+        PlayerPrefs.Save();
+
+    }
+
+    private void OnProceedToBattleClicked()
+    {
+        // Check if team is already finalized
+        if (IsTeamFinalized())
+        {
+            // Team is finalized, return to MapScene2
+
+            SceneManager.LoadScene("MapScene2");
+            return;
+        }
+
+        // Check if we have at least one character
+        if (!HasAtLeastOneCharacter())
+        {
+            Debug.LogWarning("Need at least one character to proceed to battle!");
+            // TODO: Show message to user
+            return;
+        }
+
+        // Save all configured characters before proceeding
+        SaveTeamToGameState();
+
+        // Mark that the team has proceeded to the map (finalized)
+        // Save to both GameStateManager and PlayerPrefs for redundancy
+        if (GameStateManager.Instance != null)
+        {
+            GameStateManager.Instance.teamSetupComplete = true;
+            GameStateManager.Instance.SaveGame();
+        }
+
+        // Also save to PlayerPrefs as backup
+        PlayerPrefs.SetInt("TeamSetupComplete", 1);
+        PlayerPrefs.Save();
+
+
+
+        SceneManager.LoadScene("MapScene2");
+    }
+
+    private void SaveTeamToGameState()
+    {
+
+
+        // Save team data to GameStateManager for persistence
+        List<TeamCharacter> configuredCharacters = new List<TeamCharacter>();
+
+        for (int i = 0; i < characterSlots.Length; i++)
+        {
+            if (characterSlots[i] != null)
+            {
+                configuredCharacters.Add(characterSlots[i]);
+                // Save individual character data
+                SaveCharacterToPlayerPrefs(characterSlots[i], i);
+
+
+
+
+                // Verify the save immediately
+                PlayerPrefs.SetInt($"Character{i}_Exists", 1);
+                string testName = PlayerPrefs.GetString($"Character{i}_Name", "NOT_FOUND");
+
+            }
+            else
+            {
+                // Clear any existing character data for empty slots
+                PlayerPrefs.DeleteKey($"Character{i}_Exists");
+
+            }
+        }
+
+
+
+        // Save team composition info
+        PlayerPrefs.SetInt("TeamSize", configuredCharacters.Count);
+
+
+        // Update GameStateManager if available
+        if (GameStateManager.Instance != null)
+        {
+
+            // Copy our team to the GameStateManager
+            for (int i = 0; i < characterSlots.Length; i++)
+            {
+                if (characterSlots[i] != null)
+                {
+                    GameStateManager.Instance.savedTeam[i] = characterSlots[i].CreateCopy();
+
+                }
+                else
+                {
+                    GameStateManager.Instance.savedTeam[i] = null;
+                }
+            }
+            GameStateManager.Instance.teamSetupComplete = true;
+            GameStateManager.Instance.SaveGame();
+
+        }
+        else
+        {
+            Debug.LogWarning("GameStateManager.Instance is null!");
+        }
+
+        // Log configured team for MapScene
+
+
+        foreach (var character in configuredCharacters)
+        {
+
+        }
+
+
+        PlayerPrefs.Save(); // Ensure data is written to disk
+
+
+    }
+
+    public List<TeamCharacter> GetConfiguredCharacters()
+    {
+        // Public method to get all configured characters (useful for other scripts)
+        List<TeamCharacter> configuredCharacters = new List<TeamCharacter>();
+
+        for (int i = 0; i < characterSlots.Length; i++)
+        {
+            if (characterSlots[i] != null)
+            {
+                configuredCharacters.Add(characterSlots[i]);
+            }
+        }
+
+        return configuredCharacters;
+    }
+
+    private void UpdateNavigationButtons()
+    {
+        // Enable/disable proceed button based on team status
+        if (proceedToBattleButton != null)
+        {
+            bool canProceed = HasAtLeastOneCharacter();
+
+
+            proceedToBattleButton.SetEnabled(canProceed);
+
+            // Also remove/add visual disabled state
+            if (!canProceed)
+            {
+                proceedToBattleButton.AddToClassList("disabled-button");
+                proceedToBattleButton.tooltip = "Create at least one character to proceed";
+            }
+            else
+            {
+                proceedToBattleButton.RemoveFromClassList("disabled-button");
+                proceedToBattleButton.tooltip = "Start adventure with your team";
+
+                // Force remove any disabled classes that might be interfering
+                proceedToBattleButton.RemoveFromClassList("unity-disabled");
+            }
+
+
+        }
+        else
+        {
+            Debug.LogWarning("UpdateNavigationButtons: proceedToBattleButton is null! The button name in the UI might be different than expected.");
+            Debug.LogWarning("Please check that a button with name 'ProceedToBattleButton' exists in your UI Document.");
+
+            // Try to find the button again with common alternative names
+            var root = uiDocument?.rootVisualElement;
+            if (root != null)
+            {
+                proceedToBattleButton = root.Q<Button>("ProceedButton") ??
+                                     root.Q<Button>("StartButton") ??
+                                     root.Q<Button>("BattleButton") ??
+                                     root.Q<Button>("ProceedToBattleButton");
+
+                if (proceedToBattleButton != null)
+                {
+
+                    // Recursively call this method now that we found the button
+                    UpdateNavigationButtons();
+                }
+            }
+        }
+    }
+
+    private bool HasAtLeastOneCharacter()
+    {
+
+        int characterCount = 0;
+        for (int i = 0; i < characterSlots.Length; i++)
+        {
+            if (characterSlots[i] != null)
+            {
+                characterCount++;
+
+            }
+            else
+            {
+
+            }
+        }
+
+        bool hasCharacters = characterCount > 0;
+
+
+        return hasCharacters;
+    }
+
+    #endregion
+
+    #region Save/Load Team Data
+
+    private void LoadSavedTeamData()
+    {
+        // Try to load from GameStateManager first (if available and has data)
+        if (GameStateManager.Instance != null && GameStateManager.Instance.savedTeam != null)
+        {
+
+            for (int i = 0; i < characterSlots.Length && i < GameStateManager.Instance.savedTeam.Length; i++)
+            {
+                if (GameStateManager.Instance.savedTeam[i] != null)
+                {
+                    characterSlots[i] = GameStateManager.Instance.savedTeam[i].CreateCopy();
+
+                    // Update the slot button
+                    if (i < characterSlotButtons.Count)
+                    {
+                        characterSlotButtons[i].text = characterSlots[i].name;
+                        characterSlotButtons[i].SetEnabled(true);
+                        characterSlotButtons[i].RemoveFromClassList("unity-disabled");
+                        characterSlotButtons[i].RemoveFromClassList("DisabledCharacterCard");
+
+                        // Hide the create button
+                        if (i < createNewCharacterButtons.Count)
+                        {
+                            createNewCharacterButtons[i].style.display = DisplayStyle.None;
+                        }
+                    }
+                }
+            }
+        }
+
+        // Always also try to load from PlayerPrefs (either as backup or primary)
+
+        for (int i = 0; i < characterSlots.Length; i++)
+        {
+            // If we haven't loaded this slot from GameStateManager, try PlayerPrefs
+            if (characterSlots[i] == null && PlayerPrefs.HasKey($"Character{i}_Exists") && PlayerPrefs.GetInt($"Character{i}_Exists") == 1)
+            {
+                // Load character data from PlayerPrefs
+                characterSlots[i] = LoadCharacterFromPlayerPrefs(i);
+
+
+                // Update the slot button
+                if (i < characterSlotButtons.Count)
+                {
+                    characterSlotButtons[i].text = characterSlots[i].name;
+                    characterSlotButtons[i].SetEnabled(true);
+                    characterSlotButtons[i].RemoveFromClassList("unity-disabled");
+                    characterSlotButtons[i].RemoveFromClassList("DisabledCharacterCard");
+
+                    // Hide the create button
+                    if (i < createNewCharacterButtons.Count)
+                    {
+                        createNewCharacterButtons[i].style.display = DisplayStyle.None;
+                    }
+                }
+            }
+        }
+
+        // Count loaded characters
+        int loadedCount = 0;
+        for (int i = 0; i < characterSlots.Length; i++)
+        {
+            if (characterSlots[i] != null) loadedCount++;
+        }
+    }
+
+    private void SaveCurrentTeamToGameState()
+    {
+        // Save the current team using PlayerPrefs for now
+        for (int i = 0; i < characterSlots.Length; i++)
+        {
+            if (characterSlots[i] != null)
+            {
+                SaveCharacterToPlayerPrefs(characterSlots[i], i);
+                PlayerPrefs.SetInt($"Character{i}_Exists", 1);
+            }
+            else
+            {
+                PlayerPrefs.SetInt($"Character{i}_Exists", 0);
+            }
+        }
+        PlayerPrefs.Save();
+    }
+
+    private TeamCharacter LoadCharacterFromPlayerPrefs(int index)
+    {
+        string prefix = $"Character{index}_";
+        var character = new TeamCharacter();
+
+        character.name = PlayerPrefs.GetString(prefix + "Name", "");
+        character.isMale = PlayerPrefs.GetInt(prefix + "IsMale", 1) == 1;
+        character.strength = PlayerPrefs.GetInt(prefix + "Strength", 10);
+        character.dexterity = PlayerPrefs.GetInt(prefix + "Dexterity", 10);
+        character.constitution = PlayerPrefs.GetInt(prefix + "Constitution", 10);
+        character.wisdom = PlayerPrefs.GetInt(prefix + "Wisdom", 10);
+        character.gold = PlayerPrefs.GetInt(prefix + "Gold", 25);
+        character.silver = PlayerPrefs.GetInt(prefix + "Silver", 0);
+        character.copper = PlayerPrefs.GetInt(prefix + "Copper", 0);
+
+        // Recalculate equipment bonuses from inventory after loading
+        character.RecalculateEquipmentBonuses();
+
+        return character;
+    }
+
+    private void SaveCharacterToPlayerPrefs(TeamCharacter character, int index)
+    {
+        string prefix = $"Character{index}_";
+
+
+
+        PlayerPrefs.SetString(prefix + "Name", character.name);
+        PlayerPrefs.SetInt(prefix + "IsMale", character.isMale ? 1 : 0);
+        PlayerPrefs.SetInt(prefix + "Strength", character.strength);
+        PlayerPrefs.SetInt(prefix + "Dexterity", character.dexterity);
+        PlayerPrefs.SetInt(prefix + "Constitution", character.constitution);
+        PlayerPrefs.SetInt(prefix + "Wisdom", character.wisdom);
+        PlayerPrefs.SetInt(prefix + "Gold", character.gold);
+        PlayerPrefs.SetInt(prefix + "Silver", character.silver);
+        PlayerPrefs.SetInt(prefix + "Copper", character.copper);
+
+        // Immediately verify what was saved
+        string savedName = PlayerPrefs.GetString(prefix + "Name", "FAILED_TO_SAVE");
+        int savedStr = PlayerPrefs.GetInt(prefix + "Strength", -1);
+
+
+        if (savedName != character.name)
+        {
+            Debug.LogError($"  ERROR: Name save failed! Expected '{character.name}', got '{savedName}'");
+        }
+    }
+
+    #endregion
+
+    #region Team Finalization
+
+    private bool IsTeamFinalized()
+    {
+        // Check if the team has been finalized (player clicked "Proceed to Battle" and went to MapScene)
+        // This is indicated by TeamSetupComplete being true or HasGeneratedMap being true
+        bool hasGeneratedMap = PlayerPrefs.HasKey("HasGeneratedMap") && PlayerPrefs.GetInt("HasGeneratedMap") == 1;
+        bool teamSetupCompletePrefs = PlayerPrefs.HasKey("TeamSetupComplete") && PlayerPrefs.GetInt("TeamSetupComplete") == 1;
+        bool teamSetupCompleteGameState = false;
+
+        if (GameStateManager.Instance != null)
+        {
+            teamSetupCompleteGameState = GameStateManager.Instance.teamSetupComplete;
+        }
+
+        bool finalized = hasGeneratedMap || teamSetupCompletePrefs || teamSetupCompleteGameState;
+
+        return finalized;
+    }
+
+    private void SetTeamFinalizedMode()
+    {
+
+
+        // Disable all character creation and editing
+        foreach (var button in createNewCharacterButtons)
+        {
+            button.SetEnabled(false);
+            button.style.opacity = 0.5f;
+            button.tooltip = "Team has been finalized - cannot create new characters";
+        }
+
+        // Disable character editing fields
+        DisableCharacterEditingFields();
+
+        // Change the proceed button to "Return to Adventure"
+        if (proceedToBattleButton != null)
+        {
+            proceedToBattleButton.text = "Return to Adventure";
+            proceedToBattleButton.tooltip = "Return to your ongoing adventure";
+        }
+
+        // Change the back button to offer new game option
+        if (backToTitleButton != null)
+        {
+            backToTitleButton.text = "New Game";
+            backToTitleButton.tooltip = "Start a completely new game (will overwrite current save)";
+        }
+
+        // Show a message that team is finalized
+
+    }
+
+    private void DisableCharacterEditingFields()
+    {
+        // Disable name editing
+        if (characterNameField != null)
+        {
+            characterNameField.SetEnabled(false);
+            characterNameField.style.opacity = 0.7f;
+        }
+
+        if (randomizeNameButton != null)
+        {
+            randomizeNameButton.SetEnabled(false);
+            randomizeNameButton.style.opacity = 0.5f;
+        }
+
+        if (genderDropdown != null)
+        {
+            genderDropdown.SetEnabled(false);
+            genderDropdown.style.opacity = 0.7f;
+        }
+
+        // Disable stat editing
+        if (strengthField != null) strengthField.SetEnabled(false);
+        if (dexterityField != null) dexterityField.SetEnabled(false);
+        if (constitutionField != null) constitutionField.SetEnabled(false);
+        if (wisdomField != null) wisdomField.SetEnabled(false);
+
+        // Disable attribute buttons
+        if (randomizeAttributesButton != null)
+        {
+            randomizeAttributesButton.SetEnabled(false);
+            randomizeAttributesButton.style.opacity = 0.5f;
+        }
+
+        if (resetToPointBuyButton != null)
+        {
+            resetToPointBuyButton.SetEnabled(false);
+            resetToPointBuyButton.style.opacity = 0.5f;
+        }
+
+        // Disable inventory management
+        if (addWeaponButton != null)
+        {
+            addWeaponButton.SetEnabled(false);
+            addWeaponButton.style.opacity = 0.5f;
+        }
+
+        if (addArmorButton != null)
+        {
+            addArmorButton.SetEnabled(false);
+            addArmorButton.style.opacity = 0.5f;
+        }
+
+        if (addMiscButton != null)
+        {
+            addMiscButton.SetEnabled(false);
+            addMiscButton.style.opacity = 0.5f;
+        }
+
+        // Disable bank editing
+        if (goldField != null) goldField.SetEnabled(false);
+        if (silverField != null) silverField.SetEnabled(false);
+        if (copperField != null) copperField.SetEnabled(false);
+    }
+
+    #endregion
+
+    private System.Collections.IEnumerator RefreshShopManagerReference()
+    {
+        // Wait for a short delay to allow for potential late initialization
+        yield return new WaitForSeconds(0.1f);
+
+        // Try to find the shop manager again
+        var newShopManager = FindFirstObjectByType<SimpleShopManager>();
+        if (newShopManager != null)
+        {
+            shopManager = newShopManager;
+            SetupShopManagerCallbacks();
+
+        }
+        else
+        {
+            Debug.LogWarning("Still no SimpleShopManager found after delay. You may need to create one manually using the ShopSystemSetup component.");
+        }
+    }
+
+    private void SetupShopManagerCallbacks()
+    {
+        if (shopManager != null)
+        {
+            // Subscribe to character data changes from the shop
+            shopManager.OnCharacterDataChanged += OnShopCharacterDataChanged;
+        }
+    }
+
+    private void OnShopCharacterDataChanged(TeamCharacter updatedCharacter)
+    {
+        if (updatedCharacter == null || currentCharacter == null)
+        {
+            Debug.LogWarning("OnShopCharacterDataChanged: updatedCharacter or currentCharacter is null");
+            return;
+        }
+
+        // Copy the updated data back to the current character
+        // This ensures the character object reference remains the same but data is updated
+        currentCharacter.gold = updatedCharacter.gold;
+        currentCharacter.silver = updatedCharacter.silver;
+        currentCharacter.copper = updatedCharacter.copper;
+
+        // Update inventory lists (create new lists to avoid reference issues)
+        currentCharacter.weapons = new System.Collections.Generic.List<string>(updatedCharacter.weapons);
+        currentCharacter.armor = new System.Collections.Generic.List<string>(updatedCharacter.armor);
+        currentCharacter.miscItems = new System.Collections.Generic.List<string>(updatedCharacter.miscItems);
+
+        // Update the UI to reflect the changes
+        UpdateInventoryUI();
+
+        // Save the updated character to the slot
+        SaveCurrentCharacterToSlot();
+    }
+
+    // Clear all equipment from existing characters to ensure shop-only acquisition
+    private void ClearAllCharacterEquipment()
+    {
+        // Clear equipment from any existing characters in slots
+        for (int i = 0; i < characterSlots.Length; i++)
+        {
+            if (characterSlots[i] != null)
+            {
+                characterSlots[i].weapons.Clear();
+                characterSlots[i].armor.Clear();
+                characterSlots[i].miscItems.Clear();
+                characterSlots[i].equippedWeapon = "";
+                characterSlots[i].equippedArmor = "";
+            }
+        }
+
+        // Also clear equipment from current character if it exists
+        if (currentCharacter != null)
+        {
+            currentCharacter.weapons.Clear();
+            currentCharacter.armor.Clear();
+            currentCharacter.miscItems.Clear();
+            currentCharacter.equippedWeapon = "";
+            currentCharacter.equippedArmor = "";
+        }
+    }
+}
+
+[System.Serializable]
+public class TeamCharacter
+{
+    public string name = "";
+    public bool isMale = true;
+
+    // Base attributes (can be modified by equipment in the future)
+    public int strength = 10;
+    public int dexterity = 10;
+    public int constitution = 10;
+    public int wisdom = 10;
+
+    // Character creation mode
+    public bool isRandomized = false; // Track if stats were randomized
+    public int availablePoints = 18; // Point-buy system (adjusted for 4 stats instead of 6)
+
+    // Equipment modifiers (for future use)
+    public int strengthModifier = 0;
+    public int dexterityModifier = 0;
+    public int constitutionModifier = 0;
+    public int wisdomModifier = 0;
+    public int acModifier = 0; // Direct AC bonuses from equipment
+
+    // Currency
+    public int gold = 25; // Reduced starting money to make shop purchases more strategic
+    public int silver = 0;
+    public int copper = 0;
+
+    // Equipment/Inventory (simple string-based for now)
+    public System.Collections.Generic.List<string> weapons = new System.Collections.Generic.List<string>();
+    public System.Collections.Generic.List<string> armor = new System.Collections.Generic.List<string>();
+    public System.Collections.Generic.List<string> miscItems = new System.Collections.Generic.List<string>();
+    public string equippedWeapon = "";
+    public string equippedArmor = "";
+
+    // Final attributes (base + equipment modifiers)
+    public int FinalStrength => strength + strengthModifier;
+    public int FinalDexterity => dexterity + dexterityModifier;
+    public int FinalConstitution => constitution + constitutionModifier;
+    public int FinalWisdom => wisdom + wisdomModifier;
+
+    // Derived stats (calculated from final stats)
+    public int Initiative => FinalDexterity - 10;
+    public int DamageBonus => (FinalStrength - 10) / 2;
+    public int SpellAC => FinalWisdom - 10; // Renamed from SpellCastingBonus
+    public int MovementSpeed => 30 + (int)(Mathf.Ceil((FinalDexterity - 10) / 5.0f) * 5); // Rounded to closest 5 above
+    public int HitPoints => Mathf.Max(10, 10 + (FinalConstitution - 10) * 2 + (FinalStrength - 10) + (FinalDexterity - 10) / 2);
+    public int ArmorClass => 10 + (FinalDexterity - 10) / 2 + (FinalConstitution - 10) / 3 + acModifier; // Base 10 + DEX bonus + small CON bonus + equipment AC
+
+    public TeamCharacter()
+    {
+        // Don't generate random name in constructor to avoid serialization issues
+        // Name will be generated explicitly when needed
+    }
+
+    public TeamCharacter(string characterName, bool male = true)
+    {
+        name = characterName;
+        isMale = male;
+    }
+
+    public void GenerateRandomName()
+    {
+        // Only generate names when the application is playing to avoid serialization issues
+        if (Application.isPlaying)
+        {
+            name = FantasyNameGenerator.GenerateCharacterName(isMale);
+        }
+        else
+        {
+            // Fallback name for serialization/design time
+            name = isMale ? "New Male Character" : "New Female Character";
+        }
+    }
+
+    public void SetGender(bool male)
+    {
+        isMale = male;
+    }
+
+    // Randomize all attributes using point-buy system (18 points)
+    public void RandomizeAttributes()
+    {
+        if (Application.isPlaying)
+        {
+            // Start with random base values (4-12 range for variety)
+            int[] stats = new int[4];
+            for (int i = 0; i < 4; i++)
+            {
+                stats[i] = UnityEngine.Random.Range(4, 13); // Random start between 4-12
+            }
+
+            // Calculate how many points we've spent so far
+            int pointsSpent = 0;
+            for (int i = 0; i < 4; i++)
+            {
+                pointsSpent += GetStatCost(stats[i]);
+            }
+
+            int pointsRemaining = 18 - pointsSpent; // Changed from 27 to 18
+
+            // If we're over budget, reduce some stats
+            while (pointsRemaining < 0)
+            {
+                int randomStat = UnityEngine.Random.Range(0, 4);
+                if (stats[randomStat] > 4) // Don't go below 4
+                {
+                    int oldCost = GetStatCost(stats[randomStat]);
+                    stats[randomStat]--;
+                    int newCost = GetStatCost(stats[randomStat]);
+                    pointsRemaining += (oldCost - newCost);
+                }
+            }
+
+            // Now spend remaining points randomly
+            while (pointsRemaining > 0)
+            {
+                // Pick a random stat to increase
+                int randomStat = UnityEngine.Random.Range(0, 4);
+
+                // Check if we can afford to increase this stat
+                int currentValue = stats[randomStat];
+                if (currentValue >= 18) continue; // Can't go higher than 18
+
+                int currentCost = GetStatCost(currentValue);
+                int newCost = GetStatCost(currentValue + 1);
+                int costDifference = newCost - currentCost;
+
+                if (pointsRemaining >= costDifference)
+                {
+                    stats[randomStat]++;
+                    pointsRemaining -= costDifference;
+                }
+                else
+                {
+                    // If we can't afford any increases, try to find a stat we can afford
+                    bool foundAffordable = false;
+                    for (int i = 0; i < 4; i++)
+                    {
+                        if (stats[i] < 18)
+                        {
+                            int testCurrentCost = GetStatCost(stats[i]);
+                            int testNewCost = GetStatCost(stats[i] + 1);
+                            int testCostDiff = testNewCost - testCurrentCost;
+
+                            if (pointsRemaining >= testCostDiff)
+                            {
+                                foundAffordable = true;
+                                break;
+                            }
+                        }
+                    }
+
+                    // If no affordable increases, break out
+                    if (!foundAffordable) break;
+                }
+            }
+
+            // Assign back to properties
+            strength = stats[0];
+            dexterity = stats[1];
+            constitution = stats[2];
+            wisdom = stats[3];
+
+            // Set as point-buy mode (not locked like true random)
+            isRandomized = false;
+            UpdateAvailablePoints();
+        }
+    }    // Alternative: Truly random stats (2-18, locked from editing)
+    public void RandomizeAttributesWild()
+    {
+        if (Application.isPlaying)
+        {
+            strength = UnityEngine.Random.Range(2, 19); // 2-18 inclusive
+            dexterity = UnityEngine.Random.Range(2, 19);
+            constitution = UnityEngine.Random.Range(2, 19);
+            wisdom = UnityEngine.Random.Range(2, 19);
+            isRandomized = true;
+            availablePoints = 0; // No points available when randomized
+        }
+    }
+
+    // Reset attributes to default for point-buy
+    public void ResetToPointBuy()
+    {
+        strength = 10;
+        dexterity = 10;
+        constitution = 10;
+        wisdom = 10;
+        isRandomized = false;
+        availablePoints = 18; // Reset to full point pool (adjusted for 4 stats)
+    }
+
+    // Calculate point cost for a stat value (point-buy system)
+    public static int GetStatCost(int statValue)
+    {
+        // Point-buy costs: 4=-4pts, 5=-2pts, 6=-1pts, 7=-1pts, 8=0pts, 9=1pt, 10=2pts, 11=3pts, 12=4pts, 13=5pts, 14=7pts, 15=9pts, 16=12pts, 17=16pts, 18=21pts
+        switch (statValue)
+        {
+            case 4: return -4;
+            case 5: return -2;
+            case 6: return -1;
+            case 7: return -1;
+            case 8: return 0;
+            case 9: return 1;
+            case 10: return 2;
+            case 11: return 3;
+            case 12: return 4;
+            case 13: return 5;
+            case 14: return 7;
+            case 15: return 9;
+            case 16: return 12;
+            case 17: return 16;
+            case 18: return 21;
+            default: return statValue < 4 ? -4 : 25; // Invalid values
+        }
+    }
+
+    // Calculate total points spent
+    public int GetTotalPointsSpent()
+    {
+        return GetStatCost(strength) + GetStatCost(dexterity) + GetStatCost(constitution) + GetStatCost(wisdom);
+    }
+
+    // Update available points based on current stats
+    public void UpdateAvailablePoints()
+    {
+        if (!isRandomized)
+        {
+            availablePoints = 18 - GetTotalPointsSpent(); // Changed from 27 to 18
+        }
+    }
+
+    // Check if we can afford to increase a stat
+    public bool CanIncreaseStat(int currentValue)
+    {
+        if (isRandomized) return false; // Can't change randomized stats
+        if (currentValue >= 18) return false; // Max value
+
+        int currentCost = GetStatCost(currentValue);
+        int newCost = GetStatCost(currentValue + 1);
+        int costDifference = newCost - currentCost;
+
+        return availablePoints >= costDifference;
+    }
+
+    // Create a deep copy of this character
+    public TeamCharacter CreateCopy()
+    {
+        var copy = new TeamCharacter(name, isMale)
+        {
+            strength = this.strength,
+            dexterity = this.dexterity,
+            constitution = this.constitution,
+            wisdom = this.wisdom,
+            isRandomized = this.isRandomized,
+            availablePoints = this.availablePoints,
+            gold = this.gold,
+            silver = this.silver,
+            copper = this.copper,
+            equippedWeapon = this.equippedWeapon,
+            equippedArmor = this.equippedArmor
+        };
+
+        // Deep copy the lists
+        copy.weapons = new System.Collections.Generic.List<string>(this.weapons);
+        copy.armor = new System.Collections.Generic.List<string>(this.armor);
+        copy.miscItems = new System.Collections.Generic.List<string>(this.miscItems);
+
+        return copy;
+    }
+
+    // Recalculate all equipment modifiers from items in inventory (temporary solution)
+    public void RecalculateEquipmentBonuses()
+    {
+        // Reset all modifiers to zero
+        strengthModifier = 0;
+        dexterityModifier = 0;
+        constitutionModifier = 0;
+        wisdomModifier = 0;
+        acModifier = 0;
+
+        // Get reference to the shop manager to access item definitions
+        var shopManager = UnityEngine.Object.FindFirstObjectByType<SimpleShopManager>();
+        if (shopManager == null) return;
+
+        // Apply bonuses from all items in inventory
+        ApplyBonusesFromItemList(shopManager.weapons, weapons);
+        ApplyBonusesFromItemList(shopManager.armor, armor);
+        ApplyBonusesFromItemList(shopManager.miscItems, miscItems);
+    }
+
+    private void ApplyBonusesFromItemList(System.Collections.Generic.List<SimpleShopItem> shopItems, System.Collections.Generic.List<string> ownedItems)
+    {
+        foreach (string itemName in ownedItems)
+        {
+            var shopItem = shopItems.Find(item => item.name == itemName);
+            if (shopItem != null && shopItem.stats != null)
+            {
+                strengthModifier += shopItem.stats.strengthBonus;
+                dexterityModifier += shopItem.stats.dexterityBonus;
+                constitutionModifier += shopItem.stats.constitutionBonus;
+                wisdomModifier += shopItem.stats.wisdomBonus;
+                acModifier += shopItem.stats.acBonus;
+            }
+        }
+    }
+
+    // Copy data from another character into this one
+    public void CopyFrom(TeamCharacter other)
+    {
+        if (other == null) return;
+
+        name = other.name;
+        isMale = other.isMale;
+        strength = other.strength;
+        dexterity = other.dexterity;
+        constitution = other.constitution;
+        wisdom = other.wisdom;
+    }
+}

+ 47 - 0
Assets/Scripts/Managers/GameInitializer.cs

@@ -0,0 +1,47 @@
+using UnityEngine;
+
+public class GameInitializer : MonoBehaviour
+{
+    [Header("Manager Prefabs")]
+    public GameObject gameStateManagerPrefab;
+    public GameObject sceneNavigationManagerPrefab;
+
+    private void Awake()
+    {
+        // Initialize core game managers if they don't exist
+        InitializeManagers();
+    }
+
+    private void InitializeManagers()
+    {
+        // Initialize GameStateManager
+        if (GameStateManager.Instance == null)
+        {
+            if (gameStateManagerPrefab != null)
+            {
+                Instantiate(gameStateManagerPrefab);
+            }
+            else
+            {
+                // Create a basic GameStateManager if no prefab is provided
+                GameObject gameStateObj = new GameObject("GameStateManager");
+                gameStateObj.AddComponent<GameStateManager>();
+            }
+        }
+
+        // Initialize SceneNavigationManager
+        if (SceneNavigationManager.Instance == null)
+        {
+            if (sceneNavigationManagerPrefab != null)
+            {
+                Instantiate(sceneNavigationManagerPrefab);
+            }
+            else
+            {
+                // Create a basic SceneNavigationManager if no prefab is provided
+                GameObject sceneNavObj = new GameObject("SceneNavigationManager");
+                sceneNavObj.AddComponent<SceneNavigationManager>();
+            }
+        }
+    }
+}

+ 388 - 0
Assets/Scripts/Managers/GameStateManager.cs

@@ -0,0 +1,388 @@
+using UnityEngine;
+using UnityEngine.SceneManagement;
+
+public class GameStateManager : MonoBehaviour
+{
+    public static GameStateManager Instance { get; private set; }
+
+    [Header("Game State")]
+    public bool hasActiveGame = false;
+    public string currentSceneName = "";
+    public int gameVersion = 1;
+
+    [Header("Team Data")]
+    public TeamCharacter[] savedTeam = new TeamCharacter[4];
+    public bool teamSetupComplete = false;
+
+    [Header("Progress Data")]
+    public int currentLevel = 1;
+    public int totalGoldEarned = 0;
+    public int battlesWon = 0;
+    public int battlesLost = 0;
+
+    [Header("Map Data")]
+    public bool hasGeneratedMap = false;
+    public int mapSeed = 0;
+    public int mapWidth = 100;
+    public int mapHeight = 100;
+    public float mapNoiseScale = 5f;
+    public float mapOceanThreshold = 0.3f;
+    public float mapMountainThreshold = 0.7f;
+    public float mapForestThreshold = 0.5f;
+
+    [Header("New Game Flags")]
+    public bool isNewGame = false; // Flag to indicate this is a new game (not a load)
+
+    private void Awake()
+    {
+        // Implement singleton pattern
+        if (Instance == null)
+        {
+            Instance = this;
+            DontDestroyOnLoad(gameObject);
+
+            // Restore new game flag from PlayerPrefs in case instance was recreated
+            isNewGame = PlayerPrefs.GetInt("IsNewGame", 0) == 1;
+            // Subscribe to scene loading events
+            SceneManager.sceneLoaded += OnSceneLoaded;
+        }
+        else
+        {
+            Destroy(gameObject);
+        }
+    }
+
+    private void OnDestroy()
+    {
+        if (Instance == this)
+        {
+            SceneManager.sceneLoaded -= OnSceneLoaded;
+        }
+    }
+
+    private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
+    {
+        currentSceneName = scene.name;
+        // Auto-save when moving between scenes (if we have an active game)
+        if (hasActiveGame && currentSceneName != "TitleScreen")
+        {
+            AutoSave();
+        }
+    }
+
+    public void StartNewGame()
+    {
+        // Reset all game state
+        hasActiveGame = true;
+        teamSetupComplete = false;
+        currentLevel = 1;
+        totalGoldEarned = 0;
+        battlesWon = 0;
+        battlesLost = 0;
+
+        // Clear team data
+        savedTeam = new TeamCharacter[4];
+
+        // Clear map data
+        hasGeneratedMap = false;
+        mapSeed = Random.Range(0, 999999);
+
+        // Set new game flag - this will force random team placement
+        isNewGame = true;
+        PlayerPrefs.SetInt("IsNewGame", 1); // Store in PlayerPrefs to persist across scenes
+        PlayerPrefs.Save(); // Force immediate save
+
+        // Clear any existing save data
+        ClearSaveData();
+
+        // Mark that we have a new game started
+        PlayerPrefs.SetInt("GameSaved", 1);
+        PlayerPrefs.Save();
+    }
+
+    public void SaveGame()
+    {
+        if (!hasActiveGame)
+        {
+            Debug.LogWarning("No active game to save!");
+            return;
+        }
+
+        // Save basic game state
+        PlayerPrefs.SetInt("GameSaved", 1);
+        PlayerPrefs.SetInt("GameVersion", gameVersion);
+        PlayerPrefs.SetString("CurrentScene", currentSceneName);
+        PlayerPrefs.SetInt("TeamSetupComplete", teamSetupComplete ? 1 : 0);
+        PlayerPrefs.SetInt("CurrentLevel", currentLevel);
+        PlayerPrefs.SetInt("TotalGoldEarned", totalGoldEarned);
+        PlayerPrefs.SetInt("BattlesWon", battlesWon);
+        PlayerPrefs.SetInt("BattlesLost", battlesLost);
+
+        // Save team data
+        SaveTeamData();
+
+        // Save map data
+        SaveMapData();
+
+        PlayerPrefs.Save();
+    }
+
+    public void LoadGame()
+    {
+        if (!PlayerPrefs.HasKey("GameSaved"))
+        {
+            Debug.LogWarning("No saved game found!");
+            return;
+        }
+
+        // Load basic game state
+        hasActiveGame = true;
+        gameVersion = PlayerPrefs.GetInt("GameVersion", 1);
+        currentSceneName = PlayerPrefs.GetString("CurrentScene", "MainTeamSelectScene");
+        teamSetupComplete = PlayerPrefs.GetInt("TeamSetupComplete", 0) == 1;
+        currentLevel = PlayerPrefs.GetInt("CurrentLevel", 1);
+        totalGoldEarned = PlayerPrefs.GetInt("TotalGoldEarned", 0);
+        battlesWon = PlayerPrefs.GetInt("BattlesWon", 0);
+        battlesLost = PlayerPrefs.GetInt("BattlesLost", 0);
+
+        // Clear new game flag - this is a load operation, use saved positions
+        isNewGame = false;
+        PlayerPrefs.SetInt("IsNewGame", 0); // Clear from PlayerPrefs too
+        PlayerPrefs.Save(); // Force immediate save
+
+
+        // Load team data
+        LoadTeamData();
+
+        // Load map data
+        LoadMapData();
+    }
+
+    public void AutoSave()
+    {
+        if (hasActiveGame)
+        {
+            SaveGame();
+        }
+    }
+
+    public void SaveTeam(TeamCharacter[] team)
+    {
+        if (team == null) return;
+
+        for (int i = 0; i < Mathf.Min(team.Length, savedTeam.Length); i++)
+        {
+            if (team[i] != null)
+            {
+                savedTeam[i] = team[i].CreateCopy();
+            }
+        }
+
+        teamSetupComplete = true;
+
+        if (hasActiveGame)
+        {
+            SaveGame();
+        }
+    }
+
+    public TeamCharacter[] GetSavedTeam()
+    {
+        return savedTeam;
+    }
+
+    private void SaveTeamData()
+    {
+        for (int i = 0; i < savedTeam.Length; i++)
+        {
+            string prefix = $"Character{i}_";
+
+            if (savedTeam[i] != null)
+            {
+                PlayerPrefs.SetInt(prefix + "Exists", 1);
+                PlayerPrefs.SetString(prefix + "Name", savedTeam[i].name);
+                PlayerPrefs.SetInt(prefix + "IsMale", savedTeam[i].isMale ? 1 : 0);
+                PlayerPrefs.SetInt(prefix + "Strength", savedTeam[i].strength);
+                PlayerPrefs.SetInt(prefix + "Dexterity", savedTeam[i].dexterity);
+                PlayerPrefs.SetInt(prefix + "Constitution", savedTeam[i].constitution);
+                PlayerPrefs.SetInt(prefix + "Wisdom", savedTeam[i].wisdom);
+                PlayerPrefs.SetInt(prefix + "Gold", savedTeam[i].gold);
+                PlayerPrefs.SetInt(prefix + "Silver", savedTeam[i].silver);
+                PlayerPrefs.SetInt(prefix + "Copper", savedTeam[i].copper);
+                PlayerPrefs.SetString(prefix + "EquippedWeapon", savedTeam[i].equippedWeapon);
+                PlayerPrefs.SetString(prefix + "EquippedArmor", savedTeam[i].equippedArmor);
+
+                // Save inventory lists as comma-separated strings
+                PlayerPrefs.SetString(prefix + "Weapons", string.Join(",", savedTeam[i].weapons));
+                PlayerPrefs.SetString(prefix + "Armor", string.Join(",", savedTeam[i].armor));
+                PlayerPrefs.SetString(prefix + "MiscItems", string.Join(",", savedTeam[i].miscItems));
+            }
+            else
+            {
+                PlayerPrefs.SetInt(prefix + "Exists", 0);
+            }
+        }
+    }
+
+    private void LoadTeamData()
+    {
+        savedTeam = new TeamCharacter[4];
+
+        for (int i = 0; i < savedTeam.Length; i++)
+        {
+            string prefix = $"Character{i}_";
+
+            if (PlayerPrefs.GetInt(prefix + "Exists", 0) == 1)
+            {
+                savedTeam[i] = new TeamCharacter();
+                savedTeam[i].name = PlayerPrefs.GetString(prefix + "Name", "");
+                savedTeam[i].isMale = PlayerPrefs.GetInt(prefix + "IsMale", 1) == 1;
+                savedTeam[i].strength = PlayerPrefs.GetInt(prefix + "Strength", 10);
+                savedTeam[i].dexterity = PlayerPrefs.GetInt(prefix + "Dexterity", 10);
+                savedTeam[i].constitution = PlayerPrefs.GetInt(prefix + "Constitution", 10);
+                savedTeam[i].wisdom = PlayerPrefs.GetInt(prefix + "Wisdom", 10);
+                savedTeam[i].gold = PlayerPrefs.GetInt(prefix + "Gold", 25);
+                savedTeam[i].silver = PlayerPrefs.GetInt(prefix + "Silver", 0);
+                savedTeam[i].copper = PlayerPrefs.GetInt(prefix + "Copper", 0);
+                savedTeam[i].equippedWeapon = PlayerPrefs.GetString(prefix + "EquippedWeapon", "");
+                savedTeam[i].equippedArmor = PlayerPrefs.GetString(prefix + "EquippedArmor", "");
+
+                // Load inventory lists
+                string weaponsStr = PlayerPrefs.GetString(prefix + "Weapons", "");
+                string armorStr = PlayerPrefs.GetString(prefix + "Armor", "");
+                string miscStr = PlayerPrefs.GetString(prefix + "MiscItems", "");
+
+                savedTeam[i].weapons = new System.Collections.Generic.List<string>();
+                savedTeam[i].armor = new System.Collections.Generic.List<string>();
+                savedTeam[i].miscItems = new System.Collections.Generic.List<string>();
+
+                if (!string.IsNullOrEmpty(weaponsStr))
+                    savedTeam[i].weapons.AddRange(weaponsStr.Split(','));
+                if (!string.IsNullOrEmpty(armorStr))
+                    savedTeam[i].armor.AddRange(armorStr.Split(','));
+                if (!string.IsNullOrEmpty(miscStr))
+                    savedTeam[i].miscItems.AddRange(miscStr.Split(','));
+            }
+        }
+    }
+
+    private void ClearSaveData()
+    {
+        // Clear main save indicators
+        PlayerPrefs.DeleteKey("GameSaved");
+        PlayerPrefs.DeleteKey("GameVersion");
+        PlayerPrefs.DeleteKey("CurrentScene");
+        PlayerPrefs.DeleteKey("TeamSetupComplete");
+        PlayerPrefs.DeleteKey("CurrentLevel");
+        PlayerPrefs.DeleteKey("TotalGoldEarned");
+        PlayerPrefs.DeleteKey("BattlesWon");
+        PlayerPrefs.DeleteKey("BattlesLost");
+
+        // Note: We DON'T clear "IsNewGame" here because it should persist until team placement is done
+
+        // Clear team data
+        for (int i = 0; i < 4; i++)
+        {
+            string prefix = $"Character{i}_";
+            PlayerPrefs.DeleteKey(prefix + "Exists");
+            PlayerPrefs.DeleteKey(prefix + "Name");
+            PlayerPrefs.DeleteKey(prefix + "IsMale");
+            PlayerPrefs.DeleteKey(prefix + "Strength");
+            PlayerPrefs.DeleteKey(prefix + "Dexterity");
+            PlayerPrefs.DeleteKey(prefix + "Constitution");
+            PlayerPrefs.DeleteKey(prefix + "Wisdom");
+            PlayerPrefs.DeleteKey(prefix + "Gold");
+            PlayerPrefs.DeleteKey(prefix + "Silver");
+            PlayerPrefs.DeleteKey(prefix + "Copper");
+            PlayerPrefs.DeleteKey(prefix + "EquippedWeapon");
+            PlayerPrefs.DeleteKey(prefix + "EquippedArmor");
+            PlayerPrefs.DeleteKey(prefix + "Weapons");
+            PlayerPrefs.DeleteKey(prefix + "Armor");
+            PlayerPrefs.DeleteKey(prefix + "MiscItems");
+        }
+
+        // Clear map data
+        PlayerPrefs.DeleteKey("MapSeed");
+        PlayerPrefs.DeleteKey("MapWidth");
+        PlayerPrefs.DeleteKey("MapHeight");
+        PlayerPrefs.DeleteKey("MapNoiseScale");
+        PlayerPrefs.DeleteKey("MapOceanThreshold");
+        PlayerPrefs.DeleteKey("MapMountainThreshold");
+        PlayerPrefs.DeleteKey("MapForestThreshold");
+        PlayerPrefs.DeleteKey("HasGeneratedMap");
+
+        PlayerPrefs.Save();
+    }
+
+    // Method to check if we're currently in a game
+    public bool IsInGame()
+    {
+        return hasActiveGame && currentSceneName != "TitleScreen";
+    }
+
+    // Method to return to title screen
+    public void ReturnToTitle()
+    {
+        SceneManager.LoadScene("TitleScreen");
+    }
+
+    private void SaveMapData()
+    {
+        PlayerPrefs.SetInt("MapSeed", mapSeed);
+        PlayerPrefs.SetInt("MapWidth", mapWidth);
+        PlayerPrefs.SetInt("MapHeight", mapHeight);
+        PlayerPrefs.SetFloat("MapNoiseScale", mapNoiseScale);
+        PlayerPrefs.SetFloat("MapOceanThreshold", mapOceanThreshold);
+        PlayerPrefs.SetFloat("MapMountainThreshold", mapMountainThreshold);
+        PlayerPrefs.SetFloat("MapForestThreshold", mapForestThreshold);
+        PlayerPrefs.SetInt("HasGeneratedMap", hasGeneratedMap ? 1 : 0);
+    }
+
+    private void LoadMapData()
+    {
+        mapSeed = PlayerPrefs.GetInt("MapSeed", Random.Range(0, 999999));
+        mapWidth = PlayerPrefs.GetInt("MapWidth", 100);
+        mapHeight = PlayerPrefs.GetInt("MapHeight", 100);
+        mapNoiseScale = PlayerPrefs.GetFloat("MapNoiseScale", 5f);
+        mapOceanThreshold = PlayerPrefs.GetFloat("MapOceanThreshold", 0.3f);
+        mapMountainThreshold = PlayerPrefs.GetFloat("MapMountainThreshold", 0.7f);
+        mapForestThreshold = PlayerPrefs.GetFloat("MapForestThreshold", 0.5f);
+        hasGeneratedMap = PlayerPrefs.GetInt("HasGeneratedMap", 0) == 1;
+    }
+
+    public void GenerateNewMap()
+    {
+        mapSeed = Random.Range(0, 999999);
+        hasGeneratedMap = true;
+        SaveMapData();
+    }
+
+    public bool HasSavedMap()
+    {
+        return PlayerPrefs.HasKey("MapSeed");
+    }
+
+    /// <summary>
+    /// Check if this is a new game that should force random team placement
+    /// </summary>
+    public bool IsNewGameForceRandom()
+    {
+        // Check both the instance variable and PlayerPrefs in case of timing issues
+        bool instanceFlag = isNewGame;
+        bool playerPrefsFlag = PlayerPrefs.GetInt("IsNewGame", 0) == 1;
+
+        bool result = instanceFlag || playerPrefsFlag;
+
+        return result;
+    }
+
+    /// <summary>
+    /// Clear the new game flag after initial team placement is complete
+    /// </summary>
+    public void ClearNewGameFlag()
+    {
+        isNewGame = false;
+        PlayerPrefs.SetInt("IsNewGame", 0); // Clear from PlayerPrefs too
+        PlayerPrefs.Save();
+    }
+}

+ 0 - 0
Assets/Scripts/Managers/MapSceneManager.cs


+ 173 - 0
Assets/Scripts/Managers/SceneNavigationManager.cs

@@ -0,0 +1,173 @@
+using UnityEngine;
+using UnityEngine.SceneManagement;
+using System.Collections;
+
+public class SceneNavigationManager : MonoBehaviour
+{
+    public static SceneNavigationManager Instance { get; private set; }
+
+    [Header("Scene Transition")]
+    public bool useLoadingScreen = false;
+    public float minimumLoadingTime = 1f;
+
+    // Scene name constants for easy reference
+    public const string TITLE_SCENE = "TitleScreen";
+    public const string TEAM_SELECT_SCENE = "MainTeamSelectScene";
+    public const string BATTLE_SETUP_SCENE = "BattleSetupMenu";
+    public const string BATTLE_SCENE = "BattleScene";
+    public const string MAP_SCENE = "MapScene";
+
+    private void Awake()
+    {
+        if (Instance == null)
+        {
+            Instance = this;
+            DontDestroyOnLoad(gameObject);
+        }
+        else
+        {
+            Destroy(gameObject);
+        }
+    }
+
+    #region Public Scene Navigation Methods
+
+    public void GoToTitleScreen()
+    {
+        LoadScene(TITLE_SCENE);
+    }
+
+    public void GoToTeamSelect()
+    {
+        LoadScene(TEAM_SELECT_SCENE);
+    }
+
+    public void GoToBattleSetup()
+    {
+        LoadScene(BATTLE_SETUP_SCENE);
+    }
+
+    public void GoToBattle()
+    {
+        LoadScene(BATTLE_SCENE);
+    }
+
+    public void GoToMapScene()
+    {
+        LoadScene(MAP_SCENE);
+    }
+
+    #endregion
+
+    #region Core Scene Loading
+
+    public void LoadScene(string sceneName)
+    {
+        if (string.IsNullOrEmpty(sceneName))
+        {
+            Debug.LogError("Scene name is null or empty!");
+            return;
+        }
+
+
+
+        if (useLoadingScreen)
+        {
+            StartCoroutine(LoadSceneWithLoadingScreen(sceneName));
+        }
+        else
+        {
+            SceneManager.LoadScene(sceneName);
+        }
+    }
+
+    public void LoadSceneAsync(string sceneName, System.Action onComplete = null)
+    {
+        StartCoroutine(LoadSceneAsyncCoroutine(sceneName, onComplete));
+    }
+
+    private IEnumerator LoadSceneWithLoadingScreen(string sceneName)
+    {
+        // TODO: Show loading screen UI here
+        yield return new WaitForSeconds(0.1f); // Brief delay to show loading screen
+
+        float startTime = Time.time;
+
+        // Start loading the scene asynchronously
+        AsyncOperation asyncLoad = SceneManager.LoadSceneAsync(sceneName);
+        asyncLoad.allowSceneActivation = false;
+
+        // Wait for the scene to be ready or minimum loading time
+        while (!asyncLoad.isDone)
+        {
+            float progress = Mathf.Clamp01(asyncLoad.progress / 0.9f);
+
+            // TODO: Update loading screen progress here
+
+
+            // If loading is done and minimum time has passed, activate the scene
+            if (asyncLoad.progress >= 0.9f && (Time.time - startTime) >= minimumLoadingTime)
+            {
+                asyncLoad.allowSceneActivation = true;
+            }
+
+            yield return null;
+        }
+
+        // TODO: Hide loading screen UI here
+    }
+
+    private IEnumerator LoadSceneAsyncCoroutine(string sceneName, System.Action onComplete)
+    {
+        AsyncOperation asyncLoad = SceneManager.LoadSceneAsync(sceneName);
+
+        while (!asyncLoad.isDone)
+        {
+            yield return null;
+        }
+
+        onComplete?.Invoke();
+    }
+
+    #endregion
+
+    #region Scene Validation
+
+    public bool IsSceneInBuildSettings(string sceneName)
+    {
+        for (int i = 0; i < SceneManager.sceneCountInBuildSettings; i++)
+        {
+            string scenePath = SceneUtility.GetScenePathByBuildIndex(i);
+            string sceneNameFromPath = System.IO.Path.GetFileNameWithoutExtension(scenePath);
+
+            if (sceneNameFromPath.Equals(sceneName, System.StringComparison.OrdinalIgnoreCase))
+            {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public string GetCurrentSceneName()
+    {
+        return SceneManager.GetActiveScene().name;
+    }
+
+    #endregion
+
+    #region Development/Debug Methods
+
+    [System.Diagnostics.Conditional("UNITY_EDITOR")]
+    public void LogAllScenesInBuild()
+    {
+
+        for (int i = 0; i < SceneManager.sceneCountInBuildSettings; i++)
+        {
+            string scenePath = SceneUtility.GetScenePathByBuildIndex(i);
+            string sceneName = System.IO.Path.GetFileNameWithoutExtension(scenePath);
+
+        }
+    }
+
+    #endregion
+}

+ 0 - 0
Assets/Scripts/Map/MapDebugHelper.cs


+ 0 - 0
Assets/Scripts/Map/MapSystemTransition.cs


+ 0 - 0
Assets/Scripts/Map/NewTeamLocationManager.cs


+ 655 - 0
Assets/Scripts/Map/SimpleTeamPlacement.cs

@@ -0,0 +1,655 @@
+using UnityEngine;
+using System.Collections;
+using System.Collections.Generic;
+
+/// <summary>
+/// Simple standalone team placement script that randomly places the team on a settlement
+/// and creates a visible marker in front of the map.
+/// </summary>
+public class SimpleTeamPlacement : MonoBehaviour
+{
+    [Header("Team Marker Settings")]
+    public GameObject teamMarkerPrefab;
+    public Material teamMarkerMaterial;
+    [Range(0.5f, 3f)]
+    public float markerSize = 1.5f;
+    [Range(-5f, 5f)]
+    public float markerZOffset = -2f; // Negative to place in front of map
+    public Color markerColor = Color.green;
+
+    [Header("Animation Settings")]
+    public bool enableBlinking = true;
+    [Range(0.1f, 2f)]
+    public float blinkSpeed = 0.5f;
+
+    // Private variables
+    private GameObject teamMarkerInstance;
+    private Vector2Int currentTeamPosition;
+    private bool isTeamPositionSet = false;
+    private bool isBlinking = false;
+    private MapMaker2 mapMaker;
+
+    public static SimpleTeamPlacement Instance { get; private set; }
+
+    void Awake()
+    {
+        if (Instance == null)
+        {
+            Instance = this;
+        }
+        else
+        {
+            Debug.LogWarning("Multiple SimpleTeamPlacement instances found. Destroying this one.");
+            Destroy(gameObject);
+            return;
+        }
+    }
+
+    void Start()
+    {
+        // Find MapMaker2
+        mapMaker = FindFirstObjectByType<MapMaker2>();
+
+        if (mapMaker == null)
+        {
+            return;
+        }
+
+        // Wait a bit for map generation, then place team
+        StartCoroutine(WaitAndPlaceTeam());
+    }
+
+    void Update()
+    {
+        // Debug keys
+        if (Input.GetKeyDown(KeyCode.R))
+        {
+            RandomlyPlaceTeam();
+        }
+
+        if (Input.GetKeyDown(KeyCode.M))
+        {
+            ShowMarkerInfo();
+        }
+
+        // Debug key to check saved positions
+        if (Input.GetKeyDown(KeyCode.P))
+        {
+            DebugSavedPositions();
+        }
+
+        // Travel system integration - allow clicking on map to plan travel
+        if (Input.GetKeyDown(KeyCode.T))
+        {
+            ShowTravelInfo();
+        }
+    }
+
+    private IEnumerator WaitAndPlaceTeam()
+    {
+        // Wait for map generation
+        yield return new WaitForSeconds(1.5f);
+
+        // Check if this is a new game that should force random placement
+        // First ensure GameStateManager exists, create it if needed
+        if (GameStateManager.Instance == null)
+        {
+            GameObject gameStateObj = new GameObject("GameStateManager");
+            gameStateObj.AddComponent<GameStateManager>();
+            // Wait a frame for the GameStateManager to initialize
+            yield return null;
+        }
+
+        bool isNewGame = GameStateManager.Instance?.IsNewGameForceRandom() ?? false;
+
+        // ALWAYS show new game detection debug logs (even if showDebugLogs is false)
+
+        if (isNewGame)
+        {
+            RandomlyPlaceTeam();
+
+            // Clear the new game flag after placement
+            GameStateManager.Instance?.ClearNewGameFlag();
+            yield break;
+        }
+
+        // Try multiple times to load saved position (in case MapMaker2 isn't ready yet)
+        int attempts = 0;
+        const int maxAttempts = 5;
+
+        while (attempts < maxAttempts)
+        {
+            attempts++;
+
+            // Try to load saved position first
+            if (TryLoadSavedPosition())
+            {
+                yield break; // Exit successfully
+            }
+
+            // If failed and MapMaker seed is still 0, wait a bit more
+            if (mapMaker?.seed == 0 && attempts < maxAttempts)
+            {
+                yield return new WaitForSeconds(0.5f);
+            }
+            else
+            {
+                break; // Either loaded successfully or MapMaker is ready but no saved position
+            }
+        }
+
+        // No saved position or invalid, place randomly
+        RandomlyPlaceTeam();
+    }
+
+    private bool TryLoadSavedPosition()
+    {
+        // Get the current map seed to make position specific to this map
+        int currentSeed = mapMaker?.seed ?? 0;
+        string positionKey = $"TeamPosition_{currentSeed}";
+
+
+        if (currentSeed == 0)
+        {
+            return false;
+        }
+
+        if (!PlayerPrefs.HasKey($"{positionKey}_X") || !PlayerPrefs.HasKey($"{positionKey}_Y"))
+        {
+            return false;
+        }
+
+        Vector2Int savedPosition = new Vector2Int(
+            PlayerPrefs.GetInt($"{positionKey}_X"),
+            PlayerPrefs.GetInt($"{positionKey}_Y")
+        );
+
+
+        // Verify position is still valid (any valid map position, not just settlements)
+        if (IsValidMapPosition(savedPosition))
+        {
+            PlaceTeamAt(savedPosition);
+            return true;
+        }
+
+        return false;
+    }
+
+    public void RandomlyPlaceTeam()
+    {
+        if (mapMaker?.GetMapData() == null)
+        {
+            return;
+        }
+
+        // For new games, ensure we're using the current random state for truly random placement
+        bool isNewGame = GameStateManager.Instance?.IsNewGameForceRandom() ?? false;
+
+        var mapData = mapMaker.GetMapData();
+        var allSettlements = new List<Settlement>();
+
+        // Combine towns and villages into one list for random selection
+        allSettlements.AddRange(mapData.GetTowns());
+        allSettlements.AddRange(mapData.GetVillages());
+
+        if (allSettlements.Count == 0)
+        {
+            return;
+        }
+
+        // Randomly select a settlement
+        int randomIndex = Random.Range(0, allSettlements.Count);
+        Settlement selectedSettlement = allSettlements[randomIndex];
+
+        PlaceTeamAt(selectedSettlement.position);
+    }
+
+    public void PlaceTeamAt(Vector2Int position)
+    {
+        currentTeamPosition = position;
+        isTeamPositionSet = true;
+
+        // Save position with map seed for persistence
+        int currentSeed = mapMaker?.seed ?? 0;
+        string positionKey = $"TeamPosition_{currentSeed}";
+        bool isNewGame = GameStateManager.Instance?.IsNewGameForceRandom() ?? false;
+
+
+        PlayerPrefs.SetInt($"{positionKey}_X", position.x);
+        PlayerPrefs.SetInt($"{positionKey}_Y", position.y);
+        PlayerPrefs.Save();
+
+        // Create/update visual marker
+        CreateTeamMarker();
+
+        // Notify MapMaker2 of position change for event-driven exploration
+        if (mapMaker != null)
+        {
+            mapMaker.OnTeamPositionChanged(position);
+        }
+
+    }
+
+    /// <summary>
+    /// Cleans up position data for old map seeds (optional maintenance)
+    /// </summary>
+    public void CleanupOldPositionData()
+    {
+        int currentSeed = mapMaker?.seed ?? 0;
+        int cleanedCount = 0;
+
+        // This is a simple cleanup - in a real game you might want more sophisticated management
+        for (int i = 0; i < 10; i++) // Check last 10 potential seeds for cleanup
+        {
+            int testSeed = currentSeed - i;
+            if (testSeed != currentSeed && testSeed > 0)
+            {
+                string positionKey = $"TeamPosition_{testSeed}";
+                if (PlayerPrefs.HasKey($"{positionKey}_X"))
+                {
+                    PlayerPrefs.DeleteKey($"{positionKey}_X");
+                    PlayerPrefs.DeleteKey($"{positionKey}_Y");
+                    cleanedCount++;
+                }
+            }
+        }
+    }
+
+    /// <summary>
+    /// Debug method to check what positions are saved in PlayerPrefs
+    /// </summary>
+    private void DebugSavedPositions()
+    {
+        int currentSeed = mapMaker?.seed ?? 0;
+
+
+
+
+        // Check current seed position
+        string currentKey = $"TeamPosition_{currentSeed}";
+        bool hasCurrentPosition = PlayerPrefs.HasKey($"{currentKey}_X") && PlayerPrefs.HasKey($"{currentKey}_Y");
+
+        if (hasCurrentPosition)
+        {
+            Vector2Int currentPos = new Vector2Int(
+                PlayerPrefs.GetInt($"{currentKey}_X"),
+                PlayerPrefs.GetInt($"{currentKey}_Y")
+            );
+
+        }
+        else
+        {
+
+        }
+
+        // Check for other potential seeds (common ones)
+        int[] testSeeds = { 0, 12345, 1000, 5000, 9999 };
+        foreach (int testSeed in testSeeds)
+        {
+            if (testSeed == currentSeed) continue; // Already checked
+
+            string testKey = $"TeamPosition_{testSeed}";
+            if (PlayerPrefs.HasKey($"{testKey}_X") && PlayerPrefs.HasKey($"{testKey}_Y"))
+            {
+                Vector2Int testPos = new Vector2Int(
+                    PlayerPrefs.GetInt($"{testKey}_X"),
+                    PlayerPrefs.GetInt($"{testKey}_Y")
+                );
+
+            }
+        }
+
+
+
+
+    }
+
+    private void CreateTeamMarker()
+    {
+        // Stop any existing blinking first
+        if (isBlinking)
+        {
+            StopAllCoroutines(); // This will stop the BlinkMarker coroutine
+            isBlinking = false;
+        }
+
+        // Remove existing marker
+        if (teamMarkerInstance != null)
+        {
+            DestroyImmediate(teamMarkerInstance);
+        }
+
+        // Create new marker
+        if (teamMarkerPrefab != null)
+        {
+            teamMarkerInstance = Instantiate(teamMarkerPrefab);
+        }
+        else
+        {
+            // Create simple sphere marker
+            teamMarkerInstance = GameObject.CreatePrimitive(PrimitiveType.Sphere);
+            teamMarkerInstance.transform.localScale = Vector3.one * markerSize;
+            teamMarkerInstance.tag = "Player";
+        }
+
+        // Position marker
+        PositionMarker();
+
+        // Apply material/color
+        ApplyMarkerMaterial();
+
+        // Set name
+        teamMarkerInstance.name = "TeamMarker";
+
+        // Start blinking if enabled
+        if (enableBlinking)
+        {
+            StartBlinking();
+        }
+
+    }
+
+    /// <summary>
+    /// Get current team position
+    /// </summary>
+    public Vector2Int GetCurrentTeamPosition()
+    {
+        return currentTeamPosition;
+    }
+
+    /// <summary>
+    /// Update team marker position when map coordinates change (called by exploration system)
+    /// </summary>
+    public void UpdateMarkerAfterMapChange(Vector2Int newVisiblePosition)
+    {
+        if (!isTeamPositionSet || teamMarkerInstance == null)
+        {
+            return;
+        }
+
+        // Store the world position before updating coordinates
+        Vector3 currentWorldPos = teamMarkerInstance.transform.position;
+
+        // Update the current team position to the new visible coordinates
+        Vector2Int oldPosition = currentTeamPosition;
+        currentTeamPosition = newVisiblePosition;
+
+        // Reposition the marker to maintain world position consistency
+        PositionMarker();
+
+    }
+
+    private void PositionMarker()
+    {
+        // Get tile size from MapVisualizer
+        float tileSize = 1f;
+        if (mapMaker?.mapVisualizer != null)
+        {
+            tileSize = mapMaker.mapVisualizer.tileSize;
+        }
+
+        // Calculate world position: 
+        // In exploration mode, we need to convert exploration coordinates to full map coordinates for world positioning
+        Vector2Int worldCoordinates = currentTeamPosition;
+
+        // Check if we're using exploration system
+        if (mapMaker != null && mapMaker.useExplorationSystem)
+        {
+            var explorationManager = mapMaker.GetExplorationManager();
+            if (explorationManager != null)
+            {
+                // Use exploration manager to convert coordinates properly
+                Vector3 correctWorldPos = explorationManager.ConvertExplorationToWorldCoordinates(currentTeamPosition);
+                teamMarkerInstance.transform.position = new Vector3(
+                    correctWorldPos.x,
+                    correctWorldPos.y,
+                    markerZOffset
+                );
+
+                return;
+            }
+        }
+
+        // Fallback for non-exploration mode: use direct coordinate mapping
+        Vector3 worldPosition = new Vector3(
+            worldCoordinates.x * tileSize,
+            worldCoordinates.y * tileSize,
+            markerZOffset // Use configurable Z offset to place in front of map
+        );
+
+        teamMarkerInstance.transform.position = worldPosition;
+
+    }
+
+    private void ApplyMarkerMaterial()
+    {
+        Renderer renderer = teamMarkerInstance.GetComponent<Renderer>();
+        if (renderer == null) return;
+
+        if (teamMarkerMaterial != null)
+        {
+            renderer.material = teamMarkerMaterial;
+        }
+        else
+        {
+            // Create simple colored material using URP shaders first
+            Shader shader = null;
+
+            // Try URP shaders first
+            shader = Shader.Find("Universal Render Pipeline/Lit");
+            if (shader == null)
+                shader = Shader.Find("Universal Render Pipeline/Simple Lit");
+            if (shader == null)
+                shader = Shader.Find("Universal Render Pipeline/Unlit");
+
+            // Fallback to built-in shaders
+            if (shader == null)
+                shader = Shader.Find("Standard");
+            if (shader == null)
+                shader = Shader.Find("Legacy Shaders/Diffuse");
+            if (shader == null)
+                shader = Shader.Find("Unlit/Color");
+
+            // Last resort fallback
+            if (shader == null)
+            {
+                return;
+            }
+
+            Material material = new Material(shader);
+
+            // Set base color (works for both URP and built-in)
+            if (material.HasProperty("_BaseColor"))
+            {
+                material.SetColor("_BaseColor", markerColor); // URP property
+            }
+            else if (material.HasProperty("_Color"))
+            {
+                material.SetColor("_Color", markerColor); // Built-in property
+            }
+
+            material.color = markerColor; // Fallback
+
+            // Add emission for better visibility
+            if (material.HasProperty("_EmissionColor"))
+            {
+                material.EnableKeyword("_EMISSION");
+                material.SetColor("_EmissionColor", markerColor * 0.3f);
+            }
+
+            renderer.material = material;
+        }
+    }
+
+    private void StartBlinking()
+    {
+        if (!isBlinking)
+        {
+            StartCoroutine(BlinkMarker());
+        }
+        else
+        {
+            // Force restart blinking as a fallback
+            StopAllCoroutines();
+            isBlinking = false;
+            StartCoroutine(BlinkMarker());
+        }
+    }
+
+    private IEnumerator BlinkMarker()
+    {
+        isBlinking = true;
+        Renderer markerRenderer = teamMarkerInstance?.GetComponent<Renderer>();
+
+        if (markerRenderer == null)
+        {
+            isBlinking = false;
+            yield break;
+        }
+
+        // Capture the enableBlinking state at start to avoid timing issues
+        bool shouldBlink = enableBlinking;
+
+        int blinkCount = 0;
+        while (teamMarkerInstance != null && markerRenderer != null && shouldBlink)
+        {
+            // Hide marker
+            markerRenderer.enabled = false;
+            yield return new WaitForSeconds(blinkSpeed);
+
+            // Show marker
+            if (markerRenderer != null && teamMarkerInstance != null)
+            {
+                markerRenderer.enabled = true;
+                yield return new WaitForSeconds(blinkSpeed);
+                blinkCount++;
+            }
+            else
+            {
+                break;
+            }
+
+            // Re-check enableBlinking periodically (every 10 blinks) in case user changes it
+            if (blinkCount % 10 == 0)
+            {
+                shouldBlink = enableBlinking;
+            }
+        }
+
+        isBlinking = false;
+    }
+
+    private bool IsValidSettlementPosition(Vector2Int position)
+    {
+        if (mapMaker?.GetMapData() == null) return false;
+
+        var mapData = mapMaker.GetMapData();
+        if (!mapData.IsValidPosition(position.x, position.y)) return false;
+
+        // Check if position has a settlement
+        foreach (var town in mapData.GetTowns())
+        {
+            if (town.position == position) return true;
+        }
+
+        foreach (var village in mapData.GetVillages())
+        {
+            if (village.position == position) return true;
+        }
+
+        return false;
+    }
+
+    /// <summary>
+    /// Checks if a position is valid for team placement (any valid map position)
+    /// Used for persistent positioning - team can be anywhere on the map
+    /// </summary>
+    private bool IsValidMapPosition(Vector2Int position)
+    {
+        if (mapMaker?.GetMapData() == null)
+        {
+            return false;
+        }
+
+        var mapData = mapMaker.GetMapData();
+        return mapData.IsValidPosition(position.x, position.y);
+    }
+
+    private void ShowMarkerInfo()
+    {
+        if (teamMarkerInstance == null)
+        {
+
+            return;
+        }
+
+
+
+
+
+
+
+
+
+    }
+
+    private void ShowTravelInfo()
+    {
+
+
+
+
+        var travelSystem = TeamTravelSystem.Instance;
+        if (travelSystem != null)
+        {
+
+
+
+
+        }
+        else
+        {
+
+        }
+
+
+
+
+
+
+
+
+    }
+
+    // Public methods for external control
+    public Vector2Int GetTeamPosition() => currentTeamPosition;
+    public bool IsTeamPlaced() => isTeamPositionSet;
+    public GameObject GetTeamMarker() => teamMarkerInstance;
+
+    [ContextMenu("Randomly Place Team")]
+    public void ContextRandomlyPlaceTeam()
+    {
+        RandomlyPlaceTeam();
+    }
+
+    [ContextMenu("Show Marker Info")]
+    public void ContextShowMarkerInfo()
+    {
+        ShowMarkerInfo();
+    }
+
+    [ContextMenu("Force New Game Random Placement")]
+    public void ContextForceNewGamePlacement()
+    {
+        // Temporarily set new game flag for testing
+        if (GameStateManager.Instance != null)
+        {
+            GameStateManager.Instance.isNewGame = true;
+        }
+
+        RandomlyPlaceTeam();
+
+        // Clear the flag after testing
+        GameStateManager.Instance?.ClearNewGameFlag();
+    }
+}

+ 0 - 0
Assets/Scripts/Map/TeamLocationManager.cs


+ 2010 - 0
Assets/Scripts/Map/TeamTravelSystem.cs

@@ -0,0 +1,2010 @@
+using UnityEngine;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+
+/// <summary>
+/// New comprehensive travel system that handles movement costs, pathfinding, and visual planning.
+/// Integrates with SimpleTeamPlacement and MapMaker2 for seamless map-based travel.
+/// </summary>
+public class TeamTravelSystem : MonoBehaviour
+{
+    [Header("Movement Costs")]
+    [Range(0.1f, 5f)]
+    public float plainsMovementCost = 1f;
+    [Range(0.1f, 5f)]
+    public float forestMovementCost = 2f;
+    [Range(0.1f, 5f)]
+    public float mountainMovementCost = 4f;
+    [Range(0.1f, 2f)]
+    public float roadMovementCost = 0.5f;
+    [Range(0.1f, 2f)]
+    public float townMovementCost = 0.1f; // Almost instant travel inside towns
+    [Range(0.1f, 2f)]
+    public float bridgeMovementCost = 0.6f;
+
+    [Header("Special Travel Costs")]
+    [Range(1, 100)]
+    public int ferryBaseCost = 25; // Gold cost for ferry
+    [Range(0.1f, 2f)]
+    public float ferryMovementCost = 0.7f; // Faster than walking but costs money
+    [Range(1, 50)]
+    public int tunnelTorchCost = 10; // Torch cost for tunnel travel
+    [Range(0.1f, 2f)]
+    public float tunnelWithTorchCost = 0.8f; // Fast with torch
+    [Range(1f, 5f)]
+    public float tunnelWithoutTorchCost = 3f; // Slow and dangerous without torch
+    [Range(1, 20)]
+    public int bridgeTollCost = 5; // Gold cost for major bridge crossings
+    [Range(1, 30)]
+    public int mountainPassCost = 15; // Guide cost for dangerous mountain passes
+
+    [Header("River Crossing")]
+    [Range(2f, 10f)]
+    public float riverCrossingCost = 2f; // Reduced from 6f - more reasonable river crossing
+    [Range(1f, 8f)]
+    public float lakeCrossingCost = 2.5f; // Reduced from 4f - more reasonable lake crossing
+    [Range(5f, 15f)]
+    public float oceanCrossingCost = 8f; // Reduced from 10f but still expensive
+
+    [Header("Visual Path Settings")]
+    public Material pathLineMaterial;
+    public Color standardPathColor = Color.blue;
+    public Color expensivePathColor = Color.red;
+    public Color alternativePathColor = Color.yellow;
+    [Range(0.1f, 5f)]
+    public float pathLineWidth = 2.5f; // Increased for much better visibility
+    [Range(-10f, 10f)]
+    public float pathLineZOffset = -2f; // Moved further forward to appear above roads
+
+    [Header("Debug")]
+    public bool showDebugLogs = false;
+    public bool showMovementCosts = false;
+
+    // References
+    private SimpleTeamPlacement teamPlacement;
+    private MapMaker2 mapMaker;
+    private Camera mapCamera;
+    private TravelUI travelUI;
+
+    // Travel state
+    private Vector2Int? plannedDestination;
+    private List<TravelRoute> availableRoutes = new List<TravelRoute>();
+    private List<GameObject> currentPathVisualizations = new List<GameObject>(); // Store multiple route lines
+    private bool isTraveling = false;
+    private int currentRouteIndex = 0; // For cycling through route visualizations
+
+    // Journey cancellation
+    private bool shouldCancelJourney = false;
+    private Coroutine currentTravelCoroutine = null;
+    private TravelRoute currentRoute = null;
+
+    // Time skip functionality
+    [Header("Time Controls")]
+    public float timeMultiplier = 1f; // Current time speed multiplier
+    public float[] timeSpeedOptions = { 1f, 2f, 4f, 8f }; // Available speed options
+    private int currentTimeSpeedIndex = 0;
+
+    // Static instance
+    public static TeamTravelSystem Instance { get; private set; }
+
+    void Awake()
+    {
+        if (Instance == null)
+        {
+            Instance = this;
+        }
+        else
+        {
+            Debug.LogWarning("Multiple TeamTravelSystem instances found. Destroying this one.");
+            Destroy(gameObject);
+            return;
+        }
+    }
+
+    void Start()
+    {
+        // Find required components
+        teamPlacement = FindFirstObjectByType<SimpleTeamPlacement>();
+        mapMaker = FindFirstObjectByType<MapMaker2>();
+        mapCamera = Camera.main;
+        travelUI = FindFirstObjectByType<TravelUI>();
+
+        // Initialize pathLineMaterial if not assigned
+        if (pathLineMaterial == null)
+        {
+            pathLineMaterial = CreateDefaultPathMaterial();
+        }
+
+        if (teamPlacement == null)
+        {
+            Debug.LogError("SimpleTeamPlacement not found! TeamTravelSystem requires it.");
+        }
+
+        if (mapMaker == null)
+        {
+            Debug.LogError("MapMaker2 not found! TeamTravelSystem requires it.");
+        }
+
+        if (travelUI == null)
+        {
+            Debug.LogWarning("TravelUI not found! UI features will be limited.");
+        }
+    }
+
+    void Update()
+    {
+        HandleInput();
+    }
+
+    private void HandleInput()
+    {
+        // Time speed controls (available during travel)
+        if (isTraveling)
+        {
+            if (Input.GetKeyDown(KeyCode.Period) || Input.GetKeyDown(KeyCode.RightArrow)) // > key or right arrow
+            {
+                IncreaseTimeSpeed();
+            }
+            else if (Input.GetKeyDown(KeyCode.Comma) || Input.GetKeyDown(KeyCode.LeftArrow)) // < key or left arrow
+            {
+                DecreaseTimeSpeed();
+            }
+            else if (Input.GetKeyDown(KeyCode.Space)) // Space to reset speed
+            {
+                ResetTimeSpeed();
+            }
+            else if (Input.GetKeyDown(KeyCode.Escape) || Input.GetKeyDown(KeyCode.C)) // ESC or C to cancel journey
+            {
+                CancelJourney();
+            }
+        }
+
+        // Handle map clicking for travel planning (only if click is outside UI panel)
+        if (Input.GetMouseButtonDown(0) && !isTraveling)
+        {
+            // Check if click is within the UI panel bounds
+            if (travelUI != null && travelUI.IsVisible && travelUI.IsPointWithinUI(Input.mousePosition))
+            {
+                return; // Block map interaction if clicking within UI panel
+            }
+
+            Vector3 mouseWorldPos = GetMouseWorldPosition();
+
+            if (mouseWorldPos != Vector3.zero)
+            {
+                Vector2Int clickedTile = WorldToTilePosition(mouseWorldPos);
+                PlanTravelTo(clickedTile);
+            }
+        }
+
+        // Check if TravelUI is blocking other input (non-map clicks)
+        if (IsTravelUIBlocking())
+        {
+            return; // Block other inputs but allow map clicks above
+        }
+
+        // Cancel travel planning
+        if (Input.GetKeyDown(KeyCode.Escape))
+        {
+            CancelTravelPlanning();
+        }
+
+        // Cycle through route visualizations
+        if (Input.GetKeyDown(KeyCode.Tab) && availableRoutes.Count > 1)
+        {
+            currentRouteIndex = (currentRouteIndex + 1) % availableRoutes.Count;
+            var selectedRoute = availableRoutes[currentRouteIndex];
+
+            // Highlight the selected route without clearing others
+            HighlightSpecificRoute(selectedRoute);
+
+            // Update the UI to show the new selected route
+            if (travelUI != null)
+            {
+                travelUI.UpdateUIForSelectedRoute(selectedRoute);
+            }
+
+            if (showDebugLogs)
+            {
+                Debug.Log($"Switched to {selectedRoute.routeType} route (Time: {selectedRoute.estimatedTime:F1}h)");
+            }
+        }
+
+        // Debug key to show movement costs
+        if (Input.GetKeyDown(KeyCode.C) && showMovementCosts)
+        {
+            ShowMovementCostInfo();
+        }
+
+        // Toggle debug logs
+        if (Input.GetKeyDown(KeyCode.F8))
+        {
+            showDebugLogs = !showDebugLogs;
+            Debug.Log($"Travel System Debug Logs: {(showDebugLogs ? "ENABLED" : "DISABLED")}");
+        }
+    }
+
+    /// <summary>
+    /// Plans travel to the specified destination and shows available routes
+    /// </summary>
+    public void PlanTravelTo(Vector2Int destination)
+    {
+        if (!teamPlacement.IsTeamPlaced())
+        {
+            Debug.LogWarning("❌ Cannot plan travel: Team not placed yet");
+            return;
+        }
+
+        Vector2Int currentPosition = teamPlacement.GetTeamPosition();
+
+        if (currentPosition == destination)
+        {
+            Debug.Log("Already at destination!");
+            return;
+        }
+
+        plannedDestination = destination;
+        currentRouteIndex = 0; // Reset route index for new destination
+
+        if (showDebugLogs)
+        {
+            Debug.Log($"🗺️ Planning travel from {currentPosition} to {destination}");
+        }
+
+        // Calculate different route options
+        CalculateRoutes(currentPosition, destination);
+
+        // If UI is already visible, refresh it with new routes
+        if (travelUI != null && travelUI.IsVisible)
+        {
+            Debug.Log("🔄 TeamTravelSystem: UI is visible, refreshing with new routes");
+            travelUI.RefreshWithNewRoutes(availableRoutes);
+        }
+
+        // Show all available routes visually with different colors
+        if (availableRoutes.Count > 0)
+        {
+            // Clear any existing visualizations first
+            ClearPathVisualization();
+
+            // Select the fastest route (shortest estimated time) by default
+            var routesByTime = availableRoutes.OrderBy(r => r.estimatedTime).ToList();
+            TravelRoute selectedRoute = routesByTime.First();
+
+            // Update currentRouteIndex to match the selected route in the original list
+            currentRouteIndex = availableRoutes.IndexOf(selectedRoute);
+
+            // Visualize all routes with the fastest one highlighted on top
+            VisualizeAllRoutes(availableRoutes);
+
+            if (showDebugLogs)
+            {
+                Debug.Log($"🔧 About to show UI for {selectedRoute.routeType} route with {selectedRoute.path.Count} waypoints");
+            }
+
+            // Show travel UI if available
+            ShowTravelUIIfAvailable(destination, availableRoutes);
+
+            if (showDebugLogs)
+            {
+                Debug.Log($"Found {availableRoutes.Count} route options. Selected {selectedRoute.routeType} route: {selectedRoute.estimatedTime:F1}h time");
+                Debug.Log("Use TAB to cycle through different route options");
+            }
+        }
+    }
+
+    /// <summary>
+    /// Calculates different route options including fastest, shortest, and cheapest routes
+    /// </summary>
+    private void CalculateRoutes(Vector2Int start, Vector2Int destination)
+    {
+        availableRoutes.Clear();
+
+        var mapData = mapMaker.GetMapData();
+        if (mapData == null) return;
+
+        if (showDebugLogs)
+        {
+            Debug.Log($"🔍 Calculating routes from {start} to {destination}");
+        }
+
+        // Fastest route (heavily prefers roads and fast terrain)
+        var fastestRoute = FindPath(start, destination, RouteType.RoadPreferred);
+        if (fastestRoute != null)
+        {
+            availableRoutes.Add(fastestRoute);
+            if (showDebugLogs)
+            {
+                Debug.Log($"Fastest route: {fastestRoute.estimatedTime:F1}h time, {fastestRoute.path.Count} waypoints");
+            }
+        }
+
+        // Shortest route (direct path, minimal waypoints)
+        var shortestRoute = FindPath(start, destination, RouteType.Standard);
+        if (shortestRoute != null)
+        {
+            bool similar = RoutesSimilar(fastestRoute, shortestRoute);
+            if (showDebugLogs)
+            {
+                Debug.Log($"Shortest route: {shortestRoute.estimatedTime:F1}h time, {shortestRoute.path.Count} waypoints, similar to fastest: {similar}");
+            }
+            if (!similar)
+            {
+                availableRoutes.Add(shortestRoute);
+            }
+        }
+
+        // Cheapest route (minimizes resource costs first, then travel time)
+        var cheapestRoute = FindCheapestPath(start, destination);
+        if (cheapestRoute != null)
+        {
+            bool similarToFastest = RoutesSimilar(fastestRoute, cheapestRoute);
+            bool similarToShortest = RoutesSimilar(shortestRoute, cheapestRoute);
+            if (showDebugLogs)
+            {
+                Debug.Log($"Cheapest route: {cheapestRoute.estimatedTime:F1}h time, {GetTotalResourceCost(cheapestRoute)} resource cost, {cheapestRoute.path.Count} waypoints");
+            }
+            if (!similarToFastest && !similarToShortest)
+            {
+                availableRoutes.Add(cheapestRoute);
+            }
+        }
+
+        // If we ended up with only one route, try to generate alternatives with different parameters
+        if (availableRoutes.Count == 1)
+        {
+            if (showDebugLogs)
+            {
+                Debug.Log("Only one unique route found, generating alternatives...");
+            }
+
+            // Try a more direct route that ignores some terrain penalties
+            var directRoute = FindDirectPath(start, destination);
+            if (directRoute != null && !RoutesSimilar(availableRoutes[0], directRoute))
+            {
+                availableRoutes.Add(directRoute);
+                if (showDebugLogs)
+                {
+                    Debug.Log($"Direct route added: {directRoute.estimatedTime:F1}h time");
+                }
+            }
+        }
+
+        if (showDebugLogs)
+        {
+            Debug.Log($"📊 Total unique routes calculated: {availableRoutes.Count}");
+        }
+    }
+
+    /// <summary>
+    /// Finds the best path between two points using A* pathfinding with different route preferences
+    /// </summary>
+    private TravelRoute FindPath(Vector2Int start, Vector2Int destination, RouteType routeType)
+    {
+        var mapData = mapMaker.GetMapData();
+        Debug.Log($"🗺️ Finding {routeType} path from {start} to {destination}");
+
+        var openSet = new List<PathNode>();
+        var closedSet = new HashSet<Vector2Int>();
+        var allNodes = new Dictionary<Vector2Int, PathNode>();
+
+        var startNode = new PathNode
+        {
+            position = start,
+            gCost = 0,
+            hCost = CalculateHeuristic(start, destination, routeType),
+            parent = null
+        };
+
+        openSet.Add(startNode);
+        allNodes[start] = startNode;
+
+        int iterations = 0;
+        const int maxIterations = 10000; // Prevent infinite loops
+
+        while (openSet.Count > 0 && iterations < maxIterations)
+        {
+            iterations++;
+
+            // Find node with lowest fCost
+            var currentNode = openSet.OrderBy(n => n.fCost).ThenBy(n => n.hCost).First();
+            openSet.Remove(currentNode);
+            closedSet.Add(currentNode.position);
+
+            // Reached destination
+            if (currentNode.position == destination)
+            {
+                var route = ReconstructRoute(currentNode, routeType);
+                if (showDebugLogs)
+                {
+                    Debug.Log($"{routeType} path found in {iterations} iterations, final cost: {currentNode.gCost:F1}");
+                }
+
+                // Analyze the route composition
+                if (showDebugLogs)
+                {
+                    AnalyzeRouteComposition(route);
+                }
+
+                return route;
+            }
+
+            // Check neighbors
+            var neighbors = GetNeighbors(currentNode.position);
+            foreach (var neighbor in neighbors)
+            {
+                if (closedSet.Contains(neighbor) || !mapData.IsValidPosition(neighbor.x, neighbor.y))
+                    continue;
+
+                float movementCost = GetMovementCost(currentNode.position, neighbor, routeType);
+                if (movementCost < 0) continue; // Impassable terrain
+
+                float tentativeGCost = currentNode.gCost + movementCost;
+
+                if (!allNodes.ContainsKey(neighbor))
+                {
+                    allNodes[neighbor] = new PathNode
+                    {
+                        position = neighbor,
+                        gCost = float.MaxValue,
+                        hCost = CalculateHeuristic(neighbor, destination, routeType),
+                        parent = null
+                    };
+                }
+
+                var neighborNode = allNodes[neighbor];
+
+                if (tentativeGCost < neighborNode.gCost)
+                {
+                    neighborNode.parent = currentNode;
+                    neighborNode.gCost = tentativeGCost;
+
+                    if (!openSet.Contains(neighborNode))
+                    {
+                        openSet.Add(neighborNode);
+                    }
+                }
+            }
+        }
+
+        Debug.LogWarning($"❌ {routeType} path not found after {iterations} iterations (max: {maxIterations})");
+        return null; // No path found
+    }
+
+    /// <summary>
+    /// Gets movement cost for moving from one tile to another, considering route type preferences
+    /// </summary>
+    private float GetMovementCost(Vector2Int from, Vector2Int to, RouteType routeType)
+    {
+        var mapData = mapMaker.GetMapData();
+        var toTile = mapData.GetTile(to.x, to.y);
+
+        // Base movement cost by terrain
+        float baseCost = GetTerrainMovementCost(toTile);
+
+        // Feature modifications
+        float featureCost = GetFeatureMovementCost(toTile, routeType);
+
+        // Combine costs
+        float totalCost = baseCost * featureCost;
+
+        // Route type adjustments
+        switch (routeType)
+        {
+            case RouteType.Standard:
+                // Shortest route: minimize distance regardless of terrain difficulty
+                // No terrain or road preferences - pure distance optimization
+                break;
+
+            case RouteType.RoadPreferred:
+                // Fastest route: heavily favors roads and fast terrain, considers costly but fast options
+                if (toTile.featureType == FeatureType.Road)
+                {
+                    totalCost *= 0.3f; // Strong road preference (70% discount) - roads are much faster but realistic
+                }
+                else if (toTile.featureType == FeatureType.Tunnel)
+                {
+                    // Tunnels are fast for fastest route (ignore resource cost for speed optimization)
+                    totalCost *= 0.4f; // Very fast travel through tunnels
+                }
+                else if (toTile.featureType == FeatureType.Ferry)
+                {
+                    // Ferries are reasonably fast for fastest route
+                    totalCost *= 0.6f; // Fast water crossing
+                }
+                else
+                {
+                    // Penalize non-road movement for road-preferred routes
+                    totalCost *= 1.5f; // 50% penalty for off-road movement
+                }
+                break;
+
+            case RouteType.Special:
+                // Cheapest route: avoid resource costs, but don't make travel time unrealistic
+                // Moderate penalties for features that cost resources
+                if (toTile.featureType == FeatureType.Ferry || toTile.featureType == FeatureType.Tunnel)
+                    totalCost *= 3.0f; // Significant penalty for resource-costing features (was 10x)
+
+                // Moderate penalties for features that might trigger resource costs
+                if (toTile.featureType == FeatureType.Bridge)
+                    totalCost *= 2.0f; // Penalty for bridges (potential tolls) (was 5x)
+
+                // Light penalty for terrain that requires guides/special costs
+                if (toTile.terrainType == TerrainType.Mountain)
+                    totalCost *= 2.0f; // Penalty for mountains (guide costs) (was 5x)
+
+                // Still avoid slow terrain, but secondary to cost avoidance
+                if (toTile.terrainType == TerrainType.River || toTile.terrainType == TerrainType.Lake)
+                    totalCost *= 1.5f; // Light penalty for water crossings (was 2x)
+
+                // Prefer roads since they're free and fast
+                if (toTile.featureType == FeatureType.Road)
+                    totalCost *= 0.5f; // Good road preference (50% discount)
+                break;
+        }
+
+        return totalCost;
+    }
+
+    /// <summary>
+    /// Gets base movement cost for different terrain types
+    /// </summary>
+    private float GetTerrainMovementCost(MapTile tile)
+    {
+        switch (tile.terrainType)
+        {
+            case TerrainType.Plains:
+                return plainsMovementCost;
+            case TerrainType.Forest:
+                return forestMovementCost;
+            case TerrainType.Mountain:
+                return mountainMovementCost;
+            case TerrainType.Ocean:
+                return oceanCrossingCost; // Allow dangerous ocean crossing
+            case TerrainType.Lake:
+                return lakeCrossingCost; // Allow swimming across lakes
+            case TerrainType.River:
+                return riverCrossingCost; // Allow slow river crossing
+            default:
+                return plainsMovementCost;
+        }
+    }
+
+    /// <summary>
+    /// Gets movement cost modifications from features (roads, bridges, etc.)
+    /// </summary>
+    private float GetFeatureMovementCost(MapTile tile, RouteType routeType)
+    {
+        switch (tile.featureType)
+        {
+            case FeatureType.Road:
+                return roadMovementCost; // Fast movement on roads
+            case FeatureType.Bridge:
+                return roadMovementCost; // Bridges are as fast as roads (crossing structures)
+            case FeatureType.Town:
+            case FeatureType.Village:
+                return townMovementCost; // Very fast through settlements
+            case FeatureType.Ferry:
+                return ferryMovementCost; // Ferries are fast transportation (cost is in gold, not time)
+            case FeatureType.Tunnel:
+                return tunnelWithTorchCost; // Tunnels are fast with torch (cost is in torches, not time)
+            default:
+                return 1f; // No modification
+        }
+    }
+
+    /// <summary>
+    /// Calculates heuristic distance for A* pathfinding with route type considerations
+    /// </summary>
+    private float CalculateHeuristic(Vector2Int from, Vector2Int to, RouteType routeType = RouteType.Standard)
+    {
+        float baseHeuristic = Vector2Int.Distance(from, to) * plainsMovementCost;
+
+        // For road-preferred routes, make the heuristic slightly more optimistic about finding roads
+        if (routeType == RouteType.RoadPreferred)
+        {
+            // Assume we'll find roads for some of the journey
+            baseHeuristic *= 0.8f; // Slightly more optimistic heuristic
+        }
+
+        return baseHeuristic;
+    }
+
+    /// <summary>
+    /// Gets valid neighboring tiles for pathfinding
+    /// </summary>
+    private List<Vector2Int> GetNeighbors(Vector2Int position)
+    {
+        var neighbors = new List<Vector2Int>();
+
+        // 8-directional movement
+        for (int dx = -1; dx <= 1; dx++)
+        {
+            for (int dy = -1; dy <= 1; dy++)
+            {
+                if (dx == 0 && dy == 0) continue;
+
+                Vector2Int neighbor = new Vector2Int(position.x + dx, position.y + dy);
+                neighbors.Add(neighbor);
+            }
+        }
+
+        return neighbors;
+    }
+
+    /// <summary>
+    /// Reconstructs the final route from pathfinding results
+    /// </summary>
+    private TravelRoute ReconstructRoute(PathNode destinationNode, RouteType routeType)
+    {
+        var route = new TravelRoute
+        {
+            routeType = routeType,
+            path = new List<Vector2Int>(),
+            totalCost = destinationNode.gCost,
+            totalDistance = 0f,
+            estimatedTime = 0f,
+            specialCosts = new Dictionary<string, int>()
+        };
+
+        var current = destinationNode;
+        while (current != null)
+        {
+            route.path.Insert(0, current.position);
+            current = current.parent;
+        }
+
+        // Calculate additional route information
+        CalculateRouteDetails(route);
+
+        return route;
+    }
+
+    /// <summary>
+    /// Finds a more direct path that ignores some terrain penalties for route variety
+    /// </summary>
+    private TravelRoute FindDirectPath(Vector2Int start, Vector2Int destination)
+    {
+        var mapData = mapMaker.GetMapData();
+        Debug.Log($"🎯 Finding direct path from {start} to {destination}");
+
+        var openSet = new List<PathNode>();
+        var closedSet = new HashSet<Vector2Int>();
+        var allNodes = new Dictionary<Vector2Int, PathNode>();
+
+        var startNode = new PathNode
+        {
+            position = start,
+            gCost = 0,
+            hCost = CalculateHeuristic(start, destination),
+            parent = null
+        };
+
+        openSet.Add(startNode);
+        allNodes[start] = startNode;
+
+        int iterations = 0;
+        const int maxIterations = 10000;
+
+        while (openSet.Count > 0 && iterations < maxIterations)
+        {
+            iterations++;
+
+            var currentNode = openSet.OrderBy(n => n.fCost).ThenBy(n => n.hCost).First();
+            openSet.Remove(currentNode);
+            closedSet.Add(currentNode.position);
+
+            if (currentNode.position == destination)
+            {
+                var route = ReconstructRoute(currentNode, RouteType.Special);
+                route.routeType = RouteType.Special; // Mark as direct route
+                Debug.Log($"✅ Direct path found in {iterations} iterations, final cost: {currentNode.gCost:F1}");
+                CalculateRouteDetails(route);
+                return route;
+            }
+
+            var neighbors = GetNeighbors(currentNode.position);
+            foreach (var neighbor in neighbors)
+            {
+                if (closedSet.Contains(neighbor) || !mapData.IsValidPosition(neighbor.x, neighbor.y))
+                    continue;
+
+                // Use simplified movement cost for direct routes (less terrain penalty)
+                float movementCost = GetDirectMovementCost(currentNode.position, neighbor);
+                if (movementCost < 0) continue;
+
+                float tentativeGCost = currentNode.gCost + movementCost;
+
+                if (!allNodes.ContainsKey(neighbor))
+                {
+                    allNodes[neighbor] = new PathNode
+                    {
+                        position = neighbor,
+                        gCost = float.MaxValue,
+                        hCost = CalculateHeuristic(neighbor, destination),
+                        parent = null
+                    };
+                }
+
+                var neighborNode = allNodes[neighbor];
+
+                if (tentativeGCost < neighborNode.gCost)
+                {
+                    neighborNode.parent = currentNode;
+                    neighborNode.gCost = tentativeGCost;
+
+                    if (!openSet.Contains(neighborNode))
+                    {
+                        openSet.Add(neighborNode);
+                    }
+                }
+            }
+        }
+
+        Debug.LogWarning($"❌ Direct path not found after {iterations} iterations");
+        return null;
+    }
+
+    /// <summary>
+    /// Simplified movement cost calculation for direct routes
+    /// </summary>
+    private float GetDirectMovementCost(Vector2Int from, Vector2Int to)
+    {
+        var mapData = mapMaker.GetMapData();
+        var toTile = mapData.GetTile(to.x, to.y);
+
+        // Simplified costs that emphasize directness over terrain optimization
+        switch (toTile.terrainType)
+        {
+            case TerrainType.Plains:
+                return 1.0f;
+            case TerrainType.Forest:
+                return 1.5f; // Less penalty than normal
+            case TerrainType.Mountain:
+                return 2.0f; // Much less penalty for directness
+            case TerrainType.River:
+                return 1.8f;
+            case TerrainType.Lake:
+                return 2.0f;
+            case TerrainType.Ocean:
+                return 4.0f; // Still expensive but possible
+            default:
+                return 1.0f;
+        }
+    }
+
+    /// <summary>
+    /// Finds the cheapest path that minimizes resource costs (gold) first, then travel time
+    /// Uses the Special route type but should calculate actual travel time correctly
+    /// </summary>
+    private TravelRoute FindCheapestPath(Vector2Int start, Vector2Int destination)
+    {
+        // Use the standard A* pathfinding with Special route type (which avoids costly features)
+        return FindPath(start, destination, RouteType.Special);
+    }
+
+    /// <summary>
+    /// Gets the resource cost for entering a specific tile
+    /// </summary>
+    private float GetResourceCostForTile(Vector2Int position)
+    {
+        var mapData = mapMaker.GetMapData();
+        var tile = mapData.GetTile(position.x, position.y);
+
+        switch (tile.featureType)
+        {
+            case FeatureType.Ferry:
+                return ferryBaseCost; // Direct gold cost
+            case FeatureType.Tunnel:
+                return tunnelTorchCost; // Torch cost (treated as gold equivalent)
+            case FeatureType.Bridge:
+                return 2.0f; // Potential bridge toll (small cost to prefer other routes)
+            default:
+                break;
+        }
+
+        // Terrain-based resource costs (for guide fees, etc.)
+        switch (tile.terrainType)
+        {
+            case TerrainType.Mountain:
+                return 3.0f; // Potential guide cost for dangerous areas
+            default:
+                return 0.0f; // No resource cost
+        }
+    }
+
+    /// <summary>
+    /// Calculates detailed information about the route (distance, time, special costs)
+    /// </summary>
+    private void CalculateRouteDetails(TravelRoute route)
+    {
+        var mapData = mapMaker.GetMapData();
+
+        route.totalDistance = route.path.Count;
+        route.estimatedTime = route.totalCost * 0.5f; // Rough time estimate
+
+        // Check for special costs
+        int bridgeCount = 0;
+        int mountainTileCount = 0;
+
+        foreach (var position in route.path)
+        {
+            var tile = mapData.GetTile(position.x, position.y);
+
+            // Ferry costs
+            if (tile.featureType == FeatureType.Ferry)
+            {
+                if (!route.specialCosts.ContainsKey("Ferry"))
+                    route.specialCosts["Ferry"] = ferryBaseCost;
+            }
+            // Tunnel costs
+            else if (tile.featureType == FeatureType.Tunnel)
+            {
+                if (!route.specialCosts.ContainsKey("Tunnel Torch"))
+                    route.specialCosts["Tunnel Torch"] = tunnelTorchCost;
+            }
+            // Bridge tolls (for major bridges)
+            else if (tile.featureType == FeatureType.Bridge)
+            {
+                bridgeCount++;
+            }
+            // Mountain passes (dangerous mountain areas need guides)
+            else if (tile.terrainType == TerrainType.Mountain)
+            {
+                mountainTileCount++;
+            }
+        }
+
+        // Add bridge toll costs (only for longer bridge crossings)
+        if (bridgeCount >= 3) // Only charge for significant bridge crossings
+        {
+            route.specialCosts["Bridge Toll"] = bridgeTollCost;
+        }
+
+        // Add mountain guide costs (for extensive mountain travel)
+        if (mountainTileCount >= 5) // Only charge for dangerous mountain passes
+        {
+            route.specialCosts["Mountain Guide"] = mountainPassCost;
+        }
+    }
+
+    /// <summary>
+    /// Calculates the total resource cost (gold equivalent) for a route
+    /// </summary>
+    private int GetTotalResourceCost(TravelRoute route)
+    {
+        if (route?.specialCosts == null) return 0;
+
+        int totalCost = 0;
+        foreach (var cost in route.specialCosts)
+        {
+            totalCost += cost.Value; // All costs are in gold or gold-equivalent
+        }
+        return totalCost;
+    }
+
+    /// <summary>
+    /// Checks if two routes are essentially the same
+    /// </summary>
+    private bool RoutesSimilar(TravelRoute route1, TravelRoute route2)
+    {
+        if (route1 == null || route2 == null) return false;
+
+        // Consider routes similar if they have >90% path overlap (more strict to allow more variations)
+        var overlap = route1.path.Intersect(route2.path).Count();
+        var maxLength = Mathf.Max(route1.path.Count, route2.path.Count);
+
+        bool similar = (float)overlap / maxLength > 0.9f;
+        Debug.Log($"🔍 Route similarity check: {overlap}/{maxLength} = {((float)overlap / maxLength):F2} > 0.9? {similar}");
+
+        return similar;
+    }
+
+    /// <summary>
+    /// Analyzes and logs the composition of a route for debugging
+    /// </summary>
+    private void AnalyzeRouteComposition(TravelRoute route)
+    {
+        if (route == null || route.path == null) return;
+
+        var mapData = mapMaker.GetMapData();
+        int plainsCount = 0, forestCount = 0, mountainCount = 0, roadCount = 0, riverCount = 0, lakeCount = 0;
+        float totalMovementCost = 0;
+        float roadBonusTotal = 0;
+
+        foreach (var pos in route.path)
+        {
+            var tile = mapData.GetTile(pos.x, pos.y);
+            float tileCost = GetMovementCost(pos, pos, route.routeType);
+            totalMovementCost += tileCost;
+
+            switch (tile.terrainType)
+            {
+                case TerrainType.Plains: plainsCount++; break;
+                case TerrainType.Forest: forestCount++; break;
+                case TerrainType.Mountain: mountainCount++; break;
+                case TerrainType.River: riverCount++; break;
+                case TerrainType.Lake: lakeCount++; break;
+            }
+
+            if (tile.featureType == FeatureType.Road)
+            {
+                roadCount++;
+                // Calculate road bonus for this route type
+                switch (route.routeType)
+                {
+                    case RouteType.Standard:
+                        roadBonusTotal += GetTerrainMovementCost(tile) * (1f - 0.6f); // 40% discount
+                        break;
+                    case RouteType.RoadPreferred:
+                        roadBonusTotal += GetTerrainMovementCost(tile) * (1f - 0.2f); // 80% discount
+                        break;
+                }
+            }
+        }
+
+        float avgCostPerTile = totalMovementCost / route.path.Count;
+        float roadPercentage = (float)roadCount / route.path.Count * 100f;
+
+        Debug.Log($"📊 Route Analysis ({route.routeType}): {route.path.Count} tiles");
+        Debug.Log($"   Terrain: Plains:{plainsCount}, Forest:{forestCount}, Mountain:{mountainCount}, Rivers:{riverCount}, Lakes:{lakeCount}");
+        Debug.Log($"   Roads: {roadCount} tiles ({roadPercentage:F1}%), saved {roadBonusTotal:F1} cost");
+        Debug.Log($"   Average cost per tile: {avgCostPerTile:F2} (Total: {totalMovementCost:F1})");
+        Debug.Log($"   Time calculation: {route.estimatedTime:F1}h = {route.totalCost:F1} cost × 0.5 multiplier");
+
+        // Explain why this route type might be different
+        string explanation = "";
+        switch (route.routeType)
+        {
+            case RouteType.Standard:
+                explanation = "Shortest route minimizes distance and waypoints";
+                break;
+            case RouteType.RoadPreferred:
+                explanation = $"Fastest route heavily favors roads (90% discount) - {roadPercentage:F1}% on roads";
+                break;
+            case RouteType.Special:
+                explanation = "Cheapest/Direct route avoids special costs and takes direct paths";
+                break;
+        }
+        Debug.Log($"   Strategy: {explanation}");
+    }
+
+    /// <summary>
+    /// Visualizes the selected route on the map
+    /// </summary>
+    private void VisualizeRoute(TravelRoute route)
+    {
+        if (showDebugLogs)
+        {
+            Debug.Log($"🎨 VisualizeRoute called with route: {route?.routeType} ({route?.path?.Count ?? 0} points)");
+        }
+
+        ClearPathVisualization();
+
+        if (route == null || route.path.Count == 0)
+        {
+            if (showDebugLogs)
+            {
+                Debug.LogWarning("❌ Cannot visualize route: route is null or has no path points");
+            }
+            return;
+        }
+
+        // Create path visualization
+        var pathObject = new GameObject("TravelPath");
+        var lineRenderer = pathObject.AddComponent<LineRenderer>();
+
+        // Configure line renderer with simple, reliable settings
+        lineRenderer.material = pathLineMaterial ?? CreateDefaultPathMaterial();
+        lineRenderer.material.color = GetRouteColor(route);
+
+        // Force line width to 1.0 for consistent visibility
+        lineRenderer.startWidth = 1.0f;
+        lineRenderer.endWidth = 1.0f;
+        lineRenderer.positionCount = route.path.Count;
+        lineRenderer.useWorldSpace = true;
+
+        // Simple LineRenderer settings for reliable visibility
+        lineRenderer.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off;
+        lineRenderer.receiveShadows = false;
+        lineRenderer.alignment = LineAlignment.View; // Face camera
+        lineRenderer.textureMode = LineTextureMode.Tile;
+        lineRenderer.sortingLayerName = "Default";
+        lineRenderer.sortingOrder = 50; // High sorting order but not excessive
+
+        // Debug the width setting
+        if (showDebugLogs)
+        {
+            Debug.Log($"🔧 Setting LineRenderer width to: {pathLineWidth} (startWidth: {lineRenderer.startWidth}, endWidth: {lineRenderer.endWidth})");
+        }
+
+        // Set path points
+        for (int i = 0; i < route.path.Count; i++)
+        {
+            Vector3 worldPos = TileToWorldPosition(route.path[i]);
+            worldPos.z = pathLineZOffset; // Place in front of map
+            lineRenderer.SetPosition(i, worldPos);
+        }
+
+        currentPathVisualizations.Add(pathObject);
+
+        if (showDebugLogs)
+        {
+            Debug.Log($"📍 Visualized {route.routeType} route with {route.path.Count} waypoints");
+            Debug.Log($"🔧 LineRenderer config: startWidth={lineRenderer.startWidth}, endWidth={lineRenderer.endWidth}, material={lineRenderer.material?.name}, color={lineRenderer.material?.color}");
+            Debug.Log($"🎯 GameObject created: {pathObject.name} at position {pathObject.transform.position}");
+        }
+    }
+
+    /// <summary>
+    /// Visualizes all available routes with different colors and proper layering
+    /// </summary>
+    private void VisualizeAllRoutes(List<TravelRoute> routes)
+    {
+        ClearPathVisualization();
+
+        // Render all routes with the first one (fastest by time) selected by default
+        var routesByTime = routes.OrderBy(r => r.estimatedTime).ToList();
+        var defaultSelected = routesByTime.FirstOrDefault();
+
+        for (int i = 0; i < routes.Count; i++)
+        {
+            var route = routes[i];
+            if (route == null || route.path.Count == 0) continue;
+
+            bool isSelected = (route == defaultSelected);
+            RenderSingleRoute(route, i, isSelected);
+        }
+
+        if (showDebugLogs)
+        {
+            string selectedName = defaultSelected?.routeType == RouteType.RoadPreferred ? "Fastest" :
+                                 defaultSelected?.routeType == RouteType.Standard ? "Shortest" : "Cheapest";
+            Debug.Log($"🎨 Visualized {routes.Count} routes with {selectedName} as default selected (on top)");
+        }
+    }    /// <summary>
+         /// Gets the appropriate color for a route based on its type (GPS-style)
+         /// </summary>
+    private Color GetRouteColor(TravelRoute route)
+    {
+        // GPS-style color coding
+        switch (route.routeType)
+        {
+            case RouteType.RoadPreferred: // Fastest route
+                if (showDebugLogs) Debug.Log($"🎨 Route color: GREEN (fastest route)");
+                return Color.green; // Green for fastest (like GPS)
+
+            case RouteType.Standard: // Shortest route
+                if (showDebugLogs) Debug.Log($"🎨 Route color: BLUE (shortest route)");
+                return standardPathColor; // Blue for shortest
+
+            case RouteType.Special: // Cheapest/Direct route
+                if (showDebugLogs) Debug.Log($"🎨 Route color: YELLOW (cheapest/direct route)");
+                return alternativePathColor; // Yellow for cheapest/alternative
+
+            default:
+                if (showDebugLogs) Debug.Log($"🎨 Route color: BLUE (default)");
+                return standardPathColor;
+        }
+    }
+
+    /// <summary>
+    /// Creates a default material for path visualization
+    /// </summary>
+    private Material CreateDefaultPathMaterial()
+    {
+        // Use simple Sprites/Default shader for reliable rendering
+        Shader shader = Shader.Find("Sprites/Default");
+        if (shader == null)
+            shader = Shader.Find("Legacy Shaders/Particles/Alpha Blended Premultiply");
+        if (shader == null)
+            shader = Shader.Find("Unlit/Color");
+        if (shader == null)
+            shader = Shader.Find("Standard");
+
+        var material = new Material(shader ?? Shader.Find("Diffuse"));
+        material.color = standardPathColor;
+
+        if (showDebugLogs)
+        {
+            Debug.Log($"🎨 Created path material with shader: {shader?.name ?? "Unknown"}");
+        }
+
+        return material;
+    }
+
+    /// <summary>
+    /// Clears any existing path visualization
+    /// </summary>
+    private void ClearPathVisualization()
+    {
+        foreach (var pathViz in currentPathVisualizations)
+        {
+            if (pathViz != null)
+            {
+                DestroyImmediate(pathViz);
+            }
+        }
+        currentPathVisualizations.Clear();
+    }
+
+    /// <summary>
+    /// Cancels current travel planning
+    /// </summary>
+    public void CancelTravelPlanning()
+    {
+        plannedDestination = null;
+        availableRoutes.Clear();
+        ClearPathVisualization();
+        HideTravelUI();
+
+        if (showDebugLogs)
+        {
+            Debug.Log("❌ Travel planning cancelled");
+        }
+    }
+
+    /// <summary>
+    /// Starts travel using the specified route
+    /// </summary>
+    public void StartTravel(TravelRoute route)
+    {
+        if (route == null || isTraveling)
+        {
+            Debug.LogWarning("Cannot start travel: invalid route or already traveling");
+            return;
+        }
+
+        // Synchronize coordinates before starting travel
+        SynchronizeWithExplorationSystem();
+
+        // Reset cancellation flag and store current route
+        shouldCancelJourney = false;
+        currentRoute = route;
+
+        // Start the travel coroutine and store reference
+        currentTravelCoroutine = StartCoroutine(ExecuteTravel(route));
+    }
+
+    /// <summary>
+    /// Cancels the current journey if one is in progress
+    /// </summary>
+    public void CancelJourney()
+    {
+        if (!isTraveling)
+        {
+            if (showDebugLogs) Debug.Log("No journey to cancel");
+            return;
+        }
+
+        if (showDebugLogs)
+        {
+            Debug.Log("Journey cancellation requested by player");
+        }
+
+        // Set the cancellation flag
+        shouldCancelJourney = true;
+
+        // The actual cleanup will happen in the ExecuteTravel coroutine
+    }
+
+    /// <summary>
+    /// Executes the actual travel along the route
+    /// </summary>
+    private IEnumerator ExecuteTravel(TravelRoute route)
+    {
+        isTraveling = true;
+
+        if (showDebugLogs)
+        {
+            Debug.Log($"🚶 Starting travel along {route.routeType} route");
+            Debug.Log($"📍 Route has {route.path.Count} waypoints, estimated time: {route.estimatedTime:F1} hours");
+        }
+
+        // Ensure team marker is visible during travel (stop blinking)
+        EnsureTeamMarkerVisible(true);
+
+        // Debug: Check initial team marker state
+        var initialMarker = teamPlacement.GetTeamMarker();
+        if (initialMarker != null)
+        {
+            Debug.Log($"🔍 Initial team marker: Position={initialMarker.transform.position}, Active={initialMarker.activeInHierarchy}, WorldPos={initialMarker.transform.position}");
+            var initialRenderer = initialMarker.GetComponent<Renderer>();
+            if (initialRenderer != null)
+            {
+                Debug.Log($"🔍 Initial renderer: Enabled={initialRenderer.enabled}, Material={initialRenderer.material?.name}");
+            }
+        }
+        else
+        {
+            Debug.LogError("❌ No team marker found at start of travel!");
+        }
+
+        // Deduct special costs before travel
+        DeductTravelCosts(route);
+
+        // Move team marker along the path with smooth animation
+        for (int i = 1; i < route.path.Count; i++)
+        {
+            // Check for cancellation at the start of each step
+            if (shouldCancelJourney)
+            {
+                if (showDebugLogs)
+                {
+                    Debug.Log($"🛑 Journey cancelled at step {i}/{route.path.Count - 1}. Stopping at {route.path[i - 1]}");
+                }
+                break; // Exit the movement loop
+            }
+
+            Vector2Int nextPosition = route.path[i];
+            Vector2Int currentPos = route.path[i - 1];
+
+            if (showDebugLogs && i % 3 == 0) // Log every 3rd step
+            {
+                Debug.Log($"🚶 Traveling step {i}/{route.path.Count - 1} to {nextPosition} ({((float)i / (route.path.Count - 1) * 100):F0}% complete)");
+            }
+
+            // Get current and target world positions for smooth movement
+            Vector3 currentWorldPos = TileToWorldPosition(currentPos);
+            Vector3 targetWorldPos = TileToWorldPosition(nextPosition);
+
+            // Animate the team marker moving smoothly between positions
+            float moveTime = 0.8f; // Base time per step (slower movement)
+            float stepCost = GetMovementCost(currentPos, nextPosition, route.routeType);
+
+            // Adjust move time based on terrain difficulty
+            moveTime *= Mathf.Clamp(stepCost * 0.3f, 0.5f, 3f); // Slower for difficult terrain
+
+            // Smooth movement animation
+            float elapsed = 0f;
+            while (elapsed < moveTime)
+            {
+                // Check for cancellation during movement animation
+                if (shouldCancelJourney)
+                {
+                    if (showDebugLogs)
+                    {
+                        Debug.Log($"🛑 Journey cancelled during movement animation. Stopping at current position.");
+                    }
+                    break; // Exit the animation loop
+                }
+
+                elapsed += Time.deltaTime;
+                float t = Mathf.SmoothStep(0f, 1f, elapsed / moveTime);
+
+                // Interpolate between current and target position
+                Vector3 lerpedWorldPos = Vector3.Lerp(currentWorldPos, targetWorldPos, t);
+                Vector2Int lerpedTilePos = WorldToTilePosition(lerpedWorldPos);
+
+                // Update team position smoothly (but only if it's a valid position)
+                if (mapMaker.GetMapData().IsValidPosition(lerpedTilePos.x, lerpedTilePos.y))
+                {
+                    teamPlacement.PlaceTeamAt(lerpedTilePos);
+
+                    // Ensure marker stays visible during travel
+                    var teamMarker = teamPlacement.GetTeamMarker();
+                    if (teamMarker != null)
+                    {
+                        teamMarker.SetActive(true);
+                        var renderer = teamMarker.GetComponent<Renderer>();
+                        if (renderer != null && !renderer.enabled)
+                        {
+                            renderer.enabled = true;
+                            if (showDebugLogs)
+                            {
+                                Debug.Log($"🔧 Re-enabled team marker renderer at {teamMarker.transform.position}");
+                            }
+                        }
+                    }
+                }
+
+                yield return null; // Wait one frame
+            }
+
+            // Break out of the inner animation loop if cancelled
+            if (shouldCancelJourney)
+            {
+                break; // Exit the for loop as well
+            }
+
+            // Ensure we end up exactly at the target position (if not cancelled)
+            if (!shouldCancelJourney)
+            {
+                teamPlacement.PlaceTeamAt(nextPosition);
+            }
+        }
+
+        // Journey cleanup - whether completed or cancelled
+        isTraveling = false;
+        ResetTimeSpeed(); // Reset time scale to normal when travel ends
+        EnsureTeamMarkerVisible(false); // Restore blinking
+        ClearPathVisualization();
+        HideTravelUI();
+
+        // Synchronize coordinate systems after travel
+        SynchronizeWithExplorationSystem();
+
+        // Clear travel state
+        currentTravelCoroutine = null;
+        currentRoute = null;
+
+        if (shouldCancelJourney)
+        {
+            if (showDebugLogs)
+            {
+                Debug.Log($"🛑 Journey cancelled! Team stopped at {teamPlacement.GetTeamPosition()}");
+            }
+            shouldCancelJourney = false; // Reset the flag
+        }
+        else
+        {
+            if (showDebugLogs)
+            {
+                Debug.Log($"✅ Travel completed! Arrived at {route.path.Last()}");
+            }
+        }
+    }
+
+    /// <summary>
+    /// Synchronize travel system coordinates with exploration system
+    /// </summary>
+    private void SynchronizeWithExplorationSystem()
+    {
+        if (mapMaker != null && mapMaker.useExplorationSystem)
+        {
+            mapMaker.SyncTeamPosition();
+            if (showDebugLogs)
+            {
+                Debug.Log("🔄 Synchronized team position with exploration system");
+            }
+        }
+    }
+
+    /// <summary>
+    /// Deducts costs for travel (gold, items, etc.)
+    /// </summary>
+    private void DeductTravelCosts(TravelRoute route)
+    {
+        if (route.specialCosts.Count == 0) return;
+
+        if (showDebugLogs)
+        {
+            Debug.Log($"💰 Deducting travel costs: {string.Join(", ", route.specialCosts.Select(kvp => $"{kvp.Key}: {kvp.Value}"))}");
+        }
+
+        // TODO: Implement actual resource deduction
+        // This would integrate with your inventory/currency system
+        foreach (var cost in route.specialCosts)
+        {
+            switch (cost.Key)
+            {
+                case "Ferry":
+                    // DeductGold(cost.Value);
+                    Debug.Log($"💰 Would deduct {cost.Value} gold for ferry");
+                    break;
+                case "Tunnel Torch":
+                    // DeductTorches(cost.Value);
+                    Debug.Log($"🔥 Would deduct {cost.Value} torches for tunnel");
+                    break;
+            }
+        }
+    }
+
+    /// <summary>
+    /// Ensures the team marker is visible during travel by controlling its blinking behavior
+    /// </summary>
+    private void EnsureTeamMarkerVisible(bool forceVisible)
+    {
+        if (teamPlacement == null)
+        {
+            Debug.LogWarning("❌ TeamPlacement is null in EnsureTeamMarkerVisible");
+            return;
+        }
+
+        var teamMarker = teamPlacement.GetTeamMarker();
+        if (teamMarker == null)
+        {
+            Debug.LogWarning("❌ Team marker is null - creating new marker");
+            // Force creation of a new marker if it doesn't exist
+            teamPlacement.PlaceTeamAt(teamPlacement.GetTeamPosition());
+            teamMarker = teamPlacement.GetTeamMarker();
+            if (teamMarker == null)
+            {
+                Debug.LogError("❌ Failed to create team marker!");
+                return;
+            }
+        }
+
+        var renderer = teamMarker.GetComponent<Renderer>();
+        if (renderer == null)
+        {
+            Debug.LogWarning("❌ Team marker has no Renderer component");
+            return;
+        }
+
+        Debug.Log($"🔧 Team marker status: Position={teamMarker.transform.position}, Active={teamMarker.activeInHierarchy}, RendererEnabled={renderer.enabled}");
+
+        if (forceVisible)
+        {
+            // Force marker to be visible and stop blinking during travel
+            teamMarker.SetActive(true);
+            renderer.enabled = true;
+
+            // Make the marker more visible by adjusting its properties
+            teamMarker.transform.localScale = Vector3.one * 2f; // Make it bigger
+
+            // Try to change material color to bright red for visibility
+            var material = renderer.material;
+            if (material != null)
+            {
+                material.color = Color.red;
+                if (material.HasProperty("_BaseColor"))
+                    material.SetColor("_BaseColor", Color.red);
+                if (material.HasProperty("_Color"))
+                    material.SetColor("_Color", Color.red);
+                Debug.Log($"🔴 Set team marker to bright red for visibility");
+            }
+
+            // Force position to be in front of everything
+            var pos = teamMarker.transform.position;
+            teamMarker.transform.position = new Vector3(pos.x, pos.y, -5f);
+
+            // Stop any blinking coroutines in SimpleTeamPlacement using reflection
+            try
+            {
+                var placementType = teamPlacement.GetType();
+                var stopCooroutinesMethod = placementType.GetMethod("StopAllCoroutines");
+                if (stopCooroutinesMethod != null)
+                {
+                    stopCooroutinesMethod.Invoke(teamPlacement, null);
+                    Debug.Log("✅ Stopped blinking coroutines");
+                }
+
+                // Set isBlinking to false using reflection
+                var isBlinkingField = placementType.GetField("isBlinking", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
+                if (isBlinkingField != null)
+                {
+                    isBlinkingField.SetValue(teamPlacement, false);
+                    Debug.Log("✅ Set isBlinking to false");
+                }
+            }
+            catch (System.Exception e)
+            {
+                Debug.LogWarning($"⚠️ Reflection failed: {e.Message}");
+            }
+
+            if (showDebugLogs)
+            {
+                Debug.Log($"👁️ Team marker forced visible for travel at {teamMarker.transform.position}");
+            }
+        }
+        else
+        {
+            // Restore normal blinking behavior after travel
+            try
+            {
+                var placementType = teamPlacement.GetType();
+                var enableBlinkingField = placementType.GetField("enableBlinking", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);
+
+                if (enableBlinkingField != null && (bool)enableBlinkingField.GetValue(teamPlacement))
+                {
+                    // Restart blinking using reflection
+                    var startBlinkingMethod = placementType.GetMethod("StartBlinking", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
+                    if (startBlinkingMethod != null)
+                    {
+                        startBlinkingMethod.Invoke(teamPlacement, null);
+                        if (showDebugLogs)
+                        {
+                            Debug.Log("✨ Team marker blinking restored after travel");
+                        }
+                    }
+                }
+            }
+            catch (System.Exception e)
+            {
+                Debug.LogWarning($"⚠️ Reflection failed during restore: {e.Message}");
+            }
+        }
+    }
+
+    /// <summary>
+    /// Utility methods for coordinate conversion
+    /// </summary>
+    private Vector3 GetMouseWorldPosition()
+    {
+        if (mapCamera == null)
+        {
+            if (showDebugLogs) Debug.LogWarning("❌ Map camera is null, trying to find Camera.main");
+            mapCamera = Camera.main;
+            if (mapCamera == null) return Vector3.zero;
+        }
+
+        Ray ray = mapCamera.ScreenPointToRay(Input.mousePosition);
+        if (showDebugLogs) Debug.Log($"📐 Raycast from camera: {ray.origin} direction: {ray.direction}");
+
+        // Try raycast first (if there are colliders)
+        if (Physics.Raycast(ray, out RaycastHit hit, 1000f))
+        {
+            if (showDebugLogs) Debug.Log($"🎯 Raycast hit: {hit.point} on {hit.collider.name}");
+            return hit.point;
+        }
+
+        // Fallback: use camera plane projection at Z=0 (map level)
+        Plane mapPlane = new Plane(Vector3.back, Vector3.zero); // Z=0 plane facing forward
+        if (mapPlane.Raycast(ray, out float distance))
+        {
+            Vector3 point = ray.GetPoint(distance);
+            if (showDebugLogs) Debug.Log($"📍 Plane intersection: {point}");
+            return point;
+        }
+
+        if (showDebugLogs) Debug.LogWarning("❌ No raycast hit and no plane intersection");
+        return Vector3.zero;
+    }
+
+    private Vector2Int WorldToTilePosition(Vector3 worldPos)
+    {
+        float tileSize = mapMaker?.mapVisualizer?.tileSize ?? 1f;
+        return new Vector2Int(
+            Mathf.RoundToInt(worldPos.x / tileSize),
+            Mathf.RoundToInt(worldPos.y / tileSize)
+        );
+    }
+
+    private Vector3 TileToWorldPosition(Vector2Int tilePos)
+    {
+        float tileSize = mapMaker?.mapVisualizer?.tileSize ?? 1f;
+        return new Vector3(
+            tilePos.x * tileSize,
+            tilePos.y * tileSize,
+            0f
+        );
+    }
+
+    /// <summary>
+    /// Debug method to show movement cost information
+    /// </summary>
+    private void ShowMovementCostInfo()
+    {
+        Debug.Log("=== MOVEMENT COST INFO ===");
+        Debug.Log("TERRAIN COSTS:");
+        Debug.Log($"  Plains: {plainsMovementCost}x");
+        Debug.Log($"  Forest: {forestMovementCost}x");
+        Debug.Log($"  Mountain: {mountainMovementCost}x");
+        Debug.Log($"  River Crossing: {riverCrossingCost}x (slow crossing)");
+        Debug.Log($"  Lake Swimming: {lakeCrossingCost}x (swimming)");
+        Debug.Log($"  Ocean Crossing: {oceanCrossingCost}x (very dangerous)");
+        Debug.Log("FEATURE COSTS:");
+        Debug.Log($"  Road: {roadMovementCost}x");
+        Debug.Log($"  Town/Village: {townMovementCost}x");
+        Debug.Log($"  Bridge: {bridgeMovementCost}x");
+        Debug.Log($"  Ferry: {ferryMovementCost}x (+ {ferryBaseCost} gold)");
+        Debug.Log($"  Tunnel (with torch): {tunnelWithTorchCost}x (+ {tunnelTorchCost} torches)");
+        Debug.Log($"  Tunnel (without torch): {tunnelWithoutTorchCost}x");
+        Debug.Log("CONTROLS:");
+        Debug.Log("  TAB: Cycle through route options");
+        Debug.Log("  ESC: Cancel travel planning (or cancel journey if traveling)");
+        Debug.Log("  C: Cancel journey while traveling");
+        Debug.Log("  F8: Toggle debug logs");
+        Debug.Log("TRAVEL CONTROLS (while traveling):");
+        Debug.Log("  >,→: Increase travel speed");
+        Debug.Log("  <,←: Decrease travel speed");
+        Debug.Log("  Space: Reset travel speed to normal");
+        Debug.Log("========================");
+    }
+
+    /// <summary>
+    /// Public getters for external systems
+    /// </summary>
+    public List<TravelRoute> GetAvailableRoutes() => availableRoutes;
+    public Vector2Int? GetPlannedDestination() => plannedDestination;
+    public bool IsTraveling() => isTraveling;
+    public bool CanCancelJourney() => isTraveling && currentTravelCoroutine != null;
+    public TravelRoute GetCurrentRoute() => currentRoute;
+
+    /// <summary>
+    /// Increases time speed for faster travel
+    /// </summary>
+    public void IncreaseTimeSpeed()
+    {
+        if (currentTimeSpeedIndex < timeSpeedOptions.Length - 1)
+        {
+            currentTimeSpeedIndex++;
+            timeMultiplier = timeSpeedOptions[currentTimeSpeedIndex];
+            Time.timeScale = timeMultiplier;
+            Debug.Log($"⏩ Time speed increased to {timeMultiplier}x");
+        }
+    }
+
+    /// <summary>
+    /// Decreases time speed
+    /// </summary>
+    public void DecreaseTimeSpeed()
+    {
+        if (currentTimeSpeedIndex > 0)
+        {
+            currentTimeSpeedIndex--;
+            timeMultiplier = timeSpeedOptions[currentTimeSpeedIndex];
+            Time.timeScale = timeMultiplier;
+            Debug.Log($"⏪ Time speed decreased to {timeMultiplier}x");
+        }
+    }
+
+    /// <summary>
+    /// Resets time speed to normal
+    /// </summary>
+    public void ResetTimeSpeed()
+    {
+        currentTimeSpeedIndex = 0;
+        timeMultiplier = timeSpeedOptions[0];
+        Time.timeScale = timeMultiplier;
+        Debug.Log($"⏸️ Time speed reset to {timeMultiplier}x");
+    }
+
+    /// <summary>
+    /// Gets current time speed multiplier
+    /// </summary>
+    public float GetTimeSpeed() => timeMultiplier;
+
+    /// <summary>
+    /// Methods for UI integration
+    /// </summary>
+    private bool IsTravelUIBlocking()
+    {
+        // Direct check instead of reflection since TravelUI is now available
+        return travelUI != null && travelUI.IsUIBlocking();
+    }
+
+    private void ShowTravelUIIfAvailable(Vector2Int destination, List<TravelRoute> routes)
+    {
+        // Direct call instead of reflection since TravelUI is now available
+        if (travelUI != null)
+        {
+            travelUI.ShowTravelUI(destination, routes);
+        }
+        else
+        {
+            Debug.LogWarning("⚠️ TravelUI not found, cannot show travel interface");
+        }
+    }
+
+    public void PlanTravelWithPreferences(Vector2Int destination, bool avoidFerries, bool avoidMountainPasses, bool preferRoads)
+    {
+        // Store preferences and recalculate routes
+        if (showDebugLogs)
+        {
+            Debug.Log($"🔄 Recalculating routes with preferences: AvoidFerries={avoidFerries}, AvoidMountains={avoidMountainPasses}, PreferRoads={preferRoads}");
+        }
+
+        // For now, just recalculate the same routes
+        // In a full implementation, these preferences would modify the pathfinding algorithm
+        PlanTravelTo(destination);
+    }
+
+    /// <summary>
+    /// Forces recalculation of routes and refreshes the UI - useful for debugging or preference changes
+    /// </summary>
+    [ContextMenu("DEBUG: Recalculate Routes")]
+    public void ForceRecalculateRoutes()
+    {
+        if (plannedDestination.HasValue)
+        {
+            Debug.Log($"🔄 TeamTravelSystem: Force recalculating routes to {plannedDestination.Value}");
+            Vector2Int currentPosition = teamPlacement.GetTeamPosition();
+
+            // Recalculate routes
+            CalculateRoutes(currentPosition, plannedDestination.Value);
+
+            // Refresh visualization
+            if (availableRoutes.Count > 0)
+            {
+                VisualizeAllRoutes(availableRoutes);
+            }
+
+            // Refresh UI if visible
+            if (travelUI != null && travelUI.IsVisible)
+            {
+                Debug.Log("🔄 TeamTravelSystem: Refreshing UI with recalculated routes");
+                travelUI.RefreshWithNewRoutes(availableRoutes);
+            }
+
+            Debug.Log($"✅ TeamTravelSystem: Routes recalculated - {availableRoutes.Count} routes available");
+        }
+        else
+        {
+            Debug.LogWarning("⚠️ TeamTravelSystem: No planned destination to recalculate routes for");
+        }
+    }
+
+    public void VisualizeSpecificRoute(TravelRoute route)
+    {
+        var callId = System.Guid.NewGuid().ToString("N")[..8]; // 8-character unique ID
+
+        if (showDebugLogs)
+        {
+            Debug.Log($"🎯 [{callId}] VisualizeSpecificRoute called with route: {route?.routeType}, availableRoutes count: {availableRoutes?.Count ?? 0}");
+        }
+
+        if (route == null)
+        {
+            Debug.LogError($"❌ [{callId}] Cannot visualize null route!");
+            return;
+        }
+
+        // If availableRoutes is empty, this might be because routes were cleared during UI interaction
+        // In this case, we can still visualize the single route that was passed to us
+        if (availableRoutes == null || availableRoutes.Count == 0)
+        {
+            Debug.LogWarning($"⚠️ [{callId}] availableRoutes is empty, visualizing single route {route.routeType}");
+
+            // Temporarily add this route to the list so the visualization system can work
+            if (availableRoutes == null) availableRoutes = new List<TravelRoute>();
+            availableRoutes.Add(route);
+
+            // Visualize just this route
+            ClearPathVisualization();
+            RenderSingleRoute(route, 0, true); // Render as selected
+
+            if (showDebugLogs)
+            {
+                Debug.Log($"🎨 [{callId}] Visualized single {route.routeType} route");
+            }
+            return;
+        }
+
+        // Normal path when we have available routes
+        // Verify the route is actually in our available routes
+        bool routeExists = availableRoutes.Contains(route);
+        if (!routeExists)
+        {
+            Debug.LogWarning($"⚠️ [{callId}] Selected route {route.routeType} is not in availableRoutes list!");
+            // Try to find a matching route by type
+            var matchingRoute = availableRoutes.FirstOrDefault(r => r?.routeType == route.routeType);
+            if (matchingRoute != null)
+            {
+                Debug.Log($"🔄 [{callId}] Found matching route by type, using that instead");
+                route = matchingRoute;
+            }
+            else
+            {
+                Debug.LogError($"❌ [{callId}] No matching route found, cannot visualize!");
+                return;
+            }
+        }
+
+        // Instead of clearing all routes, just highlight the selected one
+        HighlightSpecificRoute(route);
+        if (showDebugLogs)
+        {
+            Debug.Log($"🎨 [{callId}] Highlighted {route.routeType} route while keeping all routes visible");
+        }
+    }
+
+    /// <summary>
+    /// Highlights a specific route while keeping all routes visible (selected route on top)
+    /// </summary>
+    private void HighlightSpecificRoute(TravelRoute selectedRoute)
+    {
+        if (showDebugLogs)
+        {
+            Debug.Log($"🔍 HighlightSpecificRoute called with {selectedRoute?.routeType}, availableRoutes count: {availableRoutes.Count}");
+            for (int i = 0; i < availableRoutes.Count; i++)
+            {
+                Debug.Log($"  Route {i}: {availableRoutes[i]?.routeType} with {availableRoutes[i]?.path?.Count ?? 0} waypoints");
+            }
+        }
+
+        // Validate that we have routes to work with
+        if (availableRoutes == null || availableRoutes.Count == 0)
+        {
+            Debug.LogError("❌ HighlightSpecificRoute: No available routes to render!");
+            return;
+        }
+
+        if (selectedRoute == null)
+        {
+            Debug.LogError("❌ HighlightSpecificRoute: Selected route is null!");
+            return;
+        }
+
+        // Clear and re-render all routes with proper transparency and layering
+        ClearPathVisualization();
+
+        // Create a copy of routes to avoid any modification issues
+        var routesToRender = new List<TravelRoute>(availableRoutes);
+
+        if (showDebugLogs)
+        {
+            Debug.Log($"🎨 About to render {routesToRender.Count} routes");
+        }
+
+        // First render non-selected routes with transparency
+        for (int i = 0; i < routesToRender.Count; i++)
+        {
+            var route = routesToRender[i];
+            if (route == null)
+            {
+                Debug.LogWarning($"⚠️ Route {i} is null, skipping");
+                continue;
+            }
+
+            if (route.path == null || route.path.Count == 0)
+            {
+                Debug.LogWarning($"⚠️ Route {i} ({route.routeType}) has no path, skipping");
+                continue;
+            }
+
+            bool isSelected = (route == selectedRoute);
+
+            if (showDebugLogs)
+            {
+                Debug.Log($"🎨 Rendering route {i}: {route.routeType}, selected: {isSelected}, pathCount: {route.path.Count}");
+            }
+
+            // All routes are rendered, but with different emphasis
+            RenderSingleRoute(route, i, isSelected);
+        }
+
+        if (showDebugLogs)
+        {
+            string routeName = selectedRoute?.routeType == RouteType.RoadPreferred ? "Fastest" :
+                             selectedRoute?.routeType == RouteType.Standard ? "Shortest" : "Cheapest";
+            Debug.Log($"🔝 Highlighted {routeName} route - rendered {currentPathVisualizations.Count} route visualizations");
+        }
+    }
+
+    /// <summary>
+    /// Renders a single route with specified layering
+    /// </summary>
+    private void RenderSingleRoute(TravelRoute route, int layerIndex, bool isSelected)
+    {
+        if (route == null || route.path.Count == 0)
+        {
+            if (showDebugLogs)
+            {
+                Debug.LogWarning($"⚠️ RenderSingleRoute: Cannot render route - route is null: {route == null}, path count: {route?.path?.Count ?? 0}");
+            }
+            return;
+        }
+
+        if (showDebugLogs)
+        {
+            Debug.Log($"🎨 RenderSingleRoute: Creating visualization for {route.routeType}, selected: {isSelected}, layerIndex: {layerIndex}");
+        }
+
+        // Create path visualization
+        var pathObject = new GameObject($"TravelPath_{route.routeType}_{(isSelected ? "Selected" : "Normal")}");
+        var lineRenderer = pathObject.AddComponent<LineRenderer>();
+
+        if (showDebugLogs)
+        {
+            Debug.Log($"🔧 Created GameObject: {pathObject.name} with LineRenderer");
+        }
+
+        // Configure line renderer with a new material instance
+        var baseMaterial = pathLineMaterial ?? CreateDefaultPathMaterial();
+        var routeMaterial = new Material(baseMaterial);
+        var routeColor = GetRouteColor(route);
+
+        // Selected route gets full opacity, non-selected get good visibility
+        if (isSelected)
+        {
+            routeColor.a = 1.0f; // Full opacity for selected
+        }
+        else
+        {
+            routeColor.a = 0.6f; // Good visibility for non-selected (was 0.8f)
+        }
+
+        routeMaterial.color = routeColor;
+        lineRenderer.material = routeMaterial;
+
+        // Selected route gets thicker line, non-selected get thinner
+        float lineWidth = 1.0f;
+        int sortingOrder = 50;
+        switch (route.routeType)
+        {
+            case RouteType.RoadPreferred: // Fastest
+                lineWidth = isSelected ? 2.2f : 1.4f; // More dramatic difference
+                sortingOrder = isSelected ? 60 : 53;
+                break;
+            case RouteType.Standard: // Shortest
+                lineWidth = isSelected ? 2.0f : 1.2f; // More dramatic difference
+                sortingOrder = isSelected ? 59 : 52;
+                break;
+            case RouteType.Special: // Cheapest
+                lineWidth = isSelected ? 1.8f : 1.0f; // More dramatic difference
+                sortingOrder = isSelected ? 58 : 51;
+                break;
+        }
+
+        lineRenderer.startWidth = lineWidth;
+        lineRenderer.endWidth = lineWidth;
+        lineRenderer.positionCount = route.path.Count;
+        lineRenderer.useWorldSpace = true;
+
+        // Enhanced settings with proper layering
+        lineRenderer.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off;
+        lineRenderer.receiveShadows = false;
+        lineRenderer.alignment = LineAlignment.View;
+        lineRenderer.sortingLayerName = "Default";
+        lineRenderer.sortingOrder = sortingOrder;
+        lineRenderer.textureMode = LineTextureMode.Tile;
+
+        // Selected route gets priority Z-offset (closer to camera)
+        float zOffset = pathLineZOffset - (isSelected ? 1.0f : layerIndex * 0.2f);
+
+        // Set path points
+        for (int j = 0; j < route.path.Count; j++)
+        {
+            Vector3 worldPos = new Vector3(route.path[j].x, route.path[j].y, 0);
+
+            // Add slight offset for non-selected routes to prevent exact overlap
+            if (!isSelected)
+            {
+                float offsetAmount = layerIndex * 0.02f;
+                worldPos.x += Mathf.Sin(j + layerIndex) * offsetAmount;
+                worldPos.y += Mathf.Cos(j + layerIndex) * offsetAmount;
+            }
+
+            worldPos.z = zOffset;
+            lineRenderer.SetPosition(j, worldPos);
+        }
+
+        currentPathVisualizations.Add(pathObject);
+
+        if (showDebugLogs)
+        {
+            string routeName = route.routeType == RouteType.RoadPreferred ? "Fastest" :
+                             route.routeType == RouteType.Standard ? "Shortest" : "Cheapest";
+            Debug.Log($"✅ Successfully rendered {routeName} route: selected={isSelected}, width={lineWidth}, sorting={sortingOrder}, z-offset={zOffset}");
+            Debug.Log($"📊 Total visualizations now: {currentPathVisualizations.Count}");
+        }
+    }
+
+    public void HideTravelUI()
+    {
+        // Direct call instead of reflection since TravelUI is now available
+        if (travelUI != null)
+        {
+            travelUI.HideTravelPanel();
+        }
+    }
+}
+
+/// <summary>
+/// Represents different types of routes with GPS-style optimization goals
+/// </summary>
+public enum RouteType
+{
+    Standard,      // Shortest path (minimal distance/waypoints)
+    RoadPreferred, // Fastest path (heavily prefers roads and fast terrain)
+    Special        // Cheapest/Direct path (avoids special costs, takes more direct routes)
+}
+
+/// <summary>
+/// Represents a complete travel route with all associated costs and information
+/// </summary>
+[System.Serializable]
+public class TravelRoute
+{
+    public RouteType routeType;
+    public List<Vector2Int> path;
+    public float totalCost;
+    public float totalDistance;
+    public float estimatedTime;
+    public Dictionary<string, int> specialCosts; // Special costs like ferry fees, torch usage
+}
+
+/// <summary>
+/// Node used for A* pathfinding
+/// </summary>
+public class PathNode
+{
+    public Vector2Int position;
+    public float gCost; // Distance from starting node
+    public float hCost; // Heuristic distance to target
+    public float fCost => gCost + hCost;
+    public PathNode parent;
+}

+ 264 - 0
Assets/Scripts/Map/TravelSystemSetup.cs

@@ -0,0 +1,264 @@
+using UnityEngine;
+using UnityEngine.UIElements;
+
+/// <summary>
+/// Setup script to configure the new travel system in the map scene.
+/// This script automatically sets up the travel system components and ensures proper integration.
+/// </summary>
+public class TravelSystemSetup : MonoBehaviour
+{
+    [Header("Setup Options")]
+    public bool autoSetupOnStart = true;
+    public bool showDebugLogs = true;
+
+    [Header("Travel System Settings")]
+    [Range(0.1f, 5f)]
+    public float plainsMovementCost = 1f;
+    [Range(0.1f, 5f)]
+    public float forestMovementCost = 2f;
+    [Range(0.1f, 5f)]
+    public float mountainMovementCost = 4f;
+    [Range(0.1f, 2f)]
+    public float roadMovementCost = 0.5f;
+    [Range(0.1f, 2f)]
+    public float townMovementCost = 0.1f;
+
+    [Header("Visual Settings")]
+    public Material pathLineMaterial;
+    public Color standardPathColor = Color.blue;
+    public Color expensivePathColor = Color.red;
+    [Range(0.1f, 1f)]
+    public float pathLineWidth = 0.2f;
+
+    void Start()
+    {
+        if (autoSetupOnStart)
+        {
+            SetupTravelSystem();
+        }
+    }
+
+    [ContextMenu("Setup Travel System")]
+    public void SetupTravelSystem()
+    {
+        if (showDebugLogs)
+        {
+            Debug.Log("🔧 Setting up Travel System...");
+        }
+
+        // 1. Create TeamTravelSystem if it doesn't exist
+        SetupTeamTravelSystem();
+
+        // 2. Setup TravelUIController if UI exists
+        SetupTravelUIController();
+
+        // 2.5. Setup TravelUI component
+        SetupTravelUIComponent();
+
+        // 3. Verify SimpleTeamPlacement integration
+        VerifyTeamPlacementIntegration();
+
+        if (showDebugLogs)
+        {
+            Debug.Log("✅ Travel System setup complete!");
+        }
+    }
+
+    private void SetupTeamTravelSystem()
+    {
+        var existingTravelSystem = FindFirstObjectByType<TeamTravelSystem>();
+
+        if (existingTravelSystem == null)
+        {
+            // Create new travel system
+            GameObject travelSystemObj = new GameObject("TeamTravelSystem");
+            var travelSystem = travelSystemObj.AddComponent<TeamTravelSystem>();
+
+            // Apply settings
+            travelSystem.plainsMovementCost = plainsMovementCost;
+            travelSystem.forestMovementCost = forestMovementCost;
+            travelSystem.mountainMovementCost = mountainMovementCost;
+            travelSystem.roadMovementCost = roadMovementCost;
+            travelSystem.townMovementCost = townMovementCost;
+            travelSystem.pathLineMaterial = pathLineMaterial;
+            travelSystem.standardPathColor = standardPathColor;
+            travelSystem.expensivePathColor = expensivePathColor;
+            travelSystem.pathLineWidth = pathLineWidth;
+            travelSystem.showDebugLogs = showDebugLogs;
+
+            if (showDebugLogs)
+            {
+                Debug.Log("📦 Created TeamTravelSystem component");
+            }
+        }
+        else
+        {
+            if (showDebugLogs)
+            {
+                Debug.Log("✅ TeamTravelSystem already exists");
+            }
+        }
+    }
+
+    private void SetupTravelUIController()
+    {
+        // Look for UI GameObject
+        GameObject uiGameObject = GameObject.Find("UI");
+        if (uiGameObject == null)
+        {
+            if (showDebugLogs)
+            {
+                Debug.Log("⚠️ No UI GameObject found - TravelUIController not setup");
+            }
+            return;
+        }
+
+        var existingUIController = uiGameObject.GetComponent<TravelUIController>();
+
+        if (existingUIController == null)
+        {
+            // Add TravelUIController to UI GameObject
+            var uiController = uiGameObject.AddComponent<TravelUIController>();
+            uiController.showDebugLogs = showDebugLogs;
+
+            if (showDebugLogs)
+            {
+                Debug.Log("📦 Added TravelUIController to UI GameObject");
+            }
+        }
+        else
+        {
+            if (showDebugLogs)
+            {
+                Debug.Log("✅ TravelUIController already exists");
+            }
+        }
+    }
+
+    /// <summary>
+    /// Sets up the TravelUI component to handle the travel interface
+    /// </summary>
+    private void SetupTravelUIComponent()
+    {
+        // Check if TravelUI exists
+        var travelUI = FindFirstObjectByType<TravelUI>();
+        if (travelUI == null)
+        {
+            // Create TravelUI GameObject
+            GameObject travelUIGameObject = new GameObject("TravelUI");
+            var uiDocument = travelUIGameObject.AddComponent<UIDocument>();
+            var travelUIComponent = travelUIGameObject.AddComponent<TravelUI>();
+            travelUIComponent.uiDocument = uiDocument;
+
+            // Try to load and assign the TravelUI.uxml file
+            var travelUIAsset = Resources.Load<VisualTreeAsset>("UI/Map/TravelUI");
+            if (travelUIAsset != null)
+            {
+                uiDocument.visualTreeAsset = travelUIAsset;
+                travelUIComponent.travelUIAsset = travelUIAsset;
+                if (showDebugLogs)
+                {
+                    Debug.Log("✅ Assigned TravelUI.uxml to new TravelUI component");
+                }
+            }
+            else
+            {
+                Debug.LogWarning("⚠️ Could not find TravelUI.uxml in Resources/UI/Map/");
+            }
+
+            if (showDebugLogs)
+            {
+                Debug.Log("📦 Created TravelUI GameObject with component");
+            }
+        }
+        else
+        {
+            // Ensure existing TravelUI has proper UXML assigned
+            var uiDocument = travelUI.uiDocument;
+            if (uiDocument != null && (uiDocument.visualTreeAsset == null || travelUI.travelUIAsset == null))
+            {
+                var travelUIAsset = Resources.Load<VisualTreeAsset>("UI/Map/TravelUI");
+                if (travelUIAsset != null)
+                {
+                    uiDocument.visualTreeAsset = travelUIAsset;
+                    travelUI.travelUIAsset = travelUIAsset;
+                    if (showDebugLogs)
+                    {
+                        Debug.Log("✅ Assigned TravelUI.uxml to existing TravelUI component");
+                    }
+                }
+            }
+
+            if (showDebugLogs)
+            {
+                Debug.Log("✅ TravelUI component already exists and is properly configured");
+            }
+        }
+    }
+
+    private void VerifyTeamPlacementIntegration()
+    {
+        var teamPlacement = FindFirstObjectByType<SimpleTeamPlacement>();
+
+        if (teamPlacement == null)
+        {
+            if (showDebugLogs)
+            {
+                Debug.LogWarning("⚠️ SimpleTeamPlacement not found - travel system may not work properly");
+            }
+            return;
+        }
+
+        if (showDebugLogs)
+        {
+            Debug.Log("✅ SimpleTeamPlacement found and ready for integration");
+        }
+    }
+
+    [ContextMenu("Show Travel System Status")]
+    public void ShowTravelSystemStatus()
+    {
+        Debug.Log("=== TRAVEL SYSTEM STATUS ===");
+
+        var travelSystem = FindFirstObjectByType<TeamTravelSystem>();
+        Debug.Log($"TeamTravelSystem: {(travelSystem != null ? "✅ Found" : "❌ Missing")}");
+
+        var uiController = FindFirstObjectByType<TravelUIController>();
+        Debug.Log($"TravelUIController: {(uiController != null ? "✅ Found" : "❌ Missing")}");
+
+        var teamPlacement = FindFirstObjectByType<SimpleTeamPlacement>();
+        Debug.Log($"SimpleTeamPlacement: {(teamPlacement != null ? "✅ Found" : "❌ Missing")}");
+
+        var mapMaker = FindFirstObjectByType<MapMaker2>();
+        Debug.Log($"MapMaker2: {(mapMaker != null ? "✅ Found" : "❌ Missing")}");
+
+        Debug.Log("===========================");
+    }
+
+    [ContextMenu("Test Travel Planning")]
+    public void TestTravelPlanning()
+    {
+        var travelSystem = FindFirstObjectByType<TeamTravelSystem>();
+        var teamPlacement = FindFirstObjectByType<SimpleTeamPlacement>();
+
+        if (travelSystem == null || teamPlacement == null)
+        {
+            Debug.LogError("❌ Cannot test travel planning - missing components");
+            return;
+        }
+
+        if (!teamPlacement.IsTeamPlaced())
+        {
+            Debug.LogError("❌ Cannot test travel planning - team not placed");
+            return;
+        }
+
+        // Plan travel to a random nearby position
+        Vector2Int currentPos = teamPlacement.GetTeamPosition();
+        Vector2Int testDestination = new Vector2Int(currentPos.x + 10, currentPos.y + 10);
+
+        travelSystem.PlanTravelTo(testDestination);
+
+        Debug.Log($"🧪 Test travel planning from {currentPos} to {testDestination}");
+    }
+}

+ 395 - 0
Assets/Scripts/Map/TravelUIController.cs

@@ -0,0 +1,395 @@
+using UnityEngine;
+using UnityEngine.UIElements;
+using System.Linq;
+
+/// <summary>
+/// Controls the travel UI and integrates with TeamTravelSystem for route planning and execution.
+/// Uses the existing travel UI elements from MapWithTravelUI.uxml
+/// </summary>
+[RequireComponent(typeof(UIDocument))]
+public class TravelUIController : MonoBehaviour
+{
+    [Header("UI References")]
+    public UIDocument uiDocument;
+
+    [Header("Settings")]
+    public bool showDebugLogs = false;
+
+    // UI Elements
+    private VisualElement travelContainer;
+    private VisualElement travelPanel;
+    private Button closeButton;
+    private Label distanceLabel;
+    private Label timeLabel;
+    private Label specialCostsLabel;
+    private Button startTravelButton;
+
+    // Route selection (if available)
+    private VisualElement routeOptionsContainer;
+    private RadioButtonGroup routeSelection;
+
+    // System references
+    private TeamTravelSystem travelSystem;
+    private SimpleTeamPlacement teamPlacement;
+
+    // Current state
+    private TravelRoute selectedRoute;
+    private bool isUIVisible = false;
+
+    void Awake()
+    {
+        if (uiDocument == null)
+            uiDocument = GetComponent<UIDocument>();
+    }
+
+    void Start()
+    {
+        // Find system references
+        travelSystem = TeamTravelSystem.Instance;
+        teamPlacement = SimpleTeamPlacement.Instance;
+
+        if (travelSystem == null)
+        {
+            Debug.LogError("❌ TeamTravelSystem not found! TravelUIController requires it.");
+            return;
+        }
+
+        // Setup UI
+        SetupUIElements();
+        SetupEventHandlers();
+
+        // Hide UI initially
+        HideTravelUI();
+    }
+
+    void Update()
+    {
+        // Monitor for travel planning
+        if (travelSystem != null && travelSystem.GetPlannedDestination().HasValue && !isUIVisible)
+        {
+            ShowTravelUI();
+        }
+        else if (travelSystem != null && !travelSystem.GetPlannedDestination().HasValue && isUIVisible)
+        {
+            HideTravelUI();
+        }
+    }
+
+    /// <summary>
+    /// Sets up references to UI elements
+    /// </summary>
+    private void SetupUIElements()
+    {
+        if (uiDocument?.rootVisualElement == null)
+        {
+            Debug.LogError("❌ UIDocument root not available");
+            return;
+        }
+
+        var root = uiDocument.rootVisualElement;
+
+        // Find main UI elements
+        travelContainer = root.Q("TravelContainer");
+        travelPanel = root.Q("TravelPanel");
+        closeButton = root.Q<Button>("CloseButton");
+        distanceLabel = root.Q<Label>("DistanceLabel");
+        timeLabel = root.Q<Label>("TimeLabel");
+        specialCostsLabel = root.Q<Label>("SpecialCostsLabel");
+        startTravelButton = root.Q<Button>("StartTravelButton");
+
+        // Optional route selection elements
+        routeOptionsContainer = root.Q("RouteOptions");
+        routeSelection = root.Q<RadioButtonGroup>("RouteSelection");
+    }
+
+    /// <summary>
+    /// Sets up event handlers for UI interactions
+    /// </summary>
+    private void SetupEventHandlers()
+    {
+        // Close button
+        if (closeButton != null)
+        {
+            closeButton.clicked += OnCloseButtonClicked;
+        }
+
+        // Start travel button
+        if (startTravelButton != null)
+        {
+            startTravelButton.clicked += OnStartTravelClicked;
+        }
+
+        // Route selection (if available)
+        if (routeSelection != null)
+        {
+            routeSelection.RegisterValueChangedCallback(OnRouteSelectionChanged);
+        }
+
+        if (showDebugLogs)
+        {
+
+        }
+    }
+
+    /// <summary>
+    /// Shows the travel UI and updates it with current route information
+    /// </summary>
+    public void ShowTravelUI()
+    {
+        if (travelContainer == null) return;
+
+        travelContainer.style.display = DisplayStyle.Flex;
+        isUIVisible = true;
+
+        // Update UI with current travel information
+        UpdateTravelInformation();
+
+        if (showDebugLogs)
+        {
+
+        }
+    }
+
+    /// <summary>
+    /// Hides the travel UI
+    /// </summary>
+    public void HideTravelUI()
+    {
+        if (travelContainer == null) return;
+
+        travelContainer.style.display = DisplayStyle.None;
+        isUIVisible = false;
+
+        if (showDebugLogs)
+        {
+
+        }
+    }
+
+    /// <summary>
+    /// Updates the travel information display with current route data
+    /// </summary>
+    private void UpdateTravelInformation()
+    {
+        if (travelSystem == null) return;
+
+        var routes = travelSystem.GetAvailableRoutes();
+        if (routes.Count == 0)
+        {
+            ShowNoRoutesMessage();
+            return;
+        }
+
+        // Select the best route by default (lowest cost)
+        selectedRoute = routes.OrderBy(r => r.totalCost).First();
+
+        // Update basic information
+        UpdateBasicRouteInfo(selectedRoute);
+
+        // Update route options if available
+        UpdateRouteOptions(routes);
+
+        // Update start button
+        UpdateStartButton(selectedRoute);
+    }
+
+    /// <summary>
+    /// Updates the basic route information display
+    /// </summary>
+    private void UpdateBasicRouteInfo(TravelRoute route)
+    {
+        if (distanceLabel != null)
+        {
+            distanceLabel.text = $"Distance: {route.totalDistance:F1} leagues";
+        }
+
+        if (timeLabel != null)
+        {
+            distanceLabel.text = $"Travel Time: {route.estimatedTime:F1} hours";
+        }
+
+        if (specialCostsLabel != null)
+        {
+            if (route.specialCosts.Count > 0)
+            {
+                var costStrings = route.specialCosts.Select(kvp => $"{kvp.Value} {kvp.Key}");
+                specialCostsLabel.text = $"Special Costs: {string.Join(", ", costStrings)}";
+                specialCostsLabel.style.color = new StyleColor(Color.yellow);
+            }
+            else
+            {
+                specialCostsLabel.text = "Special Costs: None";
+                specialCostsLabel.style.color = new StyleColor(Color.white);
+            }
+        }
+    }
+
+    /// <summary>
+    /// Updates route selection options if multiple routes are available
+    /// </summary>
+    private void UpdateRouteOptions(System.Collections.Generic.List<TravelRoute> routes)
+    {
+        if (routeOptionsContainer == null || routes.Count <= 1)
+        {
+            // Hide route options if not available or only one route
+            if (routeOptionsContainer != null)
+                routeOptionsContainer.style.display = DisplayStyle.None;
+            return;
+        }
+
+        routeOptionsContainer.style.display = DisplayStyle.Flex;
+
+        // TODO: Implement route selection UI if needed
+        // For now, we'll just use the best route automatically
+    }
+
+    /// <summary>
+    /// Updates the start travel button with appropriate text and state
+    /// </summary>
+    private void UpdateStartButton(TravelRoute route)
+    {
+        if (startTravelButton == null) return;
+
+        // Check if player can afford the route
+        bool canAfford = CanAffordRoute(route);
+
+        startTravelButton.SetEnabled(canAfford);
+
+        if (canAfford)
+        {
+            if (route.specialCosts.Count > 0)
+            {
+                var totalCost = route.specialCosts.Values.Sum();
+                startTravelButton.text = $"Start Journey ({totalCost} gold)";
+            }
+            else
+            {
+                startTravelButton.text = "Start Journey (Free)";
+            }
+        }
+        else
+        {
+            startTravelButton.text = "Insufficient Resources";
+        }
+    }
+
+    /// <summary>
+    /// Checks if the player can afford the selected route
+    /// </summary>
+    private bool CanAffordRoute(TravelRoute route)
+    {
+        // TODO: Implement player resource checking
+        // For now, assume player can always afford free routes
+        return route.specialCosts.Count == 0 || route.specialCosts.Values.Sum() <= 100; // Placeholder
+    }
+
+    /// <summary>
+    /// Shows a message when no routes are available
+    /// </summary>
+    private void ShowNoRoutesMessage()
+    {
+        if (distanceLabel != null)
+            distanceLabel.text = "Distance: No route available";
+
+        if (timeLabel != null)
+            timeLabel.text = "Travel Time: --";
+
+        if (specialCostsLabel != null)
+            specialCostsLabel.text = "Cannot reach destination";
+
+        if (startTravelButton != null)
+        {
+            startTravelButton.text = "No Route Available";
+            startTravelButton.SetEnabled(false);
+        }
+    }
+
+    /// <summary>
+    /// Event handler for close button
+    /// </summary>
+    private void OnCloseButtonClicked()
+    {
+        if (travelSystem != null)
+        {
+            travelSystem.CancelTravelPlanning();
+        }
+
+        HideTravelUI();
+
+        if (showDebugLogs)
+        {
+
+        }
+    }
+
+    /// <summary>
+    /// Event handler for start travel button
+    /// </summary>
+    private void OnStartTravelClicked()
+    {
+        if (selectedRoute == null || travelSystem == null)
+        {
+            Debug.LogWarning("Cannot start travel: no route selected or travel system unavailable");
+            return;
+        }
+
+        if (!CanAffordRoute(selectedRoute))
+        {
+            Debug.LogWarning("Cannot start travel: insufficient resources");
+            return;
+        }
+
+        // Start the travel
+        travelSystem.StartTravel(selectedRoute);
+
+        // Hide UI
+        HideTravelUI();
+
+        if (showDebugLogs)
+        {
+
+        }
+    }
+
+    /// <summary>
+    /// Event handler for route selection changes
+    /// </summary>
+    private void OnRouteSelectionChanged(ChangeEvent<int> evt)
+    {
+        if (travelSystem == null) return;
+
+        var routes = travelSystem.GetAvailableRoutes();
+        if (evt.newValue >= 0 && evt.newValue < routes.Count)
+        {
+            selectedRoute = routes[evt.newValue];
+            UpdateBasicRouteInfo(selectedRoute);
+            UpdateStartButton(selectedRoute);
+
+            if (showDebugLogs)
+            {
+
+            }
+        }
+    }
+
+    /// <summary>
+    /// Public methods for external control
+    /// </summary>
+    public bool IsUIVisible() => isUIVisible;
+    public TravelRoute GetSelectedRoute() => selectedRoute;
+
+    /// <summary>
+    /// Context menu methods for debugging
+    /// </summary>
+    [ContextMenu("Show Travel UI (Test)")]
+    public void TestShowTravelUI()
+    {
+        ShowTravelUI();
+    }
+
+    [ContextMenu("Hide Travel UI (Test)")]
+    public void TestHideTravelUI()
+    {
+        HideTravelUI();
+    }
+}

+ 188 - 0
Assets/Scripts/MapMaker2/Data/MapData.cs

@@ -0,0 +1,188 @@
+using System.Collections.Generic;
+using UnityEngine;
+using System.Linq;
+
+public class MapData
+{
+    public int Width { get; private set; }
+    public int Height { get; private set; }
+
+    private MapTile[,] tiles;
+    private List<Settlement> settlements;
+
+    public MapData(int width, int height)
+    {
+        Width = width;
+        Height = height;
+        tiles = new MapTile[width, height];
+        settlements = new List<Settlement>();
+
+        InitializeTiles();
+    }
+
+    private void InitializeTiles()
+    {
+        for (int x = 0; x < Width; x++)
+        {
+            for (int y = 0; y < Height; y++)
+            {
+                tiles[x, y] = new MapTile(x, y);
+            }
+        }
+    }
+
+    public MapTile GetTile(int x, int y)
+    {
+        if (IsValidPosition(x, y))
+            return tiles[x, y];
+        return null;
+    }
+
+    public void SetTile(int x, int y, MapTile tile)
+    {
+        if (IsValidPosition(x, y))
+            tiles[x, y] = tile;
+    }
+
+    public bool IsValidPosition(int x, int y)
+    {
+        return x >= 0 && x < Width && y >= 0 && y < Height;
+    }
+
+    public void ExpandMap(int newWidth, int newHeight)
+    {
+        MapTile[,] newTiles = new MapTile[newWidth, newHeight];
+
+        // Copy existing tiles
+        for (int x = 0; x < Width; x++)
+        {
+            for (int y = 0; y < Height; y++)
+            {
+                newTiles[x, y] = tiles[x, y];
+            }
+        }
+
+        // Initialize new tiles
+        for (int x = 0; x < newWidth; x++)
+        {
+            for (int y = 0; y < newHeight; y++)
+            {
+                if (newTiles[x, y] == null)
+                {
+                    newTiles[x, y] = new MapTile(x, y);
+                }
+            }
+        }
+
+        tiles = newTiles;
+        Width = newWidth;
+        Height = newHeight;
+    }
+
+    public void ExpandMapWithOffset(int newWidth, int newHeight, int offsetX, int offsetY)
+    {
+        MapTile[,] newTiles = new MapTile[newWidth, newHeight];
+
+        // Copy existing tiles with offset
+        for (int x = 0; x < Width; x++)
+        {
+            for (int y = 0; y < Height; y++)
+            {
+                int newX = x + offsetX;
+                int newY = y + offsetY;
+                if (newX >= 0 && newX < newWidth && newY >= 0 && newY < newHeight)
+                {
+                    newTiles[newX, newY] = tiles[x, y];
+                    // Update tile coordinates
+                    newTiles[newX, newY].x = newX;
+                    newTiles[newX, newY].y = newY;
+                }
+            }
+        }
+
+        // Initialize new tiles
+        for (int x = 0; x < newWidth; x++)
+        {
+            for (int y = 0; y < newHeight; y++)
+            {
+                if (newTiles[x, y] == null)
+                {
+                    newTiles[x, y] = new MapTile(x, y);
+                }
+            }
+        }
+
+        // Update settlements positions
+        foreach (var settlement in settlements)
+        {
+            settlement.position.x += offsetX;
+            settlement.position.y += offsetY;
+        }
+
+        tiles = newTiles;
+        Width = newWidth;
+        Height = newHeight;
+    }
+
+    public void AddSettlement(Settlement settlement)
+    {
+        settlements.Add(settlement);
+    }
+
+    public List<Settlement> GetTowns()
+    {
+        return settlements.Where(s => s.Type == SettlementType.Town).ToList();
+    }
+
+    public List<Settlement> GetVillages()
+    {
+        return settlements.Where(s => s.Type == SettlementType.Village).ToList();
+    }
+
+    public List<Vector2Int> GetNeighbors(int x, int y, bool includeDiagonals = false)
+    {
+        List<Vector2Int> neighbors = new List<Vector2Int>();
+
+        for (int dx = -1; dx <= 1; dx++)
+        {
+            for (int dy = -1; dy <= 1; dy++)
+            {
+                if (dx == 0 && dy == 0) continue;
+                if (!includeDiagonals && dx != 0 && dy != 0) continue;
+
+                int nx = x + dx;
+                int ny = y + dy;
+
+                if (IsValidPosition(nx, ny))
+                {
+                    neighbors.Add(new Vector2Int(nx, ny));
+                }
+            }
+        }
+
+        return neighbors;
+    }
+}
+
+[System.Serializable]
+public class Settlement
+{
+    public string name;
+    public SettlementType Type;
+    public Vector2Int position;
+    public List<Vector2Int> tiles;
+
+    public Settlement(string name, SettlementType type, Vector2Int position)
+    {
+        this.name = name;
+        this.Type = type;
+        this.position = position;
+        this.tiles = new List<Vector2Int>();
+    }
+}
+
+public enum SettlementType
+{
+    Town,
+    Village
+}

+ 23 - 0
Assets/Scripts/MapMaker2/Data/TerrainType.cs

@@ -0,0 +1,23 @@
+public enum TerrainType
+{
+    Plains,
+    Forest,
+    Ocean,
+    Lake,
+    Shore,
+    River,
+    Mountain,
+    ForestRiver // Hybrid tile: River flowing through forest
+}
+
+public enum FeatureType
+{
+    None,
+    Road,
+    Bridge,
+    Tunnel,
+    Harbour,
+    Ferry,
+    Town,
+    Village
+}

+ 36 - 0
Assets/Scripts/MapMaker2/Data/Tile.cs

@@ -0,0 +1,36 @@
+using UnityEngine;
+
+[System.Serializable]
+public class MapTile
+{
+    public TerrainType terrainType;
+    public FeatureType featureType;
+    public int x, y;
+    public float height;
+    public bool isWalkable;
+    public string name; // For towns/villages
+
+    public MapTile(int x, int y)
+    {
+        this.x = x;
+        this.y = y;
+        this.terrainType = TerrainType.Plains;
+        this.featureType = FeatureType.None;
+        this.height = 0f;
+        this.isWalkable = true;
+        this.name = string.Empty;
+    }
+
+    public bool IsWater()
+    {
+        return terrainType == TerrainType.Ocean ||
+               terrainType == TerrainType.Lake ||
+               terrainType == TerrainType.River;
+    }
+
+    public bool CanBuildOn()
+    {
+        return terrainType == TerrainType.Plains &&
+               featureType == FeatureType.None;
+    }
+}

+ 1041 - 0
Assets/Scripts/MapMaker2/Expansion/ExpansionManager.cs

@@ -0,0 +1,1041 @@
+using UnityEngine;
+using System.Collections.Generic;
+
+public class ExpansionManager
+{
+    private MapMaker2 mapMaker;
+    private NoiseGenerator noiseGenerator;
+    private System.Random random;
+
+    public ExpansionManager(MapMaker2 mapMaker)
+    {
+        this.mapMaker = mapMaker;
+        this.noiseGenerator = new NoiseGenerator();
+        this.random = new System.Random(mapMaker.seed);
+    }
+
+    public bool ShouldExpand(Vector2 playerPosition, MapData mapData)
+    {
+        float distanceThreshold = mapMaker.playerDistanceThreshold;
+
+        // Check distance to each edge
+        float distToLeft = playerPosition.x;
+        float distToRight = mapData.Width - playerPosition.x;
+        float distToTop = mapData.Height - playerPosition.y;
+        float distToBottom = playerPosition.y;
+
+        bool shouldExpand = distToLeft < distanceThreshold ||
+                           distToRight < distanceThreshold ||
+                           distToTop < distanceThreshold ||
+                           distToBottom < distanceThreshold;
+
+        if (shouldExpand)
+        {
+            Debug.Log($"Expansion needed! Threshold: {distanceThreshold}");
+            Debug.Log($"Distances - Left: {distToLeft}, Right: {distToRight}, Top: {distToTop}, Bottom: {distToBottom}");
+        }
+
+        return shouldExpand;
+    }
+
+    public void ExpandMap(MapData mapData, Vector2 playerPosition, int expansionSize)
+    {
+        float distanceThreshold = mapMaker.playerDistanceThreshold;
+
+        // Determine expansion directions
+        bool expandLeft = playerPosition.x < distanceThreshold;
+        bool expandRight = mapData.Width - playerPosition.x < distanceThreshold;
+        bool expandUp = mapData.Height - playerPosition.y < distanceThreshold;
+        bool expandDown = playerPosition.y < distanceThreshold;
+
+        // Calculate new dimensions
+        int leftExpansion = expandLeft ? expansionSize : 0;
+        int rightExpansion = expandRight ? expansionSize : 0;
+        int upExpansion = expandUp ? expansionSize : 0;
+        int downExpansion = expandDown ? expansionSize : 0;
+
+        int newWidth = mapData.Width + leftExpansion + rightExpansion;
+        int newHeight = mapData.Height + upExpansion + downExpansion;
+
+        // Store old dimensions and expansion info
+        ExpansionInfo expansionInfo = new ExpansionInfo
+        {
+            oldWidth = mapData.Width,
+            oldHeight = mapData.Height,
+            newWidth = newWidth,
+            newHeight = newHeight,
+            leftExpansion = leftExpansion,
+            rightExpansion = rightExpansion,
+            upExpansion = upExpansion,
+            downExpansion = downExpansion
+        };
+
+        // Expand the map with offset handling
+        ExpandMapWithOffset(mapData, expansionInfo);
+
+        // Generate logical terrain and features for new areas using enhanced system
+        GenerateEnhancedExpansion(mapData, expansionInfo);
+
+        Debug.Log($"Map expanded from {expansionInfo.oldWidth}x{expansionInfo.oldHeight} to {newWidth}x{newHeight}");
+        Debug.Log($"Expansion directions - Left: {leftExpansion}, Right: {rightExpansion}, Up: {upExpansion}, Down: {downExpansion}");
+    }
+
+    private struct ExpansionInfo
+    {
+        public int oldWidth, oldHeight;
+        public int newWidth, newHeight;
+        public int leftExpansion, rightExpansion;
+        public int upExpansion, downExpansion;
+    }
+
+    private void ExpandMapWithOffset(MapData mapData, ExpansionInfo info)
+    {
+        mapData.ExpandMapWithOffset(info.newWidth, info.newHeight, info.leftExpansion, info.downExpansion);
+    }
+
+    private void GenerateEnhancedExpansion(MapData mapData, ExpansionInfo info)
+    {
+        // Enhanced multi-pass terrain generation for natural-looking results
+        GenerateNaturalTerrain(mapData, info);
+        SmoothTerrainTransitions(mapData, info);
+        GenerateNaturalFeatures(mapData, info);
+        GenerateSettlementsAndRoads(mapData, info);
+    }
+
+    private void GenerateNaturalTerrain(MapData mapData, ExpansionInfo info)
+    {
+        // Generate each expansion region with proper biome continuity
+        if (info.leftExpansion > 0)
+            GenerateTerrainRegion(mapData, 0, 0, info.leftExpansion, info.newHeight, ExpansionDirection.Left, info);
+
+        if (info.rightExpansion > 0)
+        {
+            int startX = info.leftExpansion + info.oldWidth;
+            GenerateTerrainRegion(mapData, startX, 0, info.rightExpansion, info.newHeight, ExpansionDirection.Right, info);
+        }
+
+        if (info.downExpansion > 0)
+            GenerateTerrainRegion(mapData, info.leftExpansion, 0, info.oldWidth, info.downExpansion, ExpansionDirection.Down, info);
+
+        if (info.upExpansion > 0)
+        {
+            int startY = info.downExpansion + info.oldHeight;
+            GenerateTerrainRegion(mapData, info.leftExpansion, startY, info.oldWidth, info.upExpansion, ExpansionDirection.Up, info);
+        }
+    }
+
+    private enum ExpansionDirection { Left, Right, Up, Down }
+
+    private void GenerateTerrainRegion(MapData mapData, int startX, int startY, int width, int height, ExpansionDirection direction, ExpansionInfo info)
+    {
+        for (int x = startX; x < startX + width; x++)
+        {
+            for (int y = startY; y < startY + height; y++)
+            {
+                GenerateEnhancedTerrain(mapData, x, y, direction, info);
+            }
+        }
+    }
+
+    private void GenerateEnhancedTerrain(MapData mapData, int x, int y, ExpansionDirection direction, ExpansionInfo info)
+    {
+        MapTile tile = mapData.GetTile(x, y);
+        if (tile == null) return;
+
+        // Get reference context from existing terrain
+        List<MapTile> referenceTiles = GetExtendedReferenceTiles(mapData, x, y, direction, info);
+
+        // Generate realistic height with proper continuity
+        float height = GenerateRealisticHeight(x, y, referenceTiles, direction, info);
+        tile.height = height;
+
+        // Determine terrain with natural biome rules
+        TerrainType terrainType = DetermineRealisticTerrain(referenceTiles, height, x, y, direction, info);
+        tile.terrainType = terrainType;
+
+        tile.isWalkable = terrainType != TerrainType.Mountain && terrainType != TerrainType.Ocean;
+    }
+
+    private List<MapTile> GetExtendedReferenceTiles(MapData mapData, int x, int y, ExpansionDirection direction, ExpansionInfo info)
+    {
+        List<MapTile> referenceTiles = new List<MapTile>();
+        int range = 4; // Wider reference for better continuity
+
+        switch (direction)
+        {
+            case ExpansionDirection.Left:
+                for (int refY = y - range; refY <= y + range; refY++)
+                {
+                    int refX = info.leftExpansion;
+                    if (mapData.IsValidPosition(refX, refY))
+                        referenceTiles.Add(mapData.GetTile(refX, refY));
+                }
+                break;
+
+            case ExpansionDirection.Right:
+                for (int refY = y - range; refY <= y + range; refY++)
+                {
+                    int refX = info.leftExpansion + info.oldWidth - 1;
+                    if (mapData.IsValidPosition(refX, refY))
+                        referenceTiles.Add(mapData.GetTile(refX, refY));
+                }
+                break;
+
+            case ExpansionDirection.Up:
+                for (int refX = x - range; refX <= x + range; refX++)
+                {
+                    int refY = info.downExpansion + info.oldHeight - 1;
+                    if (mapData.IsValidPosition(refX, refY))
+                        referenceTiles.Add(mapData.GetTile(refX, refY));
+                }
+                break;
+
+            case ExpansionDirection.Down:
+                for (int refX = x - range; refX <= x + range; refX++)
+                {
+                    int refY = info.downExpansion;
+                    if (mapData.IsValidPosition(refX, refY))
+                        referenceTiles.Add(mapData.GetTile(refX, refY));
+                }
+                break;
+        }
+
+        return referenceTiles;
+    }
+
+    private float GenerateRealisticHeight(int x, int y, List<MapTile> referenceTiles, ExpansionDirection direction, ExpansionInfo info)
+    {
+        float distanceFromBoundary = GetDistanceFromBoundary(x, y, direction, info);
+
+        // For very close tiles, copy heights directly
+        if (distanceFromBoundary < 6f)
+        {
+            Vector2Int sourcePos = GetCorrespondingOriginalTile(x, y, direction, info);
+            if (IsInOriginalArea(sourcePos.x, sourcePos.y, info))
+            {
+                MapTile sourceTile = mapMaker.GetMapData().GetTile(sourcePos.x, sourcePos.y);
+                if (sourceTile != null)
+                {
+                    // Add very small noise to avoid perfect repetition
+                    float noise = noiseGenerator.GetNoise(x, y, 0.1f) * 0.05f;
+                    return sourceTile.height + noise;
+                }
+            }
+        }
+
+        // For farther tiles, use blended approach
+        float height = 0f;
+        height += noiseGenerator.GetNoise(x, y, 0.02f) * 0.6f;  // Large landforms
+        height += noiseGenerator.GetNoise(x, y, 0.06f) * 0.25f; // Medium features  
+        height += noiseGenerator.GetNoise(x, y, 0.12f) * 0.1f;  // Small details
+        height += noiseGenerator.GetNoise(x, y, 0.25f) * 0.05f; // Fine noise
+
+        // Strong blending with reference heights
+        if (referenceTiles.Count > 0)
+        {
+            float refAverage = 0f;
+            foreach (var tile in referenceTiles)
+                refAverage += tile.height;
+            refAverage /= referenceTiles.Count;
+
+            float blendFactor = Mathf.Lerp(0.8f, 0.2f, Mathf.Clamp01(distanceFromBoundary / 15f));
+            height = Mathf.Lerp(height, refAverage, blendFactor);
+        }
+
+        return height;
+    }
+
+    private float GetDistanceFromBoundary(int x, int y, ExpansionDirection direction, ExpansionInfo info)
+    {
+        switch (direction)
+        {
+            case ExpansionDirection.Left:
+                return x;
+            case ExpansionDirection.Right:
+                return (info.newWidth - 1) - x;
+            case ExpansionDirection.Down:
+                return y;
+            case ExpansionDirection.Up:
+                return (info.newHeight - 1) - y;
+            default:
+                return 10f;
+        }
+    }
+
+    private TerrainType DetermineRealisticTerrain(List<MapTile> referenceTiles, float height, int x, int y, ExpansionDirection direction, ExpansionInfo info)
+    {
+        // Calculate distance from boundary for continuity strength
+        float distanceFromBoundary = GetDistanceFromBoundary(x, y, direction, info);
+
+        // For the first 8 tiles from boundary, use direct terrain copying
+        if (distanceFromBoundary < 8f)
+        {
+            return CopyNearestTerrain(x, y, direction, info);
+        }
+        else
+        {
+            // For further tiles, still use heavy continuity
+            Dictionary<TerrainType, float> biomeInfluence = AnalyzeBiomeInfluence(referenceTiles);
+            TerrainType dominantBiome = GetDominantBiome(biomeInfluence);
+            return GenerateContinuousTerrain(dominantBiome, height, x, y);
+        }
+    }
+
+    private TerrainType CopyNearestTerrain(int x, int y, ExpansionDirection direction, ExpansionInfo info)
+    {
+        // Find the exact corresponding tile in the original map and copy its terrain
+        Vector2Int sourcePos = GetCorrespondingOriginalTile(x, y, direction, info);
+
+        if (IsInOriginalArea(sourcePos.x, sourcePos.y, info))
+        {
+            MapTile sourceTile = mapMaker.GetMapData().GetTile(sourcePos.x, sourcePos.y);
+            if (sourceTile != null)
+            {
+                return sourceTile.terrainType;
+            }
+        }
+
+        // Fallback to nearest boundary tile
+        return GetNearestBoundaryTerrain(x, y, direction, info);
+    }
+
+    private Vector2Int GetCorrespondingOriginalTile(int x, int y, ExpansionDirection direction, ExpansionInfo info)
+    {
+        switch (direction)
+        {
+            case ExpansionDirection.Left:
+                // Mirror from the left boundary
+                int offsetFromLeft = x;
+                return new Vector2Int(info.leftExpansion + offsetFromLeft, y);
+
+            case ExpansionDirection.Right:
+                // Mirror from the right boundary
+                int offsetFromRight = x - (info.leftExpansion + info.oldWidth);
+                return new Vector2Int(info.leftExpansion + info.oldWidth - 1 - offsetFromRight, y);
+
+            case ExpansionDirection.Down:
+                // Mirror from the bottom boundary
+                int offsetFromBottom = y;
+                return new Vector2Int(x, info.downExpansion + offsetFromBottom);
+
+            case ExpansionDirection.Up:
+                // Mirror from the top boundary
+                int offsetFromTop = y - (info.downExpansion + info.oldHeight);
+                return new Vector2Int(x, info.downExpansion + info.oldHeight - 1 - offsetFromTop);
+
+            default:
+                return new Vector2Int(x, y);
+        }
+    }
+
+    private TerrainType GetNearestBoundaryTerrain(int x, int y, ExpansionDirection direction, ExpansionInfo info)
+    {
+        Vector2Int boundaryPos = Vector2Int.zero;
+
+        switch (direction)
+        {
+            case ExpansionDirection.Left:
+                boundaryPos = new Vector2Int(info.leftExpansion, y);
+                break;
+            case ExpansionDirection.Right:
+                boundaryPos = new Vector2Int(info.leftExpansion + info.oldWidth - 1, y);
+                break;
+            case ExpansionDirection.Down:
+                boundaryPos = new Vector2Int(x, info.downExpansion);
+                break;
+            case ExpansionDirection.Up:
+                boundaryPos = new Vector2Int(x, info.downExpansion + info.oldHeight - 1);
+                break;
+        }
+
+        if (IsInOriginalArea(boundaryPos.x, boundaryPos.y, info))
+        {
+            MapTile boundaryTile = mapMaker.GetMapData().GetTile(boundaryPos.x, boundaryPos.y);
+            if (boundaryTile != null)
+                return boundaryTile.terrainType;
+        }
+
+        return TerrainType.Plains;
+    }
+
+    private Dictionary<TerrainType, float> AnalyzeBiomeInfluence(List<MapTile> referenceTiles)
+    {
+        Dictionary<TerrainType, float> influence = new Dictionary<TerrainType, float>();
+
+        foreach (var tile in referenceTiles)
+        {
+            float weight = GetBiomeWeight(tile.terrainType);
+            if (influence.ContainsKey(tile.terrainType))
+                influence[tile.terrainType] += weight;
+            else
+                influence[tile.terrainType] = weight;
+        }
+
+        return influence;
+    }
+
+    private float GetBiomeWeight(TerrainType terrain)
+    {
+        // Some terrain types are more "influential" for expansion
+        switch (terrain)
+        {
+            case TerrainType.Ocean: return 4.0f; // Much stronger ocean influence
+            case TerrainType.Mountain: return 2.5f;
+            case TerrainType.Lake: return 2.0f; // Stronger water influence  
+            case TerrainType.Forest: return 1.5f;
+            case TerrainType.Shore: return 1.5f; // Stronger shore influence
+            case TerrainType.River: return 1.2f;
+            default: return 0.8f;
+        }
+    }
+
+    private TerrainType GetDominantBiome(Dictionary<TerrainType, float> influence)
+    {
+        if (influence.Count == 0) return TerrainType.Plains;
+
+        TerrainType dominant = TerrainType.Plains;
+        float maxInfluence = 0f;
+
+        foreach (var kvp in influence)
+        {
+            if (kvp.Value > maxInfluence)
+            {
+                maxInfluence = kvp.Value;
+                dominant = kvp.Key;
+            }
+        }
+
+        return dominant;
+    }
+
+    private TerrainType GenerateContinuousTerrain(TerrainType dominantBiome, float height, int x, int y)
+    {
+        switch (dominantBiome)
+        {
+            case TerrainType.Mountain:
+                return TransitionMountain(height, x, y);
+            case TerrainType.Forest:
+                return TransitionForest(height, x, y);
+            case TerrainType.Ocean:
+                return TransitionOcean(height, x, y);
+            case TerrainType.Lake:
+                return TransitionLake(height, x, y);
+            case TerrainType.Shore:
+                return TransitionShore(height, x, y);
+            case TerrainType.River:
+                return TransitionRiver(height, x, y);
+            default:
+                return TerrainType.Plains;
+        }
+    }
+
+    private TerrainType TransitionMountain(float height, int x, int y)
+    {
+        // Mountains are very conservative
+        if (height > 0.3f) // Lower threshold for mountain continuation
+            return TerrainType.Mountain;
+        else if (height > 0.0f) // Wide foothill zone
+            return TerrainType.Forest; // Mountain foothills
+        else
+            return TerrainType.Plains;
+    }
+
+    private TerrainType TransitionForest(float height, int x, int y)
+    {
+        // Conservative forest generation
+        if (height > 0.2f)
+            return TerrainType.Mountain; // Higher areas become mountains
+        else if (height > -0.1f) // Wide forest zone
+            return TerrainType.Forest;
+        else
+            return TerrainType.Plains;
+    }
+
+    private TerrainType TransitionOcean(float height, int x, int y)
+    {
+        // Ocean is extremely conservative - almost always continues as ocean
+        if (height < 0.0f) // Much more lenient for ocean continuation
+            return TerrainType.Ocean;
+        else if (height < 0.2f) // Very wide shore zone
+            return TerrainType.Shore;
+        else if (height < 0.4f)
+            return TerrainType.Plains; // Coastal plains
+        else
+            return TerrainType.Forest;
+    }
+
+    private TerrainType TransitionLake(float height, int x, int y)
+    {
+        // Lakes are very conservative
+        if (height < 0.0f) // Much more lenient for lake continuation
+            return TerrainType.Lake;
+        else if (height < 0.2f) // Wide shore zone
+            return TerrainType.Shore;
+        else
+            return TerrainType.Plains;
+    }
+
+    private TerrainType TransitionShore(float height, int x, int y)
+    {
+        if (height < -0.1f) // More lenient transition to water
+            return TerrainType.Ocean;
+        else if (height < 0.4f) // Much wider shore zone
+            return TerrainType.Shore;
+        else
+            return TerrainType.Plains;
+    }
+
+    private TerrainType TransitionRiver(float height, int x, int y)
+    {
+        // Rivers are conservative
+        if (height < 0.0f)
+            return TerrainType.River;
+        else if (height < 0.1f)
+            return TerrainType.Plains; // River plains
+        else
+            return TerrainType.Forest;
+    }
+
+    private TerrainType GenerateNaturalTerrainFromHeight(float height, int x, int y)
+    {
+        // Pure height-based generation without noise variation
+        if (height > 0.6f) return TerrainType.Mountain;
+        else if (height > 0.2f) return TerrainType.Forest;
+        else if (height < -0.5f) return TerrainType.Ocean;
+        else if (height < -0.2f) return TerrainType.Lake;
+        else if (height < 0.0f) return TerrainType.Shore;
+        else return TerrainType.Plains;
+    }
+
+    private void SmoothTerrainTransitions(MapData mapData, ExpansionInfo info)
+    {
+        // Much more aggressive smoothing for natural blending
+        int smoothRadius = 8; // Increased from 5
+
+        // Process each expansion boundary multiple times
+        for (int pass = 0; pass < 3; pass++) // Multiple smoothing passes
+        {
+            if (info.leftExpansion > 0)
+                SmoothBoundaryRegion(mapData, info.leftExpansion - smoothRadius, 0, smoothRadius * 2, info.newHeight);
+
+            if (info.rightExpansion > 0)
+                SmoothBoundaryRegion(mapData, info.leftExpansion + info.oldWidth - smoothRadius, 0, smoothRadius * 2, info.newHeight);
+
+            if (info.upExpansion > 0)
+                SmoothBoundaryRegion(mapData, 0, info.downExpansion + info.oldHeight - smoothRadius, info.newWidth, smoothRadius * 2);
+
+            if (info.downExpansion > 0)
+                SmoothBoundaryRegion(mapData, 0, info.downExpansion - smoothRadius, info.newWidth, smoothRadius * 2);
+        }
+    }
+
+    private void SmoothBoundaryRegion(MapData mapData, int startX, int startY, int width, int height)
+    {
+        for (int x = startX; x < startX + width; x++)
+        {
+            for (int y = startY; y < startY + height; y++)
+            {
+                if (!mapData.IsValidPosition(x, y)) continue;
+
+                SmoothTileWithNeighbors(mapData, x, y);
+            }
+        }
+    }
+
+    private void SmoothTileWithNeighbors(MapData mapData, int x, int y)
+    {
+        MapTile centerTile = mapData.GetTile(x, y);
+        Dictionary<TerrainType, int> neighborTerrain = GetNeighborTerrain(mapData, x, y, 3); // Larger radius
+
+        // If this tile is very isolated, consider changing it
+        if (!neighborTerrain.ContainsKey(centerTile.terrainType) ||
+            neighborTerrain[centerTile.terrainType] < 3) // Stricter isolation check
+        {
+            TerrainType newTerrain = GetMostCommonNeighborTerrain(neighborTerrain);
+            if (IsValidTerrainTransition(centerTile.terrainType, newTerrain))
+            {
+                centerTile.terrainType = newTerrain;
+
+                // Also smooth the height towards neighbors
+                float avgHeight = GetAverageNeighborHeight(mapData, x, y, 2);
+                centerTile.height = Mathf.Lerp(centerTile.height, avgHeight, 0.5f);
+            }
+        }
+    }
+
+    private Dictionary<TerrainType, int> GetNeighborTerrain(MapData mapData, int centerX, int centerY, int radius)
+    {
+        Dictionary<TerrainType, int> terrain = new Dictionary<TerrainType, int>();
+
+        for (int x = centerX - radius; x <= centerX + radius; x++)
+        {
+            for (int y = centerY - radius; y <= centerY + radius; y++)
+            {
+                if (x == centerX && y == centerY) continue;
+                if (!mapData.IsValidPosition(x, y)) continue;
+
+                TerrainType terrainType = mapData.GetTile(x, y).terrainType;
+                terrain[terrainType] = terrain.ContainsKey(terrainType) ? terrain[terrainType] + 1 : 1;
+            }
+        }
+
+        return terrain;
+    }
+
+    private float GetAverageNeighborHeight(MapData mapData, int centerX, int centerY, int radius)
+    {
+        float totalHeight = 0f;
+        int count = 0;
+
+        for (int x = centerX - radius; x <= centerX + radius; x++)
+        {
+            for (int y = centerY - radius; y <= centerY + radius; y++)
+            {
+                if (x == centerX && y == centerY) continue;
+                if (!mapData.IsValidPosition(x, y)) continue;
+
+                totalHeight += mapData.GetTile(x, y).height;
+                count++;
+            }
+        }
+
+        return count > 0 ? totalHeight / count : 0f;
+    }
+
+    private TerrainType GetMostCommonNeighborTerrain(Dictionary<TerrainType, int> terrain)
+    {
+        TerrainType mostCommon = TerrainType.Plains;
+        int maxCount = 0;
+
+        foreach (var kvp in terrain)
+        {
+            if (kvp.Value > maxCount)
+            {
+                maxCount = kvp.Value;
+                mostCommon = kvp.Key;
+            }
+        }
+
+        return mostCommon;
+    }
+
+    private bool IsValidTerrainTransition(TerrainType from, TerrainType to)
+    {
+        // Some terrain transitions don't make sense (e.g., ocean to mountain directly)
+        if (from == TerrainType.Ocean && to == TerrainType.Mountain) return false;
+        if (from == TerrainType.Mountain && to == TerrainType.Ocean) return false;
+        return true;
+    }
+
+    private void GenerateNaturalFeatures(MapData mapData, ExpansionInfo info)
+    {
+        // Extend rivers naturally
+        ExtendRiversIntoExpansion(mapData, info);
+
+        // Create natural water bodies
+        GenerateNaturalLakes(mapData, info);
+    }
+
+    private void ExtendRiversIntoExpansion(MapData mapData, ExpansionInfo info)
+    {
+        // Find rivers at boundaries and extend them naturally
+        List<Vector2Int> riverEnds = FindRiversAtBoundaries(mapData, info);
+
+        foreach (var riverEnd in riverEnds)
+        {
+            ExtendRiverNaturally(mapData, riverEnd, info);
+        }
+    }
+
+    private List<Vector2Int> FindRiversAtBoundaries(MapData mapData, ExpansionInfo info)
+    {
+        List<Vector2Int> riverPoints = new List<Vector2Int>();
+
+        // Check boundaries for rivers
+        CheckBoundaryForRivers(mapData, info.leftExpansion, 0, 1, info.newHeight, riverPoints);
+        CheckBoundaryForRivers(mapData, info.leftExpansion + info.oldWidth - 1, 0, 1, info.newHeight, riverPoints);
+
+        return riverPoints;
+    }
+
+    private void CheckBoundaryForRivers(MapData mapData, int startX, int startY, int width, int height, List<Vector2Int> riverPoints)
+    {
+        for (int x = startX; x < startX + width; x++)
+        {
+            for (int y = startY; y < startY + height; y++)
+            {
+                if (mapData.IsValidPosition(x, y))
+                {
+                    MapTile tile = mapData.GetTile(x, y);
+                    if (tile.terrainType == TerrainType.River)
+                    {
+                        riverPoints.Add(new Vector2Int(x, y));
+                    }
+                }
+            }
+        }
+    }
+
+    private void ExtendRiverNaturally(MapData mapData, Vector2Int start, ExpansionInfo info)
+    {
+        Vector2Int current = start;
+        int maxLength = 25;
+
+        for (int i = 0; i < maxLength; i++)
+        {
+            Vector2Int next = FindBestRiverDirection(mapData, current);
+            if (next == current) break;
+
+            MapTile nextTile = mapData.GetTile(next.x, next.y);
+            if (nextTile.terrainType == TerrainType.Plains || nextTile.terrainType == TerrainType.Shore)
+            {
+                nextTile.terrainType = TerrainType.River;
+                current = next;
+            }
+            else
+            {
+                break;
+            }
+        }
+    }
+
+    private Vector2Int FindBestRiverDirection(MapData mapData, Vector2Int current)
+    {
+        Vector2Int[] directions = {
+            new Vector2Int(0, 1), new Vector2Int(1, 0), new Vector2Int(0, -1), new Vector2Int(-1, 0),
+            new Vector2Int(1, 1), new Vector2Int(-1, 1), new Vector2Int(1, -1), new Vector2Int(-1, -1)
+        };
+
+        Vector2Int best = current;
+        float bestScore = float.MinValue;
+
+        foreach (var dir in directions)
+        {
+            Vector2Int candidate = current + dir;
+            if (mapData.IsValidPosition(candidate.x, candidate.y))
+            {
+                float score = EvaluateRiverDirection(mapData, candidate);
+                if (score > bestScore)
+                {
+                    bestScore = score;
+                    best = candidate;
+                }
+            }
+        }
+
+        return best;
+    }
+
+    private float EvaluateRiverDirection(MapData mapData, Vector2Int position)
+    {
+        MapTile tile = mapData.GetTile(position.x, position.y);
+
+        // Rivers prefer lower elevations and suitable terrain
+        float score = -tile.height; // Lower is better
+
+        if (tile.terrainType == TerrainType.Plains) score += 2f;
+        else if (tile.terrainType == TerrainType.Shore) score += 1f;
+        else if (tile.terrainType == TerrainType.Forest) score += 0.5f;
+        else score -= 10f; // Avoid mountains, existing water, etc.
+
+        return score;
+    }
+
+    private void GenerateNaturalLakes(MapData mapData, ExpansionInfo info)
+    {
+        // Create 1-2 small lakes in suitable locations
+        for (int i = 0; i < 2; i++)
+        {
+            Vector2Int lakeCenter = FindSuitableLakeLocation(mapData, info);
+            if (lakeCenter != Vector2Int.zero)
+            {
+                CreateNaturalLake(mapData, lakeCenter);
+            }
+        }
+    }
+
+    private Vector2Int FindSuitableLakeLocation(MapData mapData, ExpansionInfo info)
+    {
+        for (int attempts = 0; attempts < 30; attempts++)
+        {
+            int x = random.Next(0, info.newWidth);
+            int y = random.Next(0, info.newHeight);
+
+            // Only in expansion areas
+            if (IsInOriginalArea(x, y, info)) continue;
+
+            if (mapData.IsValidPosition(x, y))
+            {
+                MapTile tile = mapData.GetTile(x, y);
+                if (tile.height < -0.1f && tile.terrainType == TerrainType.Plains)
+                {
+                    return new Vector2Int(x, y);
+                }
+            }
+        }
+
+        return Vector2Int.zero;
+    }
+
+    private bool IsInOriginalArea(int x, int y, ExpansionInfo info)
+    {
+        return x >= info.leftExpansion && x < info.leftExpansion + info.oldWidth &&
+               y >= info.downExpansion && y < info.downExpansion + info.oldHeight;
+    }
+
+    private void CreateNaturalLake(MapData mapData, Vector2Int center)
+    {
+        int radius = random.Next(3, 6);
+
+        for (int x = center.x - radius; x <= center.x + radius; x++)
+        {
+            for (int y = center.y - radius; y <= center.y + radius; y++)
+            {
+                if (mapData.IsValidPosition(x, y))
+                {
+                    float distance = Vector2Int.Distance(center, new Vector2Int(x, y));
+                    if (distance <= radius)
+                    {
+                        MapTile tile = mapData.GetTile(x, y);
+                        if (distance < radius - 1)
+                        {
+                            tile.terrainType = TerrainType.Lake;
+                        }
+                        else if (distance < radius)
+                        {
+                            tile.terrainType = TerrainType.Shore;
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    private void GenerateSettlementsAndRoads(MapData mapData, ExpansionInfo info)
+    {
+        GenerateExpansionSettlements(mapData, info);
+        ExtendRoadsToExpansion(mapData, info);
+        GenerateExpansionHarbours(mapData, info);
+    }
+
+    // Settlement and road generation methods (enhanced versions)
+    private void GenerateExpansionSettlements(MapData mapData, ExpansionInfo info)
+    {
+        int totalNewArea = (info.newWidth * info.newHeight) - (info.oldWidth * info.oldHeight);
+        int newSettlementCount = Mathf.Max(1, totalNewArea / 3000); // Fewer, better placed settlements
+
+        Debug.Log($"Generating {newSettlementCount} new settlements for {totalNewArea} new tiles");
+
+        for (int i = 0; i < newSettlementCount; i++)
+        {
+            Vector2Int position = FindSuitableSettlementPosition(mapData, info);
+            if (position != Vector2Int.zero)
+            {
+                CreateNewSettlement(mapData, position);
+                Debug.Log($"Created new settlement at {position}");
+            }
+        }
+    }
+
+    private Vector2Int FindSuitableSettlementPosition(MapData mapData, ExpansionInfo info)
+    {
+        for (int attempts = 0; attempts < 100; attempts++)
+        {
+            int x = random.Next(0, info.newWidth);
+            int y = random.Next(0, info.newHeight);
+
+            if (IsInOriginalArea(x, y, info)) continue;
+
+            MapTile tile = mapData.GetTile(x, y);
+            if (tile != null && tile.terrainType == TerrainType.Plains && tile.featureType == FeatureType.None)
+            {
+                // Check distance from other settlements
+                bool validLocation = true;
+                var existingSettlements = mapData.GetTowns();
+                existingSettlements.AddRange(mapData.GetVillages());
+
+                foreach (var settlement in existingSettlements)
+                {
+                    float distance = Vector2Int.Distance(new Vector2Int(x, y), settlement.position);
+                    if (distance < 25) // Increased minimum distance for better distribution
+                    {
+                        validLocation = false;
+                        break;
+                    }
+                }
+
+                if (validLocation)
+                    return new Vector2Int(x, y);
+            }
+        }
+
+        return Vector2Int.zero;
+    }
+
+    private void CreateNewSettlement(MapData mapData, Vector2Int position)
+    {
+        MapTile tile = mapData.GetTile(position.x, position.y);
+
+        SettlementType type = random.NextDouble() < 0.25 ? SettlementType.Town : SettlementType.Village;
+
+        tile.featureType = type == SettlementType.Town ? FeatureType.Town : FeatureType.Village;
+        string settlementName = GenerateSettlementName(type);
+        tile.name = settlementName;
+
+        Settlement settlement = new Settlement(settlementName, type, position);
+        mapData.AddSettlement(settlement);
+    }
+
+    private string GenerateSettlementName(SettlementType type)
+    {
+        string[] townNames = { "Newborough", "Westhold", "Eastport", "Northgate", "Southhaven", "Riverside", "Hillcrest", "Stoneburg" };
+        string[] villageNames = { "Millbrook", "Fairfield", "Greendale", "Oakwood", "Rosehaven", "Brightwater", "Meadowbrook", "Willowbend" };
+
+        string[] names = type == SettlementType.Town ? townNames : villageNames;
+        return names[random.Next(names.Length)];
+    }
+
+    private void ExtendRoadsToExpansion(MapData mapData, ExpansionInfo info)
+    {
+        var settlements = mapData.GetTowns();
+        settlements.AddRange(mapData.GetVillages());
+
+        foreach (var settlement in settlements)
+        {
+            bool nearExpansionEdge = IsNearExpansionEdge(settlement.position, info);
+            if (nearExpansionEdge)
+            {
+                var nearestNewSettlement = FindNearestNewSettlement(mapData, settlement.position, info);
+                if (nearestNewSettlement != Vector2Int.zero)
+                {
+                    CreateRoadBetween(mapData, settlement.position, nearestNewSettlement);
+                }
+            }
+        }
+    }
+
+    private bool IsNearExpansionEdge(Vector2Int position, ExpansionInfo info)
+    {
+        int edgeDistance = 20;
+
+        bool nearLeft = info.leftExpansion > 0 && position.x < info.leftExpansion + edgeDistance;
+        bool nearRight = info.rightExpansion > 0 && position.x > info.leftExpansion + info.oldWidth - edgeDistance;
+        bool nearBottom = info.downExpansion > 0 && position.y < info.downExpansion + edgeDistance;
+        bool nearTop = info.upExpansion > 0 && position.y > info.downExpansion + info.oldHeight - edgeDistance;
+
+        return nearLeft || nearRight || nearBottom || nearTop;
+    }
+
+    private Vector2Int FindNearestNewSettlement(MapData mapData, Vector2Int fromPosition, ExpansionInfo info)
+    {
+        Vector2Int nearest = Vector2Int.zero;
+        float nearestDistance = float.MaxValue;
+
+        var settlements = mapData.GetTowns();
+        settlements.AddRange(mapData.GetVillages());
+
+        foreach (var settlement in settlements)
+        {
+            bool inNewArea = !IsInOriginalArea(settlement.position.x, settlement.position.y, info);
+            if (inNewArea)
+            {
+                float distance = Vector2Int.Distance(fromPosition, settlement.position);
+                if (distance < nearestDistance)
+                {
+                    nearestDistance = distance;
+                    nearest = settlement.position;
+                }
+            }
+        }
+
+        return nearest;
+    }
+
+    private void CreateRoadBetween(MapData mapData, Vector2Int start, Vector2Int end)
+    {
+        Vector2Int current = start;
+
+        while (current != end)
+        {
+            if (current.x < end.x) current.x++;
+            else if (current.x > end.x) current.x--;
+            else if (current.y < end.y) current.y++;
+            else if (current.y > end.y) current.y--;
+
+            if (mapData.IsValidPosition(current.x, current.y))
+            {
+                MapTile tile = mapData.GetTile(current.x, current.y);
+                if (tile.featureType == FeatureType.None && tile.isWalkable)
+                {
+                    tile.featureType = FeatureType.Road;
+                }
+            }
+        }
+    }
+
+    private void GenerateExpansionHarbours(MapData mapData, ExpansionInfo info)
+    {
+        var settlements = mapData.GetTowns();
+        settlements.AddRange(mapData.GetVillages());
+
+        foreach (var settlement in settlements)
+        {
+            if (!IsInOriginalArea(settlement.position.x, settlement.position.y, info))
+            {
+                if (IsNearWater(mapData, settlement.position.x, settlement.position.y, 5))
+                {
+                    Vector2Int harbourPos = FindHarbourPosition(mapData, settlement.position);
+                    if (harbourPos != Vector2Int.zero)
+                    {
+                        mapData.GetTile(harbourPos.x, harbourPos.y).featureType = FeatureType.Harbour;
+                    }
+                }
+            }
+        }
+    }
+
+    private bool IsNearWater(MapData mapData, int x, int y, int range)
+    {
+        for (int dx = -range; dx <= range; dx++)
+        {
+            for (int dy = -range; dy <= range; dy++)
+            {
+                int checkX = x + dx;
+                int checkY = y + dy;
+
+                if (mapData.IsValidPosition(checkX, checkY))
+                {
+                    MapTile tile = mapData.GetTile(checkX, checkY);
+                    if (tile.IsWater())
+                        return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    private Vector2Int FindHarbourPosition(MapData mapData, Vector2Int settlementPos)
+    {
+        for (int range = 1; range <= 5; range++)
+        {
+            for (int dx = -range; dx <= range; dx++)
+            {
+                for (int dy = -range; dy <= range; dy++)
+                {
+                    int x = settlementPos.x + dx;
+                    int y = settlementPos.y + dy;
+
+                    if (mapData.IsValidPosition(x, y))
+                    {
+                        MapTile tile = mapData.GetTile(x, y);
+                        if (tile.terrainType == TerrainType.Shore && tile.featureType == FeatureType.None)
+                        {
+                            return new Vector2Int(x, y);
+                        }
+                    }
+                }
+            }
+        }
+        return Vector2Int.zero;
+    }
+}

+ 1919 - 0
Assets/Scripts/MapMaker2/Exploration/ExplorationManager.cs

@@ -0,0 +1,1919 @@
+using UnityEngine;
+using System.Collections.Generic;
+using System.Linq;
+
+/// <summary>
+/// Manages map exploration using a pre-generated large map with fog of war
+/// </summary>
+public class ExplorationManager
+{
+    private MapMaker2 mapMaker;
+    private MapData fullMapData; // The complete pre-generated map
+    private bool[,] exploredMask; // Tracks which areas have been revealed
+    private float lastExplorationTime = 0f; // Cooldown tracking
+
+    // Performance settings for large maps
+    private bool performanceMode = false; // Enable for maps larger than 200x200
+    private int lodLevel = 1; // Level of Detail: 1 = full detail, 2 = half detail, 4 = quarter detail
+
+    // Exploration Settings - Public properties for MapMaker2 to set
+    public int fullMapWidth { get; set; } = 300;
+    public int fullMapHeight { get; set; } = 300;
+    public int initialVisibleSize { get; set; } = 80; // Starting visible area
+    public int explorationChunkSize { get; set; } = 40; // Size of chunks to reveal
+    public float explorationDistance { get; set; } = 10f; // Distance from edge to trigger exploration (reduced from 20f)
+    public float explorationCooldown { get; set; } = 3f; // Cooldown between explorations
+
+    public ExplorationManager(MapMaker2 mapMaker)
+    {
+        this.mapMaker = mapMaker;
+    }
+
+    /// <summary>
+    /// Initialize the exploration system with a large pre-generated map
+    /// </summary>
+    public void InitializeExploration()
+    {
+        Debug.Log("🗺️ Initializing Exploration System...");
+
+        // Check if we need performance mode for large maps
+        if (fullMapWidth > 200 || fullMapHeight > 200)
+        {
+            performanceMode = true;
+            lodLevel = CalculateOptimalLOD(fullMapWidth, fullMapHeight);
+            Debug.Log($"⚡ Performance mode enabled with LOD level {lodLevel} for large map");
+        }
+
+        // Generate the full large map
+        GenerateFullMap();
+
+        // Initialize exploration mask
+        exploredMask = new bool[fullMapWidth, fullMapHeight];
+        Debug.Log($"🔍 Created exploration mask: {fullMapWidth}x{fullMapHeight}");
+
+        // Reveal initial area around the center
+        RevealInitialArea();
+
+        // Update the visible map data
+        UpdateVisibleMap();
+
+        Debug.Log($"✅ Exploration System initialized - Full map: {fullMapWidth}x{fullMapHeight}, Initial visible: {initialVisibleSize}x{initialVisibleSize}");
+    }
+
+    /// <summary>
+    /// Calculate optimal Level of Detail for given map size
+    /// </summary>
+    private int CalculateOptimalLOD(int width, int height)
+    {
+        int totalTiles = width * height;
+
+        if (totalTiles > 250000) // 500x500+
+            return 4; // Quarter detail
+        else if (totalTiles > 100000) // 316x316+
+            return 2; // Half detail
+        else
+            return 1; // Full detail
+    }
+
+    /// <summary>
+    /// DEBUG: Show the entire 300x300 map for testing purposes
+    /// </summary>
+    public void ShowFullMap()
+    {
+        if (fullMapData == null)
+        {
+            Debug.LogError("❌ Full map data not available!");
+            return;
+        }
+
+        Debug.Log("🌍 Loading full 300x300 map for debugging...");
+
+        // Get the current position in full map coordinates BEFORE switching to full map
+        Vector2Int currentFullMapPosition = GetCurrentTeamPositionInFullMapImproved();
+        Debug.Log($"🎯 Team position before full map: Full map coordinates ({currentFullMapPosition})");
+
+        // Mark entire map as explored
+        for (int x = 0; x < fullMapWidth; x++)
+        {
+            for (int y = 0; y < fullMapHeight; y++)
+            {
+                exploredMask[x, y] = true;
+            }
+        }
+
+        // Update the visible map to show everything
+        UpdateVisibleMap();
+
+        // Restore team marker to the correct full map position
+        RestoreTeamMarkerToFullMapPosition(currentFullMapPosition);
+
+        Debug.Log($"✅ Full map is now visible!");
+    }
+
+    /// <summary>
+    /// TEST: Debug coordinate conversion to find the issue
+    /// </summary>
+    public void TestCoordinateConversion()
+    {
+        SimpleTeamPlacement teamPlacement = Object.FindFirstObjectByType<SimpleTeamPlacement>();
+        if (teamPlacement == null)
+        {
+            Debug.LogError("❌ SimpleTeamPlacement not found!");
+            return;
+        }
+
+        GameObject teamMarker = GameObject.Find("TeamMarker");
+        if (teamMarker == null)
+        {
+            Debug.LogError("❌ TeamMarker not found!");
+            return;
+        }
+
+        // Get current state
+        Vector3 worldPos = teamMarker.transform.position;
+        Vector2Int storedPos = teamPlacement.GetCurrentTeamPosition();
+        Rect exploredBounds = GetExploredBounds();
+        bool isShowingFullMap = exploredBounds.width >= fullMapWidth - 5 && exploredBounds.height >= fullMapHeight - 5;
+
+        Debug.Log("=== COORDINATE CONVERSION TEST ===");
+        Debug.Log($"Team Marker World Position: ({worldPos.x:F1}, {worldPos.y:F1})");
+        Debug.Log($"Team Placement Stored Position: ({storedPos.x}, {storedPos.y})");
+        Debug.Log($"Explored Bounds: {exploredBounds}");
+        Debug.Log($"Is Showing Full Map: {isShowingFullMap}");
+        Debug.Log($"Full Map Size: {fullMapWidth}x{fullMapHeight}");
+
+        // Test the conversion
+        Vector2Int convertedPos = GetCurrentTeamPositionInFullMapImproved();
+        Debug.Log($"Converted Full Map Position: ({convertedPos.x}, {convertedPos.y})");
+
+        // Expected position for center of map
+        Vector2Int expectedCenter = new Vector2Int(fullMapWidth / 2, fullMapHeight / 2);
+        Debug.Log($"Expected Map Center: ({expectedCenter.x}, {expectedCenter.y})");
+
+        // Check if the stored position makes sense
+        if (!isShowingFullMap)
+        {
+            Vector2Int expectedFullMapPos = new Vector2Int(
+                (int)exploredBounds.x + storedPos.x,
+                (int)exploredBounds.y + storedPos.y
+            );
+            Debug.Log($"Expected Full Map Pos from Stored: Bounds({exploredBounds.x}, {exploredBounds.y}) + Stored({storedPos.x}, {storedPos.y}) = ({expectedFullMapPos.x}, {expectedFullMapPos.y})");
+        }
+
+        Debug.Log("=====================================");
+    }
+
+    /// <summary>
+    /// TEST: Simple coordinate conversion test
+    /// </summary>
+    public void TestSimpleCoordinateConversion()
+    {
+        SimpleTeamPlacement teamPlacement = Object.FindFirstObjectByType<SimpleTeamPlacement>();
+        if (teamPlacement == null)
+        {
+            Debug.LogError("❌ SimpleTeamPlacement not found!");
+            return;
+        }
+
+        Vector2Int storedPos = teamPlacement.GetCurrentTeamPosition();
+        Rect exploredBounds = GetExploredBounds();
+
+        Debug.Log("=== SIMPLE COORDINATE TEST ===");
+        Debug.Log($"Stored team position: ({storedPos.x}, {storedPos.y})");
+        Debug.Log($"Explored bounds: {exploredBounds}");
+
+        // Expected full map position
+        Vector2Int expectedFullMapPos = new Vector2Int(
+            (int)exploredBounds.x + storedPos.x,
+            (int)exploredBounds.y + storedPos.y
+        );
+        Debug.Log($"Expected full map position: ({expectedFullMapPos.x}, {expectedFullMapPos.y})");
+        Debug.Log($"Map center: ({fullMapWidth / 2}, {fullMapHeight / 2})");
+
+        bool isNearCenter = Vector2Int.Distance(expectedFullMapPos, new Vector2Int(fullMapWidth / 2, fullMapHeight / 2)) < 10;
+        Debug.Log($"Is near map center: {(isNearCenter ? "✅ YES" : "❌ NO")}");
+
+        Debug.Log("===============================");
+    }
+
+    /// <summary>
+    /// DEBUG: Test positioning after camera and tile fixes
+    /// </summary>
+    public void TestPositioningAfterFix()
+    {
+        SimpleTeamPlacement teamPlacement = Object.FindFirstObjectByType<SimpleTeamPlacement>();
+        if (teamPlacement == null)
+        {
+            Debug.LogError("❌ SimpleTeamPlacement not found!");
+            return;
+        }
+
+        GameObject teamMarker = GameObject.Find("TeamMarker");
+        if (teamMarker == null)
+        {
+            Debug.LogError("❌ TeamMarker not found!");
+            return;
+        }
+
+        Vector2Int storedPos = teamPlacement.GetCurrentTeamPosition();
+        Rect exploredBounds = GetExploredBounds();
+        Vector3 teamMarkerWorldPos = teamMarker.transform.position;
+
+        Debug.Log("=== POSITIONING TEST AFTER FIX ===");
+        Debug.Log($"📍 Team Marker World Position: ({teamMarkerWorldPos.x:F1}, {teamMarkerWorldPos.y:F1})");
+        Debug.Log($"🗂️ Stored Team Position: ({storedPos.x}, {storedPos.y})");
+        Debug.Log($"🗺️ Explored Bounds: {exploredBounds}");
+
+        // Calculate expected world position for the center tile
+        Vector3 expectedCenterTileWorldPos = new Vector3(
+            (exploredBounds.x + exploredBounds.width / 2f),
+            (exploredBounds.y + exploredBounds.height / 2f),
+            0
+        );
+        Debug.Log($"🎯 Expected Center Tile World Position: ({expectedCenterTileWorldPos.x:F1}, {expectedCenterTileWorldPos.y:F1})");
+
+        // Check camera position
+        Camera mainCam = Camera.main;
+        if (mainCam != null)
+        {
+            Debug.Log($"📹 Camera Position: ({mainCam.transform.position.x:F1}, {mainCam.transform.position.y:F1})");
+            Debug.Log($"📹 Camera Size: {mainCam.orthographicSize:F1}");
+        }
+
+        // Check if team marker should be visible
+        float distanceFromExpectedCenter = Vector3.Distance(teamMarkerWorldPos, expectedCenterTileWorldPos);
+        Debug.Log($"📏 Distance from expected center: {distanceFromExpectedCenter:F1}");
+
+        bool shouldBeVisible = distanceFromExpectedCenter < 40f; // Within 40 units of center
+        Debug.Log($"👁️ Should be visible: {(shouldBeVisible ? "✅ YES" : "❌ NO")}");
+
+        Debug.Log("===================================");
+    }
+
+    /// <summary>
+    /// DEBUG: Test full map tile coverage to find missing quadrants
+    /// </summary>
+    public void TestFullMapTileCoverage()
+    {
+        Debug.Log("=== FULL MAP TILE COVERAGE TEST ===");
+
+        // Get current map data from MapMaker2
+        var currentMapData = mapMaker?.GetMapData();
+        if (currentMapData == null)
+        {
+            Debug.LogError("❌ No current map data available!");
+            return;
+        }
+
+        Debug.Log($"📊 Current Map Data Size: {currentMapData.Width}x{currentMapData.Height}");
+
+        // Check if we're showing full map
+        Rect exploredBounds = GetExploredBounds();
+        bool isShowingFullMap = exploredBounds.width >= fullMapWidth - 5 && exploredBounds.height >= fullMapHeight - 5;
+        Debug.Log($"🗺️ Is Showing Full Map: {isShowingFullMap}");
+        Debug.Log($"🗺️ Explored Bounds: {exploredBounds}");
+        Debug.Log($"🗺️ Full Map Size: {fullMapWidth}x{fullMapHeight}");
+
+        if (isShowingFullMap)
+        {
+            // Test if we have tiles in each quadrant
+            int centerX = currentMapData.Width / 2;
+            int centerY = currentMapData.Height / 2;
+
+            // Test each quadrant
+            Vector2Int[] testPoints = {
+                new Vector2Int(centerX / 2, centerY / 2),           // Lower-left
+                new Vector2Int(centerX + centerX / 2, centerY / 2), // Lower-right
+                new Vector2Int(centerX / 2, centerY + centerY / 2), // Upper-left
+                new Vector2Int(centerX + centerX / 2, centerY + centerY / 2) // Upper-right
+            };
+
+            string[] quadrantNames = { "Lower-Left", "Lower-Right", "Upper-Left", "Upper-Right" };
+
+            for (int i = 0; i < testPoints.Length; i++)
+            {
+                var testPoint = testPoints[i];
+                var tile = currentMapData.GetTile(testPoint.x, testPoint.y);
+                bool hasValidTile = tile != null;
+
+                Debug.Log($"🔍 {quadrantNames[i]} Quadrant ({testPoint.x}, {testPoint.y}): {(hasValidTile ? "✅ HAS TILE" : "❌ NO TILE")}");
+                if (hasValidTile)
+                {
+                    Debug.Log($"   Terrain: {tile.terrainType}, Feature: {tile.featureType}");
+                }
+            }
+
+            // Test specific areas that might be missing
+            Debug.Log("🔍 Testing specific problematic areas:");
+            Vector2Int[] problematicPoints = {
+                new Vector2Int(0, 0),                    // Bottom-left corner
+                new Vector2Int(currentMapData.Width-1, 0),     // Bottom-right corner
+                new Vector2Int(0, currentMapData.Height-1),    // Top-left corner
+                new Vector2Int(currentMapData.Width-1, currentMapData.Height-1) // Top-right corner
+            };
+
+            for (int i = 0; i < problematicPoints.Length; i++)
+            {
+                var testPoint = problematicPoints[i];
+                var tile = currentMapData.GetTile(testPoint.x, testPoint.y);
+                bool hasValidTile = tile != null;
+                Debug.Log($"🔍 Corner ({testPoint.x}, {testPoint.y}): {(hasValidTile ? "✅ HAS TILE" : "❌ NO TILE")}");
+            }
+        }
+        else
+        {
+            Debug.Log("⚠️ Not currently showing full map - switch to full map first to test coverage");
+        }
+
+        Debug.Log("=====================================");
+    }
+
+    /// <summary>
+    /// DEBUG: Test visual tile rendering to find missing areas
+    /// </summary>
+    public void TestVisualTileRendering()
+    {
+        Debug.Log("=== VISUAL TILE RENDERING TEST ===");
+
+        // Check if we're showing full map
+        Rect exploredBounds = GetExploredBounds();
+        bool isShowingFullMap = exploredBounds.width >= fullMapWidth - 5 && exploredBounds.height >= fullMapHeight - 5;
+        Debug.Log($"🗺️ Is Showing Full Map: {isShowingFullMap}");
+        Debug.Log($"🗺️ Explored Bounds: {exploredBounds}");
+
+        if (isShowingFullMap)
+        {
+            // Check for actual GameObjects in each quadrant
+            string[] quadrantNames = { "Lower-Left", "Lower-Right", "Upper-Left", "Upper-Right" };
+            Vector2Int[] testPoints = {
+                new Vector2Int(75, 75),           // Lower-left
+                new Vector2Int(225, 75),          // Lower-right  
+                new Vector2Int(75, 225),          // Upper-left
+                new Vector2Int(225, 225)          // Upper-right
+            };
+
+            for (int i = 0; i < testPoints.Length; i++)
+            {
+                var testPoint = testPoints[i];
+
+                // Look for actual tile GameObjects at these world positions
+                string terrainTileName = $"TerrainTile_{testPoint.x}_{testPoint.y}";
+                GameObject terrainTile = GameObject.Find(terrainTileName);
+
+                string featureTileName = $"FeatureTile_{testPoint.x}_{testPoint.y}";
+                GameObject featureTile = GameObject.Find(featureTileName);
+
+                Debug.Log($"🎮 {quadrantNames[i]} Quadrant ({testPoint.x}, {testPoint.y}):");
+                Debug.Log($"   Terrain GameObject: {(terrainTile != null ? "✅ EXISTS" : "❌ MISSING")}");
+                Debug.Log($"   Feature GameObject: {(featureTile != null ? "✅ EXISTS" : "❌ MISSING")}");
+
+                if (terrainTile != null)
+                {
+                    Debug.Log($"   Terrain Position: ({terrainTile.transform.position.x:F1}, {terrainTile.transform.position.y:F1})");
+                    Debug.Log($"   Terrain Active: {terrainTile.activeInHierarchy}");
+                }
+            }
+
+            // Check corner tiles specifically
+            Debug.Log("🔍 Testing corner tile GameObjects:");
+            Vector2Int[] corners = {
+                new Vector2Int(0, 0),        // Bottom-left corner
+                new Vector2Int(299, 0),      // Bottom-right corner  
+                new Vector2Int(0, 299),      // Top-left corner
+                new Vector2Int(299, 299)     // Top-right corner
+            };
+
+            string[] cornerNames = { "Bottom-Left", "Bottom-Right", "Top-Left", "Top-Right" };
+
+            for (int i = 0; i < corners.Length; i++)
+            {
+                var corner = corners[i];
+                string tileName = $"TerrainTile_{corner.x}_{corner.y}";
+                GameObject tile = GameObject.Find(tileName);
+
+                Debug.Log($"🎮 {cornerNames[i]} Corner ({corner.x}, {corner.y}): {(tile != null ? "✅ EXISTS" : "❌ MISSING")}");
+                if (tile != null)
+                {
+                    Debug.Log($"   Position: ({tile.transform.position.x:F1}, {tile.transform.position.y:F1})");
+                    Debug.Log($"   Active: {tile.activeInHierarchy}");
+                }
+            }
+
+            // Count total rendered tiles  
+            var allObjects = Object.FindObjectsByType<GameObject>(FindObjectsSortMode.None);
+            var terrainTiles = allObjects.Where(go => go.name.StartsWith("TerrainTile_")).ToArray();
+            Debug.Log($"📊 Total rendered terrain tiles: {terrainTiles.Length}");
+            Debug.Log($"📊 Expected tiles for 300x300: {300 * 300}");
+
+            if (terrainTiles.Length < 300 * 300)
+            {
+                Debug.Log($"⚠️ Missing {(300 * 300) - terrainTiles.Length} tiles!");
+
+                // Sample some missing tile names
+                for (int y = 0; y < 10; y++)
+                {
+                    for (int x = 0; x < 10; x++)
+                    {
+                        string tileName = $"TerrainTile_{x}_{y}";
+                        if (GameObject.Find(tileName) == null)
+                        {
+                            Debug.Log($"   Missing: {tileName}");
+                        }
+                    }
+                }
+            }
+        }
+        else
+        {
+            Debug.Log("⚠️ Not currently showing full map - switch to full map first");
+        }
+
+        Debug.Log("===================================");
+    }
+
+    /// <summary>
+    /// Restore team marker to correct position in full map coordinates
+    /// </summary>
+    private void RestoreTeamMarkerToFullMapPosition(Vector2Int fullMapPosition)
+    {
+        SimpleTeamPlacement teamPlacement = Object.FindFirstObjectByType<SimpleTeamPlacement>();
+        if (teamPlacement == null) return;
+
+        // In full map mode, full map coordinates = visible coordinates
+        Debug.Log($"🔧 Restoring team marker to full map position: ({fullMapPosition})");
+
+        // Update team marker position
+        teamPlacement.UpdateMarkerAfterMapChange(fullMapPosition);
+    }
+
+    /// <summary>
+    /// Get current team marker position in full map coordinates (improved version)
+    /// </summary>
+    private Vector2Int GetCurrentTeamPositionInFullMapImproved()
+    {
+        SimpleTeamPlacement teamPlacement = Object.FindFirstObjectByType<SimpleTeamPlacement>();
+        if (teamPlacement == null) return new Vector2Int(fullMapWidth / 2, fullMapHeight / 2);
+
+        // Instead of reading world position, use the stored position and convert it properly
+        Vector2Int storedPosition = teamPlacement.GetCurrentTeamPosition();
+
+        // Check if we're currently showing the full map or a partial exploration view
+        Rect exploredBounds = GetExploredBounds();
+        bool isShowingFullMap = exploredBounds.width >= fullMapWidth - 5 && exploredBounds.height >= fullMapHeight - 5;
+
+        Vector2Int fullMapPos;
+        if (isShowingFullMap)
+        {
+            // If already showing full map, stored position = full map coordinates
+            fullMapPos = storedPosition;
+            Debug.Log($"🎯 Current team position (Full Map): Stored({storedPosition}) = FullMap({fullMapPos})");
+        }
+        else
+        {
+            // If showing partial exploration view, convert exploration coordinates to full map coordinates
+            fullMapPos = new Vector2Int(
+                (int)exploredBounds.x + storedPosition.x,
+                (int)exploredBounds.y + storedPosition.y
+            );
+            Debug.Log($"🎯 Current team position (Exploration): Stored({storedPosition}) + Bounds({exploredBounds.x}, {exploredBounds.y}) → FullMap({fullMapPos})");
+            Debug.Log($"🔍 DEBUG: ExploredBounds = {exploredBounds}, IsFullMap = {isShowingFullMap}");
+        }
+
+        return fullMapPos;
+    }
+
+    /// <summary>
+    /// Restore team marker to correct position after map view changes
+    /// </summary>
+    private void RestoreTeamMarkerPosition(Vector2Int fullMapPosition)
+    {
+        SimpleTeamPlacement teamPlacement = Object.FindFirstObjectByType<SimpleTeamPlacement>();
+        if (teamPlacement == null) return;
+
+        // Check if we're currently showing the full map
+        Rect exploredBounds = GetExploredBounds();
+        bool isShowingFullMap = exploredBounds.width >= fullMapWidth - 5 && exploredBounds.height >= fullMapHeight - 5;
+
+        Vector2Int visiblePosition;
+
+        if (isShowingFullMap)
+        {
+            // If showing full map, full map coordinates = visible coordinates
+            visiblePosition = fullMapPosition;
+            Debug.Log($"🔧 Restored team marker (Full Map): FullMap({fullMapPosition}) → Visible({visiblePosition})");
+        }
+        else if (performanceMode)
+        {
+            // Account for LOD scaling in exploration mode
+            visiblePosition = new Vector2Int(
+                (fullMapPosition.x - (int)exploredBounds.x) / lodLevel,
+                (fullMapPosition.y - (int)exploredBounds.y) / lodLevel
+            );
+
+            int visibleWidth = (int)exploredBounds.width / lodLevel;
+            int visibleHeight = (int)exploredBounds.height / lodLevel;
+
+            visiblePosition.x = Mathf.Clamp(visiblePosition.x, 0, visibleWidth - 1);
+            visiblePosition.y = Mathf.Clamp(visiblePosition.y, 0, visibleHeight - 1);
+
+            Debug.Log($"🔧 Restored team marker (Exploration LOD): FullMap({fullMapPosition}) → Visible({visiblePosition}) [LOD:{lodLevel}]");
+        }
+        else
+        {
+            // Standard coordinate conversion for exploration mode
+            visiblePosition = new Vector2Int(
+                fullMapPosition.x - (int)exploredBounds.x,
+                fullMapPosition.y - (int)exploredBounds.y
+            );
+
+            int visibleWidth = (int)exploredBounds.width;
+            int visibleHeight = (int)exploredBounds.height;
+
+            visiblePosition.x = Mathf.Clamp(visiblePosition.x, 0, visibleWidth - 1);
+            visiblePosition.y = Mathf.Clamp(visiblePosition.y, 0, visibleHeight - 1);
+
+            Debug.Log($"🔧 Restored team marker (Exploration): FullMap({fullMapPosition}) → Visible({visiblePosition})");
+        }
+
+        // Update team marker position
+        teamPlacement.UpdateMarkerAfterMapChange(visiblePosition);
+    }
+
+    /// <summary>
+    /// Toggle performance mode for testing different map sizes
+    /// </summary>
+    public void TogglePerformanceMode()
+    {
+        performanceMode = !performanceMode;
+
+        if (performanceMode)
+        {
+            lodLevel = CalculateOptimalLOD(fullMapWidth, fullMapHeight);
+            Debug.Log($"⚡ Performance mode enabled with LOD {lodLevel}");
+        }
+        else
+        {
+            lodLevel = 1;
+            Debug.Log("🎯 Performance mode disabled - using full detail");
+        }
+
+        // Refresh the visible map
+        UpdateVisibleMap();
+    }
+
+    /// <summary>
+    /// Set custom map size for scalability testing
+    /// </summary>
+    public void SetMapSize(int width, int height)
+    {
+        fullMapWidth = width;
+        fullMapHeight = height;
+
+        // Auto-enable performance mode for large maps
+        if (width > 200 || height > 200)
+        {
+            performanceMode = true;
+            lodLevel = CalculateOptimalLOD(width, height);
+            Debug.Log($"⚡ Auto-enabled performance mode for {width}x{height} map (LOD {lodLevel})");
+        }
+        else
+        {
+            performanceMode = false;
+            lodLevel = 1;
+            Debug.Log($"🎯 Standard mode for {width}x{height} map");
+        }
+    }
+
+    /// <summary>
+    /// Convert world coordinates to exploration-system-aware tile coordinates
+    /// This handles the coordinate system differences between journey and exploration systems
+    /// </summary>
+    public Vector2Int ConvertWorldToExplorationCoordinates(Vector3 worldPosition)
+    {
+        // Convert world position to base tile coordinates
+        Vector2Int baseTilePos = new Vector2Int(
+            Mathf.RoundToInt(worldPosition.x),
+            Mathf.RoundToInt(worldPosition.y)
+        );
+
+        // Get current exploration bounds to determine coordinate system
+        Rect exploredBounds = GetExploredBounds();
+
+        // Check if we're showing the full map (when bounds = full map size)
+        bool isShowingFullMap = (exploredBounds.width >= fullMapWidth - 5 && exploredBounds.height >= fullMapHeight - 5);
+
+        if (isShowingFullMap)
+        {
+            // When showing full map, world coordinates ARE the exploration coordinates
+            // Just apply LOD scaling if needed
+            Vector2Int explorationCoords = baseTilePos;
+
+            if (performanceMode && lodLevel > 1)
+            {
+                explorationCoords.x = explorationCoords.x / lodLevel;
+                explorationCoords.y = explorationCoords.y / lodLevel;
+
+                // Clamp to LOD-scaled bounds
+                int lodWidth = (int)exploredBounds.width / lodLevel;
+                int lodHeight = (int)exploredBounds.height / lodLevel;
+                explorationCoords.x = Mathf.Clamp(explorationCoords.x, 0, lodWidth - 1);
+                explorationCoords.y = Mathf.Clamp(explorationCoords.y, 0, lodHeight - 1);
+            }
+            else
+            {
+                // Clamp to full map bounds
+                explorationCoords.x = Mathf.Clamp(explorationCoords.x, 0, (int)exploredBounds.width - 1);
+                explorationCoords.y = Mathf.Clamp(explorationCoords.y, 0, (int)exploredBounds.height - 1);
+            }
+
+            Debug.Log($"🌍 FULL MAP: World({worldPosition.x:F1}, {worldPosition.y:F1}) → Exploration({explorationCoords}) [LOD:{lodLevel}]");
+            return explorationCoords;
+        }
+        else
+        {
+            // Normal exploration mode - convert to relative coordinates within visible area
+            Vector2Int explorationCoords = new Vector2Int(
+                baseTilePos.x - (int)exploredBounds.x,
+                baseTilePos.y - (int)exploredBounds.y
+            );
+
+            if (performanceMode && lodLevel > 1)
+            {
+                // Apply LOD scaling
+                explorationCoords.x = explorationCoords.x / lodLevel;
+                explorationCoords.y = explorationCoords.y / lodLevel;
+
+                int visibleWidth = (int)exploredBounds.width / lodLevel;
+                int visibleHeight = (int)exploredBounds.height / lodLevel;
+
+                explorationCoords.x = Mathf.Clamp(explorationCoords.x, 0, visibleWidth - 1);
+                explorationCoords.y = Mathf.Clamp(explorationCoords.y, 0, visibleHeight - 1);
+            }
+            else
+            {
+                explorationCoords.x = Mathf.Clamp(explorationCoords.x, 0, (int)exploredBounds.width - 1);
+                explorationCoords.y = Mathf.Clamp(explorationCoords.y, 0, (int)exploredBounds.height - 1);
+            }
+
+            Debug.Log($"🔄 PARTIAL: World({worldPosition.x:F1}, {worldPosition.y:F1}) → Base({baseTilePos}) → Exploration({explorationCoords}) [LOD:{lodLevel}]");
+            return explorationCoords;
+        }
+    }
+
+    /// <summary>
+    /// Convert exploration coordinates back to world coordinates  
+    /// </summary>
+    public Vector3 ConvertExplorationToWorldCoordinates(Vector2Int explorationCoords)
+    {
+        Rect exploredBounds = GetExploredBounds();
+
+        // Check if we're showing the full map
+        bool isShowingFullMap = (exploredBounds.width >= fullMapWidth - 5 && exploredBounds.height >= fullMapHeight - 5);
+
+        Vector2Int fullMapCoords;
+
+        if (isShowingFullMap)
+        {
+            // When showing full map, exploration coordinates ARE the world coordinates (with LOD scaling)
+            if (performanceMode && lodLevel > 1)
+            {
+                // Scale up from LOD coordinates
+                fullMapCoords = new Vector2Int(
+                    explorationCoords.x * lodLevel,
+                    explorationCoords.y * lodLevel
+                );
+            }
+            else
+            {
+                // Direct mapping
+                fullMapCoords = explorationCoords;
+            }
+        }
+        else
+        {
+            // Normal exploration mode - add bounds offset
+            if (performanceMode && lodLevel > 1)
+            {
+                // Scale up coordinates and add bounds offset
+                fullMapCoords = new Vector2Int(
+                    (explorationCoords.x * lodLevel) + (int)exploredBounds.x,
+                    (explorationCoords.y * lodLevel) + (int)exploredBounds.y
+                );
+            }
+            else
+            {
+                // Direct conversion with bounds offset
+                fullMapCoords = new Vector2Int(
+                    explorationCoords.x + (int)exploredBounds.x,
+                    explorationCoords.y + (int)exploredBounds.y
+                );
+            }
+        }
+
+        Vector3 worldPos = new Vector3(fullMapCoords.x, fullMapCoords.y, 0);
+
+        Debug.Log($"🔄 Exploration({explorationCoords}) → FullMap({fullMapCoords}) → World({worldPos.x:F1}, {worldPos.y:F1}) [LOD:{lodLevel}, FullMap:{isShowingFullMap}]");
+
+        return worldPos;
+    }
+
+    /// <summary>
+    /// Synchronize team marker position between coordinate systems
+    /// Call this method when switching between journey and exploration systems
+    /// </summary>
+    public void SynchronizeTeamMarkerPosition()
+    {
+        SimpleTeamPlacement teamPlacement = Object.FindFirstObjectByType<SimpleTeamPlacement>();
+        if (teamPlacement == null) return;
+
+        GameObject teamMarker = GameObject.Find("TeamMarker");
+        if (teamMarker == null) return;
+
+        // Get current world position from the marker
+        Vector3 currentWorldPos = teamMarker.transform.position;
+
+        // Convert to proper exploration coordinates
+        Vector2Int correctExplorationCoords = ConvertWorldToExplorationCoordinates(currentWorldPos);
+
+        // Get the current stored position in team placement
+        Vector2Int storedPosition = teamPlacement.GetCurrentTeamPosition();
+
+        // Check if there's a mismatch that needs fixing
+        if (storedPosition != correctExplorationCoords)
+        {
+            Debug.Log($"🔧 Coordinate mismatch detected: Stored({storedPosition}) ≠ Calculated({correctExplorationCoords})");
+            Debug.Log($"   World position: ({currentWorldPos.x:F1}, {currentWorldPos.y:F1})");
+
+            // Fix the mismatch by updating the stored position to match the world position
+            // This preserves the actual visual location of the marker
+            teamPlacement.UpdateMarkerAfterMapChange(correctExplorationCoords);
+
+            Debug.Log($"✅ Fixed coordinate mismatch: Updated stored position to ({correctExplorationCoords})");
+        }
+        else
+        {
+            Debug.Log($"✅ Coordinates are synchronized: World({currentWorldPos.x:F1}, {currentWorldPos.y:F1}) → Exploration({correctExplorationCoords})");
+        }
+    }
+
+    /// <summary>
+    /// Debug method to show current coordinate state
+    /// </summary>
+    public void DebugCoordinateState()
+    {
+        SimpleTeamPlacement teamPlacement = Object.FindFirstObjectByType<SimpleTeamPlacement>();
+        if (teamPlacement == null) return;
+
+        GameObject teamMarker = GameObject.Find("TeamMarker");
+        if (teamMarker == null) return;
+
+        Vector3 worldPos = teamMarker.transform.position;
+        Vector2Int storedPos = teamPlacement.GetCurrentTeamPosition();
+        Vector2Int calculatedPos = ConvertWorldToExplorationCoordinates(worldPos);
+        Rect exploredBounds = GetExploredBounds();
+        bool isShowingFullMap = (exploredBounds.width >= fullMapWidth - 5 && exploredBounds.height >= fullMapHeight - 5);
+
+        Debug.Log("=== COORDINATE DEBUG ===");
+        Debug.Log($"World Position: ({worldPos.x:F1}, {worldPos.y:F1})");
+        Debug.Log($"Stored Position: ({storedPos.x}, {storedPos.y})");
+        Debug.Log($"Calculated Position: ({calculatedPos.x}, {calculatedPos.y})");
+        Debug.Log($"Explored Bounds: {exploredBounds}");
+        Debug.Log($"Showing Full Map: {isShowingFullMap}");
+        Debug.Log($"Performance Mode: {performanceMode}, LOD Level: {lodLevel}");
+        Debug.Log($"Coordinate Match: {(storedPos == calculatedPos ? "✅ YES" : "❌ NO")}");
+
+        if (storedPos != calculatedPos)
+        {
+            Debug.Log($"🔧 MISMATCH DETECTED! Use 'FIX: Force Coordinate Sync' to fix this.");
+        }
+
+        Debug.Log("========================");
+    }
+
+    /// <summary>
+    /// Force coordinate synchronization regardless of current state
+    /// </summary>
+    public void ForceCoordinateSync()
+    {
+        SimpleTeamPlacement teamPlacement = Object.FindFirstObjectByType<SimpleTeamPlacement>();
+        if (teamPlacement == null) return;
+
+        GameObject teamMarker = GameObject.Find("TeamMarker");
+        if (teamMarker == null) return;
+
+        // Get current world position from the marker
+        Vector3 currentWorldPos = teamMarker.transform.position;
+
+        // Convert to proper exploration coordinates
+        Vector2Int correctExplorationCoords = ConvertWorldToExplorationCoordinates(currentWorldPos);
+
+        // Force update the stored position
+        teamPlacement.UpdateMarkerAfterMapChange(correctExplorationCoords);
+
+        Debug.Log($"🔧 FORCED coordinate sync: World({currentWorldPos.x:F1}, {currentWorldPos.y:F1}) → Exploration({correctExplorationCoords})");
+        Debug.Log($"✅ Team marker position forcibly synchronized");
+    }
+
+    /// <summary>
+    /// Reset team marker to the center of the map (useful when coordinates get messed up)
+    /// </summary>
+    public void ResetTeamMarkerToMapCenter()
+    {
+        SimpleTeamPlacement teamPlacement = Object.FindFirstObjectByType<SimpleTeamPlacement>();
+        if (teamPlacement == null) return;
+
+        // Calculate the center of the full map
+        int centerX = fullMapWidth / 2;
+        int centerY = fullMapHeight / 2;
+        Vector2Int mapCenter = new Vector2Int(centerX, centerY);
+
+        // Check if we're currently showing the full map
+        Rect exploredBounds = GetExploredBounds();
+        bool isShowingFullMap = exploredBounds.width >= fullMapWidth - 5 && exploredBounds.height >= fullMapHeight - 5;
+
+        Vector2Int targetPosition;
+        if (isShowingFullMap)
+        {
+            // In full map mode, place at actual center coordinates
+            targetPosition = mapCenter;
+            Debug.Log($"🎯 Resetting team marker to full map center: ({targetPosition})");
+        }
+        else
+        {
+            // In exploration mode, place at center of visible area
+            targetPosition = new Vector2Int(
+                centerX - (int)exploredBounds.x,
+                centerY - (int)exploredBounds.y
+            );
+            Debug.Log($"🎯 Resetting team marker to exploration center: Full({mapCenter}) → Visible({targetPosition})");
+        }
+
+        // Update team marker position
+        teamPlacement.UpdateMarkerAfterMapChange(targetPosition);
+
+        Debug.Log($"✅ Team marker reset to map center");
+    }    /// <summary>
+         /// Generate the complete large map using existing MapMaker2 systems
+         /// </summary>
+    private void GenerateFullMap()
+    {
+        Debug.Log($"🌍 Generating full map of size {fullMapWidth}x{fullMapHeight}...");
+
+        // Temporarily modify MapMaker2 settings for large map generation
+        int originalWidth = mapMaker.mapWidth;
+        int originalHeight = mapMaker.mapHeight;
+        int originalSeed = mapMaker.seed;
+
+        mapMaker.mapWidth = fullMapWidth;
+        mapMaker.mapHeight = fullMapHeight;
+
+        // Use the same seed for consistency, but initialize it properly
+        Random.InitState(originalSeed);
+        UnityEngine.Random.InitState(originalSeed);
+
+        // Generate the full map
+        fullMapData = new MapData(fullMapWidth, fullMapHeight);
+        Debug.Log($"📊 Created MapData with size: {fullMapData.Width}x{fullMapData.Height}");
+
+        // Generate the complete map using MapMaker2's generation system
+        mapMaker.GenerateCompleteMap(fullMapData);
+
+        // Ensure roads and features connect properly across the entire map
+        PostProcessMapConnectivity();
+
+        // Restore original settings
+        mapMaker.mapWidth = originalWidth;
+        mapMaker.mapHeight = originalHeight;
+
+        // Debug settlement count in full map
+        int townCount = fullMapData.GetTowns().Count;
+        int villageCount = fullMapData.GetVillages().Count;
+        Debug.Log($"🏘️ Generated full map with {townCount} towns and {villageCount} villages");
+
+        Debug.Log("✅ Full map generation complete");
+    }
+
+    /// <summary>
+    /// Post-process the map to ensure better connectivity of roads and features
+    /// </summary>
+    private void PostProcessMapConnectivity()
+    {
+        Debug.Log("🔧 Post-processing map for better connectivity...");
+
+        // Ensure all settlements are connected by roads
+        ConnectSettlementsWithRoads();
+
+        // Smooth terrain transitions to prevent harsh breaks
+        SmoothTerrainTransitions();
+
+        // Validate water bodies and rivers for continuity
+        ValidateWaterFeatures();
+
+        Debug.Log("✅ Map connectivity post-processing complete");
+    }
+
+    /// <summary>
+    /// Connect all settlements with roads for better navigation
+    /// </summary>
+    private void ConnectSettlementsWithRoads()
+    {
+        var allSettlements = new List<Settlement>();
+        allSettlements.AddRange(fullMapData.GetTowns());
+        allSettlements.AddRange(fullMapData.GetVillages());
+
+        Debug.Log($"🛣️ Connecting {allSettlements.Count} settlements with roads...");
+
+        for (int i = 0; i < allSettlements.Count - 1; i++)
+        {
+            for (int j = i + 1; j < allSettlements.Count; j++)
+            {
+                Settlement from = allSettlements[i];
+                Settlement to = allSettlements[j];
+
+                // Only connect nearby settlements (within reasonable distance)
+                float distance = Vector2.Distance(from.position, to.position);
+                if (distance < 50f) // Adjust distance threshold as needed
+                {
+                    CreateRoadBetweenPoints(from.position, to.position);
+                }
+            }
+        }
+    }
+
+    /// <summary>
+    /// Create a road between two points
+    /// </summary>
+    private void CreateRoadBetweenPoints(Vector2Int start, Vector2Int end)
+    {
+        // Simple pathfinding - create L-shaped or direct path
+        List<Vector2Int> roadPath = new List<Vector2Int>();
+
+        // Direct line approach (can be enhanced with A* pathfinding later)
+        Vector2Int current = start;
+        Vector2Int diff = end - start;
+
+        // Horizontal movement first
+        int stepX = diff.x > 0 ? 1 : -1;
+        while (current.x != end.x)
+        {
+            roadPath.Add(current);
+            current.x += stepX;
+        }
+
+        // Vertical movement
+        int stepY = diff.y > 0 ? 1 : -1;
+        while (current.y != end.y)
+        {
+            roadPath.Add(current);
+            current.y += stepY;
+        }
+        roadPath.Add(end);
+
+        // Place road tiles
+        foreach (var point in roadPath)
+        {
+            if (IsValidExplorationPosition(point.x, point.y))
+            {
+                MapTile tile = fullMapData.GetTile(point.x, point.y);
+                if (tile != null && !tile.IsWater())
+                {
+                    // Set road feature (assuming FeatureType.Road exists)
+                    tile.featureType = FeatureType.Road;
+                }
+            }
+        }
+    }
+
+    /// <summary>
+    /// Smooth terrain transitions to prevent harsh breaks
+    /// </summary>
+    private void SmoothTerrainTransitions()
+    {
+        Debug.Log("🌄 Smoothing terrain transitions...");
+
+        // Apply smoothing filter to height values
+        for (int x = 1; x < fullMapWidth - 1; x++)
+        {
+            for (int y = 1; y < fullMapHeight - 1; y++)
+            {
+                MapTile center = fullMapData.GetTile(x, y);
+                if (center == null) continue;
+
+                // Get surrounding tiles
+                List<MapTile> neighbors = new List<MapTile>();
+                for (int dx = -1; dx <= 1; dx++)
+                {
+                    for (int dy = -1; dy <= 1; dy++)
+                    {
+                        if (dx == 0 && dy == 0) continue;
+                        MapTile neighbor = fullMapData.GetTile(x + dx, y + dy);
+                        if (neighbor != null) neighbors.Add(neighbor);
+                    }
+                }
+
+                if (neighbors.Count > 0)
+                {
+                    // Average the height with neighbors for smoother transitions
+                    float avgHeight = neighbors.Average(t => t.height);
+                    center.height = (center.height + avgHeight) * 0.5f;
+                }
+            }
+        }
+    }
+
+    /// <summary>
+    /// Validate and fix water features for better continuity
+    /// </summary>
+    private void ValidateWaterFeatures()
+    {
+        Debug.Log("🌊 Validating water features...");
+
+        // Ensure water tiles form connected bodies
+        // This is a simplified version - can be enhanced for better water flow
+        for (int x = 0; x < fullMapWidth; x++)
+        {
+            for (int y = 0; y < fullMapHeight; y++)
+            {
+                MapTile tile = fullMapData.GetTile(x, y);
+                if (tile != null && tile.IsWater())
+                {
+                    // Ensure isolated water tiles have proper connections
+                    EnsureWaterConnection(x, y);
+                }
+            }
+        }
+    }
+
+    /// <summary>
+    /// Ensure water tile has proper connections to other water
+    /// </summary>
+    private void EnsureWaterConnection(int x, int y)
+    {
+        // Count water neighbors
+        int waterNeighbors = 0;
+        for (int dx = -1; dx <= 1; dx++)
+        {
+            for (int dy = -1; dy <= 1; dy++)
+            {
+                if (dx == 0 && dy == 0) continue;
+                if (IsValidExplorationPosition(x + dx, y + dy))
+                {
+                    MapTile neighbor = fullMapData.GetTile(x + dx, y + dy);
+                    if (neighbor != null && neighbor.IsWater())
+                    {
+                        waterNeighbors++;
+                    }
+                }
+            }
+        }
+
+        // If isolated water tile, convert to land or extend water
+        if (waterNeighbors == 0)
+        {
+            MapTile tile = fullMapData.GetTile(x, y);
+            if (tile != null)
+            {
+                // Convert single water tiles to plains to prevent isolated lakes
+                tile.terrainType = TerrainType.Plains;
+            }
+        }
+    }
+
+    /// <summary>
+    /// Reveal the initial area around the map center
+    /// </summary>
+    private void RevealInitialArea()
+    {
+        int centerX = fullMapWidth / 2;
+        int centerY = fullMapHeight / 2;
+
+        int halfSize = initialVisibleSize / 2;
+
+        for (int x = centerX - halfSize; x < centerX + halfSize; x++)
+        {
+            for (int y = centerY - halfSize; y < centerY + halfSize; y++)
+            {
+                if (IsValidExplorationPosition(x, y))
+                {
+                    exploredMask[x, y] = true;
+                }
+            }
+        }
+
+        // Ensure we have at least one settlement in the initial area
+        EnsureSettlementsInInitialArea(centerX, centerY, halfSize);
+
+        Debug.Log($"🔍 Initial area revealed: {initialVisibleSize}x{initialVisibleSize} around center ({centerX}, {centerY})");
+    }
+
+    /// <summary>
+    /// Get the correct initial team position in visible map coordinates
+    /// </summary>
+    public Vector2Int GetInitialTeamPosition()
+    {
+        // The team should be placed at the center of the visible map
+        // Since we start with the full map center revealed, and the visible map shows just the explored area
+        Rect exploredBounds = GetExploredBounds();
+
+        int centerX = fullMapWidth / 2;
+        int centerY = fullMapHeight / 2;
+
+        // Convert full map center to visible map coordinates
+        Vector2Int visiblePosition = new Vector2Int(
+            centerX - (int)exploredBounds.x,
+            centerY - (int)exploredBounds.y
+        );
+
+        Debug.Log($"🎯 Initial team position: Full({centerX}, {centerY}) → Visible({visiblePosition.x}, {visiblePosition.y})");
+
+        return visiblePosition;
+    }
+
+    /// <summary>
+    /// Ensure there are settlements in the initial revealed area
+    /// </summary>
+    private void EnsureSettlementsInInitialArea(int centerX, int centerY, int halfSize)
+    {
+        // Check if there are already settlements in the initial area
+        bool hasSettlements = false;
+        var allSettlements = new List<Settlement>();
+        allSettlements.AddRange(fullMapData.GetTowns());
+        allSettlements.AddRange(fullMapData.GetVillages());
+
+        foreach (var settlement in allSettlements)
+        {
+            if (settlement.position.x >= centerX - halfSize && settlement.position.x < centerX + halfSize &&
+                settlement.position.y >= centerY - halfSize && settlement.position.y < centerY + halfSize)
+            {
+                hasSettlements = true;
+                break;
+            }
+        }
+
+        // If no settlements in initial area, place one near the center
+        if (!hasSettlements)
+        {
+            Debug.Log("⚠️ No settlements in initial area, creating one...");
+
+            // Find a good spot for a settlement near the center
+            Vector2Int settlementPos = FindSuitableSettlementPosition(centerX, centerY, halfSize - 5);
+
+            if (settlementPos != Vector2Int.zero)
+            {
+                Settlement newSettlement = new Settlement("Starting Village", SettlementType.Village, settlementPos);
+                fullMapData.AddSettlement(newSettlement);
+
+                Debug.Log($"🏘️ Created starting settlement at ({settlementPos.x}, {settlementPos.y})");
+            }
+        }
+    }
+
+    /// <summary>
+    /// Find a suitable position for a settlement within the given area
+    /// </summary>
+    private Vector2Int FindSuitableSettlementPosition(int centerX, int centerY, int searchRadius)
+    {
+        for (int radius = 5; radius <= searchRadius; radius += 5)
+        {
+            for (int angle = 0; angle < 360; angle += 45)
+            {
+                float radians = angle * Mathf.Deg2Rad;
+                int x = centerX + (int)(radius * Mathf.Cos(radians));
+                int y = centerY + (int)(radius * Mathf.Sin(radians));
+
+                if (IsValidExplorationPosition(x, y))
+                {
+                    MapTile tile = fullMapData.GetTile(x, y);
+                    if (tile != null && !tile.IsWater())
+                    {
+                        return new Vector2Int(x, y);
+                    }
+                }
+            }
+        }
+
+        // If no suitable position found, use center as fallback
+        return new Vector2Int(centerX, centerY);
+    }
+
+    /// <summary>
+    /// Check if exploration should be triggered based on player position
+    /// </summary>
+    public bool ShouldExplore(Vector2 playerPosition, MapData currentMapData)
+    {
+        // Check cooldown first
+        if (Time.time - lastExplorationTime < explorationCooldown)
+        {
+            return false;
+        }
+
+        // Convert player position to full map coordinates
+        Vector2Int playerFullMapPos = GetPlayerPositionInFullMap(playerPosition, currentMapData);
+
+        // Check distance to unexplored edges
+        bool shouldExplore = IsNearUnexploredEdge(playerFullMapPos);
+
+        if (shouldExplore)
+        {
+            Debug.Log($"✅ Exploration triggered! Player at {playerFullMapPos} near unexplored edge");
+        }
+
+        return shouldExplore;
+    }
+
+    /// <summary>
+    /// Reveal new areas around the player position
+    /// </summary>
+    public void ExploreNewAreas(Vector2 playerPosition, MapData currentMapData)
+    {
+        // Set exploration cooldown
+        lastExplorationTime = Time.time;
+
+        Vector2Int playerFullMapPos = GetPlayerPositionInFullMap(playerPosition, currentMapData);
+
+        Debug.Log($"🔍 Exploring new areas around player position {playerFullMapPos}");
+
+        // Determine which direction to explore
+        ExplorationDirection direction = GetExplorationDirection(playerFullMapPos);
+
+        // Reveal new chunk in that direction
+        RevealChunk(playerFullMapPos, direction);
+
+        // Update the visible map
+        UpdateVisibleMap();
+    }
+
+    /// <summary>
+    /// Convert player position from current map to full map coordinates
+    /// </summary>
+    private Vector2Int GetPlayerPositionInFullMap(Vector2 playerPosition, MapData currentMapData)
+    {
+        // Find the offset of the current visible area within the full map
+        Vector2Int visibleOffset = GetCurrentVisibleOffset(currentMapData);
+
+        // Ensure player position is valid within current map bounds
+        int clampedX = Mathf.Clamp((int)playerPosition.x, 0, currentMapData.Width - 1);
+        int clampedY = Mathf.Clamp((int)playerPosition.y, 0, currentMapData.Height - 1);
+
+        Vector2Int fullMapPos = new Vector2Int(
+            visibleOffset.x + clampedX,
+            visibleOffset.y + clampedY
+        );
+
+        return fullMapPos;
+    }
+
+    /// <summary>
+    /// Get the offset of the current visible area within the full map
+    /// </summary>
+    private Vector2Int GetCurrentVisibleOffset(MapData currentMapData)
+    {
+        // Find the bounds of the explored area
+        Rect exploredBounds = GetExploredBounds();
+        Vector2Int offset = new Vector2Int((int)exploredBounds.x, (int)exploredBounds.y);
+
+        return offset;
+    }
+
+    /// <summary>
+    /// Check if player is near an unexplored edge
+    /// </summary>
+    private bool IsNearUnexploredEdge(Vector2Int playerPos)
+    {
+        // Validate player position is within full map bounds
+        if (!IsValidExplorationPosition(playerPos.x, playerPos.y))
+        {
+            Debug.LogWarning($"⚠️ Player position {playerPos} is outside full map bounds!");
+            return false;
+        }
+
+        // First check: Is player near the edge of the currently explored area?
+        Rect exploredBounds = GetExploredBounds();
+
+        // Calculate distances to each edge of explored area
+        float distToLeft = playerPos.x - exploredBounds.x;
+        float distToRight = (exploredBounds.x + exploredBounds.width - 1) - playerPos.x;
+        float distToBottom = playerPos.y - exploredBounds.y;
+        float distToTop = (exploredBounds.y + exploredBounds.height - 1) - playerPos.y;
+
+        float minDistToExploredEdge = Mathf.Min(distToLeft, distToRight, distToBottom, distToTop);
+
+        if (minDistToExploredEdge <= explorationDistance)
+        {
+            Debug.Log($"🎯 Player at {playerPos} is {minDistToExploredEdge} tiles from explored edge - triggering exploration!");
+            return true;
+        }
+
+        // Second check: Look for unexplored areas within exploration distance
+        for (int dx = -(int)explorationDistance; dx <= explorationDistance; dx++)
+        {
+            for (int dy = -(int)explorationDistance; dy <= explorationDistance; dy++)
+            {
+                int checkX = playerPos.x + dx;
+                int checkY = playerPos.y + dy;
+
+                if (IsValidExplorationPosition(checkX, checkY) && !exploredMask[checkX, checkY])
+                {
+                    Debug.Log($"🎯 Found unexplored area at ({checkX}, {checkY}) near player {playerPos}");
+                    return true;
+                }
+            }
+        }
+
+        return false;
+    }
+
+    /// <summary>
+    /// Determine which direction to explore based on player position
+    /// </summary>
+    private ExplorationDirection GetExplorationDirection(Vector2Int playerPos)
+    {
+        // Find the closest unexplored edge
+        float minDistance = float.MaxValue;
+        ExplorationDirection closestDirection = ExplorationDirection.North;
+
+        // Check each direction
+        float northDist = CheckDirectionDistance(playerPos, ExplorationDirection.North);
+        float southDist = CheckDirectionDistance(playerPos, ExplorationDirection.South);
+        float eastDist = CheckDirectionDistance(playerPos, ExplorationDirection.East);
+        float westDist = CheckDirectionDistance(playerPos, ExplorationDirection.West);
+
+        // Find the minimum distance
+        if (northDist <= minDistance) { minDistance = northDist; closestDirection = ExplorationDirection.North; }
+        if (southDist <= minDistance) { minDistance = southDist; closestDirection = ExplorationDirection.South; }
+        if (eastDist <= minDistance) { minDistance = eastDist; closestDirection = ExplorationDirection.East; }
+        if (westDist <= minDistance) { minDistance = westDist; closestDirection = ExplorationDirection.West; }
+
+        Debug.Log($"🧭 Exploration direction: {closestDirection} (N:{northDist:F0}, S:{southDist:F0}, E:{eastDist:F0}, W:{westDist:F0})");
+
+        return closestDirection;
+    }
+
+    private float CheckDirectionDistance(Vector2Int playerPos, ExplorationDirection direction)
+    {
+        Vector2Int checkPos = playerPos;
+        float distance = 0;
+
+        // Move in the specified direction until we hit unexplored area
+        Vector2Int dirVector = GetDirectionVector(direction);
+
+        while (IsValidExplorationPosition(checkPos.x, checkPos.y) && exploredMask[checkPos.x, checkPos.y])
+        {
+            checkPos += dirVector;
+            distance++;
+
+            // Safety check to prevent infinite loops
+            if (distance > 100)
+            {
+                Debug.LogWarning($"⚠️ Direction check exceeded 100 steps for {direction}, breaking");
+                break;
+            }
+        }
+
+        return distance;
+    }
+
+    private Vector2Int GetDirectionVector(ExplorationDirection direction)
+    {
+        switch (direction)
+        {
+            case ExplorationDirection.North: return new Vector2Int(0, 1);
+            case ExplorationDirection.South: return new Vector2Int(0, -1);
+            case ExplorationDirection.East: return new Vector2Int(1, 0);
+            case ExplorationDirection.West: return new Vector2Int(-1, 0);
+            default: return Vector2Int.zero;
+        }
+    }
+
+    /// <summary>
+    /// Reveal a chunk of the map in the specified direction
+    /// </summary>
+    private void RevealChunk(Vector2Int playerPos, ExplorationDirection direction)
+    {
+        Vector2Int chunkCenter = GetChunkCenterForDirection(playerPos, direction);
+
+        int halfChunk = explorationChunkSize / 2;
+
+        for (int x = chunkCenter.x - halfChunk; x < chunkCenter.x + halfChunk; x++)
+        {
+            for (int y = chunkCenter.y - halfChunk; y < chunkCenter.y + halfChunk; y++)
+            {
+                if (IsValidExplorationPosition(x, y))
+                {
+                    exploredMask[x, y] = true;
+                }
+            }
+        }
+
+        Debug.Log($"✅ Revealed {explorationChunkSize}x{explorationChunkSize} chunk at {chunkCenter} in direction {direction}");
+    }
+
+    private Vector2Int GetChunkCenterForDirection(Vector2Int playerPos, ExplorationDirection direction)
+    {
+        switch (direction)
+        {
+            case ExplorationDirection.North:
+                return new Vector2Int(playerPos.x, playerPos.y + explorationChunkSize);
+            case ExplorationDirection.South:
+                return new Vector2Int(playerPos.x, playerPos.y - explorationChunkSize);
+            case ExplorationDirection.East:
+                return new Vector2Int(playerPos.x + explorationChunkSize, playerPos.y);
+            case ExplorationDirection.West:
+                return new Vector2Int(playerPos.x - explorationChunkSize, playerPos.y);
+            default:
+                return playerPos;
+        }
+    }
+
+    /// <summary>
+    /// Update the visible map data based on explored areas
+    /// </summary>
+    private void UpdateVisibleMap()
+    {
+        if (performanceMode)
+        {
+            UpdateVisibleMapOptimized();
+        }
+        else
+        {
+            UpdateVisibleMapStandard();
+        }
+    }
+
+    /// <summary>
+    /// Standard map update for smaller maps
+    /// </summary>
+    private void UpdateVisibleMapStandard()
+    {
+        // Find the bounds of the explored area
+        Rect exploredBounds = GetExploredBounds();
+
+        // Create new map data for the visible area
+        int visibleWidth = (int)exploredBounds.width;
+        int visibleHeight = (int)exploredBounds.height;
+
+        MapData newVisibleMap = new MapData(visibleWidth, visibleHeight);
+
+        // Copy explored tiles to the visible map
+        for (int x = 0; x < visibleWidth; x++)
+        {
+            for (int y = 0; y < visibleHeight; y++)
+            {
+                int fullMapX = (int)exploredBounds.x + x;
+                int fullMapY = (int)exploredBounds.y + y;
+
+                if (IsValidExplorationPosition(fullMapX, fullMapY) && exploredMask[fullMapX, fullMapY])
+                {
+                    MapTile sourceTile = fullMapData.GetTile(fullMapX, fullMapY);
+                    MapTile destTile = newVisibleMap.GetTile(x, y);
+
+                    if (sourceTile != null && destTile != null)
+                    {
+                        CopyTileData(sourceTile, destTile);
+                    }
+                }
+            }
+        }
+
+        // Copy settlements from the full map to the visible map (adjusted coordinates)
+        CopySettlementsToVisibleMap(newVisibleMap, exploredBounds);
+
+        // Update the map maker's current map data
+        mapMaker.SetMapData(newVisibleMap);
+
+        // Fix team marker position after map bounds change
+        FixTeamMarkerPosition(exploredBounds);
+
+        Debug.Log($"🗺️ Updated visible map: {visibleWidth}x{visibleHeight}");
+
+        // Debug settlement count
+        int townCount = newVisibleMap.GetTowns().Count;
+        int villageCount = newVisibleMap.GetVillages().Count;
+        Debug.Log($"🏘️ Visible settlements: {townCount} towns, {villageCount} villages");
+    }
+
+    /// <summary>
+    /// Optimized map update for large maps using Level of Detail
+    /// </summary>
+    private void UpdateVisibleMapOptimized()
+    {
+        Debug.Log($"⚡ Using optimized map update with LOD level {lodLevel}...");
+
+        // Find the bounds of the explored area
+        Rect exploredBounds = GetExploredBounds();
+
+        // Calculate downsampled dimensions
+        int visibleWidth = (int)exploredBounds.width / lodLevel;
+        int visibleHeight = (int)exploredBounds.height / lodLevel;
+
+        // Ensure minimum size
+        visibleWidth = Mathf.Max(visibleWidth, 50);
+        visibleHeight = Mathf.Max(visibleHeight, 50);
+
+        MapData newVisibleMap = new MapData(visibleWidth, visibleHeight);
+
+        // Copy tiles with Level of Detail sampling
+        for (int x = 0; x < visibleWidth; x++)
+        {
+            for (int y = 0; y < visibleHeight; y++)
+            {
+                // Sample from the full map using LOD
+                int fullMapX = (int)exploredBounds.x + (x * lodLevel);
+                int fullMapY = (int)exploredBounds.y + (y * lodLevel);
+
+                if (IsValidExplorationPosition(fullMapX, fullMapY) && exploredMask[fullMapX, fullMapY])
+                {
+                    // Average surrounding tiles for better representation
+                    MapTile sampledTile = SampleTileWithLOD(fullMapX, fullMapY, lodLevel);
+                    MapTile destTile = newVisibleMap.GetTile(x, y);
+
+                    if (sampledTile != null && destTile != null)
+                    {
+                        CopyTileData(sampledTile, destTile);
+                    }
+                }
+            }
+        }
+
+        // Copy settlements with adjusted coordinates for LOD
+        CopySettlementsToVisibleMapLOD(newVisibleMap, exploredBounds, lodLevel);
+
+        // Update the map maker's current map data
+        mapMaker.SetMapData(newVisibleMap);
+
+        // Fix team marker position with LOD adjustment
+        FixTeamMarkerPositionLOD(exploredBounds, lodLevel);
+
+        Debug.Log($"⚡ Optimized visible map updated: {visibleWidth}x{visibleHeight} (LOD {lodLevel})");
+    }
+
+    /// <summary>
+    /// Sample a tile from the full map using Level of Detail
+    /// </summary>
+    private MapTile SampleTileWithLOD(int centerX, int centerY, int sampleSize)
+    {
+        List<MapTile> sampleTiles = new List<MapTile>();
+
+        // Collect tiles in the sample area
+        for (int dx = 0; dx < sampleSize && dx + centerX < fullMapWidth; dx++)
+        {
+            for (int dy = 0; dy < sampleSize && dy + centerY < fullMapHeight; dy++)
+            {
+                MapTile tile = fullMapData.GetTile(centerX + dx, centerY + dy);
+                if (tile != null && exploredMask[centerX + dx, centerY + dy])
+                {
+                    sampleTiles.Add(tile);
+                }
+            }
+        }
+
+        if (sampleTiles.Count == 0)
+            return fullMapData.GetTile(centerX, centerY);
+
+        // Return the most common terrain type in the sample
+        var terrainGroups = sampleTiles.GroupBy(t => t.terrainType);
+        var mostCommonTerrain = terrainGroups.OrderByDescending(g => g.Count()).First().Key;
+
+        // Create a representative tile
+        MapTile representativeTile = fullMapData.GetTile(centerX, centerY);
+        if (representativeTile != null)
+        {
+            representativeTile.terrainType = mostCommonTerrain;
+            representativeTile.height = sampleTiles.Average(t => t.height);
+        }
+
+        return representativeTile;
+    }
+
+    /// <summary>
+    /// Copy settlements to visible map with LOD adjustment
+    /// </summary>
+    private void CopySettlementsToVisibleMapLOD(MapData visibleMap, Rect exploredBounds, int lod)
+    {
+        var fullTowns = fullMapData.GetTowns();
+        var fullVillages = fullMapData.GetVillages();
+
+        foreach (var town in fullTowns)
+        {
+            if (town.position.x >= exploredBounds.x && town.position.x < exploredBounds.x + exploredBounds.width &&
+                town.position.y >= exploredBounds.y && town.position.y < exploredBounds.y + exploredBounds.height)
+            {
+                Vector2Int adjustedPos = new Vector2Int(
+                    (town.position.x - (int)exploredBounds.x) / lod,
+                    (town.position.y - (int)exploredBounds.y) / lod
+                );
+
+                Settlement adjustedTown = new Settlement(town.name, town.Type, adjustedPos);
+                visibleMap.AddSettlement(adjustedTown);
+            }
+        }
+
+        foreach (var village in fullVillages)
+        {
+            if (village.position.x >= exploredBounds.x && village.position.x < exploredBounds.x + exploredBounds.width &&
+                village.position.y >= exploredBounds.y && village.position.y < exploredBounds.y + exploredBounds.height)
+            {
+                Vector2Int adjustedPos = new Vector2Int(
+                    (village.position.x - (int)exploredBounds.x) / lod,
+                    (village.position.y - (int)exploredBounds.y) / lod
+                );
+
+                Settlement adjustedVillage = new Settlement(village.name, village.Type, adjustedPos);
+                visibleMap.AddSettlement(adjustedVillage);
+            }
+        }
+    }
+
+    /// <summary>
+    /// Fix team marker position with LOD adjustment
+    /// </summary>
+    private void FixTeamMarkerPositionLOD(Rect exploredBounds, int lod)
+    {
+        SimpleTeamPlacement teamPlacement = Object.FindFirstObjectByType<SimpleTeamPlacement>();
+        if (teamPlacement == null) return;
+
+        GameObject teamMarker = GameObject.Find("TeamMarker");
+        if (teamMarker == null) return;
+
+        Vector3 currentWorldPos = teamMarker.transform.position;
+
+        // Convert to LOD-adjusted coordinates
+        Vector2Int newTilePos = new Vector2Int(
+            Mathf.RoundToInt(currentWorldPos.x) / lod,
+            Mathf.RoundToInt(currentWorldPos.y) / lod
+        );
+
+        int visibleWidth = (int)exploredBounds.width / lod;
+        int visibleHeight = (int)exploredBounds.height / lod;
+
+        newTilePos.x = Mathf.Clamp(newTilePos.x, 0, visibleWidth - 1);
+        newTilePos.y = Mathf.Clamp(newTilePos.y, 0, visibleHeight - 1);
+
+        teamPlacement.UpdateMarkerAfterMapChange(newTilePos);
+
+        Debug.Log($"⚡ Fixed team marker with LOD {lod}: World({currentWorldPos.x:F1}, {currentWorldPos.y:F1}) → Tile({newTilePos.x}, {newTilePos.y})");
+    }
+
+    /// <summary>
+    /// Fix team marker position after map bounds change
+    /// </summary>
+    private void FixTeamMarkerPosition(Rect exploredBounds)
+    {
+        SimpleTeamPlacement teamPlacement = Object.FindFirstObjectByType<SimpleTeamPlacement>();
+        if (teamPlacement == null) return;
+
+        // Get the team marker GameObject to preserve world position
+        GameObject teamMarker = GameObject.Find("TeamMarker");
+        if (teamMarker == null) return;
+
+        // Get current world position
+        Vector3 currentWorldPos = teamMarker.transform.position;
+
+        // Convert world position to new tile coordinates
+        // Assuming 1 unit = 1 tile (adjust if your tile scale is different)
+        Vector2Int newTilePos = new Vector2Int(
+            Mathf.RoundToInt(currentWorldPos.x),
+            Mathf.RoundToInt(currentWorldPos.y)
+        );
+
+        // Ensure the position is within the new visible map bounds
+        int visibleWidth = (int)exploredBounds.width;
+        int visibleHeight = (int)exploredBounds.height;
+
+        newTilePos.x = Mathf.Clamp(newTilePos.x, 0, visibleWidth - 1);
+        newTilePos.y = Mathf.Clamp(newTilePos.y, 0, visibleHeight - 1);
+
+        // Update the team placement with the corrected position
+        teamPlacement.UpdateMarkerAfterMapChange(newTilePos);
+
+        Debug.Log($"🔧 Fixed team marker: World({currentWorldPos.x:F1}, {currentWorldPos.y:F1}) → Tile({newTilePos.x}, {newTilePos.y})");
+    }    /// <summary>
+         /// Copy settlements from full map to visible map, adjusting coordinates
+         /// </summary>
+    private void CopySettlementsToVisibleMap(MapData visibleMap, Rect exploredBounds)
+    {
+        // Get settlements from full map
+        var fullTowns = fullMapData.GetTowns();
+        var fullVillages = fullMapData.GetVillages();
+
+        foreach (var town in fullTowns)
+        {
+            // Check if settlement is within explored bounds
+            if (town.position.x >= exploredBounds.x && town.position.x < exploredBounds.x + exploredBounds.width &&
+                town.position.y >= exploredBounds.y && town.position.y < exploredBounds.y + exploredBounds.height)
+            {
+                // Adjust coordinates to visible map
+                Vector2Int adjustedPos = new Vector2Int(
+                    town.position.x - (int)exploredBounds.x,
+                    town.position.y - (int)exploredBounds.y
+                );
+
+                // Create new settlement with adjusted position
+                Settlement adjustedTown = new Settlement(town.name, town.Type, adjustedPos);
+                visibleMap.AddSettlement(adjustedTown);
+            }
+        }
+
+        foreach (var village in fullVillages)
+        {
+            // Check if settlement is within explored bounds
+            if (village.position.x >= exploredBounds.x && village.position.x < exploredBounds.x + exploredBounds.width &&
+                village.position.y >= exploredBounds.y && village.position.y < exploredBounds.y + exploredBounds.height)
+            {
+                // Adjust coordinates to visible map
+                Vector2Int adjustedPos = new Vector2Int(
+                    village.position.x - (int)exploredBounds.x,
+                    village.position.y - (int)exploredBounds.y
+                );
+
+                // Create new settlement with adjusted position
+                Settlement adjustedVillage = new Settlement(village.name, village.Type, adjustedPos);
+                visibleMap.AddSettlement(adjustedVillage);
+            }
+        }
+    }
+
+    private Rect GetExploredBounds()
+    {
+        int minX = fullMapWidth, maxX = 0;
+        int minY = fullMapHeight, maxY = 0;
+
+        for (int x = 0; x < fullMapWidth; x++)
+        {
+            for (int y = 0; y < fullMapHeight; y++)
+            {
+                if (exploredMask[x, y])
+                {
+                    minX = Mathf.Min(minX, x);
+                    maxX = Mathf.Max(maxX, x);
+                    minY = Mathf.Min(minY, y);
+                    maxY = Mathf.Max(maxY, y);
+                }
+            }
+        }
+
+        return new Rect(minX, minY, maxX - minX + 1, maxY - minY + 1);
+    }
+
+    /// <summary>
+    /// Public method to get explored bounds for camera positioning
+    /// </summary>
+    public Rect GetExploredBoundsForCamera()
+    {
+        return GetExploredBounds();
+    }
+
+    /// <summary>
+    /// Update team marker position to account for new visible map coordinates
+    /// </summary>
+    private void UpdateTeamMarkerPosition(Rect exploredBounds)
+    {
+        // Get the SimpleTeamPlacement instance
+        SimpleTeamPlacement teamPlacement = Object.FindFirstObjectByType<SimpleTeamPlacement>();
+        if (teamPlacement == null)
+        {
+            Debug.LogWarning("⚠️ SimpleTeamPlacement not found - cannot update team marker position");
+            return;
+        }
+
+        // Get current team position in full map coordinates
+        Vector2Int currentFullMapPos = GetCurrentTeamPositionInFullMap();
+        if (currentFullMapPos == Vector2Int.zero)
+        {
+            Debug.LogWarning("⚠️ Could not determine current team position in full map");
+            return;
+        }
+
+        // Convert full map position to new visible map coordinates
+        Vector2Int newVisiblePos = new Vector2Int(
+            currentFullMapPos.x - (int)exploredBounds.x,
+            currentFullMapPos.y - (int)exploredBounds.y
+        );
+
+        // Validate the new position is within visible bounds
+        if (newVisiblePos.x >= 0 && newVisiblePos.x < exploredBounds.width &&
+            newVisiblePos.y >= 0 && newVisiblePos.y < exploredBounds.height)
+        {
+            // Update the team marker position
+            teamPlacement.UpdateMarkerAfterMapChange(newVisiblePos);
+
+            Debug.Log($"🎯 Updated team marker from full map pos {currentFullMapPos} to visible pos {newVisiblePos}");
+        }
+        else
+        {
+            Debug.LogWarning($"⚠️ Calculated team position {newVisiblePos} is outside visible bounds {exploredBounds}");
+        }
+    }
+
+    /// <summary>
+    /// Get current team position in full map coordinates
+    /// </summary>
+    private Vector2Int GetCurrentTeamPositionInFullMap()
+    {
+        // Try to get team position from SimpleTeamPlacement
+        SimpleTeamPlacement teamPlacement = Object.FindFirstObjectByType<SimpleTeamPlacement>();
+        if (teamPlacement == null) return Vector2Int.zero;
+
+        // Get current visible map position
+        Vector2Int currentVisiblePos = teamPlacement.GetCurrentTeamPosition();
+        if (currentVisiblePos == Vector2Int.zero) return Vector2Int.zero;
+
+        // Convert to full map coordinates
+        Vector2Int visibleOffset = GetCurrentVisibleOffset(mapMaker.GetMapData());
+        Vector2Int fullMapPos = new Vector2Int(
+            visibleOffset.x + currentVisiblePos.x,
+            visibleOffset.y + currentVisiblePos.y
+        );
+
+        return fullMapPos;
+    }
+
+    /// <summary>
+    /// Copy tile data from source to destination
+    /// </summary>
+    private void CopyTileData(MapTile source, MapTile destination)
+    {
+        destination.terrainType = source.terrainType;
+        destination.height = source.height;
+        destination.isWalkable = source.isWalkable;
+        destination.featureType = source.featureType;
+        destination.name = source.name;
+        // Copy any other tile properties as needed
+    }
+
+    private bool IsValidExplorationPosition(int x, int y)
+    {
+        return x >= 0 && x < fullMapWidth && y >= 0 && y < fullMapHeight;
+    }
+
+    /// <summary>
+    /// Get exploration progress information
+    /// </summary>
+    public ExplorationInfo GetExplorationInfo()
+    {
+        int exploredTiles = 0;
+        for (int x = 0; x < fullMapWidth; x++)
+        {
+            for (int y = 0; y < fullMapHeight; y++)
+            {
+                if (exploredMask[x, y])
+                    exploredTiles++;
+            }
+        }
+
+        int totalTiles = fullMapWidth * fullMapHeight;
+        float explorationPercentage = (float)exploredTiles / totalTiles * 100f;
+
+        return new ExplorationInfo
+        {
+            exploredTiles = exploredTiles,
+            totalTiles = totalTiles,
+            explorationPercentage = explorationPercentage,
+            fullMapSize = new Vector2Int(fullMapWidth, fullMapHeight)
+        };
+    }
+
+    /// <summary>
+    /// DEBUG: Get detailed exploration info for debugging
+    /// </summary>
+    public void DebugExplorationState(Vector2 playerPos, MapData currentMapData)
+    {
+        Vector2Int playerFullMapPos = GetPlayerPositionInFullMap(playerPos, currentMapData);
+        Rect exploredBounds = GetExploredBounds();
+
+        Debug.Log("=== EXPLORATION DEBUG ===");
+        Debug.Log($"Player Visible Pos: {playerPos}");
+        Debug.Log($"Player Full Map Pos: {playerFullMapPos}");
+        Debug.Log($"Explored Bounds: {exploredBounds}");
+        Debug.Log($"Current Map Size: {currentMapData.Width}x{currentMapData.Height}");
+        Debug.Log($"Full Map Size: {fullMapWidth}x{fullMapHeight}");
+
+        // Check distances to edges
+        float distToLeft = playerFullMapPos.x - exploredBounds.x;
+        float distToRight = (exploredBounds.x + exploredBounds.width - 1) - playerFullMapPos.x;
+        float distToBottom = playerFullMapPos.y - exploredBounds.y;
+        float distToTop = (exploredBounds.y + exploredBounds.height - 1) - playerFullMapPos.y;
+
+        Debug.Log($"Distance to edges - Left: {distToLeft}, Right: {distToRight}, Bottom: {distToBottom}, Top: {distToTop}");
+        Debug.Log($"Exploration Distance Threshold: {explorationDistance}");
+        Debug.Log($"Should Explore: {IsNearUnexploredEdge(playerFullMapPos)}");
+        Debug.Log($"Last Exploration Time: {lastExplorationTime}, Current Time: {Time.time}, Cooldown: {explorationCooldown}");
+        Debug.Log("========================");
+    }
+
+    public enum ExplorationDirection
+    {
+        North, South, East, West
+    }
+}
+
+/// <summary>
+/// Information about exploration progress
+/// </summary>
+public struct ExplorationInfo
+{
+    public int exploredTiles;
+    public int totalTiles;
+    public float explorationPercentage;
+    public Vector2Int fullMapSize;
+}

+ 103 - 0
Assets/Scripts/MapMaker2/Features/FeatureGenerator.cs

@@ -0,0 +1,103 @@
+using UnityEngine;
+using System.Collections.Generic;
+
+public class FeatureGenerator
+{
+    private SettlementGenerator settlementGenerator;
+    private RoadGenerator roadGenerator;
+
+    public FeatureGenerator()
+    {
+        settlementGenerator = new SettlementGenerator();
+        roadGenerator = new RoadGenerator();
+    }
+
+    public void GenerateFeatures(MapData mapData)
+    {
+        // Generate settlements first
+        settlementGenerator.GenerateSettlements(mapData);
+
+        // Generate roads connecting settlements (handles bridges and tunnels automatically)
+        roadGenerator.GenerateRoads(mapData);
+
+        // Generate harbours
+        GenerateHarbours(mapData);
+    }
+
+    private void GenerateHarbours(MapData mapData)
+    {
+        var settlements = mapData.GetTowns();
+        settlements.AddRange(mapData.GetVillages());
+
+        foreach (var settlement in settlements)
+        {
+            // Check if settlement is near water
+            if (IsNearWater(mapData, settlement.position.x, settlement.position.y, 3))
+            {
+                // Find a suitable position for harbour
+                var harbourPos = FindHarbourPosition(mapData, settlement.position);
+                if (harbourPos != Vector2Int.zero)
+                {
+                    mapData.GetTile(harbourPos.x, harbourPos.y).featureType = FeatureType.Harbour;
+                }
+            }
+        }
+    }
+
+    private Vector2Int FindHarbourPosition(MapData mapData, Vector2Int settlementPos)
+    {
+        for (int range = 1; range <= 3; range++)
+        {
+            for (int x = settlementPos.x - range; x <= settlementPos.x + range; x++)
+            {
+                for (int y = settlementPos.y - range; y <= settlementPos.y + range; y++)
+                {
+                    if (mapData.IsValidPosition(x, y))
+                    {
+                        MapTile tile = mapData.GetTile(x, y);
+                        if (tile.terrainType == TerrainType.Shore &&
+                            IsAdjacentToWater(mapData, x, y))
+                        {
+                            return new Vector2Int(x, y);
+                        }
+                    }
+                }
+            }
+        }
+        return Vector2Int.zero;
+    }
+
+    private bool IsNearWater(MapData mapData, int x, int y, int range)
+    {
+        for (int dx = -range; dx <= range; dx++)
+        {
+            for (int dy = -range; dy <= range; dy++)
+            {
+                int checkX = x + dx;
+                int checkY = y + dy;
+
+                if (mapData.IsValidPosition(checkX, checkY))
+                {
+                    if (mapData.GetTile(checkX, checkY).IsWater())
+                    {
+                        return true;
+                    }
+                }
+            }
+        }
+        return false;
+    }
+
+    private bool IsAdjacentToWater(MapData mapData, int x, int y)
+    {
+        var neighbors = mapData.GetNeighbors(x, y);
+        foreach (var neighbor in neighbors)
+        {
+            if (mapData.GetTile(neighbor.x, neighbor.y).IsWater())
+            {
+                return true;
+            }
+        }
+        return false;
+    }
+}

+ 238 - 0
Assets/Scripts/MapMaker2/Features/RiverGenerator.cs

@@ -0,0 +1,238 @@
+using UnityEngine;
+using System.Collections.Generic;
+
+public class RiverGenerator
+{
+    public void GenerateRivers(MapData mapData)
+    {
+        // Find water bodies to connect
+        var waterBodies = FindWaterBodies(mapData);
+
+        Debug.Log($"Found {waterBodies.Count} water body tiles for river generation");
+
+        // Generate fewer, thinner rivers between some water bodies
+        int riverCount = Mathf.Min(3, waterBodies.Count - 1); // Maximum 3 rivers
+        riverCount = Mathf.Max(1, riverCount); // Force at least 1 river if possible
+
+        Debug.Log($"Attempting to generate {riverCount} rivers");
+
+        for (int i = 0; i < riverCount && i < waterBodies.Count - 1; i++)
+        {
+            CreateRiver(mapData, waterBodies[i], waterBodies[i + 1]);
+            Debug.Log($"Created river {i + 1} from {waterBodies[i]} to {waterBodies[i + 1]}");
+        }
+    }
+    private List<Vector2Int> FindWaterBodies(MapData mapData)
+    {
+        List<Vector2Int> waterBodyCenters = new List<Vector2Int>();
+        bool[,] visited = new bool[mapData.Width, mapData.Height];
+
+        // Find distinct water bodies (groups of connected water tiles)
+        for (int x = 0; x < mapData.Width; x++)
+        {
+            for (int y = 0; y < mapData.Height; y++)
+            {
+                MapTile tile = mapData.GetTile(x, y);
+                if (!visited[x, y] && (tile.terrainType == TerrainType.Ocean || tile.terrainType == TerrainType.Lake))
+                {
+                    // Found a new water body, find its center
+                    var waterTiles = FloodFillWaterBody(mapData, visited, x, y);
+                    if (waterTiles.Count > 5) // Only consider substantial water bodies
+                    {
+                        Vector2Int center = CalculateCenter(waterTiles);
+                        waterBodyCenters.Add(center);
+                        Debug.Log($"Found water body center at {center} with {waterTiles.Count} tiles");
+                    }
+                }
+            }
+        }
+
+        return waterBodyCenters;
+    }
+
+    private List<Vector2Int> FloodFillWaterBody(MapData mapData, bool[,] visited, int startX, int startY)
+    {
+        List<Vector2Int> waterTiles = new List<Vector2Int>();
+        Queue<Vector2Int> queue = new Queue<Vector2Int>();
+        queue.Enqueue(new Vector2Int(startX, startY));
+
+        while (queue.Count > 0)
+        {
+            Vector2Int current = queue.Dequeue();
+            if (visited[current.x, current.y]) continue;
+
+            visited[current.x, current.y] = true;
+            waterTiles.Add(current);
+
+            // Check neighbors
+            for (int dx = -1; dx <= 1; dx++)
+            {
+                for (int dy = -1; dy <= 1; dy++)
+                {
+                    if (dx == 0 && dy == 0) continue;
+
+                    int newX = current.x + dx;
+                    int newY = current.y + dy;
+
+                    if (mapData.IsValidPosition(newX, newY) && !visited[newX, newY])
+                    {
+                        MapTile tile = mapData.GetTile(newX, newY);
+                        if (tile.terrainType == TerrainType.Ocean || tile.terrainType == TerrainType.Lake)
+                        {
+                            queue.Enqueue(new Vector2Int(newX, newY));
+                        }
+                    }
+                }
+            }
+        }
+
+        return waterTiles;
+    }
+
+    private Vector2Int CalculateCenter(List<Vector2Int> tiles)
+    {
+        if (tiles.Count == 0) return Vector2Int.zero;
+
+        float avgX = 0f;
+        float avgY = 0f;
+
+        foreach (var tile in tiles)
+        {
+            avgX += tile.x;
+            avgY += tile.y;
+        }
+
+        return new Vector2Int(Mathf.RoundToInt(avgX / tiles.Count), Mathf.RoundToInt(avgY / tiles.Count));
+    }
+
+    private void CreateRiver(MapData mapData, Vector2Int start, Vector2Int end)
+    {
+        var riverPath = FindRiverPath(mapData, start, end);
+
+        foreach (var point in riverPath)
+        {
+            if (mapData.IsValidPosition(point.x, point.y))
+            {
+                MapTile tile = mapData.GetTile(point.x, point.y);
+                if (tile.terrainType == TerrainType.Plains || tile.terrainType == TerrainType.Shore)
+                {
+                    tile.terrainType = TerrainType.River;
+                    tile.isWalkable = false;
+                }
+            }
+        }
+
+        // Smart diagonal blocking - only fill specific diagonal gaps
+        BlockDiagonalCrossings(mapData, riverPath);
+    }
+
+    private void BlockDiagonalCrossings(MapData mapData, List<Vector2Int> riverPath)
+    {
+        foreach (var riverPoint in riverPath)
+        {
+            // Check for diagonal gaps that would allow diagonal crossing
+            for (int dx = -1; dx <= 1; dx += 2) // -1 and 1
+            {
+                for (int dy = -1; dy <= 1; dy += 2) // -1 and 1
+                {
+                    Vector2Int diagonal = new Vector2Int(riverPoint.x + dx, riverPoint.y + dy);
+                    Vector2Int horizontal = new Vector2Int(riverPoint.x + dx, riverPoint.y);
+                    Vector2Int vertical = new Vector2Int(riverPoint.x, riverPoint.y + dy);
+
+                    if (mapData.IsValidPosition(diagonal.x, diagonal.y) &&
+                        mapData.IsValidPosition(horizontal.x, horizontal.y) &&
+                        mapData.IsValidPosition(vertical.x, vertical.y))
+                    {
+                        // If diagonal tile is river and both adjacent tiles are not river,
+                        // there's a crossable diagonal gap
+                        if (mapData.GetTile(diagonal.x, diagonal.y).terrainType == TerrainType.River &&
+                            mapData.GetTile(horizontal.x, horizontal.y).terrainType != TerrainType.River &&
+                            mapData.GetTile(vertical.x, vertical.y).terrainType != TerrainType.River)
+                        {
+                            // Fill one of the adjacent tiles to block diagonal crossing
+                            MapTile fillTile = mapData.GetTile(horizontal.x, horizontal.y);
+                            if (fillTile.terrainType == TerrainType.Plains || fillTile.terrainType == TerrainType.Shore)
+                            {
+                                fillTile.terrainType = TerrainType.River;
+                                fillTile.isWalkable = false;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+    private List<Vector2Int> FindRiverPath(MapData mapData, Vector2Int start, Vector2Int end)
+    {
+        List<Vector2Int> path = new List<Vector2Int>();
+        Vector2Int current = start;
+
+        while (Vector2Int.Distance(current, end) > 1)
+        {
+            path.Add(current);
+
+            // Move towards end with some meandering
+            Vector2Int direction = new Vector2Int(
+                end.x > current.x ? 1 : (end.x < current.x ? -1 : 0),
+                end.y > current.y ? 1 : (end.y < current.y ? -1 : 0)
+            );
+
+            // Add meandering
+            if (Random.value < 0.4f)
+            {
+                direction.x += Random.Range(-1, 2);
+                direction.y += Random.Range(-1, 2);
+                direction.x = Mathf.Clamp(direction.x, -1, 1);
+                direction.y = Mathf.Clamp(direction.y, -1, 1);
+            }
+
+            Vector2Int next = current + direction;
+            if (mapData.IsValidPosition(next.x, next.y))
+            {
+                current = next;
+            }
+            else
+            {
+                break;
+            }
+        }
+
+        return path;
+    }
+
+    private void FillRiverDiagonals(MapData mapData, int x, int y)
+    {
+        // Check and fill diagonal gaps to prevent crossing without a bridge
+        for (int dx = -1; dx <= 1; dx++)
+        {
+            for (int dy = -1; dy <= 1; dy++)
+            {
+                if (dx == 0 || dy == 0) continue; // Skip cardinal directions
+
+                int checkX = x + dx;
+                int checkY = y + dy;
+
+                if (mapData.IsValidPosition(checkX, checkY))
+                {
+                    MapTile neighbor = mapData.GetTile(checkX, checkY);
+                    if (neighbor.terrainType == TerrainType.River)
+                    {
+                        // Fill the gap
+                        int fillX = x + (dx > 0 ? 1 : 0);
+                        int fillY = y + (dy > 0 ? 1 : 0);
+
+                        if (mapData.IsValidPosition(fillX, fillY))
+                        {
+                            MapTile fillTile = mapData.GetTile(fillX, fillY);
+                            if (fillTile.terrainType == TerrainType.Plains)
+                            {
+                                fillTile.terrainType = TerrainType.River;
+                                fillTile.isWalkable = false;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+}

+ 883 - 0
Assets/Scripts/MapMaker2/Features/RoadGenerator.cs

@@ -0,0 +1,883 @@
+using UnityEngine;
+using System.Collections.Generic;
+using System.Linq;
+
+public class RoadGenerator
+{
+    public void GenerateRoads(MapData mapData)
+    {
+        var settlements = mapData.GetTowns();
+        settlements.AddRange(mapData.GetVillages());
+
+        // Connect settlements with roads
+        ConnectSettlements(mapData, settlements);
+
+        // Connect to map edges
+        ConnectToMapEdges(mapData, settlements);
+
+        // Add standalone harbours on lakes
+        GenerateLakeHarbours(mapData);
+    }
+
+    private void ConnectSettlements(MapData mapData, List<Settlement> settlements)
+    {
+        var towns = settlements.Where(s => s.Type == SettlementType.Town).ToList();
+        var villages = settlements.Where(s => s.Type == SettlementType.Village).ToList();
+
+        Debug.Log($"Connecting {towns.Count} towns and {villages.Count} villages");
+
+        // Connect towns to each other (main highway network)
+        List<List<Vector2Int>> mainRoads = new List<List<Vector2Int>>();
+        int townConnections = 0;
+        int maxTownConnections = towns.Count * (towns.Count - 1) / 2; // Limit total connections
+
+        for (int i = 0; i < towns.Count; i++)
+        {
+            for (int j = i + 1; j < towns.Count; j++)
+            {
+                townConnections++;
+                if (townConnections > maxTownConnections)
+                {
+                    Debug.LogWarning($"Limiting town connections to prevent performance issues ({townConnections}/{maxTownConnections})");
+                    break;
+                }
+
+                Debug.Log($"Creating road between towns {i} and {j}");
+                var roadPath = CreateRoad(mapData, towns[i].position, towns[j].position);
+                mainRoads.Add(roadPath);
+            }
+            if (townConnections > maxTownConnections) break;
+        }
+
+        // Create village chains - connect villages to nearest settlements (including other villages)
+        var unconnectedVillages = new List<Settlement>(villages);
+        var connectedSettlements = new List<Settlement>(towns); // Towns are already connected
+        int villageConnections = 0;
+        int maxVillageConnections = villages.Count + 10; // Safety limit
+
+        Debug.Log($"Connecting {unconnectedVillages.Count} villages to settlement network");
+
+        while (unconnectedVillages.Count > 0 && villageConnections < maxVillageConnections)
+        {
+            villageConnections++;
+            Settlement nearestVillage = null;
+            Settlement nearestTarget = null;
+            float shortestDistance = float.MaxValue;
+
+            // Find the closest unconnected village to any connected settlement
+            foreach (var village in unconnectedVillages)
+            {
+                foreach (var connectedSettlement in connectedSettlements)
+                {
+                    float distance = Vector2.Distance(
+                        new Vector2(village.position.x, village.position.y),
+                        new Vector2(connectedSettlement.position.x, connectedSettlement.position.y));
+
+                    if (distance < shortestDistance)
+                    {
+                        shortestDistance = distance;
+                        nearestVillage = village;
+                        nearestTarget = connectedSettlement;
+                    }
+                }
+            }
+
+            // Connect the nearest village and add it to connected settlements
+            if (nearestVillage != null && nearestTarget != null)
+            {
+                Debug.Log($"Connecting village {villageConnections}/{villages.Count}");
+                CreateRoad(mapData, nearestVillage.position, nearestTarget.position);
+                connectedSettlements.Add(nearestVillage);
+                unconnectedVillages.Remove(nearestVillage);
+            }
+            else
+            {
+                Debug.LogWarning("Could not find village connection, breaking loop");
+                break; // Safety break
+            }
+        }
+
+        if (villageConnections >= maxVillageConnections)
+        {
+            Debug.LogWarning($"Village connection limit reached ({maxVillageConnections}), some villages may remain unconnected");
+        }
+    }
+
+    private Vector2Int FindNearestRoadConnection(MapData mapData, Vector2Int villagePos, List<List<Vector2Int>> mainRoads, List<Settlement> towns)
+    {
+        Vector2Int nearestPoint = villagePos;
+        float nearestDistance = float.MaxValue;
+
+        // Check all main road points
+        foreach (var road in mainRoads)
+        {
+            foreach (var roadPoint in road)
+            {
+                float distance = Vector2.Distance(new Vector2(villagePos.x, villagePos.y), new Vector2(roadPoint.x, roadPoint.y));
+                if (distance < nearestDistance && distance > 5) // Don't connect too close to avoid overlaps
+                {
+                    nearestDistance = distance;
+                    nearestPoint = roadPoint;
+                }
+            }
+        }
+
+        // If no good road connection found, connect to nearest town
+        if (nearestDistance > 50f || nearestPoint == villagePos)
+        {
+            foreach (var town in towns)
+            {
+                float distance = Vector2.Distance(new Vector2(villagePos.x, villagePos.y), new Vector2(town.position.x, town.position.y));
+                if (distance < nearestDistance)
+                {
+                    nearestDistance = distance;
+                    nearestPoint = town.position;
+                }
+            }
+        }
+
+        return nearestPoint;
+    }
+
+    private void ConnectToMapEdges(MapData mapData, List<Settlement> settlements)
+    {
+        var towns = settlements.Where(s => s.Type == SettlementType.Town).ToList();
+
+        // Only connect 1-2 towns to map edges (trade routes)
+        int edgeConnections = Mathf.Min(2, towns.Count);
+
+        for (int i = 0; i < edgeConnections; i++)
+        {
+            var town = towns[i];
+            Vector2Int edgePoint = FindNearestEdgePoint(mapData, town.position);
+            CreateRoad(mapData, town.position, edgePoint);
+        }
+    }
+
+    private Vector2Int FindNearestEdgePoint(MapData mapData, Vector2Int position)
+    {
+        int distToLeft = position.x;
+        int distToRight = mapData.Width - 1 - position.x;
+        int distToTop = mapData.Height - 1 - position.y;
+        int distToBottom = position.y;
+
+        int minDist = Mathf.Min(distToLeft, distToRight, distToTop, distToBottom);
+
+        if (minDist == distToLeft)
+            return new Vector2Int(0, position.y);
+        else if (minDist == distToRight)
+            return new Vector2Int(mapData.Width - 1, position.y);
+        else if (minDist == distToTop)
+            return new Vector2Int(position.x, mapData.Height - 1);
+        else
+            return new Vector2Int(position.x, 0);
+    }
+
+    private List<Vector2Int> CreateRoad(MapData mapData, Vector2Int start, Vector2Int end)
+    {
+        var path = FindPath(mapData, start, end);
+
+        // Process the path to handle water crossings and mountain tunnels
+        path = ProcessRoadPath(mapData, path);
+
+        foreach (var point in path)
+        {
+            if (mapData.IsValidPosition(point.x, point.y))
+            {
+                MapTile tile = mapData.GetTile(point.x, point.y);
+                if (tile.featureType == FeatureType.None)
+                {
+                    // Determine road type based on terrain
+                    if (tile.IsWater())
+                    {
+                        tile.featureType = FeatureType.Bridge;
+                    }
+                    else if (tile.terrainType == TerrainType.Mountain)
+                    {
+                        tile.featureType = FeatureType.Tunnel;
+                    }
+                    else
+                    {
+                        tile.featureType = FeatureType.Road;
+                    }
+                    tile.isWalkable = true;
+                }
+            }
+        }
+
+        return path;
+    }
+
+    private List<Vector2Int> ProcessRoadPath(MapData mapData, List<Vector2Int> originalPath)
+    {
+        List<Vector2Int> processedPath = new List<Vector2Int>();
+
+        for (int i = 0; i < originalPath.Count; i++)
+        {
+            Vector2Int current = originalPath[i];
+            processedPath.Add(current);
+
+            // Check if we're about to cross water and need a bridge
+            if (i < originalPath.Count - 1)
+            {
+                Vector2Int next = originalPath[i + 1];
+
+                if (mapData.IsValidPosition(next.x, next.y) && mapData.GetTile(next.x, next.y).IsWater())
+                {
+                    // We're about to enter water, check bridge length
+                    List<Vector2Int> waterCrossing = GetWaterCrossingSegment(mapData, originalPath, i + 1);
+
+                    Debug.Log($"Water crossing detected: {waterCrossing.Count} tiles");
+
+                    if (waterCrossing.Count > 5) // Bridge too long
+                    {
+                        // Check if this is an ocean crossing - perfect for harbours and ferry
+                        if (IsOceanCrossing(mapData, waterCrossing))
+                        {
+                            Debug.Log($"Ocean crossing detected ({waterCrossing.Count} tiles) - creating harbour and ferry connection");
+                            CreateHarbourFerryConnection(mapData, current, waterCrossing, originalPath, i);
+                            // Continue with the road after the water crossing
+                            i += waterCrossing.Count; // Skip over the water tiles
+                            continue;
+                        }
+                        // Check if it's a large lake - also suitable for harbours
+                        else if (IsLargeLakeCrossing(mapData, waterCrossing))
+                        {
+                            Debug.Log($"Large lake crossing detected ({waterCrossing.Count} tiles) - creating harbour connection");
+                            CreateHarbourFerryConnection(mapData, current, waterCrossing, originalPath, i);
+                            // Continue with the road after the water crossing
+                            i += waterCrossing.Count; // Skip over the water tiles
+                            continue;
+                        }
+                        else
+                        {
+                            // It's a river or small lake - try to find alternative path or skip this connection
+                            Debug.LogWarning($"Bridge too long ({waterCrossing.Count} tiles), skipping water crossing - not suitable for harbours");
+                            break; // Stop building this road segment
+                        }
+                    }
+                    else
+                    {
+                        Debug.Log($"Water crossing short enough for bridge ({waterCrossing.Count} tiles)");
+                    }
+                }
+            }
+        }
+
+        return processedPath;
+    }
+
+    private List<Vector2Int> GetWaterCrossingSegment(MapData mapData, List<Vector2Int> path, int startIndex)
+    {
+        List<Vector2Int> waterSegment = new List<Vector2Int>();
+
+        for (int i = startIndex; i < path.Count; i++)
+        {
+            Vector2Int point = path[i];
+            if (mapData.IsValidPosition(point.x, point.y) && mapData.GetTile(point.x, point.y).IsWater())
+            {
+                waterSegment.Add(point);
+            }
+            else
+            {
+                break; // End of water crossing
+            }
+        }
+
+        return waterSegment;
+    }
+
+    private bool IsOceanCrossing(MapData mapData, List<Vector2Int> waterCrossing)
+    {
+        // Check if any of the water tiles are ocean tiles
+        int oceanTiles = 0;
+        int totalWaterTiles = 0;
+
+        foreach (var waterTile in waterCrossing)
+        {
+            if (mapData.IsValidPosition(waterTile.x, waterTile.y))
+            {
+                MapTile tile = mapData.GetTile(waterTile.x, waterTile.y);
+                totalWaterTiles++;
+                if (tile.terrainType == TerrainType.Ocean)
+                {
+                    oceanTiles++;
+                }
+            }
+        }
+
+        Debug.Log($"Water crossing analysis: {oceanTiles} ocean tiles out of {totalWaterTiles} total water tiles");
+
+        // Consider it an ocean crossing if more than 30% of the water is ocean
+        return oceanTiles > 0 && (float)oceanTiles / totalWaterTiles > 0.3f;
+    }
+
+    private bool IsLargeLakeCrossing(MapData mapData, List<Vector2Int> waterCrossing)
+    {
+        // Check if any of the water tiles are lake tiles and it's a substantial crossing
+        int lakeTiles = 0;
+        int totalWaterTiles = 0;
+
+        foreach (var waterTile in waterCrossing)
+        {
+            if (mapData.IsValidPosition(waterTile.x, waterTile.y))
+            {
+                MapTile tile = mapData.GetTile(waterTile.x, waterTile.y);
+                totalWaterTiles++;
+                if (tile.terrainType == TerrainType.Lake)
+                {
+                    lakeTiles++;
+                }
+            }
+        }
+
+        Debug.Log($"Lake crossing analysis: {lakeTiles} lake tiles out of {totalWaterTiles} total water tiles");
+
+        // Consider it a large lake crossing if:
+        // 1. More than 50% of the water is lake
+        // 2. AND the crossing is at least 8 tiles long (larger than normal bridge)
+        return lakeTiles > 0 &&
+               (float)lakeTiles / totalWaterTiles > 0.5f &&
+               waterCrossing.Count >= 8;
+    }
+
+    private void CreateHarbourFerryConnection(MapData mapData, Vector2Int roadStart, List<Vector2Int> waterCrossing, List<Vector2Int> originalPath, int pathIndex)
+    {
+        // Find the end of the water crossing to place the destination harbour
+        Vector2Int roadEnd = Vector2Int.zero;
+        int endIndex = pathIndex + 1 + waterCrossing.Count;
+
+        if (endIndex < originalPath.Count)
+        {
+            roadEnd = originalPath[endIndex];
+        }
+        else if (waterCrossing.Count > 0)
+        {
+            // Use the last water tile and find adjacent land
+            Vector2Int lastWaterTile = waterCrossing[waterCrossing.Count - 1];
+            roadEnd = FindNearestLandTile(mapData, lastWaterTile);
+        }
+
+        if (roadEnd != Vector2Int.zero)
+        {
+            // Create harbour at the start of water crossing
+            Vector2Int startHarbour = FindHarbourPosition(mapData, roadStart);
+            if (startHarbour != Vector2Int.zero && !HasNearbyHarbour(mapData, startHarbour, 8))
+            {
+                mapData.GetTile(startHarbour.x, startHarbour.y).featureType = FeatureType.Harbour;
+                Debug.Log($"Created start harbour at {startHarbour}");
+            }
+            else if (startHarbour != Vector2Int.zero)
+            {
+                Debug.Log($"Skipped start harbour at {startHarbour} - too close to existing harbour");
+                // Still try to find the existing nearby harbour for ferry connection
+                startHarbour = FindNearestHarbour(mapData, startHarbour, 8);
+            }
+
+            // Create harbour at the end of water crossing
+            Vector2Int endHarbour = FindHarbourPosition(mapData, roadEnd);
+            if (endHarbour != Vector2Int.zero && !HasNearbyHarbour(mapData, endHarbour, 8))
+            {
+                mapData.GetTile(endHarbour.x, endHarbour.y).featureType = FeatureType.Harbour;
+                Debug.Log($"Created end harbour at {endHarbour}");
+            }
+            else if (endHarbour != Vector2Int.zero)
+            {
+                Debug.Log($"Skipped end harbour at {endHarbour} - too close to existing harbour");
+                // Still try to find the existing nearby harbour for ferry connection
+                endHarbour = FindNearestHarbour(mapData, endHarbour, 8);
+            }
+
+            // Create ferry route between harbours (visual connection)
+            if (startHarbour != Vector2Int.zero && endHarbour != Vector2Int.zero)
+            {
+                CreateFerryRoute(mapData, startHarbour, endHarbour);
+            }
+        }
+    }
+
+    private Vector2Int FindHarbourPosition(MapData mapData, Vector2Int nearPosition)
+    {
+        // Look for shore tiles near the given position that can become harbours
+        for (int range = 1; range <= 5; range++)
+        {
+            for (int x = nearPosition.x - range; x <= nearPosition.x + range; x++)
+            {
+                for (int y = nearPosition.y - range; y <= nearPosition.y + range; y++)
+                {
+                    if (mapData.IsValidPosition(x, y))
+                    {
+                        MapTile tile = mapData.GetTile(x, y);
+
+                        // Perfect spot: shore tile adjacent to water
+                        if (tile.terrainType == TerrainType.Shore && IsAdjacentToWater(mapData, x, y))
+                        {
+                            return new Vector2Int(x, y);
+                        }
+
+                        // Alternative: land tile adjacent to water that we can convert to shore/harbour
+                        if ((tile.terrainType == TerrainType.Plains || tile.terrainType == TerrainType.Forest)
+                            && IsAdjacentToWater(mapData, x, y) && tile.featureType == FeatureType.None)
+                        {
+                            // Convert to shore first, then harbour
+                            tile.terrainType = TerrainType.Shore;
+                            return new Vector2Int(x, y);
+                        }
+                    }
+                }
+            }
+        }
+        return Vector2Int.zero;
+    }
+
+    private Vector2Int FindNearestLandTile(MapData mapData, Vector2Int waterPosition)
+    {
+        // Find the nearest non-water tile from the given water position
+        for (int range = 1; range <= 10; range++)
+        {
+            for (int x = waterPosition.x - range; x <= waterPosition.x + range; x++)
+            {
+                for (int y = waterPosition.y - range; y <= waterPosition.y + range; y++)
+                {
+                    if (mapData.IsValidPosition(x, y))
+                    {
+                        MapTile tile = mapData.GetTile(x, y);
+                        if (!tile.IsWater())
+                        {
+                            return new Vector2Int(x, y);
+                        }
+                    }
+                }
+            }
+        }
+        return Vector2Int.zero;
+    }
+
+    private bool IsAdjacentToWater(MapData mapData, int x, int y)
+    {
+        // Check if the tile is adjacent to any water tile
+        Vector2Int[] directions = {
+            new Vector2Int(1, 0), new Vector2Int(-1, 0),
+            new Vector2Int(0, 1), new Vector2Int(0, -1)
+        };
+
+        foreach (var dir in directions)
+        {
+            int checkX = x + dir.x;
+            int checkY = y + dir.y;
+
+            if (mapData.IsValidPosition(checkX, checkY))
+            {
+                MapTile tile = mapData.GetTile(checkX, checkY);
+                if (tile.IsWater())
+                {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    private void CreateFerryRoute(MapData mapData, Vector2Int startHarbour, Vector2Int endHarbour)
+    {
+        // Create a simple straight line ferry route for visualization
+        // This could be enhanced with ferry scheduling, costs, etc.
+
+        Vector2Int current = startHarbour;
+        Vector2Int direction = new Vector2Int(
+            endHarbour.x > startHarbour.x ? 1 : (endHarbour.x < startHarbour.x ? -1 : 0),
+            endHarbour.y > startHarbour.y ? 1 : (endHarbour.y < startHarbour.y ? -1 : 0)
+        );
+
+        int steps = 0;
+        int maxSteps = Mathf.Max(Mathf.Abs(endHarbour.x - startHarbour.x), Mathf.Abs(endHarbour.y - startHarbour.y));
+
+        while (current != endHarbour && steps < maxSteps * 2)
+        {
+            steps++;
+            current += direction;
+
+            if (mapData.IsValidPosition(current.x, current.y))
+            {
+                MapTile tile = mapData.GetTile(current.x, current.y);
+
+                // Mark water tiles as ferry route
+                if (tile.IsWater() && tile.featureType == FeatureType.None)
+                {
+                    tile.featureType = FeatureType.Ferry;
+                    tile.isWalkable = true; // Ferry routes are walkable (for a cost)
+                }
+            }
+
+            // Adjust direction to reach target
+            if (current.x != endHarbour.x)
+                direction.x = endHarbour.x > current.x ? 1 : -1;
+            if (current.y != endHarbour.y)
+                direction.y = endHarbour.y > current.y ? 1 : -1;
+        }
+
+        Debug.Log($"Created ferry route from {startHarbour} to {endHarbour}");
+    }
+
+    private void GenerateLakeHarbours(MapData mapData)
+    {
+        // Find lakes and add small harbours to them
+        HashSet<Vector2Int> processedAreas = new HashSet<Vector2Int>();
+        int harboursCreated = 0;
+        int maxHarbours = 3; // Reduced from 6 to prevent too many harbours
+
+        for (int x = 0; x < mapData.Width && harboursCreated < maxHarbours; x++)
+        {
+            for (int y = 0; y < mapData.Height && harboursCreated < maxHarbours; y++)
+            {
+                if (processedAreas.Contains(new Vector2Int(x, y)))
+                    continue;
+
+                MapTile tile = mapData.GetTile(x, y);
+                if (tile.terrainType == TerrainType.Lake)
+                {
+                    // Check if this lake is large enough for a harbour
+                    int lakeSize = MeasureLakeSize(mapData, x, y, processedAreas);
+
+                    if (lakeSize >= 25) // Increased from 15 - only add harbours to larger lakes
+                    {
+                        Vector2Int harbourPos = FindLakeHarbourPosition(mapData, x, y);
+                        if (harbourPos != Vector2Int.zero && !HasNearbyHarbour(mapData, harbourPos, 12))
+                        {
+                            mapData.GetTile(harbourPos.x, harbourPos.y).featureType = FeatureType.Harbour;
+                            harboursCreated++;
+                            Debug.Log($"Created lake harbour at {harbourPos} (lake size: {lakeSize})");
+                        }
+                        else if (harbourPos != Vector2Int.zero)
+                        {
+                            Debug.Log($"Skipped lake harbour at {harbourPos} - too close to existing harbour");
+                        }
+                    }
+                }
+            }
+        }
+
+        Debug.Log($"Generated {harboursCreated} lake harbours");
+    }
+
+    private int MeasureLakeSize(MapData mapData, int startX, int startY, HashSet<Vector2Int> processedAreas)
+    {
+        // Simple flood fill to measure lake size
+        Queue<Vector2Int> toCheck = new Queue<Vector2Int>();
+        HashSet<Vector2Int> lakeArea = new HashSet<Vector2Int>();
+
+        toCheck.Enqueue(new Vector2Int(startX, startY));
+
+        while (toCheck.Count > 0 && lakeArea.Count < 100) // Limit search to prevent performance issues
+        {
+            Vector2Int current = toCheck.Dequeue();
+
+            if (lakeArea.Contains(current) || !mapData.IsValidPosition(current.x, current.y))
+                continue;
+
+            MapTile tile = mapData.GetTile(current.x, current.y);
+            if (tile.terrainType != TerrainType.Lake)
+                continue;
+
+            lakeArea.Add(current);
+            processedAreas.Add(current);
+
+            // Check adjacent tiles
+            Vector2Int[] directions = {
+                new Vector2Int(1, 0), new Vector2Int(-1, 0),
+                new Vector2Int(0, 1), new Vector2Int(0, -1)
+            };
+
+            foreach (var dir in directions)
+            {
+                Vector2Int next = current + dir;
+                if (!lakeArea.Contains(next))
+                {
+                    toCheck.Enqueue(next);
+                }
+            }
+        }
+
+        return lakeArea.Count;
+    }
+
+    private Vector2Int FindLakeHarbourPosition(MapData mapData, int lakeX, int lakeY)
+    {
+        // Find a good position for a harbour near this lake
+        for (int range = 1; range <= 8; range++)
+        {
+            for (int x = lakeX - range; x <= lakeX + range; x++)
+            {
+                for (int y = lakeY - range; y <= lakeY + range; y++)
+                {
+                    if (mapData.IsValidPosition(x, y))
+                    {
+                        MapTile tile = mapData.GetTile(x, y);
+
+                        // Look for shore tiles or land tiles adjacent to the lake
+                        if ((tile.terrainType == TerrainType.Shore ||
+                             tile.terrainType == TerrainType.Plains ||
+                             tile.terrainType == TerrainType.Forest) &&
+                            tile.featureType == FeatureType.None &&
+                            IsAdjacentToLake(mapData, x, y))
+                        {
+                            // Convert to shore if it isn't already
+                            if (tile.terrainType != TerrainType.Shore)
+                            {
+                                tile.terrainType = TerrainType.Shore;
+                            }
+                            return new Vector2Int(x, y);
+                        }
+                    }
+                }
+            }
+        }
+        return Vector2Int.zero;
+    }
+
+    private bool HasNearbyHarbour(MapData mapData, Vector2Int position, int checkRadius)
+    {
+        // Check if there's already a harbour within the specified radius
+        for (int x = position.x - checkRadius; x <= position.x + checkRadius; x++)
+        {
+            for (int y = position.y - checkRadius; y <= position.y + checkRadius; y++)
+            {
+                if (mapData.IsValidPosition(x, y))
+                {
+                    MapTile tile = mapData.GetTile(x, y);
+                    if (tile.featureType == FeatureType.Harbour)
+                    {
+                        float distance = Vector2.Distance(
+                            new Vector2(position.x, position.y),
+                            new Vector2(x, y)
+                        );
+                        if (distance <= checkRadius)
+                        {
+                            return true;
+                        }
+                    }
+                }
+            }
+        }
+        return false;
+    }
+
+    private Vector2Int FindNearestHarbour(MapData mapData, Vector2Int position, int searchRadius)
+    {
+        // Find the nearest existing harbour within the search radius
+        Vector2Int nearestHarbour = Vector2Int.zero;
+        float nearestDistance = float.MaxValue;
+
+        for (int x = position.x - searchRadius; x <= position.x + searchRadius; x++)
+        {
+            for (int y = position.y - searchRadius; y <= position.y + searchRadius; y++)
+            {
+                if (mapData.IsValidPosition(x, y))
+                {
+                    MapTile tile = mapData.GetTile(x, y);
+                    if (tile.featureType == FeatureType.Harbour)
+                    {
+                        float distance = Vector2.Distance(
+                            new Vector2(position.x, position.y),
+                            new Vector2(x, y)
+                        );
+                        if (distance <= searchRadius && distance < nearestDistance)
+                        {
+                            nearestDistance = distance;
+                            nearestHarbour = new Vector2Int(x, y);
+                        }
+                    }
+                }
+            }
+        }
+        return nearestHarbour;
+    }
+
+    private bool IsAdjacentToLake(MapData mapData, int x, int y)
+    {
+        Vector2Int[] directions = {
+            new Vector2Int(1, 0), new Vector2Int(-1, 0),
+            new Vector2Int(0, 1), new Vector2Int(0, -1)
+        };
+
+        foreach (var dir in directions)
+        {
+            int checkX = x + dir.x;
+            int checkY = y + dir.y;
+
+            if (mapData.IsValidPosition(checkX, checkY))
+            {
+                MapTile tile = mapData.GetTile(checkX, checkY);
+                if (tile.terrainType == TerrainType.Lake)
+                {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    private List<Vector2Int> FindPath(MapData mapData, Vector2Int start, Vector2Int end)
+    {
+        // Simple pathfinding with some randomness for variation and water avoidance
+        List<Vector2Int> path = new List<Vector2Int>();
+        Vector2Int current = start;
+        HashSet<Vector2Int> visitedPositions = new HashSet<Vector2Int>();
+        int maxIterations = mapData.Width * mapData.Height; // Prevent infinite loops
+        int iterations = 0;
+
+        while (current != end && iterations < maxIterations)
+        {
+            iterations++;
+
+            // Check if we're stuck in a loop
+            if (visitedPositions.Contains(current))
+            {
+                Debug.LogWarning($"Pathfinding detected loop at {current}, breaking to prevent infinite loop");
+                break;
+            }
+
+            visitedPositions.Add(current);
+            path.Add(current);
+
+            Vector2Int direction = new Vector2Int(
+                end.x > current.x ? 1 : (end.x < current.x ? -1 : 0),
+                end.y > current.y ? 1 : (end.y < current.y ? -1 : 0)
+            );
+
+            // Add some randomness to avoid perfectly straight roads
+            if (Random.value < 0.3f)
+            {
+                if (Random.value < 0.5f)
+                    direction.x = 0;
+                else
+                    direction.y = 0;
+            }
+
+            Vector2Int nextPos = current + direction;
+
+            // Check if next position would be water and try to avoid long water crossings
+            if (mapData.IsValidPosition(nextPos.x, nextPos.y))
+            {
+                MapTile nextTile = mapData.GetTile(nextPos.x, nextPos.y);
+
+                // If next tile is water, try to find alternative route first
+                if (nextTile.IsWater())
+                {
+                    Vector2Int alternativePos = FindAlternativeRoute(mapData, current, end, visitedPositions);
+                    if (alternativePos != current && !visitedPositions.Contains(alternativePos))
+                    {
+                        nextPos = alternativePos;
+                    }
+                }
+            }
+
+            // Ensure we're making progress and not going to visited positions
+            if (!mapData.IsValidPosition(nextPos.x, nextPos.y) || visitedPositions.Contains(nextPos))
+            {
+                // Find any valid adjacent position that moves toward target
+                Vector2Int fallbackPos = FindFallbackMove(mapData, current, end, visitedPositions);
+                if (fallbackPos != current)
+                {
+                    nextPos = fallbackPos;
+                }
+                else
+                {
+                    Debug.LogWarning($"Pathfinding stuck at {current}, unable to continue to {end}");
+                    break;
+                }
+            }
+
+            current = nextPos;
+        }
+
+        if (iterations >= maxIterations)
+        {
+            Debug.LogError($"Pathfinding exceeded maximum iterations ({maxIterations}), terminating path from {start} to {end}");
+        }
+
+        // Only add end if we actually reached it
+        if (current == end)
+        {
+            path.Add(end);
+        }
+
+        return path;
+    }
+
+    private Vector2Int FindAlternativeRoute(MapData mapData, Vector2Int current, Vector2Int end, HashSet<Vector2Int> visitedPositions = null)
+    {
+        // Try to find a non-water adjacent tile that still moves toward the destination
+        Vector2Int[] directions = {
+            new Vector2Int(1, 0), new Vector2Int(-1, 0),
+            new Vector2Int(0, 1), new Vector2Int(0, -1),
+            new Vector2Int(1, 1), new Vector2Int(-1, -1),
+            new Vector2Int(1, -1), new Vector2Int(-1, 1)
+        };
+
+        Vector2Int bestDirection = Vector2Int.zero;
+        float bestScore = float.MaxValue;
+
+        foreach (var dir in directions)
+        {
+            Vector2Int candidate = current + dir;
+
+            if (mapData.IsValidPosition(candidate.x, candidate.y))
+            {
+                // Skip if we've already visited this position
+                if (visitedPositions != null && visitedPositions.Contains(candidate))
+                    continue;
+
+                MapTile candidateTile = mapData.GetTile(candidate.x, candidate.y);
+
+                // Prefer non-water tiles
+                if (!candidateTile.IsWater())
+                {
+                    // Calculate distance to end and prefer directions that move toward target
+                    float distanceToEnd = Vector2.Distance(new Vector2(candidate.x, candidate.y), new Vector2(end.x, end.y));
+                    float currentDistanceToEnd = Vector2.Distance(new Vector2(current.x, current.y), new Vector2(end.x, end.y));
+
+                    // Only consider if it moves us closer or maintains distance
+                    if (distanceToEnd <= currentDistanceToEnd + 1f && distanceToEnd < bestScore)
+                    {
+                        bestScore = distanceToEnd;
+                        bestDirection = dir;
+                    }
+                }
+            }
+        }
+
+        return bestDirection != Vector2Int.zero ? current + bestDirection : current;
+    }
+
+    private Vector2Int FindFallbackMove(MapData mapData, Vector2Int current, Vector2Int end, HashSet<Vector2Int> visitedPositions)
+    {
+        // Find any valid adjacent position that hasn't been visited and moves toward target
+        Vector2Int[] directions = {
+            new Vector2Int(1, 0), new Vector2Int(-1, 0),
+            new Vector2Int(0, 1), new Vector2Int(0, -1),
+            new Vector2Int(1, 1), new Vector2Int(-1, -1),
+            new Vector2Int(1, -1), new Vector2Int(-1, 1)
+        };
+
+        Vector2Int bestMove = current;
+        float bestDistance = float.MaxValue;
+
+        foreach (var dir in directions)
+        {
+            Vector2Int candidate = current + dir;
+
+            if (mapData.IsValidPosition(candidate.x, candidate.y) && !visitedPositions.Contains(candidate))
+            {
+                float distanceToEnd = Vector2.Distance(new Vector2(candidate.x, candidate.y), new Vector2(end.x, end.y));
+                if (distanceToEnd < bestDistance)
+                {
+                    bestDistance = distanceToEnd;
+                    bestMove = candidate;
+                }
+            }
+        }
+
+        return bestMove;
+    }
+}

+ 141 - 0
Assets/Scripts/MapMaker2/Features/SettlementGenerator.cs

@@ -0,0 +1,141 @@
+using UnityEngine;
+using System.Collections.Generic;
+using System.Linq;
+
+public class SettlementGenerator
+{
+    private static readonly string[] townNames = {
+        "Ashford", "Brookhaven", "Clearwater", "Drakemoor", "Emberfall",
+        "Frostholm", "Goldmeadow", "Ironbridge", "Moonhaven", "Oakenford",
+        "Ravenshollow", "Silverdale", "Thornwick", "Wolfsburg", "Brightwater"
+    };
+
+    private static readonly string[] villageNames = {
+        "Millbrook", "Stonefield", "Greenhill", "Redrock", "Fairhaven",
+        "Smallwood", "Riverside", "Hillcrest", "Meadowbrook", "Pinewood",
+        "Sunset", "Morning", "Pleasant", "Quiet", "Little"
+    };
+
+    public void GenerateSettlements(MapData mapData)
+    {
+        GenerateTowns(mapData);
+        GenerateVillages(mapData);
+    }
+
+    private void GenerateTowns(MapData mapData)
+    {
+        int townCount = Random.Range(2, 5);
+        int attempts = 0;
+        int maxAttempts = 100;
+
+        while (mapData.GetTowns().Count < townCount && attempts < maxAttempts)
+        {
+            attempts++;
+
+            int x = Random.Range(15, mapData.Width - 15);
+            int y = Random.Range(15, mapData.Height - 15);
+
+            if (CanPlaceSettlement(mapData, x, y, 9, 10))
+            {
+                CreateTown(mapData, x, y);
+            }
+        }
+    }
+
+    private void GenerateVillages(MapData mapData)
+    {
+        int villageCount = Random.Range(8, 15);
+        int attempts = 0;
+        int maxAttempts = 200;
+
+        while (mapData.GetVillages().Count < villageCount && attempts < maxAttempts)
+        {
+            attempts++;
+
+            int x = Random.Range(5, mapData.Width - 5);
+            int y = Random.Range(5, mapData.Height - 5);
+
+            if (CanPlaceSettlement(mapData, x, y, 1, 10))
+            {
+                CreateVillage(mapData, x, y);
+            }
+        }
+    }
+
+    private bool CanPlaceSettlement(MapData mapData, int x, int y, int size, int minDistance)
+    {
+        // Check if area is suitable (plains terrain)
+        for (int dx = -size / 2; dx <= size / 2; dx++)
+        {
+            for (int dy = -size / 2; dy <= size / 2; dy++)
+            {
+                int checkX = x + dx;
+                int checkY = y + dy;
+
+                if (!mapData.IsValidPosition(checkX, checkY))
+                    return false;
+
+                MapTile tile = mapData.GetTile(checkX, checkY);
+                if (tile.terrainType != TerrainType.Plains &&
+                    tile.terrainType != TerrainType.Shore)
+                    return false;
+            }
+        }
+
+        // Check distance from other settlements
+        var allSettlements = mapData.GetTowns();
+        allSettlements.AddRange(mapData.GetVillages());
+
+        foreach (var settlement in allSettlements)
+        {
+            float distance = Vector2.Distance(new Vector2(x, y),
+                                            new Vector2(settlement.position.x, settlement.position.y));
+            if (distance < minDistance)
+                return false;
+        }
+
+        return true;
+    }
+
+    private void CreateTown(MapData mapData, int centerX, int centerY)
+    {
+        string name = GetRandomName(townNames);
+        var settlement = new Settlement(name, SettlementType.Town, new Vector2Int(centerX, centerY));
+
+        // Create 3x3 town area
+        for (int dx = -1; dx <= 1; dx++)
+        {
+            for (int dy = -1; dy <= 1; dy++)
+            {
+                int x = centerX + dx;
+                int y = centerY + dy;
+
+                if (mapData.IsValidPosition(x, y))
+                {
+                    mapData.GetTile(x, y).featureType = FeatureType.Town;
+                    mapData.GetTile(x, y).name = name;
+                    settlement.tiles.Add(new Vector2Int(x, y));
+                }
+            }
+        }
+
+        mapData.AddSettlement(settlement);
+    }
+
+    private void CreateVillage(MapData mapData, int x, int y)
+    {
+        string name = GetRandomName(villageNames);
+        var settlement = new Settlement(name, SettlementType.Village, new Vector2Int(x, y));
+
+        mapData.GetTile(x, y).featureType = FeatureType.Village;
+        mapData.GetTile(x, y).name = name;
+        settlement.tiles.Add(new Vector2Int(x, y));
+
+        mapData.AddSettlement(settlement);
+    }
+
+    private string GetRandomName(string[] nameArray)
+    {
+        return nameArray[Random.Range(0, nameArray.Length)];
+    }
+}

+ 88 - 0
Assets/Scripts/MapMaker2/MapMaker.cs

@@ -0,0 +1,88 @@
+using UnityEngine;
+using System.Collections.Generic;
+using System.Linq;
+
+public class MapMaker : MonoBehaviour
+{
+    [Header("Map Settings")]
+    public int initialMapSize = 150;
+    public int expansionSize = 50;
+    public float playerDistanceThreshold = 20f;
+
+    [Header("Generation Settings")]
+    public int seed = 12345;
+
+    private MapData mapData;
+    private TerrainGenerator terrainGenerator;
+    private FeatureGenerator featureGenerator;
+    private ExpansionManager expansionManager;
+    private Transform player;
+
+    // Start is called once before the first execution of Update after the MonoBehaviour is created
+    void Start()
+    {
+        InitializeMap();
+        GenerateInitialMap();
+    }
+
+    // Update is called once per frame
+    void Update()
+    {
+        if (player != null)
+        {
+            CheckForExpansion();
+        }
+    }
+
+    private void InitializeMap()
+    {
+        Random.InitState(seed);
+
+        mapData = new MapData(initialMapSize, initialMapSize);
+        terrainGenerator = new TerrainGenerator();
+        featureGenerator = new FeatureGenerator();
+        //expansionManager = new ExpansionManager(this);
+
+        // Find player object (assuming it has a "Player" tag)
+        GameObject playerObj = GameObject.FindGameObjectWithTag("Player");
+        if (playerObj != null)
+            player = playerObj.transform;
+    }
+
+    private void GenerateInitialMap()
+    {
+        // Generate base terrain
+        terrainGenerator.GenerateTerrain(mapData);
+
+        // Generate features
+        featureGenerator.GenerateFeatures(mapData);
+
+        // Visualize the map (you'll need to implement this based on your rendering system)
+        VisualizeMap();
+    }
+
+    private void CheckForExpansion()
+    {
+        Vector2 playerPos = new Vector2(player.position.x, player.position.z);
+        if (expansionManager.ShouldExpand(playerPos, mapData))
+        {
+            ExpandMap(playerPos);
+        }
+    }
+
+    private void ExpandMap(Vector2 playerPos)
+    {
+        expansionManager.ExpandMap(mapData, playerPos, expansionSize);
+        VisualizeMap(); // Update visualization
+    }
+
+    private void VisualizeMap()
+    {
+        // This is where you'd implement your map visualization
+        // For now, we'll just log the map data
+        Debug.Log($"Map generated with size: {mapData.Width}x{mapData.Height}");
+        Debug.Log($"Towns: {mapData.GetTowns().Count}, Villages: {mapData.GetVillages().Count}");
+    }
+
+    public MapData GetMapData() => mapData;
+}

+ 918 - 0
Assets/Scripts/MapMaker2/MapMaker2.cs

@@ -0,0 +1,918 @@
+using UnityEngine;
+using System.Collections.Generic;
+
+public class MapMaker2 : MonoBehaviour
+{
+    [Header("Map Settings")]
+    public int initialMapSize = 150;
+    public int expansionSize = 50;
+    public float playerDistanceThreshold = 20f;
+
+    [Header("Simple Mode")]
+    [Tooltip("Use simple static map generation (no exploration/expansion)")]
+    public bool useSimpleMode = true;
+
+    [Header("Exploration Settings")]
+    [Tooltip("Use exploration system instead of expansion")]
+    public bool useExplorationSystem = true;
+
+    public void SetMapData(MapData newMapData)
+    {
+        mapData = newMapData;
+        Debug.Log($"📊 Map data updated to size: {mapData.Width}x{mapData.Height}");
+
+        // Update the visualization
+        if (mapVisualizer != null)
+        {
+            mapVisualizer.VisualizeMap(mapData);
+            Debug.Log("🗺️ Map visualization updated");
+        }
+        else
+        {
+            Debug.LogWarning("⚠️ MapVisualizer is null, cannot update visualization");
+        }
+    }
+
+    public MapData GetMapData()
+    {
+        return mapData;
+    }
+
+    [Header("Exploration Settings")]
+    public int explorationMapSize = 300;
+    public int explorationInitialVisible = 80;
+
+    [Header("Expansion Settings")]
+    [Tooltip("Cooldown time between map expansions in seconds")]
+    public float expansionCooldown = 5f;
+    [Tooltip("Chance for terrain to continue from existing edge (0-1)")]
+    [Range(0f, 1f)]
+    public float terrainContinuityChance = 0.7f;
+
+    [Header("Generation Settings")]
+    public int seed = 12345;
+
+    [Header("Visualization")]
+    public MapVisualizer mapVisualizer;
+
+    private MapData mapData;
+    private TerrainGenerator terrainGenerator;
+    private FeatureGenerator featureGenerator;
+    private ExpansionManager expansionManager;
+    private ExplorationManager explorationManager;
+    private Transform player;
+    private float lastExpansionTime = 0f;
+
+    void Start()
+    {
+        Debug.Log($"🚀 MapMaker2 starting - useSimpleMode: {useSimpleMode}, useExplorationSystem: {useExplorationSystem}");
+        InitializeMap();
+
+        if (useSimpleMode)
+        {
+            Debug.Log("🎮 Starting with Simple Mode - Full map generation with team marker placement");
+            GenerateCompleteMapWithTeamMarker();
+        }
+        else if (useExplorationSystem)
+        {
+            Debug.Log("🔍 Starting with Exploration System");
+            InitializeExplorationSystem();
+        }
+        else
+        {
+            Debug.Log("📏 Starting with Expansion System");
+            GenerateInitialMap();
+        }
+    }
+    void Update()
+    {
+        // In simple mode, no expansion or exploration updates needed
+        if (useSimpleMode)
+        {
+            // Only handle finding the player reference if missing
+            if (player == null)
+            {
+                GameObject teamMarker = GameObject.Find("TeamMarker");
+                if (teamMarker != null)
+                {
+                    player = teamMarker.transform;
+                }
+            }
+            return;
+        }
+
+        // Only handle finding the player reference, not continuous exploration checks
+        if (player == null)
+        {
+            // Debug log every few seconds to show player reference status
+            if (Time.time % 3f < Time.deltaTime)
+            {
+                Debug.LogWarning($"🚫 MapMaker2 Update: Player reference is null! useExplorationSystem: {useExplorationSystem}");
+
+                // Try to find TeamMarker if not found
+                GameObject teamMarker = GameObject.Find("TeamMarker");
+                if (teamMarker != null)
+                {
+                    Debug.Log($"🎯 Found TeamMarker at {teamMarker.transform.position}, setting as player reference");
+                    player = teamMarker.transform;
+                }
+            }
+        }
+        else if (!useExplorationSystem)
+        {
+            // Only run expansion checks for the old system
+            CheckForExpansion();
+        }
+        // Exploration system is now event-driven, no Update checks needed!
+    }
+
+    private void InitializeMap()
+    {
+        Random.InitState(seed);
+
+        mapData = new MapData(initialMapSize, initialMapSize);
+        terrainGenerator = new TerrainGenerator();
+        featureGenerator = new FeatureGenerator();
+        expansionManager = new ExpansionManager(this);
+        explorationManager = new ExplorationManager(this);
+
+        // Find player object - try multiple approaches
+        GameObject playerObj = GameObject.FindGameObjectWithTag("Player");
+
+        // If no "Player" tag found, try finding by name patterns
+        if (playerObj == null)
+        {
+            // Try common player names
+            string[] playerNames = { "TeamMarker", "Player", "PlayerCharacter", "Team", "MainCharacter" };
+            foreach (string name in playerNames)
+            {
+                playerObj = GameObject.Find(name);
+                if (playerObj != null)
+                {
+                    Debug.LogWarning($"Found player object by name '{name}' but it doesn't have 'Player' tag. Consider adding the tag.");
+                    break;
+                }
+            }
+        }
+
+        if (playerObj != null)
+        {
+            player = playerObj.transform;
+            Debug.Log($"Player found: {playerObj.name} at position {player.position}");
+        }
+        else
+        {
+            Debug.LogWarning("No player object found! Trying to find any object that might be the player...");
+            Debug.Log("Available GameObjects:");
+            GameObject[] allObjects = FindObjectsByType<GameObject>(FindObjectsSortMode.None);
+            foreach (GameObject obj in allObjects)
+            {
+                Debug.Log($"- {obj.name} (Tag: {obj.tag})");
+            }
+        }
+
+        // Initialize visualizer if not set
+        if (mapVisualizer == null)
+            mapVisualizer = GetComponent<MapVisualizer>();
+    }
+
+    private void GenerateInitialMap()
+    {
+        // Generate base terrain
+        terrainGenerator.GenerateTerrain(mapData);
+
+        // Generate features
+        featureGenerator.GenerateFeatures(mapData);
+
+        // Visualize the map
+        VisualizeMap();
+    }
+
+    /// <summary>
+    /// Generate complete map with team marker placement - Simple Mode
+    /// </summary>
+    private void GenerateCompleteMapWithTeamMarker()
+    {
+        Debug.Log("🗺️ Generating complete map with beautiful terrain...");
+
+        // Generate the full beautiful map using original generators
+        terrainGenerator.GenerateTerrain(mapData);
+        featureGenerator.GenerateFeatures(mapData);
+
+        Debug.Log("🎯 Placing team marker on a settlement...");
+
+        // Find a good settlement for team marker placement
+        Vector2Int? settlementPos = FindBestSettlementForTeamMarker();
+
+        if (settlementPos.HasValue)
+        {
+            // PlaceTeamMarkerAt(settlementPos.Value);
+            Debug.Log($"✅ Team marker placed at settlement: {settlementPos.Value}");
+        }
+        else
+        {
+            // Fallback to center if no settlements found
+            Vector2Int centerPos = new Vector2Int(mapData.Width / 2, mapData.Height / 2);
+            // PlaceTeamMarkerAt(centerPos);
+            Debug.LogWarning($"⚠️ No settlements found, placed team marker at center: {centerPos}");
+        }
+
+        // Visualize the map
+        VisualizeMap();
+
+        Debug.Log("🎮 Simple mode map generation complete!");
+    }
+
+    /// <summary>
+    /// Find the best settlement position for team marker placement
+    /// </summary>
+    private Vector2Int? FindBestSettlementForTeamMarker()
+    {
+        List<Vector2Int> settlements = new List<Vector2Int>();
+
+        // Find all towns and villages
+        for (int x = 0; x < mapData.Width; x++)
+        {
+            for (int y = 0; y < mapData.Height; y++)
+            {
+                MapTile tile = mapData.GetTile(x, y);
+                if (tile != null && (tile.featureType == FeatureType.Town || tile.featureType == FeatureType.Village))
+                {
+                    settlements.Add(new Vector2Int(x, y));
+                }
+            }
+        }
+
+        if (settlements.Count == 0) return null;
+
+        // Prefer towns over villages, and those closer to center
+        Vector2 center = new Vector2(mapData.Width / 2f, mapData.Height / 2f);
+        Vector2Int bestSettlement = settlements[0];
+        float bestScore = float.MinValue;
+
+        foreach (Vector2Int settlement in settlements)
+        {
+            MapTile tile = mapData.GetTile(settlement.x, settlement.y);
+            float score = 0;
+
+            // Prefer towns (higher score)
+            if (tile.featureType == FeatureType.Town) score += 100;
+            else score += 50; // Village
+
+            // Prefer locations closer to center (but not exactly center)
+            float distanceToCenter = Vector2.Distance(settlement, center);
+            score += Mathf.Max(0, 50 - distanceToCenter); // Closer to center = higher score
+
+            if (score > bestScore)
+            {
+                bestScore = score;
+                bestSettlement = settlement;
+            }
+        }
+
+        Debug.Log($"🏛️ Found {settlements.Count} settlements, selected {mapData.GetTile(bestSettlement.x, bestSettlement.y).featureType} at {bestSettlement}");
+        return bestSettlement;
+    }
+
+    /// <summary>
+    /// Place team marker at specified map coordinates
+    /// </summary>
+    private void PlaceTeamMarkerAt(Vector2Int mapPos)
+    {
+        // Remove existing team marker
+        GameObject existingMarker = GameObject.Find("TeamMarker");
+        if (existingMarker != null)
+        {
+            DestroyImmediate(existingMarker);
+            Debug.Log("🗑️ Removed existing team marker");
+        }
+
+        // Create new team marker
+        GameObject teamMarker = new GameObject("TeamMarkerMapMaker2");
+
+        // Position it correctly in world space
+        teamMarker.transform.position = new Vector3(mapPos.x, 0.5f, mapPos.y);
+
+        // Add visual representation
+        GameObject visualMarker = GameObject.CreatePrimitive(PrimitiveType.Sphere);
+        visualMarker.transform.SetParent(teamMarker.transform);
+        visualMarker.transform.localPosition = Vector3.zero;
+        visualMarker.transform.localScale = Vector3.one * 0.8f;
+
+        // Make it green and distinctive
+        Renderer renderer = visualMarker.GetComponent<Renderer>();
+        if (renderer != null)
+        {
+            renderer.material.color = Color.green;
+        }
+
+        // Add a tag for easy finding
+        teamMarker.tag = "Player";
+
+        Debug.Log($"📍 Team marker created at world position: {teamMarker.transform.position} (map {mapPos})");
+
+        // Update player reference
+        player = teamMarker.transform;
+    }
+
+    private void CheckForExpansion()
+    {
+        // Check if mapVisualizer is available and has valid tileSize
+        if (mapVisualizer == null)
+        {
+            Debug.LogWarning("MapVisualizer is null! Cannot check for expansion.");
+            return;
+        }
+
+        float tileSize = mapVisualizer.tileSize;
+        if (tileSize <= 0)
+        {
+            Debug.LogWarning($"Invalid tile size: {tileSize}. Using default value of 1.");
+            tileSize = 1f;
+        }
+
+        // Debug player position
+        Vector2 playerPos = new Vector2(player.position.x / tileSize, player.position.z / tileSize);
+
+        // Debug log every few seconds
+        if (Time.time % 2f < Time.deltaTime) // Log every 2 seconds
+        {
+            Debug.Log($"Player world position: {player.position}");
+            Debug.Log($"Player tile position: {playerPos} (using tileSize: {tileSize})");
+            Debug.Log($"Map size: {mapData.Width}x{mapData.Height}");
+            Debug.Log($"Distance to edges - Left: {playerPos.x:F1}, Right: {(mapData.Width - playerPos.x):F1}, Top: {(mapData.Height - playerPos.y):F1}, Bottom: {playerPos.y:F1}");
+            Debug.Log($"Expansion threshold: {playerDistanceThreshold}");
+        }
+
+        // Check cooldown to prevent rapid expansions
+        if (Time.time - lastExpansionTime < expansionCooldown)
+            return;
+
+        if (expansionManager.ShouldExpand(playerPos, mapData))
+        {
+            Debug.Log($"Expansion triggered! Player position: {playerPos}");
+            ExpandMap(playerPos);
+        }
+    }
+
+    private void ExpandMap(Vector2 playerPos)
+    {
+        lastExpansionTime = Time.time;
+
+        Debug.Log("Expanding map due to player proximity to edge...");
+        expansionManager.ExpandMap(mapData, playerPos, expansionSize);
+        VisualizeMap(); // Update visualization
+    }
+
+    private void VisualizeMap()
+    {
+        if (mapVisualizer != null)
+        {
+            mapVisualizer.VisualizeMap(mapData);
+        }
+
+        Debug.Log($"Map generated with size: {mapData.Width}x{mapData.Height}");
+        Debug.Log($"Towns: {mapData.GetTowns().Count}, Villages: {mapData.GetVillages().Count}");
+    }
+
+    public TerrainGenerator GetTerrainGenerator() => terrainGenerator;
+    public FeatureGenerator GetFeatureGenerator() => featureGenerator;
+    public ExplorationManager GetExplorationManager() => explorationManager;
+
+    // Public method to manually set player reference if automatic detection fails
+    public void SetPlayer(Transform playerTransform)
+    {
+        player = playerTransform;
+        Debug.Log($"Player manually set to: {player.name}");
+    }
+
+    /// <summary>
+    /// Enable Simple Mode - Beautiful map generation without exploration/expansion
+    /// </summary>
+    [ContextMenu("🎮 Enable Simple Mode (Beautiful Map + Team Marker)")]
+    public void EnableSimpleMode()
+    {
+        Debug.Log("🎮 Switching to Simple Mode...");
+
+        useSimpleMode = true;
+        useExplorationSystem = false;
+
+        // Clear existing map visualization
+        if (mapVisualizer != null)
+            mapVisualizer.ClearAllTiles();
+
+        // Regenerate with simple mode
+        mapData = new MapData(initialMapSize, initialMapSize);
+        GenerateCompleteMapWithTeamMarker();
+
+        Debug.Log("✅ Simple Mode enabled - Beautiful map with team marker placement!");
+    }
+
+    // For debugging - regenerate map
+    [ContextMenu("Regenerate Map")]
+    public void RegenerateMap()
+    {
+        if (mapVisualizer != null)
+            mapVisualizer.ClearAllTiles();
+
+        // Preserve current map size instead of resetting to initial size
+        int currentWidth = mapData != null ? mapData.Width : initialMapSize;
+        int currentHeight = mapData != null ? mapData.Height : initialMapSize;
+
+        Debug.Log($"Regenerating map with current size: {currentWidth}x{currentHeight}");
+
+        Random.InitState(seed);
+        mapData = new MapData(currentWidth, currentHeight);
+        terrainGenerator = new TerrainGenerator();
+        featureGenerator = new FeatureGenerator();
+
+        GenerateInitialMap();
+    }
+
+    // For debugging - reset to original size
+    [ContextMenu("Reset to Original Size")]
+    public void ResetToOriginalSize()
+    {
+        if (mapVisualizer != null)
+            mapVisualizer.ClearAllTiles();
+
+        Debug.Log($"Resetting map to original size: {initialMapSize}x{initialMapSize}");
+        InitializeMap();
+        GenerateInitialMap();
+    }
+
+    // For debugging - force map expansion
+    [ContextMenu("Force Map Expansion")]
+    public void ForceExpansion()
+    {
+        Vector2 playerPos;
+
+        if (player != null)
+        {
+            float tileSize = mapVisualizer != null && mapVisualizer.tileSize > 0 ? mapVisualizer.tileSize : 1f;
+            playerPos = new Vector2(player.position.x / tileSize, player.position.z / tileSize);
+        }
+        else
+        {
+            // If no player, expand from center-right edge to test the system
+            playerPos = new Vector2(mapData.Width - 10, mapData.Height / 2);
+            Debug.LogWarning("No player found, using test position for forced expansion");
+        }
+
+        lastExpansionTime = 0f; // Reset cooldown
+        Debug.Log($"Forcing expansion from position: {playerPos}");
+        ExpandMap(playerPos);
+    }
+
+    // For debugging - manually set TeamMarker as player
+    [ContextMenu("Set TeamMarker as Player")]
+    public void SetTeamMarkerAsPlayer()
+    {
+        GameObject teamMarker = GameObject.Find("TeamMarker");
+        if (teamMarker != null)
+        {
+            SetPlayer(teamMarker.transform);
+            Debug.Log("TeamMarker set as player successfully!");
+        }
+        else
+        {
+            Debug.LogError("TeamMarker object not found!");
+        }
+    }
+
+    // === Exploration System Methods ===
+
+    private void InitializeExplorationSystem()
+    {
+        Debug.Log("🔍 Initializing Exploration System...");
+
+        if (explorationManager == null)
+        {
+            Debug.LogError("❌ ExplorationManager is null! Cannot initialize exploration system.");
+            return;
+        }
+
+        explorationManager.fullMapWidth = explorationMapSize;
+        explorationManager.fullMapHeight = explorationMapSize;
+        explorationManager.initialVisibleSize = explorationInitialVisible;
+        explorationManager.InitializeExploration();
+
+        Debug.Log("✅ Exploration System initialization complete");
+    }
+
+    private void ExploreNewAreas(Vector2 playerPos)
+    {
+        lastExpansionTime = Time.time;
+
+        Debug.Log("🌍 Exploring new areas due to team movement...");
+        explorationManager.ExploreNewAreas(playerPos, mapData);
+        VisualizeMap(); // Update visualization
+    }
+
+    // === Public Methods for Event-Driven Exploration ===
+
+    /// <summary>
+    /// Check for exploration when team position changes (event-driven)
+    /// </summary>
+    public void OnTeamPositionChanged(Vector2Int newPosition)
+    {
+        if (!useExplorationSystem || explorationManager == null)
+            return;
+
+        // Optimization: Only check if team moved a significant distance or cooldown passed
+        if (Time.time - lastExpansionTime < expansionCooldown)
+            return;
+
+        // Convert tile position to world position for exploration system
+        Vector2 worldPos = new Vector2(newPosition.x, newPosition.y);
+
+        Debug.Log($"🚶 Team moved to {newPosition} - checking for exploration...");
+
+        if (explorationManager.ShouldExplore(worldPos, mapData))
+        {
+            Debug.Log($"🔍 Exploration triggered by team movement to {newPosition}!");
+            ExploreNewAreas(worldPos);
+        }
+    }
+
+    // === Methods needed by ExplorationManager ===
+
+    public void GenerateCompleteMap(MapData targetMapData)
+    {
+        // Generate base terrain
+        terrainGenerator.GenerateTerrain(targetMapData);
+
+        // Generate features
+        featureGenerator.GenerateFeatures(targetMapData);
+
+        Debug.Log($"✅ Complete map generated: {targetMapData.Width}x{targetMapData.Height}");
+    }
+
+    [ContextMenu("Enable Exploration System")]
+    public void EnableExplorationSystem()
+    {
+        useExplorationSystem = true;
+        Debug.Log("🔍 Exploration system enabled! Restart the scene to take effect.");
+    }
+
+    [ContextMenu("Test Exploration Now")]
+    public void TestExplorationNow()
+    {
+        if (!useExplorationSystem)
+        {
+            Debug.LogWarning("⚠️ Exploration system is not enabled! Enable it first.");
+            return;
+        }
+
+        // Debug player detection
+        Debug.Log($"🔍 Player object: {(player != null ? player.name : "NULL")}");
+        Debug.Log($"🔍 ExplorationManager: {(explorationManager != null ? "EXISTS" : "NULL")}");
+
+        if (player == null)
+        {
+            // Try to find player again
+            GameObject playerObj = GameObject.FindGameObjectWithTag("Player");
+            if (playerObj == null)
+            {
+                playerObj = GameObject.Find("TeamMarker");
+            }
+
+            if (playerObj != null)
+            {
+                player = playerObj.transform;
+                Debug.Log($"✅ Found player: {playerObj.name}");
+            }
+            else
+            {
+                Debug.LogError("❌ Cannot find player object! Make sure TeamMarker has 'Player' tag or is named 'TeamMarker'");
+                return;
+            }
+        }
+
+        if (explorationManager == null)
+        {
+            Debug.LogError("❌ ExplorationManager is null! This should be created in InitializeMap()");
+            return;
+        }
+
+        float tileSize = mapVisualizer != null && mapVisualizer.tileSize > 0 ? mapVisualizer.tileSize : 1f;
+        Vector2 playerPos = new Vector2(player.position.x / tileSize, player.position.z / tileSize);
+
+        Debug.Log($"🧪 MANUAL EXPLORATION TEST");
+        Debug.Log($"Player world position: {player.position}");
+        Debug.Log($"Player tile position: {playerPos}");
+        Debug.Log($"Current map size: {mapData.Width}x{mapData.Height}");
+        Debug.Log($"Tile size: {tileSize}");
+
+        // Force exploration regardless of cooldown
+        lastExpansionTime = 0f;
+        ExploreNewAreas(playerPos);
+    }
+
+    [ContextMenu("DEBUG: Show Full 300x300 Map")]
+    public void ShowFullMap()
+    {
+        if (!useExplorationSystem || explorationManager == null)
+        {
+            Debug.LogError("❌ Exploration system not enabled or null!");
+            return;
+        }
+
+        explorationManager.ShowFullMap();
+    }
+
+    [ContextMenu("DEBUG: Show Exploration State")]
+    public void DebugExplorationState()
+    {
+        if (!useExplorationSystem || explorationManager == null)
+        {
+            Debug.LogError("❌ Exploration system not enabled or null!");
+            return;
+        }
+
+        if (player == null)
+        {
+            GameObject teamMarker = GameObject.Find("TeamMarker");
+            if (teamMarker != null) player = teamMarker.transform;
+        }
+
+        if (player == null)
+        {
+            Debug.LogError("❌ No player/team marker found!");
+            return;
+        }
+
+        float tileSize = mapVisualizer != null && mapVisualizer.tileSize > 0 ? mapVisualizer.tileSize : 1f;
+        Vector2 playerPos = new Vector2(player.position.x / tileSize, player.position.z / tileSize);
+
+        explorationManager.DebugExplorationState(playerPos, mapData);
+    }
+
+    [ContextMenu("Disable Exploration System")]
+    public void DisableExplorationSystem()
+    {
+        useExplorationSystem = false;
+        Debug.Log("📏 Expansion system enabled! Restart the scene to take effect.");
+    }
+
+    [ContextMenu("PERF: Toggle Performance Mode")]
+    public void TogglePerformanceMode()
+    {
+        if (explorationManager != null)
+        {
+            explorationManager.TogglePerformanceMode();
+        }
+        else
+        {
+            Debug.LogError("❌ Exploration manager not available!");
+        }
+    }
+
+    [ContextMenu("PERF: Test 500x500 Map")]
+    public void TestLargeMap500()
+    {
+        if (explorationManager != null)
+        {
+            explorationManager.SetMapSize(500, 500);
+            Debug.Log("🗺️ Testing 500x500 map - will use LOD level 4 for performance");
+        }
+        else
+        {
+            Debug.LogError("❌ Exploration manager not available!");
+        }
+    }
+
+    [ContextMenu("PERF: Test 1000x1000 Map")]
+    public void TestMassiveMap1000()
+    {
+        if (explorationManager != null)
+        {
+            explorationManager.SetMapSize(1000, 1000);
+            Debug.Log("🗺️ Testing 1000x1000 map - maximum LOD will be applied");
+        }
+        else
+        {
+            Debug.LogError("❌ Exploration manager not available!");
+        }
+    }
+
+    [ContextMenu("PERF: Reset to 300x300")]
+    public void ResetToStandardSize()
+    {
+        if (explorationManager != null)
+        {
+            explorationManager.SetMapSize(300, 300);
+            Debug.Log("🗺️ Reset to standard 300x300 map");
+        }
+        else
+        {
+            Debug.LogError("❌ Exploration manager not available!");
+        }
+    }
+
+    [ContextMenu("FIX: Synchronize Team Marker Position")]
+    public void SynchronizeTeamMarkerPosition()
+    {
+        if (explorationManager != null)
+        {
+            explorationManager.SynchronizeTeamMarkerPosition();
+            Debug.Log("🔄 Team marker position synchronized between coordinate systems");
+        }
+        else
+        {
+            Debug.LogError("❌ Exploration manager not available!");
+        }
+    }
+
+    [ContextMenu("TEST: Debug Full Map Coordinate Fix")]
+    public void TestFullMapCoordinateFix()
+    {
+        if (!useExplorationSystem || explorationManager == null)
+        {
+            Debug.LogError("❌ Exploration system not enabled or null!");
+            return;
+        }
+
+        GameObject teamMarker = GameObject.Find("TeamMarker");
+        if (teamMarker == null)
+        {
+            Debug.LogError("❌ Team marker not found!");
+            return;
+        }
+
+        Vector3 worldPos = teamMarker.transform.position;
+        Vector2Int worldTilePos = new Vector2Int(
+            Mathf.RoundToInt(worldPos.x),
+            Mathf.RoundToInt(worldPos.y)
+        );
+
+        Debug.Log("🧪 COORDINATE FIX TEST - Before showing full map:");
+        Debug.Log($"   Team marker world position: {worldPos}");
+        Debug.Log($"   Team marker tile position: {worldTilePos}");
+        Debug.Log($"   Current map size: {mapData?.Width ?? 0}x{mapData?.Height ?? 0}");
+
+        // Show full map and check if position is preserved
+        explorationManager.ShowFullMap();
+
+        // Check position after full map is shown
+        Vector3 newWorldPos = teamMarker.transform.position;
+        Vector2Int newWorldTilePos = new Vector2Int(
+            Mathf.RoundToInt(newWorldPos.x),
+            Mathf.RoundToInt(newWorldPos.y)
+        );
+
+        Debug.Log("🧪 COORDINATE FIX TEST - After showing full map:");
+        Debug.Log($"   Team marker world position: {newWorldPos}");
+        Debug.Log($"   Team marker tile position: {newWorldTilePos}");
+        Debug.Log($"   Position preserved: {(worldTilePos == newWorldTilePos ? "✅ YES" : "❌ NO")}");
+
+        if (worldTilePos != newWorldTilePos)
+        {
+            Debug.LogError($"❌ COORDINATE FIX FAILED: Position changed from {worldTilePos} to {newWorldTilePos}");
+        }
+        else
+        {
+            Debug.Log("✅ COORDINATE FIX SUCCESS: Team marker position preserved when showing full map");
+        }
+    }
+
+    [ContextMenu("FIX: Reset Team Marker to Map Center")]
+    public void ResetTeamMarkerToCenter()
+    {
+        if (!useExplorationSystem || explorationManager == null)
+        {
+            Debug.LogError("❌ Exploration system not enabled or null!");
+            return;
+        }
+
+        explorationManager.ResetTeamMarkerToMapCenter();
+        Debug.Log("🎯 Team marker has been reset to the center of the map");
+    }
+
+    [ContextMenu("FIX: Clear Saved Team Position")]
+    public void ClearSavedTeamPosition()
+    {
+        // Clear saved position from PlayerPrefs
+        string keyX = $"TeamPosition_{seed}_X";
+        string keyY = $"TeamPosition_{seed}_Y";
+
+        if (PlayerPrefs.HasKey(keyX)) PlayerPrefs.DeleteKey(keyX);
+        if (PlayerPrefs.HasKey(keyY)) PlayerPrefs.DeleteKey(keyY);
+
+        PlayerPrefs.Save();
+
+        Debug.Log($"🗑️ Cleared saved team position for seed {seed}");
+        Debug.Log($"   Deleted keys: {keyX}, {keyY}");
+        Debug.Log("   Restart the scene to use default center position");
+    }
+
+    [ContextMenu("DEBUG: Show Coordinate State")]
+    public void DebugCoordinateState()
+    {
+        if (explorationManager != null)
+        {
+            explorationManager.DebugCoordinateState();
+        }
+        else
+        {
+            Debug.LogError("❌ Exploration manager not available!");
+        }
+    }
+
+    [ContextMenu("FIX: Force Coordinate Sync")]
+    public void ForceCoordinateSync()
+    {
+        if (explorationManager != null)
+        {
+            explorationManager.ForceCoordinateSync();
+        }
+        else
+        {
+            Debug.LogError("❌ Exploration manager not available!");
+        }
+    }
+
+    [ContextMenu("TEST: Simple Coordinate Conversion")]
+    public void TestSimpleCoordinateConversion()
+    {
+        if (!useExplorationSystem || explorationManager == null)
+        {
+            Debug.LogError("❌ Exploration system not enabled or null!");
+            return;
+        }
+
+        explorationManager.TestSimpleCoordinateConversion();
+    }
+
+    [ContextMenu("TEST: Positioning After Fix")]
+    public void TestPositioningAfterFix()
+    {
+        if (!useExplorationSystem || explorationManager == null)
+        {
+            Debug.LogError("❌ Exploration system not enabled or null!");
+            return;
+        }
+
+        explorationManager.TestPositioningAfterFix();
+    }
+
+    [ContextMenu("TEST: Full Map Tile Coverage")]
+    public void TestFullMapTileCoverage()
+    {
+        if (!useExplorationSystem || explorationManager == null)
+        {
+            Debug.LogError("❌ Exploration system not enabled or null!");
+            return;
+        }
+
+        explorationManager.TestFullMapTileCoverage();
+    }
+
+    [ContextMenu("TEST: Visual Tile Rendering")]
+    public void TestVisualTileRendering()
+    {
+        if (!useExplorationSystem || explorationManager == null)
+        {
+            Debug.LogError("❌ Exploration system not enabled or null!");
+            return;
+        }
+
+        explorationManager.TestVisualTileRendering();
+    }
+
+    [ContextMenu("TEST: Detailed Coordinate Conversion")]
+    public void TestDetailedCoordinateConversion()
+    {
+        if (!useExplorationSystem || explorationManager == null)
+        {
+            Debug.LogError("❌ Exploration system not enabled or null!");
+            return;
+        }
+
+        explorationManager.TestCoordinateConversion();
+    }
+
+    /// <summary>
+    /// Public method to synchronize team position - can be called by travel system
+    /// </summary>
+    public void SyncTeamPosition()
+    {
+        if (useExplorationSystem && explorationManager != null)
+        {
+            explorationManager.SynchronizeTeamMarkerPosition();
+        }
+    }
+
+    // Expose map size properties for ExplorationManager
+    public int mapWidth
+    {
+        get => mapData?.Width ?? initialMapSize;
+        set { /* Can be used by exploration system */ }
+    }
+
+    public int mapHeight
+    {
+        get => mapData?.Height ?? initialMapSize;
+        set { /* Can be used by exploration system */ }
+    }
+}

+ 163 - 0
Assets/Scripts/MapMaker2/MapMaker2Controller.cs

@@ -0,0 +1,163 @@
+using UnityEngine;
+
+/// <summary>
+/// Clean MapMaker2 controller - handles only the new system
+/// </summary>
+public class MapMaker2Controller : MonoBehaviour
+{
+    [Header("Map References")]
+    public MapMaker2 mapMaker;
+    public SimpleTeamPlacement teamPlacement;
+
+    [Header("Debug")]
+    public bool showDebugInfo = true;
+
+    void Start()
+    {
+        SetupMapMaker2System();
+    }
+
+    private void SetupMapMaker2System()
+    {
+        // Find MapMaker2 if not assigned
+        if (mapMaker == null)
+        {
+            mapMaker = FindFirstObjectByType<MapMaker2>();
+        }
+
+        // Find SimpleTeamPlacement if not assigned
+        if (teamPlacement == null)
+        {
+            teamPlacement = FindFirstObjectByType<SimpleTeamPlacement>();
+        }
+
+        // Create SimpleTeamPlacement if it doesn't exist
+        if (teamPlacement == null)
+        {
+            Debug.Log("Creating SimpleTeamPlacement...");
+            GameObject teamPlacementObj = new GameObject("SimpleTeamPlacement");
+            teamPlacement = teamPlacementObj.AddComponent<SimpleTeamPlacement>();
+
+            // Configure the team placement
+            teamPlacement.markerSize = 1.5f;
+            teamPlacement.markerZOffset = -2f;
+            teamPlacement.markerColor = Color.green;
+            teamPlacement.enableBlinking = true;
+        }
+
+        if (showDebugInfo)
+        {
+            Debug.Log("=== MapMaker2 System Status ===");
+            Debug.Log($"MapMaker2: {(mapMaker != null ? "✅ Found" : "❌ Missing")}");
+            Debug.Log($"SimpleTeamPlacement: {(teamPlacement != null ? "✅ Found" : "❌ Missing")}");
+
+            if (mapMaker != null)
+            {
+                Debug.Log($"Map Size: {mapMaker.initialMapSize}x{mapMaker.initialMapSize}");
+                Debug.Log($"Seed: {mapMaker.seed}");
+                Debug.Log($"MapVisualizer: {(mapMaker.mapVisualizer != null ? "✅ Assigned" : "❌ Missing")}");
+            }
+        }
+    }
+
+    [ContextMenu("Regenerate Map")]
+    public void RegenerateMap()
+    {
+        if (mapMaker != null)
+        {
+            // Change seed for variety
+            mapMaker.seed = Random.Range(1000, 9999);
+            mapMaker.RegenerateMap();
+
+            if (showDebugInfo)
+            {
+                Debug.Log($"🎲 Map regenerated with new seed: {mapMaker.seed}");
+            }
+        }
+        else
+        {
+            Debug.LogError("❌ MapMaker2 not found!");
+        }
+    }
+
+    [ContextMenu("Debug River Paths Info")]
+    public void DebugRiverPathsInfo()
+    {
+        if (mapMaker?.GetMapData() == null)
+        {
+            Debug.LogError("❌ No map data available");
+            return;
+        }
+
+        var mapData = mapMaker.GetMapData();
+        int riverPathsCount = 0;
+        int forestCount = 0;
+        int riverCount = 0;
+
+        // Count rivers that have forests around them (creating paths)
+        for (int x = 0; x < mapData.Width; x++)
+        {
+            for (int y = 0; y < mapData.Height; y++)
+            {
+                var tile = mapData.GetTile(x, y);
+                switch (tile.terrainType)
+                {
+                    case TerrainType.Forest:
+                        forestCount++;
+                        break;
+                    case TerrainType.River:
+                        riverCount++;
+                        // Check if this river has forests nearby (creating a path effect)
+                        bool hasNearbyForest = false;
+                        for (int dx = -1; dx <= 1; dx++)
+                        {
+                            for (int dy = -1; dy <= 1; dy++)
+                            {
+                                if (dx == 0 && dy == 0) continue;
+                                int checkX = x + dx, checkY = y + dy;
+                                if (mapData.IsValidPosition(checkX, checkY))
+                                {
+                                    if (mapData.GetTile(checkX, checkY).terrainType == TerrainType.Forest)
+                                    {
+                                        hasNearbyForest = true;
+                                        break;
+                                    }
+                                }
+                            }
+                            if (hasNearbyForest) break;
+                        }
+                        if (hasNearbyForest) riverPathsCount++;
+                        break;
+                }
+            }
+        }
+
+        Debug.Log("=== RIVER PATHS ANALYSIS ===");
+        Debug.Log($"🌊 Total River tiles: {riverCount}");
+        Debug.Log($"🌲 Forest tiles: {forestCount}");
+        Debug.Log($"🛤️ River paths through forests: {riverPathsCount}");
+        Debug.Log($"💡 Rivers create clear blue paths through green forests");
+
+        if (riverPathsCount > 0)
+        {
+            Debug.Log($"✅ SUCCESS: Found {riverPathsCount} river paths through forests! Look for blue waterways cutting through green forest areas.");
+        }
+        else
+        {
+            Debug.Log("❓ No river paths found. Try regenerating the map with a different seed.");
+        }
+    }
+    void Update()
+    {
+        // Debug keys
+        if (Input.GetKeyDown(KeyCode.F5))
+        {
+            RegenerateMap();
+        }
+
+        if (Input.GetKeyDown(KeyCode.F6))
+        {
+            DebugRiverPathsInfo();
+        }
+    }
+}

+ 0 - 0
Assets/Scripts/MapMaker2/SimpleMapClickHandler.cs


+ 506 - 0
Assets/Scripts/MapMaker2/SimpleMapMaker2.cs

@@ -0,0 +1,506 @@
+using UnityEngine;
+
+/// <summary>
+/// Simplified MapMaker2 - Basic map generation with team placement on towns/villages
+/// No exploration or expansion systems - just a clean, working map
+/// </summary>
+public class SimpleMapMaker2 : MonoBehaviour
+{
+    [Header("Basic Map Settings")]
+    public int mapSize = 100;
+    public int seed = 12345;
+
+    [Header("Team Placement")]
+    public GameObject teamMarkerPrefab;
+
+    [Header("Visualization")]
+    public MapVisualizer mapVisualizer;
+
+    // Core components
+    private MapData mapData;
+    private Transform teamMarker;
+
+    void Start()
+    {
+        GenerateSimpleMap();
+    }
+
+    /// <summary>
+    /// Generate a simple map and place team marker on a town/village
+    /// </summary>
+    public void GenerateSimpleMap()
+    {
+        Debug.Log("🗺️ SimpleMapMaker2: Generating basic map...");
+
+        // Generate basic map data
+        CreateBasicMapData();
+
+        // Visualize the map
+        if (mapVisualizer != null)
+        {
+            mapVisualizer.VisualizeMap(mapData);
+            Debug.Log("✅ Map visualization complete");
+        }
+        else
+        {
+            Debug.LogWarning("⚠️ MapVisualizer not assigned - creating simple cubes for visualization");
+            CreateSimpleCubeVisualization();
+        }
+
+        // Place team marker on a town/village
+        PlaceTeamMarkerOnTown();
+
+        Debug.Log($"🎯 SimpleMapMaker2: Map generation complete - Size: {mapSize}x{mapSize}");
+    }
+
+    /// <summary>
+    /// Create basic map data with terrain and settlements
+    /// </summary>
+    private void CreateBasicMapData()
+    {
+        Random.InitState(seed);
+
+        mapData = new MapData(mapSize, mapSize);
+
+        // Generate basic terrain
+        for (int x = 0; x < mapSize; x++)
+        {
+            for (int y = 0; y < mapSize; y++)
+            {
+                // Simple terrain generation
+                float noise = Mathf.PerlinNoise(x * 0.1f, y * 0.1f);
+
+                MapTile tile = mapData.GetTile(x, y);
+                if (tile != null)
+                {
+                    if (noise < 0.3f)
+                    {
+                        tile.terrainType = TerrainType.Plains;
+                    }
+                    else if (noise < 0.6f)
+                    {
+                        tile.terrainType = TerrainType.Forest;
+                    }
+                    else if (noise < 0.8f)
+                    {
+                        tile.terrainType = TerrainType.Plains; // Use plains for hills
+                        tile.height = 1f; // Use height for elevation
+                    }
+                    else
+                    {
+                        tile.terrainType = TerrainType.Mountain;
+                    }
+                }
+            }
+        }
+
+        // Add some roads
+        AddBasicRoads();
+
+        // Add settlements (towns and villages)
+        AddSettlements();
+
+        Debug.Log($"📊 Basic map data created: {mapSize}x{mapSize}");
+    }
+
+    /// <summary>
+    /// Add basic road network
+    /// </summary>
+    private void AddBasicRoads()
+    {
+        // Horizontal road across the middle
+        int midY = mapSize / 2;
+        for (int x = 0; x < mapSize; x++)
+        {
+            MapTile tile = mapData.GetTile(x, midY);
+            if (tile != null && tile.terrainType != TerrainType.Mountain)
+            {
+                tile.featureType = FeatureType.Road;
+            }
+        }
+
+        // Vertical road across the middle
+        int midX = mapSize / 2;
+        for (int y = 0; y < mapSize; y++)
+        {
+            MapTile tile = mapData.GetTile(midX, y);
+            if (tile != null && tile.terrainType != TerrainType.Mountain)
+            {
+                tile.featureType = FeatureType.Road;
+            }
+        }
+
+        Debug.Log("🛤️ Basic roads added");
+    }
+
+    /// <summary>
+    /// Add towns and villages to the map
+    /// </summary>
+    private void AddSettlements()
+    {
+        // Add a few towns and villages
+        Vector2Int[] settlementPositions = {
+            new Vector2Int(25, 25),
+            new Vector2Int(75, 25),
+            new Vector2Int(25, 75),
+            new Vector2Int(75, 75),
+            new Vector2Int(50, 50), // Center town
+            new Vector2Int(30, 60),
+            new Vector2Int(70, 40)
+        };
+
+        for (int i = 0; i < settlementPositions.Length; i++)
+        {
+            Vector2Int pos = settlementPositions[i];
+
+            // Make sure position is valid
+            if (pos.x >= 0 && pos.x < mapSize && pos.y >= 0 && pos.y < mapSize)
+            {
+                MapTile tile = mapData.GetTile(pos.x, pos.y);
+                if (tile != null)
+                {
+                    // First three are towns, rest are villages
+                    FeatureType settlementType = i < 3 ? FeatureType.Town : FeatureType.Village;
+                    tile.featureType = settlementType;
+
+                    // Give settlements names
+                    if (settlementType == FeatureType.Town)
+                    {
+                        tile.name = $"Town_{i + 1}";
+                    }
+                    else
+                    {
+                        tile.name = $"Village_{i + 1}";
+                    }
+
+                    Debug.Log($"🏘️ Placed {settlementType} at ({pos.x}, {pos.y})");
+                }
+            }
+        }
+    }
+
+    /// <summary>
+    /// Place team marker on a town or village
+    /// </summary>
+    private void PlaceTeamMarkerOnTown()
+    {
+        // Find a suitable town or village
+        Vector2Int? townPosition = FindTownOrVillage();
+
+        if (townPosition.HasValue)
+        {
+            PlaceTeamMarkerAt(townPosition.Value);
+        }
+        else
+        {
+            // Fallback to center if no town found
+            Debug.LogWarning("⚠️ No town/village found, placing team marker at center");
+            PlaceTeamMarkerAt(new Vector2Int(mapSize / 2, mapSize / 2));
+        }
+    }
+
+    /// <summary>
+    /// Find the first town or village on the map
+    /// </summary>
+    private Vector2Int? FindTownOrVillage()
+    {
+        for (int x = 0; x < mapSize; x++)
+        {
+            for (int y = 0; y < mapSize; y++)
+            {
+                MapTile tile = mapData.GetTile(x, y);
+                if (tile != null && (tile.featureType == FeatureType.Town || tile.featureType == FeatureType.Village))
+                {
+                    return new Vector2Int(x, y);
+                }
+            }
+        }
+        return null;
+    }
+
+    /// <summary>
+    /// Place team marker at specific map coordinates
+    /// </summary>
+    private void PlaceTeamMarkerAt(Vector2Int mapPos)
+    {
+        // Find existing team marker or create one
+        GameObject teamMarkerObj = GameObject.Find("TeamMarker");
+
+        if (teamMarkerObj == null)
+        {
+            // Create a simple team marker if none exists
+            if (teamMarkerPrefab != null)
+            {
+                teamMarkerObj = Instantiate(teamMarkerPrefab);
+                teamMarkerObj.name = "TeamMarkerSimpleMapMaker2";
+                Debug.Log("🎯 Created new TeamMarker from prefab");
+            }
+            else
+            {
+                // Create a simple sphere as team marker
+                teamMarkerObj = GameObject.CreatePrimitive(PrimitiveType.Sphere);
+                teamMarkerObj.name = "TeamMarkerSimplMapMaker2";
+                teamMarkerObj.transform.localScale = new Vector3(2f, 2f, 2f);
+
+                // Make it green and easily visible
+                Renderer renderer = teamMarkerObj.GetComponent<Renderer>();
+                if (renderer != null)
+                {
+                    renderer.material.color = Color.green;
+                }
+
+                Debug.Log("🎯 Created simple sphere TeamMarker");
+            }
+        }
+
+        if (teamMarkerObj != null)
+        {
+            // Convert map coordinates to world position
+            Vector3 worldPos = new Vector3(mapPos.x, 1f, mapPos.y); // Y=1 to be above ground
+            teamMarkerObj.transform.position = worldPos;
+            teamMarker = teamMarkerObj.transform;
+
+            Debug.Log($"📍 Team marker placed at map position ({mapPos.x}, {mapPos.y}) = world position {worldPos}");
+
+            // Log what type of settlement we're on
+            MapTile tile = mapData.GetTile(mapPos.x, mapPos.y);
+            if (tile != null)
+            {
+                Debug.Log($"🏘️ Team marker placed on: Terrain={tile.terrainType}, Feature={tile.featureType}");
+                if (!string.IsNullOrEmpty(tile.name))
+                {
+                    Debug.Log($"🏘️ Settlement name: {tile.name}");
+                }
+            }
+        }
+        else
+        {
+            Debug.LogError("❌ Could not create TeamMarker!");
+        }
+    }
+
+    /// <summary>
+    /// Context menu helper to regenerate map
+    /// </summary>
+    [ContextMenu("Generate New Map")]
+    public void RegenerateMap()
+    {
+        seed = Random.Range(1, 99999);
+        GenerateSimpleMap();
+    }
+
+    /// <summary>
+    /// Context menu helper to disable conflicting systems
+    /// </summary>
+    [ContextMenu("Setup Simple System (Disable Conflicts)")]
+    public void SetupSimpleSystem()
+    {
+        Debug.Log("🔧 Setting up simple system by disabling conflicting components...");
+
+        // Disable SimpleTeamPlacement if present
+        SimpleTeamPlacement teamPlacement = FindFirstObjectByType<SimpleTeamPlacement>();
+        if (teamPlacement != null)
+        {
+            teamPlacement.enabled = false;
+            Debug.Log("🚫 Disabled SimpleTeamPlacement component");
+        }
+
+        // Disable old TravelUI if present
+        TravelUI oldTravelUI = FindFirstObjectByType<TravelUI>();
+        if (oldTravelUI != null)
+        {
+            oldTravelUI.enabled = false;
+            Debug.Log("🚫 Disabled old TravelUI component");
+        }
+
+        // Disable TeamTravelSystem if present
+        TeamTravelSystem travelSystem = FindFirstObjectByType<TeamTravelSystem>();
+        if (travelSystem != null)
+        {
+            travelSystem.enabled = false;
+            Debug.Log("🚫 Disabled TeamTravelSystem component");
+        }
+
+        // Disable ExplorationManager if present (search by component name)
+        MonoBehaviour[] allComponents = FindObjectsByType<MonoBehaviour>(FindObjectsSortMode.None);
+        foreach (var component in allComponents)
+        {
+            if (component.GetType().Name == "ExplorationManager")
+            {
+                component.enabled = false;
+                Debug.Log("🚫 Disabled ExplorationManager component");
+                break;
+            }
+        }
+
+        Debug.Log("✅ Simple system setup complete - conflicting systems disabled");
+
+        // Regenerate the map to ensure clean state
+        GenerateSimpleMap();
+    }
+
+    /// <summary>
+    /// Context menu helper to place team marker on different town
+    /// </summary>
+    [ContextMenu("Move Team to Random Town")]
+    public void MoveTeamToRandomTown()
+    {
+        // Find all towns and villages
+        var settlements = new System.Collections.Generic.List<Vector2Int>();
+
+        for (int x = 0; x < mapSize; x++)
+        {
+            for (int y = 0; y < mapSize; y++)
+            {
+                MapTile tile = mapData.GetTile(x, y);
+                if (tile != null && (tile.featureType == FeatureType.Town || tile.featureType == FeatureType.Village))
+                {
+                    settlements.Add(new Vector2Int(x, y));
+                }
+            }
+        }
+
+        if (settlements.Count > 0)
+        {
+            int randomIndex = Random.Range(0, settlements.Count);
+            PlaceTeamMarkerAt(settlements[randomIndex]);
+        }
+        else
+        {
+            Debug.LogWarning("⚠️ No settlements found on map");
+        }
+    }
+
+    /// <summary>
+    /// Create simple cube visualization when MapVisualizer is not available
+    /// </summary>
+    private void CreateSimpleCubeVisualization()
+    {
+        // Create a parent object for all tiles
+        GameObject mapContainer = GameObject.Find("MapContainer");
+        if (mapContainer == null)
+        {
+            mapContainer = new GameObject("MapContainer");
+        }
+
+        // Clear existing tiles
+        for (int i = mapContainer.transform.childCount - 1; i >= 0; i--)
+        {
+            DestroyImmediate(mapContainer.transform.GetChild(i).gameObject);
+        }
+
+        // Create simple cubes for visualization
+        for (int x = 0; x < mapSize; x++)
+        {
+            for (int y = 0; y < mapSize; y++)
+            {
+                MapTile tile = mapData.GetTile(x, y);
+                if (tile != null)
+                {
+                    CreateTileVisualization(x, y, tile, mapContainer.transform);
+                }
+            }
+        }
+
+        Debug.Log($"✅ Created simple cube visualization with {mapSize * mapSize} tiles");
+    }
+
+    /// <summary>
+    /// Create a simple cube to represent a tile
+    /// </summary>
+    private void CreateTileVisualization(int x, int y, MapTile tile, Transform parent)
+    {
+        // Create a cube for the tile
+        GameObject tileObj = GameObject.CreatePrimitive(PrimitiveType.Cube);
+        tileObj.name = $"Tile_{x}_{y}";
+        tileObj.transform.parent = parent;
+        tileObj.transform.position = new Vector3(x, 0, y);
+        tileObj.transform.localScale = new Vector3(0.9f, 0.1f, 0.9f); // Flat tiles
+
+        // Get the renderer to change colors
+        Renderer renderer = tileObj.GetComponent<Renderer>();
+        if (renderer != null)
+        {
+            // Color based on terrain type
+            Color terrainColor = GetTerrainColor(tile.terrainType);
+            renderer.material.color = terrainColor;
+        }
+
+        // Add feature visualization on top if needed
+        if (tile.featureType != FeatureType.None)
+        {
+            CreateFeatureVisualization(x, y, tile, tileObj.transform);
+        }
+    }
+
+    /// <summary>
+    /// Create feature visualization (towns, villages, roads)
+    /// </summary>
+    private void CreateFeatureVisualization(int x, int y, MapTile tile, Transform tileParent)
+    {
+        GameObject featureObj = null;
+
+        switch (tile.featureType)
+        {
+            case FeatureType.Town:
+                featureObj = GameObject.CreatePrimitive(PrimitiveType.Cylinder);
+                featureObj.name = $"Town_{x}_{y}";
+                featureObj.transform.localScale = new Vector3(0.6f, 0.5f, 0.6f);
+                featureObj.GetComponent<Renderer>().material.color = Color.blue;
+                break;
+
+            case FeatureType.Village:
+                featureObj = GameObject.CreatePrimitive(PrimitiveType.Cylinder);
+                featureObj.name = $"Village_{x}_{y}";
+                featureObj.transform.localScale = new Vector3(0.4f, 0.3f, 0.4f);
+                featureObj.GetComponent<Renderer>().material.color = Color.cyan;
+                break;
+
+            case FeatureType.Road:
+                featureObj = GameObject.CreatePrimitive(PrimitiveType.Cube);
+                featureObj.name = $"Road_{x}_{y}";
+                featureObj.transform.localScale = new Vector3(0.8f, 0.05f, 0.8f);
+                featureObj.GetComponent<Renderer>().material.color = Color.yellow;
+                break;
+        }
+
+        if (featureObj != null)
+        {
+            featureObj.transform.parent = tileParent;
+            featureObj.transform.localPosition = new Vector3(0, 0.6f, 0); // On top of tile
+        }
+    }
+
+    /// <summary>
+    /// Get color for terrain type
+    /// </summary>
+    private Color GetTerrainColor(TerrainType terrainType)
+    {
+        return terrainType switch
+        {
+            TerrainType.Plains => Color.green,
+            TerrainType.Forest => new Color(0f, 0.5f, 0f), // Dark green
+            TerrainType.Mountain => Color.gray,
+            TerrainType.Ocean => Color.blue,
+            TerrainType.Lake => new Color(0f, 0.5f, 1f), // Light blue
+            TerrainType.River => Color.cyan,
+            _ => Color.white
+        };
+    }
+
+    /// <summary>
+    /// Get the current map data
+    /// </summary>
+    public MapData GetMapData()
+    {
+        return mapData;
+    }
+
+    /// <summary>
+    /// Get the team marker transform
+    /// </summary>
+    public Transform GetTeamMarker()
+    {
+        return teamMarker;
+    }
+}

+ 682 - 0
Assets/Scripts/MapMaker2/Terrain/TerrainGenerator.cs

@@ -0,0 +1,682 @@
+using UnityEngine;
+using System.Collections.Generic;
+
+public class TerrainGenerator
+{
+    private NoiseGenerator noiseGenerator;
+    private List<Vector2Int> originalRiverPositions;
+
+    public TerrainGenerator()
+    {
+        noiseGenerator = new NoiseGenerator();
+        originalRiverPositions = new List<Vector2Int>();
+    }
+
+    public void GenerateTerrain(MapData mapData)
+    {
+        // Clear previous river positions
+        originalRiverPositions.Clear();
+
+        // Generate base heightmap
+        GenerateHeightmap(mapData);
+
+        // Generate water bodies first (they take priority)
+        GenerateOceans(mapData);
+        GenerateLakes(mapData);
+        GenerateRivers(mapData);
+
+        // Store river positions after generation but before forests
+        StoreRiverPositions(mapData);
+
+        // Generate mountains (avoid water areas)
+        GenerateMountains(mapData);
+
+        // Generate forests (can overlap with rivers initially)
+        GenerateForests(mapData);
+
+        // Create river paths through forests (this cuts paths after forests are placed)
+        CreateRiverPathsThroughForests(mapData);
+
+        // Generate shores (around water)
+        GenerateShores(mapData);
+    }
+
+    private void GenerateHeightmap(MapData mapData)
+    {
+        for (int x = 0; x < mapData.Width; x++)
+        {
+            for (int y = 0; y < mapData.Height; y++)
+            {
+                float height = noiseGenerator.GetNoise(x, y, 0.1f);
+                mapData.GetTile(x, y).height = height;
+            }
+        }
+    }
+
+    private void GenerateOceans(MapData mapData)
+    {
+        // Generate one large ocean that extends to map edge
+        int edgeChoice = Random.Range(0, 4); // 0=left, 1=right, 2=top, 3=bottom
+
+        int oceanX, oceanY, oceanWidth, oceanHeight;
+
+        switch (edgeChoice)
+        {
+            case 0: // Left edge ocean - cover entire left edge
+                oceanX = 0;
+                oceanY = 0;
+                oceanWidth = Random.Range(40, 70);
+                oceanHeight = mapData.Height;
+                break;
+            case 1: // Right edge ocean - cover entire right edge
+                oceanWidth = Random.Range(40, 70);
+                oceanX = mapData.Width - oceanWidth;
+                oceanY = 0;
+                oceanHeight = mapData.Height;
+                break;
+            case 2: // Top edge ocean - cover entire top edge
+                oceanX = 0;
+                oceanHeight = Random.Range(40, 70);
+                oceanY = mapData.Height - oceanHeight;
+                oceanWidth = mapData.Width;
+                break;
+            default: // Bottom edge ocean - cover entire bottom edge
+                oceanX = 0;
+                oceanY = 0;
+                oceanWidth = mapData.Width;
+                oceanHeight = Random.Range(40, 70);
+                break;
+        }
+
+        // Create the main ocean shape
+        List<Vector2Int> oceanTiles = new List<Vector2Int>();
+
+        for (int x = oceanX; x < oceanX + oceanWidth && x < mapData.Width; x++)
+        {
+            for (int y = oceanY; y < oceanY + oceanHeight && y < mapData.Height; y++)
+            {
+                // Calculate distance from the map edge that should be ocean
+                float distanceFromOceanEdge = 0f;
+
+                if (edgeChoice == 0) distanceFromOceanEdge = x; // Left edge
+                else if (edgeChoice == 1) distanceFromOceanEdge = mapData.Width - 1 - x; // Right edge
+                else if (edgeChoice == 2) distanceFromOceanEdge = mapData.Height - 1 - y; // Top edge
+                else distanceFromOceanEdge = y; // Bottom edge
+
+                // Create probability that decreases from edge with some noise
+                float maxDepth = Mathf.Min(oceanWidth, oceanHeight) * 0.8f;
+                float edgeProbability = 1f - (distanceFromOceanEdge / maxDepth);
+
+                // Add noise for coastline variation, but keep it more cohesive
+                float noise = noiseGenerator.GetNoise(x, y, 0.1f) * 0.2f;
+                float finalProbability = Mathf.Clamp01(edgeProbability + noise);
+
+                // Ensure edge tiles are always ocean for proper ocean coverage
+                if (distanceFromOceanEdge < 3 || finalProbability > 0.4f)
+                {
+                    oceanTiles.Add(new Vector2Int(x, y));
+                }
+            }
+        }        // Apply ocean tiles
+        foreach (var pos in oceanTiles)
+        {
+            mapData.GetTile(pos.x, pos.y).terrainType = TerrainType.Ocean;
+            mapData.GetTile(pos.x, pos.y).isWalkable = false;
+        }
+
+        // Fill gaps more aggressively to reduce scattered cells
+        FillTerrainGaps(mapData, TerrainType.Ocean, 3);
+    }
+
+    private void GenerateLakes(MapData mapData)
+    {
+        int lakeCount = Random.Range(3, 6);
+
+        for (int i = 0; i < lakeCount; i++)
+        {
+            int attempts = 0;
+            while (attempts < 20)
+            {
+                attempts++;
+
+                int lakeX = Random.Range(10, mapData.Width - 10);
+                int lakeY = Random.Range(10, mapData.Height - 10);
+                int lakeSize = Random.Range(4, 10);
+
+                // Check if area is suitable for a lake (no water nearby)
+                if (IsAreaSuitable(mapData, lakeX, lakeY, lakeSize * 2, TerrainType.Plains))
+                {
+                    CreateLake(mapData, lakeX, lakeY, lakeSize);
+                    break;
+                }
+            }
+        }
+    }
+
+    private void CreateLake(MapData mapData, int centerX, int centerY, int size)
+    {
+        List<Vector2Int> lakeTiles = new List<Vector2Int>();
+
+        for (int x = centerX - size; x <= centerX + size; x++)
+        {
+            for (int y = centerY - size; y <= centerY + size; y++)
+            {
+                if (mapData.IsValidPosition(x, y))
+                {
+                    float distance = Vector2.Distance(new Vector2(x, y), new Vector2(centerX, centerY));
+                    if (distance <= size * Random.Range(0.8f, 1.2f))
+                    {
+                        lakeTiles.Add(new Vector2Int(x, y));
+                    }
+                }
+            }
+        }
+
+        // Apply lake tiles
+        foreach (var pos in lakeTiles)
+        {
+            mapData.GetTile(pos.x, pos.y).terrainType = TerrainType.Lake;
+            mapData.GetTile(pos.x, pos.y).isWalkable = false;
+        }
+
+        // Fill gaps
+        FillTerrainGaps(mapData, TerrainType.Lake, 1);
+    }
+
+    private void GenerateRivers(MapData mapData)
+    {
+        var riverGenerator = new RiverGenerator();
+        riverGenerator.GenerateRivers(mapData);
+    }
+
+    private void GenerateForests(MapData mapData)
+    {
+        // Generate one huge forest first (if possible)
+        GenerateHugeForest(mapData);
+
+        // Generate medium forests
+        int mediumForestCount = Random.Range(3, 6);
+        for (int i = 0; i < mediumForestCount; i++)
+        {
+            int attempts = 0;
+            while (attempts < 20)
+            {
+                attempts++;
+
+                int forestX = Random.Range(10, mapData.Width - 10);
+                int forestY = Random.Range(10, mapData.Height - 10);
+                int forestSize = Random.Range(8, 18);
+
+                if (IsAreaSuitableForForest(mapData, forestX, forestY, forestSize))
+                {
+                    CreateForest(mapData, forestX, forestY, forestSize);
+                    break;
+                }
+            }
+        }
+
+        // Generate small forests and forest patches
+        int smallForestCount = Random.Range(5, 10);
+        for (int i = 0; i < smallForestCount; i++)
+        {
+            int attempts = 0;
+            while (attempts < 15)
+            {
+                attempts++;
+
+                int forestX = Random.Range(5, mapData.Width - 5);
+                int forestY = Random.Range(5, mapData.Height - 5);
+                int forestSize = Random.Range(3, 8);
+
+                if (IsAreaSuitableForForest(mapData, forestX, forestY, forestSize))
+                {
+                    CreateForest(mapData, forestX, forestY, forestSize);
+                    break;
+                }
+            }
+        }
+    }
+
+    private void GenerateHugeForest(MapData mapData)
+    {
+        int attempts = 0;
+        while (attempts < 10)
+        {
+            attempts++;
+
+            // Try to place a huge forest away from water and edges
+            int forestX = Random.Range(25, mapData.Width - 45);
+            int forestY = Random.Range(25, mapData.Height - 45);
+            int forestSize = Random.Range(25, 40);
+
+            if (IsAreaSuitableForForest(mapData, forestX, forestY, forestSize))
+            {
+                CreateHugeForest(mapData, forestX, forestY, forestSize);
+                break;
+            }
+        }
+    }
+
+    private void CreateHugeForest(MapData mapData, int centerX, int centerY, int size)
+    {
+        List<Vector2Int> forestTiles = new List<Vector2Int>();
+
+        // Create multiple overlapping forest areas for irregular huge forest
+        int subForests = Random.Range(3, 6);
+
+        for (int sf = 0; sf < subForests; sf++)
+        {
+            // Each sub-forest has its own center near the main center
+            int subCenterX = centerX + Random.Range(-size / 3, size / 3);
+            int subCenterY = centerY + Random.Range(-size / 3, size / 3);
+            int subSize = Random.Range(size / 2, size);
+
+            // Generate organic forest shape for this sub-forest
+            for (int x = subCenterX - subSize; x <= subCenterX + subSize; x++)
+            {
+                for (int y = subCenterY - subSize; y <= subCenterY + subSize; y++)
+                {
+                    if (mapData.IsValidPosition(x, y))
+                    {
+                        float distance = Vector2.Distance(new Vector2(x, y), new Vector2(subCenterX, subCenterY));
+                        float maxDistance = subSize * Random.Range(0.7f, 1.3f);
+
+                        // Add some noise for irregular edges
+                        float noise = noiseGenerator.GetNoise(x, y, 0.2f);
+                        maxDistance += noise * (subSize * 0.2f);
+
+                        if (distance <= maxDistance)
+                        {
+                            MapTile tile = mapData.GetTile(x, y);
+                            // Allow forests on Plains and Rivers - we'll cut river paths later
+                            if (tile.terrainType == TerrainType.Plains || tile.terrainType == TerrainType.River)
+                            {
+                                forestTiles.Add(new Vector2Int(x, y));
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        // Apply forest tiles (only on Plains now, rivers are left as paths)
+        foreach (var pos in forestTiles)
+        {
+            MapTile tile = mapData.GetTile(pos.x, pos.y);
+            tile.terrainType = TerrainType.Forest;
+        }
+
+        // Fill gaps more aggressively for huge forests
+        FillTerrainGaps(mapData, TerrainType.Forest, 2);
+    }
+
+    private bool IsAreaSuitableForForest(MapData mapData, int centerX, int centerY, int size)
+    {
+        int plainsCount = 0;
+        int totalCount = 0;
+
+        for (int x = centerX - size / 2; x <= centerX + size / 2; x++)
+        {
+            for (int y = centerY - size / 2; y <= centerY + size / 2; y++)
+            {
+                if (mapData.IsValidPosition(x, y))
+                {
+                    totalCount++;
+                    var tile = mapData.GetTile(x, y);
+                    if (tile.terrainType == TerrainType.Plains)
+                    {
+                        plainsCount++;
+                    }
+                }
+            }
+        }
+
+        return totalCount > 0 && (float)plainsCount / totalCount > 0.8f;
+    }
+
+    private void CreateForest(MapData mapData, int centerX, int centerY, int size)
+    {
+        List<Vector2Int> forestTiles = new List<Vector2Int>();
+
+        // Determine forest type - some are dense, some are sparse
+        bool isDenseForest = Random.value < 0.4f; // 40% chance for dense forest
+        bool hasClearing = Random.value < 0.3f && size > 6; // 30% chance for clearing in larger forests
+
+        // Create organic forest shape with variation
+        for (int x = centerX - size; x <= centerX + size; x++)
+        {
+            for (int y = centerY - size; y <= centerY + size; y++)
+            {
+                if (mapData.IsValidPosition(x, y))
+                {
+                    float distance = Vector2.Distance(new Vector2(x, y), new Vector2(centerX, centerY));
+                    float maxDistance = size * Random.Range(0.6f, 1.2f);
+
+                    // Add noise for irregular edges
+                    float noise = noiseGenerator.GetNoise(x, y, 0.15f);
+                    float noiseInfluence = isDenseForest ? 0.1f : 0.3f; // Dense forests are more regular
+                    maxDistance += noise * (size * noiseInfluence);
+
+                    // Create clearings in some forests
+                    bool inClearing = false;
+                    if (hasClearing)
+                    {
+                        float clearingDistance = Vector2.Distance(new Vector2(x, y), new Vector2(centerX, centerY));
+                        inClearing = clearingDistance < size * 0.3f && Random.value < 0.7f;
+                    }
+
+                    if (distance <= maxDistance && !inClearing)
+                    {
+                        MapTile tile = mapData.GetTile(x, y);
+                        // Allow forests on Plains and Rivers - we'll cut river paths later
+                        if (tile.terrainType == TerrainType.Plains || tile.terrainType == TerrainType.River)
+                        {
+                            // Dense forests fill more completely, sparse forests are more scattered
+                            float fillProbability = isDenseForest ? 0.85f : 0.65f;
+                            if (Random.value < fillProbability)
+                            {
+                                forestTiles.Add(new Vector2Int(x, y));
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        // Apply forest tiles (only on Plains now, rivers are left as paths)
+        foreach (var pos in forestTiles)
+        {
+            MapTile tile = mapData.GetTile(pos.x, pos.y);
+            tile.terrainType = TerrainType.Forest;
+        }
+
+        // Dense forests get better gap filling
+        int gapFillLevel = isDenseForest ? 2 : 1;
+        FillTerrainGaps(mapData, TerrainType.Forest, gapFillLevel);
+    }
+
+    private void GenerateMountains(MapData mapData)
+    {
+        // Generate more varied mountain ranges with different sizes
+        int mountainCount = Random.Range(2, 5); // Slightly more mountain ranges
+
+        for (int i = 0; i < mountainCount; i++)
+        {
+            int attempts = 0;
+            while (attempts < 20)
+            {
+                attempts++;
+
+                int mountainX = Random.Range(15, mapData.Width - 15);
+                int mountainY = Random.Range(15, mapData.Height - 15);
+
+                // More varied mountain sizes - some small, some large
+                int mountainSize;
+                float sizeRoll = Random.value;
+                if (sizeRoll < 0.3f)
+                    mountainSize = Random.Range(5, 10); // Small mountains
+                else if (sizeRoll < 0.7f)
+                    mountainSize = Random.Range(10, 18); // Medium mountains
+                else
+                    mountainSize = Random.Range(18, 28); // Large mountain ranges
+
+                if (IsAreaSuitableForMountains(mapData, mountainX, mountainY, mountainSize))
+                {
+                    CreateMountainRange(mapData, mountainX, mountainY, mountainSize);
+                    break;
+                }
+            }
+        }
+    }
+
+    private bool IsAreaSuitableForMountains(MapData mapData, int centerX, int centerY, int size)
+    {
+        // Check if area is mostly plains (not water or already mountains)
+        int suitableCount = 0;
+        int totalCount = 0;
+
+        for (int x = centerX - size; x <= centerX + size; x++)
+        {
+            for (int y = centerY - size; y <= centerY + size; y++)
+            {
+                if (mapData.IsValidPosition(x, y))
+                {
+                    totalCount++;
+                    var tile = mapData.GetTile(x, y);
+                    if (tile.terrainType == TerrainType.Plains || tile.terrainType == TerrainType.Forest)
+                    {
+                        suitableCount++;
+                    }
+                }
+            }
+        }
+
+        return totalCount > 0 && (float)suitableCount / totalCount > 0.7f;
+    }
+
+    private void CreateMountainRange(MapData mapData, int centerX, int centerY, int size)
+    {
+        List<Vector2Int> mountainTiles = new List<Vector2Int>();
+
+        // Create mountain range with multiple peaks - more varied
+        int peaks = Random.Range(2, 6); // More variation in peak count
+        for (int p = 0; p < peaks; p++)
+        {
+            // More random peak placement instead of evenly spaced
+            float angle = Random.Range(0f, 360f) * Mathf.Deg2Rad;
+            float peakDistance = Random.Range(0.2f, 0.5f) * size; // Varied distance from center
+            int peakX = centerX + Mathf.RoundToInt(Mathf.Cos(angle) * peakDistance);
+            int peakY = centerY + Mathf.RoundToInt(Mathf.Sin(angle) * peakDistance);
+
+            // Each peak has its own size variation
+            int peakSize = Random.Range(size / 3, size);
+
+            for (int x = peakX - peakSize / 2; x <= peakX + peakSize / 2; x++)
+            {
+                for (int y = peakY - peakSize / 2; y <= peakY + peakSize / 2; y++)
+                {
+                    if (mapData.IsValidPosition(x, y))
+                    {
+                        float distance = Vector2.Distance(new Vector2(x, y), new Vector2(peakX, peakY));
+                        // More random distance threshold for irregular mountain shapes
+                        float maxDistance = peakSize * Random.Range(0.3f, 0.9f);
+
+                        // Add noise for more natural mountain edges
+                        float noise = noiseGenerator.GetNoise(x, y, 0.15f);
+                        maxDistance += noise * (peakSize * 0.2f);
+
+                        if (distance <= maxDistance)
+                        {
+                            MapTile tile = mapData.GetTile(x, y);
+                            if (!tile.IsWater()) // Don't override water
+                            {
+                                mountainTiles.Add(new Vector2Int(x, y));
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        // Apply mountain tiles
+        foreach (var pos in mountainTiles)
+        {
+            mapData.GetTile(pos.x, pos.y).terrainType = TerrainType.Mountain;
+            mapData.GetTile(pos.x, pos.y).isWalkable = false;
+        }
+
+        // Fill gaps
+        FillTerrainGaps(mapData, TerrainType.Mountain, 1);
+    }
+
+    private void FillTerrainGaps(MapData mapData, TerrainType terrainType, int maxGapSize)
+    {
+        for (int x = 0; x < mapData.Width; x++)
+        {
+            for (int y = 0; y < mapData.Height; y++)
+            {
+                MapTile tile = mapData.GetTile(x, y);
+                if (tile.terrainType != terrainType)
+                {
+                    // Check if this tile is surrounded by the target terrain type
+                    int neighborCount = 0;
+                    int targetNeighbors = 0;
+
+                    for (int dx = -maxGapSize; dx <= maxGapSize; dx++)
+                    {
+                        for (int dy = -maxGapSize; dy <= maxGapSize; dy++)
+                        {
+                            if (dx == 0 && dy == 0) continue;
+
+                            int checkX = x + dx;
+                            int checkY = y + dy;
+
+                            if (mapData.IsValidPosition(checkX, checkY))
+                            {
+                                neighborCount++;
+                                if (mapData.GetTile(checkX, checkY).terrainType == terrainType)
+                                {
+                                    targetNeighbors++;
+                                }
+                            }
+                        }
+                    }
+
+                    // If most neighbors are the target terrain, fill this gap
+                    if (neighborCount > 0 && (float)targetNeighbors / neighborCount > 0.6f)
+                    {
+                        if (terrainType == TerrainType.Ocean || terrainType == TerrainType.Lake || terrainType == TerrainType.River)
+                        {
+                            tile.isWalkable = false;
+                        }
+                        if (terrainType == TerrainType.Mountain)
+                        {
+                            tile.isWalkable = false;
+                        }
+                        tile.terrainType = terrainType;
+                    }
+                }
+            }
+        }
+    }
+
+    private void GenerateShores(MapData mapData)
+    {
+        for (int x = 0; x < mapData.Width; x++)
+        {
+            for (int y = 0; y < mapData.Height; y++)
+            {
+                MapTile tile = mapData.GetTile(x, y);
+                if (tile.terrainType == TerrainType.Plains)
+                {
+                    if (IsNearWater(mapData, x, y, 2)) // Reduced range for shores
+                    {
+                        tile.terrainType = TerrainType.Shore;
+                    }
+                }
+            }
+        }
+    }
+
+    private bool IsNearWater(MapData mapData, int x, int y, int range)
+    {
+        for (int dx = -range; dx <= range; dx++)
+        {
+            for (int dy = -range; dy <= range; dy++)
+            {
+                int checkX = x + dx;
+                int checkY = y + dy;
+
+                if (mapData.IsValidPosition(checkX, checkY))
+                {
+                    MapTile checkTile = mapData.GetTile(checkX, checkY);
+                    if (checkTile.IsWater())
+                    {
+                        return true;
+                    }
+                }
+            }
+        }
+        return false;
+    }
+
+    private bool IsAreaSuitable(MapData mapData, int centerX, int centerY, int size, TerrainType requiredType)
+    {
+        int suitableCount = 0;
+        int totalCount = 0;
+
+        for (int x = centerX - size; x <= centerX + size; x++)
+        {
+            for (int y = centerY - size; y <= centerY + size; y++)
+            {
+                if (mapData.IsValidPosition(x, y))
+                {
+                    totalCount++;
+                    if (mapData.GetTile(x, y).terrainType == requiredType)
+                    {
+                        suitableCount++;
+                    }
+                }
+            }
+        }
+
+        return totalCount > 0 && (float)suitableCount / totalCount > 0.8f;
+    }
+
+    private void StoreRiverPositions(MapData mapData)
+    {
+        originalRiverPositions.Clear();
+
+        for (int x = 0; x < mapData.Width; x++)
+        {
+            for (int y = 0; y < mapData.Height; y++)
+            {
+                var tile = mapData.GetTile(x, y);
+                if (tile.terrainType == TerrainType.River)
+                {
+                    originalRiverPositions.Add(new Vector2Int(x, y));
+                }
+            }
+        }
+    }
+
+    private void CreateRiverPathsThroughForests(MapData mapData)
+    {
+        // Restore rivers that got covered by forests with more natural-looking paths
+        foreach (var riverPos in originalRiverPositions)
+        {
+            var tile = mapData.GetTile(riverPos.x, riverPos.y);
+
+            // If this river position got turned into forest, restore it as river
+            if (tile.terrainType == TerrainType.Forest)
+            {
+                tile.terrainType = TerrainType.River;
+
+                // Create narrower, more natural river paths
+                // Only expand along the main river flow directions (not diagonally)
+                for (int dx = -1; dx <= 1; dx++)
+                {
+                    for (int dy = -1; dy <= 1; dy++)
+                    {
+                        // Skip center (already handled) and diagonal directions (keep forest)
+                        if ((dx == 0 && dy == 0) || (Mathf.Abs(dx) == 1 && Mathf.Abs(dy) == 1))
+                            continue;
+
+                        int x = riverPos.x + dx;
+                        int y = riverPos.y + dy;
+
+                        if (mapData.IsValidPosition(x, y))
+                        {
+                            var neighborTile = mapData.GetTile(x, y);
+                            // Only expand river into forests, and with lower probability for narrower channels
+                            if (neighborTile.terrainType == TerrainType.Forest && Random.value < 0.3f)
+                            {
+                                neighborTile.terrainType = TerrainType.River;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+}

+ 37 - 0
Assets/Scripts/MapMaker2/Utils/NoiseGenerator.cs

@@ -0,0 +1,37 @@
+using UnityEngine;
+
+public class NoiseGenerator
+{
+    public float GetNoise(float x, float y, float scale)
+    {
+        return Mathf.PerlinNoise(x * scale, y * scale) * 2f - 1f;
+    }
+    
+    public float GetNoise(float x, float y, float z, float scale)
+    {
+        // 3D noise approximation using multiple 2D noise samples
+        float xy = Mathf.PerlinNoise(x * scale, y * scale);
+        float xz = Mathf.PerlinNoise(x * scale, z * scale);
+        float yz = Mathf.PerlinNoise(y * scale, z * scale);
+        
+        return (xy + xz + yz) / 3f * 2f - 1f;
+    }
+    
+    public float GetFractalNoise(float x, float y, float scale, int octaves = 4)
+    {
+        float value = 0f;
+        float amplitude = 1f;
+        float frequency = scale;
+        float maxValue = 0f;
+        
+        for (int i = 0; i < octaves; i++)
+        {
+            value += Mathf.PerlinNoise(x * frequency, y * frequency) * amplitude;
+            maxValue += amplitude;
+            amplitude *= 0.5f;
+            frequency *= 2f;
+        }
+        
+        return (value / maxValue) * 2f - 1f;
+    }
+}

Деякі файли не було показано, через те що забагато файлів було змінено