0

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;

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

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.

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

DAVIDBALAS1
  • 484
  • 10
  • 31

1 Answers1

3

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?

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

    }
}

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.

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>();
    }
}
Programmer
  • 121,791
  • 22
  • 236
  • 328
  • For the second script I get an error - Multiple eventsystems in scene... – DAVIDBALAS1 Jun 15 '16 at 13:28
  • by commenting this section you meant surrounding with if statement? – DAVIDBALAS1 Jun 15 '16 at 13:29
  • @DAVIDBALAS1 No. That means putting `//` in front `addEventSystem();` or just removing `addEventSystem();` from the `Start()` function. Adding `//` will tell the compiler to not compile that line of code. So, replace `addEventSystem();` with `//addEventSystem();` or remove it. – Programmer Jun 15 '16 at 13:35
  • Oh sure, I didn't know it's called commenting a line.. The second script doesn't work to me on both phone and desktop... – DAVIDBALAS1 Jun 15 '16 at 13:38
  • @DAVIDBALAS1 It works for me on both mobile and desktop. Just don't change anything in it except for the comment stuff I talked about. It should work and you must attach it to the Sprite you are clicking on. – Programmer Jun 15 '16 at 13:41
  • I attached it as I showed in the question, Wondering why it doesn't work for me. – DAVIDBALAS1 Jun 15 '16 at 13:43
  • @DAVIDBALAS1 Remember this is for 2D project not 3D so make sure your project is 2D. You can verify this by creating a new project, creating a simple 2D Sprite. Attach the script to it. Make sure to un-comment the `addEventSystem()`. Let me know if that works. Drag the Sprite around. That should work. – Programmer Jun 15 '16 at 13:44
  • Actually, in a new project, I just dragged an image to create a sprite and attached the script, I also un-commented the function and it didn't work either.. I think I will just stick to the first example ... – DAVIDBALAS1 Jun 15 '16 at 13:50
  • @DAVIDBALAS1 Here you go http://wikisend.com/download/976582/DAVIDBALAS1.rar Download and run it then drag the Sprite around. If that doesn't work then you have to update your Unity version to 5.4.0.13 which the version I am using. I recommend you to use the second solution and get it working. – Programmer Jun 15 '16 at 14:01
  • All my objects are on a sprite, background sprite, maybe it caused the errors? – DAVIDBALAS1 Jun 15 '16 at 14:11
  • @DAVIDBALAS1 You never told me what happened...did the project I sent you work? – Programmer Jun 15 '16 at 14:13
  • @DAVIDBALAS1 You have to SELECT 2D when creating new Project. Do it gain but select 2D instead of 3D when creating project. – Programmer Jun 15 '16 at 14:14
  • I am sure I chose 2D when creating the project, However when I created a new project and copied your script it still didn't work to me. :( – DAVIDBALAS1 Jun 15 '16 at 14:16
  • @DAVIDBALAS1 Did you attach a collider to the Sprite? A 2D collider? Can you close Unity, zip that **SAMPLE** project you just created and upload it to the-same website I uploaded mine. I will take a look at it. This should work. – Programmer Jun 15 '16 at 14:19
  • When adding the collider in the inspector it works fine now, but when I added it programmatically ( newSprite.AddComponent(); ) it doesn't work... – DAVIDBALAS1 Jun 15 '16 at 14:25
  • @DAVIDBALAS1 U guess collider was the problem. When you add it from code check in the Editor and make sure that the collider is created during run-time when you click play. If it is created, you have to click Edit Collider button on the Collider then go to scene view instead of game view. Check if the Collder covers the Sprite. Maybe that is the problem. – Programmer Jun 15 '16 at 14:37
  • When I add some object in the inspector and not at runtime when I drag it across other objects they move too, so they won't touch each other- it means they actually have a collider.. but I can't drag them. – DAVIDBALAS1 Jun 15 '16 at 20:05