Reputation: 235
I'm developing an app that has many balls that float around but do not collide with each other. This means they overlap a lot. I've got it so if you click/touch the balls, they are destroyed. However, if one ball is behind another, this one is not destroyed until the one in front is cleared.
The above diagram shows what I'm looking for, if the user clicks/touches at position x, then destroy all the objects, not just the most forward of them. Any help much appreciated.
Here's my input script:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class TouchInput : MonoBehaviour {
public LayerMask touchInputMask;
private List<GameObject> touchList = new List<GameObject> ();
private GameObject[] touchesOld;
private RaycastHit2D hit;
void Update () {
#if UNITY_EDITOR
if (Input.GetMouseButton(0) || Input.GetMouseButtonDown(0) || Input.GetMouseButtonUp(0)) {
touchesOld = new GameObject[touchList.Count];
touchList.CopyTo (touchesOld);
touchList.Clear ();
hit = Physics2D.Raycast(Camera.main.ScreenToWorldPoint(Input.mousePosition), Vector2.zero, touchInputMask);
//Ray ray = Camera.main.ScreenPointToRay (Input.mousePosition);
if (hit) {
GameObject recipient = hit.transform.gameObject;
touchList.Add (recipient);
if (Input.GetMouseButtonDown(0)) {
recipient.SendMessage ("OnTouchDown",hit.point,SendMessageOptions.DontRequireReceiver);
}
if (Input.GetMouseButtonUp(0)) {
recipient.SendMessage ("OnTouchUp",hit.point,SendMessageOptions.DontRequireReceiver);
}
if (Input.GetMouseButton(0)) {
recipient.SendMessage ("OnTouchStay",hit.point,SendMessageOptions.DontRequireReceiver);
}
}
foreach (GameObject g in touchesOld) {
if (!touchList.Contains (g)) {
if(g!=null) {
g.SendMessage ("OnTouchExit", hit.point, SendMessageOptions.DontRequireReceiver);
}
}
}
}
#endif
if (Input.touchCount > 0) {
touchesOld = new GameObject[touchList.Count];
touchList.CopyTo (touchesOld);
touchList.Clear ();
foreach (Touch touch in Input.touches) {
hit = Physics2D.Raycast(Camera.main.ScreenToWorldPoint(Input.mousePosition), Vector2.zero, touchInputMask);
if (hit) {
GameObject recipient = hit.transform.gameObject;
touchList.Add (recipient);
if (touch.phase == TouchPhase.Began) {
recipient.SendMessage ("OnTouchDown",hit.point,SendMessageOptions.DontRequireReceiver);
}
if (touch.phase == TouchPhase.Ended) {
recipient.SendMessage ("OnTouchUp",hit.point,SendMessageOptions.DontRequireReceiver);
}
if (touch.phase == TouchPhase.Stationary) {
recipient.SendMessage ("OnTouchStay",hit.point,SendMessageOptions.DontRequireReceiver);
}
if (touch.phase == TouchPhase.Canceled) {
recipient.SendMessage ("OnTouchExit",hit.point,SendMessageOptions.DontRequireReceiver);
}
}
}
foreach (GameObject g in touchesOld) {
if (!touchList.Contains (g)) {
if (g != null) {
g.SendMessage ("OnTouchExit", hit.point, SendMessageOptions.DontRequireReceiver);
}
}
}
}
}
}
And on the ball I simply have a:
void OnTouchDown() {
KillBall ();
}
void OnTouchStay() {
KillBall ();
}
Upvotes: 2
Views: 1332
Reputation: 235
Answer provided by @Savlon, so thanks for that :)
private RaycastHit2D[] hits;
...
hits = Physics2D.RaycastAll(Camera.main.ScreenToWorldPoint(Input.mousePosition), Vector2.zero, touchInputMask);
foreach(RaycastHit2D hit in hits) {
GameObject recipient = hit.transform.gameObject;
touchList.Add (recipient);
if (Input.GetMouseButtonDown(0)) {
recipient.SendMessage ("OnTouchDown",hit.point,SendMessageOptions.DontRequireReceiver);
}
if (Input.GetMouseButtonUp(0)) {
recipient.SendMessage ("OnTouchUp",hit.point,SendMessageOptions.DontRequireReceiver);
}
if (Input.GetMouseButton(0)) {
recipient.SendMessage ("OnTouch",hit.point,SendMessageOptions.DontRequireReceiver);
}
}
Upvotes: 1