public override void ReactToPassenger(Vector3 velocity, PassengerMovement passenger) { bool squisch = false; Vector3 hitSourcePosition = transform.position; if ((!passenger.standingOnPlatform && velocity.x < 0 && passengerDictionary[passenger.transform].IsLeft()) || (!passenger.standingOnPlatform && velocity.x > 0 && passengerDictionary[passenger.transform].IsRight())) { // sideways squisch! squisch = true; hitSourcePosition = new Vector3(transform.position.x, passenger.transform.position.y, transform.position.z); } if ((passenger.standingOnPlatform && velocity.y > 0 && passengerDictionary[passenger.transform].IsBelow() && passengerDictionary[passenger.transform].IsAbove()) || (!passenger.standingOnPlatform && passengerDictionary[passenger.transform].IsBelow() && velocity.y < 0)) { // vertical squisch! squisch = true; hitSourcePosition = new Vector3(passenger.transform.position.x, transform.position.y, transform.position.z); } if (squisch) { HurtBox hurtBox = passenger.transform.GetComponent <HurtBox>(); if (!hurtBox) { hurtBox = passenger.transform.GetComponentInChildren <HurtBox>(); } if (hurtBox) { hurtBox.ReceiveHit(true, 100, HitBox.DAMAGE_TYPE.SQUISH, hitSourcePosition); // create squish effect on platform Vector3 positionEffectPlatform = BoundUtils.GetPositionOnBounds(velocity, passenger.transform.position, myCollider.bounds, 26); InstantiateEffect(squishEffect, positionEffectPlatform, BoundUtils.GetEffectRotation(velocity, true), transform); // create squish effect on ground BoxCollider2D collider2D = passenger.transform.GetComponent <BoxCollider2D>(); if (collider2D) { Vector3 positionEffectGround = BoundUtils.GetPositionOnBounds(velocity, positionEffectPlatform, collider2D.bounds); InstantiateEffect(squishEffect, positionEffectGround, BoundUtils.GetEffectRotation(velocity, false)); } } } }
/// <summary> /// Funzione che muove i passeggeri /// </summary> /// <param name="beforeMovePlatform"></param> public void MovePassengers(bool beforeMovePlatform) { for (int i = 0; i < passengerMovement.Count; i++) { PassengerMovement passenger = passengerMovement[i]; if (passenger.moveBeforePassenger == beforeMovePlatform) { PlayerCollisionController collisionCtrl = passenger.transform.GetComponentInParent <PlayerCollisionController>(); if (collisionCtrl != null) { if (!collisionCtrl.GetCollisionInfo().StickyCollision()) { collisionCtrl.transform.Translate(collisionCtrl.CheckMovementCollisions(passenger.velocity, passenger.standingOnPlatform)); } } else { passenger.transform.Translate(passenger.velocity); } } } }
public virtual void ReactToPassenger(Vector3 velocity, PassengerMovement passenger) { // can be overriden from other classes to reacht to passenger move }
void MovePassenger(PassengerMovement passengerMovement) { passengerMovement.passenger.Move(Vector2.up * passengerMovement.pushY); }
void CalculatePassengerMovement(Vector3 velocity) { Dictionary <Transform, IPlatformMoveBlocker> movedPassengers = new Dictionary <Transform, IPlatformMoveBlocker> (); passengerMovement = new List <PassengerMovement> (); System.Func <Vector2, RaycastHit2D, PassengerMovement> GetMovement = (dir, hit) => { IPlatformMoveBlocker blocker = movedPassengers[hit.transform]; // add 90 to convert from Vector2.down being default direction to Vector2.right Vector2 gravityAngle = Utils.AngleToVector(blocker.GravityAngle - 90); Vector2 normalizedVelocity = velocity.normalized; var rotatedVelocity = velocity.Rotate(-blocker.GravityAngle); float dot = Vector2.Dot(gravityAngle, normalizedVelocity); bool movingWithDirection = rotatedVelocity.y > 0; // we need to check the direction cast in comparison to gravity to determine // players position relative to the platform (i.e. player on top) float positionDot = Vector2.Dot(gravityAngle, dir); bool onTop = positionDot < -0.9f; float velocityDot = Vector2.Dot(normalizedVelocity, dir); if (dot > 0.5f) { // gravity and platform moving in same direction if (onTop) { // passenger is on top of the platform and should be moved with it float pushX = velocity.x; float pushY = velocity.y; return(new PassengerMovement(hit.transform, new Vector3(pushX, pushY), true, false, false)); } else { // passenger is below the platform and will be pushed float pushX = 0f; float pushY = rotatedVelocity.y - (hit.distance - skinWidth) * Mathf.Sign(rotatedVelocity.y); return(new PassengerMovement(hit.transform, new Vector3(pushX, pushY), false, true, true)); } } else if (dot < -0.5f) { // gravity and platform moving in opposite directions float pushX = movingWithDirection ? rotatedVelocity.x : 0; float pushY = rotatedVelocity.y - (hit.distance - skinWidth) * Mathf.Sign(rotatedVelocity.y); return(new PassengerMovement(hit.transform, new Vector3(pushX, pushY), onTop, true, false)); } else if (positionDot < 0.9f) { // platform is moving side-to-side relative to gravity // only disallow movement is player is below platform float pushX = rotatedVelocity.x - (hit.distance - skinWidth) * Mathf.Sign(rotatedVelocity.x); float pushY = 0f; return(new PassengerMovement(hit.transform, new Vector3(pushX, pushY), onTop, false, false)); } return(null); }; System.Action <Vector2, Vector2, float> CastForPoint = (pt, dir, dist) => { //Debug.DrawRay(pt, dir*dist, new Color(dir.y*0.5f+0.5f, dir.x*0.5f+0.5f, 0), 0.1f); RaycastHit2D hit = Physics2D.Raycast(pt, dir, dist, passengerMask); if (hit) { if (!movedPassengers.ContainsKey(hit.transform)) { movedPassengers.Add(hit.transform, hit.transform.GetComponent <IPlatformMoveBlocker>()); PassengerMovement m = GetMovement(dir, hit); if (m != null) { passengerMovement.Add(m); } } else { PassengerMovement m = GetMovement(dir, hit); int index = passengerMovement.FindIndex(pm => pm.transform == hit.transform); if (m != null && index >= 0 && m.velocity.sqrMagnitude > passengerMovement[index].velocity.sqrMagnitude) { passengerMovement[index] = m; } } } }; var pts = GeneratePoints(); float topDistance = skinWidth * 2f; float bottomDistance = skinWidth * 2f; Vector2 rotatedPlatformVelocity = velocity.Rotate(-transform.eulerAngles.z); if (rotatedPlatformVelocity.y > 0) { topDistance = Mathf.Max(topDistance, Mathf.Abs(rotatedPlatformVelocity.y) + skinWidth); } else { bottomDistance = Mathf.Max(bottomDistance, Mathf.Abs(rotatedPlatformVelocity.y) + skinWidth); } Vector2 up = Vector2.up.Rotate(transform.eulerAngles.z); Vector2 right = Vector2.right.Rotate(transform.eulerAngles.z); foreach (var pt in pts.Top) { CastForPoint(pt, up, topDistance); } foreach (var pt in pts.Bottom) { CastForPoint(pt, -up, bottomDistance); } float leftDistance = skinWidth * 2f; float rightDistance = skinWidth * 2f; if (rotatedPlatformVelocity.x > 0) { rightDistance = Mathf.Max(rightDistance, Mathf.Abs(rotatedPlatformVelocity.x) + skinWidth); } else { leftDistance = Mathf.Max(leftDistance, Mathf.Abs(rotatedPlatformVelocity.x) + skinWidth); } foreach (var pt in pts.Right) { CastForPoint(pt, right, rightDistance); } foreach (var pt in pts.Left) { CastForPoint(pt, -right, leftDistance); } }
private void AddPassengerMovement(Transform transform, Vector3 velocity, bool standingOnPlatform, bool moveBeforePlatform) { PassengerMovement entry = new PassengerMovement(transform, velocity, standingOnPlatform, moveBeforePlatform); passengerMovement.Add(entry); }