/// <summary> /// EnterState and start centering /// </summary> public override void GainControl(float delta) { base.GainControl(delta); character.EnterState(States.Ladder); centering = moveToCenter; dismount.Reset(); }
public override void PerformAction(float delta) { Vector3 ori = character.transform.position; Vector3 target = character.grab.GetCenter() - grabbingOffset; // once we center, stop moving! if (!centering) { character.velocity = Vector3.zero; } // close enough to our target position ? if (centering && Vector3.Distance(ori, target) < 0.1f) { character.velocity = target - ori; centering = false; } // close the gap a little more if (centering) { // centering phase Vector3.SmoothDamp( ori, target, ref character.velocity, towardsTime, towardsSpeed, //Mathf.Infinity, delta); } character.SetFacing(input.GetAxisRawX()); // check for dismount conditions if (dismountJumping && input.IsActionHeld(actionJump.action)) { canGrab.Reset(); character.ExitState(States.Grabbing); actionJump.Jump(new JumpConstant(character, jumpOff.Clone((int)character.faceDir) )); } else if (dismountPressingDown && input.GetAxisRawY() < 0) { // TODO Dismount down delay ? canGrab.Reset(); character.ExitState(States.Grabbing); } }
public override int WantsToUpdate(float delta) { if (!pc2d.collisions.below) { return(0); } float x = input.GetAxisRawX(); if (x > 0) { if (faceDir != 1) { pushingCD.Reset(); } faceDir = 1; if (character.IsBox(Directions.Right) && pushingCD.IncReady()) { return(priority); } return(0); } if (x < 0) { if (faceDir != -1) { pushingCD.Reset(); } faceDir = -1; if (character.IsBox(Directions.Left) && pushingCD.IncReady()) { return(priority); } return(0); } pushingCD.Reset(); return(0); }
public override int WantsToUpdate(float delta) { float x = input.GetAxisRawX(); if (x > 0) { if (faceDir != 1) { pushingCD.Reset(); } faceDir = 1; if (IsBoxRight() && pushingCD.IncReady()) { return(priority); } return(0); } if (x < 0) { if (faceDir != -1) { pushingCD.Reset(); } faceDir = -1; if (IsBoxLeft() && pushingCD.IncReady()) { return(priority); } return(0); } pushingCD.Reset(); return(0); }
/// <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 /// /// 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> /// Turns a character invulnerable, but still can be killed using Kill /// /// NOTE use float.MaxValue for unlimited time /// </summary> public void SetInvulnerable(float time) { invulnerability.Set(time); invulnerability.Reset(); }
public override void PerformAction(float delta) { Vector3 ori = character.transform.position; Vector3 ropePosition = character.rope.sections[character.ropeIndex].GetComponent <RopeSection>().GetPositionInSection(positionOfSection); Vector3 target = ropePosition + character.rope.faceDir * grabbingOffset; // close enough to our target position ? if (centering && Vector3.Distance(ori, target) < 0.1f) { character.velocity = target - ori; centering = false; } else if (centering) { // centering phase: close the gap a little more Vector3.SmoothDamp( ori, target, ref character.velocity, towardsTime, towardsSpeed, //Mathf.Infinity, delta); } else { // once we center, follow the rope movement character.velocity = (target - ori) / delta; } // climb / descend the rope float offsetSeed = character.rope.SpeedToSectionOffset(climbSpeed) * delta; float y = input.GetAxisRawY(); if (y > 0) { positionOfSection = Mathf.Clamp01(positionOfSection + offsetSeed); if (positionOfSection == 1) { // go to up if possible if (character.ropeIndex != 0) { --character.ropeIndex; positionOfSection = 0; } } } else if (y < 0) { positionOfSection = Mathf.Clamp01(positionOfSection - offsetSeed); if (positionOfSection == 0) { // go to up if possible if (character.ropeIndex != character.rope.segments - 1) { ++character.ropeIndex; positionOfSection = 1; } else { // TODO maybe we can dismount here :D } } } // check for dismount conditions if (dismountJumping && input.IsActionHeld(actionJump.action)) { canGrab.Reset(); character.ExitState(States.Rope); actionJump.Jump(new JumpConstant(character, jumpOff.Clone((int)character.faceDir) )); } }
/// <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; }