Noticias

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

Rebotes de físicas no funciona con OnMouseDrag

Iniciado por UnitySpec, Agosto 12, 2015, 12:06:15 AM

Tema anterior - Siguiente tema
Agosto 12, 2015, 12:06:15 AM Ultima modificación: Agosto 12, 2015, 01:50:03 PM por UnitySpec
 REEDITADO:Quiero que un jugador (esfera azul) se mueva en el eje X siguiendo la posición del dedo o del ratón, ignorando el eje Y y el eje Z. Para ello he utilizado la funcion OnMouseDown, y OnMouseDrag, pero este sistema entra en conflicto con las físicas. El objetivo es que podamos mover al jugador para que otros objetos reboten contra el.También hay que añadir que este sistema ignora los colliders, si se da el caso de que el collider del jugador invade el collider de una pared, o un objeto, y un tercer objeto choca con el collider jugador, provocara un fallo en las fisicas (por ejemplo el tercer objeto saldra disparado a gran velocidad) . Para evitar eso he creado un script que limita la posicion en los ejes X , Y , y Z. El eje X esta ajustado para que pueda moverse dentro de los margenes establecidos sin entrar dentro de otros colliders. En los otros ejes no hay margen de movimiento asi que permanecera en la misma posición.El problema que no consigo solucionar es que cuando estas arrastrando el jugador, las fisicas de los rebotes no se calculan bien en algunas ocasiones. Tambien es debido a que el jugador se mueve con gran velocidad debido a que sigue la posicion del puntero, y el puntero puede moverse de extremo a extremo 5 veces cada segundo si se mueve el raton o el dedo con gran velocidad. En ocasiones aun siendo arrastrado a poca velocidad rebota dos veces con el jugador en vez de una y genera una collision erronea, o bien disminuye la velocidad del objeto que rebota, o bien primero atraviesa al objeto y despues rebota al chocar con el otro extremo del collider, saliendo el rebote en otro sentido Este es el caso concreto. Un objeto padre y su hijo. Ambos con un collider. El primero que sera el que detecte la collision con el dedo, esta en una posicion Z diferente para que no choquen colliders padre hijo entre si. El padre es el que lleva asociado el script OnMouseDrag. El hijo lleva el collider que choca con las fisicas, y tiene un rigidbody y ningun tipo de scriptNota : Todos los objetos son esferas. Y lleva un sphere collider.Script OnMouseDrag: using UnityEngine;
using System.Collections;
public class MoverAzul: MonoBehaviour 
{
    
    private Vector3 screenPoint;
    Vector3 offset;        public Vector2 limitsx;
    public Vector2 limitsy;
    public Vector2 limitsz;        void Start ()
    {
        limitsz = new Vector2(-4.85f,-4.85f);
        limitsy = new Vector2(0.25f,0.25f);
        limitsx = new Vector2(-2.2f,2.2f);
        
    }    void OnMouseDown()
    {
        
        screenPoint = Camera.main.WorldToScreenPoint(gameObject.transform.position);
        
        offset = gameObject.transform.position - Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenPoint.z));
        
     
        
        
    }
    
    
    void OnMouseDrag()
    {
        
        
        
                Vector3 curScreenPoint = new Vector3 (Input.mousePosition.x, Input.mousePosition.y, screenPoint.z);
                Vector3 curPosition = Camera.main.ScreenToWorldPoint (curScreenPoint) + offset;            
                curPosition.x = Mathf.Clamp (curPosition.x, limitsx.x, limitsx.y);
                curPosition.y = Mathf.Clamp (curPosition.y, limitsy.x, limitsy.y);
                curPosition.z = Mathf.Clamp (curPosition.z, limitsz.x, limitsz.y);    
                
        //mover con transform
        transform.position = curPosition;
         
        
        
    }   ¿Como puedo hacer que un objeto siga la posicion del dedo y a su vez las fisicas funcionen correctamente sin dar este tipo de problemas? Aqui adjunto el proyecto unity con solo esa escena y los scripts que intervienen en ella.(Se genera un error de respawn durante la ejecución, ignorarlo) 
http://unityspain.com/applications/core/interface/file/attachment.php?id=8297">Unity Fisico.rar


