1
\$\begingroup\$

I'm studying game development in Unity and I want to create a idle/clicker game like Cow Evolution.

I'm using OnMouseDown, OnMouseDrag and OnMouseUp to move the GameObject around the scene.

Now I want to detect the collision when dropping (OnMouseUp) a GameObject over another GameObject.

Like in this video: https://www.youtube.com/watch?v=3OK77oVV_G0

Assuming there's more than one object below, I must detect which one is with most below the dropped object.

I apologize if it is difficult to understand my English.

Thank you.

\$\endgroup\$
1
\$\begingroup\$

I have achieved something like that with this script

using UnityEngine;
using UnityEngine.UI;

[RequireComponent(typeof (RectTransform))]
[RequireComponent(typeof (Image))]
public class RayCastMask : MonoSingleton<RayCastMask>, ICanvasRaycastFilter
{
    private Image _image;
    private Sprite _sprite;

    public bool IsRaycastLocationValid(Vector2 sp, Camera eventCamera)
    {
        _sprite = _image.sprite;

        var rectTransform = (RectTransform) transform;
        Vector2 localPositionPivotRelative;
        RectTransformUtility.ScreenPointToLocalPointInRectangle((RectTransform) transform, sp, eventCamera,
        out localPositionPivotRelative);

        // convert to bottom-left origin coordinates
       var localPosition = new Vector2(localPositionPivotRelative.x + rectTransform.pivot.x*rectTransform.rect.width,
        localPositionPivotRelative.y + rectTransform.pivot.y*rectTransform.rect.height);

        var spriteRect = _sprite.textureRect;
        var maskRect = rectTransform.rect;

        var x = 0;
        var y = 0;
        // convert to texture space
        switch (_image.type)
        {
            case Image.Type.Sliced:
            {
                var border = _sprite.border;
                // x slicing
                if (localPosition.x < border.x)
                {
                    x = Mathf.FloorToInt(spriteRect.x + localPosition.x);
                }
                else if (localPosition.x > maskRect.width - border.z)
                {
                    x = Mathf.FloorToInt(spriteRect.x + spriteRect.width - (maskRect.width - localPosition.x));
                }
                else
                {
                    x = Mathf.FloorToInt(spriteRect.x + border.x +
                                     ((localPosition.x - border.x)/
                                      (maskRect.width - border.x - border.z))*
                                     (spriteRect.width - border.x - border.z));
                }
                // y slicing
                if (localPosition.y < border.y)
                {
                    y = Mathf.FloorToInt(spriteRect.y + localPosition.y);
                }
                else if (localPosition.y > maskRect.height - border.w)
                {
                    y = Mathf.FloorToInt(spriteRect.y + spriteRect.height - (maskRect.height - localPosition.y));
                }
                else
                {
                    y = Mathf.FloorToInt(spriteRect.y + border.y +
                                     ((localPosition.y - border.y)/
                                      (maskRect.height - border.y - border.w))*
                                     (spriteRect.height - border.y - border.w));
                }
            }
                break;
            case Image.Type.Simple:
            default:
            {
                // conversion to uniform UV space
                x = Mathf.FloorToInt(spriteRect.x + spriteRect.width*localPosition.x/maskRect.width);
                y = Mathf.FloorToInt(spriteRect.y + spriteRect.height*localPosition.y/maskRect.height);
            }
                break;
        }

        // destroy component if texture import settings are wrong
        try
        {
            return _sprite.texture.GetPixel(x, y).a > 0;
        }
        catch (UnityException e)
        {
            Debug.LogError(
            "Mask texture not readable, set your sprite to Texture Type 'Advanced' and check 'Read/Write Enabled'");
            Destroy(this);
            return false;
        }
    }

    private void Start()
    {
        _image = GetComponent<Image>();
    }
}

Just add this script to your target and change texture type property to advanced, enable read/write and check "Alpha is transparency"

\$\endgroup\$
0
\$\begingroup\$

For getting all the colliders which are below the touch position , we need to use the RaycastAll function.

This returns an array of hits from which we can determine the GameObject which is at the farthest distance from the camera.

Also take care of the situation where no objects where detected, to avoid the null reference error.

void Update() 
    {
        if (Input.GetMouseButtonUp (0)) 
        {
            RaycastHit[] hits;
            Ray camRay = Camera.main.ScreenPointToRay(Input.mousePosition);
            hits = Physics.RaycastAll (camRay);

            Debug.Log("hits "+hits.Length);
            GameObject LastGameObject = null;

            for (int i = 0; i < hits.Length; i++) 
            {
                RaycastHit hit = hits [i];

                if(LastGameObject == null)
                {
                    LastGameObject =  hit.transform.gameObject;

                }
                else 
                {

                    if(Vector3.Distance (LastGameObject.transform.position,Camera.main.transform.position) < Vector3.Distance (hit.collider.transform.position,Camera.main.transform.position))
                    {
                        LastGameObject =  hit.transform.gameObject;
                    }
                }

            }

            if(LastGameObject)
                Debug.Log("last "+LastGameObject.name);
        }


    }
\$\endgroup\$
  • \$\begingroup\$ Hi Hash Buoy, as I learn before, I have to use Physics2D.RaycastAll, but the arguments are different. Can you fix it and show me how to do? \$\endgroup\$ – paulohr Aug 22 '15 at 13:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.