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

查看:23
本文介绍了拖动和移动 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 而不是 RaycastHit> 和 Physics.Raycast.那些是3D的.其次,确保将碰撞器附加到 Sprite.由于这是一个 2D 游戏,对撞机中必须包含2D"字样.例如,编辑器中的 Box Collider 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.

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

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

    }
}

这仅适用于移动设备,而不适用于桌面版.我建议你实现 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天全站免登陆