protected void OnAreaExit(ReactiveArea area) { if (!(area is Water) || Player.Inside <Water>()) { return; } var exit = FindWaterExit(); if (!exit) { return; } var splash = Instantiate(Splash); splash.transform.position = exit.point; splash.transform.eulerAngles = new Vector3( splash.transform.eulerAngles.x, splash.transform.eulerAngles.y, DMath.Angle(exit.normal) * Mathf.Rad2Deg - 90f); OnExitSplash.Invoke(); }
public void FixedUpdate() { // Apply gravity Rigidbody2D.velocity -= Vector2.up * Gravity * Time.fixedDeltaTime; if (Rigidbody2D.velocity.magnitude > 0.01f) { // Make sure we don't hit ourselves var queriesHitTriggers = Physics2D.queriesHitTriggers; Physics2D.queriesHitTriggers = false; // Circlecast the change in position var result = Physics2D.CircleCast(_previousPosition, Radius, transform.position - _previousPosition, (transform.position - _previousPosition).magnitude, CollisionLayers.AllMask); Vector2 velocity = Rigidbody2D.velocity; if (result && result.fraction > 0f) { // Store positive angle in degrees var angle = DMath.PositiveAngle_d(DMath.Angle(result.normal) * Mathf.Rad2Deg); if (AccurateBounce) { // For an accurate bounce, just reflect off the normal velocity = Vector2.Reflect(velocity, result.normal) * AccurateBounceLoss; } else { // Check if the surface is vertical or horizontal if ((angle > 22.5f && angle < 157.5f) || (angle > 202.5f && angle < 337.5f)) { // Horizontal surface, bounce vertically velocity = new Vector2(velocity.x, -BounceLoss.y); // If we've lost all momentum, set horizontal velocity to zero too if (velocity.y < 0.01f) { velocity = new Vector2(0.0f, 0.0f); } } else { // Vertical surface, bounce horizontally velocity = new Vector2(-BounceLoss.x, velocity.y); // If we've lost all momentum, set vertical velocity to zero too if (velocity.x < 0.01f) { velocity = new Vector2(0.0f, 0.0f); } } } // We hit something, revert the position change transform.position = _previousPosition; } Rigidbody2D.velocity = velocity; Physics2D.queriesHitTriggers = queriesHitTriggers; } _previousPosition = transform.position; }
public override void OnAreaStay(Hitbox hitbox) { var controller = hitbox.Controller; if (PullOffGround && controller.Grounded) { controller.Detach(); } if (WorkOnGround && controller.Grounded) { var oldVelocity = controller.GroundVelocity; var surfaceAngle = controller.SurfaceAngle * Mathf.Deg2Rad; var targetAngle = surfaceAngle - DMath.Angle(TargetVelocity); var targetMagnitude = TargetVelocity.magnitude; var result = Mathf.Cos(targetAngle) * Power * Time.fixedDeltaTime; var limit = Mathf.Cos(targetAngle) * targetMagnitude; if (Mathf.Abs(oldVelocity) > Mathf.Abs(limit)) { return; } if (AccountForFriction && !DMath.Equalsf(result)) { result += controller.GroundFriction * Mathf.Sign(result) * Time.fixedDeltaTime; } controller.GroundVelocity += result; if (oldVelocity < limit && controller.GroundVelocity > limit) { controller.GroundVelocity = limit; } } else if (WorkInAir && !controller.Grounded) { var oldVelocity = controller.Velocity; var targetAngle = DMath.Angle(TargetVelocity); var targetMagnitude = TargetVelocity.magnitude; var normalized = (TargetVelocity - oldVelocity).normalized; var result = normalized * Power * Time.fixedDeltaTime; if (AccountForGravity) { result += Vector2.up * controller.AirGravity * Time.fixedDeltaTime; } if (Mathf.Abs(DMath.ShortestArc(DMath.Angle(result), targetAngle)) > DMath.HalfPi) { controller.Velocity = TargetVelocity; return; } controller.Velocity += result; if (oldVelocity.magnitude < targetMagnitude && controller.Velocity.magnitude > targetMagnitude) { controller.Velocity = TargetVelocity; } } }