Esempio n. 1
0
        /// <summary>
        /// Whether the controller is on the surface given the terrain cast results. This doesn't affect
        /// the controller's physics, but rather will not invoke surface events if false.
        /// </summary>
        /// <param name="hit">The terrain cast results.</param>
        /// <returns></returns>
        public bool IsOnSurface(TerrainCastHit hit)
        {
            if (SurfaceRules.Count == 0)
            {
                return(DefaultSurfaceRule(hit));
            }

            for (var i = 0; i < SurfaceRules.Count; ++i)
            {
                if (!SurfaceRules[i](hit))
                {
                    return(false);
                }
            }

            if (Parents.Count == 0)
            {
                return(true);
            }

            for (var i = 0; i < Parents.Count; ++i)
            {
                var parent = Parents[i];
                if (!ReceivesEvents(parent, transform))
                {
                    return(false);
                }
            }

            return(true);
        }
Esempio n. 2
0
        public override void OnPlatformEnter(TerrainCastHit hit)
        {
            // Must be hit from the air
            if (hit.Controller == null || hit.Controller.Grounded)
            {
                return;
            }

            // Must be hit from the player's bottom side
            if (hit.Side != ControllerSide.Bottom || hit.Controller.RelativeVelocity.y > 0.0f)
            {
                return;
            }

            // Player must be in a roll
            if (!hit.Controller.IsPerforming <Roll>())
            {
                return;
            }

            hit.Controller.IgnoreThisCollision();
            hit.Controller.RelativeVelocity = new Vector2(hit.Controller.RelativeVelocity.x, BounceSpeed);
            ActivateObject(hit.Controller);
            Destroy(gameObject);
        }
Esempio n. 3
0
        // Removes the anchor associated with the hit.Source
        public override void OnSurfaceExit(TerrainCastHit hit)
        {
            if (!_anchors.ContainsKey(hit.Controller))
            {
                return;
            }

            var anchor   = _anchors[hit.Controller];
            var velocity = (Vector2)anchor.DeltaPosition / Time.fixedDeltaTime;

            if (hit.Controller.Grounded)
            {
                if (TransferMomentumGround)
                {
                    hit.Controller.PushOnGround(velocity);
                }
            }
            else
            {
                hit.Controller.Velocity += new Vector2(
                    TransferMomentumX ? velocity.x : 0.0f,
                    TransferMomentumY ? velocity.y : 0.0f);
            }

            _anchors.Remove(hit.Controller);
            Destroy(anchor.gameObject);
        }
Esempio n. 4
0
 public override void OnPlatformStay(TerrainCastHit hit)
 {
     if (!ObjectTrigger.Activated)
     {
         OnPlatformEnter(hit);
     }
 }
Esempio n. 5
0
        public override void OnPlatformEnter(TerrainCastHit hit)
        {
            if (hit.Controller == null || !hit.Controller.Grounded)
            {
                return;
            }
            if (hit.Side == ControllerSide.Bottom || hit.Side == ControllerSide.Top)
            {
                return;
            }

            var moveManager = hit.Controller.GetComponent <MoveManager>();

            if (moveManager == null || moveManager.IsActive <Roll>() ||
                Mathf.Abs(hit.Controller.GroundVelocity) < MinGroundSpeed)
            {
                return;
            }

            hit.Controller.IgnoreThisCollision();
            ActivateObject(hit.Controller);
            Destroy(gameObject);

            if (FreezeTime <= 0.0f)
            {
                return;
            }
            hit.Controller.Interrupt(FreezeTime);
        }
Esempio n. 6
0
 public override void OnPlatformExit(TerrainCastHit hit)
 {
     if (!WhenColliding)
     {
         return;
     }
     DeactivateObject(hit.Controller);
 }
Esempio n. 7
0
        // Restores old physics values.
        public override void OnSurfaceExit(TerrainCastHit hit)
        {
            var groundControl = hit.Controller.GetComponent <MoveManager>().Get <GroundControl>();

            groundControl.Acceleration    /= Friction;
            groundControl.Deceleration    /= Friction;
            hit.Controller.GroundFriction /= Friction;
        }
Esempio n. 8
0
 public override void OnSurfaceEnter(TerrainCastHit hit)
 {
     if (!RestoreOnExit)
     {
         return;
     }
     _oldGravities[hit.Controller.GetInstanceID()] = hit.Controller.GravityDirection;
 }
Esempio n. 9
0
 public override void OnSurfaceExit(TerrainCastHit hit)
 {
     if (!WhenOnSurface)
     {
         return;
     }
     DeactivateObject(hit.Controller);
 }
