public void moveAttachedBody(RopeGrabComponent ropeGrabComponent, Body bodyToMove, float climbSpeed) { float newDistance = ropeGrabComponent.distance + (ropeGrabComponent.reverseClimbDirection ? -climbSpeed : climbSpeed); RopeNode newNode = ropeGrabComponent.ropeNode.getByIndex((int)Math.Floor(newDistance)); if (newNode != null) { if (ropeGrabComponent.reverseClimbDirection) { if (climbSpeed > 0 && newNode != ropeGrabComponent.ropeNode && ropeGrabComponent.ropeNode.joint == null) { return; } else if (climbSpeed < 0 && newNode != ropeGrabComponent.ropeNode && newNode.joint == null) { return; } } else { if (climbSpeed > 0 && newNode != ropeGrabComponent.ropeNode && newNode.joint == null) { return; } else if (climbSpeed < 0 && newNode != ropeGrabComponent.ropeNode && ropeGrabComponent.ropeNode.joint == null) { return; } } ropeGrabComponent.distance = newDistance; releaseRope(ropeGrabComponent, bodyToMove); grabRope(ropeGrabComponent, bodyToMove); } }
public void releaseRope(RopeGrabComponent ropeGrabComponent, Body bodyToDetach) { RevoluteJoint joint = ropeGrabComponent.joints[bodyToDetach]; bodyToDetach.World.RemoveJoint(joint); ropeGrabComponent.joints.Remove(bodyToDetach); }
public void detachAll(RopeGrabComponent ropeGrabComponent) { foreach (RevoluteJoint joint in ropeGrabComponent.joints.Values) { joint.BodyA.World.RemoveJoint(joint); } ropeGrabComponent.joints.Clear(); }
public void killRope(string levelUid, int entityId) { RopeComponent ropeComponent = (RopeComponent)_entityManager.getComponent(levelUid, entityId, ComponentType.Rope); List <int> ropeGrabEntities = _entityManager.getEntitiesPosessing(levelUid, ComponentType.RopeGrab); // Detach any rope grab components from this rope for (int i = 0; i < ropeGrabEntities.Count; i++) { RopeGrabComponent ropeGrabComponent = (RopeGrabComponent)_entityManager.getComponent(levelUid, ropeGrabEntities[i], ComponentType.RopeGrab); if (ropeGrabComponent.ropeEntityId == entityId) { detachAll(ropeGrabComponent); _entityManager.removeComponent(levelUid, ropeGrabEntities[i], ropeGrabComponent); } } if (ropeComponent != null) { RopeNode current = ropeComponent.ropeNodeHead; while (current != null) { if (current.anchorJoint != null) { int entityIdA = (int)current.anchorJoint.BodyA.UserData; int entityIdB = (int)current.anchorJoint.BodyB.UserData; MetamerComponent metamerComponentA = _entityManager.getComponent(levelUid, entityIdA, ComponentType.Metamer) as MetamerComponent; MetamerComponent metamerComponentB = _entityManager.getComponent(levelUid, entityIdB, ComponentType.Metamer) as MetamerComponent; if (metamerComponentA != null) { metamerComponentA.metamer.anchorCount--; if (metamerComponentA.metamer.anchorCount <= 0) { current.anchorJoint.BodyA.World.RemoveBody(current.anchorJoint.BodyA); metamerComponentA.metamer.body = null; } } if (metamerComponentB != null) { metamerComponentB.metamer.anchorCount--; if (metamerComponentB.metamer.anchorCount <= 0) { current.anchorJoint.BodyB.World.RemoveBody(current.anchorJoint.BodyB); metamerComponentB.metamer.body = null; } } } // Destroy body current.body.World.RemoveBody(current.body); current = current.next; } _entityManager.killEntity(levelUid, entityId); } }
public void grabRope(RopeGrabComponent ropeGrabComponent, Body bodyToAttach) { int index = (int)Math.Floor(ropeGrabComponent.distance); float fraction = ropeGrabComponent.distance - (float)index; RopeNode node = ropeGrabComponent.ropeNode.getByIndex(index); float lengthPosition = -(node.halfLength * 2 * fraction - node.halfLength); RevoluteJoint joint; ropeGrabComponent.ropeNode = node; bodyToAttach.Position = node.body.GetWorldPoint(new Vector2(lengthPosition, 0)); joint = JointFactory.CreateRevoluteJoint(bodyToAttach.World, bodyToAttach, node.body, node.body.GetLocalPoint(bodyToAttach.Position)); ropeGrabComponent.joints.Add(bodyToAttach, joint); }
// update public void update(GameTime gameTime) { if (_singleStep || !_paused) { string levelUid = LevelSystem.currentLevelUid; LevelSystem levelSystem = _systemManager.getSystem(SystemType.Level) as LevelSystem; if (levelSystem.finalized) { PlayerSystem playerSystem = _systemManager.getSystem(SystemType.Player) as PlayerSystem; RopeSystem ropeSystem = _systemManager.getSystem(SystemType.Rope) as RopeSystem; PhysicsComponent playerPhysicsComponent = _entityManager.getComponent(levelUid, PlayerSystem.PLAYER_ID, ComponentType.Physics) as PhysicsComponent; List <int> toolbarEntities = _entityManager.getEntitiesPosessing(levelUid, ComponentType.Toolbar); // Player equipment if (playerSystem != null) { ToolbarComponent playerToolbar = _entityManager.getComponent(levelUid, PlayerSystem.PLAYER_ID, ComponentType.Toolbar) as ToolbarComponent; WorldPositionComponent playerPositionComponent = _entityManager.getComponent(levelUid, PlayerSystem.PLAYER_ID, ComponentType.WorldPosition) as WorldPositionComponent; ItemComponent selectedItem = playerToolbar.selectedItem; if (selectedItem != null) { selectedItem.primaryContinuousAction = InputSystem.newMouseState.LeftButton == ButtonState.Pressed; selectedItem.primarySingleAction = selectedItem.primaryContinuousAction && InputSystem.oldMouseState.LeftButton == ButtonState.Released; selectedItem.secondaryContinuousAction = InputSystem.newMouseState.RightButton == ButtonState.Pressed; selectedItem.secondarySingleAction = selectedItem.secondaryContinuousAction && InputSystem.oldMouseState.RightButton == ButtonState.Released; //bool leftTriggerDown = InputSystem.usingGamepad && InputSystem.newGamepadState.Triggers.Left > 0.5f && InputSystem.oldGamepadState.Triggers.Left <= 0.5f; //bool rightTriggerDown = InputSystem.usingGamepad && InputSystem.newGamepadState.Triggers.Right > 0.5f && InputSystem.oldGamepadState.Triggers.Right <= 0.5f; AimComponent aimComponent = _entityManager.getComponent(levelUid, PlayerSystem.PLAYER_ID, ComponentType.Aim) as AimComponent; if (selectedItem.definition.hasAimingComponent && aimComponent != null) { WorldPositionComponent worldPositionComponent = _entityManager.getComponent(levelUid, PlayerSystem.PLAYER_ID, ComponentType.WorldPosition) as WorldPositionComponent; if (worldPositionComponent != null) { Vector2 worldPosition = worldPositionComponent.position; if (InputSystem.usingGamepad) { Vector2 vector = InputSystem.newGamepadState.ThumbSticks.Left * selectedItem.state.currentRangeLimit; vector.Y *= -1; aimComponent.angle = (float)Math.Atan2(vector.Y, vector.X); aimComponent.length = vector.Length(); aimComponent.vector = vector; } else { Vector2 relative = (InputSystem.worldMouse - worldPosition); aimComponent.angle = (float)Math.Atan2(relative.Y, relative.X); aimComponent.length = Math.Min(relative.Length(), selectedItem.state.currentRangeLimit); aimComponent.vector = relative; } } } } } // All toolbars for (int i = 0; i < toolbarEntities.Count; i++) { ToolbarComponent toolbarComponent = _entityManager.getComponent(levelUid, toolbarEntities[i], ComponentType.Toolbar) as ToolbarComponent; ItemComponent selectedItem = toolbarComponent.selectedItem; if (selectedItem != null) { if (selectedItem.secondarySingleAction) { Console.WriteLine("secondary action"); } switch (selectedItem.definition.uid) { // RopeGun case "ropegun": if (selectedItem.primarySingleAction) { AimComponent aimComponent = _entityManager.getComponent(levelUid, toolbarEntities[i], ComponentType.Aim) as AimComponent; Vector2 initialPointA = (_entityManager.getComponent(levelUid, toolbarEntities[i], ComponentType.WorldPosition) as WorldPositionComponent).position; Vector2 initialPointB = initialPointA + new Vector2((float)Math.Cos(aimComponent.angle), (float)Math.Sin(aimComponent.angle)) * aimComponent.length; int ropeEntityId = _entityManager.factory.createSingleAnchorRope(levelUid, initialPointA, initialPointB, _defaultRopeMaterial, true); if (ropeEntityId != -1) { RopeGrabComponent ropeGrabComponent = _entityManager.getComponent(levelUid, toolbarComponent.entityId, ComponentType.RopeGrab) as RopeGrabComponent; RopeComponent ropeComponent = _entityManager.getComponent(levelUid, ropeEntityId, ComponentType.Rope) as RopeComponent; PhysicsComponent physicsComponent = _entityManager.getComponent(levelUid, toolbarEntities[i], ComponentType.Physics) as PhysicsComponent; RopeGrabComponent newRopeGrabComponent = null; Vector2 initialVelocity = physicsComponent.body.LinearVelocity; RopeNode currentNode = null; int ropeSegmentCount; if (physicsComponent == null) { break; } // Handle initial velocity currentNode = ropeComponent.ropeNodeHead; ropeSegmentCount = currentNode.count; System.Diagnostics.Debug.Assert(ropeSegmentCount != 0); int count = ropeSegmentCount; while (currentNode != null) { float weight = (float)count / (float)ropeSegmentCount; currentNode.body.LinearVelocity = currentNode.body.LinearVelocity + initialVelocity * weight; count--; currentNode = currentNode.next; } // Handle previous grabs if (ropeGrabComponent != null) { RopeComponent previouslyGrabbedRope = _entityManager.getComponent(levelUid, ropeGrabComponent.ropeEntityId, ComponentType.Rope) as RopeComponent; ropeSystem.releaseRope(ropeGrabComponent, physicsComponent.body); if (previouslyGrabbedRope.destroyAfterRelease) { previouslyGrabbedRope.timeToLive = 100; } _entityManager.removeComponent(levelUid, toolbarComponent.entityId, ropeGrabComponent); ropeGrabComponent = null; } newRopeGrabComponent = new RopeGrabComponent(ropeEntityId, ropeComponent.ropeNodeHead, 0f, ropeComponent.reverseClimbDirection); ropeSystem.grabRope(newRopeGrabComponent, physicsComponent.body); _entityManager.addComponent(levelUid, toolbarComponent.entityId, newRopeGrabComponent); } } break; // Dynamite case "dynamite": if (selectedItem.primarySingleAction) { AimComponent aimComponent = _entityManager.getComponent(levelUid, toolbarEntities[i], ComponentType.Aim) as AimComponent; _entityManager.factory.createDynamite(levelUid, playerPhysicsComponent.body.Position, aimComponent.vector * 80f); } break; // Water gun case "watergun": if (selectedItem.primaryContinuousAction) { FluidSystem fluidSystem = _systemManager.getSystem(SystemType.Fluid) as FluidSystem; AimComponent aimComponent = _entityManager.getComponent(levelUid, toolbarEntities[i], ComponentType.Aim) as AimComponent; Vector2 aimUnitVector = Vector2.Normalize(aimComponent.vector); Vector2 particlePosition = playerPhysicsComponent.body.Position + aimUnitVector + new Vector2(StasisMathHelper.floatBetween(-0.1f, 0.1f, _rng), StasisMathHelper.floatBetween(-0.1f, 0.1f, _rng)); Vector2 particleVelocity = aimUnitVector * 0.4f; fluidSystem.createParticle(particlePosition, particleVelocity); } break; } selectedItem.primarySingleAction = false; selectedItem.secondarySingleAction = false; selectedItem.primaryContinuousAction = false; selectedItem.secondaryContinuousAction = false; } } } } _singleStep = false; }
public void update(GameTime gameTime) { if (!_paused || _singleStep) { string levelUid = LevelSystem.currentLevelUid; LevelSystem levelSystem = _systemManager.getSystem(SystemType.Level) as LevelSystem; if (levelSystem.finalized) { List <int> ropeEntities = _entityManager.getEntitiesPosessing(levelUid, ComponentType.Rope); for (int i = 0; i < ropeEntities.Count; i++) { RopeComponent ropeComponent = _entityManager.getComponent(levelUid, ropeEntities[i], ComponentType.Rope) as RopeComponent; RopeGrabComponent ropeGrabComponent = _entityManager.getComponent(levelUid, ropeEntities[i], ComponentType.RopeGrab) as RopeGrabComponent; RopeNode head = ropeComponent.ropeNodeHead; RopeNode current = head; RopeNode tail = head.tail; // Check segment length if (head.count < 3 && ropeGrabComponent == null) { ropeComponent.startTTLCountdown(); } // Check anchors if (head.anchorJoint == null && tail.anchorJoint == null) { ropeComponent.startTTLCountdown(); } // Check time to live if (ropeComponent.timeToLive == 0) { killRope(levelUid, ropeEntities[i]); ropeComponent.timeToLive--; } else if (ropeComponent.timeToLive > -1) { ropeComponent.timeToLive--; } while (current != null) { // Check tensions if (current.joint != null) { Vector2 relative; if (current == head || current == tail) { // Check anchor joint if (current.anchorJoint != null) { relative = current.anchorJoint.BodyA.GetWorldPoint(current.anchorJoint.LocalAnchorA) - current.anchorJoint.BodyB.GetWorldPoint(current.anchorJoint.LocalAnchorB); if (relative.Length() > 0.8f || current.anchorJoint.GetReactionForce(60f).Length() > 400f) { breakAnchor(current); } } } // Check other joints relative = current.joint.BodyA.GetWorldPoint(current.joint.LocalAnchorA) - current.joint.BodyB.GetWorldPoint(current.joint.LocalAnchorB); if (relative.Length() > 1.2f || current.joint.GetReactionForce(60f).Length() > 300f) { breakJoint(levelUid, ropeEntities[i], current); } } current = current.next; } } } } _singleStep = false; }
public void attemptRopeGrab(string levelUid, int characterId, CharacterMovementComponent characterMovementComponent, PhysicsComponent physicsComponent, RopeGrabComponent existingRopeGrabComponent) { float margin = 0.5f; AABB region = new AABB(); RopeNode ropeNode = null; int nodeCount = 0; region.LowerBound = physicsComponent.body.Position - new Vector2(margin, margin); region.UpperBound = physicsComponent.body.Position + new Vector2(margin, margin); if (physicsComponent == null) { return; } // Query the world for a body, and check to see if it's a rope physicsComponent.body.World.QueryAABB((fixture) => { int ropeEntityId = (int)fixture.Body.UserData; RopeComponent ropeComponent = (RopeComponent)_entityManager.getComponent(levelUid, ropeEntityId, ComponentType.Rope); RopeGrabComponent ropeGrabComponent = null; if (ropeComponent != null && !ropeComponent.doubleAnchor) { RopeNode current = ropeComponent.ropeNodeHead; characterMovementComponent.allowRopeGrab = false; while (current != null) { if (current.body == fixture.Body) { ropeNode = current; break; } nodeCount++; current = current.next; } if (existingRopeGrabComponent != null) { RopeComponent existingRopeComponent = (RopeComponent)_entityManager.getComponent(levelUid, existingRopeGrabComponent.ropeEntityId, ComponentType.Rope); if (existingRopeComponent.destroyAfterRelease) { existingRopeComponent.timeToLive = 100; } _ropeSystem.releaseRope(existingRopeGrabComponent, physicsComponent.body); _entityManager.removeComponent(levelUid, characterId, existingRopeGrabComponent); } ropeGrabComponent = new RopeGrabComponent(ropeEntityId, ropeNode, (float)nodeCount, ropeComponent.reverseClimbDirection); _ropeSystem.grabRope(ropeGrabComponent, physicsComponent.body); _entityManager.addComponent(levelUid, characterId, ropeGrabComponent); return(false); } return(true); }, ref region); }
public void update(GameTime gameTime) { if (!_paused || _singleStep) { LevelSystem levelSystem = _systemManager.getSystem(SystemType.Level) as LevelSystem; if (levelSystem.finalized) { string levelUid = LevelSystem.currentLevelUid; List <int> characterEntities = _entityManager.getEntitiesPosessing(levelUid, ComponentType.CharacterMovement); for (int i = 0; i < characterEntities.Count; i++) { PhysicsComponent physicsComponent = _entityManager.getComponent(levelUid, characterEntities[i], ComponentType.Physics) as PhysicsComponent; ParticleInfluenceComponent particleInfluenceComponent = _entityManager.getComponent(levelUid, characterEntities[i], ComponentType.ParticleInfluence) as ParticleInfluenceComponent; CharacterMovementComponent characterMovementComponent = _entityManager.getComponent(levelUid, characterEntities[i], ComponentType.CharacterMovement) as CharacterMovementComponent; RopeGrabComponent ropeGrabComponent = _entityManager.getComponent(levelUid, characterEntities[i], ComponentType.RopeGrab) as RopeGrabComponent; Body body = physicsComponent.body; float currentSpeed = body.LinearVelocity.Length(); // Handle fluid properties characterMovementComponent.inFluid = particleInfluenceComponent.particleCount > 2; // Handle rope grabs if (characterMovementComponent.allowRopeGrab && characterMovementComponent.doRopeGrab) { attemptRopeGrab(levelUid, characterEntities[i], characterMovementComponent, physicsComponent, ropeGrabComponent); } // Calculate movement vector if (characterMovementComponent.collisionNormals.Count > 0) { characterMovementComponent.movementUnitVector = Vector2.Zero; for (int j = 0; j < characterMovementComponent.collisionNormals.Count; j++) { characterMovementComponent.movementUnitVector += characterMovementComponent.collisionNormals[j] / characterMovementComponent.collisionNormals.Count; } characterMovementComponent.movementUnitVector = new Vector2(characterMovementComponent.movementUnitVector.Y, -characterMovementComponent.movementUnitVector.X); characterMovementComponent.movementUnitVector.Normalize(); } else { characterMovementComponent.movementUnitVector = new Vector2(-1, 0); } // On surface movement if (characterMovementComponent.onSurface) { if (characterMovementComponent.walkLeft || characterMovementComponent.walkRight) { // Adjust friction if (body.LinearVelocity.X < -0.1f && characterMovementComponent.walkRight) { body.Friction = 10f; } else if (body.LinearVelocity.X > 0.1f && characterMovementComponent.walkLeft) { body.Friction = 10f; } else { body.Friction = 0.1f; } // Walk if (currentSpeed <= characterMovementComponent.speedLimit) { Vector2 impulse = characterMovementComponent.movementUnitVector * _baseWalkMultiplier; if (characterMovementComponent.walkRight) { impulse *= -1; } if (characterMovementComponent.inFluid) { impulse *= 0.5f; } body.ApplyLinearImpulse(ref impulse); } } else { body.Friction = 10f; } } else // In-air movement { if (characterMovementComponent.walkLeft || characterMovementComponent.walkRight) { if (ropeGrabComponent != null) { // Swing Vector2 impulse = characterMovementComponent.movementUnitVector * _baseSwingMultiplier; if (characterMovementComponent.walkRight) { impulse *= -1; } body.ApplyLinearImpulse(ref impulse); } else { // Air walk if ((body.LinearVelocity.X < 0 && characterMovementComponent.walkRight) || (body.LinearVelocity.X > 0 && characterMovementComponent.walkLeft) || (body.LinearVelocity.X > -characterMovementComponent.speedLimit && characterMovementComponent.walkLeft) || (body.LinearVelocity.X < characterMovementComponent.speedLimit && characterMovementComponent.walkRight)) { Vector2 impulse = characterMovementComponent.movementUnitVector * _baseAirWalkMultiplier; if (characterMovementComponent.walkRight) { impulse *= -1; } body.ApplyLinearImpulse(ref impulse); } } } } // Jump if (characterMovementComponent.attemptJump) { // While holding rope if (ropeGrabComponent != null) { RopeComponent ropeComponent = _entityManager.getComponent(levelUid, ropeGrabComponent.ropeEntityId, ComponentType.Rope) as RopeComponent; Vector2 impulse = new Vector2(0, -1.2f); if (ropeComponent != null && ropeComponent.destroyAfterRelease) { ropeComponent.timeToLive = 100; } _ropeSystem.releaseRope(ropeGrabComponent, physicsComponent.body); _entityManager.removeComponent(levelUid, characterEntities[i], ropeGrabComponent); ropeGrabComponent = null; body.ApplyLinearImpulse(ref impulse); } if (characterMovementComponent.onSurface) { Vector2 impulse = new Vector2(0, -2f); float adjustment = 0f; // Try to limit the impulse based on the current y velocity. // This is done to prevent jumps from contributing too much to the y velocity when // the player is already moving upwards too fast (which results in a super-jump). adjustment = (body.LinearVelocity.Y / 6f); impulse.Y -= adjustment; body.ApplyLinearImpulse(ref impulse); characterMovementComponent.attemptJump = false; } } // Swim if (characterMovementComponent.inFluid && characterMovementComponent.swimUp) { Vector2 impulse = new Vector2(0, -0.25f); body.ApplyLinearImpulse(ref impulse); } // Climbing if (ropeGrabComponent != null) { float climbSpeed = characterMovementComponent.climbAmount * CLIMB_SPEED; if (characterMovementComponent.climbUp) { _ropeSystem.moveAttachedBody(ropeGrabComponent, physicsComponent.body, climbSpeed); } else if (characterMovementComponent.climbDown) { _ropeSystem.moveAttachedBody(ropeGrabComponent, physicsComponent.body, -climbSpeed); } } } } } _singleStep = false; }
// Handle player character movement private void handleCharacterMovement(string levelUid, PhysicsComponent playerPhysicsComponent, bool inDialogue) { if (playerPhysicsComponent != null) { CharacterMovementComponent characterMovementComponent = _entityManager.getComponent(levelUid, PLAYER_ID, ComponentType.CharacterMovement) as CharacterMovementComponent; RopeGrabComponent ropeGrabComponent = _entityManager.getComponent(levelUid, PLAYER_ID, ComponentType.RopeGrab) as RopeGrabComponent; if (InputSystem.usingGamepad) { if (InputSystem.newGamepadState.ThumbSticks.Left.X < 0) { //characterMovementComponent.walkSpeedModifier = Math.Abs(InputSystem.newGamepadState.ThumbSticks.Left.X); characterMovementComponent.walkLeft = true; } else if (InputSystem.newGamepadState.DPad.Left == ButtonState.Pressed) { characterMovementComponent.walkLeft = true; } else { characterMovementComponent.walkLeft = false; } if (InputSystem.newGamepadState.ThumbSticks.Left.X > 0) { //characterMovementComponent.walkSpeedModifier = InputSystem.newGamepadState.ThumbSticks.Left.X; characterMovementComponent.walkRight = true; } else if (InputSystem.newGamepadState.DPad.Right == ButtonState.Pressed) { characterMovementComponent.walkRight = true; } else { characterMovementComponent.walkRight = false; } characterMovementComponent.climbAmount = 0f; characterMovementComponent.climbDown = false; characterMovementComponent.climbUp = false; if (InputSystem.newGamepadState.ThumbSticks.Left.Y > 0) { characterMovementComponent.climbUp = true; characterMovementComponent.climbAmount = Math.Abs(InputSystem.newGamepadState.ThumbSticks.Left.Y); } else if (InputSystem.newGamepadState.ThumbSticks.Left.Y < 0) { characterMovementComponent.climbDown = true; characterMovementComponent.climbAmount = Math.Abs(InputSystem.newGamepadState.ThumbSticks.Left.Y); } characterMovementComponent.attemptJump = InputSystem.newGamepadState.Buttons.A == ButtonState.Pressed; } else { //characterMovementComponent.walkSpeedModifier = 1f; characterMovementComponent.walkLeft = InputSystem.newKeyState.IsKeyDown(Keys.A) || InputSystem.newKeyState.IsKeyDown(Keys.Left); characterMovementComponent.walkRight = InputSystem.newKeyState.IsKeyDown(Keys.D) || InputSystem.newKeyState.IsKeyDown(Keys.Right); characterMovementComponent.attemptJump = InputSystem.newKeyState.IsKeyDown(Keys.Space) && InputSystem.oldKeyState.IsKeyUp(Keys.Space); characterMovementComponent.swimUp = InputSystem.newKeyState.IsKeyDown(Keys.Space); characterMovementComponent.climbUp = InputSystem.newKeyState.IsKeyDown(Keys.W); characterMovementComponent.climbDown = InputSystem.newKeyState.IsKeyDown(Keys.S); characterMovementComponent.climbAmount = 1f; characterMovementComponent.doRopeGrab = InputSystem.newKeyState.IsKeyDown(Keys.E) && InputSystem.oldKeyState.IsKeyUp(Keys.E); characterMovementComponent.allowRopeGrab = characterMovementComponent.allowRopeGrab ? true : (InputSystem.newKeyState.IsKeyUp(Keys.E) && InputSystem.oldKeyState.IsKeyDown(Keys.E)); } } }