Noticias

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

Mover objeto hijo dentro de padre segun posision de pantalla

Iniciado por Mac, Febrero 18, 2016, 06:18:20 PM

Tema anterior - Siguiente tema
 Hola amigos primero que nada, saludarlos y agradecer su ayuda de antemano, soy nuevo en este foro y un poco nuevo también con unity, estoy desarrollando un juego y necesito resolver un problema que es el siguiente: Adjunto una imagen para que se entienda mejor el problema.
Tengo un objeto-hijo dentro del padre y lo que necesito hacer es que cuando el usuario toque cualquier posición de la pantalla, el objeto-hijo se dirija a esa posición de la pantalla pero sin salirse de su padre, por ejemplo:
Si el usuario toca la pantalla en la parte superior el objeto hijo vaya a la parte superior del padre pero sin salir de sus fronteras y así con cualquier posición de la pantalla.
El juego es en 2D y he intentado varios métodos utilizando el Distance Join  2D o restando la distancia del objeto-padre a la posición del touch y luego restando a la nueva posición del objeto-hijo pero no logro conseguirlo. Alguien sabe si hay algún componente especial que permita mantener al hijo dentro del padre o que formula o método podría utilizar?Agradezco mucho su ayuda y saludo nuevamente a todos.
Gracias.

El objeto padre siempre es un cuadrado o rectangulo??? Si es asi podrias usar Mesh.Bounds o Renderer.Bounds para calcular el limite .Tambien podrias lanzar raycast en la direccion en la que se mueve el hijo para mirar la distancia ,aunque diria que si es por rgidbodies pues con que le pongas colliders al objeto padre  ya tendria que funcionar.

Muchas gracias Hammer te agradesco tu comentario, el objeto padre tambien podria ser sircular, intentare lo que dices a ver si me funciona. Saludos.

Febrero 18, 2016, 09:05:52 PM #3 Ultima modificación: Febrero 18, 2016, 09:08:08 PM por hammer
Ojo, cuando digo que le pongas colliders ,me re fereria poniendolos tu a mano, si es un circulo puede ser un coñazo,xD Puedes ponerle al padre un meshCollider solo que el mesh que le pongas como collider tendra que ser el mismo mesh que el padre,obvio, pero con las normales invertidas para que funcione.Como Blender  tarda mucho en renderizar y me aburro mucho te  lo pongo. xD
using UnityEngine;
using System.Collections;
public class SetMeshCollider : MonoBehaviour {

void Start(){
   SetCollider();
}
void SetCollider(){


   MeshFilter filter = GetComponent(typeof (MeshFilter)) as MeshFilter;
   if (filter != null)
   {
      Mesh meshCollider = new Mesh ();
         
      meshCollider.vertices = filter.mesh.vertices;
      meshCollider.normals = filter.mesh.normals;
      meshCollider.uv = filter.mesh.uv;
      meshCollider.triangles = filter.mesh.triangles;
      meshCollider.tangents = filter.mesh.tangents;
      meshCollider.Optimize ();

      Vector3[] normals = meshCollider.normals;
      for (int i=0;i<normals.Length;i++)
         normals = -normals;
      meshCollider.normals = normals;

      for (int m=0;m<meshCollider.subMeshCount;m++)
      {
         int[] triangles = meshCollider.GetTriangles(m);
         for (int i=0;i<triangles.Length;i+=3)
         {
            int temp = triangles[i + 0];
            triangles[i + 0] = triangles[i + 1];
            triangles[i + 1] = temp;
         }
         meshCollider.SetTriangles(triangles, m);
      }


      MeshCollider _collider = GetComponent<MeshCollider> ();
      if (_collider != null) {
         _collider.sharedMesh = meshCollider;
      } else
         gameObject.AddComponent<MeshCollider> ().sharedMesh = meshCollider;
   }      

}
}
Asi choca con el interior de un mesh, lo de invertir las normales lo he sacado de google, solo he actualizado para que lo ponga en el meshcolliderhttp://wiki.unity3d.com/index.php/ReverseNormals">http://wiki.unity3d.com/index.php/ReverseNormals

