コード例 #1
0
ファイル: EntryPoint_World.cs プロジェクト: yemel/explorer
    internal static void Query(Protocol.QueryPayload payload)
    {
        MessagingBus.QueuedSceneMessage_Scene queuedMessage = GetSceneMessageInstance();

        string queryId = Convert.ToString(payload.raycastPayload.id);

        RaycastType raycastType = (RaycastType)payload.raycastPayload.raycastType;

        Ray ray = new Ray()
        {
            origin    = payload.raycastPayload.origin,
            direction = payload.raycastPayload.direction,
            distance  = payload.raycastPayload.distance
        };

        queuedMessage.method  = MessagingTypes.QUERY;
        queuedMessage.payload = new QueryMessage()
        {
            payload = new RaycastQuery()
            {
                id          = queryId,
                raycastType = raycastType,
                ray         = ray,
                sceneId     = currentSceneId
            }
        };

        queueHandler.EnqueueSceneMessage(queuedMessage);
    }
コード例 #2
0
 public RaycastSensor(RaycastType type, Vector3 direction, float distance, bool hitObject = false)
 {
     Type      = type;
     Direction = direction;
     Distance  = distance;
     HitObject = hitObject;
 }
コード例 #3
0
 /// <summary>
 /// Returns true if the this raycast type  is or contains the given raycast type.
 /// </summary>
 /// <param name="go">Go.</param>
 /// <param name="type">Type.</param>
 public static bool Contains(this RaycastType container, RaycastType type)
 {
     if ((container & type) == type)
     {
         return(true);
     }
     return(false);
 }
コード例 #4
0
        bool raycast(Vector2 origin, Vector2 target, Layer layer, RaycastType rcType)
        {
            var ray   = origin;
            var angle = MathHelper.PiOver2 - (float)Math.Atan2(ray.Y - target.Y, ray.X - target.X);

            while ((ray - target).Length() > 10)
            {
                if (rcType == RaycastType.Hit && _map.Layers[(int)layer].Tiles[GridToIndex(WorldToGrid(ray))].Gid != 0)
                {
                    return(true);
                }
                ray += new Vector2((float)Math.Sin(angle) * -2, (float)Math.Cos(angle) * -2);
            }
            return(rcType == RaycastType.Hit ? false : true);
        }
コード例 #5
0
    private void Raycast(Vector2 from, Vector2 to, RaycastType rayType)
    {
        bool hitDetected = false;

        hits = Physics2D.LinecastAll(from, to);

        //Iterate results
        foreach (RaycastHit2D hit in hits)
        {
            //Check if collider exists and is not the collider attached to target transform (self)
            if (hit.collider != null && hit.collider.transform != target)
            {
                hitDetected = true;
                HandleHit(hit);
            }
        }

        #region Debug rays
        if (showDebugRays)
        {
            Color lineColor = Color.white;

            switch (rayType)
            {
            case RaycastType.Horizontal:
                lineColor = Color.white;
                break;

            case RaycastType.Vertical:
                lineColor = Color.cyan;
                break;

            case RaycastType.IntersectionTop:
                lineColor = Color.magenta;
                break;

            case RaycastType.IntersectionBottom:
                lineColor = Color.yellow;
                break;
            }

            //Red whenever it hits something
            Debug.DrawLine(from, to, hitDetected ? Color.red : lineColor, debugRayLifetime);
        }
        #endregion
    }
