南梦宫 拼图笔记 1.流畅的拖拽操作

  实现:流畅的拖拽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

}
改变自己
原文地址:https://www.cnblogs.com/sun-shadow/p/9206173.html