UniversalViewer/Assets/Scripts/ModelViewerBase/CameraOrbit.cs

292 lines
9.2 KiB
C#
Raw Permalink Normal View History

2024-04-21 22:38:26 +08:00
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<Camera>();
eventSystem = EventSystem.current;
return this;
}
void Update()
{
if (ModelViewerMain.GetInstance() == null) return;
UpdateImmediate();
}
public void UpdateImmediate(bool forceUpdate = false)
2024-04-21 22:38:26 +08:00
{
if(!forceUpdate)
{
if (HandleManager.InteractionInProgress || _settings.CameraLock) return;
}
2024-04-21 22:38:26 +08:00
switch (_settings.CameraMode)
{
case 0:
OrbitAround();
OrbitLight();
break;
case 1:
OrbitAround(true);
OrbitLight();
break;
case 2: FreeCamera(); break;
}
}
#region Camera
/// <summary>
/// Orbit camera around world center
/// </summary>
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;
}
}
/// <summary>
/// Free Camera, Unity-Style
/// </summary>
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
/// <summary>
/// Rotate Light Source
/// </summary>
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<Light>().color = color;
}
public void SetLightIntensity(float value)
{
Light.GetComponent<Light>().intensity = value;
}
public void SetLightShadowIntensity(float value)
{
Light.GetComponent<Light>().shadowStrength = value;
}
public void SetLightShadows(int value)
{
Light.GetComponent<Light>().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);
}
}
}