コード例 #6
0
        /// <summary>
        /// Check for a gap by casting rays extending along the side colldiers.
        /// </summary>
        /// <returns><c>true</c>, if gap dection from side colliders was done, <c>false</c> otherwise.</returns>
        virtual protected bool DoGapDectionFromSideColliders()
        {
            RaycastType typeToCheck = character.Colliders [character.CurrentWallCollider].RaycastType;
            // Determine how much to offset the raycasts from ledge position
            Vector2 transformOffset = Vector2.zero;

            switch (animationTargetting)
            {
            case LedgeClimbAnimationTargetting.SPRITE_PIVOT:
                // For a sprite pivot use the stand offset
                transformOffset = standOffset;
                if (typeToCheck == RaycastType.SIDE_RIGHT)
                {
                    transformOffset.x = transformOffset.x * -1;
                }
                break;

            case LedgeClimbAnimationTargetting.BAKED:
                // For a sprite pivot use the stand offset
                transformOffset = standOffset;
                if (typeToCheck == RaycastType.SIDE_RIGHT)
                {
                    transformOffset.x = transformOffset.x * -1;
                }
                break;
            }
            foreach (BasicRaycast c in character.Colliders)
            {
                // If collider is of the right type
                if (c.RaycastType == typeToCheck)
                {
                    Vector2 finalPosition   = CurrentLedgePosition + c.Extent + transformOffset;
                    Vector2 initialPosition = new Vector2(character.transform.position.x, finalPosition.y);
                    Vector2 direction       = (finalPosition - initialPosition).normalized;
                    float   distance        = Mathf.Abs(finalPosition.x - character.transform.position.x);

                    RaycastHit2D hit = Physics2D.Raycast(initialPosition, direction, distance, character.geometryLayerMask);
                    if (hit.collider != null)
                    {
                        return(false);
                    }
                }
            }
            return(true);
        }
コード例 #7
0
        private void DrawPhysics1()          // 射线检测
        {
            m_RaycastType = (RaycastType)m_Tools.BiaoTi_O(m_RaycastType, (int)m_RaycastType, RaycastTypeStrs, 60);
            switch (m_RaycastType)
            {
            case RaycastType.Physics_Raycast:
                DrawPhysicsRaycast();
                break;

            case RaycastType.Physics_RaycastAll:
                DrawPhysicsRaycastAll();
                break;

            case RaycastType.Physics2D_Raycast:
                DrawPhysics2DRaycast();
                break;
            }
        }
コード例 #8
0
 /// <summary>
 /// Checks the given collisions type for enemies.
 /// </summary>
 /// <returns>Returns an IHurtable if found, or null if not found.</returns>
 virtual protected IHurtable CheckCollisions(RaycastType type)
 {
     for (int i = 0; i < character.Colliders.Length; i++)
     {
         if (character.Colliders[i].RaycastType == type)
         {
             for (int j = 0; j < character.CurrentCollisions[i].Length; j++)
             {
                 if (character.CurrentCollisions[i][j].collider != null &&
                     ((1 << character.CurrentCollisions[i][j].collider.gameObject.layer & enemyLayerMask) == enemyLayerMask))
                 {
                     IHurtable enemyHurtBox = (IHurtable)character.CurrentCollisions[i][j].collider.GetComponent(typeof(IHurtable));
                     if (enemyHurtBox != null)
                     {
                         return(enemyHurtBox);
                     }
                 }
             }
         }
     }
     return(null);
 }
コード例 #9
0
ファイル: Interface.cs プロジェクト: JacobLee325/explorer
 public static void ReportRaycastHitAllResult(string sceneId, string queryId, RaycastType raycastType, RaycastHitEntities payload)
 {
     ReportRaycastResult <RaycastHitAllResponse, RaycastHitEntities>(sceneId, queryId, Protocol.RaycastTypeToLiteral(raycastType), payload);
 }
