Add cameraTargetYOffset to PlayerPose so each pose can offset the Cinemachine ThirdPersonCamera follow/look target independently of the body mesh. PlayerCharacterController gains a cameraTarget reference (auto-resolved via the "CameraTarget" child, base position captured in Awake) and a single-writer SetCameraTargetLocalYOffset. PlayerPoseController eases the per-pose camera offset and composes it with the shared ceiling offset, so the camera target follows the ceiling lift in lockstep with the mesh. Wire cameraTarget explicitly in SampleScene. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
74 lines
3.8 KiB
C#
74 lines
3.8 KiB
C#
using UnityEngine;
|
|
|
|
/// <summary>
|
|
/// A selectable player pose: an idle <see cref="AnimationClip"/> held while the player stands still,
|
|
/// plus optional walk and run clips that the pose system plays itself (the Animator stays empty) while
|
|
/// moving on the ground, and a y-offset applied to the visual model only while stuck to the ceiling
|
|
/// (so the pose hangs at the right height). The first ScriptableObject in this project.
|
|
///
|
|
/// Named PlayerPose (not Pose) to avoid shadowing the built-in UnityEngine.Pose struct, mirroring
|
|
/// why the controller is PlayerCharacterController and not just "PlayerController".
|
|
/// </summary>
|
|
[CreateAssetMenu(fileName = "NewPose", menuName = "Chameleon/Pose")]
|
|
public class PlayerPose : ScriptableObject
|
|
{
|
|
[Tooltip("Clip held while the player is idle in this pose (looped if the clip itself loops, " +
|
|
"otherwise frozen on its last frame). Authored for the paintman generic rig; clips for " +
|
|
"other hierarchies will not retarget.")]
|
|
[SerializeField] private AnimationClip clip;
|
|
|
|
[Tooltip("Playback speed multiplier for the idle clip. 1 = authored speed.")]
|
|
[Range(0.1f, 3f)]
|
|
[SerializeField] private float clipSpeed = 1f;
|
|
|
|
[Tooltip("Optional. Played instead of the idle clip while walking on the ground (moving, not " +
|
|
"sprinting). Leave empty to keep holding the idle pose while walking. Should loop.")]
|
|
[SerializeField] private AnimationClip walkClip;
|
|
|
|
[Tooltip("Playback speed multiplier for the walk clip. 1 = authored speed.")]
|
|
[Range(0.1f, 3f)]
|
|
[SerializeField] private float walkClipSpeed = 1f;
|
|
|
|
[Tooltip("Optional. Played instead of the idle clip while sprinting on the ground. Leave empty to " +
|
|
"keep holding the idle pose while sprinting. Should loop.")]
|
|
[SerializeField] private AnimationClip runClip;
|
|
|
|
[Tooltip("Playback speed multiplier for the run clip. 1 = authored speed.")]
|
|
[Range(0.1f, 3f)]
|
|
[SerializeField] private float runClipSpeed = 1f;
|
|
|
|
[Tooltip("Local-up offset added to the visual model ONLY while stuck to the ceiling, so the pose " +
|
|
"hangs at the right height. Ignored on the ground and on walls. Meters.")]
|
|
[SerializeField] private float ceilingYOffset;
|
|
|
|
[Tooltip("Local-up offset applied to the camera target (the ThirdPersonCamera's follow/look target) " +
|
|
"while this pose is active, in ANY state. Frames the pose by raising/lowering what the camera " +
|
|
"tracks, without moving the body. The ceiling offset is added on top of this while on the " +
|
|
"ceiling. Meters.")]
|
|
[SerializeField] private float cameraTargetYOffset;
|
|
|
|
/// <summary>Idle clip held while the player stands still in this pose (may be null).</summary>
|
|
public AnimationClip Clip => clip;
|
|
|
|
/// <summary>Playback speed multiplier for the idle clip (1 = authored speed).</summary>
|
|
public float ClipSpeed => clipSpeed;
|
|
|
|
/// <summary>Optional clip played while walking on the ground; null = hold the idle pose.</summary>
|
|
public AnimationClip WalkClip => walkClip;
|
|
|
|
/// <summary>Playback speed multiplier for the walk clip (1 = authored speed).</summary>
|
|
public float WalkClipSpeed => walkClipSpeed;
|
|
|
|
/// <summary>Optional clip played while sprinting on the ground; null = hold the idle pose.</summary>
|
|
public AnimationClip RunClip => runClip;
|
|
|
|
/// <summary>Playback speed multiplier for the run clip (1 = authored speed).</summary>
|
|
public float RunClipSpeed => runClipSpeed;
|
|
|
|
/// <summary>Local-up offset applied to the model only while on the ceiling.</summary>
|
|
public float CeilingYOffset => ceilingYOffset;
|
|
|
|
/// <summary>Local-up offset applied to the camera target while this pose is active (any state).</summary>
|
|
public float CameraTargetYOffset => cameraTargetYOffset;
|
|
}
|