Unity 双指旋转
2017-02-11 18:38
267 查看
思路都是:
每一帧以两指坐标生成一个向量Vector2,不同帧比较向量的角度变化Vector2.Angle()。
简化版:参考EasyTouch的实现
另一种写法,参考的博客已失效,这里贴一下
const float pinchTurnRatio = Mathf.PI / 2;
//用这个数值来判定旋转的最小角度,自己决定大小
const float minTurnAngle = 0;
/// <summary>
/// The delta of the angle between two touch points
/// </summary>
static public float turnAngleDelta;
/// <summary>
/// The angle between two touch points
/// </summary>
static public float turnAngle;
/// <summary>
/// Calculates Pinch and Turn - This should be used inside LateUpdate
/// </summary>
static public void Calculate()
{
//pinchDistance = pinchDistanceDelta = 0;
turnAngle = turnAngleDelta = 0;
// if two fingers are touching the screen at the same time ...
if (Input.touchCount == 2) {
Touch touch1 = Input.touches[0];
Touch touch2 = Input.touches[1];
// ... if at least one of them moved ...如果有一根手指有移动
if (touch1.phase == TouchPhase.Moved || touch2.phase == TouchPhase.Moved) {
// ... or check the delta angle between them ...
//当前两手指与X轴的角
turnAngle = Angle(touch1.position, touch2.position);
//之前两手指与X的角度
float prevTurn = Angle(touch1.position - touch1.deltaPosition,
touch2.position - touch2.deltaPosition);
//旋转的偏移量, 增量角
turnAngleDelta = Mathf.DeltaAngle(prevTurn, turnAngle);
// ... if it's greater than a minimum threshold, it's a turn!
//增量角如果大于设定值
if (Mathf.Abs(turnAngleDelta) > minTurnAngle) {
turnAngleDelta *= pinchTurnRatio;
} else {
turnAngle = turnAngleDelta = 0;
}
}
}
//鼠标判断事件,这个只是个测试
#if UNITY_EDITOR
MouseRotateEvent();
#endif
}
/// <summary>
/// 取两个向量之间的角度 与X轴
/// </summary>
/// <param name="pos1"></param>
/// <param name="pos2"></param>
/// <returns></returns>
static private float Angle(Vector2 pos1, Vector2 pos2)
{
//取两个向量相减
Vector2 from = pos2 - pos1;
//X轴
Vector2 to = new Vector2(1, 0);
//与X轴夹角
float result = Vector2.Angle(from, to);
//向量的叉乘
Vector3 cross = Vector3.Cross(from, to);
//如果超出360度
if (cross.z > 0) {
//用360来减这个角度
result = 360f - result;
}
return result;
}
#if UNITY_EDITOR
static bool isPress = false;
static float preAngle = 0;
/// <summary>
/// 鼠标右键旋转事件,并非完美实现,因为没有判断角度为正还是为负。
/// </summary>
static public void MouseRotateEvent()
{
if (Input.GetMouseButton(1)) {
//第一次按下
if (!isPress) {
//上一帧的角度
preAngle = Angle(Input.mousePosition, Vector2.zero);
isPress = true;
} else {
//转动的角度
turnAngle = Angle(Input.mousePosition, Vector2.zero);
//旋转的偏移量, 增量角
turnAngleDelta = Mathf.DeltaAngle(preAngle, turnAngle);
Log.log("增量角:"+turnAngleDelta);
//增量角如果大于设定值
if (Mathf.Abs(turnAngleDelta) > minTurnAngle) {
turnAngleDelta *= pinchTurnRatio;
} else {
turnAngle = turnAngleDelta = 0;
}
//更新为这一帧
preAngle = Angle(Input.mousePosition, Vector2.zero);
}
} else {
isPress = false;
}
}
#endif
/// <summary>
/// 绕点旋转,或者是Z轴旋转?
/// </summary>
public bool isRotateAround = false;
//目标
public Transform target;
//围绕点
protected Vector3 axis {
get {
return new Vector3(target.position.x, transform.position.y, target.position.z);
}
}
//void Start()
//{
// if (target == null) {
// Debug.Log("target is null!");
// enabled = false;
// }
//}
void Update()
{
Calculate();
if (Mathf.Abs(turnAngleDelta) > 0) {
if (isRotateAround) {
//围点旋转
transform.RotateAround(axis, Vector3.up, -turnAngleDelta);
//目视对方
transform.LookAt(target);
} else {
Quaternion desiredRotation = transform.rotation;
Vector3 rotationDeg = Vector3.zero;
//z轴旋转
rotationDeg.z = -turnAngleDelta;
desiredRotation *= Quaternion.Euler(rotationDeg);
transform.rotation = desiredRotation;
}
}
}
每一帧以两指坐标生成一个向量Vector2,不同帧比较向量的角度变化Vector2.Angle()。
简化版:参考EasyTouch的实现
public class TouchTest : MonoBehaviour { Touch oldTouch1; //上次触摸点1(手指1) Touch oldTouch2; //上次触摸点2(手指2) void Update() { if (Input.touchCount <= 1) { return; } Touch touch1 = Input.GetTouch(0); Touch touch2 = Input.GetTouch(1); //启用双指,尚未旋转 if (touch2.phase == TouchPhase.Began) { oldTouch2 = touch2; oldTouch1 = touch1; return; } if (touch1.phase == TouchPhase.Moved || touch2.phase == TouchPhase.Moved) { Vector2 curVec = touch2.position - touch1.position; Vector2 oldVec = oldTouch2.position - oldTouch1.position; float angle = Vector2.Angle(oldVec, curVec); angle *= Mathf.Sign(Vector3.Cross(oldVec, curVec).z); transform.Rotate(new Vector3(0, 0, angle)); oldTouch1 = touch1; oldTouch2 = touch2; } } }
另一种写法,参考的博客已失效,这里贴一下
const float pinchTurnRatio = Mathf.PI / 2;
//用这个数值来判定旋转的最小角度,自己决定大小
const float minTurnAngle = 0;
/// <summary>
/// The delta of the angle between two touch points
/// </summary>
static public float turnAngleDelta;
/// <summary>
/// The angle between two touch points
/// </summary>
static public float turnAngle;
/// <summary>
/// Calculates Pinch and Turn - This should be used inside LateUpdate
/// </summary>
static public void Calculate()
{
//pinchDistance = pinchDistanceDelta = 0;
turnAngle = turnAngleDelta = 0;
// if two fingers are touching the screen at the same time ...
if (Input.touchCount == 2) {
Touch touch1 = Input.touches[0];
Touch touch2 = Input.touches[1];
// ... if at least one of them moved ...如果有一根手指有移动
if (touch1.phase == TouchPhase.Moved || touch2.phase == TouchPhase.Moved) {
// ... or check the delta angle between them ...
//当前两手指与X轴的角
turnAngle = Angle(touch1.position, touch2.position);
//之前两手指与X的角度
float prevTurn = Angle(touch1.position - touch1.deltaPosition,
touch2.position - touch2.deltaPosition);
//旋转的偏移量, 增量角
turnAngleDelta = Mathf.DeltaAngle(prevTurn, turnAngle);
// ... if it's greater than a minimum threshold, it's a turn!
//增量角如果大于设定值
if (Mathf.Abs(turnAngleDelta) > minTurnAngle) {
turnAngleDelta *= pinchTurnRatio;
} else {
turnAngle = turnAngleDelta = 0;
}
}
}
//鼠标判断事件,这个只是个测试
#if UNITY_EDITOR
MouseRotateEvent();
#endif
}
/// <summary>
/// 取两个向量之间的角度 与X轴
/// </summary>
/// <param name="pos1"></param>
/// <param name="pos2"></param>
/// <returns></returns>
static private float Angle(Vector2 pos1, Vector2 pos2)
{
//取两个向量相减
Vector2 from = pos2 - pos1;
//X轴
Vector2 to = new Vector2(1, 0);
//与X轴夹角
float result = Vector2.Angle(from, to);
//向量的叉乘
Vector3 cross = Vector3.Cross(from, to);
//如果超出360度
if (cross.z > 0) {
//用360来减这个角度
result = 360f - result;
}
return result;
}
#if UNITY_EDITOR
static bool isPress = false;
static float preAngle = 0;
/// <summary>
/// 鼠标右键旋转事件,并非完美实现,因为没有判断角度为正还是为负。
/// </summary>
static public void MouseRotateEvent()
{
if (Input.GetMouseButton(1)) {
//第一次按下
if (!isPress) {
//上一帧的角度
preAngle = Angle(Input.mousePosition, Vector2.zero);
isPress = true;
} else {
//转动的角度
turnAngle = Angle(Input.mousePosition, Vector2.zero);
//旋转的偏移量, 增量角
turnAngleDelta = Mathf.DeltaAngle(preAngle, turnAngle);
Log.log("增量角:"+turnAngleDelta);
//增量角如果大于设定值
if (Mathf.Abs(turnAngleDelta) > minTurnAngle) {
turnAngleDelta *= pinchTurnRatio;
} else {
turnAngle = turnAngleDelta = 0;
}
//更新为这一帧
preAngle = Angle(Input.mousePosition, Vector2.zero);
}
} else {
isPress = false;
}
}
#endif
/// <summary>
/// 绕点旋转,或者是Z轴旋转?
/// </summary>
public bool isRotateAround = false;
//目标
public Transform target;
//围绕点
protected Vector3 axis {
get {
return new Vector3(target.position.x, transform.position.y, target.position.z);
}
}
//void Start()
//{
// if (target == null) {
// Debug.Log("target is null!");
// enabled = false;
// }
//}
void Update()
{
Calculate();
if (Mathf.Abs(turnAngleDelta) > 0) {
if (isRotateAround) {
//围点旋转
transform.RotateAround(axis, Vector3.up, -turnAngleDelta);
//目视对方
transform.LookAt(target);
} else {
Quaternion desiredRotation = transform.rotation;
Vector3 rotationDeg = Vector3.zero;
//z轴旋转
rotationDeg.z = -turnAngleDelta;
desiredRotation *= Quaternion.Euler(rotationDeg);
transform.rotation = desiredRotation;
}
}
}
相关文章推荐
- unity触摸放大缩小旋转
- 【Unity技巧】四元数(Quaternion)和旋转
- unity还原three导出的json——基本模型,位移,旋转,缩放
- unity 旋转函数
- Unity旋转以及万向锁问题
- 【Unity】【Code】Unity+触摸屏 单点旋转,双点放大缩小
- unity旋转注视以及四元数的学习
- 【Unity 3D学习】获取鼠标滑动方向(上下左右)-控制摄像机围绕物体旋转
- 让物体围绕自身某一点旋转的方法 Unity
- Unity Shader之uv旋转
- unity中通过收拾实现物体旋转和放大缩小
- [HTC Vive + Unity开发]——VRTK的研究——用手柄旋转物体(使用VRTK_Knob脚本)
- 怎么在 unity 里鼠标旋转一个物体
- unity中的旋转
- 【小松教你手游开发】【unity实用技能】unity3d 陀螺仪控制camera移动旋转
- 【狼】unity 鼠标拖拽物体实现任意角度自旋转
- unity旋转 缩放摄像机
- Unity触摸激活旋转缩放
- Unity的旋转
- Unity中用触摸控制物体旋转和放大