using UnityEngine; namespace ECM2.Examples.FirstPersonFly { /// /// This example shows how to extend a Character (through composition) and use /// its Flying movement mode to implement a fly ability. /// /// Flying movement mode needs to be manually enabled / disabled as needed. /// public class FlyAbility : MonoBehaviour { public bool canEverFly = true; private Character _character; /// /// Determines if the Character is able to fly in its current state. /// private bool IsFlyAllowed() { return canEverFly && _character.IsFalling(); } /// /// Determines if the character should enter flying movement mode. /// protected virtual bool CanFly() { bool isFlyAllowed = IsFlyAllowed(); if (isFlyAllowed) { // If Fly is allowed, determine if is falling down otherwise its a jump! Vector3 worldUp = -_character.GetGravityDirection(); float verticalSpeed = Vector3.Dot(_character.GetVelocity(), worldUp); isFlyAllowed = verticalSpeed < 0.0f; } return isFlyAllowed; } private void OnCollided(ref CollisionResult collisionResult) { // If flying and collided with walkable ground, exit flying state. // I.e: Change to Falling movement mode as this is managed based on grounding status. if (_character.IsFlying() && collisionResult.isWalkable) _character.SetMovementMode(Character.MovementMode.Falling); } private void OnBeforeSimulationUpdated(float deltaTime) { // Attempts to enter Flying movement mode bool isFlying = _character.IsFlying(); bool wantsToFly = _character.jumpInputPressed; if (!isFlying && wantsToFly && CanFly()) _character.SetMovementMode(Character.MovementMode.Flying); } private void Awake() { _character = GetComponent(); } private void OnEnable() { _character.Collided += OnCollided; _character.BeforeSimulationUpdated += OnBeforeSimulationUpdated; } private void OnDisable() { _character.Collided -= OnCollided; _character.BeforeSimulationUpdated -= OnBeforeSimulationUpdated; } } }