实现:流畅的拖拽GameObject
主要注意:MonoBehaviour下的默认接口:
void OnMouseDown()
void OnMouseUp()
void Updata
还有一点:计算射线交点时候,代码里用的ray和plane, 而不是这个挂接的GameObject。如果使用ray和挂接的GameObject可能会出现:鼠标滑动过快,导致鼠标移除GameObject,不再计算位置。
using System.Collections; using System.Collections.Generic; using UnityEngine; /// <summary> /// 单个Piece的控制器 /// </summary> public class PieceControl : MonoBehaviour { /// <summary> /// 正确的位置 成功后不再移动 /// </summary> private Vector3 mFinishedPos = Vector3.zero; /// <summary> /// 初始随机的错误位置 /// </summary> private Vector3 mStartPos = Vector3.zero; private Camera mGameCamera = null; private GameObject mCameraObject = null; private PieceState mNowState = PieceState.None; private Vector3 mOffsetVec3 = Vector3.zero; /// <summary> /// 已经选中了这个对象 /// </summary> private bool mIsClickObject = false; /// <summary> /// 鼠标是否按下 /// </summary> private bool mIsMouseDown = false; private Vector3 oldInput = Vector3.zero; // Use this for initialization void Start() { mCameraObject = GameObject.FindGameObjectWithTag("MainCamera"); mGameCamera = mCameraObject.GetComponent<Camera>(); } void Update() { if (mIsMouseDown) { DragingRefreshPos(); } } // 按下鼠标按键时 void OnMouseDown() { this.mIsMouseDown = true; Debug.LogError("Down:"+this.name); GetBeginDownOffset(); } // 松开鼠标按键时 void OnMouseUp() { Debug.LogError("Up" + this.name); this.mIsMouseDown = false; } /// <summary> /// 获取刚拖动object时鼠标交点和object中心的偏移 /// </summary> private void GetBeginDownOffset() { Vector3 rejectPos = Vector3.zero; if (GetClickProjectPos(ref rejectPos, Input.mousePosition)) { mOffsetVec3 = transform.position - rejectPos; mIsClickObject = true; } } /// <summary> /// 根据GameObject和mouse的相对位置 /// 每帧刷新拖动的位置 /// </summary> private void DragingRefreshPos() { if (mIsClickObject) { Vector3 rejectPos = Vector3.zero; if (GetClickProjectPos(ref rejectPos, Input.mousePosition)) { transform.position = mOffsetVec3 + rejectPos; } } } /// <summary> /// 获取交点坐标 /// 当鼠标射线和大plane相交 /// </summary> /// <returns></returns> private bool GetClickProjectPos(ref Vector3 click3dPos, Vector3 inputPos) { Ray ray = mGameCamera.ScreenPointToRay(inputPos); // Debug.LogError("GetClickProjectPos oldInput:" + oldInput + " inputpos:" + inputPos); oldInput = inputPos; Plane plane = new Plane(Vector3.forward, new Vector3(0.0f, this.transform.position.y, 0.0f)); float rayDepth; if(plane.Raycast(ray,out rayDepth)) { click3dPos = ray.origin + ray.direction * rayDepth; return true; } return false; } #region 碎片的状态 private enum PieceState { None = -1, Idle = 0, Draging = 2, Finished = 3, Restart = 4, Snapping = 5//吸附过程中 } #endregion }