拖动和移动2D游戏对象 [英] Dragging and moving 2D gameObject

查看:124
本文介绍了拖动和移动2D游戏对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此,正如我之前的线程所显示的那样,我正在使用以下代码在运行时从精灵图像创建gameObject:

so as my previous threads show, I am creating a gameObject from sprites images at runtime using this code:

 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;

如您所见,我添加了一个脚本"ObjectMovement",我想在此脚本中检查是否有人拖动了该特定的gameObject,如果这样,请使其跟随触摸位置,仅此提及-该游戏是2D.我从未使用过RaysRaycast,所以我不确定哪里出了问题.无论如何,这是我的脚本代码:

As you see I added a script "ObjectMovement", I want to check in this script if someone is dragging this particular gameObject and if so, make it follow the touch position, just to mention - this game is 2D. I never used RaysorRaycast so I am not sure where I gone wrong. Anyway here is my script code:

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处于此位置,移动手指时使其跟随它.拖放.谢谢.

So basically - when touching the screen, fire a ray and check which gameObject is in this position, when moving the finger make it follow it. Drag and drop. Thanks.

编辑:我注意到该脚本已附加到每个gameObject上,这无效,有什么想法吗?

I noticed the script is attached to every gameObject which is not effective, any ideas?

推荐答案

对于2D,您使用RaycastHit2DPhysics2D.Raycast而不是RaycastHitPhysics.Raycast.这些是用于3D的.其次,确保将对撞机连接到Sprite.由于这是2D游戏,因此对撞机中必须包含单词" 2D ".例如,编辑器中的Box Colider 2D.您也可以使用Circle Collider 2D.

For 2D, you use RaycastHit2D and Physics2D.Raycast instead of RaycastHit and Physics.Raycast. Those are for 3D. Secondly, Make sure to attach a collider to the Sprite. Since this is a 2D game, the collider must have word "2D" in it. For example, Box Colider 2D from the Editor. You can also use Circle Collider 2D.

我注意到该脚本已附加到每个gameObject上,而不是 有效,有什么想法吗?

I noticed the script is attached to every gameObject which is not effective, any ideas?

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

Just create an empty GameObject and attach that script to it. That's it.

这是您代码的固定版本:

Here is fixed version of your code:

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;
        }

    }
}

那将仅在移动设备上有效,而在Desktop Build上无效.我建议您实现IBeginDragHandlerIDragHandlerIEndDragHandler,并覆盖它们随附的功能.现在,它可以在移动和台式机平台上使用.

That would only work on mobile but not on the Desktop Build. I suggest you implement IBeginDragHandler, IDragHandler, IEndDragHandler and override the functions that comes with them. Now, it will work with both mobile and desktop platforms.

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

Note: For the second solution you have to attach the script below to all Sprites you want to drag unlike the first script above.

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>();
    }
}

这篇关于拖动和移动2D游戏对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