コード例 #10
0
        /// <summary>
        /// Check for collider penetration of the given types on the given layers and move the character if found.
        /// </summary>
        /// <param name="typeMask">The types to consider.</param>
        /// <param name="layerMask">The layers to consider.</param>
        /// <returns>A vector representing the amount of movement applied.</returns>
        virtual public Vector2 DoCollisions(RaycastType typeMask, int layerMask, int passthroughLayerMask)
        {
            Vector2 result = Vector2.zero;

            float deepestSidePenetration = 0.0f;
            float deepestHeadPenetration = 0.0f;
            float deepestFootPenetration = 0.0f;
            float deepestNonPassthroughFootPenetration = 0.0f;

            int sideIndex = -1;
            int headIndex = -1;
            int footIndex = -1;
            int nonPassthroughFootIndex = -1;

            int groundedFeetCount    = 0;
            int passthroughFeetCount = 0;

            int  layer;
            bool parentFound = false;

            // TODO could we just do this every frame only sending a message once even if multiple collider types hit the collider?
            ResetCollisions();



            // If we are doing feet collisions update grounded
            if ((RaycastType.FOOT & typeMask) == RaycastType.FOOT)
            {
                grounded = false;
                if (character is Character)
                {
                    ((Character)character).StoodOnPlatform = null;
                    ((Character)character).GroundLayer     = -1;
                    ((Character)character).GroundCollider  = null;
                }
            }

            // If we are moving in Y assume we aren't grounded
            // if (character.Velocity.y != 0 ) grounded = false;

            // Get the closest collision - TODO: we have similar code in character too, its (very slightly) more efficient this way but maybe easier to maintain if we reuse?
            for (int i = 0; i < character.CurrentCollisions.Length; i++)
            {
                // If we are considering this type of collider
                if ((character.Colliders[i].RaycastType & typeMask) == character.Colliders[i].RaycastType)
                {
                    int      closest          = -1;
                    float    smallestFraction = float.MaxValue;
                    Platform platform         = null;
                    for (int j = 0; j < character.CurrentCollisions[i].Length; j++)
                    {
                        // Make sure we have a collision to support raycast colliders which use statically allocated hits arrays
                        if (character.CurrentCollisions[i][j].collider != null)
                        {
                            // Correct layer?
                            layer = character.CurrentCollisions[i][j].collider.gameObject.layer;
                            if ((1 << layer & layerMask) == 1 << layer || (character.Colliders[i].RaycastType == RaycastType.FOOT && (1 << layer & passthroughLayerMask) == 1 << layer))
                            {
                                if (character.CurrentCollisions[i][j].fraction > 0 && character.CurrentCollisions[i][j].fraction < smallestFraction)
                                {
                                    // The memory allocation only occurs in the editor, its not the GC trap that is seems
                                    Platform tmpPlatform = character.CurrentCollisions[i][j].collider.GetComponent <Platform>();
                                    if (tmpPlatform == null || !tmpPlatform.IgnoreCollision(character, character.Colliders[i]))
                                    {
                                        smallestFraction = character.CurrentCollisions[i][j].fraction;
                                        closest          = j;
                                        platform         = tmpPlatform;
                                    }
                                }
                            }
                        }
                    }

                    // Store the closest collider
                    closestColliders[i] = closest;
                    // Found a collision
                    if (closest != -1)
                    {
                        layer = character.CurrentCollisions[i][closest].collider.gameObject.layer;
                        float penetration = (character.CurrentCollisions[i][closest].fraction * (character.Colliders[i].Length + character.Colliders[i].LookAhead)) - character.Colliders[i].Length;
                        switch (character.Colliders[i].RaycastType)
                        {
                        case RaycastType.SIDE_LEFT:
                            if (penetration < deepestSidePenetration)
                            {
                                deepestSidePenetration = penetration;
                                sideIndex = i;
                            }
                            // Check for platforms
                            // TODO We may need a new lookahead if condition here. If the grounded look ahead
                            // was large we may be triggering platforms too early.
                            if (!HasReceivedCollideMessage(character.CurrentCollisions[i][closest].collider))
                            {
                                platformCollisionArgs.Character       = character;
                                platformCollisionArgs.RaycastCollider = character.Colliders[i];
                                platformCollisionArgs.Penetration     = penetration;
                                if (platform != null)
                                {
                                    bool parent = platform.Collide(platformCollisionArgs);
                                    if (parent)
                                    {
                                        parentFound = true;
                                        character.ParentPlatform    = platform;
                                        character.ParentRaycastType = RaycastType.SIDE_LEFT;
                                    }
                                    AddColliderToSentMessageReceivers(character.CurrentCollisions[i][closest].collider);
                                }
                            }
                            break;

                        case RaycastType.SIDE_RIGHT:
                            if (penetration < deepestSidePenetration)
                            {
                                deepestSidePenetration = penetration;
                                sideIndex = i;
                            }
                            // Check for platforms
                            // TODO We may need a new lookahead if condition here. If the grounded look ahead
                            // was large we may be triggering platforms too early.
                            if (!HasReceivedCollideMessage(character.CurrentCollisions[i][closest].collider))
                            {
                                platformCollisionArgs.Character       = character;
                                platformCollisionArgs.RaycastCollider = character.Colliders[i];
                                platformCollisionArgs.Penetration     = penetration;
                                if (platform != null)
                                {
                                    bool parent = platform.Collide(platformCollisionArgs);
                                    if (parent)
                                    {
                                        parentFound = true;
                                        character.ParentPlatform    = platform;
                                        character.ParentRaycastType = RaycastType.SIDE_RIGHT;
                                    }
                                    AddColliderToSentMessageReceivers(character.CurrentCollisions[i][closest].collider);
                                }
                            }
                            break;

                        case RaycastType.HEAD:
                            if (penetration < deepestHeadPenetration)
                            {
                                deepestHeadPenetration = penetration;
                                headIndex = i;
                            }
                            // Check for platforms
                            // TODO We may need a new lookahead if condition here. If the head look ahead
                            // was large we may be triggering platforms too early.
                            if (!HasReceivedCollideMessage(character.CurrentCollisions[i][closest].collider))
                            {
                                platformCollisionArgs.Character       = character;
                                platformCollisionArgs.RaycastCollider = character.Colliders[i];
                                platformCollisionArgs.Penetration     = penetration;
                                if (platform != null)
                                {
                                    bool parent = platform.Collide(platformCollisionArgs);
                                    if (parent)
                                    {
                                        parentFound = true;
                                        character.ParentPlatform    = platform;
                                        character.ParentRaycastType = RaycastType.HEAD;
                                    }
                                    AddColliderToSentMessageReceivers(character.CurrentCollisions[i][closest].collider);
                                }
                            }
                            character.WouldHitHeadThisFrame = true;
                            break;

                        case RaycastType.FOOT:
                            if (penetration < deepestFootPenetration)
                            {
                                deepestFootPenetration = penetration;
                                footIndex = i;
                            }
                            // Keep track of non passthrough feet collisions as these should be applied even if passthrough is deeper
                            if (((1 << layer & passthroughLayerMask) != 1 << layer) && penetration < deepestNonPassthroughFootPenetration)
                            {
                                deepestNonPassthroughFootPenetration = penetration;
                                nonPassthroughFootIndex = i;
                            }
                            // Check for platforms
                            // TODO We may need a new lookahead if condition here. If the grounded look ahead
                            // was large we may be triggering platforms too early.
                            if (!HasReceivedCollideMessage(character.CurrentCollisions[i][closest].collider))
                            {
                                platformCollisionArgs.Character       = character;
                                platformCollisionArgs.RaycastCollider = character.Colliders[i];
                                platformCollisionArgs.Penetration     = penetration;
                                if (platform != null)
                                {
                                    bool parent = platform.Collide(platformCollisionArgs);
                                    if (parent)
                                    {
                                        parentFound = true;
                                        character.ParentPlatform    = platform;
                                        character.ParentRaycastType = RaycastType.FOOT;
                                    }
                                    AddColliderToSentMessageReceivers(character.CurrentCollisions[i][closest].collider);
                                    // TODO: Currently we just take whichever is last in the feet collider array
                                    // we could update this to handle multiple platforms.
                                    character.StoodOnPlatform = platform;
                                }
                            }

                            if (penetration <= character.groundedLookAhead)
                            {
                                // Keep track of how many passthrough feet we have
                                if ((1 << layer & passthroughLayerMask) == 1 << layer)
                                {
                                    passthroughFeetCount++;
                                    // TODO consider if this should be user configurable?
                                    if (character.Velocity.y <= 0 && penetration > character.passthroughLeeway)
                                    {
                                        // Set grounded only if we are moving downwards
                                        grounded = true;
                                        // Keep track of how many feet we have grounded
                                        groundedFeetCount++;
                                        // Set layer if its not set or if this is the middle foot collider
                                        if (character.GroundLayer == -1 || i == character.FootCount / 2)
                                        {
                                            character.GroundLayer    = layer;
                                            character.GroundCollider = character.CurrentCollisions[i][closest].collider;
                                        }
                                    }
                                }
                                else
                                {
                                    // Set grounded
                                    grounded = true;
                                    // Keep track of how many feet we have grounded
                                    groundedFeetCount++;
                                    // Set layer if its not set or if this is the middle foot collider
                                    if (character.GroundLayer == -1 || i == character.FootCount / 2)
                                    {
                                        character.GroundLayer    = layer;
                                        character.GroundCollider = character.CurrentCollisions[i][closest].collider;
                                    }
                                }
                            }
                            break;

                        default:
                            Debug.LogError("Unexpected collider type");
                            break;
                        }
                    }
                }
            }

            // If we had penetration apply movement
            if (sideIndex != -1 && deepestSidePenetration < 0)
            {
                result.x = deepestSidePenetration * (character.Colliders[sideIndex].RaycastType == RaycastType.SIDE_LEFT ? -1 : 1);
                character.Translate(result.x, 0, false);
                if (!character.ActiveMovement.PreventXVelocityReset)
                {
                    if ((character.Velocity.x > 0 && character.Colliders[sideIndex].RaycastType == RaycastType.SIDE_RIGHT) ||
                        (character.Velocity.x < 0 && character.Colliders[sideIndex].RaycastType == RaycastType.SIDE_LEFT))
                    {
                        character.SetVelocityX(0);
                    }
                }
                // character.SetVelocityY(character.Velocity.y);
            }
            // Always apply geometry layer feet collisions
            if (nonPassthroughFootIndex != -1 && deepestNonPassthroughFootPenetration < 0)
            {
                result.y = -deepestNonPassthroughFootPenetration;
                character.Translate(0, -deepestNonPassthroughFootPenetration, false);
                // If we were moving down reset Y velocity to 0
                if (character.Velocity.y < 0)
                {
                    character.SetVelocityY(0);
                }
            }
            // Check for passthrough feet too
            if (footIndex != -1 && footIndex != nonPassthroughFootIndex && deepestFootPenetration < deepestNonPassthroughFootPenetration)
            {
                // Ensure we calculate the time to move feet distance
                if (!assumeConstantGravityAndFeetDistance && character.Colliders[footIndex].RaycastType == RaycastType.FOOT)
                {
                    if (character.Gravity < 0)
                    {
                        timeToFallFeetDistance = Mathf.Sqrt((-2 * character.Colliders[footIndex].Length) / character.Gravity);
                    }
                }
                // Additional conditions for passthrough feet
                if (character.Velocity.y <= 0 && (grounded || character.TimeFalling >= timeToFallFeetDistance))
                {
                    result.y = -deepestFootPenetration;
                    character.Translate(0, -deepestFootPenetration, false);

                    // If we were moving down reset Y velocity to 0
                    if (character.Velocity.y < 0)
                    {
                        character.SetVelocityY(0);
                    }
                }
            }
            if (headIndex != -1 & deepestHeadPenetration < 0)
            {
                result.y = deepestHeadPenetration;
                character.Translate(0, deepestHeadPenetration, false);
                // If we were moving up reset Y velocity to 0
                if (character.Velocity.y > 0)
                {
                    character.SetVelocityY(0);
                }
            }

            // If we are doing feet collisions update parent state
            if (((character.ParentRaycastType & typeMask) == character.ParentRaycastType) && !parentFound)
            {
                character.ParentPlatform = null;
            }

            // If we are doing feet collisions update grounded
            if ((RaycastType.FOOT & typeMask) == RaycastType.FOOT)
            {
                character.GroundedFootCount = groundedFeetCount;
            }
            return(result);
        }
コード例 #11
0
        /// <summary>
        /// Gets a value indicating whether this movement wants to control the movement on the ground.
        /// This movement wants control if the side colliders are pulling a box.
        /// </summary>
        /// <value><c>true</c> if this instance wants control; otherwise, <c>false</c>.</value>
        override public bool WantsGroundControl()
        {
            if (!enabled)
            {
                return(false);
            }
            if (character.DefaultGroundMovement == this)
            {
                Debug.LogError("The Pull movement can't be the default ground movement. Disabling movement.");
                enabled = false;
            }

            // Early out, only pull if grounded.
            if (!character.Grounded)
            {
                LosingControl();
                return(false);
            }

            // Early out, if last frame we were pulling one way, we want to lose control for at least one frame before pulling another way
            if (!latched && pullDirection == -character.Input.HorizontalAxisDigital)
            {
                LosingControl();
                return(false);
            }

            // Early out, if we were pulling, and our velocity is non zero and we are still holding down pull keep going
            if (pullable != null && !latched && pullDirection == character.Input.HorizontalAxisDigital && character.Velocity.x != 0)
            {
                return(true);
            }

            // If we are latched check if we are still latched
            if (latched && pullable != null)
            {
                if (character.Input.HorizontalAxisDigital == -pullDirection || character.Input.HorizontalAxisDigital == 0)
                {
                    if (latchTimer <= 0)
                    {
                        LosingControl();
                    }
                    return(false);
                }
                // Start pulling
                if (character.Input.HorizontalAxisDigital == pullDirection)
                {
                    latched        = false;
                    pullDelayTimer = PullDelayTime;
                    return(true);
                }
            }

            // Try to find a pullable
            int         hitCount            = 0;
            IPullable   matchingPullable    = null;
            float       pullableDistance    = 1;
            float       nonPullableDistance = 1;
            RaycastType typeToCheck         = (character.Input.HorizontalAxisDigital == 1 ? RaycastType.SIDE_RIGHT : RaycastType.SIDE_LEFT);

            initialPullOffset = 0;
            for (int i = 0; i < character.Colliders.Length; i++)
            {
                if (character.Colliders[i].RaycastType == typeToCheck)
                {
                    RaycastHit2D hit = character.GetClosestCollision(i);
                    if (hit.collider != null)
                    {
                        IPullable currentPullable = (IPullable)hit.collider.GetComponent(typeof(IPullable));
                        // Pulling  something that isn't pushable TODO add distance checks.
                        if (currentPullable == null)
                        {
                            if (hit.fraction < nonPullableDistance)
                            {
                                nonPullableDistance = hit.fraction;
                            }
                        }
                        else
                        {
                            if (currentPullable != matchingPullable)
                            {
                                // Found a closer pushable (or if matching pushable is null we just found a pushable)
                                if (hit.fraction < pullableDistance)
                                {
                                    pullableDistance  = hit.fraction;
                                    matchingPullable  = currentPullable;
                                    initialPullOffset = (hit.fraction * (character.Colliders[i].Length + character.Colliders[i].LookAhead)) - character.Colliders[i].Length - character.Colliders[i].LookAhead;
                                    hitCount          = 1;
                                }
                            }
                            else
                            {
                                hitCount++;
                            }
                        }
                    }
                }
            }

            if (matchingPullable != null && pullableDistance < nonPullableDistance && initialPullOffset < 0)
            {
                pullable           = matchingPullable;
                initialPullOffset *= -character.Input.HorizontalAxisDigital;
                pullDirection      = -character.Input.HorizontalAxisDigital;
                latched            = true;
                latchTimer         = LatchTime;
            }
            return(false);
        }
コード例 #12
0
 public WindowRaycastNode(WindowSection section_, Vector3 pos_, RaycastType type_)
 {
     section = section_;
     pos     = pos_;
     type    = type_;
 }
コード例 #13
0
        /// <summary>
        /// Utility method which checks for side collissions.
        /// </summary>
        /// <returns><c>true</c>, if sides hit something, <c>false</c> otherwise.</returns>
        /// <param name="character">Character to check.</param>
        /// <param name="requiredHits">Required number of side hits.</param>
        /// <param name="types">Side types to check.</param>
        static public bool CheckSideCollisions(Character character, int requiredHits, RaycastType types)
        {
            int hitCount = 0;

            for (int i = 0; i < character.Colliders.Length; i++)
            {
                if ((character.Colliders[i].RaycastType & types) == character.Colliders[i].RaycastType)
                {
                    RaycastHit2D hit = character.GetClosestCollision(i);
                    if (hit.collider != null)
                    {
                        hitCount++;
                        if (hitCount >= requiredHits)
                        {
                            return(true);
                        }
                    }
                }
            }
            return(false);
        }
コード例 #14
0
ファイル: Raycaster.cs プロジェクト: Wttewaall/3dhype-gamejam
 public void UseCenter()
 {
     castType = RaycastType.Center;
     CastRay();
 }
コード例 #15
0
ファイル: Raycaster.cs プロジェクト: Wttewaall/3dhype-gamejam
    // ---- public methods ----

    public void UseMouse()
    {
        castType = RaycastType.Mouse;
        CastRay();
    }
コード例 #16
0
ファイル: Raycaster.cs プロジェクト: Wttewaall/3dhype-gamejam
 // ---- public methods ----
 public void UseMouse()
 {
     castType = RaycastType.Mouse;
     CastRay();
 }
コード例 #17
0
ファイル: Movement.cs プロジェクト: Connorlc/UnityProjects
 /// <summary>
 /// Utility method which checks for side collissions.
 /// </summary>
 /// <returns><c>true</c>, if sides hit something, <c>false</c> otherwise.</returns>
 /// <param name="character">Character to check.</param>
 /// <param name="requiredHits">Required number of side hits.</param>
 /// <param name="types">Side types to check.</param>
 public static bool CheckSideCollisions(Character character, int requiredHits, RaycastType types)
 {
     int hitCount = 0;
     for (int i = 0; i < character.Colliders.Length; i++)
     {
         if ((character.Colliders[i].RaycastType & types) == character.Colliders[i].RaycastType)
         {
             RaycastHit2D hit = character.GetClosestCollision(i);
             if (hit.collider != null)
             {
                 hitCount++;
                 if (hitCount >= requiredHits) return true;
             }
         }
     }
     return false;
 }
コード例 #18
0
        /// <summary>
        /// Gets a value indicating whether this movement wants to control the movement on the ground.
        /// This movement wants control if the side colliders are pushing against a box.
        /// </summary>
        /// <value><c>true</c> if this instance wants control; otherwise, <c>false</c>.</value>
        override public bool WantsGroundControl()
        {
            if (!enabled)
            {
                return(false);
            }
            if (character.DefaultGroundMovement == this)
            {
                Debug.LogError("The Push movement can't be the default ground movement. Disabling movement.");
                enabled = false;
            }

            // Early out, only push if grounded.
            if (!character.Grounded)
            {
                return(false);
            }

            // Early out, only push if pressing in a direction.
            if (character.Input.HorizontalAxisDigital == 0)
            {
                return(false);
            }

            // Early out, if last frame we were pusing one way, we want to lose control for at least one frame before pushing another way
            if (pushDirection == -character.Input.HorizontalAxisDigital)
            {
                return(false);
            }

            int         hitCount            = 0;
            Pushable    matchingPushable    = null;
            float       pushableDistance    = 1;
            float       nonPushableDistance = 1;
            RaycastType typeToCheck         = (character.Input.HorizontalAxisDigital == 1 ? RaycastType.SIDE_RIGHT : RaycastType.SIDE_LEFT);

            initialPushOffset = 0;
            for (int i = 0; i < character.Colliders.Length; i++)
            {
                if (character.Colliders[i].RaycastType == typeToCheck)
                {
                    RaycastHit2D hit = character.GetClosestCollision(i);
                    if (hit.collider != null)
                    {
                        Pushable currentPushable = hit.collider.GetComponent <Pushable>();
                        // Pushing against something that isn't pushable TODO add distance checks.
                        if (currentPushable == null)
                        {
                            if (hit.fraction < nonPushableDistance)
                            {
                                nonPushableDistance = hit.fraction;
                            }
                        }
                        else
                        {
                            if (currentPushable != matchingPushable)
                            {
                                // Found a closer pushable (or if matching pushable is null we just found a pushable)
                                if (hit.fraction < pushableDistance)
                                {
                                    pushableDistance  = hit.fraction;
                                    matchingPushable  = currentPushable;
                                    initialPushOffset = (hit.fraction * (character.Colliders[i].Length + character.Colliders[i].LookAhead)) - character.Colliders[i].Length - character.Colliders[i].LookAhead;
                                    hitCount          = 1;
                                }
                            }
                            else
                            {
                                hitCount++;
                            }
                        }
                    }
                }
            }

            if (matchingPushable != null && pushableDistance < nonPushableDistance && initialPushOffset < 0)
            {
                pushable           = matchingPushable;
                initialPushOffset *= -character.Input.HorizontalAxisDigital;
                pushDirection      = character.Input.HorizontalAxisDigital;
                return(true);
            }
            return(false);
        }
コード例 #19
0
ファイル: Raycaster.cs プロジェクト: Wttewaall/3dhype-gamejam
 public void UseCenter()
 {
     castType = RaycastType.Center;
     CastRay();
 }