Esempio n. 10
0
        public override void OnSurfaceStay(TerrainCastHit hit)
        {
            var controller = hit.Controller;

            if (hit.Controller == null)
            {
                return;
            }

            var oldVelocity = controller.GroundVelocity;

            if (AccelerateBothWays)
            {
                if (AccountForFriction)
                {
                    controller.GroundVelocity += (controller.GroundFriction + Acceleration)
                                                 * Mathf.Sign(controller.GroundVelocity) * Time.fixedDeltaTime;
                }
                else
                {
                    controller.GroundVelocity += Acceleration * Mathf.Sign(controller.GroundVelocity) * Time.fixedDeltaTime;
                }

                var absTargetVg = Mathf.Abs(TargetVelocity);
                if (Mathf.Abs(oldVelocity) < absTargetVg && Mathf.Abs(controller.GroundVelocity) > absTargetVg)
                {
                    controller.GroundVelocity = TargetVelocity * Mathf.Sign(controller.GroundVelocity);
                }
            }
            else
            {
                if (AccountForFriction)
                {
                    controller.GroundVelocity += (Acceleration + controller.GroundFriction * Mathf.Sign(Acceleration))
                                                 * Time.fixedDeltaTime;
                }
                else
                {
                    controller.GroundVelocity += Acceleration * Time.fixedDeltaTime;
                }

                if (TargetVelocity > 0.0f)
                {
                    if (oldVelocity < TargetVelocity && controller.GroundVelocity > TargetVelocity)
                    {
                        controller.GroundVelocity = TargetVelocity;
                    }
                }
                else
                {
                    if (oldVelocity > TargetVelocity && controller.GroundVelocity < TargetVelocity)
                    {
                        controller.GroundVelocity = TargetVelocity;
                    }
                }
            }
        }
Esempio n. 11
0
        /// <summary>
        /// Lets the trigger know about a controller standing on its surface.
        /// </summary>
        /// <param name="hit">The collision data.</param>
        public void NotifySurfaceCollision(TerrainCastHit hit, bool bubble)
        {
            if (!IsOnSurface(hit))
            {
                return;
            }

            for (var i = 0; i < SurfaceCollisions.Count; ++i)
            {
                var collision = SurfaceCollisions[i];
                if (collision.Controller != hit.Controller)
                {
                    continue;
                }

                for (i = 0; i < _notifiedSurfaceCollisions.Count; ++i)
                {
                    var notifiedCollision = _notifiedSurfaceCollisions[i];
                    if (notifiedCollision.Controller == hit.Controller)
                    {
                        goto bubble;
                    }
                }

                _notifiedSurfaceCollisions.Add(hit);
                goto bubble;
            }

            if (SurfaceEnterSound != null)
            {
                SoundManager.Instance.PlayClipAtPoint(SurfaceEnterSound, transform.position);
            }
            SurfaceCollisions.Add(hit);
            _notifiedSurfaceCollisions.Add(hit);
            OnSurfaceEnter.Invoke(hit);

            if (SurfaceCollisions.Count == 1 && !enabled)
            {
                enabled = true;
            }

bubble:
            if (!bubble)
            {
                return;
            }
            for (var i = 0; i < Parents.Count; ++i)
            {
                var parent = Parents[i];
                if (!ReceivesEvents(parent, transform))
                {
                    return;
                }
                parent.NotifySurfaceCollision(hit, false);
            }
        }
Esempio n. 12
0
 public override bool IsSolid(TerrainCastHit hit)
 {
     if (hit.Controller == null)
     {
         return(true);
     }
     return(base.IsSolid(hit) && (!RequireGroundEntry ||
                                  (RequireGroundEntry && hit.Controller.Grounded &&
                                   !DMath.Equalsf(hit.Hit.fraction))));
 }
Esempio n. 13
0
 // The platform can be collided with if the player is checking its bottom side and
 // the result of the check did not stop where it started.
 public override bool IsSolid(TerrainCastHit hit)
 {
     // Check must be coming from player's bottom side and be close to the top
     // of the platform
     return(base.IsSolid(hit) &&
            hit.Hit.fraction > 0.0f &&
            (TopSolid && (hit.Side & ControllerSide.Bottom) > 0) ||
            (BottomSolid && (hit.Side & ControllerSide.Top) > 0) ||
            (LeftSolid && (hit.Side & ControllerSide.Right) > 0) ||
            (RightSolid && (hit.Side & ControllerSide.Left) > 0));
 }
Esempio n. 14
0
        public override void OnSurfaceExit(TerrainCastHit hit)
        {
            if (!RestoreOnExit)
            {
                return;
            }
            var instanceID = hit.Controller.GetInstanceID();

            hit.Controller.GravityDirection = _oldGravities[instanceID];
            _oldGravities.Remove(instanceID);
        }
