拖动开始时防止对象跳转到中心点

时间:2015-08-12 02:00:33

标签: c# unity3d drag-and-drop

我有一个用于拖动游戏对象的脚本,但此时,每当我开始拖动对象时,它就会跳到中心本身到指针上。我想要实现的是无论我在哪里开始拖动它在该点开始拖动的对象而不是首先跳到对象中心。我需要在OnDrag或OnBeginDrag方法中修改什么才能实现此目的?

using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using UnityEngine.EventSystems;
using System.Collections.Generic;

public class DragHandling : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler, IPointerClickHandler
{
    public float partScale;

    [HideInInspector] public Transform placeholderParent = null;
    [HideInInspector] public Transform parentToReturnTo = null;
    [HideInInspector] public GameObject trashCan; 
    [HideInInspector] public GameObject partsPanel;
    [HideInInspector] public GameObject partsWindow;
    [HideInInspector] public GameObject buildBoard;

    GameObject placeholder = null;
    GameObject dragLayer;
    Vector3 buildPanelScale;
    Vector3 partsPanelScale = new Vector3(1.0f, 1.0f, 1.0f);
    Vector3 startPosition;

    // PolygonCollider2D collider;

    void Start ()
    {
        dragLayer = GameObject.FindGameObjectWithTag("DragLayer");
        buildBoard = GameObject.FindGameObjectWithTag("Board");
        partsPanel = GameObject.FindGameObjectWithTag("Parts");
        partsWindow = GameObject.FindGameObjectWithTag("PartsWindow");
        trashCan = GameObject.FindGameObjectWithTag("Trash");

        // collider = transform.GetComponent<PolygonCollider2D>();
    }

    #region IPointerClickHandler implementation

    public void OnPointerClick (PointerEventData eventData)
    {
        if(transform.parent.gameObject == buildBoard)
            transform.SetAsLastSibling();
    }

    #endregion

    #region IBeginDragHandler implementation

    public void OnBeginDrag (PointerEventData eventData)
    {
        // create placeholder gap and hold correct position in layout
        placeholder = new GameObject();
        placeholder.transform.SetParent(transform.parent);
        placeholder.transform.SetSiblingIndex(transform.GetSiblingIndex());
        parentToReturnTo = transform.parent;                                    // store original parent location
        placeholderParent = parentToReturnTo;                                   // set placeholder gameobject transform
        startPosition = transform.position;
        GetComponent<CanvasGroup>().blocksRaycasts = false;                     // turn off image raycasting when dragging image in order to see what's behind the image            
    }

    #endregion

    #region IDragHandler implementation

    public void OnDrag (PointerEventData eventData)
    {
        Vector3 mousePosition = new Vector3(eventData.position.x, eventData.position.y, 0);
        transform.position = Input.mousePosition;                                           // set object coordinates to mouse coordinates

        if(transform.parent.gameObject == partsPanel)
            transform.SetParent(dragLayer.transform);                                       // pop object to draglayer to move object out of parts Panel
        if(transform.parent.gameObject == buildBoard)
            transform.SetParent(dragLayer.transform);
    }

    #endregion

    #region IEndDragHandler implementation

    public void OnEndDrag (PointerEventData eventData)
    {
        transform.SetParent(parentToReturnTo);                                  // Snaps object back to orginal parent if dropped outside of a dropzone
        transform.SetSiblingIndex(placeholder.transform.GetSiblingIndex());     // Returns card back to placeholder location
        GetComponent<CanvasGroup>().blocksRaycasts = true;                      // turn Raycast back on
        Destroy(placeholder);                                                   // kill the placeholder if object hits a drop zone or returns to parts panel

        if(transform.parent.gameObject == buildBoard)
        {
            buildPanelScale = new Vector3(partScale, partScale, partScale);
            transform.localScale = buildPanelScale;
            transform.SetAsLastSibling();                                       // always place last piece on top
        }
        if(transform.parent.gameObject == partsPanel)
            transform.localScale = partsPanelScale;
    }

    #endregion

}

2 个答案:

答案 0 :(得分:2)

我从未使用过任何接口来实现它,但解决方案应该与使用OnMouseDown,OnMouseUp和OnMouseDrag以及sprite一样。尝试使用当前的实现

 using UnityEngine;
using System.Collections;

public class Drag : MonoBehaviour {

    private Vector3 offset = Vector3.zero;

    void OnMouseDown () {
        Vector3 worldPos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
        worldPos.z = transform.position.z;
        offset = worldPos - transform.position;
    }


    void OnMouseDrag () {
        Vector3 worldPos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
        worldPos.z = transform.position.z;
        worldPos = worldPos - offset;
        transform.position = worldPos;
    }


    void OnMouseUp () {
        offset = Vector3.zero;
    }

}

我在Sprites上使用了正交相机。希望这会有所帮助。

修改

尝试使用UI元素在代码中实现接口。它按预期工作。唯一的事情是将画布设置为ScreenSpace-Camera实现相应接口中的代码

答案 1 :(得分:0)

你的问题有点令人困惑,如果我正确你说你开始拖动的对象一直移动到屏幕的中间,如果你不想要只是在OnEndDrag中更新拖动的对象变换。