Noticias

¡RECUERDA QUE SI ERES UN NUEVO USUARIO, DEBES PRESENTARTE PARA PODER PUBLICAR MENSAJES! | TENEMOS CANAL OFICIAL DE TELEGRAM: t.me/unity3dspain

Problema con los eventos Touch

Iniciado por WalterScript, Septiembre 06, 2018, 05:28:58 PM

Tema anterior - Siguiente tema
Septiembre 06, 2018, 05:28:58 PM Ultima modificación: Septiembre 06, 2018, 05:30:16 PM por WalterScript
Buenas tardes, me encuentro haciendo un juego en 2D y me ha surgido una duda con los eventos Touch pero también con los Raycast para detectar en este caso el collider que estás pulsando.
 
Tengo un sprite 2D que quiero mover por el escenario del juego y conseguí hacerlo pero con colliders 3D ya que era lo que me pareció más sencillo utilizando Raycast y los eventos de Touch(Began, Moved y Ended). El problema llega cuando he intentado convertir esto para colliders 2D ya que ahí tengo edge collider para ajustar el perímetro a mi objeto en 2D. He probado con Raycast2D pero no hay manera de conseguir que con los eventos Touch y un collider 2D se mueva el objeto.
 
Os dejo el código que tengo ahora mismo y con el que me funciona si tengo colliders 3D.
 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]
public class Boundary
{
    public float xMin, xMax, yMin, yMax;
}
public class TouchManager : MonoBehaviour {
    GameObject gObj = null;
    Plane objPlane;
    Vector3 m0;
    public Boundary boundary;
    Ray GenerateMouseRay(Vector3 touchPos)
    {
        Vector3 mousePosFar = new Vector3(touchPos.x, touchPos.y, Camera.main.farClipPlane);
        Vector3 mousePosNear = new Vector3(touchPos.x, touchPos.y, Camera.main.nearClipPlane);
        Vector3 mousePosF = Camera.main.ScreenToWorldPoint(mousePosFar);
        Vector3 mousePosN = Camera.main.ScreenToWorldPoint(mousePosNear);
        Ray mr = new Ray(mousePosN, mousePosF-mousePosN);
        return mr;
    }
 
    // Update is called once per frame
    void FixedUpdate ()
    {
        if(Input.touchCount > 0)
        {
            if(Input.GetTouch(0).phase == TouchPhase.Began)
            {
                Ray mouseRay = GenerateMouseRay(Input.GetTouch(0).position);
                RaycastHit hit;
                if(Physics.Raycast(mouseRay.origin, mouseRay.direction, out hit))
                {
                    gObj = hit.transform.gameObject;
                    objPlane = new Plane(Camera.main.transform.forward*-1, gObj.transform.position);
                    //calc touch offset
                    Ray mRay = Camera.main.ScreenPointToRay(Input.GetTouch(0).position);
                    float rayDistance;
                    objPlane.Raycast(mRay, out rayDistance);
                    m0 = gObj.transform.position - mRay.GetPoint(rayDistance);
                }
            }
            else if(Input.GetTouch(0).phase == TouchPhase.Moved && gObj)
            {
                Ray mRay = Camera.main.ScreenPointToRay(Input.GetTouch(0).position);
                float rayDistance;
                if(objPlane.Raycast(mRay, out rayDistance))
                {
                    gObj.transform.position = new Vector3(Mathf.Clamp(mRay.GetPoint(rayDistance).x + m0.x, boundary.xMin, boundary.xMax),
                                                          Mathf.Clamp(mRay.GetPoint(rayDistance).y + m0.y, boundary.yMin, boundary.yMax));
                }
            }
            else if(Input.GetTouch(0).phase == TouchPhase.Ended && gObj)
            {
                gObj = null;
            }
        }
    }
}

 
Muchas gracias!

Hola,  que subás el código actual en 3D no ayuda de mucho, tendrías que haber subido el que te estaba dando problemas.
 
Cita de: WalterScript date=1536247738He probado con Raycast2D pero no hay manera de conseguir que con los eventos Touch y un collider 2D se mueva el objeto
   


El "raycast2D" es el raycast de Physics2D, para que esto funcione necesitas un RayCastHit2D (ahora que me doy cuenta se llaman raycastHit quizás podrían haberle puesto un mejor nombre como HitInfo o parecido) esto funciona solo para colliders2D. La parte del Touch simplemente relaciona a las inputs, por lo que si vas a hacer un raycast (o similar) necesitas una posición bidimensional(partis del touch) y colliders2D disponibles, no se si acá es donde tenés problemas.
 
 
 
El método que usas es muy usado, el plano de frente (creo) y el ray colisionando, para usarlo en 2D podés usar lo que estás haciendo o simplemente, en vez de crear un Ray (screenPointToRay) creas un punto o un vector2(ScreenToWorldPoint) ya que ninguna signature de "RayCast2D" toma un ray, la dirección es aproximadamente forward de la cámara para un nearPlane bajo -> 0:
 

//Sacado de la doc oficial
p = cam.ScreenToWorldPoint(new Vector3(x, y, cam.nearClipPlane));

 
con x e y la coordenadas de la pantalla, podrías sacarlas con : https://docs.unity3d.com/ScriptReference/Touch-position.html
 
Luego hacer el Raycast con este punto "p" hacia adelante y debería funcionar.
 
No se por que usas FixedUpdate, en materia de inputs siempre se recomienda Update, necesitas velocidad de respuesta, lo que dé.
 
Saludos

Muchas gracias por responder @lightbug ! Finalmente lo he conseguido con las pistas que me has dado 

Etiquetas: