1 (edited by MrPonton 2017-01-27 18:42:51)

Topic: Bug: Rect Body Colliders Don't Push Back (Pseudo-fixed)

Hello,

While researching my other topic (Creating unique HitBox states), found a bug that I've been trying to fix. Could use some help from the community if you guys can.

Bug: If a rectangular body collider hitbox collides with another body collider hitbox (circle or rect), there is no pushback.

Original Code from HitBoxesScript.cs (~Line 290):

    public float TestCollision(HitBox[] opHitBoxes) {
        float totalPushForce = 0;
        foreach (HitBox hitBox in hitBoxes) {
            if (hitBox.collisionType != CollisionType.bodyCollider) continue;
            foreach (HitBox opHitBox in opHitBoxes) {
                if (opHitBox.collisionType != CollisionType.bodyCollider) continue;
                Vector3 opHitBoxPosition = opHitBox.position.position;
                Vector3 hitBoxPosition = hitBox.position.position;
                if (!UFE.config.detect3D_Hits){
                    opHitBoxPosition = new Vector3(opHitBox.position.position.x, opHitBox.position.position.y, 0);
                    hitBoxPosition = new Vector3(hitBox.position.position.x, hitBox.position.position.y, 0);
                }
                float dist = Vector3.Distance(opHitBoxPosition, hitBoxPosition);
                if (dist <= opHitBox.radius + hitBox.radius) 
                    totalPushForce += (opHitBox.radius + hitBox.radius) - dist;
        }
        return totalPushForce;
    }

At Line 303 you'll see it only check for a the Circular body colliders. (By default, if you're using a Rectangular body collider then the default circular collider's radius is set to 0.5, which is still set regardless of it being a rectangle).

I've been able to get the game to register a collision correctly, but I have not been able to figure out how much totalPushForce to do in order to push the opponent to the edges of the boxes:

    public float TestCollision(HitBox[] opHitBoxes) {
        float totalPushForce = 0;
        foreach (HitBox hitBox in hitBoxes) {
            if (hitBox.collisionType != CollisionType.bodyCollider) continue;
            foreach (HitBox opHitBox in opHitBoxes) {
                if (opHitBox.collisionType != CollisionType.bodyCollider) continue;
                Vector3 opHitBoxPosition = opHitBox.position.position;
                Vector3 hitBoxPosition = hitBox.position.position;
                if (!UFE.config.detect3D_Hits){
                    opHitBoxPosition = new Vector3(opHitBox.position.position.x, opHitBox.position.position.y, 0);
                    hitBoxPosition = new Vector3(hitBox.position.position.x, hitBox.position.position.y, 0);
                }
                if (hitBox.shape == HitBoxShape.rectangle && opHitBox.shape == HitBoxShape.rectangle) {
                    float mirror = currentMirror ? 1 : -1;
                    float mirrorDiff = mirror > 0 ? opHitBox.rect.width : 0f;
                    Rect opHitBoxRectanglePosition = new Rect(
                                                        ((opHitBox.rect.x + mirrorDiff) * mirror) + opHitBoxPosition.x - opHitBoxPosition.x,
                                                        opHitBox.rect.y + opHitBoxPosition.y,
                                                        opHitBox.rect.width, 
                                                        opHitBox.rect.height);
                    mirrorDiff = mirror > 0 ? hitBox.rect.width : 0f;
                    Rect hitBoxRectanglePosition = new Rect(
                                                       ((hitBox.rect.x + mirrorDiff) * -mirror) + hitBoxPosition.x,
                                                       hitBox.rect.y + hitBoxPosition.y,
                                                       hitBox.rect.width, 
                                                       hitBox.rect.height);
                    if (opHitBoxRectanglePosition.Overlaps(hitBoxRectanglePosition)) {
                        totalForcePush += 0.2f;
                    }
                } else if (hitBox.shape == HitBoxShape.circle && opHitBox.shape == HitBoxShape.circle) {
                    float dist = Vector3.Distance(opHitBoxPosition, hitBoxPosition);
                    if (dist <= opHitBox.radius + hitBox.radius)
                        totalPushForce += (opHitBox.radius + hitBox.radius) - dist;
                }
            }
        }
        return totalPushForce;
    }

Note: While not confirmed, I don't think this code handles it if a rectangle collides with a circle, this would only cover instances of a rectangle body collider colliding with a rectangle body collider, and instances where a circle body collider collides with the circle body collider. We'd probably need to add that check as well, but starting first with Rectangle v Rectangle at this time.

Any help appreciated guys as I'm spinning my wheels here. In my example I should be getting ~0.1 to 0.5 as the totalPushForce but keep getting 1.0+ whenever I'm trying formulas.

Share

Thumbs up Thumbs down

2 (edited by MrPonton 2017-01-27 18:41:42)

Re: Bug: Rect Body Colliders Don't Push Back (Pseudo-fixed)

Was able to get it working thanks to finding an issue with calculations in creating the opHitBoxRectanglePosition rectangle. Still trying to find the best way to calculate the totalForcePush but for now have been fine with just setting it to 0.2f. Below is the corrected code and updated the first post as well with it.

Note: Still don't have a solution for Rectangle vs Circle, but I am only using Rectangles in my game so.... until someone else comes up with the issue of that case and wants to work together on it, this will do.

    public float TestCollision(HitBox[] opHitBoxes) {
        float totalPushForce = 0;
        foreach (HitBox hitBox in hitBoxes) {
            if (hitBox.collisionType != CollisionType.bodyCollider) continue;
            foreach (HitBox opHitBox in opHitBoxes) {
                if (opHitBox.collisionType != CollisionType.bodyCollider) continue;
                Vector3 opHitBoxPosition = opHitBox.position.position;
                Vector3 hitBoxPosition = hitBox.position.position;
                if (!UFE.config.detect3D_Hits){
                    opHitBoxPosition = new Vector3(opHitBox.position.position.x, opHitBox.position.position.y, 0);
                    hitBoxPosition = new Vector3(hitBox.position.position.x, hitBox.position.position.y, 0);
                }
                if (hitBox.shape == HitBoxShape.rectangle && opHitBox.shape == HitBoxShape.rectangle) {
                    float mirror = currentMirror ? 1 : -1;
                    float mirrorDiff = mirror > 0 ? opHitBox.rect.width : 0f;
                    Rect opHitBoxRectanglePosition = new Rect(
                                                        ((opHitBox.rect.x + mirrorDiff) * mirror) + opHitBoxPosition.x - opHitBoxPosition.x,
                                                        opHitBox.rect.y + opHitBoxPosition.y,
                                                        opHitBox.rect.width, 
                                                        opHitBox.rect.height);
                    mirrorDiff = mirror > 0 ? hitBox.rect.width : 0f;
                    Rect hitBoxRectanglePosition = new Rect(
                                                       ((hitBox.rect.x + mirrorDiff) * -mirror) + hitBoxPosition.x,
                                                       hitBox.rect.y + hitBoxPosition.y,
                                                       hitBox.rect.width, 
                                                       hitBox.rect.height);
                    if (opHitBoxRectanglePosition.Overlaps(hitBoxRectanglePosition)) {
                        totalForcePush += 0.2f;
                    }
                } else if (hitBox.shape == HitBoxShape.circle && opHitBox.shape == HitBoxShape.circle) {
                    float dist = Vector3.Distance(opHitBoxPosition, hitBoxPosition);
                    if (dist <= opHitBox.radius + hitBox.radius)
                        totalPushForce += (opHitBox.radius + hitBox.radius) - dist;
                }
            }
        }
        return totalPushForce;
    }

Share

Thumbs up Thumbs down