多点触摸+摄像机旋转拉伸学习笔记

来源:互联网 发布:ahocorasick 算法 编辑:程序博客网 时间:2024/06/14 20:26

using UnityEngine;using System.Collections;public class Move : MonoBehaviour {// Use this for initialization    [SerializeField]    Transform Target;//目标物体    [SerializeField]    float distance = 10f;//摄像机与目标物体的距离,Z轴负方向是远离目标,正方向是靠近目标(当然是对于本例子)    [SerializeField]    float xScale = 2.40f;//对应旋转角度的系数,鼠标位移*系数 = 旋转角度    [SerializeField]    float yScale = 5.0f;//对应旋转角度的系数    [SerializeField]    float yMinLimit = 0f;//垂直移动,也就是绕x轴移动,最小范围,在Unity中一边移动,一边尝试    [SerializeField]    float yMaxLimit = 180f;//最大范围    [SerializeField]    float x = 0;//水平方向的旋转角度    [SerializeField]    float y = 0;//垂直方向的旋转角度    Vector2 oldPosition1;    Vector2 oldPosition2;void Start () {        Vector3 angles = transform.eulerAngles;        x = angles.x;        y = angles.y;        if (rigidbody)        {            rigidbody.freezeRotation = true;        }}// Update is called once per framevoid Update () {        if (Input.touchCount == 1)//单点触摸时,可以让摄像机围绕物体旋转        {            if (Input.GetTouch(0).phase == TouchPhase.Moved)            {                x += Input.GetAxis("Mouse X") * xScale;//屏幕x方向拖动,是沿y轴旋转,另外注意,角度是累加的                y -= Input.GetAxis("Mouse Y") * yScale;//屏幕y方向拖动,是沿x轴旋转            }        }        else if(Input.GetMouseButton(0))//鼠标左键可以控制        {            x += Input.GetAxis("Mouse X") * xScale;            y -= Input.GetAxis("Mouse Y") * yScale;        }        if (Input.touchCount > 1)        {            //这里很巧妙,只要一个手指一动,就算形成手势,这个很巧妙            if (Input.GetTouch(0).phase == TouchPhase.Moved || Input.GetTouch(1).phase == TouchPhase.Moved)            {                Vector2 tempPos1 = Input.GetTouch(0).position;                Vector2 tempPos2 = Input.GetTouch(1).position;                if(isEnlarge(oldPosition1,oldPosition2,tempPos1,tempPos2))                {                    if(distance>3f)                    {                        distance -=0.5f;                    }                }                else                {                    if(distance<18.5f)                    {                        distance += 0.5f;                    }                }                oldPosition1 = tempPos1;                oldPosition2 = tempPos2;            }        }}    /// <summary>    /// 比较之前的两个手指距离, 和新的两个手指的距离,看看变化    /// </summary>    /// <param name="op1"></param>    /// <param name="op2"></param>    /// <param name="np1"></param>    /// <param name="np2"></param>    /// <returns></returns>    bool isEnlarge(Vector2 op1, Vector2 op2, Vector2 np1, Vector2 np2)    {        float leng1 = (op1 - op2).magnitude;//取模运算        float leng2 = (np1 - np2).magnitude;        if (leng1 < leng2)        {            return true;        }        else         {            return false;        }    }    void LateUpdate()//在update之后每一帧都会调用该函数    {        if (Target)        {            //确定垂直方向的范围            y = ClampAngle(y, yMinLimit, yMaxLimit);            //摄像机始终要面朝物体,所以需要旋转            //将欧拉角转换为旋转使用的四元数,表示沿x轴方(竖直)向旋转y度,沿y轴(水平)方向旋转x度            Quaternion rotation = Quaternion.Euler(y, x, 0);            //将向量 (其实就是有物体指向摄像机的向量)按照这个四元数旋转 + 物体坐标(世界坐标系) = 摄像机的位置             //另外,这个乘法,和四元数的数学乘法有点区别啊,不是完全一样的            Vector3 position = rotation * (new Vector3(0f, 0f, -distance)) + Target.position;            //物体rotation的定义是:The rotation of the transform in world space stored as a Quaternion.物体在世界坐标系的,以四元数方式存储的旋转            //所以,我们改变这个值,就是改变了摄像机的朝向            transform.rotation = rotation;            //光有朝向没有用,还要有正确的位置            transform.position = position;        }    }    static float ClampAngle(float angle, float min, float max)    {        //放置旋转太猛,直接翻几个跟头        if (angle < -360)            angle += 30;        if (angle > 360)            angle -= 360;        return Mathf.Clamp(angle,min,max);    }}

摄像机沿Z轴正方向正对物体


摄像机和物体的位置关系



参考: 代码参考:http://www.xuanyusong.com/archives/512

      四元数参考:http://www.cnblogs.com/Mrt-02/archive/2011/10/15/2213656.html

 

0 0