【问题标题】:Making only the graphic inside the bounds of a sprite draggable仅使精灵边界内的图形可拖动
【发布时间】:2015-08-05 14:18:03
【问题描述】:

我正在构建一个游戏,在该游戏上可以拖动对象并排列它们以构建不同类型的动物。我的问题是,有没有一种方法可以定义每个精灵的可拖动区域,而不仅仅是一个简单的矩形?我的精灵中的许多图形本质上都是椭圆形和三角形的,这在实际图像周围留下了很多空白空间。我想让我的精灵的矩形边界内的图形可拖动。如何做到这一点?

这里有一些图形来说明我所说的不规则形状的含义。

因此,当您在这些形状周围绘制一个边界框时,会有很多我不想拖动或点击的空白空间。我已经有一个处理拖动的脚本,但是它使整个精灵可拖动,我如何让 2D 多边形对撞机接受拖动事件?

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

public class DragHandling : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler, IPointerClickHandler
{
    Vector3 partsPanelScale = new Vector3(1.0f, 1.0f, 1.0f);
    public float partScale;
    // public float partRotate;
    Vector3 buildPanelScale;
    // Vector3 buildPanelRotate;

    [HideInInspector] public Transform placeholderParent = null;
    [HideInInspector] public Transform parentToReturnTo = null;

    GameObject placeholder = null;

    [HideInInspector] public GameObject animalPart;

    [HideInInspector] public GameObject trashCan; 
    [HideInInspector] public GameObject partsPanel;
    [HideInInspector] public GameObject partsWindow;
    [HideInInspector] public GameObject buildBoard;
    [HideInInspector] public GameObject horns;
    [HideInInspector] public GameObject heads;
    [HideInInspector] public GameObject ears;
    [HideInInspector] public GameObject necks;
    [HideInInspector] public GameObject bodies;
    [HideInInspector] public GameObject legs;
    [HideInInspector] public GameObject tails;
    [HideInInspector] public GameObject more;

    GameObject dragLayer;

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

        horns = GameObject.FindGameObjectWithTag("AnimalPart-Horns");
        heads = GameObject.FindGameObjectWithTag("AnimalPart-Heads");
        ears = GameObject.FindGameObjectWithTag("AnimalPart-Ears");
        necks = GameObject.FindGameObjectWithTag("AnimalPart-Necks");
        bodies = GameObject.FindGameObjectWithTag("AnimalPart-Bodies");
        legs = GameObject.FindGameObjectWithTag("AnimalPart-Legs");
        tails = GameObject.FindGameObjectWithTag("AnimalPart-Tails");
        more = GameObject.FindGameObjectWithTag("AnimalPart-More");
    }

    #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());
/*
        if(transform.parent.gameObject == partsPanel)
        {
            partsPanelScale = transform.localScale;
        }
*/
        parentToReturnTo = transform.parent;                                    // store current parent location
        placeholderParent = parentToReturnTo;                                   // set placeholder gameobject transform

        GetComponent<CanvasGroup>().blocksRaycasts = false;                     // turn off image raycasting when dragging image in order to see what's behind the image            
    }

    #endregion

    #region IDragHandler implementation

    float distance = 0;

    public void OnDrag (PointerEventData eventData)
    {
        Vector3 mousePosition = new Vector3(eventData.position.x, eventData.position.y, distance);
        // Vector3 objPosition = Camera.main.ViewportToScreenPoint(mousePosition);
        transform.position = 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);
            // Constrain drag to boundaries of buildBoard Code
        }
    }

    #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)
        {
            // Debug.Log ("Your sprite is now on the " + transform.parent.name);

            buildPanelScale = new Vector3(partScale, partScale, partScale);
            transform.localScale = buildPanelScale;
            transform.SetAsLastSibling();                                       
        }

        if(transform.parent.gameObject == partsPanel)
        {
            // transform.SetParent(buildBoard.transform);
            transform.localScale = partsPanelScale;
        }
    }

    #endregion

}

【问题讨论】:

  • “互动区”是什么意思?
  • 他可能是指对撞机
  • 我的意思是当我创建精灵时,它们总是有矩形边界,但我不希望整个精灵可以拖动,只有边界内的图形。有没有办法用对撞机做到这一点?

标签: c# unity3d sprite draggable


【解决方案1】:

如果您使用 BoxCollider2D 作为拼图的默认碰撞器,则可以将其更改为 PolygonCollider2D。它会自动为您的 Sprite 生成碰撞器(IIRC,它使用 alpha 通道),您还可以通过向碰撞器的网格添加顶点来进一步自定义它。

【讨论】:

  • 好的,很酷。所以我画了一个多边形碰撞器,它只勾勒出我的精灵边界内的图形区域,但是我如何才能使那个碰撞器区域可拖动?
  • 制作一个使用 OnMouseDrag 的脚本,并在那里编写代码
  • 我已经有一个处理拖动的脚本(上面发布),但它使整个精灵可拖动,我如何让 2D 多边形碰撞器接受拖动事件?
猜你喜欢
  • 1970-01-01
  • 2015-05-31
  • 1970-01-01
  • 1970-01-01
  • 2012-06-18
  • 1970-01-01
  • 2018-11-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多