Hello,
in my current iPhone project, I need to move the camera on a “circle path”. Let me try to make this more clear. The camera needs to be focused on a certain object and I want to view this object from different angles. All these angles lie on an imaginary circle, which surrounds this object. You can easily compare it to the unity editor camera. If you select an object, you can rotate the camera around this object and view it from different angles. I want to do the exact same thing in my unity game.
In theory, its a combination of rotating and moving the camera at the same time. The “only” problem I’m having right now, is to come up with a function, that moves and rotates the camera on a perfect circle path, so it always stays focused on my desired game object.
Hope someone can point me into the right direction.
Thanks in advance.
Getting closer:
Just remembered something from school - thought I’d never need this “crap” again
Maybe someone can tell me, if the following is correct:
In theory, I need to define a center spot for my imaginary circle path. Then I need to use some math (there should be a formula) to calculate any spot on this circle, given a certain radius. This way I should be able to calculate every spot on the circle. Now, by moving the camera in a positive or negative direction on this path, it should rotate and move as expected, right?
Why not have your camera parented to an empty game object that serves as your focal point, with the camera pointed directly at it. Rotating this focal point object would have the camera orbit around it in a circle.
2 Likes
Hehe That sounds a lot easier Thanks. I’ll give it a try!
Darn…that was easy I’m affraid I’ll never gonna be a good coder, if I can’t stop thinking too complicated.
Hehe, glad that worked out for you. Don’t worry, it’s easy to overthink things. Sometimes even the “pros” in this industry try to build a ferrari when a bicycle would suffice.
I just did this a second ago, to debug some view angles:
function Update () {
transform.RotateAround (Vector3.zero, Vector3.up, 30 * Time.deltaTime);
}
That will rotate the camera around the world origin automatically, at 30 degrees per second.
If you want an interactive version, this script will rotate around a target (selected in the inspector) with pinching for zoom control. This is someone else’s code (I mashed pinch-zoom and iphone-orbit code together, can’t recall who should get the credit).
var target : Transform;
var distanceMin = 10.0;
var distanceMax = 15.0;
var distanceInitial = 12.5;
var scrollSpeed = 1.0;
var xSpeed = 250.0;
var ySpeed = 120.0;
var yMinLimit = -20;
var yMaxLimit = 80;
private var x = 0.0;
private var y = 0.0;
private var distanceCurrent = 0.0;
@script AddComponentMenu ("Camera-Control/Key Mouse Orbit")
function Start () {
calibrateAccelerometer();
var angles = transform.eulerAngles;
x = angles.y;
y = angles.x;
distanceCurrent = distanceInitial;
// Make the rigid body not change rotation
if (rigidbody)
rigidbody.freezeRotation = true;
}
function LateUpdate () {
if (target) {
x -= getAccelerometer(iPhoneInput.acceleration).y * xSpeed * Time.deltaTime;
y += getAccelerometer(iPhoneInput.acceleration).x * ySpeed * Time.deltaTime;
distanceCurrent -= Input.GetAxis("Mouse ScrollWheel") * scrollSpeed;
if (iPhoneInput.touchCount > 1) {
var touch : iPhoneTouch = iPhoneInput.GetTouch(0);
var touch2 : iPhoneTouch = iPhoneInput.GetTouch(1);
// Find out how the touches have moved relative to eachother:
var curDist: Vector2 = touch.position - touch2.position;
var prevDist : Vector2 = (touch.position - touch.positionDelta) - (touch2.position - touch2.positionDelta);
distanceCurrent -= (curDist.magnitude - prevDist.magnitude)/2;
}
distanceCurrent = Mathf.Clamp(distanceCurrent, distanceMin, distanceMax);
y = ClampAngle(y, yMinLimit, yMaxLimit);
var rotation = Quaternion.Euler(y, x, 0);
var position = rotation * Vector3(0.0, 0.0, -distanceCurrent) + target.position;
transform.rotation = rotation;
transform.position = position;
}
}
var calibrationMatrix : Matrix4x4;
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);
}
function calibrateAccelerometer(){
var wantedDeadZone : Vector3 = iPhoneInput.acceleration;
var rotateQuaternion : Quaternion = Quaternion.FromToRotation(new Vector3(0, 0, -1), wantedDeadZone);
//create identity matrix ... rotate our matrix to match up with down vec
var matrix : Matrix4x4 = Matrix4x4.TRS(Vector3.zero, rotateQuaternion, new Vector3(1, 1, 1));
//get the inverse of the matrix
this.calibrationMatrix = matrix.inverse;
}
//Whenever you need an accelerator value from the user
//call this function to get the 'calibrated' value
function getAccelerometer(accelerator : Vector3 ) : Vector3 {
var accel : Vector3 = this.calibrationMatrix.MultiplyVector(accelerator);
return accel;
}
1 Like
Awsome! Thanks, very helpful indeed.
Hi guys
This looks interesting to me as I am currently trying to do something similar but not as complex.
Did this script work?
I attached the script to a camera and I get this warning…
ssets/CameraTarget.js(49,99): BCW0012: WARNING: ‘UnityEngine.iPhoneTouch.positionDelta’ is obsolete. “positionDelta property is deprecated. Please use iPhoneTouch.deltaPosition instead.”
[/code]
Not sure if anyone whats an 3.3 version…
var target : Transform;
var distanceMin = 10.0;
var distanceMax = 15.0;
var distanceInitial = 12.5;
var scrollSpeed = 1.0;
var xSpeed = 250.0;
var ySpeed = 120.0;
var yMinLimit = -20;
var yMaxLimit = 80;
private var x = 0.0;
private var y = 0.0;
private var distanceCurrent = 0.0;
@script AddComponentMenu ("Camera-Control/Key Mouse Orbit")
function Start () {
calibrateAccelerometer();
var angles = transform.eulerAngles;
x = angles.y;
y = angles.x;
distanceCurrent = distanceInitial;
// Make the rigid body not change rotation
if (rigidbody)
rigidbody.freezeRotation = true;
}
function LateUpdate () {
if (target) {
x -= getAccelerometer(Input.acceleration).y * xSpeed * Time.deltaTime;
y += getAccelerometer(Input.acceleration).x * ySpeed * Time.deltaTime;
distanceCurrent -= Input.GetAxis("Mouse ScrollWheel") * scrollSpeed;
if (Input.touchCount > 1) {
var touch : Touch = Input.GetTouch(0);
var touch2 : Touch = Input.GetTouch(1);
// Find out how the touches have moved relative to eachother:
var curDist: Vector2 = touch.position - touch2.position;
var prevDist : Vector2 = (touch.position - touch.deltaPosition) - (touch2.position - touch2.deltaPosition);
distanceCurrent -= (curDist.magnitude - prevDist.magnitude)/2;
}
distanceCurrent = Mathf.Clamp(distanceCurrent, distanceMin, distanceMax);
y = ClampAngle(y, yMinLimit, yMaxLimit);
var rotation = Quaternion.Euler(y, x, 0);
var position = rotation * Vector3(0.0, 0.0, -distanceCurrent) + target.position;
transform.rotation = rotation;
transform.position = position;
}
}
var calibrationMatrix : Matrix4x4;
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);
}
function calibrateAccelerometer(){
var wantedDeadZone : Vector3 = Input.acceleration;
var rotateQuaternion : Quaternion = Quaternion.FromToRotation(new Vector3(0, 0, -1), wantedDeadZone);
//create identity matrix ... rotate our matrix to match up with down vec
var matrix : Matrix4x4 = Matrix4x4.TRS(Vector3.zero, rotateQuaternion, new Vector3(1, 1, 1));
//get the inverse of the matrix
this.calibrationMatrix = matrix.inverse;
}
//Whenever you need an accelerator value from the user
//call this function to get the 'calibrated' value
function getAccelerometer(accelerator : Vector3 ) : Vector3 {
var accel : Vector3 = this.calibrationMatrix.MultiplyVector(accelerator);
return accel;
}
1 Like