static public Silly ( string format ) : void | ||
format | string | |
Результат | void |
/// <summary> /// Character enter: set track property and call onEnter /// </summary> override public void CharacterEnter(Character character) { Debug.LogFormat("CharacterEnter: {0}", character); // only the first track is enabled if (character.track == null) { if (!characterState.ValidStates(character)) { return; } Log.Silly("(Track) Enter " + character.gameObject.GetFullName()); // delegate when to move to character class // this prevent fights between tile modifiers character.onBeforeMove += Accelerate; character.EnterArea(Areas.Track); character.track = new TrackData(this); if (onEnter != null) { onEnter(character); } } }
void HorizontalCollisions(ref RaycastHit2D ray, ref Vector3 velocity, int dir, int idx) { if (ray && ray.distance != 0) { // ignore oneWayPlatformsUp/Down, both aren't walls if (Configuration.IsOneWayPlatformUp(ray.collider) || Configuration.IsOneWayPlatformDown(ray.collider)) { return; } if (( // ignore left wall while moving left Configuration.IsOneWayWallLeft(ray.collider) && velocity.x < 0 ) || ( // ignore right wall while moving right Configuration.IsOneWayWallRight(ray.collider) && velocity.x > 0 )) { return; } collisions.PushContact(ray, dir == -1 ? Directions.Left : Directions.Right); float slopeAngle = Vector2.Angle(ray.normal, Vector2.up); if (slopeAngle > maxClimbAngle) { if (dir == -1) { collisions.left = true; if (Mathf.Approximately(slopeAngle, 90)) { collisions.leftIsWall = true; } } if (dir == 1) { collisions.right = true; if (Mathf.Approximately(slopeAngle, 90)) { collisions.rightIsWall = true; } } // same direction // TODO REVIEW check variable-slope. while on ground i the slope push // the character strange things happens because of this if (velocity.x == 0 || dir == Mathf.Sign(velocity.x)) { velocity.x = dir == 1 ? Mathf.Min(velocity.x, (ray.distance - minDistanceToEnv) * dir) : Mathf.Max(velocity.x, (ray.distance - minDistanceToEnv) * dir); Log.Silly("(PlatformerCollider2D) HorizontalCollisions new velocity {0}", velocity.ToString("F4")); } } } }
/// <summary> /// EnterState and start centering /// </summary> public override void GainControl(float delta) { base.GainControl(delta); character.EnterState(States.Pulling); Log.level = LogLevel.Silly; Log.Silly("(Push) {0} Start pulling", gameObject.name); }
/// <summary> /// EnterState and start centering /// </summary> public override void LoseControl(float delta) { base.LoseControl(delta); character.ExitState(States.Pulling); Log.Silly("(Push) {0} Stop pulling", gameObject.name); Log.level = LogLevel.Info; }
/// <summary> /// I'm a DealDamage, o is RecieveDamage, then Deal Damage to it's owner! /// </summary> public void OnTriggerEnter2D(Collider2D o) { if (type == HitBoxType.DealDamage) { // source disabled? if (IsDisabled()) { Log.Debug("{0} cannot deal damage it's disabled", this.gameObject.GetFullName()); return; } //Debug.LogFormat("me {0} of {1} collide with {2}@{3}", name, owner, o.gameObject, o.gameObject.layer); var hitbox = o.gameObject.GetComponent <HitBox> (); Log.Silly("o is a HitBox? {0} at {0}", hitbox, o.gameObject.GetFullName()); if (hitbox != null && hitbox.type == HitBoxType.RecieveDamage) { Log.Debug("Collide {0} with {1}", gameObject.GetFullName(), hitbox.gameObject.GetFullName()); // target disabled? if (hitbox.IsDisabled()) { Log.Debug("{0} cannot recieve damage it's disabled", o.gameObject.GetFullName()); return; } // can I deal damage to this HitBox? // check layer if (hitbox.GetCollisionMask().Contains(gameObject.layer)) { Log.Silly("compatible layers"); // check we not the same, or i can damage to myself at lest if (dealDamageToSelf || (!dealDamageToSelf && hitbox.owner != damage.causer)) { Log.Debug("Damage to {0} with {1}", hitbox.owner.gameObject.GetFullName(), damage); hitbox.owner.Damage(damage); } } else { Log.Silly("incompatible layers {0} vs {1}", string.Join(",", hitbox.GetCollisionMask().MaskToNames()), LayerMask.LayerToName(gameObject.layer) ); } } } }
/// <summary> /// Modify velocity to smooth descend current slope /// </summary> /// <param name="velocity">Amount to be moved</param> void DescendSlope(ref Vector3 velocity) { if (collisions.descendingSlope && (collisions.slopeAngle <= maxDescendAngle || ignoreDescendAngle) ) { Vector3 slopeDir = GetDownSlopeDir(); //Debug.DrawRay(raycastOrigins.bottomCenter, slopeDir * 10, Color.blue); //Debug.DrawRay(raycastOrigins.bottomCenter, collisions.slopeNormal * 10, Color.blue); velocity.x = velocity.x * Math.Abs(slopeDir.x); //velocity.y = (Mathf.Abs(velocity.x) + collisions.slopeDistance) * slopeDir.y; velocity.y = Mathf.Abs(velocity.x) * slopeDir.y; collisions.below = true; Log.Silly("(PlatformerCollider2D) DescendSlope new velocity {0}", velocity.ToString("F4")); } }
void ClimbSlope(ref Vector3 velocity) { if (collisions.climbingSlope) { if (collisions.slopeAngle > maxClimbAngle) { velocity.x = 0; return; } Vector3 slopeDir = GetDownSlopeDir(); //Debug.DrawRay(raycastOrigins.bottomCenter, slopeDir * 10, Color.blue); velocity.x *= Mathf.Abs(slopeDir.x); velocity.y = Mathf.Abs(velocity.x * slopeDir.y); collisions.below = true; Log.Silly("(PlatformerCollider2D) ClimbSlope new velocity {0}", velocity.ToString("F4")); } }
/// <summary> /// Get the lowest box (the one Character Pull/Push) /// </summary> public Box GetLowestBox(Directions dir) { PlatformerCollider2D.Contacts[] contacts = collisions.contacts; // sarch the lowest box and push it float minY = Mathf.Infinity; int index = -1; Log.Silly("(Push) PushBox.count {0}", collisions.contactsCount); for (int i = 0; i < collisions.contactsCount; ++i) { if (contacts[i].dir != dir) { continue; } Box b = contacts[i].hit.collider.gameObject.GetComponent <Box>(); if (b != null) { if (!Configuration.IsBox(b.boxCharacter.gameObject)) { Debug.LogWarning("Found a Character that should be a box", b.boxCharacter.gameObject); continue; } float y = b.transform.position.y; Log.Silly("(Push) Found a box at index {0} {1} {2} {3}", i, b, minY, y); if (y < minY) { minY = y; index = i; } } } Log.Silly("(Push) will push {0} {1}", index, velocity.ToString("F4")); if (index != -1) { return(contacts[index].hit.collider.gameObject.GetComponent <Box>()); } return(null); }
public void PushBox(Vector3 velocity, ref RaycastHit2D[] hits, int count, float delta) { if (forbidVerticalPush) { velocity.y = 0.0f; } // sarch the lowest box and push it float minY = Mathf.Infinity; int index = -1; Log.Silly("(Push) PushBox.count {0}", count); for (int i = 0; i < count; ++i) { Box b = hits[i].collider.gameObject.GetComponent <Box>(); if (b != null) { if (!Configuration.IsBox(b.boxCharacter.gameObject)) { Debug.LogWarning("Found a Character that should be a box", b.boxCharacter.gameObject); return; } float y = b.transform.position.y; Log.Silly("(Push) Found a box at index {0} {1} {2} {3}", i, b, minY, y); if (y < minY) { minY = y; index = i; } } } Log.Silly("(Push) will push {0} {1}", index, velocity.ToString("F4")); if (index != -1) { Box b = hits[index].collider.gameObject.GetComponent <Box>(); b.boxCharacter.pc2d.Move(velocity, delta); b.boxMovingPlatform.PlatformerUpdate(delta); } }
/// <summary> /// Disable track /// </summary> override public void CharacterExit(Character character) { // same as above, only diable if we leave the section we are grabbing if (character.track != null && character.track.track == this) { Log.Silly("(Track) Leave " + character.gameObject.GetFullName()); character.onBeforeMove -= Accelerate; character.ExitArea(Areas.Track); // when character exit, we must continue to apply the velocity // but this time not as world, as 'Character' velocity to keep // a smooth exit // this will be ok unless you exceeed terminalVelocity character.worldVelocity -= character.track.appliedAcceleration; character.velocity += character.track.appliedAcceleration; character.track = null; if (onExit != null) { onExit(character); } } }
/// <summary> /// Enable track /// </summary> override public void CharacterEnter(Character character) { Debug.LogFormat("CharacterEnter: {0}", character); // only the first one enable the track if (character.track == null) { if (!characterState.ValidStates(character)) { return; } Log.Silly("(Track) Enter " + character.gameObject.GetFullName()); character.onBeforeMove += Accelerate; character.EnterArea(Areas.Track); character.track = new TrackData(this); //character.worldVelocity += velocity; if (onEnter != null) { onEnter(character); } } }
/// <summary> /// Callback for ForeachHeadRay/ForeachFeetRay /// </summary> /// <param name="ray">result of Raycast vertically</param> /// <param name="velocity">Amount to be moved</param> /// <param name="dir">Direction</param> /// <param name="idx">ray index</param> void VerticalCollisions(ref RaycastHit2D ray, ref Vector3 velocity, int dir, int idx) { // hit anything? if (!ray || ray.distance == 0) { return; } // when climb/descend a slope we want continuous collisions // to do that we just need to separate a specific corner // if more test are perform it end up being unstable if (collisions.climbingSlope) { if (velocity.x > 0 && idx != horizontalRayCount - 1) { return; } if (velocity.x < 0 && idx != 0) { return; } } if (collisions.descendingSlope) { if (velocity.x > 0 && idx != 0) { return; } if (velocity.x < 0 && idx != horizontalRayCount - 1) { return; } } // fallingThroughPlatform ? if ( Configuration.IsOneWayPlatformUp(ray.collider) && collisions.fallingThroughPlatform ) { return; } // left/right wall are ignored for vertical collisions if (Configuration.IsOneWayWallLeft(ray.collider) || Configuration.IsOneWayWallRight(ray.collider)) { return; } if (( // ignore up platforms while moving up Configuration.IsOneWayPlatformUp(ray.collider) && velocity.y > 0 ) || ( // ignore down platforms while moving down Configuration.IsOneWayPlatformDown(ray.collider) && velocity.y < 0 )) { return; } collisions.PushContact(ray, dir == 1 ? Directions.Top : Directions.Bottom); if (!leavingGround) { // Separate but only if we are not jumping velocity.y = (ray.distance - minDistanceToEnv) * dir; collisions.below = IsDirectionBelow(dir); } else if (ray.distance < minDistanceToEnv * 0.5f) { // we just want to override if we are not separating enough from // ground also, do not set collision below until that moment or // current jump will be stopped float wanted = (ray.distance - minDistanceToEnv) * dir; if (velocity.y < wanted) { velocity.y = wanted; collisions.below = IsDirectionBelow(dir); Log.Silly("(PlatformerCollider2D) VerticalCollisions new velocity {0}", velocity.ToString("F4")); } } collisions.above = IsDirectionAbove(dir); }
/// <summary> /// Attempt to move the character to current position + velocity. /// /// Any colliders in our way will cause velocity to be modified /// ex: wall -> stop. slope -> modifiy velocity.\n /// NOTE collisions.velocity has the real velocity applied /// </summary> /// <param name="velocity">Amount to be moved (velocity * delta)</param> /// <param name="delta">Time since last update</param> /// <returns>Real velocity after collisions</returns> public Vector3 Move(Vector3 velocity, float delta) { gravitySwapped = gravity.y > 0; Log.Silly("(PlatformerCollider2D) Move({0}, {1}, {2})", gameObject.GetFullName(), velocity.ToString("F4"), delta); // swap layers, this makes possible to collide with something inside // my own layer like boxes previousLayer = gameObject.layer; gameObject.layer = 2; // Ignore Raycast UpdateRaycastOrigins(); if (debug) { var b = bounds; b.Draw(transform, new Color(1, 1, 1, 0.25f)); b.center += velocity; b.Draw(transform, new Color(0, 0, 1, 0.5f)); b.Expand(minDistanceToEnv * 2); //b.center -= new Vector3(minDistanceToEnv, minDistanceToEnv, 0); b.Draw(transform, new Color(0, 0, 1, 0.75f)); } // set previous collisions and reset current one pCollisions = collisions.Clone(); collisions.Reset(); // Climb or descend a slope if in range // NOTE slopes are not supported when gravity is positive atm. // https://github.com/llafuente/unity-platformer/issues/49 if (enableSlopes) { UpdateCurrentSlope(velocity); // TODO PERF add: pCcollisions.below, so wont be testing while falling // if (collisions.slopeAngle != 0 && pCollisions.below) { if (collisions.slopeAngle != 0) { //Debug.Log("velocity before" + velocity.ToString("F4")); ClimbSlope(ref velocity); DescendSlope(ref velocity); //Debug.Log("velocity after" + velocity.ToString("F4")); } } // be sure we stay outside others colliders if (!disableWorldCollisions) { ForeachLeftRay(skinWidth, ref velocity, HorizontalCollisions); ForeachRightRay(skinWidth, ref velocity, HorizontalCollisions); if (IsMovingAgainstGravity(ref velocity)) { ForeachFeetRay(skinWidth, ref velocity, VerticalCollisions); ForeachHeadRay(skinWidth, ref velocity, VerticalCollisions); } else { ForeachFeetRay(skinWidth, ref velocity, VerticalCollisions); } } if (Math.Abs(velocity.x) < minTranslation) { velocity.x = 0; } if (Math.Abs(velocity.y) < minTranslation) { velocity.y = 0; } if (useRigidbody2D) { //rigidBody2D.AddForce((Vector2)velocity, ForceMode2D.Impulse); rigidBody2D.velocity = velocity / delta; } else { transform.Translate(velocity); } collisions.velocity = velocity; ConsolidateCollisions(); gameObject.layer = previousLayer; if (debug) { var b = bounds; b.center += velocity; b.Draw(transform, new Color(0, 1, 1, 0.25f)); } Log.Silly("(PlatformerCollider2D) Moved({0}, {1}, {2})", gameObject.GetFullName(), velocity.ToString("F4"), delta); return(velocity); }
/// <summary> /// Attempt to move the character to position + velocity. /// Any colliders in the way will cause velocity to be modified /// NOTE collisions.velocity has the real velocity applied /// </summary> public Vector3 Move(Vector3 velocity, float delta) { Log.Silly("(PlatformerCollider2D) Move({0} {1}, {2})", gameObject.name, velocity.ToString("F4"), delta); // swap layers, this makes possible to collide with something inside my own layer // like boxes previousLayer = gameObject.layer; gameObject.layer = 2; // Ignore Raycast UpdateRaycastOrigins(); var b = bounds; b.Draw(transform, new Color(1, 1, 1, 0.25f)); b.center += velocity; b.Draw(transform, new Color(0, 0, 1, 0.5f)); b.Expand(minDistanceToEnv * 2); //b.center -= new Vector3(minDistanceToEnv, minDistanceToEnv, 0); b.Draw(transform, new Color(0, 0, 1, 0.75f)); // set previous collisions and reset current one pCollisions = collisions.Clone(); collisions.Reset(); // Climb or descend a slope if in range if (enableSlopes) { GetCurrentSlope(velocity); // TODO PERF add: pCcollisions.below, so wont be testing while falling // if (collisions.slopeAngle != 0 && pCollisions.below) { if (collisions.slopeAngle != 0) { //Debug.Log("velocity before" + velocity.ToString("F4")); ClimbSlope(ref velocity); DescendSlope(ref velocity); //Debug.Log("velocity after" + velocity.ToString("F4")); } } // be sure we stay outside others colliders if (!disableWorldCollisions) { ForeachLeftRay(skinWidth, ref velocity, HorizontalCollisions); ForeachRightRay(skinWidth, ref velocity, HorizontalCollisions); if (velocity.y > 0) { ForeachFeetRay(skinWidth, ref velocity, VerticalCollisions); ForeachHeadRay(skinWidth, ref velocity, VerticalCollisions); } else { ForeachFeetRay(skinWidth, ref velocity, VerticalCollisions); } } if (Math.Abs(velocity.x) < minTranslation) { velocity.x = 0; } if (Math.Abs(velocity.y) < minTranslation) { velocity.y = 0; } if (useRigidbody2D) { rigidBody2D.velocity = velocity / delta; } else { transform.Translate(velocity); } collisions.velocity = velocity; ConsolidateCollisions(); gameObject.layer = previousLayer; b = bounds; b.center += velocity; b.Draw(transform, new Color(0, 1, 1, 0.25f)); Log.Silly("(PlatformerCollider2D) Moved({0}m {1}, {2})", gameObject.name, velocity.ToString("F4"), delta); return(velocity); }