[quote author=iRobb" data-ipsquote-contapp="forums" data-ipsquote-contenttype="forums" data-ipsquote-contentclass="forums_Topic" data-ipsquote-contentid="15952" data-ipsquote-contentcommentid="101482 date=1439349640]Pasa una escena y lo pruebo.[/quote]He reeditado el post para ser mas claro y concisoHe añadido el proyecto con la escena

Bueno, de entrada al lanzarlo, te está dando un montón de errores al tratar de acceder a un objeto que no contiene el componente DirRebote, ya que en el collider no compruebas que sea una bola. Se corrige así:    void OnCollisionEnter(Collision Objeto)
    {
        if (Objeto.gameObject.tag == "bola") {
            int aleatorio = Random.Range(1, 5);
            //print (aleatorio);
            switch (aleatorio) {
                case 1: Objeto.gameObject.GetComponent<DirRebote>().salida1 = true;
                    Objeto.transform.position = respawn1.transform.position; break;
                case 2: Objeto.gameObject.GetComponent<DirRebote>().salida2 = true;
                    Objeto.transform.position = respawn2.transform.position; break;
                case 3: Objeto.gameObject.GetComponent<DirRebote>().salida3 = true;
                    Objeto.transform.position = respawn3.transform.position; break;
                case 4: Objeto.gameObject.GetComponent<DirRebote>().salida4 = true;
                    Objeto.transform.position = respawn4.transform.position; break;
            }
        }
    }La línea         if (Objeto.gameObject.tag == "bola") {
para asegurarse que es una bola, ya que tienes el tag marcado.A partir de aquí, me comentas. 

[quote author=iRobb" data-ipsquote-contapp="forums" data-ipsquote-contenttype="forums" data-ipsquote-contentclass="forums_Topic" data-ipsquote-contentid="15952" data-ipsquote-contentcommentid="101508">Bueno, de entrada al lanzarlo, te está dando un montón de errores al tratar de acceder a un objeto que no contiene el componente DirRebote, ya que en el collider no compruebas que sea una bola. Se corrige así:    void OnCollisionEnter(Collision Objeto)
    {
        if (Objeto.gameObject.tag == "bola") {
            int aleatorio = Random.Range(1, 5);
            //print (aleatorio);
            switch (aleatorio) {
                case 1: Objeto.gameObject.GetComponent<DirRebote>().salida1 = true;
                    Objeto.transform.position = respawn1.transform.position; break;
                case 2: Objeto.gameObject.GetComponent<DirRebote>().salida2 = true;
                    Objeto.transform.position = respawn2.transform.position; break;
                case 3: Objeto.gameObject.GetComponent<DirRebote>().salida3 = true;
                    Objeto.transform.position = respawn3.transform.position; break;
                case 4: Objeto.gameObject.GetComponent<DirRebote>().salida4 = true;
                    Objeto.transform.position = respawn4.transform.position; break;
            }
        }
    }La línea         if (Objeto.gameObject.tag == "bola") {

Así me funciona a mí. No veo errores de detección. Si lo ves correcto, te digo lo que me parece a mí.
http://unityspain.com/applications/core/interface/file/attachment.php?id=8300">Unity 2015-08-13 11-00-43-26.mkv

[quote author=iRobb" data-ipsquote-contapp="forums" data-ipsquote-contenttype="forums" data-ipsquote-contentclass="forums_Topic" data-ipsquote-contentid="15952" data-ipsquote-contentcommentid="101531">Así me funciona a mí. No veo errores de detección. Si lo ves correcto, te digo lo que me parece a mí.

Bájate fraps, que es para capturar videojuegos, aunque deberías tener algún conversor de vídeo ya que los genera enormes los vídeos. Yo los convierto a algo muy enano con StaXRip, pero ya es un programita más complicado si no sabes de encoding/decoding.

[quote author=iRobb" data-ipsquote-contapp="forums" data-ipsquote-contenttype="forums" data-ipsquote-contentclass="forums_Topic" data-ipsquote-contentid="15952" data-ipsquote-contentcommentid="101533 date=1439457454]Bájate fraps, que es para capturar videojuegos, aunque deberías tener algún conversor de vídeo ya que los genera enormes los vídeos. Yo los convierto a algo muy enano con StaXRip, pero ya es un programita más complicado si no sabes de encoding/decoding.[/quote]Lo tengo, no sabia que grababa. Ahora te paso un video entonces. Y Lo convierto con Xmedia Recode.Las bolas se te han ido de la escena en tu video, te recomiendo que vuelvas a usar el proyecto orginal, sin modificar el codigo, y para solucionar el error que daba, simplemente añade dirRebote a bola exit, y desactivala, ( o bien desactivandola es suficiente, esa bola es inecesaria) 

[quote author=UnitySpec" data-ipsquote-contapp="forums" data-ipsquote-contenttype="forums" data-ipsquote-contentclass="forums_Topic" data-ipsquote-contentid="15952" data-ipsquote-contentcommentid="101534">Lo tengo, no sabia que grababa. Ahora te paso un video entonces. Y Lo convierto con Xmedia Recode.Las bolas se te han ido de la escena en tu video, te recomiendo que vuelvas a usar el proyecto orginal, sin modificar el codigo, y para solucionar el error que daba, simplemente añade dirRebote a bola exit, y desactivala, ( o bien desactivandola es suficiente, esa bola es inecesaria) [/quote]Listo. Concretamente mira el caso en el segundo 5 al segundo 7 , y en el segundo 17 hasta el final.Puedes verlo frame por frame y veras que atraviesa las bolas sin generar colision.Unity 2015-08-13 11-23-27-56.mp4

Elimina ese código del collider que te genera error y vuelve a probar. Lo digo porque, yo me he encontrado que cuando hay errores de excepciones null ya no funciona todo igual. Y sí, veo que no choca en el 5 sobretodo cuando ya casi sale la bola del suelo. 

[quote author=iRobb" data-ipsquote-contapp="forums" data-ipsquote-contenttype="forums" data-ipsquote-contentclass="forums_Topic" data-ipsquote-contentid="15952" data-ipsquote-contentcommentid="101536 date=1439460744]Elimina ese código del collider que te genera error y vuelve a probar. Lo digo porque, yo me he encontrado que cuando hay errores de excepciones null ya no funciona todo igual. Y sí, veo que no choca en el 5 sobretodo cuando ya casi sale la bola del suelo. [/quote]Ya tengo el codigo limpio sin errores cuando he hecho el video, en la escena original sigue pasando, y en otros proyectos y escenas diferentes con otros scripts, sigue pasando lo mismo. Nose si conoceras alguna solución o otra forma alternativa de usar la posicion del puntero de forma que esto no suceda. 

Si hay otra solución, más compleja pero puede ser más precisa:Desactivar los colliders creando una layer para las bolas que en el physics editor marques como no colisión. Luego utilizar raycast en el update para detectar las colisiones.Pero claro, creo que tendrás que aplicar tu la física después sobre el objeto, con AddForce sería lo recomendable. 

[quote author=iRobb" data-ipsquote-contapp="forums" data-ipsquote-contenttype="forums" data-ipsquote-contentclass="forums_Topic" data-ipsquote-contentid="15952" data-ipsquote-contentcommentid="101538 date=1439462188]Si hay otra solución, más compleja pero puede ser más precisa:Desactivar los colliders creando una layer para las bolas que en el physics editor marques como no colisión. Luego utilizar raycast en el update para detectar las colisiones.Pero claro, creo que tendrás que aplicar tu la física después sobre el objeto, con AddForce sería lo recomendable. [/quote]Bastante complejoRealmente el problema es el OnMouseDrag, algo deberia haber para mejorar la precisión de la posicion del puntero. He probado poniendo las fisicas en contiunous dynamic pero es indiferente.Si no hay otra alternativa, supongo que usare un control "Touchpad deslizante" del siguiente tipo, pero realmente no se como se hace, sabrias asesorarme sobre ello? (Ver imagen adjunta)Segun este metodo, si pulsas izquierda (un toque y levantar el click) el jugador se movera hacia la izquierda un poco y se detendra, y viceversa. Si arrastras hacia un lado tambien se movera, y si mantienes el click en la derecha o la izquiera, se movera hacia donde permanezca el click. Pero digamos que con este metodo, el control no se puede volver loco, ya que el jugador no puede sobrepasar cierta velocidad. Al igual que si tuvieras un jostick y lo movieras bruscamente el jugador solo se mueve por "toques". Nose explicarme mejor. 

En los standard assets de Unity hay control visual TouchPad (y otros) a utilizar con un código llamado CrossPlatformInput (para usar igual en PC que en mobile). Aunque te parezca un poco complicado al principio, cuando los domines, te quitarán un montón de horas de trabajo. Hay scenes de ejemplo.

Etiquetas: