using System;
using UnityEngine;
namespace NeoCC
{
///
/// INeoCharacterController is a character controller, which handles kinematic character movement and collision resolution within a scene.
///
public interface INeoCharacterController
{
///
/// The velocity of the character during the last move phase with some corrections such as ignoring the vertical movement of steps.
///
Vector3 velocity { get; }
///
/// The actual velocity of the character during the last move phase with no modifications applied.
///
Vector3 rawVelocity { get; }
///
/// The velocity from the character input during the last move phase, before collision response was calculated.
///
Vector3 targetVelocity { get; }
///
/// The collision layers the controller will collide with when moving.
///
LayerMask collisionMask { get; set; }
///
/// The collision layers the controller will depenetrate from. Use this to prevent small rigidbodies from causing the character to move out of the way
///
LayerMask depenetrationMask { get; set; }
///
/// Is the character in contact with a ground surface.
///
bool isGrounded { get; }
///
/// The amount of time the controller has been airborne without a ground contact.
///
float airTime { get; }
///
/// The normal of the last ground contact.
///
Vector3 groundNormal { get; }
///
/// The normal of the ground surface for the last contact. If the controller is on a ledge, this is the top surface of the ledge.
///
Vector3 groundSurfaceNormal { get; }
///
/// The height below which the character controller should snap to the ground.
///
float groundSnapHeight { get; set; }
///
/// The collision flags for detecting scene collisions while moving.
///
NeoCharacterCollisionFlags collisionFlags { get; }
///
/// Should the character move with platforms it's in contact with. Defaults to false.
///
bool ignorePlatforms { get; set; }
///
/// The platform the character is currently affected by.
///
IMovingPlatform platform { get; }
///
/// Should the character inherit yaw rotation from moving platforms? Defaults to true.
///
bool inheritPlatformYaw { get; set; }
///
/// Should the character inherit velocity along its up vector from moving platforms? Defaults to false.
///
NeoCharacterVelocityInheritance inheritPlatformVelocity { get; set; }
///
/// The maximum upwards slope the character can climb. Any horizontal movement into the slope will not become vertical movement above this angle.
///
float slopeLimit { get; set; }
///
/// The friction of ground contacts when standiong on a slope. At 1, all downward velocity will be cancelled out. At 0, the character will slide down the slope.
///
float slopeFriction { get; set; }
///
/// The friction of ground contacts when the controller is overhanging a ledge. At 1, the character will not slide off the ledge.
///
float ledgeFriction { get; set; }
///
/// The move vector from the last fixed update move.
///
Vector3 lastFrameMove { get; }
///
/// The character will step up onto ledges with this height without losing horizontal speed.
/// The upward movement will not be factored into the character velocity at the end of the move.
///
float stepHeight { get; set; }
///
/// The up axis for the controller in world space.
///
Vector3 up { get; }
///
/// The forward axis of the controller in world space.
///
Vector3 forward { get; }
///
/// The right axis of the controller in world space.
///
Vector3 right { get; }
///
/// The gravity vector applied to this character.
///
Vector3 gravity { get; }
///
/// The variable gravity setup for this character if applicable.
///
INeoCharacterVariableGravity characterGravity { get; }
///
/// The height of the character capsule.
///
float height { get; set; }
///
/// The radius of the character capsule.
///
float radius { get; set; }
///
/// When performing the move loop, the capsule is shrunk by this amount. When testing for contacts it is grown by this amount.
///
float skinWidth { get; set; }
///
/// The mass of the character.
///
float mass { get; set; }
///
/// Should the character collide with scene colliders (static or otherwise). Defaults to true.
///
bool collisionsEnabled { get; set; }
///
/// Should the character push dynamic rigidbodies. Defaults to true.
///
bool pushRigidbodies { get; set; }
///
/// Should the character push other character controllers. Defaults to true.
///
bool pushCharacters { get; set; }
///
/// Can the character be pushed by other character controllers. Defaults to true.
///
bool pushedByCharacters { get; set; }
///
/// If this is true, any forces applied with AddForce() will be ignored. Defaults to false.
///
bool ignoreExternalForces { get; set; }
///
/// A manual initialisation function to prevent issues with script execution order
///
void Initialise();
///
/// Attach input callbacks to the character controller. The controller movement needs to occur in a specific sequence, and so will
/// request input when required.
///
/// A callback for the character move, called each fixed update.
void SetMoveCallback(NeoCharacterControllerDelegates.GetMoveVector moveCallback, NeoCharacterControllerDelegates.OnMoved onMovedCallback);
///
/// Check if the character has space to change its height to the specified value without overlapping the environment.
///
/// The target height. The height can not be smaller than double the radius.
/// Can the character expand or not.
bool IsHeightRestricted(float h);
///
/// Try to set the character capsule height to a specific value. The height can not be smaller than double the radius.
/// If the character height is restricted by the environment, then the character height will not be changed.
///
/// The target height.
/// The point to resize from. 0 is the bottom of the current capsule, and 1 is the top.
/// Did the character height change (true), or was it restricted (false).
bool TrySetHeight(float h, float fromNormalisedHeight = 0f);
///
/// Set the height of the character to a specific value. The height can not be smaller than double the radius.
/// If the resulting capsule would overlap the environment then the controller will keep trying until there is space for the capsule to be resized.
///
/// The target height.
/// The point to resize from. 0 is the bottom of the current capsule, and 1 is the top.
void SetHeight(float h, float fromNormalisedHeight = 0f);
///
/// Try to reset the character capsule height to its value upon start.
/// If the character height is restricted by the environment, then the character height will not be changed.
///
/// The point to resize from. 0 is the bottom of the current capsule, and 1 is the top.
/// Did the character height change (true), or was it restricted (false).
bool TryResetHeight(float fromNormalisedHeight = 0f);
///
/// Reset the character capsule height to its value upon start.
/// If the character height is restricted, it will keep trying until it has space to resize, or the height change is cancelled.
///
/// The point to resize from. 0 is the bottom of the current capsule, and 1 is the top.
void ResetHeight(float fromNormalisedHeight = 0f);
///
/// Cancel any delayed height change and keep the current height.
///
void CancelHeightChange();
///
/// Try to reset the character capsule radius to its value upon start.
/// If the resulting capsule would overlap the environment then the character capsule will not be changed.
///
/// The target radius.
/// Did the character radius change (true), or was it restricted (false).
bool TrySetRadius(float r);
///
/// Set the radius of the character to a specific value.
/// If the resulting capsule would overlap the environment then the controller will keep trying until there is space for the capsule to be resized.
///
/// The target radius.
void SetRadius(float r);
///
/// Try to reset the character capsule radius to its value upon start.
/// If the resulting capsule would overlap the environment then the character capsule will not be changed.
///
/// Did the character radius change (true), or was it restricted (false).
bool TryResetRadius();
///
/// Reset the character capsule radius to its value upon start.
/// If the resulting capsule would overlap the environment then the controller will keep trying until there is space for the capsule to be resized.
///
void ResetRadius();
///
/// An event that is fired when the character changes height.
/// If the character height is restricted, then a height change will be delayed until the character has space to resize.
///
event NeoCharacterControllerDelegates.OnHeightChange onHeightChanged;
///
/// A callback that is used by the character to resolve collisions with other INeoCharacterController characters.
/// The character should implement and expose a default handler.
///
NeoCharacterControllerDelegates.OnHitCharacter characterCollisionHandler { get; set; }
///
/// A callback that is used by the character to resolve collisions with dynamic rigidbodies.
/// The character should implement and expose a default handler.
///
NeoCharacterControllerDelegates.OnHitRigidbody rigidbodyCollisionHandler { get; set; }
///
/// An event fired when the character collides with an obstacle while calculating its move.
/// Not all collisions fire an event. For example, colliding with a step and stepping up is handled silently.
///
event NeoCharacterControllerDelegates.OnCharacterControllerHit onControllerHit;
///
/// An event fired when the character is teleported to a new position.
///
event NeoCharacterControllerDelegates.OnTeleported onTeleported;
///
/// Move to the new position and rotation. Updates velocity and properties to match new frame of reference
///
/// The position the character should move to.
/// The new rotation for the character.
/// Is the rotation parameter relative to the current rotation or absolute?
void Teleport(Vector3 position, Quaternion rotation, bool relativeRotation = true);
///
/// Add a force to the character outside of the usual movement logic (eg. explosions, etc)
///
/// Force vector in world coordinates.
/// Type of force to apply. See the Unity Scripting Reference.
void AddForce (Vector3 force, ForceMode mode = ForceMode.Force, bool disableGroundSnapping = false);
///
/// Add a position offset to the next movement tick
///
void AddPositionOffset(Vector3 offset);
///
/// Add a yaw rotation offset to the next movement tick
///
void AddYawOffset(float yaw);
///
/// Set all velocity variables to a specific vector
///
void SetVelocity(Vector3 v);
///
/// Reset all velocity variables to zero
///
void ResetVelocity();
///
/// Reset the vertical component of all velocity variables to zero
///
void ResetVerticalVelocity();
///
/// Reset the horizontal component of all velocity variables to zero
///
void ResetHorizontalVelocity();
bool RayCast(float normalisedHeight, Vector3 castVector, Space space, int layerMask = -5);
bool RayCast(float normalisedHeight, Vector3 castVector, Space space, out RaycastHit hit, int layerMask = -5, QueryTriggerInteraction queryTriggerInteraction = QueryTriggerInteraction.UseGlobal);
bool SphereCast(float normalisedHeight, Vector3 castVector, Space space, int layerMask = -5);
bool SphereCast(float normalisedHeight, Vector3 castVector, Space space, out RaycastHit hit, int layerMask = -5, QueryTriggerInteraction queryTriggerInteraction = QueryTriggerInteraction.UseGlobal);
bool CapsuleCast(Vector3 castVector, Space space, int layerMask = -5);
bool CapsuleCast(Vector3 castVector, Space space, out RaycastHit hit, int layerMask = -5, QueryTriggerInteraction queryTriggerInteraction = QueryTriggerInteraction.UseGlobal);
T GetComponent();
Transform transform { get; }
#if UNITY_EDITOR
Vector3 debugExternalForceMove { get; }
bool debugSnapToGround { get; }
int debugMoveIterations { get; }
int debugDepenetrationCount { get; }
#endif
}
}