diff --git a/Assets/Poses/Pose_Ball.asset b/Assets/Poses/Pose_Ball.asset index 426028f..06c8e94 100644 --- a/Assets/Poses/Pose_Ball.asset +++ b/Assets/Poses/Pose_Ball.asset @@ -22,3 +22,4 @@ MonoBehaviour: controllerRadius: 0.15 controllerHeight: 0.5 cameraTargetYOffset: -0.5 + firstPersonCameraTargetYOffset: -0.8 diff --git a/Assets/Poses/Pose_Sit.asset b/Assets/Poses/Pose_Sit.asset index 25271eb..ca90d1c 100644 --- a/Assets/Poses/Pose_Sit.asset +++ b/Assets/Poses/Pose_Sit.asset @@ -22,3 +22,4 @@ MonoBehaviour: controllerRadius: 0.1 controllerHeight: 0.85 cameraTargetYOffset: -0.2 + firstPersonCameraTargetYOffset: -0.2 diff --git a/Assets/Poses/Pose_Star.asset b/Assets/Poses/Pose_Star.asset index d473c34..f274ff2 100644 --- a/Assets/Poses/Pose_Star.asset +++ b/Assets/Poses/Pose_Star.asset @@ -22,3 +22,4 @@ MonoBehaviour: controllerRadius: 0.1 controllerHeight: 0.3 cameraTargetYOffset: -0.55 + firstPersonCameraTargetYOffset: -1.18 diff --git a/Assets/Prefabs/Hider.prefab b/Assets/Prefabs/Hider.prefab new file mode 100644 index 0000000..e88df9f --- /dev/null +++ b/Assets/Prefabs/Hider.prefab @@ -0,0 +1,79 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1001 &488197323585957958 +PrefabInstance: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_Modification: + serializedVersion: 3 + m_TransformParent: {fileID: 0} + m_Modifications: + - target: {fileID: 273411532115212066, guid: 97017ed3bb40aff4e885440d9a7336ee, type: 3} + propertyPath: scale + value: 0.5 + objectReference: {fileID: 0} + - target: {fileID: 4587432968399885263, guid: 97017ed3bb40aff4e885440d9a7336ee, type: 3} + propertyPath: m_Enabled + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 5384024074013944205, guid: 97017ed3bb40aff4e885440d9a7336ee, type: 3} + propertyPath: m_Name + value: Player Variant + objectReference: {fileID: 0} + - target: {fileID: 6997860362608943113, guid: 97017ed3bb40aff4e885440d9a7336ee, type: 3} + propertyPath: m_LocalScale.x + value: 0.5 + objectReference: {fileID: 0} + - target: {fileID: 6997860362608943113, guid: 97017ed3bb40aff4e885440d9a7336ee, type: 3} + propertyPath: m_LocalScale.y + value: 0.5 + objectReference: {fileID: 0} + - target: {fileID: 6997860362608943113, guid: 97017ed3bb40aff4e885440d9a7336ee, type: 3} + propertyPath: m_LocalScale.z + value: 0.5 + objectReference: {fileID: 0} + - target: {fileID: 6997860362608943113, guid: 97017ed3bb40aff4e885440d9a7336ee, type: 3} + propertyPath: m_LocalPosition.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 6997860362608943113, guid: 97017ed3bb40aff4e885440d9a7336ee, type: 3} + propertyPath: m_LocalPosition.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 6997860362608943113, guid: 97017ed3bb40aff4e885440d9a7336ee, type: 3} + propertyPath: m_LocalPosition.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 6997860362608943113, guid: 97017ed3bb40aff4e885440d9a7336ee, type: 3} + propertyPath: m_LocalRotation.w + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 6997860362608943113, guid: 97017ed3bb40aff4e885440d9a7336ee, type: 3} + propertyPath: m_LocalRotation.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 6997860362608943113, guid: 97017ed3bb40aff4e885440d9a7336ee, type: 3} + propertyPath: m_LocalRotation.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 6997860362608943113, guid: 97017ed3bb40aff4e885440d9a7336ee, type: 3} + propertyPath: m_LocalRotation.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 6997860362608943113, guid: 97017ed3bb40aff4e885440d9a7336ee, type: 3} + propertyPath: m_LocalEulerAnglesHint.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 6997860362608943113, guid: 97017ed3bb40aff4e885440d9a7336ee, type: 3} + propertyPath: m_LocalEulerAnglesHint.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 6997860362608943113, guid: 97017ed3bb40aff4e885440d9a7336ee, type: 3} + propertyPath: m_LocalEulerAnglesHint.z + value: 0 + objectReference: {fileID: 0} + m_RemovedComponents: [] + m_RemovedGameObjects: [] + m_AddedGameObjects: [] + m_AddedComponents: [] + m_SourcePrefab: {fileID: 100100000, guid: 97017ed3bb40aff4e885440d9a7336ee, type: 3} diff --git a/Assets/Prefabs/Hider.prefab.meta b/Assets/Prefabs/Hider.prefab.meta new file mode 100644 index 0000000..81b5ad0 --- /dev/null +++ b/Assets/Prefabs/Hider.prefab.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 6b0b58e8352625343951db00beb8cb0a +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Prefabs/Hunter.prefab b/Assets/Prefabs/Hunter.prefab new file mode 100644 index 0000000..28515be --- /dev/null +++ b/Assets/Prefabs/Hunter.prefab @@ -0,0 +1,75 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1001 &8795081103086920006 +PrefabInstance: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_Modification: + serializedVersion: 3 + m_TransformParent: {fileID: 0} + m_Modifications: + - target: {fileID: 273411532115212066, guid: 97017ed3bb40aff4e885440d9a7336ee, type: 3} + propertyPath: scale + value: 2.5 + objectReference: {fileID: 0} + - target: {fileID: 5384024074013944205, guid: 97017ed3bb40aff4e885440d9a7336ee, type: 3} + propertyPath: m_Name + value: Hunter + objectReference: {fileID: 0} + - target: {fileID: 6997860362608943113, guid: 97017ed3bb40aff4e885440d9a7336ee, type: 3} + propertyPath: m_LocalScale.x + value: 2.5 + objectReference: {fileID: 0} + - target: {fileID: 6997860362608943113, guid: 97017ed3bb40aff4e885440d9a7336ee, type: 3} + propertyPath: m_LocalScale.y + value: 2.5 + objectReference: {fileID: 0} + - target: {fileID: 6997860362608943113, guid: 97017ed3bb40aff4e885440d9a7336ee, type: 3} + propertyPath: m_LocalScale.z + value: 2.5 + objectReference: {fileID: 0} + - target: {fileID: 6997860362608943113, guid: 97017ed3bb40aff4e885440d9a7336ee, type: 3} + propertyPath: m_LocalPosition.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 6997860362608943113, guid: 97017ed3bb40aff4e885440d9a7336ee, type: 3} + propertyPath: m_LocalPosition.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 6997860362608943113, guid: 97017ed3bb40aff4e885440d9a7336ee, type: 3} + propertyPath: m_LocalPosition.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 6997860362608943113, guid: 97017ed3bb40aff4e885440d9a7336ee, type: 3} + propertyPath: m_LocalRotation.w + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 6997860362608943113, guid: 97017ed3bb40aff4e885440d9a7336ee, type: 3} + propertyPath: m_LocalRotation.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 6997860362608943113, guid: 97017ed3bb40aff4e885440d9a7336ee, type: 3} + propertyPath: m_LocalRotation.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 6997860362608943113, guid: 97017ed3bb40aff4e885440d9a7336ee, type: 3} + propertyPath: m_LocalRotation.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 6997860362608943113, guid: 97017ed3bb40aff4e885440d9a7336ee, type: 3} + propertyPath: m_LocalEulerAnglesHint.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 6997860362608943113, guid: 97017ed3bb40aff4e885440d9a7336ee, type: 3} + propertyPath: m_LocalEulerAnglesHint.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 6997860362608943113, guid: 97017ed3bb40aff4e885440d9a7336ee, type: 3} + propertyPath: m_LocalEulerAnglesHint.z + value: 0 + objectReference: {fileID: 0} + m_RemovedComponents: [] + m_RemovedGameObjects: [] + m_AddedGameObjects: [] + m_AddedComponents: [] + m_SourcePrefab: {fileID: 100100000, guid: 97017ed3bb40aff4e885440d9a7336ee, type: 3} diff --git a/Assets/Prefabs/Hunter.prefab.meta b/Assets/Prefabs/Hunter.prefab.meta new file mode 100644 index 0000000..7c71314 --- /dev/null +++ b/Assets/Prefabs/Hunter.prefab.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: cf153a3aea3d5da4f9d4cdbff0be8180 +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Prefabs/Player.prefab b/Assets/Prefabs/Player.prefab index b587e7d..c7cb008 100644 --- a/Assets/Prefabs/Player.prefab +++ b/Assets/Prefabs/Player.prefab @@ -126,8 +126,9 @@ MonoBehaviour: poses: - {fileID: 11400000, guid: 3b59c882f27d0d04a82d2db251af1728, type: 2} - {fileID: 11400000, guid: 649ecccdabb7ef9438addcec6663b037, type: 2} - - {fileID: 11400000, guid: 1545cfba9b5e06d41ae72c7ec766baaf, type: 2} + - {fileID: 11400000, guid: 90df501d86681394b834f647f6f4e939, type: 2} - {fileID: 11400000, guid: c5cf9d420554e5e4e96d3bee1903967a, type: 2} + - {fileID: 11400000, guid: 1545cfba9b5e06d41ae72c7ec766baaf, type: 2} defaultPoseIndex: 0 cycleKey: 17 poseBlendDuration: 0.2 @@ -233,6 +234,10 @@ PrefabInstance: propertyPath: m_IsActive value: 1 objectReference: {fileID: 0} + - target: {fileID: 3763709765074082564, guid: c2044ff1352a6bb4586d6d04b59012b7, type: 3} + propertyPath: m_TagString + value: Player + objectReference: {fileID: 0} - target: {fileID: 5866666021909216657, guid: c2044ff1352a6bb4586d6d04b59012b7, type: 3} propertyPath: m_Avatar value: diff --git a/Assets/Scenes/SampleScene.unity b/Assets/Scenes/SampleScene.unity index 28bb52e..d125683 100644 --- a/Assets/Scenes/SampleScene.unity +++ b/Assets/Scenes/SampleScene.unity @@ -603,7 +603,7 @@ MonoBehaviour: TransparentLayers: serializedVersion: 2 m_Bits: 0 - MinimumDistanceFromTarget: 0.8 + MinimumDistanceFromTarget: 0.5 AvoidObstacles: Enabled: 1 DistanceLimit: 0 @@ -614,7 +614,7 @@ MonoBehaviour: YOffset: 0 Strategy: 0 MaximumEffort: 4 - SmoothingTime: 0 + SmoothingTime: 0.05 Damping: 0.2 DampingWhenOccluded: 0.1 ShotQualityEvaluation: @@ -735,11 +735,11 @@ MonoBehaviour: m_StreamingVersion: 20241001 m_LegacyPriority: 0 Target: - TrackingTarget: {fileID: 1774267802} - LookAtTarget: {fileID: 1774267802} + TrackingTarget: {fileID: 5297240775790447668} + LookAtTarget: {fileID: 0} CustomLookAtTarget: 0 Lens: - FieldOfView: 40 + FieldOfView: 45 OrthographicSize: 10 NearClipPlane: 0.1 FarClipPlane: 5000 @@ -767,7 +767,7 @@ Transform: m_GameObject: {fileID: 172071430} serializedVersion: 2 m_LocalRotation: {x: 0.1305262, y: 2.1996925e-11, z: -4.1198815e-12, w: 0.9914449} - m_LocalPosition: {x: 0, y: 1.5396858, z: -4.3466663} + m_LocalPosition: {x: 0, y: 3.0396857, z: -4.3466663} m_LocalScale: {x: 1, y: 1, z: 1} m_ConstrainProportionsScale: 0 m_Children: [] @@ -1453,7 +1453,7 @@ Camera: height: 1 near clip plane: 0.1 far clip plane: 5000 - field of view: 40 + field of view: 45 orthographic: 0 orthographic size: 10 m_Depth: -1 @@ -1480,7 +1480,7 @@ Transform: m_GameObject: {fileID: 330585543} serializedVersion: 2 m_LocalRotation: {x: 0.1305262, y: 2.1832952e-11, z: -2.8743629e-12, w: 0.9914449} - m_LocalPosition: {x: 0, y: 1.5396858, z: -4.3466663} + m_LocalPosition: {x: 0, y: 3.0396857, z: -4.3466663} m_LocalScale: {x: 1, y: 1, z: 1} m_ConstrainProportionsScale: 0 m_Children: [] @@ -2246,6 +2246,19 @@ Transform: m_CorrespondingSourceObject: {fileID: 433010, guid: ac92cfb4db971489da14157130119008, type: 3} m_PrefabInstance: {fileID: 505084142} m_PrefabAsset: {fileID: 0} +--- !u!134 &539493728 +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!1001 &551852894 PrefabInstance: m_ObjectHideFlags: 0 @@ -2498,6 +2511,104 @@ Transform: m_CorrespondingSourceObject: {fileID: 477104, guid: 6aacb349af157442ebc4e122e8d6b9bd, type: 3} m_PrefabInstance: {fileID: 580280589} m_PrefabAsset: {fileID: 0} +--- !u!1 &582951479 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 582951482} + - component: {fileID: 582951481} + - component: {fileID: 582951480} + m_Layer: 0 + m_Name: FirstPersonCamera + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &582951480 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 582951479} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 43b8f1dc43642294f99fab0aaabf6197, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::FirstPersonController + cameraTarget: {fileID: 897939465} + hiddenRenderers: + - {fileID: 1294962561} + horizontalSensitivity: 0.1 + verticalSensitivity: 0.075 + invertY: 0 + maxPitch: 89 + lookSmoothTime: 0.04 + activePriority: 100 + inactivePriority: -100 +--- !u!114 &582951481 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 582951479} + 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: 45 + 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 &582951482 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 582951479} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 1.875, 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 &607565146 PrefabInstance: m_ObjectHideFlags: 0 @@ -2559,19 +2670,6 @@ 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 @@ -3965,6 +4063,37 @@ MeshCollider: m_Convex: 0 m_CookingOptions: 30 m_Mesh: {fileID: 4300000, guid: 6d5becbf770f24fa3ab1ceaba45fcefa, type: 3} +--- !u!1 &897939464 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 897939465} + m_Layer: 0 + m_Name: FirstPersonTarget + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &897939465 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 897939464} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 1.2, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 1141039639} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!1001 &924705986 PrefabInstance: m_ObjectHideFlags: 0 @@ -4530,10 +4659,15 @@ Transform: m_CorrespondingSourceObject: {fileID: 411130, guid: a4bb788560e5d4617b970cd301097f38, type: 3} m_PrefabInstance: {fileID: 1039758568} m_PrefabAsset: {fileID: 0} +--- !u!4 &1141039639 stripped +Transform: + m_CorrespondingSourceObject: {fileID: 1950906664192868687, guid: cf153a3aea3d5da4f9d4cdbff0be8180, type: 3} + m_PrefabInstance: {fileID: 5297240775790447667} + m_PrefabAsset: {fileID: 0} --- !u!114 &1141039642 stripped MonoBehaviour: - m_CorrespondingSourceObject: {fileID: 1035623159758896108, guid: 97017ed3bb40aff4e885440d9a7336ee, type: 3} - m_PrefabInstance: {fileID: 2016604527338364568} + m_CorrespondingSourceObject: {fileID: 8381518232634759850, guid: cf153a3aea3d5da4f9d4cdbff0be8180, type: 3} + m_PrefabInstance: {fileID: 5297240775790447667} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 0} m_Enabled: 1 @@ -4934,7 +5068,7 @@ CharacterController: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1282734303} - m_Material: {fileID: 610463647} + m_Material: {fileID: 539493728} m_IncludeLayers: serializedVersion: 2 m_Bits: 0 @@ -4976,7 +5110,7 @@ MonoBehaviour: LookAtTarget: {fileID: 0} CustomLookAtTarget: 0 Lens: - FieldOfView: 40 + FieldOfView: 45 OrthographicSize: 10 NearClipPlane: 0.1 FarClipPlane: 5000 @@ -5010,6 +5144,11 @@ Transform: m_Children: [] m_Father: {fileID: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!137 &1294962561 stripped +SkinnedMeshRenderer: + m_CorrespondingSourceObject: {fileID: 8001664246499114791, guid: cf153a3aea3d5da4f9d4cdbff0be8180, type: 3} + m_PrefabInstance: {fileID: 5297240775790447667} + m_PrefabAsset: {fileID: 0} --- !u!1001 &1317768121 PrefabInstance: m_ObjectHideFlags: 0 @@ -5800,6 +5939,7 @@ MonoBehaviour: cameraInput: {fileID: 172071431} painter: {fileID: 0} freeCam: {fileID: 1282734304} + firstPerson: {fileID: 582951480} switchKey: 3 startModeIndex: 0 --- !u!4 &1516578028 @@ -6824,11 +6964,6 @@ Transform: m_CorrespondingSourceObject: {fileID: 468598, guid: 0525b7ad910d145f9a39a0da3b697815, type: 3} m_PrefabInstance: {fileID: 1762911884} m_PrefabAsset: {fileID: 0} ---- !u!4 &1774267802 stripped -Transform: - m_CorrespondingSourceObject: {fileID: 4348940595172967010, guid: 97017ed3bb40aff4e885440d9a7336ee, type: 3} - m_PrefabInstance: {fileID: 2016604527338364568} - m_PrefabAsset: {fileID: 0} --- !u!1001 &1797333846 PrefabInstance: m_ObjectHideFlags: 0 @@ -7678,7 +7813,7 @@ Transform: m_CorrespondingSourceObject: {fileID: 4922444305696846, guid: ac1cc01cb5dbf5d4f869c403b38f8a21, type: 3} m_PrefabInstance: {fileID: 1424346480} m_PrefabAsset: {fileID: 0} ---- !u!1001 &2016604527338364568 +--- !u!1001 &5297240775790447667 PrefabInstance: m_ObjectHideFlags: 0 serializedVersion: 2 @@ -7686,95 +7821,71 @@ PrefabInstance: serializedVersion: 3 m_TransformParent: {fileID: 0} m_Modifications: - - target: {fileID: 273411532115212066, guid: 97017ed3bb40aff4e885440d9a7336ee, type: 3} - propertyPath: scale - value: 0.5 - objectReference: {fileID: 0} - - target: {fileID: 1514890176713383521, guid: 97017ed3bb40aff4e885440d9a7336ee, type: 3} - propertyPath: m_Enabled - value: 1 - objectReference: {fileID: 0} - - target: {fileID: 4587432968399885263, guid: 97017ed3bb40aff4e885440d9a7336ee, type: 3} - propertyPath: poses.Array.size - value: 5 - objectReference: {fileID: 0} - - target: {fileID: 4587432968399885263, guid: 97017ed3bb40aff4e885440d9a7336ee, type: 3} - propertyPath: 'poses.Array.data[2]' - value: - objectReference: {fileID: 11400000, guid: 90df501d86681394b834f647f6f4e939, type: 2} - - target: {fileID: 4587432968399885263, guid: 97017ed3bb40aff4e885440d9a7336ee, type: 3} - propertyPath: 'poses.Array.data[3]' - value: - objectReference: {fileID: 11400000, guid: c5cf9d420554e5e4e96d3bee1903967a, type: 2} - - target: {fileID: 4587432968399885263, guid: 97017ed3bb40aff4e885440d9a7336ee, type: 3} - propertyPath: 'poses.Array.data[4]' - value: - objectReference: {fileID: 11400000, guid: 1545cfba9b5e06d41ae72c7ec766baaf, type: 2} - - target: {fileID: 5280718916654756701, guid: 97017ed3bb40aff4e885440d9a7336ee, type: 3} - propertyPath: m_IsActive - value: 1 - objectReference: {fileID: 0} - - target: {fileID: 5384024074013944205, guid: 97017ed3bb40aff4e885440d9a7336ee, type: 3} - propertyPath: m_Name - value: Player - objectReference: {fileID: 0} - - target: {fileID: 6997860362608943113, guid: 97017ed3bb40aff4e885440d9a7336ee, type: 3} - propertyPath: m_LocalScale.x - value: 0.5 - objectReference: {fileID: 0} - - target: {fileID: 6997860362608943113, guid: 97017ed3bb40aff4e885440d9a7336ee, type: 3} - propertyPath: m_LocalScale.y - value: 0.5 - objectReference: {fileID: 0} - - target: {fileID: 6997860362608943113, guid: 97017ed3bb40aff4e885440d9a7336ee, type: 3} - propertyPath: m_LocalScale.z - value: 0.5 - objectReference: {fileID: 0} - - target: {fileID: 6997860362608943113, guid: 97017ed3bb40aff4e885440d9a7336ee, type: 3} + - target: {fileID: 1950906664192868687, guid: cf153a3aea3d5da4f9d4cdbff0be8180, type: 3} propertyPath: m_LocalPosition.x value: 0 objectReference: {fileID: 0} - - target: {fileID: 6997860362608943113, guid: 97017ed3bb40aff4e885440d9a7336ee, type: 3} + - target: {fileID: 1950906664192868687, guid: cf153a3aea3d5da4f9d4cdbff0be8180, type: 3} propertyPath: m_LocalPosition.y value: 0 objectReference: {fileID: 0} - - target: {fileID: 6997860362608943113, guid: 97017ed3bb40aff4e885440d9a7336ee, type: 3} + - target: {fileID: 1950906664192868687, guid: cf153a3aea3d5da4f9d4cdbff0be8180, type: 3} propertyPath: m_LocalPosition.z value: 0 objectReference: {fileID: 0} - - target: {fileID: 6997860362608943113, guid: 97017ed3bb40aff4e885440d9a7336ee, type: 3} + - target: {fileID: 1950906664192868687, guid: cf153a3aea3d5da4f9d4cdbff0be8180, type: 3} propertyPath: m_LocalRotation.w value: 1 objectReference: {fileID: 0} - - target: {fileID: 6997860362608943113, guid: 97017ed3bb40aff4e885440d9a7336ee, type: 3} + - target: {fileID: 1950906664192868687, guid: cf153a3aea3d5da4f9d4cdbff0be8180, type: 3} propertyPath: m_LocalRotation.x value: 0 objectReference: {fileID: 0} - - target: {fileID: 6997860362608943113, guid: 97017ed3bb40aff4e885440d9a7336ee, type: 3} + - target: {fileID: 1950906664192868687, guid: cf153a3aea3d5da4f9d4cdbff0be8180, type: 3} propertyPath: m_LocalRotation.y value: 0 objectReference: {fileID: 0} - - target: {fileID: 6997860362608943113, guid: 97017ed3bb40aff4e885440d9a7336ee, type: 3} + - target: {fileID: 1950906664192868687, guid: cf153a3aea3d5da4f9d4cdbff0be8180, type: 3} propertyPath: m_LocalRotation.z value: 0 objectReference: {fileID: 0} - - target: {fileID: 6997860362608943113, guid: 97017ed3bb40aff4e885440d9a7336ee, type: 3} + - target: {fileID: 1950906664192868687, guid: cf153a3aea3d5da4f9d4cdbff0be8180, type: 3} propertyPath: m_LocalEulerAnglesHint.x value: 0 objectReference: {fileID: 0} - - target: {fileID: 6997860362608943113, guid: 97017ed3bb40aff4e885440d9a7336ee, type: 3} + - target: {fileID: 1950906664192868687, guid: cf153a3aea3d5da4f9d4cdbff0be8180, type: 3} propertyPath: m_LocalEulerAnglesHint.y value: 0 objectReference: {fileID: 0} - - target: {fileID: 6997860362608943113, guid: 97017ed3bb40aff4e885440d9a7336ee, type: 3} + - target: {fileID: 1950906664192868687, guid: cf153a3aea3d5da4f9d4cdbff0be8180, type: 3} propertyPath: m_LocalEulerAnglesHint.z value: 0 objectReference: {fileID: 0} + - target: {fileID: 3510981371713521867, guid: cf153a3aea3d5da4f9d4cdbff0be8180, type: 3} + propertyPath: m_Name + value: Player + objectReference: {fileID: 0} + - target: {fileID: 3510981371713521867, guid: cf153a3aea3d5da4f9d4cdbff0be8180, type: 3} + propertyPath: m_IsActive + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 8381518232634759850, guid: cf153a3aea3d5da4f9d4cdbff0be8180, type: 3} + propertyPath: sprintSpeedMultiplier + value: 2 + objectReference: {fileID: 0} m_RemovedComponents: [] m_RemovedGameObjects: [] - m_AddedGameObjects: [] + m_AddedGameObjects: + - targetCorrespondingSourceObject: {fileID: 1950906664192868687, guid: cf153a3aea3d5da4f9d4cdbff0be8180, type: 3} + insertIndex: -1 + addedObject: {fileID: 897939465} m_AddedComponents: [] - m_SourcePrefab: {fileID: 100100000, guid: 97017ed3bb40aff4e885440d9a7336ee, type: 3} + m_SourcePrefab: {fileID: 100100000, guid: cf153a3aea3d5da4f9d4cdbff0be8180, type: 3} +--- !u!4 &5297240775790447668 stripped +Transform: + m_CorrespondingSourceObject: {fileID: 5067936922952835876, guid: cf153a3aea3d5da4f9d4cdbff0be8180, type: 3} + m_PrefabInstance: {fileID: 5297240775790447667} + m_PrefabAsset: {fileID: 0} --- !u!1660057539 &9223372036854775807 SceneRoots: m_ObjectHideFlags: 0 @@ -7782,12 +7893,13 @@ SceneRoots: - {fileID: 1516578028} - {fileID: 2009475134} - {fileID: 330585546} + - {fileID: 582951482} - {fileID: 172071436} - {fileID: 1282734307} - {fileID: 832575519} - {fileID: 410087041} - {fileID: 2025317892} - - {fileID: 2016604527338364568} + - {fileID: 5297240775790447667} - {fileID: 686187287} - {fileID: 489277934} - {fileID: 347639557} diff --git a/Assets/Scripts/FirstPersonController.cs b/Assets/Scripts/FirstPersonController.cs new file mode 100644 index 0000000..2932e6d --- /dev/null +++ b/Assets/Scripts/FirstPersonController.cs @@ -0,0 +1,214 @@ +using UnityEngine; +using Unity.Cinemachine; +#if ENABLE_INPUT_SYSTEM +using UnityEngine.InputSystem; +#endif + +/// +/// First-person camera. Drives its OWN dedicated : each frame it snaps +/// to the player's CameraTarget (the same point the ThirdPersonCamera tracks) for position and +/// applies free mouse-look (yaw/pitch) for rotation. While active the player's mesh is hidden so the +/// body isn't seen from the inside. Movement stays with the player controller, which reads the +/// brain-driven Main Camera forward, so WASD is automatically relative to this view. +/// +/// Activation is driven by via : it raises the +/// vcam priority so the CinemachineBrain blends to it, snaps look to the current view (no jump), hides +/// the mesh and locks the cursor. While inactive the vcam rests at a low priority and this component +/// does nothing. +/// +[RequireComponent(typeof(CinemachineCamera))] +[DisallowMultipleComponent] +public class FirstPersonController : MonoBehaviour +{ + [Header("Target")] + [Tooltip("Eye position the camera sits at (the player's CameraTarget). Empty = auto-resolved from the player's \"CameraTarget\" child.")] + public Transform cameraTarget; + + [Tooltip("Renderers hidden while first-person is active (so you don't see your own body). Empty = the player's SkinnedMeshRenderers, auto-resolved.")] + public Renderer[] hiddenRenderers; + + [Header("Look")] + [Tooltip("Horizontal look sensitivity (degrees of yaw per pixel).")] + public float horizontalSensitivity = 0.2f; + + [Tooltip("Vertical look sensitivity (degrees of pitch per pixel).")] + public float verticalSensitivity = 0.15f; + + [Tooltip("Invert vertical look (mouse up tilts the camera down).")] + public bool invertY = false; + + [Tooltip("Pitch is clamped to +/- this angle (degrees) so the camera never flips over.")] + [Range(1f, 89.9f)] + public float maxPitch = 89f; + + [Header("Smoothing")] + [Tooltip("Look smoothing, in seconds. 0 = raw mouse (instant); small values take the edge off jitter without feeling laggy.")] + [Range(0f, 0.3f)] + public float lookSmoothTime = 0.04f; + + [Header("Camera")] + [Tooltip("Priority the dedicated CinemachineCamera takes while active (must beat the gameplay camera).")] + public int activePriority = 100; + + [Tooltip("Priority the dedicated CinemachineCamera rests at while inactive (must lose to the gameplay camera).")] + public int inactivePriority = -100; + + CinemachineCamera _vcam; + PlayerCharacterController _player; // body whose yaw we pin to the camera while active + PlayerPoseController _poseController; // supplies the active pose's per-pose first-person eye offset + float _yaw; // look target (raw input accumulates here) + float _pitch; + float _displayYaw; // smoothed value actually applied to the transform + float _displayPitch; + float _yawSmoothRef; + float _pitchSmoothRef; + bool _resolved; + + void Awake() + { + _vcam = GetComponent(); + if (!_vcam) + Debug.LogError("[FirstPersonController] No CinemachineCamera on this GameObject; first-person cannot go live.", this); + else + _vcam.Priority = inactivePriority; + + ResolveReferences(); + + // Dormant until FirstPersonMode enters; nothing reads input or moves the rig meanwhile. + enabled = false; + } + + /// Enter/leave first-person. Raises/lowers the vcam priority, hides the player mesh, snaps + /// look to the live view and manages the cursor. Called by . + public void SetActive(bool active) + { + if (_vcam) + _vcam.Priority = active ? activePriority : inactivePriority; + + SetMeshHidden(active); + + if (active) + { + SyncToCurrentView(); + SetCursorLocked(true); + ApplyTransform(); // place at the eye on the same frame so the blend starts from there + if (_player) _player.FaceYaw = _displayYaw; // body faces the camera from frame one + } + else + { + SetCursorLocked(false); + if (_player) _player.FaceYaw = null; // restore movement-facing + } + + enabled = active; + } + + void LateUpdate() + { + // LateUpdate so the player has already moved the CameraTarget this frame. + LookTick(); + ApplyTransform(); + if (_player) _player.FaceYaw = _displayYaw; // keep the body's yaw locked to the camera + } + + void LookTick() + { + Vector2 delta = ReadMouseDelta(); + _yaw += delta.x * horizontalSensitivity; + float vs = verticalSensitivity * (invertY ? 1f : -1f); + _pitch = Mathf.Clamp(_pitch + delta.y * vs, -maxPitch, maxPitch); + + if (lookSmoothTime > 0f) + { + // SmoothDampAngle is frame-rate-independent and wraps yaw correctly. + _displayYaw = Mathf.SmoothDampAngle(_displayYaw, _yaw, ref _yawSmoothRef, lookSmoothTime); + _displayPitch = Mathf.SmoothDampAngle(_displayPitch, _pitch, ref _pitchSmoothRef, lookSmoothTime); + } + else + { + _displayYaw = _yaw; + _displayPitch = _pitch; + } + } + + void ApplyTransform() + { + Quaternion rot = Quaternion.Euler(_displayPitch, _displayYaw, 0f); + if (cameraTarget) + { + // Sit at the shared camera target, then raise/lower the eye by the active pose's first-person + // offset. TransformVector keeps it in the target's local up and scales with the player (so it + // tracks PlayerScaler), without disturbing the target the ThirdPersonCamera shares. + Vector3 pos = cameraTarget.position; + float offset = _poseController ? _poseController.FirstPersonCameraYOffset : 0f; + if (offset != 0f) + pos += cameraTarget.TransformVector(Vector3.up * offset); + transform.SetPositionAndRotation(pos, rot); + } + else + transform.rotation = rot; + } + + /// Seed look from the currently rendered view so going live produces no visible jump. + void SyncToCurrentView() + { + var cam = Camera.main; + if (cam) + { + Vector3 e = cam.transform.rotation.eulerAngles; + _yaw = e.y; + float p = e.x > 180f ? e.x - 360f : e.x; + _pitch = Mathf.Clamp(p, -maxPitch, maxPitch); + } + + // Snap the smoothed state to the fresh pose so entering never lags/jumps to catch up. + _displayYaw = _yaw; + _displayPitch = _pitch; + _yawSmoothRef = 0f; + _pitchSmoothRef = 0f; + } + + void SetMeshHidden(bool hidden) + { + if (hiddenRenderers == null) return; + foreach (var r in hiddenRenderers) + if (r) r.enabled = !hidden; + } + + void ResolveReferences() + { + if (_resolved) return; + _resolved = true; + + var player = FindFirstObjectByType(FindObjectsInactive.Include); + if (!player) return; + _player = player; + + if (!_poseController) + _poseController = player.GetComponent(); + + if (!cameraTarget) + { + Transform t = player.transform.Find("CameraTarget"); + if (t) cameraTarget = t; + } + + if (hiddenRenderers == null || hiddenRenderers.Length == 0) + hiddenRenderers = player.GetComponentsInChildren(true); + } + + Vector2 ReadMouseDelta() + { +#if ENABLE_INPUT_SYSTEM + return Mouse.current != null ? Mouse.current.delta.ReadValue() : Vector2.zero; +#else + return new Vector2(Input.GetAxisRaw("Mouse X"), Input.GetAxisRaw("Mouse Y")) * 10f; +#endif + } + + static void SetCursorLocked(bool locked) + { + Cursor.lockState = locked ? CursorLockMode.Locked : CursorLockMode.None; + Cursor.visible = !locked; + } +} diff --git a/Assets/Scripts/FirstPersonController.cs.meta b/Assets/Scripts/FirstPersonController.cs.meta new file mode 100644 index 0000000..0c797b4 --- /dev/null +++ b/Assets/Scripts/FirstPersonController.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 43b8f1dc43642294f99fab0aaabf6197 \ No newline at end of file diff --git a/Assets/Scripts/FirstPersonMode.cs b/Assets/Scripts/FirstPersonMode.cs new file mode 100644 index 0000000..e4a89df --- /dev/null +++ b/Assets/Scripts/FirstPersonMode.cs @@ -0,0 +1,41 @@ +/// +/// First-person mode. The player keeps walking (WASD, camera-relative) but the camera moves to the +/// player's eye (the CameraTarget) with free mouse-look, and the player's mesh is hidden so the body +/// isn't seen from the inside. The orbit camera input is disabled while here so it doesn't fight for +/// the cursor; the drives its own dedicated CinemachineCamera. +/// +public class FirstPersonMode : GameMode +{ + public override string DisplayName => "First Person"; + + public override void Enter() + { + // Player stays fully controllable; only the view changes. + if (Manager.Player) + { + Manager.Player.enabled = true; + Manager.Player.ControlEnabled = true; + } + + if (Manager.Painter) + Manager.Painter.PaintingEnabled = false; + + // The orbit rig would otherwise keep grabbing the cursor and reading the mouse every frame. + if (Manager.CameraInput) + Manager.CameraInput.enabled = false; + + if (Manager.FirstPerson) + Manager.FirstPerson.SetActive(true); + } + + public override void Exit() + { + // Modes are Enter-only, so first-person must undo its own camera takeover (and unhide the mesh) + // here; the next mode's Enter restores the player/painter/look-mode state. + if (Manager.FirstPerson) + Manager.FirstPerson.SetActive(false); + + if (Manager.CameraInput) + Manager.CameraInput.enabled = true; + } +} diff --git a/Assets/Scripts/FirstPersonMode.cs.meta b/Assets/Scripts/FirstPersonMode.cs.meta new file mode 100644 index 0000000..3b1883c --- /dev/null +++ b/Assets/Scripts/FirstPersonMode.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: c514f1116e18b6c42907a5cb19aa228d \ No newline at end of file diff --git a/Assets/Scripts/GameModeManager.cs b/Assets/Scripts/GameModeManager.cs index b136b2d..6f4cdab 100644 --- a/Assets/Scripts/GameModeManager.cs +++ b/Assets/Scripts/GameModeManager.cs @@ -25,6 +25,9 @@ public class GameModeManager : MonoBehaviour [Tooltip("Free-fly spectator camera. Empty = found automatically. Absent = Free Cam is left out of the cycle.")] public FreeCamController freeCam; + [Tooltip("First-person camera. Empty = found automatically. Absent = First Person is left out of the cycle.")] + public FirstPersonController firstPerson; + //[Tooltip("Insect / surface-walk controller. Empty = found automatically.")] //public InsectController insect; @@ -43,6 +46,7 @@ public class GameModeManager : MonoBehaviour public ThirdPersonOrbitInput CameraInput => cameraInput; public MeshPainter Painter => painter; public FreeCamController FreeCam => freeCam; + public FirstPersonController FirstPerson => firstPerson; //public InsectController Insect => insect; /// Raised after a mode switch finishes (the new mode's Enter has already run). @@ -63,6 +67,7 @@ public class GameModeManager : MonoBehaviour if (!painter) painter = FindFirstObjectByType(); // Include inactive so a freecam rig that starts disabled is still found and wired. if (!freeCam) freeCam = FindFirstObjectByType(FindObjectsInactive.Include); + if (!firstPerson) firstPerson = FindFirstObjectByType(FindObjectsInactive.Include); //if (!insect) insect = FindFirstObjectByType(); BuildModes(); @@ -90,6 +95,10 @@ public class GameModeManager : MonoBehaviour if (freeCam) _modes.Add(new FreeCamMode()); + // First Person only joins the cycle when a first-person rig is present, so scenes without one are unchanged. + if (firstPerson) + _modes.Add(new FirstPersonMode()); + // Insect mode only joins the Tab cycle when a surface walker is present, so a scene // without one behaves exactly as before (no dead, player-freezing mode in the cycle). //if (insect) diff --git a/Assets/Scripts/PlayerCharacterController.cs b/Assets/Scripts/PlayerCharacterController.cs index f3f2206..4a800eb 100644 --- a/Assets/Scripts/PlayerCharacterController.cs +++ b/Assets/Scripts/PlayerCharacterController.cs @@ -147,6 +147,13 @@ public partial class PlayerCharacterController : MonoBehaviour /// public bool ControlEnabled { get; set; } = true; + /// + /// When set, the body faces this world-space yaw (degrees) every frame instead of turning toward its + /// movement direction. First-person sets it so the character always faces where the camera looks; + /// null restores movement-facing. Only affects ground/air locomotion — wall-climb owns its own facing. + /// + public float? FaceYaw { get; set; } + /// True while in wall-climb mode. public bool IsWallClimbing => _isWallClimbing; @@ -425,8 +432,13 @@ public partial class PlayerCharacterController : MonoBehaviour if (!_groundNormalUpdated) _groundNormal = Vector3.up; - // Face the movement direction, unless the right-button turn is actively steering the body. - if (rotateTowardMovement && !groundYawDrag && moveDir.sqrMagnitude > 0.0001f) + // Facing: first-person pins the body to the camera yaw (even while idle); otherwise turn toward + // the movement direction, unless the right-button turn is actively steering the body. + if (FaceYaw.HasValue) + { + transform.rotation = Quaternion.Euler(0f, FaceYaw.Value, 0f); + } + else if (rotateTowardMovement && !groundYawDrag && moveDir.sqrMagnitude > 0.0001f) { Quaternion target = Quaternion.LookRotation(moveDir, Vector3.up); transform.rotation = Quaternion.RotateTowards( diff --git a/Assets/Scripts/PlayerPose.cs b/Assets/Scripts/PlayerPose.cs index 382c54a..496d16b 100644 --- a/Assets/Scripts/PlayerPose.cs +++ b/Assets/Scripts/PlayerPose.cs @@ -58,6 +58,12 @@ public class PlayerPose : ScriptableObject "tracks, without moving the body. Meters.")] [SerializeField] private float cameraTargetYOffset; + [Tooltip("Additional local-up offset applied to the first-person eye (the FirstPersonController's camera " + + "position) while this pose is active, on top of the shared camera target. Only affects first " + + "person — never the body or the ThirdPersonCamera. Lets a low pose (ball/star) keep its eye at a " + + "sensible height even though the camera target sits where third-person frames it. Meters.")] + [SerializeField] private float firstPersonCameraTargetYOffset; + /// Idle clip held while the player stands still in this pose (may be null). public AnimationClip Clip => clip; @@ -87,4 +93,7 @@ public class PlayerPose : ScriptableObject /// Local-up offset applied to the camera target while this pose is active (any state). public float CameraTargetYOffset => cameraTargetYOffset; + + /// Additional local-up offset for the first-person eye, on top of the camera target (first person only). + public float FirstPersonCameraTargetYOffset => firstPersonCameraTargetYOffset; } diff --git a/Assets/Scripts/PlayerPoseController.cs b/Assets/Scripts/PlayerPoseController.cs index 0f66ce8..f947066 100644 --- a/Assets/Scripts/PlayerPoseController.cs +++ b/Assets/Scripts/PlayerPoseController.cs @@ -95,6 +95,7 @@ public partial class PlayerPoseController : MonoBehaviour private bool _blending; private float _cameraPoseOffset; // eased per-pose camera-target offset routed to the controller's camera target + private float _firstPersonCameraOffset; // eased per-pose first-person eye offset, read by the FirstPersonController (never written to the shared camera target) // Capsule blend: the CharacterController dimensions are eased toward the active pose's via a single // normalized blend (so the capsule stays a valid shape throughout) and written through the controller. @@ -120,6 +121,9 @@ public partial class PlayerPoseController : MonoBehaviour /// Index of the currently selected pose. public int CurrentIndex => _currentIndex; + /// Eased per-pose y-offset for the first-person eye, applied on top of the camera target by the FirstPersonController. + public float FirstPersonCameraYOffset => _firstPersonCameraOffset; + void Awake() { _player = GetComponent(); @@ -178,6 +182,14 @@ public partial class PlayerPoseController : MonoBehaviour ? Mathf.MoveTowards(_cameraPoseOffset, cameraPoseTarget, cameraOffsetSpeed * Time.deltaTime) : cameraPoseTarget; _player.SetCameraTargetLocalYOffset(_cameraPoseOffset); + + // First-person eye: a separate per-pose offset, eased the same way but NOT routed to the shared + // camera target (that would also move the ThirdPersonCamera). The FirstPersonController reads this + // and applies it to its own eye position only. + float firstPersonTarget = pose ? pose.FirstPersonCameraTargetYOffset : 0f; + _firstPersonCameraOffset = cameraOffsetSpeed > 0f + ? Mathf.MoveTowards(_firstPersonCameraOffset, firstPersonTarget, cameraOffsetSpeed * Time.deltaTime) + : firstPersonTarget; } void OnDisable() @@ -186,6 +198,7 @@ public partial class PlayerPoseController : MonoBehaviour // next idle frame. Also clear the camera offset and restore the default capsule we were holding. ReleasePose(); _cameraPoseOffset = 0f; + _firstPersonCameraOffset = 0f; if (_player) { _player.SetCameraTargetLocalYOffset(0f);