I’m creating a 3D model previewer. I have the camera orbiting as I want around the model, and I have a zoom function I’m working on.
Initially the script rotated the object on the screen, but I’m now rotating the camera around Vector3.zero as this gives a better experience.
The zooming functionality is a smooth movement, hence the additional logic in zoom.
The problem I’m having is thus:
If I start the scene, when I click & drag the mouse, I orbit around the model (located at 0,0,0). It works how I expect.
I then mouse scroll wheel in/out, and the zoom works exactly how I expect.
If I now rotate the camera by using mouse click & drag, the camera rotates around the camera’s transform.position, NOT Vector3.zero, as I’ve scripted.
Input welcome, here is the full logic:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class PreviewHandler : MonoBehaviour {
public GameObject mainLight;
[SerializeField]
public List<GameObject> modelPrefabs;
[Range(0.0f, 20.0f)]
public float maximumZoom = 8.0f;
[Range(0.0f, 50.0f)]
public float zoomSpeed = 8.0f;
[Range(0.0f, 10.0f)]
public float zoomSmooth = 2.0f;
[SerializeField]
public List<Material> skySpheres;
[SerializeField]
public List<Cubemap> skyMaps;
int currentSphere = 0;
public float speed = 0.2f;
GameObject activeModel;
GameObject mainCamera;
Vector3 cameraStart;
private float startTime;
private float journeyLength = 0f;
private Vector3 startPos = Vector3.zero;
private Vector3 endPos = Vector3.zero;
Transform camTransform;
public float panSpeed = 0.5f;
float originalZoom;
float zoomDistanceRatio;
void Start(){
originalZoom = zoomSpeed;
mainCamera = GameObject.FindGameObjectWithTag("MainCamera");
camTransform = mainCamera.transform;
cameraStart = camTransform.position;
LoadModel(0);
camTransform.LookAt (Vector3.zero);
zoomDistanceRatio = 1f / Vector3.Distance(Vector3.zero, camTransform.position) ;
startPos = camTransform.position ;
endPos = camTransform.position ;
}
void ResetCamera(){
camTransform.position = cameraStart;
camTransform.LookAt (Vector3.zero);
activeModel.transform.position = new Vector3(0f,0f,0f);
activeModel.transform.rotation = Quaternion.Euler(0f,0f,0f);
Debug.Log("Reset "+originalZoom + " " +zoomSpeed);
zoomSpeed = originalZoom;
startPos = mainCamera.transform.position ;
endPos = mainCamera.transform.position ;
}
void Update () {
if (Input.GetMouseButton (0)) {
float x = (Input.GetAxis ("Mouse Y") * speed * Time.deltaTime);
float y = - (Input.GetAxis ("Mouse X") * speed * Time.deltaTime);
camTransform.RotateAround( new Vector3(0,0,0) , Vector3.up, -y);
camTransform.RotateAround( new Vector3(0,0,0) , camTransform.right, -x);
}
float scroll = Input.GetAxis("Mouse ScrollWheel");
if(scroll != 0f){
float moveDelta = scroll * zoomSpeed;
startPos = camTransform.position;
endPos = camTransform.position + (camTransform.forward * moveDelta);
startTime = Time.time;
journeyLength = Vector3.Distance(startPos, endPos);
if (endPos.z > 0f) {
startPos = camTransform.position ;
endPos = camTransform.position ;
}
}
if(endPos != Vector3.zero){
float distCovered = (Time.time - startTime) * zoomSmooth;
float fracJourney = journeyLength != 0 ? distCovered / journeyLength : 0f;
camTransform.position = Vector3.Lerp(camTransform.position, endPos, fracJourney);
float zoomDist = Vector3.Distance(cameraStart,camTransform.position);
if(camTransform.position != endPos){
if( camTransform.position.z > cameraStart.z ){
float newZoom = originalZoom * ( 1 - (zoomDistanceRatio * zoomDist));
if (newZoom > 1) {
zoomSpeed = newZoom;
}
}
}
}
if (Input.GetKeyDown (KeyCode.F)) {
ResetCamera ();
}
}
public void LoadModel(int modelIndex){
if(modelIndex > modelPrefabs.Count ){
return;
}else if(modelIndex < 0 ){
return;
}else if(modelPrefabs.Count == 0){
return;
}else{
foreach(GameObject model in modelPrefabs){
if(model == modelPrefabs[modelIndex]){
activeModel = model;
model.SetActive(true);
model.transform.position = new Vector3(0f,0f,0f);
model.transform.rotation = Quaternion.Euler(0f,0f,0f);
}else{
model.SetActive(false);
}
}
}
ResetCamera ();
}
}