Dear all, I try to figure out one of my user interface for my project. I would like to use mouse to : 1. orbit - with mouse movement 2. zoom - with mouse scroll 3. pan - with mouse click-drag It's like Sketch-Up -UI if you familiar with. After combine some scripts in this forum, no.1 and 2 has been solved. No.3 always failed. Anyone has this experience? Any help is greatly appreciated. Thank you.
Something like: Code (csharp): var moveSpeed : float = .5; function Update () { if (Input.GetMouseButton(0)) { transform.Translate(Vector3.right * -Input.GetAxis("Mouse X") * moveSpeed); transform.Translate(transform.up * -Input.GetAxis("Mouse Y") * moveSpeed, Space.World); } } --Eric
Thanks Erich, But it still doesn't work. It seems that mouse movement and click_drag movement have the same effect : orbit movement. I want to disable click_drag from orbital movement. Is it possible?
Sure; you'd want to check for a mouse click and only allow the orbit code if there isn't one, probably like: Code (csharp): if (Input.GetMouseButton(0)) { // Pan code here } else { // Orbit code here } --Eric
Thanks again, this is the script : (sorry, it might look mess, but it works - at least, orbit and zoom) Code (csharp): var target : Transform; var distance = 10.0; var xSpeed = 250.0; var ySpeed = 120.0; var yMinLimit = -20; var yMaxLimit = 80; var zoomRate = 2; var moveSpeed : float = 1; private var x = 0.0; private var y = 0.0; @script AddComponentMenu("Camera-Control/Mouse Orbit") function Start () { var angles = transform.eulerAngles; x = angles.y; y = angles.x; } function LateUpdate () { if (!Input.GetMouseButton(0)){ if (target) { x += Input.GetAxis("Mouse X") * xSpeed * 0.02; y -= Input.GetAxis("Mouse Y") * ySpeed * 0.02; distance += -(Input.GetAxis("Mouse ScrollWheel") * Time.deltaTime) * zoomRate * Mathf.Abs(distance); y = ClampAngle(y, yMinLimit, yMaxLimit); var rotation = Quaternion.Euler(y, x, 0); var position = rotation * Vector3(0.0, 0.0, -distance) + target.position; transform.rotation = rotation; transform.position = position; } } } function Update () { if (Input.GetMouseButton(0)) { transform.Translate(Vector3.right * -Input.GetAxis("Mouse X") * moveSpeed); transform.Translate(transform.up * -Input.GetAxis("Mouse Y") * moveSpeed, Space.World); } } static function ClampAngle (angle : float, min : float, max : float) { if (angle < -360) angle += 360; if (angle > 360) angle -= 360; return Mathf.Clamp (angle, min, max); }
Yeah, the orbit code is setting the position explicitly, so as soon as you let up on the mouse button and the orbit code takes over, it just puts everything back again. Probably the easiest thing to do at this point is to make two separate objects. First, remove the "var moveSpeed" line and the Update function from the script you posted. Replace the LateUpdate function with this: Code (csharp): var mover : Transform; function LateUpdate () { if (!target) {return;} if (!Input.GetMouseButton(0)) { x += Input.GetAxis("Mouse X") * xSpeed * 0.02; y -= Input.GetAxis("Mouse Y") * ySpeed * 0.02; } distance += -Input.GetAxis("Mouse ScrollWheel") * zoomRate * Mathf.Abs(distance); y = ClampAngle(y, yMinLimit, yMaxLimit); var rotation = Quaternion.Euler(y, x, 0); var position = rotation * Vector3(0.0, 0.0, -distance) + target.position; transform.rotation = rotation; transform.position = position + mover.position; } Make a new empty GameObject in the scene, and call it Mover (or something). Make sure it's at position 0,0,0. Add this script to it: Code (csharp): var moveSpeed : float = 1; var cam : Transform; function Update () { if (Input.GetMouseButton(0)) { transform.rotation = cam.rotation; transform.Translate(Vector3.right * -Input.GetAxis("Mouse X") * moveSpeed); transform.Translate(transform.up * -Input.GetAxis("Mouse Y") * moveSpeed, Space.World); } } In the Inspector for the camera, drag the Mover object onto the Mover slot in your new script. In the Inspector for the Mover object, drag the camera onto the Cam slot in the script. That should do it. (I took out the * Time.deltaTime for the mousewheel code, because mouse axes, like movement and the wheel, are already framerate-independent, since they depend on how fast you move them. So multiplying by Time.deltaTime actually makes them framerate-dependent, ironically. Therefore you might need to adjust the ZoomRate variable.) --Eric
Thank you Erich, It works like a charm. Just want to know, what is the difference between : Code (csharp): if (!Input.GetMouseButton(0)) { and Code (csharp): if (Input.GetMouseButton(0)) { Again, thank you.
Sorry to bump this post. I'm having an issue with trying to rotate an object to the same y rotation as the camera. It seems to work for the first 180 degrees but starts to wander afterwards. Here's the edited code. Code (csharp): var target : Transform; var mover : Transform; var distance = 10.0; var xSpeed = 250.0; var ySpeed = 120.0; var yMinLimit = -20; var yMaxLimit = 80; var zoomRate = 2; var minZoom = 4; var maxZoom = 100; private var x = 0.0; private var y = 0.0; @script AddComponentMenu("Camera-Control/Mouse Orbit") function Start () { var angles = transform.eulerAngles; x = angles.y; y = angles.x; } function LateUpdate () { if (!target) {return;} if (Input.GetMouseButton(1)) { x += Input.GetAxis("Mouse X") * xSpeed * 0.02; y -= Input.GetAxis("Mouse Y") * ySpeed * 0.02; } distance += -Input.GetAxis("Mouse ScrollWheel") * zoomRate * Mathf.Abs(distance); distance = Mathf.Clamp(distance, minZoom, maxZoom); y = ClampAngle(y, yMinLimit, yMaxLimit); var rotation = Quaternion.Euler(y, x, 0); target.rotation.y = rotation.y; //<<THIS IS WHERE I'M HAVING A PROBLEM<< var position = rotation * Vector3(0.0, 0.0, -distance) + target.position; transform.rotation = rotation; transform.position = position + mover.position; } static function ClampAngle (angle : float, min : float, max : float) { if (angle < -360) angle += 360; if (angle > 360) angle -= 360; return Mathf.Clamp (angle, min, max); }
Hello, im using this particular script for one of my cameras where the player is looking at a map right below it, i would like to be able to give a rotation/orbit on the Y axis and what happens is when I do such thing and zoom in via the middle mouse button, i can not pan around because when i pan around backwards my camera also tranforms on the Y axis as well.. what to do ? or did i explain it correctly> thanks
aswinindra, could you post the 2 final script there? I am trying to get the pan to work. All the rest works. carl
hey guys, I tried using the corrected script mentioned in the beginning posts of this thread, but can't seem to get them to work. I'm orbiting fine, but I think that's b/c of the existing MouseOrbit script. I have a game object that I want to the player to be able to zoom, orbit, and pan about. Then I have the following: Parent - First Person Controller has: rigidbody, Mouse Orbit script Child - Main Camera has: the corrected camera script from Eric and aswinindra, with the Mover object in the Mover slot; no target object Child - Mover has: the Mover script, with the Main Camera in the Cam slot I cannot get my scroll wheel to produce any results. I'm very new at this, so please excuse my ignorance. I plan on studying javascript beginning tomorrow, but thought I'd give it an amateurish shot. Meena
Here's another version of a combined 'editor' type script modeled vaguely after the 3dsmax camera controls, taking parts from the Wow camera script at http://forum.unity3d.com/viewtopic.php?t=18073 and trimming out the collision detection Code (csharp): //In a file MaxCamera.cs using UnityEngine; using System.Collections; public class MaxCamera : MonoBehaviour { public Transform target; public Vector3 targetOffset; public float distance = 5.0f; public float maxDistance = 20; public float minDistance = .6f; public float xSpeed = 200.0f; public float ySpeed = 200.0f; public int yMinLimit = -80; public int yMaxLimit = 80; public int zoomRate = 40; public float panSpeed = 0.3f; public float zoomDampening = 5.0f; private float xDeg = 0.0f; private float yDeg = 0.0f; private float currentDistance; private float desiredDistance; void Start() { Vector3 angles = transform.eulerAngles; xDeg = angles.x; yDeg = angles.y; currentDistance = distance; desiredDistance = distance; } /** * Camera logic on LateUpdate to only update after all character movement logic has been handled. */ void LateUpdate() { // Don't do anything if target is not defined if (!target) return; // If Control and Alt and Middle button? ZOOM! if (Input.GetMouseButton(2) Input.GetKey(KeyCode.LeftAlt) Input.GetKey(KeyCode.LeftControl)) { desiredDistance -= Input.GetAxis("Mouse Y") * Time.deltaTime * zoomRate*0.125f * Mathf.Abs(desiredDistance); } // If middle mouse and left alt are selected? ORBIT else if (Input.GetMouseButton(2) Input.GetKey(KeyCode.LeftAlt)) { xDeg += Input.GetAxis("Mouse X") * xSpeed * 0.02f; yDeg -= Input.GetAxis("Mouse Y") * ySpeed * 0.02f; } // otherwise if middle mouse is selected, we pan by way of transforming the target in screenspace else if (Input.GetMouseButton(2)) { //grab the rotation of the camera target.rotation = transform.rotation; target.Translate(Vector3.right * -Input.GetAxis("Mouse X") * panSpeed); target.Translate(transform.up * -Input.GetAxis("Mouse Y") * panSpeed, Space.World); } // affect the desired Zoom distance if we roll the scrollwheel desiredDistance -= Input.GetAxis("Mouse ScrollWheel") * Time.deltaTime * zoomRate * Mathf.Abs(desiredDistance); //clamp the zoom min/max desiredDistance = Mathf.Clamp(desiredDistance, minDistance, maxDistance); //Clamp the vertical axis for the orbit yDeg = ClampAngle(yDeg, yMinLimit, yMaxLimit); // set camera rotation Quaternion rotation = Quaternion.Euler(yDeg, xDeg, 0); // For smoothing of the zoom, lerp distance currentDistance = Mathf.Lerp(currentDistance, desiredDistance, Time.deltaTime * zoomDampening); // keep within legal limits currentDistance = Mathf.Clamp(currentDistance, minDistance, maxDistance); // calculate position based on the new currentDistance Vector3 position = target.position - (rotation * Vector3.forward * currentDistance + targetOffset); transform.rotation = rotation; transform.position = position; } private static float ClampAngle(float angle, float min, float max) { if (angle < -360) angle += 360; if (angle > 360) angle -= 360; return Mathf.Clamp(angle, min, max); } }
Hi all, I've used a slight modification of the orbit/pan/zoom script posted by Eric5h5 and Aswinindra (using a Mover object as well) and am having some problems. In addition to using the mouse input buttons, I'd like to use GUI buttons to control the camera movements mentioned above (note - I've used the terms orbit and rotate interchangeably). The problem I'm having is twofold: 1. Each time I switch to a different GUI button, the camera goes back to it's starting position for that specific GUI button. So for example, if I start rotating the game object using its GUI button, and then switch to the GUI pan button, the camera movement repositions to its panning beginning coordinates. But then if I go back to "rotate/orbit," the camera repositions itself where it left off last within the rotate movement before a different GUI button was pressed. 2. If either the pan or the rotate GUI button is pressed, after I press the corresponding mouse button, the position of the camera changes slightly. My set up is similar to the posted scripts above, in that I've created a separate Mover game object with the following script attached to it: Code (csharp): var moveSpeed : float = 1; var cam : Transform; function Update () { //pan if (Input.GetMouseButton(1)) { transform.rotation = cam.rotation; transform.Translate(Vector3.right * -Input.GetAxis("Mouse X") * moveSpeed); transform.Translate(transform.up * -Input.GetAxis("Mouse Y") * moveSpeed, Space.World); } } and then the camera has this script attached to it: Code (csharp): var toolbarInt = 0; var toolbarStrings : String[] = ["Select","Rotate", "Zoom", "Pan"]; function OnGUI () { toolbarInt = GUI.Toolbar (Rect (20, 165, 180, 30), toolbarInt, toolbarStrings); } var target : Transform; var distance = 10.0; var xSpeed = 250.0; var ySpeed = 120.0; var yMinLimit = -20; var yMaxLimit = 80; var zoomRate = 2; private var x = 0.0; private var y = 0.0; @script AddComponentMenu("Camera-Control/Mouse Orbit") function Start () { var angles = transform.eulerAngles; x = angles.y; y = angles.x; if (rigidbody) rigidbody.freezeRotation = true; } var mover : Transform; function LateUpdate () { if (toolbarStrings[toolbarInt] == "Select") {return;} if (toolbarStrings[toolbarInt] == "Rotate" Input.GetMouseButton(0)) { x += Input.GetAxis("Mouse X") * xSpeed * 0.02; y -= Input.GetAxis("Mouse Y") * ySpeed * 0.02; y = ClampAngle(y, yMinLimit, yMaxLimit); var rotation = Quaternion.Euler(y, x, 0); var position = rotation * Vector3(0.0, 0.0, -distance) + target.position; transform.rotation = rotation; transform.position = position; } if (toolbarStrings[toolbarInt] == "Zoom") { x += Input.GetAxis("Mouse X") * xSpeed * 0.02; y -= Input.GetAxis("Mouse Y") * ySpeed * 0.02; y = ClampAngle(y, yMinLimit, yMaxLimit); distance += -Input.GetAxis("Mouse ScrollWheel") * zoomRate * Mathf.Abs(distance); position = rotation * Vector3(0.0, 0.0, -distance) + target.position; transform.rotation = rotation; transform.position = position; } if (toolbarStrings[toolbarInt] == "Pan" Input.GetMouseButton(1)) { x += Input.GetAxis("Mouse X") * xSpeed * 0.02; y -= Input.GetAxis("Mouse Y") * ySpeed * 0.02; y = ClampAngle(y, yMinLimit, yMaxLimit); position = rotation * Vector3(0.0, 0.0, -distance) + target.position; transform.rotation = rotation; transform.position = position + mover.position; } } static function ClampAngle (angle : float, min : float, max : float) { if (angle < -360) angle += 360; if (angle > 360) angle -= 360; return Mathf.Clamp (angle, min, max); } I would love it if somebody could help me or even guide me in a certain direction, but if you can't I understand... thanks so much in advance.
Dont have much time to debug yours quite yet, but i had updated my version for a similar effect a while back and maybe it could help you. On second read, no.. it wont actually for you, but i like where you are going! Primary differences from previous posted version are: moved all the initializing of the variables to an "Init" function that is called anytime the script is enabled this gets rid of the jump when switching between orbit and another script.. also added an option to automatically create the target if there isn't one supplied in the unity interface (Ex: Change views could be something like, disable maxcamera, delete temporary target (Maybe this should be in an OnDisable()), translate your camera, enable maxcamera) Code (csharp): using UnityEngine; using System.Collections; [AddComponentMenu("Camera-Control/3dsMax Camera Style")] public class maxCamera : MonoBehaviour { public Transform target; public Vector3 targetOffset; public float distance = 5.0f; public float maxDistance = 20; public float minDistance = .6f; public float xSpeed = 200.0f; public float ySpeed = 200.0f; public int yMinLimit = -80; public int yMaxLimit = 80; public int zoomRate = 40; public float panSpeed = 0.3f; public float zoomDampening = 5.0f; private float xDeg = 0.0f; private float yDeg = 0.0f; private float currentDistance; private float desiredDistance; private Quaternion currentRotation; private Quaternion desiredRotation; private Quaternion rotation; private Vector3 position; void Start() { Init(); } void OnEnable() { Init(); } public void Init() { //If there is no target, create a temporary target at 'distance' from the cameras current viewpoint if (!target) { GameObject go = new GameObject("Cam Target"); go.transform.position = transform.position + (transform.forward * distance); target = go.transform; } distance = Vector3.Distance(transform.position, target.position); currentDistance = distance; desiredDistance = distance; //be sure to grab the current rotations as starting points. position = transform.position; rotation = transform.rotation; currentRotation = transform.rotation; desiredRotation = transform.rotation; xDeg = Vector3.Angle(Vector3.right, transform.right ); yDeg = Vector3.Angle(Vector3.up, transform.up ); } /* * Camera logic on LateUpdate to only update after all character movement logic has been handled. */ void LateUpdate() { // If Control and Alt and Middle button? ZOOM! if (Input.GetMouseButton(2) Input.GetKey(KeyCode.LeftAlt) Input.GetKey(KeyCode.LeftControl)) { desiredDistance -= Input.GetAxis("Mouse Y") * Time.deltaTime * zoomRate*0.125f * Mathf.Abs(desiredDistance); } // If middle mouse and left alt are selected? ORBIT else if (Input.GetMouseButton(2) Input.GetKey(KeyCode.LeftAlt)) { xDeg += Input.GetAxis("Mouse X") * xSpeed * 0.02f; yDeg -= Input.GetAxis("Mouse Y") * ySpeed * 0.02f; ////////OrbitAngle //Clamp the vertical axis for the orbit yDeg = ClampAngle(yDeg, yMinLimit, yMaxLimit); // set camera rotation desiredRotation = Quaternion.Euler(yDeg, xDeg, 0); currentRotation = transform.rotation; rotation = Quaternion.Lerp(currentRotation, desiredRotation, Time.deltaTime * zoomDampening); transform.rotation = rotation; } // otherwise if middle mouse is selected, we pan by way of transforming the target in screenspace else if (Input.GetMouseButton(2)) { //grab the rotation of the camera so we can move in a psuedo local XY space target.rotation = transform.rotation; target.Translate(Vector3.right * -Input.GetAxis("Mouse X") * panSpeed); target.Translate(transform.up * -Input.GetAxis("Mouse Y") * panSpeed, Space.World); } ////////Orbit Position // affect the desired Zoom distance if we roll the scrollwheel desiredDistance -= Input.GetAxis("Mouse ScrollWheel") * Time.deltaTime * zoomRate * Mathf.Abs(desiredDistance); //clamp the zoom min/max desiredDistance = Mathf.Clamp(desiredDistance, minDistance, maxDistance); // For smoothing of the zoom, lerp distance currentDistance = Mathf.Lerp(currentDistance, desiredDistance, Time.deltaTime * zoomDampening); // calculate position based on the new currentDistance position = target.position - (rotation * Vector3.forward * currentDistance + targetOffset); transform.position = position; } private static float ClampAngle(float angle, float min, float max) { if (angle < -360) angle += 360; if (angle > 360) angle -= 360; return Mathf.Clamp(angle, min, max); } } It doesn't feel quite perfect yet, i think i may adjust the mouse wheel zoom to move/dolly the target object when the desired distance gets near the minimum.. instead of shrinking the desired distance you end up with a finite ability to zoom in. Another thought or potential upgrade might be to build the initial orbit target by raycasting into the scene, and if there is a hit, use that depth to place the auto generated target that said, so far i like it better than any other publicly available one please, lets tweak it up some more!
Hi, Panning functionality in this script does not work when i try it. I attached the script at http://www.unifycommunity.com/wiki/index.php?title=MouseOrbitZoom, which is the same as the one above, to my MainCamera and set the target to a simple Cube object. When trying to pan, the cube object is rotated once to match the rotation of the camera, but there is no visual padding. I changed the padding speed, but no noticeable effect... Any ideas about what i am doing wrong? Any help? Thank you in advance!
Thanks for posting your original script aswinindra, and for your contribution to it Eric5h5. I'm really just a beginner with coding and just figured out how to do something on my own (that worked, haha) for the first time...and just had to share it! I wanted to be able to limit the amount the player could zoom out. I had a theory the following addition might do it: if(distance > 5) distance = 5; After first inserting it where I thought seemed a reasonable place I got an error. It seemed logical to me however, and I decided to at least try changing its location in the script. The following was the third spot I tried (and it worked!!!). It's really a great feeling to have one's thinking one is beginning to understand confirmed :~). var target : Transform; var distance = 5.0; var xSpeed = 250.0; var ySpeed = 120.0; var yMinLimit = -20; var yMaxLimit = 80; var zoomRate = 2; var moveSpeed : float = 1; private var x = 0.0; private var y = 0.0; @script AddComponentMenu("Camera-Control/Mouse Orbit") function Start () { var angles = transform.eulerAngles; x = angles.y; y = angles.x; } function LateUpdate () { if (!Input.GetMouseButton(0)){ if (target) { x += Input.GetAxis("Mouse X") * xSpeed * 0.02; y -= Input.GetAxis("Mouse Y") * ySpeed * 0.02; distance += -(Input.GetAxis("Mouse ScrollWheel") * Time.deltaTime) * zoomRate * Mathf.Abs(distance); y = ClampAngle(y, yMinLimit, yMaxLimit); var rotation = Quaternion.Euler(y, x, 0); var position = rotation * Vector3(0.0, 0.0, -distance) + target.position; transform.rotation = rotation; transform.position = position; if(distance > 5) distance = 5; } } } function Update () { if (Input.GetMouseButton(0)) { transform.Translate(Vector3.right * -Input.GetAxis("Mouse X") * moveSpeed); transform.Translate(transform.up * -Input.GetAxis("Mouse Y") * moveSpeed, Space.World); } } static function ClampAngle (angle : float, min : float, max : float) { if (angle < -360) angle += 360; if (angle > 360) angle -= 360; return Mathf.Clamp (angle, min, max); }
Hi, I am trying to modify this Camera to allow for "roll" on the Z Axis. I have tried a few things and they are not working. Does anyone have a suggestion? Thanks, Fred
An easy way to isolate one axis in a camera script is to put the camera inside an empty parent object. In your case, you could use the parent for the main rotation, but then use the camera's local rotation inside the empty object to isolate the Z axis.
@Andeeee Thanks for the reply and idea. I was heading down a different path and ran into an odd issue. The "Roll" portion of my script, CenterMouse + Left Control, is not Working when I Build+Run the app. It works in the editor when I preview the app. Here is my modified version. Thanks, Fred Code (csharp): using UnityEngine; using System.Collections; [AddComponentMenu("Camera-Control/3dsMax Camera Style")] public class maxCamera : MonoBehaviour { public Transform target; public Vector3 targetOffset; public float distance = 5.0f; public float maxDistance = 40; public float minDistance = 1.0f; public float xSpeed = 200.0f; public float ySpeed = 200.0f; public float zSpeed = 200.0f; public int yMinLimit = -90; public int yMaxLimit = 90; public int zoomRate = 40; public float panSpeed = 0.3f; public float zoomDampening = 5.0f; private float xDeg = 0.0f; private float yDeg = 0.0f; private float zDeg = 0.0f; private float currentDistance; private float desiredDistance; private Quaternion currentRotation; private Quaternion desiredRotation; private Quaternion rotation; private Vector3 position; void Start() { Init(); } void OnEnable() { Init(); } public void Init() { //If there is no target, create a temporary target at 'distance' from the cameras current viewpoint if (!target) { GameObject go = new GameObject("Cam Target"); go.transform.position = transform.position + (transform.forward * distance); target = go.transform; } distance = Vector3.Distance(transform.position, target.position); currentDistance = distance; desiredDistance = distance; //be sure to grab the current rotations as starting points. position = transform.position; rotation = transform.rotation; currentRotation = transform.rotation; desiredRotation = transform.rotation; xDeg = Vector3.Angle(Vector3.right, transform.right ); yDeg = Vector3.Angle(Vector3.up, transform.up ); //zDeg = Vector3.Angle(Vector3.forward, transform.forward ); } /* * Camera logic on LateUpdate to only update after all character movement logic has been handled. */ void LateUpdate() { // If Control and Alt and Middle button? ZOOM! if (Input.GetMouseButton(2) Input.GetKey(KeyCode.LeftAlt) Input.GetKey(KeyCode.LeftControl)) { desiredDistance -= Input.GetAxis("Mouse Y") * Time.deltaTime * zoomRate*0.125f * Mathf.Abs(desiredDistance); } // If middle mouse and left alt are selected? ORBIT else if (Input.GetMouseButton(2) Input.GetKey(KeyCode.LeftAlt)) { xDeg += Input.GetAxis("Mouse X") * xSpeed * 0.02f; yDeg -= Input.GetAxis("Mouse Y") * ySpeed * 0.02f; ////////OrbitAngle //Clamp the vertical axis for the orbit yDeg = ClampAngle(yDeg, yMinLimit, yMaxLimit); // set camera rotation desiredRotation = Quaternion.Euler(yDeg, xDeg, zDeg); currentRotation = transform.rotation; rotation = Quaternion.Lerp(currentRotation, desiredRotation, Time.deltaTime * zoomDampening); transform.rotation = rotation; } else if (Input.GetMouseButton(2) Input.GetKey(KeyCode.LeftControl)) { // this is where the roll will go. zDeg += Input.GetAxis("Mouse X") * zSpeed * 0.02f; desiredRotation = Quaternion.Euler(yDeg, xDeg, zDeg); currentRotation = transform.rotation; rotation = Quaternion.Lerp(currentRotation, desiredRotation, Time.deltaTime * zoomDampening); transform.rotation = rotation; } // otherwise if middle mouse is selected, we pan by way of transforming the target in screenspace else if (Input.GetMouseButton(2)) { //grab the rotation of the camera so we can move in a psuedo local XY space target.rotation = transform.rotation; target.Translate(Vector3.right * -Input.GetAxis("Mouse X") * panSpeed); target.Translate(transform.up * -Input.GetAxis("Mouse Y") * panSpeed, Space.World); } ////////Orbit Position // affect the desired Zoom distance if we roll the scrollwheel desiredDistance -= Input.GetAxis("Mouse ScrollWheel") * Time.deltaTime * zoomRate * Mathf.Abs(desiredDistance); //clamp the zoom min/max desiredDistance = Mathf.Clamp(desiredDistance, minDistance, maxDistance); // For smoothing of the zoom, lerp distance currentDistance = Mathf.Lerp(currentDistance, desiredDistance, Time.deltaTime * zoomDampening); // calculate position based on the new currentDistance position = target.position - (rotation * Vector3.forward * currentDistance + targetOffset); transform.position = position; } private static float ClampAngle(float angle, float min, float max) { if (angle < -360) angle += 360; if (angle > 360) angle -= 360; return Mathf.Clamp(angle, min, max); } }
this is my code so far: Code (csharp): // //Filename: maxCamera.cs // // original: [url]http://www.unifycommunity.com/wiki/index.php?title=MouseOrbitZoom[/url] // // --01-18-2010 - create temporary temp, if none supplied at start using UnityEngine; using System.Collections; [AddComponentMenu("Camera-Control/3dsMax Camera Style")] public class maxCamera_combined : MonoBehaviour { //Meine private bool tswitch = true; // Orbit public Transform target; // maxCamera public Transform temp; public Vector3 tempOffset; public float distance = 5.0f; public float maxDistance = 20; public float minDistance = .6f; public float xSpeed = 200.0f; public float ySpeed = 200.0f; public int yMinLimit = -80; public int yMaxLimit = 80; public int zoomRate = 40; public float panSpeed = 0.3f; public float zoomDampening = 5.0f; public float xDeg = 0.0f; public float yDeg = 0.0f; public float currentDistance; public float desiredDistance; private Quaternion currentRotation; private Quaternion desiredRotation; private Quaternion rotation; private Vector3 position; void Start() { Init(); } void OnEnable() { Init(); } public void Init() { //If there is no temp, create a temporary temp at 'distance' from the cameras current viewpoint if (!temp) { GameObject go = new GameObject("Cam temp"); go.transform.position = transform.position + (transform.forward * distance); temp = go.transform; } distance = Vector3.Distance(transform.position, temp.position); currentDistance = distance; desiredDistance = distance; //be sure to grab the current rotations as starting points. position = transform.position; rotation = transform.rotation; currentRotation = transform.rotation; desiredRotation = transform.rotation; xDeg = Vector3.Angle(Vector3.right, transform.right ); yDeg = Vector3.Angle(Vector3.up, transform.up ); } /* * Camera logic on LateUpdate to only update after all character movement logic has been handled. */ void LateUpdate() { if (Input.GetKeyDown("b")) { //LOCAL OFF tswitch = false; //Change camera position to target, BUT HOW???? } if (Input.GetKeyDown("v")) { tswitch = true; // Sets temp-position in front of cam temp.transform.position = transform.position + (transform.forward * desiredDistance); } if (tswitch) { // If Control and Alt and Middle button? ZOOM! if (Input.GetMouseButton(2) Input.GetKey(KeyCode.LeftAlt) Input.GetKey(KeyCode.LeftControl)) { desiredDistance -= Input.GetAxis("Mouse Y") * Time.deltaTime * zoomRate*0.125f * Mathf.Abs(desiredDistance); } // If middle mouse and left alt are selected? ORBIT else if (Input.GetMouseButton(2) Input.GetKey(KeyCode.LeftAlt)) { xDeg += Input.GetAxis("Mouse X") * xSpeed * 0.02f; yDeg -= Input.GetAxis("Mouse Y") * ySpeed * 0.02f; ////////OrbitAngle //Clamp the vertical axis for the orbit yDeg = ClampAngle(yDeg, yMinLimit, yMaxLimit); // set camera rotation desiredRotation = Quaternion.Euler(yDeg, xDeg, 0); currentRotation = transform.rotation; rotation = Quaternion.Lerp(currentRotation, desiredRotation, Time.deltaTime * zoomDampening); transform.rotation = rotation; } // otherwise if middle mouse is selected, we pan by way of transforming the temp in screenspace else if (Input.GetMouseButton(2)) { //grab the rotation of the camera so we can move in a psuedo local XY space temp.rotation = transform.rotation; temp.Translate(Vector3.right * -Input.GetAxis("Mouse X") * panSpeed); // these move temp temp.Translate(transform.up * -Input.GetAxis("Mouse Y") * panSpeed, Space.World); } ////////Orbit Position // affect the desired Zoom distance if we roll the scrollwheel desiredDistance -= Input.GetAxis("Mouse ScrollWheel") * Time.deltaTime * zoomRate * Mathf.Abs(desiredDistance); //clamp the zoom min/max desiredDistance = Mathf.Clamp(desiredDistance, minDistance, maxDistance); // For smoothing of the zoom, lerp distance currentDistance = Mathf.Lerp(currentDistance, desiredDistance, Time.deltaTime * zoomDampening); // calculate position based on the new currentDistance position = temp.position - (rotation * Vector3.forward * currentDistance + tempOffset); transform.position = position; } if (!tswitch) { xDeg += Input.GetAxis("Mouse X") * xSpeed * 0.02f; yDeg -= Input.GetAxis("Mouse Y") * ySpeed * 0.02f; yDeg = ClampAngle(yDeg, yMinLimit, yMaxLimit); desiredRotation = Quaternion.Euler(yDeg, xDeg, 0); //position = rotation * Vector3(0.0f, 0.0f, -distance) + target.position; currentRotation = transform.rotation; // if this is off, cam wiggles rotation = Quaternion.Lerp(currentRotation, desiredRotation, Time.deltaTime * zoomDampening); // affect the desired Zoom distance if we roll the scrollwheel desiredDistance -= Input.GetAxis("Mouse ScrollWheel") * Time.deltaTime * zoomRate * Mathf.Abs(desiredDistance); //clamp the zoom min/max desiredDistance = Mathf.Clamp(desiredDistance, minDistance, maxDistance); // For smoothing of the zoom, lerp distance currentDistance = Mathf.Lerp(currentDistance, desiredDistance, Time.deltaTime * zoomDampening); //Important for Zoom!!! position = target.position - (rotation * Vector3.forward * currentDistance); //PROBLEM at switch from V to B transform.rotation = rotation; transform.position = position; } } private static float ClampAngle(float angle, float min, float max) { if (angle < -360) angle += 360; if (angle > 360) angle -= 360; return Mathf.Clamp(angle, min, max); } } you have to switch between local-and global-mode via V and B. there are still two issues (or one??) left: 1. the cam changes its position 2. it doesnot stay at its position and changes its view (rotation) from 'temp' to 'target' maybe anyone can help?
Hello, I use the same script (found here), but the pan doesn't work. Something is wrong, but I don't know what. Can you help me please ?
Hello, guys, I was trying to make this code work with touch but can't figure out yet, can you guys help me, Thanks in advance
I have created a video that shows how to use Unity script to orbit, pan and zoom the camera to the mouse position.