using UnityEngine; namespace ECM2.Examples.Glide { /// /// This example shows how to extend a Character (through composition) implementing a Glide mechanic. /// public class GlideAbility : MonoBehaviour { public bool canEverGlide = true; public float maxFallSpeedGliding = 1.0f; private Character _character; protected bool _glideInputPressed; protected bool _isGliding; public bool glideInputPressed => _glideInputPressed; /// /// Is the Character gliding? /// public virtual bool IsGliding() { return _isGliding; } /// /// Request to start a glide. /// public virtual void Glide() { _glideInputPressed = true; } /// /// Request to stop gliding. /// public virtual void StopGliding() { _glideInputPressed = false; } /// /// Determines if the character is able to perform a glide in its current state. /// protected virtual bool IsGlideAllowed() { return canEverGlide && _character.IsFalling(); } /// /// Determines if the character can perform a requested glide. /// protected virtual bool CanGlide() { bool isGlideAllowed = IsGlideAllowed(); if (isGlideAllowed) { Vector3 worldUp = -_character.GetGravityDirection(); float verticalSpeed = Vector3.Dot(_character.GetVelocity(), worldUp); isGlideAllowed = verticalSpeed < 0.0f; } return isGlideAllowed; } /// /// Start / Stop a requested glide. /// protected virtual void CheckGlideInput() { if (!_isGliding && _glideInputPressed && CanGlide()) { _isGliding = true; _character.maxFallSpeed = maxFallSpeedGliding; } else if (_isGliding && (!_glideInputPressed || !CanGlide())) { _isGliding = false; _character.maxFallSpeed = 40.0f; } } private void OnBeforeCharacterSimulationUpdated(float deltaTime) { CheckGlideInput(); } private void Awake() { _character = GetComponent(); } private void OnEnable() { _character.BeforeSimulationUpdated += OnBeforeCharacterSimulationUpdated; } private void OnDisable() { _character.BeforeSimulationUpdated -= OnBeforeCharacterSimulationUpdated; } } }