/// <summary> /// Managed update called by UpdateManager /// /// Call all actions ask them who 'WantsToUpdate'\n /// The highest priority action what want GainControl and PerformAction\n /// Given action give a list of things to do after using GetPostUpdateActions\n /// When all is done, fire events /// </summary> public virtual void PlatformerUpdate(float delta) { colBounds = bounds; // before anything try to find if there is a ladder below // it's neccesary for ActionLadder&ActionCrounch // this is not the right place... but where?! to be unique RaycastHit2D hit = FeetRay( skinWidth * 2, 1 << Configuration.instance.laddersMask ); if (hit) { ladderBottom = hit.collider.gameObject.GetComponent <Ladder>(); Assert.IsNotNull(ladderBottom, "GameObject at Ladders layer without Ladder MonoBehaviour at " + hit.collider.gameObject.GetFullName()); } else { ladderBottom = null; } // frozen -= delta; int prio = 0; int tmp; CharacterAction action = null; if (frozen < 0) { foreach (var i in actions) { tmp = i.WantsToUpdate(delta); if (tmp < 0) { i.PerformAction(Time.fixedDeltaTime); } else if (prio < tmp) { prio = tmp; action = i; } } } // reset / defaults disableWorldCollisions = false; PostUpdateActions a = PostUpdateActions.WORLD_COLLISIONS | PostUpdateActions.APPLY_GRAVITY; if (action != null) { if (lastAction != action) { action.GainControl(delta); } action.PerformAction(Time.fixedDeltaTime); a = action.GetPostUpdateActions(); } if (BitOn((int)a, (int)PostUpdateActions.APPLY_GRAVITY)) { // TODO REVIEW x/y gravity... velocity.y += gravity.y * delta; } if (!BitOn((int)a, (int)PostUpdateActions.WORLD_COLLISIONS)) { disableWorldCollisions = true; } if (Mathf.Abs(velocity.x) < minVelocity) { velocity.x = 0.0f; } if (Mathf.Abs(velocity.y) < minVelocity) { velocity.y = 0.0f; } if (onBeforeMove != null) { onBeforeMove(this, delta); } // check velocity don't exceed terminalVelocity // Limit X //velocity.x = Mathf.Min(velocity.x, terminalVelocity.x); //velocity.x = Mathf.Max(velocity.x, -terminalVelocity.x); // Limit Y but only freefall velocity.y = Mathf.Max(velocity.y, -terminalVelocity.y); movedLastFrame = Move((velocity + worldVelocity) * delta, delta); if (onAfterMove != null) { onAfterMove(this, delta); } // this is meant to fix jump and falling hit something unexpected if (collisions.above || collisions.below) { velocity.y = 0; } if (collisions.below) { fallingCD.Reset(); groundCD.Reset(); EnterStateGraceful(States.OnGround); } else { // give some margin if (groundCD.Ready()) { ExitStateGraceful(States.OnGround); } // falling but not wallsliding if (velocity.y < 0 && !IsOnState(States.WallSliding) && !IsOnState(States.Liquid) && !IsOnState(States.Rope)) { if (fallingCD.Ready()) { EnterStateGraceful(States.Falling); } } } if (lastAction != null && lastAction != action) { lastAction.LoseControl(delta); } lastAction = action; }
/// <summary> /// Managed update called by UpdateManager /// Transform Input into platformer magic :) /// </summary> public virtual void PlatformerUpdate(float delta) { frozen -= delta; int prio = 0; int tmp; CharacterAction action = null; if (frozen < 0) { foreach (var i in actions) { tmp = i.WantsToUpdate(delta); if (tmp < 0) { i.PerformAction(Time.fixedDeltaTime); } else if (prio < tmp) { prio = tmp; action = i; } } } // reset / defaults pc2d.disableWorldCollisions = false; PostUpdateActions a = PostUpdateActions.WORLD_COLLISIONS | PostUpdateActions.APPLY_GRAVITY; if (action != null) { if (lastAction != action) { action.GainControl(delta); } action.PerformAction(Time.fixedDeltaTime); a = action.GetPostUpdateActions(); } if (Utils.biton((int)a, (int)PostUpdateActions.APPLY_GRAVITY)) { // TODO REVIEW x/y gravity... velocity.y += pc2d.gravity.y * delta; } if (!Utils.biton((int)a, (int)PostUpdateActions.WORLD_COLLISIONS)) { pc2d.disableWorldCollisions = true; } if (Mathf.Abs(velocity.x) < minVelocity) { velocity.x = 0.0f; } if (Mathf.Abs(velocity.y) < minVelocity) { velocity.y = 0.0f; } if (onBeforeMove != null) { onBeforeMove(this, delta); } pc2d.Move((velocity + worldVelocity) * delta, delta); if (onAfterMove != null) { onAfterMove(this, delta); } // this is meant to fix jump and falling hit something unexpected if (pc2d.collisions.above || pc2d.collisions.below) { velocity.y = 0; } if (pc2d.collisions.below) { fallingCD.Reset(); groundCD.Reset(); SolfEnterState(States.OnGround); } else { groundCD.Increment(); // give some margin if (groundCD.Ready()) { SolfExitState(States.OnGround); } // falling but not wallsliding if (velocity.y < 0 && !IsOnState(States.WallSliding) && !IsOnState(States.Liquid) && !IsOnState(States.Rope)) { fallingCD.Increment(); if (fallingCD.Ready()) { SolfEnterState(States.Falling); } } } if (lastAction != null && lastAction != action) { lastAction.LoseControl(delta); } lastAction = action; }
/// <summary> /// Managed update called by UpdateManager /// Transform Input into platformer magic :) /// </summary> public virtual void PlatformerUpdate(float delta) { // before anything try to find if there is a ladder below // it's neccesary for ActionLadder&ActionCrounch RaycastHit2D hit = pc2d.DoFeetRay( pc2d.skinWidth * 2, Configuration.instance.laddersMask ); if (hit) { ladderBottom = hit.collider.gameObject.GetComponent <Ladder>(); if (ladderBottom == null) { Debug.LogWarning("Object with ladder mask but no Ladder Behaviour found", hit.collider.gameObject); } } else { ladderBottom = null; } // frozen -= delta; int prio = 0; int tmp; CharacterAction action = null; if (frozen < 0) { foreach (var i in actions) { tmp = i.WantsToUpdate(delta); if (tmp < 0) { i.PerformAction(Time.fixedDeltaTime); } else if (prio < tmp) { prio = tmp; action = i; } } } // reset / defaults pc2d.disableWorldCollisions = false; PostUpdateActions a = PostUpdateActions.WORLD_COLLISIONS | PostUpdateActions.APPLY_GRAVITY; if (action != null) { if (lastAction != action) { action.GainControl(delta); } action.PerformAction(Time.fixedDeltaTime); a = action.GetPostUpdateActions(); } if (Utils.biton((int)a, (int)PostUpdateActions.APPLY_GRAVITY)) { // TODO REVIEW x/y gravity... velocity.y += pc2d.gravity.y * delta; } if (!Utils.biton((int)a, (int)PostUpdateActions.WORLD_COLLISIONS)) { pc2d.disableWorldCollisions = true; } if (Mathf.Abs(velocity.x) < minVelocity) { velocity.x = 0.0f; } if (Mathf.Abs(velocity.y) < minVelocity) { velocity.y = 0.0f; } if (onBeforeMove != null) { onBeforeMove(this, delta); } movedLastFrame = pc2d.Move((velocity + worldVelocity) * delta, delta); if (onAfterMove != null) { onAfterMove(this, delta); } // this is meant to fix jump and falling hit something unexpected if (pc2d.collisions.above || pc2d.collisions.below) { velocity.y = 0; } if (pc2d.collisions.below) { fallingCD.Reset(); groundCD.Reset(); EnterStateGraceful(States.OnGround); } else { groundCD.Increment(); // give some margin if (groundCD.Ready()) { ExitStateGraceful(States.OnGround); } // falling but not wallsliding if (velocity.y < 0 && !IsOnState(States.WallSliding) && !IsOnState(States.Liquid) && !IsOnState(States.Rope)) { fallingCD.Increment(); if (fallingCD.Ready()) { EnterStateGraceful(States.Falling); } } } if (lastAction != null && lastAction != action) { lastAction.LoseControl(delta); } lastAction = action; }