Esempio n. 15
0
        private MovingPlatformAnchor CreateAnchor(TerrainCastHit hit)
        {
            var anchor = new GameObject().AddComponent <MovingPlatformAnchor>();

            anchor.LinkController(hit.Controller);
            anchor.name = hit.Controller.name + "'s Moving Platform Anchor";
            anchor.transform.SetParent(hit.Hit.transform);
            // We will update the anchor manually and lazily
            anchor.enabled = false;

            return(anchor);
        }
Esempio n. 16
0
 // The water is a surface if the player is upright, on top of it, grounded, not already submerged,
 // and running quickly enough.
 public override bool IsSolid(TerrainCastHit hit)
 {
     if (hit.Controller == null)
     {
         return(false);
     }
     return(base.IsSolid(hit) &&
            (hit.Side & ControllerSide.Bottom) > 0 &&
            hit.Hit.fraction > 0.0f &&
            hit.Controller.Grounded &&
            Mathf.Abs(hit.Controller.GroundVelocity) >= MinFloatSpeed);
 }
Esempio n. 17
0
        public override void OnPlatformStay(TerrainCastHit hit)
        {
            if (hit.Controller == null)
            {
                return;
            }

            if (CheckCrush(hit.Controller))
            {
                TriggerObject(hit.Controller);
            }
        }
Esempio n. 18
0
        public override void OnSurfaceExit(TerrainCastHit hit)
        {
            var instanceID = hit.Controller.GetInstanceID();

            if (!_originalSlopeGravities.ContainsKey(instanceID))
            {
                return;
            }

            hit.Controller.SlopeGravity = _originalSlopeGravities[instanceID];
            _originalSlopeGravities.Remove(instanceID);
        }
Esempio n. 19
0
 // Check if a controller leaves the platform
 public override void OnSurfaceExit(TerrainCastHit hit)
 {
     if (!_colliding)
     {
         return;
     }
     _colliding = false;
     if (Return)
     {
         DelayReturn();
     }
 }
Esempio n. 20
0
        public override void OnPlatformEnter(TerrainCastHit hit)
        {
            var hitSide = TerrainUtility.NormalToControllerSide(hit.NormalAngle * Mathf.Rad2Deg - transform.eulerAngles.z);

            if ((BouncySides & hitSide) == 0)
            {
                return;
            }

            if (LockControl)
            {
                hit.Controller.GetComponent <MoveManager>().Get <GroundControl>().Lock(LockDuration);
            }
            if (!KeepOnGround)
            {
                hit.Controller.Detach();

                var moveManager = hit.Controller.GetComponent <MoveManager>();
                if (moveManager != null)
                {
                    moveManager.End <Roll>();
                    moveManager.Perform <AirControl>(true);
                }

                hit.Controller.IgnoreThisCollision();
            }

            if (AccurateBounce)
            {
                hit.Controller.Velocity = new Vector2(hit.Controller.Velocity.x * Mathf.Abs(Mathf.Sin(hit.NormalAngle)),
                                                      hit.Controller.Velocity.y * Mathf.Abs(Mathf.Cos(hit.NormalAngle)));
                hit.Controller.Velocity += DMath.AngleToVector(hit.NormalAngle) * Power;
            }
            else
            {
                hit.Controller.Velocity = DMath.AngleToVector(hit.NormalAngle) * Power;
            }

            if (hit.Controller.Animator != null)
            {
                var logWarnings = hit.Controller.Animator.logWarnings;
                hit.Controller.Animator.logWarnings = false;

                if (!string.IsNullOrEmpty(HitTrigger))
                {
                    hit.Controller.Animator.SetTrigger(HitTrigger);
                }

                hit.Controller.Animator.logWarnings = logWarnings;
            }

            TriggerObject(hit.Controller);
        }
Esempio n. 21
0
        public override void OnSurfaceEnter(TerrainCastHit hit)
        {
            if (!WhenOnSurface)
            {
                return;
            }
            if (!Check(hit))
            {
                return;
            }

            ActivateObject(hit.Controller);
        }
Esempio n. 22
0
        public override void OnPlatformEnter(TerrainCastHit hit)
        {
            if (!WhenColliding)
            {
                return;
            }
            if (!Check(hit))
            {
                return;
            }

            ActivateObject(hit.Controller);
        }
Esempio n. 23
0
        // Updates the anchor associated with the hit.Source
        public override void OnSurfaceStay(TerrainCastHit hit)
        {
            if (!_anchors.ContainsKey(hit.Controller))
            {
                return;
            }
            var anchor = _anchors[hit.Controller];

            if (anchor.transform.parent != hit.Hit.transform)
            {
                anchor.transform.SetParent(hit.Hit.transform);
            }
            anchor.TranslateController();
        }
