// 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); }
// 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); }