Unity: touch object raycast problem


#1

Może mi ktoś wytłumaczyć dlaczego jak dotknę obiekt z tym skryptem to pozostałe obiekty z tym samym skryptem też reagują na dotknięcie?
private bool button = false;

// Use this for initialization
void Start () {



// Update is called once per frame
void Update () {

	RaycastHit hit = new RaycastHit();
	for (int i = 0; i < Input.touchCount; ++i) {
		if (Input.GetTouch(i).phase.Equals(TouchPhase.Began)) {
			// Construct a ray from the current touch coordinates
			Ray ray = Camera.main.ScreenPointToRay(Input.GetTouch(i).position);
			if (Physics.Raycast(ray, out hit)) {
				hit.transform.gameObject.SendMessage ("");
				if (button) {
					 {
						transform.position += new Vector3 (0, 0, 30);
						button = false;
					}
				} else {
					 {
						transform.position += new Vector3 (0, 0, -30);
						button = true;
					}
				} 
			}
		}
	}
}

}

Dla przykładu: robię 4 kostki i do każdej dołączam ten skrypt. Jak dotknę jedną to reagują wszystkie. O co chodzi?
Próbowałem też zastąpić out hit na (hit.collider.CompareTag (“tag1”)) i jednej kostce ustawiłem właśnie taki tag.
Efekt był taki że na dotyk reagowała tylko ta jedna z tagiem1 ale po dotknięciu poruszały się wszystkie no WTF?


#2

Physics.Raycast zwraca true wtedy kiedy w coś trafi. Twoim zadaniem jest sprawdzić w co trafił a tego nie robisz. Zadziała jeżeli zmienisz kod tak:

if (Physics.Raycast(ray, out hit)) {
   if (hit.tag == "blabla") {
...

Inna sprawa, że takie podejście nie jest dobre i strasznie nie wydajne. Raycast jest operacją czasochłonna i nie powinna być oddzielnie uruchamiana w każdym obiekcie. Można to zrobić raz w jakimś skrypcie nadrzędnym. Jednak najlepiej będzie jeżeli oprzesz to o EvenSystem i użyjesz IPointerClickHandler.


#3

A możesz mi wytłumaczyć dlaczego jak dotknę obiekt z tagiem 1 to zaczynają się poruszać obiekty z innymi tagami?


#4

Zrób to tak: Do obiektu dołącz ten skrypt:

using UnityEngine;
using UnityEngine.EventSystems;

public class ClickableObject : MonoBehaviour, IPointerDownHandler, IPointerUpHandler
{
    public void OnPointerDown(PointerEventData eventData)
    {
        transform.position += new Vector3(0, 0, 1);
    }

    public void OnPointerUp(PointerEventData eventData)
    {
        transform.position -= new Vector3(0, 0, 1);
    }
}

Dodaj do projektu EventSystem (menu Create->UI->EventSystem).
Do kamery dodaj komponent Raycaster (dla obiektów 3d to będzie PhysicsRaycaster).

W ten sposób wykorzystujesz system stworzony pod UI, który jest wygodny i łatwo go rozszerzyć o kolejne funkcjonalności. Możesz dodatkowo zaimplementować interfesy IPointerClickHandler, IPointerExitHandler, PointerEnterHandler i kilka innych bardzo przydatnych. Wszystko znajdziesz w domuentacji API w rozdziale UnityEngine.EventSystems.