using UnityEngine; /// /// A selectable player pose: an idle 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, its own CharacterController capsule dimensions (so a low pose like a ball can /// crawl under furniture the default standing capsule is too tall for), and a camera-target y-offset that /// frames the pose without moving the body. 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". /// [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; [Header("Collision")] [Tooltip("CharacterController capsule center Y while this pose is active (meters, local space). Lower " + "this together with Height so a short pose still rests its feet on the floor.")] [SerializeField] private float controllerCenterY = 0.66f; [Tooltip("CharacterController capsule radius while this pose is active (meters). Unity clamps it to " + "half the height.")] [Min(0.01f)] [SerializeField] private float controllerRadius = 0.1f; [Tooltip("CharacterController capsule height while this pose is active (meters). Lower it (with Center " + "Y) so a ball/star pose can crawl under a table or couch the default capsule is too tall for.")] [Min(0.01f)] [SerializeField] private float controllerHeight = 1.3f; [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. Meters.")] [SerializeField] private float cameraTargetYOffset; /// Idle clip held while the player stands still in this pose (may be null). public AnimationClip Clip => clip; /// Playback speed multiplier for the idle clip (1 = authored speed). public float ClipSpeed => clipSpeed; /// Optional clip played while walking on the ground; null = hold the idle pose. public AnimationClip WalkClip => walkClip; /// Playback speed multiplier for the walk clip (1 = authored speed). public float WalkClipSpeed => walkClipSpeed; /// Optional clip played while sprinting on the ground; null = hold the idle pose. public AnimationClip RunClip => runClip; /// Playback speed multiplier for the run clip (1 = authored speed). public float RunClipSpeed => runClipSpeed; /// CharacterController capsule center Y applied while this pose is active. public float ControllerCenterY => controllerCenterY; /// CharacterController capsule radius applied while this pose is active. public float ControllerRadius => controllerRadius; /// CharacterController capsule height applied while this pose is active. public float ControllerHeight => controllerHeight; /// Local-up offset applied to the camera target while this pose is active (any state). public float CameraTargetYOffset => cameraTargetYOffset; }