- Home /
gesture rotation clamp
hi everybody, I've found this script by Alexander Orozco somewhere on the web, and it works perfectly with pinch and swipe gesture to rotate and zoom in/out the camera, but I can't figure it out how I can clamp the y and z axis value. I've tried with Mathf.Clamp but I can't find the right value to clamp..
using UnityEngine; using System.Collections;
public class Gestures : MonoBehaviour {
// adjust accordingly in the inspector
public float zoomNearLimit = 5;
public float zoomFarLimit = 12;
public float zoomScreenToWorldRatio = 3.0f;
public float orbitScreenToWorldRatio = 1.0f;
public float twistScreenToWorldRatio = 5.0f;
public float rotateMinLimit = 0;
public float rotateMaxLimit = 80;
// don't change these
Vector3 orbitSpeed = Vector3.zero;
float twistSpeed = 0;
float distWeight;
float zoomDistance;
float zoomSpeed = 0;
float lastf0f1Dist;
void Update () {
// one finger gestures
if (iPhoneInput.touchCount == 1) {
// finger data
iPhoneTouch f0 = iPhoneInput.GetTouch(0);
// finger delta
Vector3 f0Delta = new Vector3(f0.deltaPosition.x, -f0.deltaPosition.y, 0);
// if finger moving
if (f0.phase == iPhoneTouchPhase.Moved) {
// compute orbit speed
orbitSpeed += (f0Delta + f0Delta * distWeight) * orbitScreenToWorldRatio * Time.deltaTime;
}
}
// two fingers gestures
else if (iPhoneInput.touchCount == 2) {
// fingers data
iPhoneTouch f0 = iPhoneInput.GetTouch(0);
iPhoneTouch f1 = iPhoneInput.GetTouch(1);
// fingers positions
Vector3 f0Pos = new Vector3(f0.position.x, f0.position.y, 0);
Vector3 f1Pos = new Vector3(f1.position.x, f1.position.y, 0);
// fingers movements
Vector3 f0Delta = new Vector3(f0.deltaPosition.x, f0.deltaPosition.y, 0);
Vector3 f1Delta = new Vector3(f1.deltaPosition.x, f1.deltaPosition.y, 0);
// fingers distance
float f0f1Dist = Vector3.Distance(f0.position, f1.position);
// if both fingers moving
if (f0.phase == iPhoneTouchPhase.Moved && f1.phase == iPhoneTouchPhase.Moved) {
// fingers moving direction
Vector3 f0Dir = f0Delta.normalized;
Vector3 f1Dir = f1Delta.normalized;
// dot product of directions
float dot = Vector3.Dot(f0Dir, f1Dir);
// if fingers moving in opposite directions
if (dot < -0.7f) {
float pinchDelta = f0f1Dist - lastf0f1Dist;
// if fingers move more than a threshold
if (Mathf.Abs(pinchDelta) > 2) {
// if pinch out, zoom in
if (f0f1Dist > lastf0f1Dist && zoomDistance > zoomNearLimit) {
zoomSpeed += (pinchDelta + pinchDelta * distWeight) * Time.deltaTime * zoomScreenToWorldRatio;
}
// if pinch in, zoom out
else if (f0f1Dist < lastf0f1Dist && zoomDistance < zoomFarLimit) {
zoomSpeed += (pinchDelta + pinchDelta * distWeight) * Time.deltaTime * zoomScreenToWorldRatio;
}
}
// detect twist
/*if (f0Delta.magnitude > 2 && f1Delta.magnitude > 2) {
// homemade algorithm works, but needs code review
Vector3 fingersDir = (f1Pos - f0Pos).normalized;
Vector3 twistNormal = Vector3.Cross(fingersDir, Vector3.forward);
Vector3 twistAxis = Vector3.Cross(fingersDir, twistNormal);
float averageDelta = (f0Delta.magnitude + f1Delta.magnitude) / 2;
if (Vector3.Dot(f0Dir, twistNormal) > 0.7f) {
twistSpeed = twistAxis.z * averageDelta * Time.deltaTime * twistScreenToWorldRatio;
}
else if (Vector3.Dot(f0Dir, twistNormal) < -0.7f) {
twistSpeed = -twistAxis.z * averageDelta * Time.deltaTime * twistScreenToWorldRatio;
}
}*/
}
}
// record last distance, for delta distances
lastf0f1Dist = f0f1Dist;
// decelerate zoom speed
zoomSpeed = zoomSpeed * (1 - Time.deltaTime * 10);
}
// no touching, or too many touches (we don't care about)
else {
// bounce to zoom limits
if (zoomDistance < zoomNearLimit) {
zoomSpeed += (zoomDistance - zoomNearLimit) * zoomScreenToWorldRatio;
}
else if (zoomDistance > zoomFarLimit) {
zoomSpeed += (zoomDistance - zoomFarLimit) * zoomScreenToWorldRatio;
}
// or decelerate
else {
zoomSpeed = zoomSpeed * (1 - Time.deltaTime * 10);
}
}
// decelerate orbit speed
orbitSpeed = orbitSpeed * (1 - Time.deltaTime * 5);
// decelerate twist speed
twistSpeed = twistSpeed * (1 - Time.deltaTime * 5);
// apply zoom
transform.position += transform.forward * zoomSpeed * Time.deltaTime;
zoomDistance = transform.position.magnitude;
// apply orbit and twist
transform.position = Vector3.zero;
transform.localRotation *= Quaternion.Euler(orbitSpeed.y, orbitSpeed.x, twistSpeed);
transform.position = -transform.forward * zoomDistance;
// compensate for distance (ej. orbit slower when zoomed in; faster when out)
distWeight = (zoomDistance - zoomNearLimit) / (zoomFarLimit - zoomNearLimit);
distWeight = Mathf.Clamp01(distWeight);
}
}
thanks for your help!
Answer by efge · Jan 13, 2012 at 06:42 PM
You could try to limit Transform.localEulerAngles after "apply orbit and twist".
how can I do this exactly?
I've tried with this code but it doesn't work and I can't undestand why..
orbitSpeed.y = $$anonymous$$athf.Clamp(orbitSpeed.y, rotate$$anonymous$$inLimit, rotate$$anonymous$$axLimit);
Answer by funasylum · Apr 05, 2012 at 12:38 PM
I know this is an old thread-- but I was looking for a similar solution. After some messing around and googling stuff I got this to work with the script above...
// define these
public float maxYRotationDegrees;
public float minYRotationDegrees;
public float maxXRotationDegrees;
public float minXRotationDegrees;
public float maxZRotationDegrees;
public float minZRotationDegrees;
private Quaternion tempQuaternion;
private Quaternion clampedQuaternion;
// then down at the apply orbit and twist, replace with:
tempQuaternion = transform.localRotation;
// apply the quaternion adjustments to our tempQuaternion
tempQuaternion *= Quaternion.Euler (orbitSpeed.y, orbitSpeed.x, twistSpeed);
// clamp the quaternion and convert to eulerangles
clampedQuaternion.eulerAngles = new Vector3 ((ClampAngle(tempQuaternion.eulerAngles.x,minXRotationDegrees, maxXRotationDegrees)), (ClampAngle(tempQuaternion.eulerAngles.y, minYRotationDegrees, maxYRotationDegrees)),(ClampAngle(tempQuaternion.eulerAngles.z, minZRotationDegrees, maxZRotationDegrees)));
// note: here you can substitute in hard number angles if you wish. I set the z to 0f to ignore twist, for instance
transform.localEulerAngles = new Vector3 (clampedQuaternion.eulerAngles.x, clampedQuaternion.eulerAngles.y, clampedQuaternion.eulerAngles.z);
// finally, a clamp euler angle function
float ClampAngle (float a, float min, float max)
{
while (max < min) max += 360.0f;
while (a > max) a -= 360.0f;
while (a < min) a += 360.0f;
if (a > max)
{
if (a - (max + min) * 0.5f < 180.0f)
return max;
else
return min;
}
else
return a;
}
Hope this is helpful to someone!,
Your answer
Follow this Question
Related Questions
Help clamping a Rotation 1 Answer
limit accelerometer controlled rotation 1 Answer
How to use Mathf.Clamp with child objects? 0 Answers
Quick Question About Limiting a Rotation. 1 Answer
Clamp Rotation Problem 1 Answer