Beispiel #1
0
    // Ready for hell?
    // Have fun
    // 3D-Ready: ABSO-F*****G-LUTELY NOT
    public override void OnCollisionEnter(Collision collision)
    {
        if (!character.InStateGroup("airCollision"))
        {
            return;
        }

        // Set ground speed or ignore collision based on angle
        // See: https://info.sonicretro.org/SPG:Solid_Tiles#Reacquisition_Of_The_Ground

        // Wait a minute, why are we doing a raycast to get a normal/position that we already know??
        // BECAUSE, the normal/position from the collision is glitchy as f**k.
        // This helps smooth things out.
        RaycastHit hit = character.GetSolidRaycast(
            collision.GetContact(0).point - transform.position
            );

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

        Vector3 hitEuler = Quaternion.FromToRotation(Vector3.up, hit.normal).eulerAngles;
        // Round this or any tiiiny deviation in angle can allow the character
        // to jump at walls and stick to them
        float hitAngle = Mathf.Round(hitEuler.z); // TODO: 3D

        CharacterCollisionModifier collisionModifier = collision.transform.GetComponentInParent <CharacterCollisionModifier>();

        if (collisionModifier != null)
        {
            switch (collisionModifier.type)
            {
            case CharacterCollisionModifier.CollisionModifierType.NoGrounding:
                return;

            case CharacterCollisionModifier.CollisionModifierType.NoGroundingLRB:
                if (hitAngle > 90 && hitAngle < 270)
                {
                    return;
                }
                break;

            case CharacterCollisionModifier.CollisionModifierType.NoGroundingLRBHigher:
                if (hitAngle > 45 && hitAngle < 315)
                {
                    return;
                }
                break;
            }
        }

        ReacquireGround(hitAngle);
    }
Beispiel #2
0
    // 3D-Ready: NO
    bool GetIsGrounded(RaycastHit hit)   // Potentially avoid recomputing raycast
    {
        if (hit.collider == null)
        {
            return(false);
        }

        float hitAngle  = Quaternion.FromToRotation(Vector3.up, hit.normal).eulerAngles.z;
        float angleDiff = Mathf.DeltaAngle(
            hitAngle,
            forwardAngle
            );

        CharacterCollisionModifier collisionModifier = hit.transform.GetComponentInParent <CharacterCollisionModifier>();

        if (collisionModifier != null)
        {
            switch (collisionModifier.type)
            {
            case CharacterCollisionModifier.CollisionModifierType.NoGrounding:
                return(false);

            case CharacterCollisionModifier.CollisionModifierType.NoGroundingLRB:
                if (hitAngle > 90 && hitAngle < 270)
                {
                    return(false);
                }
                break;

            case CharacterCollisionModifier.CollisionModifierType.NoGroundingLRBHigher:
                if (hitAngle > 45 && hitAngle < 315)
                {
                    return(false);
                }
                break;
            }
        }

        return(angleDiff < 67.5F);
    }