拖动和移动2D gameObject

时间:2016-06-15 10:41:29

标签: c# android unity3d

正如我之前的主题所示,我在运行时使用以下代码从sprite图像创建gameObject

 tex = Resources.Load<Texture2D>("pig") as Texture2D;
 Sprite sprite = new Sprite();
 sprite = Sprite.Create(tex, new Rect(0, 0, 250, 150), new Vector2(0.5f, 0.5f));
 GameObject newSprite = new GameObject();
 newSprite.AddComponent<Rigidbody2D>();
 newSprite.GetComponent<Rigidbody2D>().gravityScale = 0f;
 newSprite.AddComponent<ObjectMovement>();
 newSprite.AddComponent<SpriteRenderer>();
 SR = newSprite.GetComponent<SpriteRenderer>();
 SR.sprite = sprite;

如您所见,我添加了一个脚本&#34; ObjectMovement&#34;,如果有人拖动此特定gameObject,我想检查此脚本,如果有,请按照触摸位置,简单来说 - 这个游戏是2D。我从未使用RaysRaycast所以我不确定我哪里出错了。无论如何这里是我的脚本代码:

public SpriteRenderer selection=null;
    void Update()
    {
        if (Input.touchCount >= 1)
        {
            foreach (Touch touch in Input.touches)
            {
                Ray ray = Camera.main.ScreenPointToRay(touch.position);
                RaycastHit hit;
                switch (touch.phase)
                {
                    case TouchPhase.Began:
                        if (Physics.Raycast(ray, out hit, 100))
                            selection = hit.transform.gameObject.GetComponent<SpriteRenderer>();
                        break;
                    case TouchPhase.Moved:
                        selection.transform.position = new Vector2(selection.transform.position.x + touch.position.x / 10, selection.transform.position.y + touch.position.y / 10);
                        break;
                    case TouchPhase.Ended:
                        selection = null;
                        break;
                }
            }
        }
    }

所以基本上 - 当触摸屏幕时,触发ray并检查哪个gameObject处于此位置,当移动手指使其跟随时。拖放。感谢。

编辑:我注意到脚本附加到每个gameObject这个无效的任何想法?

1 个答案:

答案 0 :(得分:2)

对于2D,您使用RaycastHit2DPhysics2D.Raycast代替RaycastHitPhysics.Raycast。那些是3D。其次,确保将对撞机附加到Sprite。由于这是2D游戏,因此对撞机必须在其中包含单词“ 2D ”。例如,编辑器中的Box Colider 2D。您也可以使用Circle Collider 2D

  

我注意到脚本附加到每个没有的gameObject   有效,有什么想法吗?

只需创建一个空的GameObject并将该脚本附加到它上面。就是这样。

以下是您的代码的修复版本:

float tempZAxis;
public SpriteRenderer selection;
void Update()
{
    Touch[] touch = Input.touches;
    for (int i = 0; i < touch.Length; i++)
    {
        Vector2 ray = Camera.main.ScreenToWorldPoint(Input.GetTouch(i).position);
        RaycastHit2D hit = Physics2D.Raycast(ray, Vector2.zero);
        switch (touch[i].phase)
        {
            case TouchPhase.Began:
                if (hit)
                {
                    selection = hit.transform.gameObject.GetComponent<SpriteRenderer>();
                    if (selection != null)
                    {
                        tempZAxis = selection.transform.position.z;
                    }
                }
                break;
            case TouchPhase.Moved:
                Vector3 tempVec = Camera.main.ScreenToWorldPoint(touch[i].position);
                tempVec.z = tempZAxis; //Make sure that the z zxis never change
                if (selection != null)
                {
                    selection.transform.position = tempVec;
                }
                break;
            case TouchPhase.Ended:
                selection = null;
                break;
        }

    }
}

这只适用于移动设备,但不适用于桌面版本。我建议您实施IBeginDragHandlerIDragHandlerIEndDragHandler并覆盖随附的功能。现在,它将适用于移动和桌面平台。

注意:对于第二个解决方案,您必须将下面的脚本附加到您要拖动的所有Sprite上,而不像上面的第一个脚本。

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

public class Dragger : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler
{

    Camera mainCamera;
    float zAxis = 0;
    Vector3 clickOffset = Vector3.zero;

    // Use this for initialization
    void Start()
    {
        //Comment this Section if EventSystem system is already in the Scene
        addEventSystem();


        mainCamera = Camera.main;
        mainCamera.gameObject.AddComponent<Physics2DRaycaster>();

        zAxis = transform.position.z;
    }

    public void OnBeginDrag(PointerEventData eventData)
    {
        clickOffset = transform.position - mainCamera.ScreenToWorldPoint(new Vector3(eventData.position.x, eventData.position.y, zAxis));
    }

    public void OnDrag(PointerEventData eventData)
    {
        //Use Offset To Prevent Sprite from Jumping to where the finger is
        Vector3 tempVec = mainCamera.ScreenToWorldPoint(eventData.position) + clickOffset;
        tempVec.z = zAxis; //Make sure that the z zxis never change

        transform.position = tempVec;
    }

    public void OnEndDrag(PointerEventData eventData)
    {

    }

    //Add Event Syste to the Camera
    void addEventSystem()
    {
        GameObject eventSystem = new GameObject("EventSystem");
        eventSystem.AddComponent<EventSystem>();
        eventSystem.AddComponent<StandaloneInputModule>();
    }
}