Add free-camera mode with player-equivalent collision

Introduce a free-fly camera as the next entry in the Tab mode cycle
(Player Control -> Paint -> Free Cam):

- FreeCamController: dedicated CinemachineCamera plus a CharacterController
  mirroring the player capsule (radius 0.1, height 1.3, slope 59, step 0.15)
  so the free camera collides with walls/ceiling/floor exactly like the
  player. WASD/Q-E (and Space/Ctrl) fly relative to view; mouse looks.
- FreeCamMode: plain-C# GameMode mirroring PaintMode, with an Exit() that
  restores camera priority and re-enables player control + camera input.
- GameModeManager: register freeCam in the Tab cycle (gated like player).
- Scene: FreeCamera object wired, Main Camera custom blends (0.4s) for the
  vcam priority hand-off.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
adminandClaude Opus 4.8 committed 2026-06-26 23:01:14 +02:00
1 parent 0edc59555a
commit a3ef7055b4
10 files changed
+472 -19

No files matched your search

+186 -18
View File
@@ -1561,7 +1561,7 @@ MonoBehaviour:
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
CustomBlends: {fileID: 0}
CustomBlends: {fileID: 11400000, guid: 47b57a7fe51fd154e975311ad293878a, type: 2}
--- !u!1 &347639556
GameObject:
m_ObjectHideFlags: 0
@@ -1750,7 +1750,7 @@ Light:
m_Type: 2
m_Resolution: -1
m_CustomResolution: -1
m_Strength: 1
m_Strength: 0.9
m_Bias: 0.05
m_NormalBias: 0.4
m_NearPlane: 0.2
@@ -2559,6 +2559,19 @@ PrefabInstance:
m_AddedGameObjects: []
m_AddedComponents: []
m_SourcePrefab: {fileID: 100100000, guid: ac1cc01cb5dbf5d4f869c403b38f8a21, type: 3}
--- !u!134 &610463647
PhysicsMaterial:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name:
serializedVersion: 2
m_DynamicFriction: 0.6
m_StaticFriction: 0.6
m_Bounciness: 0
m_FrictionCombine: 0
m_BounceCombine: 0
--- !u!1001 &626957352
PrefabInstance:
m_ObjectHideFlags: 0
@@ -3020,19 +3033,6 @@ Transform:
m_CorrespondingSourceObject: {fileID: 4922444305696846, guid: ac1cc01cb5dbf5d4f869c403b38f8a21, type: 3}
m_PrefabInstance: {fileID: 696901729}
m_PrefabAsset: {fileID: 0}
--- !u!134 &699178043
PhysicsMaterial:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name:
serializedVersion: 2
m_DynamicFriction: 0.6
m_StaticFriction: 0.6
m_Bounciness: 0
m_FrictionCombine: 0
m_BounceCombine: 0
--- !u!1001 &724408611
PrefabInstance:
m_ObjectHideFlags: 0
@@ -4571,7 +4571,7 @@ CharacterController:
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1141039638}
m_Material: {fileID: 699178043}
m_Material: {fileID: 1671101580}
m_IncludeLayers:
serializedVersion: 2
m_Bits: 0
@@ -4979,6 +4979,155 @@ Transform:
m_CorrespondingSourceObject: {fileID: 415460, guid: ab99da1b8f76c44549a399bcdd9c8caa, type: 3}
m_PrefabInstance: {fileID: 1253165018}
m_PrefabAsset: {fileID: 0}
--- !u!1 &1260370184 stripped
GameObject:
m_CorrespondingSourceObject: {fileID: 133438, guid: 6f95ff39b42c3414d9a7ced2eea58274, type: 3}
m_PrefabInstance: {fileID: 1860487067}
m_PrefabAsset: {fileID: 0}
--- !u!64 &1260370189
MeshCollider:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1260370184}
m_Material: {fileID: 0}
m_IncludeLayers:
serializedVersion: 2
m_Bits: 0
m_ExcludeLayers:
serializedVersion: 2
m_Bits: 0
m_LayerOverridePriority: 0
m_IsTrigger: 0
m_ProvidesContacts: 0
m_Enabled: 1
serializedVersion: 5
m_Convex: 0
m_CookingOptions: 30
m_Mesh: {fileID: 4300000, guid: 6bb1e412df9cd4efd8941377ebabb1be, type: 3}
--- !u!1 &1282734303
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1282734307}
- component: {fileID: 1282734306}
- component: {fileID: 1282734305}
- component: {fileID: 1282734304}
m_Layer: 0
m_Name: FreeCamera
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &1282734304
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1282734303}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 5ca7cff7542b53b498f0a9834786b9e0, type: 3}
m_Name:
m_EditorClassIdentifier: Assembly-CSharp::FreeCamController
moveSpeed: 6
sprintMultiplier: 3
horizontalSensitivity: 0.1
verticalSensitivity: 0.07
invertY: 0
maxPitch: 89
activePriority: 100
inactivePriority: -100
--- !u!143 &1282734305
CharacterController:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1282734303}
m_Material: {fileID: 610463647}
m_IncludeLayers:
serializedVersion: 2
m_Bits: 0
m_ExcludeLayers:
serializedVersion: 2
m_Bits: 0
m_LayerOverridePriority: 0
m_ProvidesContacts: 0
m_Enabled: 1
serializedVersion: 3
m_Height: 1.3
m_Radius: 0.1
m_SlopeLimit: 59
m_StepOffset: 0.15
m_SkinWidth: 0.01
m_MinMoveDistance: 0.001
m_Center: {x: 0, y: -0.09, z: 0}
--- !u!114 &1282734306
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1282734303}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: f9dfa5b682dcd46bda6128250e975f58, type: 3}
m_Name:
m_EditorClassIdentifier: Unity.Cinemachine::Unity.Cinemachine.CinemachineCamera
Priority:
Enabled: 1
m_Value: -100
OutputChannel: 1
StandbyUpdate: 2
m_StreamingVersion: 20241001
m_LegacyPriority: 0
Target:
TrackingTarget: {fileID: 0}
LookAtTarget: {fileID: 0}
CustomLookAtTarget: 0
Lens:
FieldOfView: 40
OrthographicSize: 10
NearClipPlane: 0.1
FarClipPlane: 5000
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!4 &1282734307
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1282734303}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 1, 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!1001 &1317768121
PrefabInstance:
m_ObjectHideFlags: 0
@@ -5768,6 +5917,7 @@ MonoBehaviour:
player: {fileID: 1141039642}
cameraInput: {fileID: 172071431}
painter: {fileID: 0}
freeCam: {fileID: 1282734304}
switchKey: 3
startModeIndex: 0
--- !u!4 &1516578028
@@ -6264,6 +6414,19 @@ MeshCollider:
m_Convex: 0
m_CookingOptions: 30
m_Mesh: {fileID: 4300000, guid: 0727ba69b779d42a0978a362226fad3e, type: 3}
--- !u!134 &1671101580
PhysicsMaterial:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: ' (Instance)'
serializedVersion: 2
m_DynamicFriction: 0.6
m_StaticFriction: 0.6
m_Bounciness: 0
m_FrictionCombine: 0
m_BounceCombine: 0
--- !u!1 &1680244256
GameObject:
m_ObjectHideFlags: 0
@@ -7029,10 +7192,14 @@ PrefabInstance:
propertyPath: m_LocalRotation.z
value: 0
objectReference: {fileID: 0}
m_RemovedComponents: []
m_RemovedComponents:
- {fileID: 6582054, guid: 6f95ff39b42c3414d9a7ced2eea58274, type: 3}
m_RemovedGameObjects: []
m_AddedGameObjects: []
m_AddedComponents: []
m_AddedComponents:
- targetCorrespondingSourceObject: {fileID: 133438, guid: 6f95ff39b42c3414d9a7ced2eea58274, type: 3}
insertIndex: -1
addedObject: {fileID: 1260370189}
m_SourcePrefab: {fileID: 100100000, guid: 6f95ff39b42c3414d9a7ced2eea58274, type: 3}
--- !u!4 &1860487068 stripped
Transform:
@@ -7836,3 +8003,4 @@ SceneRoots:
- {fileID: 686187287}
- {fileID: 489277934}
- {fileID: 347639557}
- {fileID: 1282734307}