using CommandUndoRedo; using UnityEngine; using UnityEngine.EventSystems; public class CameraOrbit : MonoBehaviour { public bool LightLock = false; public Camera Cam; bool controlOn; float controlTime; [Header("Light")] public GameObject Light; public GameObject CameraTargetHelper; public Vector3 TargetCenter; EventSystem eventSystem; [Header("Free Camera")] bool FreeCamLeft = false; bool FreeCamRight = false; public Vector3 lookRotation; private CameraSettings _settings => ModelViewerMain.GetInstance().GetCameraHandler().Settings; private CameraTransformCommand _tempCommand; private void Start() { Init(); } public CameraOrbit Init() { Cam = GetComponentInChildren(); eventSystem = EventSystem.current; return this; } void Update() { if (ModelViewerMain.GetInstance() == null) return; UpdateImmediate(); } public void UpdateImmediate(bool forceUpdate = false) { if(!forceUpdate) { if (HandleManager.InteractionInProgress || _settings.CameraLock) return; } switch (_settings.CameraMode) { case 0: OrbitAround(); OrbitLight(); break; case 1: OrbitAround(true); OrbitLight(); break; case 2: FreeCamera(); break; } } #region Camera /// /// Orbit camera around world center /// void OrbitAround(bool aroundCharacter = false) { float x = 0; float y = 0; var settings = _settings; using (var context = new KeyframeToggleContext(settings)) { if (eventSystem.currentSelectedGameObject == null) { x = Input.GetAxis("Horizontal"); y = Input.GetAxis("Vertical"); } if (aroundCharacter) { var selectedObject = ModelViewerMain.GetInstance().SelectedObject; TargetCenter = selectedObject != null ? selectedObject.GetCenter() : Vector3.zero; } else { TargetCenter = Vector3.zero; } Cam.fieldOfView = settings.Fov; Vector3 position = transform.position; Vector3 rotation = Cam.transform.localEulerAngles; if (Input.GetMouseButtonDown(0) && !eventSystem.IsPointerOverGameObject()) { StartKeyframe(); controlOn = true; controlTime = 0; } if (Input.GetMouseButton(0) && controlOn) { controlTime += Time.deltaTime; position -= Input.GetAxis("Mouse X") * settings.RotSpeed * transform.right; settings.SliderCamDist.value -= Input.mouseScrollDelta.y * settings.ZoomSpeed; settings.SliderCamHeight.value -= Input.GetAxis("Mouse Y") * settings.RotSpeed; } else if (controlOn) { controlOn = false; if (controlTime > 0.2f) { context.ForceSetKeyframe(); EndKeyframe(); } } if (Input.GetMouseButtonDown(2) && !eventSystem.IsPointerOverGameObject()) { StartKeyframe(); CameraTargetHelper.SetActive(true); controlTime = 0; } if (Input.GetMouseButton(2) && CameraTargetHelper.activeSelf) { controlTime += Time.deltaTime; settings.SliderTargetHeight.value -= Input.GetAxis("Mouse Y"); CameraTargetHelper.transform.position = settings.SliderTargetHeight.value * Vector3.up; } if (CameraTargetHelper.activeSelf && Input.GetMouseButtonUp(2)) { CameraTargetHelper.SetActive(false); if (controlTime > 0.2f) { context.ForceSetKeyframe(); EndKeyframe(); } } float camDist = settings.CamDist; settings.SliderCamHeight.maxValue = camDist + 1 - camDist * 0.2f; settings.SliderCamHeight.minValue = -camDist + 1 + camDist * 0.2f; settings.SliderCamHeight.value += y * settings.RotSpeed; Vector3 target = TargetCenter + settings.TargetHeight * Vector3.up; //set target offsets position.y = TargetCenter.y + settings.CamHeight; //set camera height transform.position = position; //set final position of camera at target transform.position += (x * transform.right) * settings.RotSpeed; //Debug.Log(rotation); transform.LookAt(target); //look at target position Cam.transform.localEulerAngles = settings.CamAngle * Vector3.forward; transform.position = target - transform.forward * camDist; //move away from target lookRotation = transform.localEulerAngles; } } /// /// Free Camera, Unity-Style /// void FreeCamera() { var settings = _settings; ; //Debug.Log("1 " + lookRotation); //Debug.Log("2 " + transform.localEulerAngles); //Debug.Log("3 " + transform.eulerAngles); Cam.fieldOfView = settings.Fov; float moveSpeed = settings.MovSpeed; float rotateSpeed = settings.RotSpeed; if (Input.GetMouseButtonDown(0) && !eventSystem.IsPointerOverGameObject()) { StartKeyframe(); lookRotation = transform.localEulerAngles; FreeCamLeft = true; controlTime = 0; } if (Input.GetMouseButton(0) && FreeCamLeft) { controlTime += Time.deltaTime; transform.position += Input.GetAxis("Vertical") * transform.forward * Time.deltaTime * moveSpeed; transform.position += Input.GetAxis("Horizontal") * transform.right * Time.deltaTime * moveSpeed; lookRotation.x -= Input.GetAxis("Mouse Y") * rotateSpeed; lookRotation.y += Input.GetAxis("Mouse X") * rotateSpeed; lookRotation.x = Mathf.Clamp(lookRotation.x, -90, 90); if (lookRotation.y >= 360) lookRotation.y -= 360; if (lookRotation.y <= -360) lookRotation.y += 360; //x (up down) y (left right) changes transform.localRotation = Quaternion.Euler(lookRotation.x, lookRotation.y, lookRotation.z); } else if (FreeCamLeft) { FreeCamLeft = false; if (controlTime > 0.2f) { ModelViewerMain.GetInstance().GetCameraHandler().SetKeyframe(); EndKeyframe(); } } if (Input.GetMouseButtonDown(1) && !eventSystem.IsPointerOverGameObject()) { StartKeyframe(); FreeCamRight = true; controlTime = 0; } if (Input.GetMouseButton(1) && FreeCamRight) { controlTime += Time.deltaTime; transform.position += Input.GetAxis("Mouse X") * transform.right * Time.deltaTime * moveSpeed; transform.position += Input.GetAxis("Mouse Y") * transform.up * Time.deltaTime * moveSpeed; } else if (FreeCamRight) { FreeCamRight = false; if (controlTime > 0.2f) { ModelViewerMain.GetInstance().GetCameraHandler().SetKeyframe(); EndKeyframe(); } } Cam.transform.localEulerAngles = settings.CamAngle * Vector3.forward; } #endregion #region Light /// /// Rotate Light Source /// private void OrbitLight() { if (Input.GetMouseButton(1) && !LightLock) { Light.transform.Rotate(Input.GetAxis("Mouse X") * Vector3.up, Space.Self); Light.transform.Rotate(Input.GetAxis("Mouse Y") * Vector3.right, Space.Self); } } public void SetLightColor(Color color) { Light.GetComponent().color = color; } public void SetLightIntensity(float value) { Light.GetComponent().intensity = value; } public void SetLightShadowIntensity(float value) { Light.GetComponent().shadowStrength = value; } public void SetLightShadows(int value) { Light.GetComponent().shadows = (LightShadows)value; } #endregion private void StartKeyframe() { var cam = ModelViewerMain.GetInstance().GetCameraHandler(); if (cam == ModelViewerMain.GetInstance().WorkCameraOrbit) { _tempCommand = null; return; } _tempCommand = new CameraTransformCommand() { Container = cam, OldValues = cam.SerializeFrame() as KeyframeDataCamera, Frame = TimelineController.Instance.CurrentFrame }; } private void EndKeyframe() { if (_tempCommand != null ) { _tempCommand.NewValues = _tempCommand.Container.SerializeFrame() as KeyframeDataCamera; UndoRedoManager.Insert(_tempCommand); } } }