unity3d 鼠标2D控制

/*

* 用到了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) {

//一般指旋转物体的中心点或鼠标围绕某个旋转的中心

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");

 

 

}

 

}

 

/// <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 @ 2011-11-25 17:07  顺手  阅读(3110)  评论(0)    收藏  举报