using ProjectM.Simulation; using Unity.CharacterController; using Unity.Entities; using UnityEngine; namespace ProjectM.Authoring { /// /// Authoring for the kinematic-character half of the player ghost (M5b: Unity Character Controller). Added /// to the SAME prefab GameObject as PlayerAuthoring + the GhostAuthoringComponent (multiple bakers /// per GameObject is supported; both resolve the same Entity). The baker calls /// , which adds the CC runtime components/buffers /// (KinematicCharacterProperties, KinematicCharacterBody, StoredKinematicCharacterData, the four CC /// buffers, kinematic PhysicsVelocity/PhysicsMass, PhysicsGravityFactor, CharacterInterpolation) and bakes /// the GameObject's CapsuleCollider into a PhysicsCollider. We then add our /// + . /// /// IMPORTANT: BakeCharacter aborts (logs an error, adds nothing) if the GameObject has a Rigidbody and /// requires uniform (1,1,1) scale — so the M5 Rigidbody MUST be removed from the prefab (the M5 /// CapsuleCollider stays — it is what gets baked into the character's PhysicsCollider). /// /// [DisallowMultipleComponent] public class PlayerCharacterAuthoring : MonoBehaviour { [Tooltip("Sharpness of ground velocity smoothing (higher = snappier).")] public float GroundedMovementSharpness = 15f; public AuthoringKinematicCharacterProperties CharacterProperties = AuthoringKinematicCharacterProperties.GetDefault(); private class PlayerCharacterBaker : Baker { public override void Bake(PlayerCharacterAuthoring authoring) { // Top-down planar character: no gravity (handled in the processor), stay on the plane. var props = authoring.CharacterProperties; props.SnapToGround = false; // no floor entity to snap to; planar props.EvaluateGrounding = true; // floor/obstacle contact still reads as grounded props.InterpolatePosition = true; // smooth fixed-step position for presentation props.InterpolateRotation = false; // rotation owned by PlayerAimSystem props.SimulateDynamicBody = false; // players don't physically shove each other (keep simple) KinematicCharacterUtilities.BakeCharacter(this, authoring.gameObject, props); var entity = GetEntity(TransformUsageFlags.Dynamic | TransformUsageFlags.WorldSpace); AddComponent(entity, new CharacterComponent { GroundedMovementSharpness = authoring.GroundedMovementSharpness, StepAndSlopeHandling = BasicStepAndSlopeHandlingParameters.GetDefault(), }); AddComponent(entity, new CharacterControl()); } } } }