Esempio n. 24
0
        // Translate the controller by the amount defined in Velocity and the direction defined by its
        // surface angle.
        public override void OnSurfaceStay(TerrainCastHit hit)
        {
            var controller = hit.Controller;

            if (hit.Controller == null)
            {
                return;
            }

            controller.transform.Translate(DMath.AngleToVector(controller.SurfaceAngle * Mathf.Deg2Rad) * Velocity *
                                           Time.fixedDeltaTime);

            _lastSurfaceAngle = controller.SurfaceAngle;
        }
Esempio n. 25
0
        public override void OnPlatformEnter(TerrainCastHit hit)
        {
            if (hit.Controller == null)
            {
                return;
            }

            hit.Controller.Detach();
            hit.Controller.IgnoreThisCollision();
            hit.Controller.RelativeVelocity     = new Vector2(hit.Controller.RelativeVelocity.x, Velocity);
            GetComponent <Collider2D>().enabled = false;

            ActivateObject(hit.Controller);
        }
Esempio n. 26
0
        public override void OnPlatformStay(TerrainCastHit hit)
        {
            if (!WhenColliding)
            {
                return;
            }

            if (Check(hit))
            {
                ActivateObject(hit.Controller);
                return;
            }

            DeactivateObject(hit.Controller);
        }
Esempio n. 27
0
        public override void OnSurfaceStay(TerrainCastHit hit)
        {
            if (!WhenOnSurface)
            {
                return;
            }

            if (Check(hit))
            {
                ActivateObject(hit.Controller);
                return;
            }

            DeactivateObject(hit.Controller);
        }
Esempio n. 28
0
        public void OnCollide(TerrainCastHit hit)
        {
            // Bounce only if it's the controller's bottom colliding with the floor
            if ((hit.Side & ControllerSide.Bottom) == 0)
            {
                return;
            }

            // Normally we can't use a double jump again until we attach to the floor, so make
            // it available manually
            Used = false;

            // Set bounce velocity based on surface normal and jump input
            if (Input.GetButton(InputName))
            {
                Controller.Velocity = Vector2.Reflect(Controller.Velocity, hit.Hit.normal).normalized *
                                      (Controller.Inside <Water>() ? UnderwaterBounceSpeed : BounceSpeed);
            }
            else
            {
                Controller.Velocity = Vector2.Reflect(Controller.Velocity, hit.Hit.normal).normalized *
                                      (Controller.Inside <Water>() ? UnderwaterBounceReleaseSpeed : BounceReleaseSpeed);

                // If the jump input is no longer held down end the move immediately
                End();
            }

            // Prevent controller from landing on the surface it just hit
            Controller.IgnoreThisCollision();

            Controller.OnCollide.RemoveListener(OnCollide);

            if (BounceSound != null)
            {
                // Interrupt the diving sound
                if (_diveAudioSource.clip == DiveSound)
                {
                    _diveAudioSource.Stop();
                }
                SoundManager.Instance.PlayClipAtPoint(BounceSound, transform.position);
            }

            Bouncing = true;
            if (Animator != null && BounceTriggerHash != 0)
            {
                Animator.SetTrigger(BounceTriggerHash);
            }
        }
Esempio n. 29
0
        public override bool IsSolid(TerrainCastHit hit)
        {
            if (hit == null || hit.Controller == null)
            {
                return(false);
            }

            // Similar to a ledge - only solid to the controller's bottom sensors
            return(hit.Side == ControllerSide.Bottom &&
                   hit.Hit.fraction > 0.0f &&
                   hit.Controller.Grounded &&

                   // Use stay speed if controller is already standing on it, entry speed otherwise
                   (hit.Controller.StandingOn(transform)
                       ? Mathf.Abs(hit.Controller.GroundVelocity) > MinStaySpeed
                       : Mathf.Abs(hit.Controller.GroundVelocity) > MinEntrySpeed));
        }
Esempio n. 30
0
        private bool SurfaceCollisionsRemover(TerrainCastHit hit)
        {
            for (var i = 0; i < _notifiedSurfaceCollisions.Count; ++i)
            {
                if (_notifiedSurfaceCollisions[i].Controller == hit.Controller)
                {
                    return(false);
                }
            }

            if (SurfaceExitSound != null)
            {
                SoundManager.Instance.PlayClipAtPoint(SurfaceExitSound, transform.position);
            }
            OnSurfaceExit.Invoke(hit);
            return(true);
        }