[quote author=hammer" data-ipsquote-contapp="forums" data-ipsquote-contenttype="forums" data-ipsquote-contentclass="forums_Topic" data-ipsquote-contentid="35216" data-ipsquote-contentcommentid="127332">Ojo, cuando digo que le pongas colliders ,me re fereria poniendolos tu a mano, si es un circulo puede ser un coñazo,xD Puedes ponerle al padre un meshCollider solo que el mesh que le pongas como collider tendra que ser el mismo mesh que el padre,obvio, pero con las normales invertidas para que funcione.Como Blender  tarda mucho en renderizar y me aburro mucho te  lo pongo. xD
using UnityEngine;using System.Collections;
public class SetMeshCollider : MonoBehaviour {

void Start(){
   SetCollider();
}
void SetCollider(){


   MeshFilter filter = GetComponent(typeof (MeshFilter)) as MeshFilter;
   if (filter != null)
   {
      Mesh meshCollider = new Mesh ();
         
      meshCollider.vertices = filter.mesh.vertices;
      meshCollider.normals = filter.mesh.normals;
      meshCollider.uv = filter.mesh.uv;
      meshCollider.triangles = filter.mesh.triangles;
      meshCollider.tangents = filter.mesh.tangents;
      meshCollider.Optimize ();

      Vector3[] normals = meshCollider.normals;
      for (int i=0;i<normals.Length;i++)
         normals[i] = -normals[i];
      meshCollider.normals = normals;

      for (int m=0;m<meshCollider.subMeshCount;m++)
      {
         int[] triangles = meshCollider.GetTriangles(m);
         for (int i=0;i<triangles.Length;i+=3)
         {
            int temp = triangles[i + 0];
            triangles[i + 0] = triangles[i + 1];
            triangles[i + 1] = temp;
         }
         meshCollider.SetTriangles(triangles, m);
      }


      MeshCollider _collider = GetComponent<MeshCollider> ();
      if (_collider != null) {
         _collider.sharedMesh = meshCollider;
      } else
         gameObject.AddComponent<MeshCollider> ().sharedMesh = meshCollider;
   }      

}
}
Asi choca con el interior de un mesh, lo de invertir las normales lo he sacado de google, solo he actualizado para que lo ponga en el meshcolliderhttp://wiki.unity3d.com/index.php/ReverseNormals">http://wiki.unity3d.com/index.php/ReverseNormals[/quote]Muchas gracias nuevamente por tu respuesta Hammer, si veo que con los círculos es un coñazo como dices xD, Ahora el problema que veo es que creo que para los Juegos en 2D no puedo utilizar el Mesh collinder no me aparece en las Physics 2D solo en las Physics normales, no si le aplico el meshCollinder al 2D funcionara?, he estado intentado de varias formas mantener al hijo dentro del padre y que este llegue a los bounds del padre pero siempre en la misma dirección del Input.GetTouch (ID).position pero como dices es un coñazo :(, probare si no hay problemas aplicando el meshCollinder al 2D.
Saludos. 

xD no funcionara, solo 3D, si es en 2D pos con edgeCollider2D,le das la forma que quieras muy facilmente.

Ok si lo imaginaba, gracias lo pruebo y os digo como me va.Saludos y muchas gracias.

OK Ok Hammer, funciono muy bien el edgeCollider2D, ya logre mantener el hijo dentro del padre, solo que ahora tengo problemas en hacer que el hijo se mueva en la dirección de la pantalla y no sobrepase al padre ya que el edgeCollider2D lo retinen pero necesito que llegue exactamente al borde y se quede ahí porque si mantengo arrastrando el dedo en la pantalla traspasa hacia el touchposition, sabes cómo puedo decirle al hijo que siga el touch position pero que no se salga del Bounds del padre?.
 El efecto que deseo lograr es algo así como que la pupila sigua la posición del dedo sin salirse del ojo.
Muchas gracias por todo te agradezco tu ayuda.

Pues lanza un raycast en la direccion en la que vayas a mover el hijo justo antes de moverlo para ver la distancia hasta el collider del padre, si esta muy cerca que no se mueva.Para sacar el vector de direcion pues hijoposition - touchposition.

Ok gracias, probare de esa forma ya que con los  Renderer.Bounds  y collider.Bounds  no lo he logrado siempre se pasa de los limites.Saludos.

Hola, logre hacer lo que necesito con el raycast muchas gracias, solo que ahora tengo un problema al utilizar los collider cuand el hijo colisiona con el padre hay un efecto de rebote, no hay problema si el usuario únicamente hace un touch porque al colisionar desactivo que el hijo que se siga moviendo, pero por ejemplo si el usuario mantiene presionado el dedo o hacer un drag, el hijo hace un efecto de rebote, lo único que se me ocurre para evitar esto es calcular que no llegue a colisionar si no a una distancia cerca del collider del padre, pero como podría realizar esta comprobación?, o en último caso eliminar los collider y únicamente realizar los Renderer.Bounds pero hasta el momento no he logrado conseguirlo, si tienen alguna idea o cómo puedo evitar el efecto de rebote cuando colisionan o la forma de calcular que este cerca de los Renderer.Bounds  les agradecería mucho la ayuda.
Saludos. 

Los bounds,como decirlo, es como el espacio maximo de un obejto,su punto mas alto,el mas ancho, y el mas profundo, siempre sera un cuadrado o un rectangulo,en este caso no te sirve,culpa mia que me fije en el dibujo,olvidate de ellos.El raycast es para hacer lo que quieres, lanzas un  raycast desde la posicion del hijo en la direccion que te vayas a mover, este te devolvera un punto de colision,sabiendo la posicion del hijo y la posicion donde ha chocado el raycast haces un Vector3.Distance y te devolvera un float con la distancia entre un punto y otro, si ves que es muy pequeña no mueves al hijo.cheers!

Etiquetas: