unity3d 鼠标2D控制

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

/*
* 用到了unity3d非常好的协同机制实现这一点,OnMouseDown事件表示鼠标已作了射线判断得到了对象。
* 拖拽时保持z轴不变,因为屏幕是xy二维的,空间是三维的。
* */


IEnumerator OnMouseDown ()
{
    var camera = Camera.mainCamera;
    if (camera)
    {
        //转换对象到当前屏幕位置       
        Vector3 screenPosition = camera.WorldToScreenPoint (transform.position);
        //鼠标屏幕坐标
        Vector3 mScreenPosition=new Vector3 (Input.mousePosition.x, Input.mousePosition.y, screenPosition.z);
        //获得鼠标和对象之间的偏移量,拖拽时相机应该保持不动
        Vector3 offset = transform.position - camera.ScreenToWorldPoint( mScreenPosition);
        print ("drag starting:"+transform.name);
        //若鼠标左键一直按着则循环继续
        while (Input.GetMouseButton (0))
        {
            //鼠标屏幕上新位置
            mScreenPosition = new Vector3 (Input.mousePosition.x, Input.mousePosition.y, screenPosition.z);
            //对象新坐标
            transform.position=offset + camera.ScreenToWorldPoint (mScreenPosition);
            //协同,等待下一帧继续
            yield return new WaitForEndOfFrame ();
        }
        print ("drag compeleted");
    }
}

 
/// <summary>
/// 跟随鼠标旋转物体,并判断手势滑动离开时的旋转方向顺时针还是逆时针,可作些模拟拖拽完成时减速度效果
/// </summary>
/// <returns>
/// A <see cref="IEnumerator"/>
/// </returns>

IEnumerator OnMouseDown ()
{
    Camera camera = Camera.mainCamera;
    if (camera)
    {
        #region
        //一般指旋转物体的中心点或鼠标围绕某个旋转的中心
        Vector3 relativePoint = camera.WorldToScreenPoint (transform.position);
        //鼠标操作时只用x,y轴,计算时必须忽略z轴
        relativePoint.z = 0;
        //鼠标按下时的方向向量,作为拖拽起始参考向量
        Vector3 relativeDirection = Input.mousePosition - relativePoint;
        //手势滑动时旋转方向,1:顺时针,-1:逆时针
        int flingDir = 1;
        //最后倒数第二个方向的角度,用于比较最后旋转方向
        float last2Angle =0;
        print ("rotation starting:" + transform.name);
        //对象原始角度
        Vector3 originAngles = transform.eulerAngles;
        Quaternion originRotation=transform.rotation;
        //旋转总角度
        float sumAngle = 0;
        while (Input.GetMouseButton (0))
        {
            #region 当前旋转角度
            Vector3 currentDirection = Input.mousePosition - relativePoint;
            //0-180正角度,不适合拖拽旋转
            //float currentAngle = Vector3.Angle (relativeDirection, currentDirection);
            //有正负角度,可做鼠标跟随旋转角度
            float currentSignAngle = SignAngle (relativeDirection, currentDirection);
            #endregion

            //离上次角度偏移量
            float offsetAngle = currentSignAngle - last2Angle;

            #region 判断方向
            flingDir = currentSignAngle - last2Angle >= 0 ? 1 : -1;
            #endregion

            #region 总计正方向旋转角度
            if (offsetAngle > 0)
            {
                sumAngle += offsetAngle;
            }
            #endregion
            last2Angle = currentSignAngle;

            //print(offsetAngle+","+sumAngle);
            print ("angle:" + currentSignAngle + ",fling:" + flingDir + ",sum:" + sumAngle);

            //设置新的角度
            transform.eulerAngles=originAngles+ originRotation*direction*currentSignAngle;

            yield return new WaitForEndOfFrame ();

        }
        print ("rotation compeleted");
        #endregion
    }
}

 

/// <summary>
/// Math.atan2(y2-y1,x2-x1)
/// </summary>
/// <param name="vector1">
/// A <see cref="Vector2"/>
/// </param>
/// <param name="vector2">
/// A <see cref="Vector2"/>
/// </param>
/// <returns>
/// A <see cref="System.Single"/>
/// </returns>
float SignAngle (Vector2 start, Vector2 end)
{
    float num1 = (end.x * start.y)-(start.x * end.y);
    float num2 = (start.x * end.x) + (start.y * end.y);
    return (Mathf.Atan2 (num1, num2) * Mathf.Rad2Deg);
}

posted @ 2012-04-17 16:36  渡蓝  阅读(323)  评论(0编辑  收藏  举报