Jump to content
UnitySpain

Search the Community

Showing results for tags 'aporte'.



More search options

  • Search By Tags

    Type tags separated by commas.
  • Search By Author

Content Type


Forums

  • Inicio
    • Proyectos
    • Offtopic
    • Unity Feeds
    • Website
  • Mesa de ayuda
    • Unity
    • Arte
    • Otras Especialidades
    • Builds & Dispositivos
  • Aportes de la Comunidad
    • Recursos
    • Eventos
    • Buenas Prácticas
  • Bolsa de trabajo & Colaboraciones
    • Ofertas y Demandas
  • Post Antiguos
    • General (Antiguo)

Blogs

  • byGui
  • El Blog de Pioj

Find results in...

Find results that contain...


Date Created

  • Start

    End


Last Updated

  • Start

    End


Filter by number of...

Joined

  • Start

    End


Group


Especialidad

Found 26 results

  1. ¡Hola a todos! Buscando mis assets por Google encontré una página que monitoriza los precios de todos los assets del Asset Store de Unity. Hay dos tipos de rebajas en el Unity Asset Store: Rebajas oficiales. Aquellas que selecciona Unity y aparecen con el precio original tachado y debajo el precio final aplicando el descuento. Los assets tienen que reunir unos requisitos para ser seleccionados para estas rebajas. Rebajas personales. Aquellas que te permiten hacer por tu cuenta siempre y cuando cumplas con unas normas como que debe de aparecer en la descripción el precio original ya que en este caso el precio rebajado es el que aparece directamente en el asset sin tachar (más info de las normas en el apartado 2.7.1 de sus Submission Guidelines). La página oficial del Asset Store sólo te permite buscar las rebajas oficiales pero no las personales. Lo bueno de esta web que encontré es que te permite buscar tanto las oficiales como las personales e incluso te dice los assets que han pasado a ser gratis. No sé si ya la conocíais pero os dejo aquí los links: Rebajas personales de lanzamiento: https://www.gameassetdeals.com/?show=launchsale Assets que han pasado a ser gratis: https://www.gameassetdeals.com/?show=nowfree
  2. Hola, He creado unos pocos vídeos de programación básica de NPC's, o programación de NPC's básicos. La intención es ir creando mas de esta tématica, sin obligación, y de tanto en tanto, pero irlos agrupando en la misma lista de visualización de youtube: Aquí os la dejo: Por ahora hay tres vídeos, o 2.5 por que el último es un poco ampliación del primero. -Como crear NPC's en Unity que te siguen. -Creamos un centinela con Waypoints en Unity, -Como hacer un NC persiga y huya en modo pánico. Ya ire informando de nuevas incorporaciones a la lista :-)
  3. Hola a todos, mi nombre es David y este es el primero de una serie de tutoriales sobre Unity3D. Esta iniciativa surge del programa Unity Student Ambassador y están creados por mi inicialmente para workshops presenciales. Los he adaptado a este formato pero si tienes cualquier duda no dudes en preguntarme. Espero que os guste. Introducción ¿Que es Shader Graph? La creación de shaders en Unity ha sido tradicionalmente el terreno de juego de personas con habilidades para programar. Shader Graph abre el campo para artistas y otros miembros del equipo para que la creación de shaders sea mucho más sencilla. Solo conecta nodos en una red gráfica y podrás ver los cambios al instante. Requisitos El Shader Graph está disponible desde Unity 2018.1. Está diseñado para funcionar con otra característica de Unity 2018.1: Scriptable Render Pipeline (SRP). Por lo tanto, no puede usarlo con el Built-In Unity Renderer. Tiene por tanto soporte tanto para LWRP como para HDRP (o para su propio SRP). Para este tutorial usaré la versión 2019.2.9f1. ¡Comencemos! Lo primero que necesitamos es abrir Unity y crear un nuevo proyecto. Asegúrese de que elige usar el nuevo SRP. En nuestro caso elegiremos el LWRP. Confirmamos y esperamos que Unity lo prepare todo. Una vez dentro de Unity ya podemos ponernos a trabajar. Por defecto debería tener incluido el paquete Shader Graph. Puedes comprobar ese y otros paquetes instalados en Windows/Package Manager. Nuestro primer Shader En la ventana Project, pulsamos el botón y elegimos Create/Shader/PBR Graph. Si queréis conocer más acerca del PBR está es una buena guía: https://blog.teamtreehouse.com/beginners-guide-physically-based-rendering-unity Nombramos el archivo con el nombre que queráis. En este caso le llamaremos Standard_Color. Ya tendríamos nuestro primer Shader creado, vamos abrirlo. Lo seleccionamos y en la ventana Inspector pulsamos Open Shader Editor. Si todo ha ido bien, deberíamos ver esto: Dentro del Shader Editor podemos ver tres sectores claramente diferenciados: PBR Master Node: Es el nodo principal, al que acaban llegando todos los demás. Es el encargado de mostrar las características en el material. BlackBoard: Puedes activarlo y desactivarlo arriba a la derecha. Es donde creas y guardas las propiedades que necesitas usar. Encontrarás Colores, Vectores, Texturas etc… Estas pueden aparecer en el inspector del material para ser usadas más adelante. Preview: Es la previsualización actual de la entrada del PBR Master Node. Puedes cambiar el tipo de renderización pulsando el botón derecho. (Cubo, quad,sphere…) Una vez conocemos las partes vamos a añadirle funcionalidad a nuestro nuevo Shader. Comencemos añadiendo color. Vamos a abrir el Blackboard y vamos a pulsar en el +. Con esto podremos crear una variable de entre las que Shader Graph nos ofrece. En este caso elegiremos Color. Ahora podremos cambiarle el nombre, pero en nuestro caso lo dejaremos tal y como está, con el nombre Color, que al fin y al cabo es lo que será para nosotros. El toggle de Exposed indica si quieres que esa variable aparezca posteriormente en el material para ser editada de forma rápida. En nuestro caso así lo queremos así que la dejamos marcada. En Default puedes elegir el color que desees por defecto, como he dicho podrás cambiarlo después en el material pero si quieres ver como queda en el Shader Editor tendrás que cambiarlo aquí. Por último el Mode te permite establecer el color como HDR. Puedes hacer efectos realmente atractivos con esto pero de momento lo dejaremos como está. Una vez creado nuestro Color vamos a arrastrarlo hacia el Grid donde esta el PBR Master y lo soltamos. Como vemos este nodo Color solo tiene una salida, conectamos la salida con la entrada de Albedo. Si habías cambiado el color default verás que la Preview ahora aparece de otro color. Sino puedes ir ahora y cambiarlo. Una vez hecho esto pulsamos arriba a la izquierda en Save Asset y podemos cerrar el editor. Ahora solo nos falta ver nuestro shader en pantalla. Para esto añadimos una esfera a la escena y creamos un nuevo material. Le pondremos de nombre Standard_Color_MAT, por ejemplo. Una vez creado el material, lo seleccionamos y en el desplegable del Shader elegimos ShaderGraph/Standard_Color o como llamases a tu Shader. Arrastramos nuestro nuevo material y lo soltamos encima de la esfera y … Ahora podemos cambiar cambiar desde el Material el Color, ya que anteriormente lo activamos. Nodos importantes Antes de continuar el tutorial voy a explicar algunos de los nodos más usados ya que los vamos a usar más adelante. Me dejo muchos pero para esta introducción son suficientes: Math Basic: Son las operaciones matemáticas más comunes. Suma, División, Multiplicación, Resta … UV: Son nodos que actúan sobre las coordenadas de uv. Podemos rotarlas, moverlas y darle algunos efectos como el Twirl o Spherize. Veremos un ejemplo más adelante. Shapes: Son texturas generadas proceduralmente dentro del editor. Podemos crear círculos, rectángulos, polígonos etc… One Minus: es simplemente la operación 1 - x. Es muy útil como veremos más tarde, tanto que tiene su propio nodo. Noise: es un nodo generador de ruido. Veremos también su uso más adelante. Step: es un nodo que dado un valor entre 0 y 1, compara la entrada con ese valor y devuelve 0 si es menor y 1 si es mayor. Por ejemplo: si nuestro valor es 0.4, todos los valores por encima que entren en el nodo, serán convertidos a 1 y todos los inferiores serán 0. Dot: es un nodo que calcula el Producto Escalar entre vectores. Devuelve 1 si apuntan exactamente en la misma dirección, -1 si apuntan en direcciones completamente opuestas y 0 si los vectores son perpendiculares. Lerp: es un nodo que devuelve el resultado de la interpolación lineal entre las dos entradas en función de la entrada T. El valor de la entrada T está sujeto al rango de 0 a 1. Por ejemplo, cuando el valor de la entrada T es 0, el valor de retorno es igual al valor de la entrada A , cuando es 1, el valor de retorno es igual al valor de la entrada B y cuando es 0.5, el valor de retorno es el punto medio de la dos entradas A y B . Dissolve Shader Una vez conocemos los nodos más importantes, vamos a hacer un Shader algo más complejo que el anterior. Vamos a crear un efecto que disuelva el objeto haciendo que desaparezca y aparezca a nuestro gusto: Para esto volvemos a crear un nuevo Shader y le ponemos de nombre Dissolve. Lo abrimos y seleccionando el PBR Master pulsamos en el icono del engranaje. Aquí vamos a encontrar algunos ajustes interesantes como si el objeto es Opaco o Transparente. En este caso lo dejaremos como está (Opaque) y lo único que marcaremos será el Two Sided. Esto hará que el objeto pinte también sus caras internas, lo que conlleva eso sí, un coste extra. Tenlo en cuenta en el futuro, en este caso para el Cubo en cuestión, nos interesa que las caras internas también se vean cuando está disolviendo. Una vez marcado, vamos a crear algunas variables que usaremos. En primer lugar necesitaremos un valor comprendido entre 0 y 1 que se encargue de llevar el progreso disuelto. Será 0 cuando el objeto se vea por completo y 1 cuando esté completamente disuelto. Para eso en el BlackBoard crearemos un Vector1(que no es más que un simple número) y lo nombraremos como Dissolve Value por ejemplo. Para facilitarnos el trabajo, podemos cambiar el tipo de número con Mode. En nuestro caso está comprendido entre 0 y 1 por lo que elegiremos Slider y rellenaremos el min y el max con esos valores. A su vez, necesitaremos también un Color para el objeto, como en nuestro anterior Shader y un Color diferente para la parte que se esté disolviendo. Creamos ambas variables, estableciendo el Color para disolver cómo HDR si quieres que brille como el del gif (necesitarás también tener el paquete de post procesos y activar el Bloom). Por último necesitaremos un valor que indique el grosor que tendrá el dissolve. Podemos revisar el Gif para ver el grosor que tiene la parte que se está disolviendo. Creadas todas las variables en mi caso quedó así: Para el efecto de disolver necesitamos en primer lugar una textura que genere ruido donde las zonas negras indiquen lo que llevamos disuelto y las zonas blancas lo que nos queda por disolver. Por suerte, como vimos antes, tenemos un nodo de ruido perfecto para este uso: Simple Noise, asique lo añadimos. Podemos cambiar el valor de Scale del nodo a nuestro gusto. Cuanto menor sea el valor más “zoom” hará el ruido. También vamos a necesitar el nodo Step que si tenías dudas de su uso, en este caso lo vas a entender perfectamente. Ahora unimos la salida de Simple Noise a la entrada Edge del Step. Ahora podemos cambiar el valor del Step entre 0 y 1 para ver su utilidad real. Los valores de ruido que estén por debajo de ese valor devolverán 0 y los que estén por encima devolverán 1. Es decir cuando el Step sea 0 el objeto no se verá y cuando sea 1 se verá completamente. Justo lo que queremos que ocurra. Simplemente conectamos nuestra variable DissolveValue a la entrada In del Step. Para hacer pruebas vamos a colocar la salida del Step en el Albedo del PBR Master. Vamos a guardar y vamos a Añadir un cubo a nuestra escena. Crearemos un material con nuestro shader y se lo colocaremos al cubo. En nuestro material podremos cambiar el valor del DissolveValue. Como vemos el efecto se acerca a lo que buscamos, aunque tenemos dos problemas. Primero no se está disolviendo realmente ya que está pasando de negro a blanco simplemente. Y segundo que el efecto está al contrario, cuando el DissolveValue vale 0 debería verse el objeto completo y cuando está a 1 indica que el objeto está completamente disuelto. Vamos a volver a abrir el Shader Editor para solucionar ambas cosas. Primero vamos a hacer que la parte negra se convierta en transparente. Para ello simplemente tienes que conectar la salida del Step con el Alpha del PBR Master. También tendrás que activar el AlphaClip. Aunque el valor que entra por defecto es 1 tendrás que ponerle tu el valor a través de un nodo. Simplemente crea un nodo Integer (que es un número sin decimal) y conectalo a AlphaClip. Para el segundo problema simplemente usaremos el nodo que comentamos anteriormente. OneMinus. Si a 1 le restamos el DissolveValue obtendremos la parte contraria, que es justo lo que necesitamos. Si guardamos y probamos comprobamos nuestro material ahora podemos ver que funciona como queriamos. Se disuelve de blanco a negro con el ruido que creamos. Solo nos falta añadirle color. Para ello volvemos al editor. Necesitamos pintar el borde que se disuelve y a raíz de ahí lo que tengamos a un lado del borde lo borramos y lo demás lo pintamos del color normal. Una forma de encontrar el borde es sumar el DissolveValue y el borde y restar por un lado el Step de la suma y por otro el Step del DissolveValue solo. Es más fácil de entender con una imagen (para que sea más visual he cambiado el valor default del Dissolve Value a 0.5): Como vemos ahora tenemos el borde diferenciado, pero no lo estamos usando. Lo que vamos a hacer es pintar con los colores que creamos al principio. Una buena forma de hacerlo es usar Lerp. Podemos hacer que si la resta es 1(blanco) se coloree con el Color del Borde y si es 0(negro) el color sea el normal. Y esa salida del Lerp la conectamos a Albedo. Ahora podemos guardar y probar el shader. Si todo ha ido bien debería funcionar como esperábamos. Puedes cambiar a tu gusto los valores del material, como los colores o el borde. Si eres perfeccionista te darás cuenta de que si el borde es muy grande, pueden quedar algunos restos al disolverse. Esto podemos arreglarlo con un simple cambio. Sumando el valor del borde al dissolve antes de hacer el OneMinus. También podrías crear una variable para el Scale del Simple Noise. Así tendrías un valor más que podrías modificar desde fuera sin tener que cambiar el shader. Por último vamos a añadir una textura que se añada al color, así lo podremos usar en más objetos. Simplemente crea una variable de tipo Texture2D y arrastrala al grid con los demás nodos. Tendrás que sacar un nodo llamado Sample Texture 2D y arrastrar la textura a la entrada correspondiente. Luego solo queda multiplicar por el color normal y sustituirlo en la entrada A del Lerp anterior. Guardamos y desde el inspector del material añadimos la textura que queramos y habríamos terminado. No es la única forma de hacer este efecto, hay muchas otras, esta es la forma que yo usé. Espero que os sea útil. Cualquier duda que tengáis hacérmela saber y estaré encantado de ayudaros. Nos vemos en el siguiente.
  4. ¡Hola! Os traigo uno de mis assets gratis más descargados: Basic Motions Pack. Se trata de un pack de animaciones 3D de movimiento básicas para que las apliquéis a los personajes de vuestros juegos y apps. Asset Store Link (Gratis) Lista de animaciones: - Idle01- Idle02- Idle01 - Idle02 (transición)- Idle02 - Idle01 (transición)- Jump (inicio - en el aire - aterrizar)- Caminar- Correr- Correr hacia atrás- Sprint Totalmente gratis y lo podéis usar en cualquier tipo de proyecto, incluso comercial. Cualquier duda o sugerencia: contact@keviniglesias.com Más assets como este: www.keviniglesias.com Asset Store Publisher Vídeo de muestra con algunos ejemplos:
  5. Hola, Os dejo una lista de youtube que he dedicado al Particle System. En ella voy poniendo los Videos de cómo he creado efectos que he ido necesitando en mis chorrijuegos. Entre ellos hay: fuegos artificiales, una explosión plana 2d, implosiones, un fondo estrellado y un muro eléctrico… La lista es también un ejemplo de lo hortera que puede llegar a ser un programador cuando se pone a hacer efectos. Os dejo también dos canales de youtube que tienen un apartado de particle system muy interesante! La verdad es que de tanto miro algún video de estos canales para encontrar “inspiración”. Mirza: https://www.youtube.com/channel/UC5c5JgFyiFXKXCVRh2DsRJgç Gabriel Aguilar: https://www.youtube.com/channel/UCtb1s859RTxx-RIgFs5ZVQA
  6. Si.... tenía que pasar, tenía que aparecer otro tutorial de Infinite Runner, y qué narices he sido YO! La verdad es que estaba empezando con un juego tipo Infinite Runner, el que todavía no he acabado, lo he cambiado tantas veces, que ya tengo empezados como cuatro diferentes... Para sentir que finalizo algo he decidido hacer un tutorial con el "motor" de infinite que he acabado haciendo. A mi me funciona para los cuatro juegos tan solo cambiando configuración en el editor de Unity. No todo lo configurable sale en el tutorial, y hay como mínimo una "mala practica" (loadscene), pero me lo perdono por que para juegos pequeños y sencillos tampoco es tan importante :-p Es un tutorial MUY CORTO. Son cinco vídeos y en total no debe llegar a los 60 minutos. Os dejo la presentación: https://youtu.be/gBfjjmOOjiQ y el link a la playlist: https://www.youtube.com/playlist?list=PL2AK-_vf44ol5C_BsapMinozqWBiocmQ7 Cualquier cosa a mejorar... pues por aqui, en comentarios de youtube, donde sea, de verdad. Espero que le pueda ser útil a alguien. Saludos!
  7. The Creativity One Este es un blog sobre Videojuegos fuertemente enfocado en la narrativa, es un blog creado por un desarrollador apasionado y creyente que grandes historias pueden ser contadas en este medio como en ningún otro. No puedo negar que comparto la misma visión y soy un apasionado de grandes historias lo cual me llevó a encontrar este sitio. Si tienes alguna duda sobre alguna historia propia, quieres algún consejo o simplemente tienes curiosidad recomiendo esta pagina. Si a sido corto pero simplemente es un blog que me gusta y quiero compartirlo. "Durante nuestro viaje descubrirás artículos sobre storytelling aplicados a la escritura, marketing, marca personal, pitching, guiones, narrativa de videojuegos y VR y mucho más. Porque contar una historia que enganche a tu audiencia es esencial en cualquier industria o proceso."
  8. Haz un juego gratis (Capítulo 1) es un vídeo fácil de entender para cualquiera. Es informativo, corto y ligero... ¡5 minutitos de naaa! ¡A disfrutarlo!
  9. Me he encontrado este trabajo buscando por la web. Espero que os sirva: https://riunet.upv.es/bitstream/handle/10251/93474/SANZ - Desarrollo de una aplicación de entretenimiento con networking para dispositivos móviles u....pdf?sequence=1
  10. Saludos Programadores Tengo mucho tiempo sin pasarme por aquí y he echo un pequeño código que creo que le resultara útil para muchos que estén iniciando y e decidido compartirlo con ustedes para empezar de nuevo en esta comunidad con el pie derecho x'D El script reproduce aleatoriamente las músicas dadas en una variable con una transición para que no cambien de golpe. Solo necesitan agregar el script a un GameObject vacío y agregarle el tiempo que desean que use para la transición y agregar una lista de músicas a reproducir. Editado: using UnityEngine; using System.Collections; using UnityEditor; // Ayuda: Boris 1998 registrado en Forum.unity.com public class ReproductorMusica : MonoBehaviour{ public AudioClip[] musicas; // Musicas a reproducir. public float fade = 2; // tiempo tardado en la trasicion de las musicas. public Vector2 lapsos = new Vector2(0,200); // lapsos de tiempo sin sonido, en segudos. [Range(0f,1f)] public float volumen = 1;// volumen deseado que se escuche la musica. public AudioClip backGround; // musica a reproducir durante el lapso. private AudioSource audio1; private AudioSource audio2; private int musicaT; public static ReproductorMusica reproductor; void Start (){ reproductor = gameObject.GetComponent<ReproductorMusica> (); audio1 = gameObject.GetComponent<AudioSource> (); if(audio1 == null){ gameObject.AddComponent<AudioSource> (); audio1 = gameObject.GetComponent<AudioSource> (); } try { audio2 = gameObject.transform.GetChild(0).gameObject.GetComponent<AudioSource> (); } catch (System.Exception ex) { if(gameObject.transform.childCount == 0){ GameObject ob = new GameObject (); ob.name = "ReproductorSecundario"; ob.transform.SetParent (transform); } gameObject.transform.GetChild(0).gameObject.AddComponent<AudioSource> (); audio2 = gameObject.transform.GetChild(0).gameObject.GetComponent<AudioSource> (); } musicaT = Random.Range (0,musicas.Length); StartCoroutine (Reproducir(audio1)); } public static void Volumen (float vol){ ReproductorMusica.reproductor.audio1.volume = vol; ReproductorMusica.reproductor.audio2.volume = vol; } public static void CambiarMusica (AudioClip musica){ ReproductorMusica.reproductor.StopAllCoroutines (); ReproductorMusica.reproductor.StartCoroutine (ReproductorMusica.reproductor.RPA(musica)); } IEnumerator RPA (AudioClip musica){ AudioSource ad,ad2; if (audio1.clip != null) { ad = audio2; ad2 = audio1; } else { ad = audio1; ad2 = audio2; } ad.clip = musica; ad.Play (); StartCoroutine (FadeStart(ad,fade,volumen)); while (ad2.volume > 0) { ad2.volume -= volumen * Time.deltaTime / fade; yield return null; } ad2.Stop (); ad2.clip = null; ad2.volume = volumen; musicaT = Random.Range (0,musicas.Length); yield return new WaitForSeconds(ad.clip.length-fade); yield return StartCoroutine(FadeOut (ad, fade)); } public static void Apagar (){ ReproductorMusica.reproductor.StopAllCoroutines (); ReproductorMusica.reproductor.StartCoroutine (ReproductorMusica.reproductor.AP()); } IEnumerator AP (){ while (audio1.volume > 0) { audio1.volume -= volumen * Time.deltaTime / fade; audio2.volume -= volumen * Time.deltaTime / fade; yield return null; } audio1.Stop (); audio1.clip = null; audio1.volume = volumen; audio2.Stop (); audio2.clip = null; audio2.volume = volumen; } public static void Reiniciar (){ ReproductorMusica.reproductor.StopAllCoroutines (); AudioSource ad,ad2; if (ReproductorMusica.reproductor.audio1.clip != null) { ad = ReproductorMusica.reproductor.audio2; ad2 = ReproductorMusica.reproductor.audio1; } else { ad = ReproductorMusica.reproductor.audio1; ad2 = ReproductorMusica.reproductor.audio2; } ReproductorMusica.reproductor.musicaT = Random.Range (0,ReproductorMusica.reproductor.musicas.Length); ReproductorMusica.reproductor.StartCoroutine (ReproductorMusica.reproductor.Reproducir(ad)); ReproductorMusica.reproductor.StartCoroutine (ReproductorMusica.reproductor.AP1(ad2)); } IEnumerator AP1 (AudioSource ad){ while (ad.volume > 0) { ad.volume -= volumen * Time.deltaTime / fade; yield return null; } ad.Stop (); ad.clip = null; ad.volume = volumen; } IEnumerator FadeStart (AudioSource audioSource, float FadeTime, float vol) { audioSource.volume = 0; while (audioSource.volume < vol) { audioSource.volume += vol * Time.deltaTime / FadeTime; yield return null; } audioSource.volume = vol; } IEnumerator Reproducir (AudioSource ad){ ad.clip = musicas [musicaT]; ad.Play (); StartCoroutine (FadeStart(ad,fade,volumen)); musicaT = Random.Range (0,musicas.Length); yield return new WaitForSeconds(ad.clip.length-fade); yield return StartCoroutine(FadeOut (ad, fade)); } IEnumerator FadeOut (AudioSource audioSource, float FadeTime) { AudioSource audioSource2; if (audioSource == audio1) { audioSource2 = audio2; } else { audioSource2 = audio1; } float lp = Random.Range ((int)lapsos.x, (int)lapsos.y); if(lp == 0){ StartCoroutine (Reproducir (audioSource2)); }else if(backGround != null){ StartCoroutine (FadeStart(audioSource2,fade,volumen*0.75f)); audioSource2.clip = backGround; audioSource2.Play (); audioSource2.loop = true; } while (audioSource.volume > 0) { audioSource.volume -= volumen * Time.deltaTime / FadeTime; yield return null; } audioSource.Stop (); audioSource.clip = null; audioSource.volume = volumen; yield return new WaitForSeconds (lp); if(lp > 0){ StartCoroutine (Reproducir (audioSource)); while (audioSource2.volume > 0) { audioSource2.volume -= volumen * Time.deltaTime / FadeTime; yield return null; } audioSource2.Stop (); audioSource2.clip = null; audioSource2.loop = false; audioSource2.volume = volumen; } } } Propiedades. fade : El tiempo que tardan las transiciones en segundos. musicas : lista de músicas a reproducir. Añadido : lapsos: lapsos de tiempo aleatorio(Vector2(Minimo,Maximo)) en el que no sonara la musica. volumen: volumen de la musica. backGround: Sonido de fondo que sonara durante los lapsos (se puede dejar en blanco). Funciones Estaticas: Volumen: cambia el volumen de la musica. CambiarMusica: cambia la musica por la musica dada con una transicion con la duracion dada en fade. Apagar: apaga el reproductor. Reiniciar: Reinicia el reproductor. Aquí pueden descargar el código. PD: no soy bueno comentando así que no comento los códigos espero entiendan el código en caso de que tengan que modificar algo :'v Edit: le cambie el titulo por que creo que generaba confucion.
  11. Hola. Aquí les traigo una herramienta para localización que he estado implementando hace unas semanas. Espero que les sea útil. En el adjunto está como usar la herramienta y los enlaces a la introducción y un tutorial en youtube. Este adjunto esta incluido dentro del paquete. (Enlace cerrado) https://www.dropbox.com/s/tthj2jjgk6tv5z4/CGLocalization%20v1.unitypackage?dl=0 La herramienta sera subida pronto al asset store. Cuando sea subida les dejare el enlace. How to Use.txt
  12. Hoy vamos a recuperar nuestro tutorial del reloj analógico y vamos a ampliar algunas funciones. Vamos a asociar la hora actual con el ciclo de día y de noche de nuestra escena. Y lo podremos aplicar con la hora actual del sistema. Sólo nos centraremos en la orientación de la iluminación y las sombras. Además, trabajaremos con el sistema de 2 cameras simultáneas que nos ofrece Unity. ¡No os lo perdáis! ¡Por favor suscríbanse al canal y dejen un comentario!
  13. Hola, que tal?, muy buenas. Hacia mucho que no venia por estos lares (años), pero ahora que me quede sin trabajo y que ando de novio, para hacer algo especial por nuestro aniversario, volvi a las andadas con unity. Primero, esto me costo entenderlo ya que desde la version 3 de unity que no lo usaba (por dios, cambiaron tantas cosas...). Pero vamos al lio. Aclaración: no soy experto, seguramente haya mas maneras de hacer esto mismo, y mas prolijo. Pero por ahora me doy por satisfecho. Bien, vamos con el primero codigo (explicacion en el mismo): #pragma strict //Declaro las variables (En este codigo solo hay 3 funciones, PLAY, STOP y SIGUIENTE-este ultimo es automatico al darle stop-) public var sereproduce : boolean; //Para reproducir var objeto : GameObject; //para un raycast, en este objeto se encuentra un plano que reproduce el video var daleplay : Video.VideoPlayer; //Plano, este lo asigno en esta variable mediante el inspector var clips : Video.VideoClip[]; //Array de todos los clips de video que se van a reproducir en el plano var clips2 : Video.VideoClip; //Segunda variable, Video no permite "slide", no se que es pero sin esta no funciona var siguiente : int; //Subindice para nuesto array de clips function Start () { sereproduce = false; clips = Resources.LoadAll.<Video.VideoClip>("Videos"); //Levanto toidos los videos que se encuentren en la carpeta "Assets/Resources/Videos" for(var i=; i < clips.length; i++){ print(clips[i].name); //Bastante simple, para saber que levantó y asignó a nuestro array todos los videos } siguiente = ; } function Update () { if(siguiente >= clips.length){ //Nuestro subindice para el array siguiente = ; } if (Input.GetButtonDown("Usar")) { var hit : RaycastHit; var ray = Camera.main.ScreenPointToRay(Input.mousePosition); } if (Physics.Raycast(ray,hit)) { if (hit.collider.name == objeto.name && sereproduce == false) { //Si golpea con un objeto con el mismo nombre que el objeto que asigne al gameobject Y si no se reproduce nada... clips2 = clips[siguiente]; //Aca asigno nuestro primer clip de video del array a nuestra segunda variable daleplay.clip = clips2; //Aca a nuesto VideoPlayer daleplay.Play(); //Comienza a reproducir print(daleplay.clip.name); //Por si las moscas, un poco de debug no viene mal sereproduce = true; } else if (hit.collider.name == objeto.name && sereproduce == true){ daleplay.Stop(); sereproduce = false; siguiente ++; } } } //Se puede hacer con isPlaying, cambiando la variable "sereproduce", pero me daba algunos problemas, tal vez por mi codigo, no soy experto, pero bueno, asi quedo andando. Bueno, no se asusten, el segundo es mas facil... Here we go again! #pragma strict //Creamos nuestras variables señores ///NOTA: esto esta muy bueno para adaptarlo a algun sistema de inventario de algun juego, aunque yo no llego a tanto var texturas : Texture2D[]; //Un hermoso array de texturas 2D var imagenes : GameObject; //Nuestro "plano-cubo-esfera" o lo que quieran, que vayan a asignarle texturas var ingresarespera : boolean; //Nuesto limitador a la hora de hacer los cambios de textura automaticos var subindice : int; //Como dice, subindice de nuestro array function Start () { texturas = Resources.LoadAll.<Texture2D>("Fotos"); //Mismo que el de arriba, tomamos el array, y le asignamos todo lo que se encuentre en la carpeta FOTOS, que sea del tipo TEXTURA 2D for(var i=; i < texturas.length; i++){ print(texturas[i].name); } ingresarespera = true; subindice = ; print(ingresarespera); print(subindice); } function Update () { if(ingresarespera == true){ ingresarespera = false; print(subindice); Espera(); } } function Espera(){ if(subindice < texturas.length){ imagenes.GetComponent.<Renderer>().material.mainTexture = texturas[subindice]; //obtenemos el componente para renderizar, con su material original, le asignamos la nueva textura subindice ++; yield WaitForSeconds (5); ingresarespera = true; //Lo ponemos a True, para el siguiente conteo =D } else{ //Si no es menor el subindice... osea, si el subindice es igual o mayor que el largo de nuestro array (siempre asi, sino el OutOfRange de los huevos) subindice = ; //Ponemos el subindice a cero para repetir todo de nuevo yield WaitForSeconds (5); ingresarespera = true; //Volvemos a repetir } } Tal vez a alguien le sirva, la guia y el manual de unity no dan a entender nada y fueron HORAS de intentar. En fin. Que esta bien y todo, pero si esto nisiquiera esta explicado en el scripting manual de unity, que te dice "es la funcion inherente a esta otra funcion" y vas en circulos todo el rato. Ya veo en 8bit de tanto darle vueltas... Suerte y hasta la proxima! =D EDIT: por un comentario de otro usuario cambie los comentarios del script, en todo caso, si asi esta mas entendible y "limpio" haganmelo saber.
  14. Es bastante genérica y no está orientada a nada de videojuegos en concreto, pero puede resultar muy útil en ciertas fases de un proyecto en las que se haya de evaluar una serie de situaciones que comprometan o entren en conflicto con otras. http://ncase.me/loopy/
  15. Paralelismo con Unity3D en C# Hola buenas, Aquí os traigo un ejemplo de aplicación de multihilos a Unity3D. En este caso, el ejemplo consiste en dada una matriz rellenada con numeros random de 1 a 1000, hacer la suma total de cada fila. Es decir dada la matriz 3x3: 1 2 3 -> 6 4 5 6 -> 15 1 2 4 -> 7 Este es un ejemplo en el cual podremos utilizar multithreading (a partir de ahora multihilos) y ahorrar costo computacional. En el unitypackage que os adjunto se rellenan dos matrices de 10000 x 10000. Así que al darle al Play puede ser que vuestro ordenador se os tire varios segundos sin arrancar la escena debido a que el relleno de las matrices es por un único hilo y con un Random.Range(), algo que es costoso para un ordenador, pero que al ser un ejemplo no nos importa (nos centraremos en el calculo paralelo, os animo a completar el código para el relleno de las matrices por paralelismo ). En la escena nos aparecerán dos botones. Al darle click a "Hilo" os hará el calculo de la primera matriz con un único hilo. Al darle click a "Multihilo" os lo hará con multihilos. Super intuitivo el ejemplo así que no os podéis quejar. Os comento un poco el codigo del multihilo para que lo entendáis: using System.Collections; using System.Collections.Generic; using System.Threading; using UnityEngine; using HelperCustom; public class multiHilo { private int[,] v; private int tamX, tamY; public multiHilo(int tamX, int tamY) { this.tamX = tamX; this.tamY = tamY; v = new int[this.tamX, this.tamY]; HelperCustom.HelperMatriz.RellenarMatriz2d(ref v, ref tamX, ref tamY); } public void sumarVectoresMultiplesHilos() { for(int x = ; x < tamX; x++) { //1 System.Threading.ParameterizedThreadStart sum = new System.Threading.ParameterizedThreadStart (sumaElementosY); //2 System.Threading.Thread sobreUnaLinea = new System.Threading.Thread(sum); //3 sobreUnaLinea.Start(x); } } private void sumaElementosY(object y) { int j = (int)y; int resultado = ; for(int p = ; p < tamY; p++) { resultado += v [j, p]; } Debug.Log ("Calculado en multihilo"); } } Iremos por partes: El constructor de la clase es súper sencillo, simplemente le pasa por parámetro las filas y columnas de la matriz, crea una matriz con esas filas y columnas y luego las rellena con un helper hecho por mi (también añadido al unitypackage). Vamos al lío: sumarVectoresMultiplesHilos() es la clase que nos interesa. Como veréis recorremos la columna de la matriz, y por cada columna declaramos qué método queremos ejecutar en diferentes hilos, en este caso, sumaElmentosY (el número 1). Ahora en el 2 crearemos el hilo pasándole las propiedades declaradas en el 1, y finalmente empezaremos la ejecución del hilo, pasándole por parámetro la posición en la que estamos (fila 1, 2, 3...). Muy importante, nos debemos fijar que en lo que pasámos por parametro en realidad es un object, es decir que en sumaElementosY() el parámetro es object. Y luego tenemos que hacerle una conversión a int, en este caso se trata de un downcasting (cosas raras de los ingenieros informáticos). Ahora ya podremos calcular el resultado de la fila como haríamos con un vector, puesto que la posición x la sabíamos anteriormente y la hemos pasado por parámetro. Notas: En el estudio del tiempo que necesitamos he puesto un Debug.Log en cada una de las filas calculadas para que se note más la diferencia de tiempos (Ya que hablamos de una matriz 10kx10k, relativamente pequeña para la tecnología hardware actual). Esto está muy bien pero... ¿Para qué necesito yo saber esto? Las aplicaciones son casi infinitas, y lo mejor, súper óptimas. Se pueden utilizar en suma de vectores donde sabes que el tamaño siempre va a ser enorme, TerrainData que se trabaja con matrices super espesas (que es mi caso), Texturas, Colores, etc. Pues lo pienso hacer todo paralelo a partir de ahora @mgarcia Para el carro, he dicho casi infinitas. Hay operaciones las cuales da igual como las hagas siempre van a ser del mismo costo temporal. Todos aquellos algoritmos donde las variables que se tienen que modificar se compartan y necesites saber el resultado de la operación x para hacer la de la x+1 no se puede hacer paralelo (la explicación técnica es más compleja pero para que os hagáis una idea de lo que digo). Resultados temporales: Ahora os dejo con el resultado temporal que me ha salido a mi, como veréis, la diferencia de tiempos es enorme: Unos 9 segundos y medio de media en un único hilo mientras que en multihilo me ha dado menos de 3. Si aumentásemos el tamaño de la matriz imagináos... Y hasta aquí la pequeña introducción al paralelismo con Unity3D. Un saludo, y ¡hasta otra! tutoMultihilo.unitypackage
  16. Hola a todos. Es que quisiera saber si hay algún problema con derechos de autor si yo utlizo el video de Unity el trailer para prmocionar mi curso en Udemy es que ya pregunte a el correo de Unity Brand pero no me responden, y pues si hubiera problema como hago un video para promocionar el curso si no tengo dinero es que no he visto intros que se vean cheveres y que no cobren mucho, tengo ese dilema que hago. Y la otra es que estoy utilizando intros biteable y no se que tan legal sea eso, pero pues la idea seria financiarme en ideame pero igual necesitaria premios y pues necesito sacar el curso para haber si puedo financiar asi sea una tableta gráfica para mejorar el curso. https://www.youtube.com/watch?v=HBELzN_khQs
  17. Hola a todos, vengo a compartir mi crosshair. dejare el codigo aqui y tambien un la descarga con los assets (que es preferible). Lo hize guiandome por el tipico de counter strike, y dandole bastantes parametros. Con el parametro Dynamic conseguimos el effecto de apertura en el crosshair tipico cuando se dispara. Con Dynamic en true presionamos boton izquierdo del raton para ver el efecto. Sin AutoUpdate pulsamos 'F' para que se actualize el crosshair. Dynamic y AutoUpdate no pueden estar seleccionados a la vez. Espero que les sirva de ayuda, Un saludo :) crosshair.unitypackage Decirles que esta echo con la Unity UI, y no con OnGUI.
  18. Sistemas integrados en el plugin: Sistema de generacion Fractal. Sistema de generacion Noise. Sistema de generacion Voxel 2D. Comparto un package que contiene el Plugin '*.dll' integrado en el proyecto junto a codigos de ejemplo para que veais como funciona. Remarco que esto no es un tutorial, simplemente estoy compartiendo mi codigo ensamblado en un dll, yo lo uso para no estar siempre escribiendo el codigo en cada proyecto. Pongo lo de Avanzado en el titulo, por que supongo que solo las personas que entienden de programacion en videojuegos sabran para que es tan necesario una generacion rapida Noise o Voxel. Espero les sirva de ayuda y automatize algo mas sus proyectos, el codigo fue modificado por mi (no es 100% mio) y hay una referencia al autor en el proyecto. Imagenes: Un Saludo. systemPlugin.unitypackage
  19. Os traigo una nueva y súper fácil forma para mostrar y compartir vuestros modelos 3D al mundo. (La mejor que he visto hasta ahora, en 10 años...) Sketchfab es un servicio web gratuíto en el que te puedes registrar con tu cuenta de Google, Twitter, o Facebook. Es un portal para mostrar y compartir tus modelos 3D, directamente desde su visor webgl en la misma web. ¡¡¿¿Cuántas veces hemos querido mostrarle un modelo 3D a los amigos??!! El plan por defecto que ofrece la web permite subir contenido menor de 50MB de tamaño por archivo, espacio infinito para modelos. El visor se controla de forma intuitiva, y permite varias opciones de visualización, incluso soporte para VR, mediante los planes de pago. ¿Lo tenéis montado todo en Unity? Mejor aún, en el AssetStore se encuentra disponible un exportador de escenas y gameobjects directamente a Sketchfab. Y es gratis: https://www.assetstore.unity3d.com/en/#!/content/14302 Ahora ya no podemos tener excusa para ir mostrando cómo vamos avanzando en nuestros proyectos a cualquiera que nos lo pida, esté dónde esté. No sé si funciona también en tablets y smartphones, pero sería todo un detallazo.
  20. Enlace de descarga: https://app.box.com/s/384vkwhfosk9zgzpftphq3oi35yifhpb Para este sistema de Save/Load necesitamos crear un prefab de la entidad. El prefab se necesita para instanciar/crear un nuevo GameObject de la forma más sencilla. El sistema de guardado consta de una clase estática llamada GameData que almacena una sola instancia MonoBehaviour(script) de cada GameObject dentro de una ArrayList, y dispone de las funciones Save y Load: using UnityEngine; using System.Collections; using System.IO; using System.Runtime.Serialization.Formatters.Binary; public static class GameData { public static string file = "GameData.dat"; public static ArrayList Data = new ArrayList(); //Aqui se almacenaria todos los datos como objetos public static bool Save(){ FileStream fs = new FileStream(file, FileMode.Create); BinaryFormatter formatter = new BinaryFormatter(); ArrayList arrayList = new ArrayList(); foreach(object data in Data){ ISaveLoad script = (ISaveLoad) data; arrayList.Add(script.GetData()); } try { formatter.Serialize(fs, arrayList); } catch (System.Runtime.Serialization.SerializationException e) { UnityEngine.Debug.Log("Failed to serialize. Reason: " + e.Message); return false; } finally { fs.Close(); } arrayList.Clear(); arrayList = null; formatter = null; fs = null; return true; } public static bool Load(){ if(!File.Exists(file)) return false; FileStream fs = new FileStream(file, FileMode.Open); ArrayList arrayList; try { BinaryFormatter formatter = new BinaryFormatter(); arrayList = (ArrayList) formatter.Deserialize(fs); formatter = null; } catch (System.Runtime.Serialization.SerializationException e) { UnityEngine.Debug.Log("Failed to deserialize. Reason: " + e.Message); return false; } finally { fs.Close(); } Data.Clear(); //Instanciar GameObjects a escena foreach(object data in arrayList){ EntityData entityData = (EntityData)data; entityData.OnLoad(UnityEngine.Object.Instantiate<GameObject>(Resources.Load<GameObject>(entityData.ResourcesPath))); } arrayList.Clear(); arrayList = null; fs = null; return true; } } Uso la instancia de un script como referencia del GameObject, y no una clase serializada directamente, porque es constante durante todo el tiempo de juego. Tampoco utilizo el GameObject directamente como referencia, para que este sistema de guardado pueda ser utilizado por cualquier tipo de script(SOLO UN SCRIPT por GameObject podrá implementar el sistema de guardado). Este único script recoge los datos de los componentes y otros script del GameObject. Para poder guardar los datos del juego de forma generalizada, utilizo una clase base serializada llamada EntityData con el campo ResourcesPath y la funcion OnLoad: [System.Serializable] public class EntityData{ public string ResourcesPath; public virtual void OnLoad(GameObject gameObject){} } Y además, necesito una interfaz para poder extraer los datos de los GameObjects, con la funcion GetData(): interface ISaveLoad{ object GetData(); } UTILIZACION Como he dicho, antes de nada, es necesario crear un prefab de la entidad/GameObject que alojaremos en la carpeta Resources. A continuación, dentro de algún script del GameObject a guardar(solo un script del GameObject puede implementar este sistema): 1) Creamos una clase derivada de EntityData. Esta clase hereda ResourcesPath y la funcion OnLoad necesaria para la carga de la escena, y añadiremos los datos que queramos guardar del GameObject. Por ejemplo: [System.Serializable] public class Data : EntityData{ [HideInInspector] public float px,py,pz,rx,ry,rz,sx,sy,sz; public int vida = 100, experiencia = 0; public override void OnLoad (GameObject gameObject) { Transform transform = gameObject.GetComponent<Transform>(); transform.position = new Vector3(px,py,pz); transform.eulerAngles = new Vector3(rx,ry,rz); transform.localScale = new Vector3(sx,sy,sz); ScriptEntidad1 script = gameObject.GetComponent<ScriptEntidad1>(); //Transformamos el object en la clase de datos de la entidad script.datos = (ScriptEntidad1.Data) this; } } public Data datos; He creado una clase llamada Data, derivada de EntityData, donde almaceno los datos del Transform y dos campos de vida y experiencia. En la funcion OnLoad asigno estos valores a los componentes, es decir, al Transform y al Script al que he vinculado los datos, en este caso al script 'ScriptEntidad1'. 2) Añadimos el script a la lista de GameData desde la funcion Start() de Unity, y los eliminamos al destruir el GameObject desde la funcion OnDestroy() de Unity: void Start () { //Añadir GameObject a la lista GameData.Data.Add(this); } void OnDestroy(){ //Eliminar GameObject de la lista GameData.Data.Remove(this); } 3) Añardir la funcion GetData de la interfaz ISaveLoad: public class ScriptEntidad1 : MonoBehaviour, ISaveLoad { object ISaveLoad.GetData(){ //Actualizar Datos Transform Vector3 temp = this.transform.position; this.datos.px = temp.x; this.datos.py = temp.y; this.datos.pz = temp.z; temp = this.transform.eulerAngles; this.datos.rx = temp.x; this.datos.ry = temp.y; this.datos.rz = temp.z; temp = this.transform.localScale; this.datos.sx = temp.x; this.datos.sy = temp.y; this.datos.sz = temp.z; return this.datos; } } Si quereis ver el codigo completo del script: using UnityEngine; using System.Collections; public class ScriptEntidad1 : MonoBehaviour, ISaveLoad { [System.Serializable] public class Data : EntityData{ [HideInInspector] public float px,py,pz,rx,ry,rz,sx,sy,sz; public int vida = 100, experiencia = 0; public override void OnLoad (GameObject gameObject) { Transform transform = gameObject.GetComponent<Transform>(); transform.position = new Vector3(px,py,pz); transform.eulerAngles = new Vector3(rx,ry,rz); transform.localScale = new Vector3(sx,sy,sz); ScriptEntidad1 script = gameObject.GetComponent<ScriptEntidad1>(); //Transformamos el object en la clase de datos de la entidad script.datos = (ScriptEntidad1.Data) this; } } public Data datos; object ISaveLoad.GetData(){ //Actualizar Datos Transform Vector3 temp = this.transform.position; this.datos.px = temp.x; this.datos.py = temp.y; this.datos.pz = temp.z; temp = this.transform.eulerAngles; this.datos.rx = temp.x; this.datos.ry = temp.y; this.datos.rz = temp.z; temp = this.transform.localScale; this.datos.sx = temp.x; this.datos.sy = temp.y; this.datos.sz = temp.z; return this.datos; } void Start () { //Añadir GameObject a la lista GameData.Data.Add(this); } void OnDestroy(){ //Eliminar GameObject de la lista GameData.Data.Remove(this); } }
  21. Buenas gente, acá les traigo un simple script para controlar el movimiento de traslación de las plataformas. Lo hice con el objetivo de facilitarme este método y dejárselo a los nuevos usuarios del foro. Es algo muy básico pero cumple su función. El siguiente script se añade a la plataforma que quieras que tenga esta propiedad. using UnityEngine; using System.Collections.Generic; public class PlatformMove : MonoBehaviour { [Range(0.0f, 15.0f)] public float speed; public enum Path { loop, reverse } public Path path; public float minDistance = 0.1f; public List<Vector3> positions = new List<Vector3>(); private int index = 0; void Start() { ResetPosition(); } //para situar la plataforma al comienzo void Update () { //Traslacion if (index < positions.Count) { transform.position = Vector3.MoveTowards(transform.position, positions[index], Time.deltaTime * speed); if (Vector3.Distance(transform.position, positions[index]) < minDistance) index++; } else { //Metodos de traslacion if (path == Path.loop) index = 0; if (path == Path.reverse) { positions.Reverse(); index = 0; } } } //EDITOR public void AddPosition() { positions.Add(transform.position); } public void RemoveLastPosition(){ positions.RemoveAt(positions.Count - 1); } public void ResetPosition() { transform.position = positions[0]; } public void ResetAll() { positions.Clear(); } void OnDrawGizmosSelected() { if (positions != null) { for (int i = 0; i < positions.Count; i++) { if(i < positions.Count - 1) { Gizmos.color = Color.green; Gizmos.DrawLine(positions[i], positions[i + 1]); } else { Gizmos.color = Color.blue; Gizmos.DrawLine(positions[i], positions[0]); } } } } }Y el siguiente dentro de la carpeta "Editor" using UnityEngine; using UnityEditor; [CustomEditor(typeof(PlatformMove))] public class PlatformMoveEditor : Editor { public override void OnInspectorGUI() { DrawDefaultInspector(); PlatformMove plataformMove = (PlatformMove)target; if (GUILayout.Button("ADD")) plataformMove.AddPosition(); if (GUILayout.Button("REMOVE LAST POSITION")) { plataformMove.RemoveLastPosition(); } if (GUILayout.Button("RESET POSITION (OBJECT)")) plataformMove.ResetPosition(); if (GUILayout.Button("RESET ALL")) plataformMove.ResetAll(); } }
  22. He encontrado esta guía para los que queráis mejorar algo más como Artistas. Siempre es bueno tener unas bases bien sólidas... http://www.floobynooby.com/ICG/artvalues.html
  23. Hola comunidad este es mi primer aporte, gracias a ustedes está listo. Pasé mucho trabajo para lograr crear un sistema para guardar cargar una partida en unity a través de la serialización. Al fin lo logré y ahora cuando alguien pase por mi situación podrá tener este material de apoyo. Sirve, yo lo uso, al que no le funcione por favor no me escriban burradas, todo lo hago por ayudar, en el .rar están los scripts y unas fotos para que vean como es. menu.rar
  24. ¡Buenas, compañer@s! Me paso por el foro para dejar un aporte: no es un script complejo para nada, pero puede seros útil para maquetar proyectos o incluso lo poidéis adaptar a vuestro juego en el caso de que queráis y os venga bien. Se trata de un Pathfinder que funciona lanzando Raycasts (de arriba a abajo) alrededor del objeto que queramos que se mueva conforme a un objetivo (inteligencia artificial). Hace un mes aproximadamente vi que en el foro alguien había subido un script de las mismas características, sin embargo, los enlaces estaban caídos y decidí desarrollarlo un poco por mi cuenta. Tengo la costumbre de programar en inglés, supongo que no tendréis problemas con el idioma... xD Y por si acaso quedaran dudas con respecto al funcionamiento del script, dejo comentarios sobre todas y cada una de las funciones y las variables principales (en ESPAÑOL). Es bastante intuitivo a la hora de usarlo, pero repito: es una solución simple, lo he programado porque necesitaba YA un pathfinder que funcionara a grosso modo en un mundo generado de forma procedural. Sin más, os dejo el archivo en adjuntos, está programado en C#. Espero que sirva de utilidad, y si se os ocurre cualquier cosa, comentadlo, a ver qué podemos hacer. PD: Si esta no es la sección apropiada, por favor, moved el tema a la sección correspondiente. Gracias. Kace. PathCalculator.cs
  25. Os presento la Asociación de Estudiantes de Videojuegos, localizada en Valencia. Ofrecen cursos, meetings, Jams, y más recursos. Me la ha recomendado un amigo y la verdad es que los tutoriales están muy bien. http://aev.org.es/
×
×
  • Create New...