void ApplyGravity() { if (isControllable) // don't move player at all if not controllable. { // Apply gravity var jumpButton = WordDetectionInput.GetButton("Jump"); // When we reach the apex of the jump we send out a message if ((jumpButton || jumping) && !jumpingReachedApex && verticalSpeed <= 0.0) { jumpingReachedApex = true; SendMessage("DidJumpReachApex", SendMessageOptions.DontRequireReceiver); } if (IsGrounded()) { verticalSpeed = 0.0f; } else { verticalSpeed -= gravity * Time.deltaTime; } } }
// Update is called once per frame void Update() { // Get the input vector from keyboard or analog stick Vector3 directionVector = new Vector3(WordDetectionInput.GetAxis("Horizontal"), 0, WordDetectionInput.GetAxis("Vertical")); if (directionVector != Vector3.zero) { // Get the length of the directon vector and then normalize it // Dividing by the length is cheaper than normalizing when we already have the length anyway var directionLength = directionVector.magnitude; directionVector = directionVector / directionLength; // Make sure the length is no bigger than 1 directionLength = Mathf.Min(1, directionLength); // Make the input vector more sensitive towards the extremes and less sensitive in the middle // This makes it easier to control slow speeds when using analog sticks directionLength = directionLength * directionLength; // Multiply the normalized direction vector by the modified length directionVector = directionVector * directionLength; } // Apply the direction to the CharacterMotor motor.inputMoveDirection = transform.rotation * directionVector; motor.inputJump = WordDetectionInput.GetButton("Jump"); }
// Update is called once per frame void Update() { // Get the input vector from keyboard or analog stick var directionVector = new Vector3(WordDetectionInput.GetAxis("Horizontal"), WordDetectionInput.GetAxis("Vertical"), 0); if (directionVector != Vector3.zero) { // Get the length of the directon vector and then normalize it // Dividing by the length is cheaper than normalizing when we already have the length anyway var directionLength = directionVector.magnitude; directionVector = directionVector / directionLength; // Make sure the length is no bigger than 1 directionLength = Mathf.Min(1, directionLength); // Make the input vector more sensitive towards the extremes and less sensitive in the middle // This makes it easier to control slow speeds when using analog sticks directionLength = directionLength * directionLength; // Multiply the normalized direction vector by the modified length directionVector = directionVector * directionLength; } // Rotate the input vector into camera space so up is camera's up and right is camera's right directionVector = Camera.main.transform.rotation * directionVector; // Rotate input vector to be perpendicular to character's up vector var camToCharacterSpace = Quaternion.FromToRotation(-Camera.main.transform.forward, transform.up); directionVector = (camToCharacterSpace * directionVector); // Apply the direction to the CharacterMotor motor.inputMoveDirection = directionVector; motor.inputJump = WordDetectionInput.GetButton("Jump"); // Set rotation to the move direction if (autoRotate && directionVector.sqrMagnitude > 0.01) { Vector3 newForward = ConstantSlerp( transform.forward, directionVector, maxRotationSpeed * Time.deltaTime ); newForward = ProjectOntoPlane(newForward, transform.up); transform.rotation = Quaternion.LookRotation(newForward, transform.up); } }
void Update() { if (axes == RotationAxes.MouseXAndY) { float rotationX = transform.localEulerAngles.y + WordDetectionInput.GetAxis("Mouse X") * sensitivityX; rotationY += WordDetectionInput.GetAxis("Mouse Y") * sensitivityY; rotationY = Mathf.Clamp(rotationY, minimumY, maximumY); transform.localEulerAngles = new Vector3(-rotationY, rotationX, 0); } else if (axes == RotationAxes.MouseX) { transform.Rotate(0, WordDetectionInput.GetAxis("Mouse X") * sensitivityX, 0); } else { rotationY += WordDetectionInput.GetAxis("Mouse Y") * sensitivityY; rotationY = Mathf.Clamp(rotationY, minimumY, maximumY); transform.localEulerAngles = new Vector3(-rotationY, transform.localEulerAngles.y, 0); } }
void Apply(Transform dummyTarget, Vector3 dummyCenter) { // Early out if we don't have a target if (!controller) { return; } var targetCenter = _target.position + centerOffset; var targetHead = _target.position + headOffset; // DebugDrawStuff(); // Calculate the current & target rotation angles var originalTargetAngle = _target.eulerAngles.y; var currentAngle = cameraTransform.eulerAngles.y; // Adjust real target angle when camera is locked var targetAngle = originalTargetAngle; // When pressing Fire2 (alt) the camera will snap to the target direction real quick. // It will stop snapping when it reaches the target if (WordDetectionInput.GetButton("Fire2")) { snap = true; } if (snap) { // We are close to the target, so we can stop snapping now! if (AngleDistance(currentAngle, originalTargetAngle) < 3.0) { snap = false; } currentAngle = Mathf.SmoothDampAngle(currentAngle, targetAngle, ref angleVelocity, snapSmoothLag, snapMaxSpeed); } // Normal camera motion else { if (controller.GetLockCameraTimer() < lockCameraTimeout) { targetAngle = currentAngle; } // Lock the camera when moving backwards! // * It is really confusing to do 180 degree spins when turning around. if (AngleDistance(currentAngle, targetAngle) > 160 && controller.IsMovingBackwards()) { targetAngle += 180; } currentAngle = Mathf.SmoothDampAngle(currentAngle, targetAngle, ref angleVelocity, angularSmoothLag, angularMaxSpeed); } // When jumping don't move camera upwards but only down! if (controller.IsJumping()) { // We'd be moving the camera upwards, do that only if it's really high var newTargetHeight = targetCenter.y + height; if (newTargetHeight < targetHeight || newTargetHeight - targetHeight > 5) { targetHeight = targetCenter.y + height; } } // When walking always update the target height else { targetHeight = targetCenter.y + height; } // Damp the height var currentHeight = cameraTransform.position.y; currentHeight = Mathf.SmoothDamp(currentHeight, targetHeight, ref heightVelocity, heightSmoothLag); // Convert the angle into a rotation, by which we then reposition the camera var currentRotation = Quaternion.Euler(0, currentAngle, 0); // Set the position of the camera on the x-z plane to: // distance meters behind the target cameraTransform.position = targetCenter; cameraTransform.position += currentRotation * Vector3.back * distance; // Set the height of the camera Vector3 cameraPosition = cameraTransform.position; cameraPosition.y = currentHeight; cameraTransform.position = cameraPosition; // Always look at the target SetUpRotation(targetCenter, targetHead); }
bool IsMoving() { return(Mathf.Abs(WordDetectionInput.GetAxisRaw("Vertical")) + Mathf.Abs(WordDetectionInput.GetAxisRaw("Horizontal")) > 0.5); }
void Update() { if (!isControllable) { // kill all inputs if not controllable. WordDetectionInput.ResetInputAxes(); } if (WordDetectionInput.GetButtonDown("Jump")) { lastJumpButtonTime = Time.time; } UpdateSmoothedMovementDirection(); // Apply gravity // - extra power jump modifies gravity // - controlledDescent mode modifies gravity ApplyGravity(); // Apply jumping logic ApplyJumping(); // Calculate actual motion Vector3 movement = moveDirection * moveSpeed + new Vector3(0, verticalSpeed, 0) + inAirVelocity; movement *= Time.deltaTime; // Move the controller CharacterController controller = GetComponent <CharacterController>(); collisionFlags = controller.Move(movement); // ANIMATION sector if (_animation) { if (_characterState == CharacterState.Jumping) { if (!jumpingReachedApex) { _animation[jumpPoseAnimation.name].speed = jumpAnimationSpeed; _animation[jumpPoseAnimation.name].wrapMode = WrapMode.ClampForever; _animation.CrossFade(jumpPoseAnimation.name); } else { _animation[jumpPoseAnimation.name].speed = -landAnimationSpeed; _animation[jumpPoseAnimation.name].wrapMode = WrapMode.ClampForever; _animation.CrossFade(jumpPoseAnimation.name); } } else { if (controller.velocity.sqrMagnitude < 0.1) { _animation.CrossFade(idleAnimation.name); } else { if (_characterState == CharacterState.Running) { _animation[runAnimation.name].speed = Mathf.Clamp(controller.velocity.magnitude, 0.0f, runMaxAnimationSpeed); _animation.CrossFade(runAnimation.name); } else if (_characterState == CharacterState.Trotting) { _animation[walkAnimation.name].speed = Mathf.Clamp(controller.velocity.magnitude, 0.0f, trotMaxAnimationSpeed); _animation.CrossFade(walkAnimation.name); } else if (_characterState == CharacterState.Walking) { _animation[walkAnimation.name].speed = Mathf.Clamp(controller.velocity.magnitude, 0.0f, walkMaxAnimationSpeed); _animation.CrossFade(walkAnimation.name); } } } } // ANIMATION sector // Set rotation to the move direction if (IsGrounded()) { transform.rotation = Quaternion.LookRotation(moveDirection); } else { var xzMove = movement; xzMove.y = 0; if (xzMove.sqrMagnitude > 0.001) { transform.rotation = Quaternion.LookRotation(xzMove); } } // We are in jump mode but just became grounded if (IsGrounded()) { lastGroundedTime = Time.time; inAirVelocity = Vector3.zero; if (jumping) { jumping = false; SendMessage("DidLand", SendMessageOptions.DontRequireReceiver); } } }
void UpdateSmoothedMovementDirection() { var cameraTransform = Camera.main.transform; var grounded = IsGrounded(); // Forward vector relative to the camera along the x-z plane var forward = cameraTransform.TransformDirection(Vector3.forward); forward.y = 0; forward = forward.normalized; // Right vector relative to the camera // Always orthogonal to the forward vector Vector3 right = new Vector3(forward.z, 0, -forward.x); float v = WordDetectionInput.GetAxisRaw("Vertical"); float h = WordDetectionInput.GetAxisRaw("Horizontal"); // Are we moving backwards or looking backwards if (v < -0.2) { movingBack = true; } else { movingBack = false; } bool wasMoving = isMoving; isMoving = Mathf.Abs(h) > 0.1 || Mathf.Abs(v) > 0.1; // Target direction relative to the camera var targetDirection = h * right + v * forward; // Grounded controls if (grounded) { // Lock camera for short period when transitioning moving & standing still lockCameraTimer += Time.deltaTime; if (isMoving != wasMoving) { lockCameraTimer = 0.0f; } // We store speed and direction seperately, // so that when the character stands still we still have a valid forward direction // moveDirection is always normalized, and we only update it if there is user input. if (targetDirection != Vector3.zero) { // If we are really slow, just snap to the target direction if (moveSpeed < walkSpeed * 0.9 && grounded) { moveDirection = targetDirection.normalized; } // Otherwise smoothly turn towards it else { moveDirection = Vector3.RotateTowards(moveDirection, targetDirection, rotateSpeed * Mathf.Deg2Rad * Time.deltaTime, 1000); moveDirection = moveDirection.normalized; } } // Smooth the speed based on the current target direction var curSmooth = speedSmoothing * Time.deltaTime; // Choose target speed //* We want to support analog input but make sure you cant walk faster diagonally than just forward or sideways float targetSpeed = Mathf.Min(targetDirection.magnitude, 1.0f); _characterState = CharacterState.Idle; // Pick speed modifier if (WordDetectionInput.GetKey(KeyCode.LeftShift) || WordDetectionInput.GetKey(KeyCode.RightShift)) { targetSpeed *= runSpeed; _characterState = CharacterState.Running; } else if (Time.time - trotAfterSeconds > walkTimeStart) { targetSpeed *= trotSpeed; _characterState = CharacterState.Trotting; } else { targetSpeed *= walkSpeed; _characterState = CharacterState.Walking; } moveSpeed = Mathf.Lerp(moveSpeed, targetSpeed, curSmooth); // Reset walk time start when we slow down if (moveSpeed < walkSpeed * 0.3) { walkTimeStart = Time.time; } } // In air controls else { // Lock camera while in air if (jumping) { lockCameraTimer = 0.0f; } if (isMoving) { inAirVelocity += targetDirection.normalized * Time.deltaTime * inAirControlAcceleration; } } }