void LateUpdate() { float wheel = Input.GetAxis("Mouse ScrollWheel"); ray = Camera.main.ScreenPointToRay(Input.mousePosition); bool rayIntersectsAnyCollider = Physics.Raycast(ray, out hit, maxCameraDistance, lm.value); //print(state); if (isLocked) { if (lockedTransform != null) { offSet = lockedTransform.position - off; off = lockedTransform.position; //in case the lockedTransform is moving if (Input.GetMouseButton(1) == false) { state = CameraState.isIdling; float magnitude = (targetTransform.position - transform.position).magnitude; //in case the lockedTransform is moving transform.position = targetTransform.position - (transform.rotation * Vector3.forward * magnitude) + offSet; targetTransform.position = lockedTransform.position; } } else { isLocked = false; } } if (state != CameraState.isTargeting) { if (panMode == true && Input.GetMouseButton(2) == true) { if (state != CameraState.isPanning) { lastMousePos = Input.mousePosition; } state = CameraState.isPanning; } if (Input.GetMouseButton(1) == true) { state = CameraState.isRotating; } else if (Input.GetMouseButtonUp(1)) { yDeg = transform.rotation.eulerAngles.x; if (yDeg > 180) { yDeg -= 360; } xDeg = transform.rotation.eulerAngles.y; state = CameraState.isIdling; } else if (wheel != 0) { state = CameraState.isZooming; } } switch (state) { #region Idling case CameraState.isIdling: break; #endregion #region Rotating case CameraState.isRotating: float getAxisX = Input.GetAxis("Mouse X"); float getAxisY = Input.GetAxis("Mouse Y"); if (Mathf.Abs(getAxisX) > 0.05f || Mathf.Abs(getAxisY) > 0.05f) { isMovingWithRotation = true; } xDeg += getAxisX * xSpeed; yDeg -= getAxisY * ySpeed; yDeg = ClampAngle(yDeg, yMinLimit, yMaxLimit, 5); transform.rotation = Quaternion.Lerp(transform.rotation, Quaternion.Euler(yDeg, xDeg, 0), Time.deltaTime * rotationDampening / Time.timeScale); transform.eulerAngles = new Vector3(transform.eulerAngles.x, transform.eulerAngles.y, 0); float magnitude = (targetTransform.position - transform.position).magnitude; transform.position = targetTransform.position - (transform.rotation * Vector3.forward * magnitude) + offSet; targetTransform.position = targetTransform.position + offSet; break; #endregion #region Zooming case CameraState.isZooming: Vector3 hitPoint = Vector3.zero; if (rayIntersectsAnyCollider) { hitPoint = hit.point; } else { planeZero.Raycast(ray, out float enter1); hitPoint = ray.GetPoint(enter1); } perpendToViewplane.SetNormalAndPosition(-transform.forward, hitPoint); perpendToViewplane.Raycast(ray, out enter); rayPlanePoint = ray.GetPoint(Mathf.Min(enter, 100f)); ray.direction = transform.forward; float par = 0.33f; enter = Mathf.Abs(enter); targetTransform.position = transform.forward * enter + transform.position; if (wheel > 0) { desiredPosition = MathLibrary.ClampMagnitude((rayPlanePoint - transform.position), cameraMaxDistance, 10) * par + transform.position; } else if (wheel < 0) { desiredPosition = -MathLibrary.ClampMagnitude((targetTransform.position - transform.position), cameraMaxDistance, 10) * par + transform.position; } transform.position = Vector3.Lerp(transform.position, desiredPosition, zoomRate * Time.deltaTime / Time.timeScale); if (Vector3.SqrMagnitude(transform.position - desiredPosition) < zoomThres) { state = CameraState.isIdling; } break; #endregion #region Panning case CameraState.isPanning: Vector3 v = new Vector3(Input.mousePosition.x - lastMousePos.x, 0, Input.mousePosition.y - lastMousePos.y); Vector3 centerToMouse = transform.rotation * v; centerToMouse.y = 0; centerToMouse.Normalize(); centerToMouse *= 30; centerToMouse *= transform.position.y; float distFromCenter = centerToMouse.magnitude; if (lockedTransform != null) { UnlockObject(); } rayPlanePoint.Set(transform.forward.x, 0, transform.forward.z); //targetTransform.Translate(centerToMouse * Time.deltaTime * panSpeed); //here, right is wrt the loc ref because Space.Self by default //transform.Translate(centerToMouse * Time.deltaTime * panSpeed); float t = panSpeed * Time.deltaTime / Time.timeScale; targetTransform.position = Vector3.Lerp(targetTransform.position, transform.position + centerToMouse, t); transform.position = Vector3.Lerp(transform.position, transform.position + centerToMouse, t); if (Input.GetMouseButtonUp(2) == true) { state = CameraState.isIdling; } break; #endregion //#region Panning //case CameraState.isPanning: // Vector3 screenCenter = new Vector3(Screen.width, Screen.height, 0) * 0.5f; // Vector3 centerToMouse = Input.mousePosition - lastMousePos; // float distFromCenter = centerToMouse.magnitude; // if (lockedTransform != null) { // UnlockObject(); // } // rayPlanePoint.Set(transform.forward.x, 0, transform.forward.z); // //targetTransform.Translate(centerToMouse * Time.deltaTime * panSpeed); //here, right is wrt the loc ref because Space.Self by default // //transform.Translate(centerToMouse * Time.deltaTime * panSpeed); // targetTransform.position = Vector3.Lerp(transform.position, transform.position + centerToMouse, panSpeed * Time.deltaTime / Time.timeScale); // transform.position = Vector3.Lerp(transform.position, transform.position + centerToMouse, panSpeed * Time.deltaTime / Time.timeScale); // if (Input.GetMouseButtonUp(2) == true) { // state = CameraState.isIdling; // } // //float panNorm = transform.position.y; // //if ((Input.mousePosition.x - Screen.width + panThres) > 0) { // // targetTransform.Translate(Vector3.right * -panSpeed * Time.deltaTime * panNorm); //here, right is wrt the loc ref because Space.Self by default // // transform.Translate(Vector3.right * -panSpeed * Time.deltaTime * panNorm); // //} else if ((Input.mousePosition.x - panThres) < 0) { // // targetTransform.Translate(Vector3.right * panSpeed * Time.deltaTime * panNorm); // // transform.Translate(Vector3.right * panSpeed * Time.deltaTime * panNorm); // //} // //if ((Input.mousePosition.y - Screen.height + panThres) > 0) { // // rayPlanePoint.Set(transform.forward.x, 0, transform.forward.z); // // targetTransform.Translate(rayPlanePoint.normalized * -panSpeed * Time.deltaTime * panNorm, Space.World); // // transform.Translate(rayPlanePoint.normalized * -panSpeed * Time.deltaTime * panNorm, Space.World); // //} // //if ((Input.mousePosition.y - panThres) < 0) { // // rayPlanePoint.Set(transform.forward.x, 0, transform.forward.z); // // targetTransform.Translate(rayPlanePoint.normalized * panSpeed * Time.deltaTime * panNorm, Space.World); // // transform.Translate(rayPlanePoint.normalized * panSpeed * Time.deltaTime * panNorm, Space.World); // //} // //if (lockedTransform != null) // // UnlockObject(); // //float panNorm = transform.position.y; // //if ((Input.mousePosition.x - Screen.width + panThres) > 0) { // // targetTransform.Translate(Vector3.right * -panSpeed * Time.deltaTime * panNorm); //here, right is wrt the loc ref because Space.Self by default // // transform.Translate(Vector3.right * -panSpeed * Time.deltaTime * panNorm); // //} else if ((Input.mousePosition.x - panThres) < 0) { // // targetTransform.Translate(Vector3.right * panSpeed * Time.deltaTime * panNorm); // // transform.Translate(Vector3.right * panSpeed * Time.deltaTime * panNorm); // //} // //if ((Input.mousePosition.y - Screen.height + panThres) > 0) { // // rayPlanePoint.Set(transform.forward.x, 0, transform.forward.z); // // targetTransform.Translate(rayPlanePoint.normalized * -panSpeed * Time.deltaTime * panNorm, Space.World); // // transform.Translate(rayPlanePoint.normalized * -panSpeed * Time.deltaTime * panNorm, Space.World); // //} // //if ((Input.mousePosition.y - panThres) < 0) { // // rayPlanePoint.Set(transform.forward.x, 0, transform.forward.z); // // targetTransform.Translate(rayPlanePoint.normalized * panSpeed * Time.deltaTime * panNorm, Space.World); // // transform.Translate(rayPlanePoint.normalized * panSpeed * Time.deltaTime * panNorm, Space.World); // //} // break; //#endregion #region Targeting case CameraState.isTargeting: off = lockedTransform.position; offSet = lockedTransform.position - off; targetTransform.position = Vector3.Lerp(targetTransform.position, lockedTransform.position, 3 * zoomRate * Time.deltaTime / Time.timeScale); desiredPosition = targetTransform.position - limit * transform.forward; transform.position = Vector3.Lerp(transform.position, desiredPosition, zoomRate * Time.deltaTime / Time.timeScale); if (Vector3.SqrMagnitude(transform.position - desiredPosition) < 50 * 50) { state = CameraState.isIdling; } break; #endregion default: break; } targetTransform.position = Vector3.ClampMagnitude(targetTransform.position, cameraMaxDistance); distanceTozero = transform.position.magnitude; if (distanceTozero > cameraMaxDistance) { transform.position = Vector3.ClampMagnitude(transform.position, cameraMaxDistance); } }