/// <summary> /// Moves the character. /// </summary> override public void DoMove() { if (swingTimer <= 0.0f) { showSwingAnimation = false; } // On a ladder/vine if (currentRopeSection == null) { float offsetFromCentre = transform.position.x - character.CurrentLadder.transform.position.x; character.Translate(-offsetFromCentre, 0, true); // Determine if we are at bottom of ladder (ie. the bottom of the feet colliders are below or at the ladders end) // Climbing if (character.Input.VerticalAxisDigital != 0) { if (character.Input.VerticalAxisDigital == 1) { character.Translate(0, TimeManager.FrameTime * climbSpeed, true); // Make sure we don't go above ladder float ladderTop = (character.CurrentLadder.transform.position.y + ((BoxCollider2D)character.CurrentLadder).Offset().y) + (character.CurrentLadder.transform.lossyScale.y * (((BoxCollider2D)character.CurrentLadder).size.y / 2)); if (ladderTop <= character.BottomOfFeet) { character.Translate(0, ladderTop - character.BottomOfFeet, true); // Dismount - climbed to bottom/top of ladder if (((int)LadderDismountType.TOP_BOTTOM & availableDismounts) == (int)LadderDismountType.TOP_BOTTOM) { dismount = true; character.ApplyBaseCollisionsForRaycastType(RaycastType.FOOT); } } } else if (character.Input.VerticalAxisDigital == -1) { character.Translate(0, TimeManager.FrameTime * -climbSpeed, true); // Make sure we don't go below ladder float ladderBottom = (character.CurrentLadder.transform.position.y + ((BoxCollider2D)character.CurrentLadder).Offset().y) - (character.CurrentLadder.transform.lossyScale.y * (((BoxCollider2D)character.CurrentLadder).size.y / 2)); if (ladderBottom >= character.BottomOfFeet) { character.Translate(0, ladderBottom - character.BottomOfFeet, true); // Dismount - climbed to bottom/top of ladder if (((int)LadderDismountType.TOP_BOTTOM & availableDismounts) == (int)LadderDismountType.TOP_BOTTOM) { dismount = true; } } } } } // On a rope else { // Handle non-climbable rope if (currentRopeSection.usedFixedPosition) { // Dismount on down if (character.Input.VerticalAxisDigital == -1) { if (((int)LadderDismountType.TOP_BOTTOM & availableDismounts) == (int)LadderDismountType.TOP_BOTTOM) { dismount = true; dismountTimer = DismountTime; character.ApplyBaseCollisionsForRaycastType(RaycastType.FOOT); } } } else { // Climbing if (character.Input.VerticalAxisDigital != 0) { if (character.Input.VerticalAxisDigital == 1) { // Make sure we can climb to the next rope piece if it exists // Move along length float newPosition = positionOnSection + (TimeManager.FrameTime * (climbSpeed / currentRopeSectionLength)); if (newPosition >= 2.0f) { Debug.LogWarning("Rope climbing speed is too large for rope section size"); newPosition = 1.9999f; } if (newPosition > 1.0f) { // If position is bigger than one move up to next rope section RopeSection nextSection = currentRopeSection.SectionAbove; // Don't allow climbing to the RopeAnchor if (nextSection is RopeAnchor) { nextSection = null; } // Or if no rope section left cap position at 1. if (nextSection == null) { positionOnSection = 1.0f; } else { positionOnSection = newPosition - 1.0f; currentRopeSection = nextSection; } } else { positionOnSection = newPosition; } } else if (character.Input.VerticalAxisDigital == -1) { // Make sure we can climb to the next rope piece if it exists // Move along length float newPosition = positionOnSection - (TimeManager.FrameTime * (climbSpeed / currentRopeSectionLength)); if (newPosition <= -1.0f) { Debug.LogWarning("Rope climbing speed is too large for rope section size"); newPosition = -0.9999f; } if (newPosition < 0) { // If position is smaller than zero move down to next rope section RopeSection nextSection = currentRopeSection.SectionBelow; // Or if no rope section left cap position at 0 if (nextSection == null) { positionOnSection = 0; if (((int)LadderDismountType.TOP_BOTTOM & availableDismounts) == (int)LadderDismountType.TOP_BOTTOM && character.Input.VerticalAxisDigital == -1) { dismount = true; dismountTimer = DismountTime; character.ApplyBaseCollisionsForRaycastType(RaycastType.FOOT); } } else { positionOnSection = newPosition + 1.0f; currentRopeSection = nextSection; } } else { positionOnSection = newPosition; } } } } // Rotate if (calculateAngles) { // TODO This rotation interacts directly with the chracter transform (and other variables) - it would be nicer to do this through the character interface float deg = currentRopeSection.GetCharacterRotationForPosition(positionOnSection, handOffset); float deg2 = currentRopeSection.GetCharacterRotationForPosition(positionOnSection, 0); deg = (deg + deg2) / 2.0f; float difference = deg - character.transform.eulerAngles.z; // Shouldn't really happen but just in case if (difference > 180) { difference = difference - 360; } if (difference < -180) { difference = difference + 360; } // character.transform.Rotate = Quaternion.Euler(0,0,deg); //character.transform.RotateAround(transform.position + new Vector3(0, handOffset, 0), new Vector3(0,0,1), difference); if (difference > character.rotationSpeed * TimeManager.FrameTime) { difference = character.rotationSpeed * TimeManager.FrameTime; } if (difference < -character.rotationSpeed * TimeManager.FrameTime) { difference = -character.rotationSpeed * TimeManager.FrameTime; } character.transform.RotateAround(character.transform.position, new Vector3(0, 0, 1), difference); } // Snap to centre Vector2 diff = (Vector2)character.transform.position + (Vector2)(character.transform.localRotation * new Vector2(0, handOffset)) - currentRopeSection.GetCharacterPositionForPosition(positionOnSection, handOffset); character.Translate(-diff.x, -diff.y, true); // Apply down force if (downforce > 0) { currentRopeSection.GetComponent <Rigidbody2D>().AddForceAtPosition(new Vector2(0, -downforce), character.Transform.position, ForceMode2D.Force); } // Swing (but only if not climbing) if (swingForce > 0 && swingTimer <= 0.0f && character.Input.HorizontalAxisDigital != 0 && character.Input.VerticalAxisDigital == 0) { currentRopeSection.GetComponent <Rigidbody2D>().AddForceAtPosition(currentRopeSection.transform.rotation * new Vector2(swingForce * character.Input.HorizontalAxisDigital, 0), character.Transform.position, ForceMode2D.Impulse); swingTimer = swingTime; showSwingAnimation = true; } } // We have no residual velocity if on a rope if (!jumpDismount) { character.SetVelocityX(0); character.SetVelocityY(0); } }