- Home /
Rotate Camera around Object
I've been searching for about two days to see if I could find a script for rotating freely around an object using androids touch events. While I've found and implemented quite a few of those solutions, nothing is meeting my needs 100%. This is actually my first Unity project as well as my first 3D project, so this may be something easy but at the moment the solution is escaping me.
If you do a search for orbit camera, or rotate camera about and object, there are a ton of examples, most of the solutions allow you to rotate around x and y (which I've got working successfully) however, I've found if you rotate the camera such that the y axis is point towards you (by swiping down), then you swipe left or right, the object spins around the y axis instead of spinning around what the screen would see as up (I think that would be z in this scenario). I'm sure this is a bit confusing so I attached my code and I can also add screenshots if that would be more clear.
This might have some dead code in it because I've been testing so many things out but the meat of what I'm trying to do can be found in the 'RotateCamera' method.
Any pointers would be appreciated tremendously.
#pragma strict
public class MainCamera extends MonoBehaviour {
// the number of degrees the camera should rotate if the user swipes
// the entire length of the screen
private static var FULLSCREEN_SWIPE_ROTATION = 180;
// capture first touch events starting position
private var startingTouchPosition : Vector2;
private var startingTouchPercent : Vector2;
// save the position and rotation so we can calculate how much the camera
// should move when the user tries to rotate their view
private var startingCameraPosition : Vector3;
private var startingCameraRotation : Quaternion;
public var target : Transform;
public var distance : float = 0f;
public var xSpeed : float = 100.0f;
public var ySpeed : float = 100.0f;
public var yMinLimit : int = -180;
public var yMaxLimit : int = 180;
public var zoomRate : int = 40;
public var panSpeed : float = 0.3f;
public var zoomDampening : float = 5.0f;
private var xDeg : float = 0.0f;
private var yDeg : float = 0.0f;
private var currentDistance : float = 2;
private var desiredDistance : float;
private var currentRotation : Quaternion;
private var desiredRotation : Quaternion;
private var rotation : Quaternion;
private var position : Vector3;
public function Start() : void { Init(); }
public function OnEnable() : void { Init(); }
/**
* On game start initialize private members
*/
public function Init () {
//If there is no target, create a temporary target at 'distance' from the cameras current viewpoint
var go : GameObject = new GameObject.Find("Terminus");
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 );
}
/**
* On game update
*/
public function LateUpdate () {
HandleTouchEvents();
}
/**
* If there are touch events filter to appropriate methods
* based on number, frequency, and change in position
*/
private function HandleTouchEvents() {
// return if there are no touch events
if (!Input.touchCount) return;
// rotate the camera if appropriate
RotateCamera();
}
private function RotateCamera() {
if (!Input.touchCount) return;
xDeg += Input.GetTouch(0).deltaPosition.x * xSpeed * 0.05f;
yDeg -= Input.GetTouch(0).deltaPosition.y * ySpeed * 0.05f;
////////OrbitAngle
// set camera rotation
desiredRotation = Quaternion.Euler(yDeg, xDeg, 0);
currentRotation = transform.rotation;
rotation = Quaternion.Lerp(currentRotation, desiredRotation, Time.deltaTime * zoomDampening);
transform.rotation = rotation;
////////Orbit Position
// 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);
transform.position = position;
}
/**
* Captures the cameras position and rotation so
* we can easily calculate how much change the view should
* change over time
*/
private function SaveStartingOrientation(firstTouch : Touch) {
startingCameraPosition = transform.position;
startingCameraRotation = transform.rotation;
startingTouchPosition = firstTouch.position;
startingTouchPercent = GetTouchLocationPercentage(firstTouch);
Debug.Log(startingTouchPercent);
}
/**
* Calculates the location of the touch event as a percentage of the screen's
* total width and height. Top Left as (0.0,0.0) Bottom Right as (1.0,1.0);
*
* @returns a Vector2 where
* x percentage representing the location of the press relative to the screen width
* y percentage representing the location of the press relative to the screen height
*/
private function GetTouchLocationPercentage(touch : Touch) : Vector2 {
return new Vector2(
Mathf.Clamp01(touch.position.x / Screen.width),
Mathf.Clamp01((Screen.height - touch.position.y) / Screen.height));
}
private 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);
}
}
Can you describe your ideal behavior for this code? If it was working right, how would it behave.
is for control the camera whit the finger on a touch screen, like a rpg game.
how to change camera's default position ? i want camera behind my player at starting position(default position). plz answer me soon.
Answer by KhShani · Mar 14, 2014 at 01:32 PM
using UnityEngine;
using System.Collections;
[AddComponentMenu("Camera-Control/Mouse Orbit with zoom")]
public class CarSelectionCameraMovement : MonoBehaviour
{
public Transform target;
public float distance = 5.0f;
public float xSpeed = 60.0f;
public float ySpeed = 60.0f;
public float yMinLimit = 10f;
public float yMaxLimit = 60f;
public float distanceMin = 5f;
public float distanceMax = 10f;
float x = 0.0f;
float y = 0.0f;
void Start()
{
Vector3 angles = transform.eulerAngles;
x = angles.y;
y = angles.x;
// Make the rigid body not change rotation
if (rigidbody)
rigidbody.freezeRotation = true;
}
void Update()
{
if (target && Input.touchCount == 1 && Input.GetTouch(0).position.x > Screen.width / 2 && Input.GetTouch(0).phase == TouchPhase.Moved) //Just orbit touch without movement
{
Debug.Log("Orbiting! 1 touch");
Orbit(Input.GetTouch(0));
}
else if (Input.touchCount == 2)
{
if (Input.GetTouch(0).position.x > Screen.width / 2 && Input.GetTouch(0).phase == TouchPhase.Moved)
Orbit(Input.GetTouch(0)); //Movement was touched second
else if (Input.GetTouch(1).position.x > Screen.width / 2 && Input.GetTouch(1).phase == TouchPhase.Moved)
Orbit(Input.GetTouch(1)); //Movement was touched first
}
}
void Orbit(Touch touch)
{
x += touch.deltaPosition.x * xSpeed * 0.02f /* * distance*/;
y -= touch.deltaPosition.y * ySpeed * 0.02f /* * distance*/;
y = ClampAngle(y, yMinLimit, yMaxLimit);
Quaternion rotation = Quaternion.Euler(y, x, 0);
//distance = Mathf.Clamp(distance - Input.GetAxis("Mouse ScrollWheel") * 5, distanceMin, distanceMax);
RaycastHit hit;
if (Physics.Linecast(target.position, transform.position, out hit))
{
// distance -= hit.distance;
}
Vector3 negDistance = new Vector3(0.0f, 0.0f, -distance);
Vector3 position = rotation * negDistance + target.position;
transform.rotation = rotation;
transform.position = position;
}
public static float ClampAngle(float angle, float min, float max)
{
if (angle < -360F)
angle += 360F;
if (angle > 360F)
angle -= 360F;
return Mathf.Clamp(angle, min, max);
}
}
Your answer
Follow this Question
Related Questions
Rotate Camera around object with touch 0 Answers
Help with camera movement using mobile input 0 Answers
How do I rotate an object on one axis to face android touch? 0 Answers
Need to rotate a 3rd person object to the camera rotation 1 Answer
Camera to rotate around object as well as follow it at the same time. 3 Answers