예제 #1
0
        /// <summary>
        /// Runs a raycast from the faction member to an actor to determine if vision is clear or blocked.
        /// This method is public to expose it to delegates that might need it when overriding default
        /// functionality.
        /// </summary>
        /// <param name="me">This faction member's eyes transform.</param>
        /// <param name="other">The transform of the actor we're trying to witness.</param>
        /// <param name="layerMask">The raycast layermask.</param>
        /// <param name="dimension">The dimension in which to run the raycast.</param>
        /// <returns></returns>
        public GameObject Raycast(Transform me, Transform other, LayerMask layerMask, Dimension dimension)
        {
            switch (dimension)
            {
            case Dimension.Is2D:
                return(MorePhysics2D.Raycast2DWithoutSelf(me, other, layerMask));

            default:
            case Dimension.Is3D:
                RaycastHit hitInfo;
                var        hit = Physics.Linecast(me.position, other.position, out hitInfo, layerMask);
                return(hit ? hitInfo.collider.gameObject : null);
            }
        }
        protected Vector2 MoveIntelligentlyTowards(Vector2 position, float precision)
        {
            // Figure out what direction we're facing based on our animator
            var direction = (transform.position.x > position.x) ? -1 : 1;

            if (transform.position.x.IsWithin(precision, position.x))
            {
                // if we're in the air, and nothing is below us, force us to keep moving so we don't fall
                if (!IsGrounded && groundCheckHit.transform == null)
                {
                    return(new Vector2(direction * moveSpeed, CurrentVelocity.y));
                }
                // if we're close enough to the position we seek, set to zero (but maintain gravity)
                return(new Vector2(0f, CurrentVelocity.y));
            }

            // Tell the animator to face towards the position
            animator.FaceTowardsPosition(position);

            var footCenter = GetFeetCenter();

            // Checks if there is ground in front of us
            groundCheckHit = MorePhysics2D.RaycastOther(gameObject, CreateCloseGroundRay(direction, footCenter), groundCheckDistance, groundLayers, -999, 999);

            // Checks if there's something we can jump over to
            jumpAcrossHit = MorePhysics2D.RaycastOther(gameObject, CreateJumpAcrossRay(direction, footCenter), jumpAcrossDistance, groundLayers, -999, 999);

            // Checks if something is in front of us
            forwardCheckHit = MorePhysics2D.RaycastOther(gameObject, CreateForwardRay(direction), forwardCheckDistance, groundLayers, -999, 999);

            // Check if something is above us
            jumpUpHit = MorePhysics2D.RaycastOther(gameObject, CreateJumpUpRay(direction), jumpUpDistance, groundLayers, -999, 999);

            // Checks if there's something we can jump down to
            jumpDownHit = MorePhysics2D.RaycastOther(gameObject, CreateJumpDownRay(direction, footCenter), jumpDownDistance, groundLayers, -999, 999);

            // if there's a solid in front of us or we're falling
            if (groundCheckHit.transform != null || !IsGrounded)
            {
                // Nothing is in our way
                if (forwardCheckHit.transform == null)
                {
                    // Move towards the destination
                    return(new Vector2(Mathf.Sign(direction) * moveSpeed, CurrentVelocity.y));
                }
                // Something is in our way but we can jump over it
                else if (jumpUpHit.transform == null && CurrentVelocity.y.IsWithin(0.1f, 0))
                {
                    // Jump straight up in the air (next frame will carry our velocity towards our destination)
                    animator.Jump();
                    AddRigidBodyForce(0, jumpHeight);
                    return(new Vector2(0, CurrentVelocity.y));
                }
            }
            // if we are on the ground but there's a gap in front of us
            else if (groundCheckHit.transform == null && IsGrounded)
            {
                // There's some ground to jump over to
                if (jumpAcrossHit.transform != null && CurrentVelocity.y.IsWithin(0.1f, 0))
                {
                    // Jump straight up in the air (next frame will carry our velocity towards our destination)
                    animator.Jump();
                    AddRigidBodyForce(0, jumpHeight);
                    return(new Vector2(0, CurrentVelocity.y));
                }
                // There's nothing to jump over to, but we can drop down to floor below us
                else if (jumpDownHit.transform != null)
                {
                    // Move towards the destination
                    return(new Vector2(Mathf.Sign(direction) * moveSpeed, CurrentVelocity.y));
                }
            }

            // If we get here, the AI has no idea what to do so just wait
            return(new Vector2(0, CurrentVelocity.y));
        }