Jump to content

Leaderboard


Popular Content

Showing content with the highest reputation since 01/20/2020 in Posts

  1. 7 points
    Hola gente les dejo un link a mi curso de youtube, totalmente gratuito y disponible para la comunidad. Esta totalmente actualizado al 2020 y hecho por mi, soy programador con titulo universitario y 10 años de experiencia en unity! El curso esta dividido en niveles de dificultad, Comenzando para gente que nunca toco unity y terminando con contenido muy avanzado como creacion de framework propios para multiplayer, entre otras cosas. Para que los usuarios mas avanzados puedan saltearse las partes que no les sirve y explorar mas fácilmente el contendio. Son mas de 200 videos, con muchisimas horas de grabacion que complete con la intención de subir a udemy. Al terminarlo cambie de parecer y ahora lo estoy subiendo de forma gratuita a youtube. Se sube 1 video cada dia de forma atomatica, y ya estan todos los videos seteados para subirse a youtube de forma automatica a este ritmo. Link: https://www.youtube.com/channel/UCl3p_fKnx2-GIUWVbiDAcMg Sin mas, espero verlos por mi canal y que les sirva el curso. Un saludo!!
  2. 6 points
    Estoy leyendo el libro "Unity Game Optimization" que está en Packt y la tercera edición es de noviembre de 2019. He hecho un resumen de los apartados dedicados a scripting que me parecen muy buenos. Algunos los conoceréis, otros no y otros es posible que no supiérais porqué utilizar una manera u otra. En todos los casos el concepto de optimización ve sus frutos cuando es un desarrollo de cierto tamaño. Desde mi punto de vista, si empiezas con buenos hábitos, luego no tendrás los mismos problemas de rendimiento que el resto de desarrolladores. La optimización se debe realizar desde el día 1. Paso a relatar. Optimización 1 Eliminar las callbacks vacías de Start() y Update() al crear un script si no son necesarias. El tenerlas afectará a la inicialización de la scene y al instanciar prefabs. La de OnGUI() es especialmente problemática ya que puede llamarse más de una vez por frame. En la de Update() se realiza un Native-Managed Bridge, o sea, hay que enlazar el modo managed de C# con el del código nativo dependiente de plataforma. En general no dejar nunca una callback vacía. Optimización 2 Cómo obtener los componentes de un GameObject. Hay tres maneras de hacerlo, aunque a la práctica se utilizan dos de ellas. Los datos hablan por si mismos para 30.000 objetos. // 6413 ms test = (TestComponent)GetComponent("TestComponent"); // 89 ms test = GetComponent<TestComponent>(); // 95 ms test = (TestComponent)GetComponent(typeof(TestComponent)); El mejor es del uso del template o tipo genérico. Como en C++ ;) Optimización 3 Cachear los GetComponent, preferiblemente en el Awake. Esto es realmente crítico si se realiza en el Update. Al final obtendremos un mejor rendimiento a cambio de un coste de memoria mínimo (entre 32 ó 64 bytes por item dependiendo de la plataforma). Optimización 4 El uso de funciones dentro de Update. Si las acciones no requieren se llamadas en cada frame es mucho mejor convertirlo a un InvokeRepeating que puede llamarse en el Start y cancelarse en el OnDestroy: private void Start() { InvokeRepeating("ProcessAI", 0f, _aiProcessDelay); } Optimización 5 La comparación de objetos null. La llamada directa de "gameobject == null" genera una conversión Native-Managed Bridge con la consiguiente sobrecarga. Es mucho mejor utilizar el ReferenceEquals que no utiliza la conversión. Por eso se incluyó en Unity: if (!System.Object.ReferenceEquals(gameObject, null)) { // No es null } Optimización 6 La comprobación con Tag directa genera memoria adicional y hará actuar al GC posteriormente. Utilizar el CompareTag no utiliza memoria ya que evita el Native-Managed Bridge completamente y tarda la mitad de tiempo: // Asignación de memoria y GC. Tarda el doble de tiempo if (gameObject.tag == "Player") { // realizar acción } // Evita el Native-Managed Bridge totalmente. No asigna memoria adicional if (gameObject.CompareTag ("Player")) { // realizar acción } Optimización 7 Dictionary vs List. Las List son mejores para iteraciones. Los Dictionary son mejores para búsquedas aleatorias. El Dictionary es peor para las iteraciones debido a que debe realizar una comparación hash para cada uno de los elementos. De todos modos tener los dos tipos en algunas situaciones no es mala idea. Optimización 8 La Transform. Cuando instanciamos un nuevo GameObject con GameObject.Instantiate(), uno de sus argumentos es el componente de la Transform del parent que queremos asignar, que por defecto es null y colocará el GameObject en el root. Todas las Transforms que está a nivel root necesitar crear un buffer de memoria para poder almacenar los children que tienen más aquellos que vendrán después. Esto no ocurre con las Transforms que son child. Pero si una Transform en root le cambiamos el parent una vez creada y la reasignamos, se procederá a descartar el buffer de memoria que iniciamos en el Instantiate. Para evitar esto es mejor proveer del parent en la función. Otro apartado interesante es que, hay una propiedad en la Transform llamada hierarchyCapacity. Si somos capaces de estimar el número de Transform child de este objeto root, podremos reducir el número de asignaciones de memoria. Optimización 9 World Position, World Rotation, World Scale. Cuánto más profundo esté en la jerarquía un objeto mayores cálculos son necesarios para determinar el resultado final de su estado. Esto significa que es mucho más eficiente utilizar los elementos de Local que de World. Optimización 10 Cambios en la Transform. Si es posible, agrupar todos los cambios en una Transform y no realizarlos hasta el final de todos los cálculos y en FixedUpdate. Esto evitará movimientos extraños o teleportaciones de los objetos debido a que Unity lanza eventos internos cada vez que una Transform es modificada. private bool _positionChanged; private Vector3 _newPosition; public void SetPosition(Vector3 position) { _newPosition = position; _positionChanged = true; } private void FixedUpdate() { if (_positionChanged) { transform.position = _newPosition; _positionChanged = false; } } Optimización 11 SendMessage y Find. El método SendMessage() y la familia de métodos GameObject.Find() so especialmente costosos y deben evitarse en su totalidad. El método SendMessage() es como 2,000 veces más lento que una simple llamada a una función, y el coste de Find() se escala pobremente según la complejidad de la scene aumente ya que tiene que iterar por todos los GameObject de la misma. Optimización 12 No solamente Occlusion Culling/Frustum Culling. Para los objetos que solamente tienen renderizado es factible utilizarlas únicamente. Otros objetos que utilicen cálculos internos de manera constante continuarán consumiendo a pesar del Culling. Una buena solución a este problema es utilizar las callbacks OnBecameVisible() y OnBecameInvisible(). Como los nombres dicen, estas callbacks son invocadas cuando un objeto renderizado se ha vuelto visible a una cámara o invisible respecto a todas las cámaras de la scene. Además, cuando hay múltiples cámara en la scene (por ejemplo en un juego multiplayer) las callbacks son solamente invocadas cuando es visible para una cámara o invisible para todas ellas de igual modo. Esto significa que las callback serán llamadas en el momento preciso que se necesitan. Si nadie puede ver el objeto se llamará a OnBecameInvisible(), si como mínimo un player puede verlo se llamará a OnBecameVisible(). Optimización 13 Distance vs sqrMagnitude. El cálculo de raíces cuadradas para las CPU implica bastante proceso comparado con otras instrucciones. Cuando tengamos que utilizar un cálculo de distancia, y si no requerimos de una precisión extrema, es mejor utilizar sqrMagnitude y valor a comparar por su potencia de 2. // Utilizar la raíz cuadrada en Distance() float distance = (transform.position – other.transform.position).Distance(); if (distance < targetDistance) { // dentro de distancia } // No realiza el proceso anterior float distanceSqrd = (transform.position – other.transform.position).sqrMagnitude; if (distanceSqrd < (targetDistance * targetDistance)) { // dentro de distancia } Optimización 14 Datos de Prefab a un Scriptable Object. Si tenemos muchos diferentes tipos de Prefabs que contienen datos que pueden compartirse entre ellos, como fuerza, velocidad, puntos, etc. entonces todos estos datos serán serializados en cada Prefab que luego se instancie. Una mejor solución es serializar estos datos en un ScriptableObject. Esto reduce la cantidad de datos a serializar en el Prefab, el tiempo de deserialización y el tamaño del Prefab en sí mismo reduciendo el tiempo de acciones que serán repetitivas. Optimización 15 Update(). Una mejor solución al problema del Update() es no utilizar nunca, o mejor dicho, una sola vez. Cuando Unity llama al callback Update(), o cualquiera relacionado, cruza la ya comentada frontera del Native-Managed Bridge que es una tarea costosa en términos relativos. En otras palabras, el coste de procesamiento de 1.000 Update() independiente será mucho más costoso que la ejecución de un Update() con 1.000 funciones. Para poder minimizar este problema es mejor agrupar todos los Update() en un solo Update() global que luego llame a las diferentes funciones que requieran la acción.
  3. 6 points
    Introducción En esta ocasión vamos a crear una Carta con un efecto 3D similar a la que vemos en el gif anterior. Para ello vamos a partir de un proyecto donde tenemos preparados los assets necesarios. Este proyecto podemos descargarlo desde aquí: URL: https://drive.google.com/open?id=19J6lgCA-DH28lMu9dmntk1K5l3lPE66f Una vez descargado vamos a abrirlo desde el Unity Hub. Este proyecto está creado con la versión 2019.2.9f1 asique podría ser incompatible con versiones anteriores. Una vez abierto vamos a tener una escena llamada “Sample Scene” y una serie de carpetas con los modelos,sprites,prefabs… necesarios. Además contamos con los paquetes TextMeshPro y PostProcessing que usaremos a lo largo del tutorial. Puedes acceder en todo momento a los paquetes usados a través del Package Manager. Preparando el proyecto En primer lugar vamos a abrir la escena “Sample Scene” y vamos a arrastrar en ella el prefab “Hornet” dentro a la ventana de Hierarchy. Verás que aparece en rosa, eso es debido a que no tenemos aún ajustado el Render Pipeline. Vamos a empezar por ahí. Vamos a crear una carpeta Settings donde colocaremos aquellos ajustes globales del proyecto. Siéntete libre de elegir otro nombre, yo siempre soy malisimo poniéndolos. Una vez creada vamos crear una configuración pulsando click derecho y Create/Rendering/LightweightRenderPipeline/PipelineAsets. Elige el nombre que quieras y seleccionalo para verlo en la ventana de Inspector. Aquí tenemos los ajustes del Render Pipeline. La configuración es muy intuitiva y prácticamente todo hace lo que indica. En nuestro caso solamente vamos a activar el HDR y el antialiasing. Lo demás no lo tocaremos, aunque esto va de experimentar, así que “rómpelo” a tu gusto. Una vez creado vamos a añadirlo a nuestro proyecto, para ello vamos a irnos a ProjectSettings/Graphics y lo colocamos en el hueco de Scriptable Render Pipeline Settings. Hecho esto si volvemos a la escena podemos ver que el color rosa ha desaparecido. Aunque ahora se verán blanco. No te preocupes que ese será nuestro siguiente paso. También verás que hay una luz añadida dentro del prefab de Hornet. Está configurada por mi pero llegado el punto puedes quitarla o cambiarla como quieras. Creación de Shaders Vamos a darle color a nuestros objetos ahora. Como has podido ver todos los objetos están en blanco. Eso es porque nuestros shaders y materiales están por defecto. Para nuestro objetivo vamos a necesitar crear un shader con la herramienta Shader Graph. Esta ya viene por defecto en todos los proyectos que usen el Scriptable Render Pipeline nuevo. Para ello vamos a crear una nueva carpeta llamada Shaders y vamos a crear un nuevo Shader PBR (Create/Shader/PBR Graph). Puedes ponerle el nombre que quieras, en mi caso lo he llamado Standard_SG (ya he dicho que soy muy malo poniendo nombres). Vamos a seleccionarlo y abrirlo. No es el objetivo de este taller aprender a usar ShaderGraph, asique no voy a pararme en explicar el contenido, aunque como veréis es muy fácil e intuitivo lo que haremos. Crearemos las siguientes variables: Conectaremos al Albedo un Sampler de una textura y la multiplicaremos por un color. Cómo veis el shader es lo más simple posible. Haremos lo mismo en el canal de Emission para poder ajustar la emisión de algunos objetos posteriormente. Pulsamos en Save arriba a la izquierda y cerramos. Ya tenemos nuestro shader creado pero tenemos un problema que veremos a continuación. Stencil Buffers Para obtener el efecto que buscamos tenemos que conocer el concepto de Stencil Buffer. Con ellos podemos principalmente renderizar unas partes de un objeto y descartar otras. Aquí podemos obtener más información: https://docs.unity3d.com/Manual/SL-Stencil.html https://www.ronja-tutorials.com/2018/08/18/stencil-buffers.html El objetivo es mantener “invisible” un objeto y que cuando este se encuentre en la “visión” de otro objeto, se muestre. Vamos a necesitar por dos shaders: Uno que leerá del stencil buffer y se dibujará solo donde el búfer tenga un valor específico, en cualquier otro lugar se descartará. Por otro, un shader que permanerá siempre invisible y que solamente mostrará aquellos valores específicos que coincidan con el stencil buffer. Para el primer solo necesitamos añadir unas líneas, pero actualmente no es posible hacerlo a través del ShaderGraph. Por lo que vamos a realizar una transcripción del Shader Graph al código. Para esto vamos crear un nuevo Shader Unlit pero esta vez no será de ShaderGraph. Le ponemos de nombre Standard_StencilRead por ejemplo y lo abrimos. Mientras se abre vamos a volver al Shader Graph y vamos a realizar la copia del código del shader. Para ello nos vamos al PBR Master Node y con el botón derecho seleccionamos Copy Shader. Una vez copiado vamos a pegarlo en nuestro reciente nuevo shader unlit creado, sobreescribiendo todo lo que este tuviese. También deberás cambiar la primera línea y ponerle tu la dirección y el nombre que elegimos antes. En mi caso lo he guardado en MyShaders con el nombre Standard_StencilRead. Ahora tenemos el mismo shader de Shader Graph pero en código para poder modificarlo. Vamos a necesitar añadir una nueva propiedad que será el valor específico del stencil. Simplemente dentro de properties al final, debajo del Color añadimos lo siguiente: [IntRange] _Stencil ("Stencil Value", Range(0,255))= 0 Quedando de la siguiente manera: Por último vamos a necesitar añadir los ajustes del Stencil debajo de los Tags antes de los diferentes pases. Esto hará que sólo cuando tengamos el valor de referencia, el objeto se muestre. Podemos obtener más información sobre la sintaxis y el contenido en los enlaces que anteriores. Ya podemos guardar el shader y volver a Unity. Tenemos preparado nuestro primer Shader. Para el segundo simplemente creamos otro shader unlit de nombre StencilWrite por ejemplo. Este estará siempre invisible y servirá para mostrar los objetos que compartan valor de referencia. Abrimos el shader y lo modificamos de la siguiente forma: En properties añadimos el valor de Stencil como con el anterior y eliminamos cualquier otra propiedad (normalmente textura) ya que este shader queremos que se muestre totalmente invisible. Añadimos el Stencil y le decimos que esté siempre comparando y si en algún momento el valor de referencia es el mismo, lo reemplace. Ahora le decimos al buffer de profundidad que no se escriba (por ser un objeto que será invisible) y cambiamos el modo de Blend. Podemos obtener más y mejor información de esto aquí: https://docs.unity3d.com/Manual/SL-Blend.html También eliminamos todos los añadidos de Fogs por defecto de Unity y aquellas referencias a texturas que no nos interesan. Por último hacemos que la función frag devuelva siempre 0, ya que como hemos comentado esto se muestra siempre como invisible. Con esto tenemos todo listo para pasar al montaje de la carta. PD: Asegurate también de que lo tienes en la misma ruta que el anterior. Esto no es necesario, pero te facilitará encontrarlo más adelante. En mi caso al igual que antes, esta en la ruta MyShaders. Montaje de la carta Para empezar vamos a cambiar por fin el blanco de nuestra escena, para ello vamos a irnos a Materials/Hornet y seleccionando todo vamos a elegir nuestro Shader (en este caso el Standard_StencilRead) Ahora tendremos que arrastrar las texturas requeridas (Main Texture y Emission Texture) si procede y establecer el MainColor en blanco (tened cuidado que el alfa no este a 0) y el EmissionColor en negro. En el caso que no tengamos texturas (como en el caso del personaje Hornet) simplemente cambiale el MainColor a tu gusto. Puedes hacerlo similar al original o ponerle tu propia versión. Así quedaría el del grass_material por ejemplo: O el dress_material, que no tendría textura: Sigue estas pautas en los demás materiales. El stencil value lo cambiaremos más adelante, de momento necesitamos ver en pantalla todo y no solo cuando este a través de nuestro “marco”.. Una vez terminado debería de quedarte algo similar a esto: Ahora vamos a crear un nuevo objeto en la escena llamado Card y lo ponemos en la posición 0,0,0. Ahora buscamos el Sprite “cover” dentro de Sprites y lo arrastramos dentro de Card. Le damos el tamaño a nuestro gusto. Este será el envoltorio de la carta. Ahora vamos a crear un Quad dentro de Card. Le ponemos de nombre StencilMask y lo colocamos en la posición 0,0,0 también. Este será nuestro marco a través del que se verá nuestra Hornet. Para poder ajustarlo vamos a tener que configurar ya el valor de referencia del stencil así como crear un nuevo material StencilWrite para nuestro quad recién creado. Vamos a empezar por esto último, crearemos un nuevo material con el shader StencilWrite. Lo colocamos dentro de Materials para tenerlo ordenado. A este material le vamos a poner en el valor de Stencil el valor 2 por ejemplo. Es simplemente un valor referencia, mientras tanto el receptor como el emisor tengan el mismo, funcionará. Una vez configurado vamos a arrastrarlo al StencilMask (o cambiamos el material dentro de MeshRenderer) para colocarselo. Veréis que se ha vuelto invisible, eso es que funciona como debería. Por último vamos a irnos a los materiales StencilRead que configuramos anteriormente y vamos a ponerles el mismo valor de referencia al Stencil. Seleccionamos todos o uno a uno y en Stencil Value le colocamos 2. Ahora debería de volverse todo invisible en la escena quedando solo la carta en negro. Vamos a desactivar de momento la carta llamada “cover” (o el nombre que tu le hayas puesto) de la ventana de Hierarchy. No se ve nada pero no es un error. Ahora mismo todos los shaders tienen el mismo Render Queue por lo que nuestro efecto no está funcionando. Más información de esto aquí: https://docs.unity3d.com/Manual/SL-SubShaderTags.html Sabiendo esto solamente tendremos que asegurarnos que nuestro StencilWrite se renderice antes. Vamos a nuestro material y le restamos 1 al RenderQueue. Con esto ya deberiamos tener visible nuestro modelo únicamente cuando estemos viendolo a través de nuestro quad. Ahora volvemos a activar el cover para ajustar la carta y el hueco como queramos. Al activarlo verás que tapa la visión a través del quad. No te preocupes, simplemente ve a los ajustes del SpriteRenderer del cover y cambia el MaskInteraction a Visible Outside Mask. Ahora ajustamos el Quad hasta tener el tamaño que deseemos. Una vez confirmado podemos probar a girar en la escena alrededor de la carta para comprobar el efecto. Para organizar mejor la escena vamos a colocar el objeto Hornet dentro de Card y vamos a crear un prefab para tenerlo guardado. Gracias a los Nested Prefab ya podemos hacer prefabs dentro de prefabs, asique nos viene genial. Ahora solo nos falta añadirle algo de texto. Vamos a usar TextMeshPro para esto. Pulsamos botón derecho y creamos un nuevo texto en 3D. Vamos a empezar por el nombre de la carta, por lo que le ponemos de nombre al text “Name” por ejemplo. Vamos a escribir el texto del nombre en el apartado Text y vamos mover y escalar el objeto colocándolo donde más nos guste. En mi caso he decidido ponerlo arriba. Vereis que no se ve cuando lo colocamos en la zona de la carta. Eso es por el orden de renderizado que tienen. Vamos a abrir los ajustes extra del texto (extra settings) y vamos a subirle el orden in layer a 1. Con esto conseguimos verlo, pero existe un problema, que el texto aparece también por detrás. Esto lo solucionaremos más adelante ya que tendremos que añadir un script simple para que active el culling. Llegados a este punto me he dado cuenta de que la carta está colocada del revés y el nombre por la parte trasera se ve invertido. En nuestro caso podemos solucionarlo rápido ya por delante la carta no se ve afectada. Simplemente nos vamos al objeto “cover” y marcamos Flip X. De esta forma la parte de atrás estará perfecta. En el caso de que tuvieras una imagen diferente deberías tener cuidado ya que la carta es la misma tanto en la partal como en la dorsal. Todo se dará la vuelta. Si quieres tener un control más exacto, deberás tener una carta delantera y otra trasera, cada una con su ajustes (y quizás optimizada para no pintar dos cada cara). Vamos a guardar el avance, aplicamos el prefab y guardamos escena. Deberíamos tener algo similar en estos momentos: Vamos a crear ahora otro texto para colocarlo en la parte de debajo. Duplicamos el objeto Name con Control+D y cambiamos el nombre a Description. Movemos el objeto a nuestro gusto, en mi caso lo coloque en la parte de abajo, centrado. Puedes tocar los ajustes del TextMesh que son maravillosos, sobre todo si has trabajado con el deprecado Text. Si queremos podemos cambiar la fuente. Para ello simplemente tendrás que descargarla de internet (o obtenerla de otra forma) y meterla dentro de Unity. Una vez dentro no es simplemente arrastrarla. Para poder usarla en TextMesh necesitarás crear un atlas de la fuente. Pero es fácil de hacer, simplemente abre la ventana Font Asset Creator desde WIndows/TextMeshPro. Selecciona la fuente y pulsa Generate Font Atlas (si quieres cambiar algún otro ajuste puedes hacerlo, pero ten cuidado. Más información sobre esto aquí: http://digitalnativestudios.com/textmeshpro/docs/font/ ) Una vez generada simplemente guárdala donde quieras y luego colócala en el texto dentro de Main Settings: Una vez tengamos la descripción vamos a guardar el prefab y a colocar los Post Procesos. Para ello Vamos a ir a la cámara y vamos a asegurarnos que tiene añadido un Post Process Layer. Esto es imprescindible para poder continuar. También vamos a activar a antialiasing FXAA y vamos a crear un nuevo layer PostProcessing para posteriormente usarlo en el Volume. Ahora vamos a crear un nuevo objeto en la escena. Le vamos a añadir el componente Post Process Volume. Vamos a marcar IsGlobal porque solo tendremos este para toda la escena y vamos a seleccionar un profile. En nuestro caso no tenemos ninguno creado, asique le daremos a New. Ahora simplemente asegurate de que este objeto está en el Layer PostProcessing De otra forma no funcionará y no podremos ver ningún cambio. Una vez configurado podremos ir añadiendo efectos ya creados por Unity o crear los nuestros propios. En este caso vamos a usar dos creados, el Bloom y el Color Grading. Pulsamos en Add Effect y seleccionamos uno y después el otro. Aquí puedes sacar tu lado artístico y elegir la configuración que más te guste. En mi caso después de una serie de pruebas quedó así: En este punto deberías tener algo similar a esto. Si no es así asegúrate de que el material del lazo tiene un emission color bien configurado. Por último nos queda solucionar el error del texto por ambas caras. Para eso simplemente vamos a crear un script con el nombre CullingTextMeshPro o el que querais y vamos a dejar solo la función Awake con el siguiente código: De esta forma al darle al Play el texto automáticamente hará culling y no se renderiza por detrás. Estuve informándome sobre otras formas de hacer esto, pero las respuesta de Unity fueron que esta era la forma. Pero si conocéis otra forma contactad conmigo y lo actualizo. Espero que os haya gustado y hayáis aprendido cosas nuevas que al final es el objetivo esto. Cualquier duda contacta conmigo via twitter: https://twitter.com/_davidlopez29 o por aquí Hasta pronto!
  4. 5 points
    Hola chicos, comparto con vosotros una implementación de ruido perlin noise con fBm para todos aquellos que esteis interesados. Si necesitais generación procedural de contenido, con esto solamente necesitais llamar a una función. Además las plantillas de ruido se guardan como Scriptable Object. Os dejo imagenes de las demos que incluye con ejemplos de uso, dependiendo del caso: link: https://github.com/davilopez10/PerlinNoise_Unity3D Perlin Noise 1D Perlin Noise 2D Perlin Noise 3D
  5. 4 points
    Buenas! soy Augusto de Chime Ayer comencé un canal dedicado a Unity y C# y largue con una serie de introducción a la programación en Unity. En el primer episodio simplemente vemos como instalar UnityHub y Visual Studio para dejar todo listo para el siguiente episodio: En el segundo creamos nuestro primer Hola Mundo en Unity, y vemos el concepto de variables con varios ejemplos. Ademas hice otro video suplementario que cubre varios temas básicos como para tener una buena base en Unity antes de empezar la serie Espero que les guste el contenido, voy a estar subiendo los siguientes capitulos a lo largo del mes!
  6. 4 points
    Hola, he creado un pequeño curso de introducción a los MLAgents. En total son nueve vídeos, donde se crean dos proyectos y un minijuego. El primer proyecto es muy sencillo, para no perder tiempo en nada que no sea el funcionamiento / configuración de MLAgents. Como seguir estas cosas por las listas de reproducción de youtube se me hacen complicadas me he liado la manta a la cabeza y he creado una pequeña WEB donde se puede seguir el curso, como si de una academia online se tratara, y acceder a los scripts y ficheros necesarios. La URL del curso es: https://cursos.uadla.com/curso/introduccion-al-machine-learning-con-ml-agents-para-unity/ Si alguien lo sigue por aquí, por favor, que me comente si el sistema funciona correctamente y es como de de usar. Os dejo también el vídeo de presentación: Espero que os guste, la verdad es que es un tema que me ha gustado de siempre, espero tener tiempo para ir haciendo cursos para tratarlo en más detalle y con entornos más complejos. También hay que tener en cuenta que ahora los MLAgents empiezan a estar mas o menos maduros, y sí que veo que empiezan a ser una forma de entrenar NPC's que podemos usar en nuestros juegos.
  7. 4 points
    hola he visto este video en un post de Vandal y no he podido resistirme a compartirlo era de una jam que se ha celebrado entre el 10 y el 12 de julio... ...o de unos locos que se han escapado de un psiquiatrico... no me ha quedado muy claro...
  8. 4 points
    Desarrollo en Unity 2019.3. Una primera aproximación a un FPS sin prácticamente optimización más allá de los lightmaps del entorno. Es posible utilizar diferentes FX dependiendo del material de contacto. He utilizado algunos assets de pago y otros gratuitos en los apartados de diseño solamente. El código y la integración es mío desde cero. El canal de youtube para seguir las actualizaciones es: https://www.youtube.com/user/LosSopranoNet/videos
  9. 4 points
    Finalmente, liberamos la herramienta! pueden acceder a ella totalmente gratis! http://www.modelatorsystem.com
  10. 4 points
    Hola @nomoregames, primero que nada decirte que esto no es con ánimo de ofender ni de crear controversia. Este tipo de dudas son básicos de la programación, no es algo de unity sino de el lenguaje. Yo te aconsejo leerte un libro de c# o hacerte un curso donde aprendas al menos lo básico y no andes dando palos de ciego hasta encontrar la respuesta. No me molesta para nada que hagas estas preguntas, pero me parece que se crea contenido innecesario, soy consciente de que nadie nace sabiendo pero si no nos intentamos educar seguiremos en ese bucle de por vida. Digo esto por tu bien y por el entusiasmo que veo que tienes con la creación de videojuegos, puedes explotar ese potencial. Hay muchos cursos de programación en Youtube, también puedes utilizar webs como codeAcademy o KhanAcademy que son gratuitas y super buenas. Es un mundo muy bonito y que si le echas ganas puede sorprenderte más de lo que imaginas.
  11. 4 points
    Me alegro de que os guste!! Si tenéis cualquier duda, estoy por aquí (pero en el Telegram suelo contestar antes 😉).
  12. 4 points
    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 🙂
  13. 3 points
    tienes que buscar un poco antes de preguntar, probar si puedes hacerlo mínimo 2 días y sino preguntas, tu pregunta esta en el manual lee un poco. URL: https://docs.unity3d.com/ScriptReference/Rigidbody-isKinematic.html Controla si la física afecta al cuerpo rígido. Si isKinematic está activado, las fuerzas, colisiones o articulaciones ya no afectarán al cuerpo rígido. El cuerpo rígido estará bajo control total de animación o control de script cambiando transform.position. Los cuerpos cinemáticos también afectan el movimiento de otros cuerpos rígidos a través de colisiones o articulaciones. Eg. puede conectar un cuerpo rígido cinemático a un cuerpo rígido normal con una articulación y el cuerpo rígido se restringirá con el movimiento del cuerpo cinemático. Los rigidbodies cinemáticos también son particularmente útiles para hacer personajes que normalmente son impulsados por una animación, pero en ciertos eventos se pueden convertir rápidamente en un ragdoll estableciendo isKinematic a false. using UnityEngine; using System.Collections; public class ExampleClass : MonoBehaviour { public Rigidbody rb; void Start() { rb = GetComponent<Rigidbody>(); } // Let the rigidbody take control and detect collisions. void EnableRagdoll() { rb.isKinematic = false; rb.detectCollisions = true; } // Let animation control the rigidbody and ignore collisions. void DisableRagdoll() { rb.isKinematic = true; rb.detectCollisions = false; } } este es un ejemplo básico solo para la colisión y estado muerto del enemigo, si quieres chocar al enemigo y que las físicas interactúe con el enemigo muerto tienes que hacer un Ragdoll del enemigo para desactivar la animación del enemigo y que cuando tenga 0 de vida se caiga y lo puedas mover cuando colisionas con el. public void Ejemplo(float amount) { if (health < 5) //este valor depende de cuanto daño le haces al enemigo., lo que dice es si vida es menor a 5 pasa a estado de muerte. { muerte(); } } void muerte() { Destroy(GetComponent<NavMeshAgent>()); // aca se desactiva la inteligencia Artificial. anim.enabled = false; //aca desactiva la animacion quedando solo el Ragdoll. } sino sabes que es un Ragdoll acá te dejo un link :"" https://www.youtube.com/watch?v=DInV-jHm9rk&t=1s¨
  14. 3 points
    necesito ayuda! no se si esto funcionara foreach (User _user in UnitySpainUserList) { _user.addMessage("felices fiestas"); }
  15. 3 points
    Hola! @Megadok para hacer ese uso es muy simple. Lo enums son tratados no solo con los nombre que les des(espada, arco,etc) sino que por defecto tiene un index asociado comenzando desde 0. Por lo que si queres que tu variable _arma sea igual a lanza por ejmplo solo tendrías que castear el tipo armas delante del index correspondiente a lanza(que sería 2). Te dejo un ejemplo. public enum armas { espada, //0 arco, //1 lanza, //2 hacha //3 } public armas _armas; private void Start() { //el casteo se hace poniendo entre parentesis el tipo que te interesa obtener _armas = (armas)1; //esto hara que _armas sea "arco" } //Con tu codigo seria asi string[] r = System.Enum.GetNames(typeof(armas)); for(int i=0;i<r.Lenght;i++){ _armas = (armas)i; }
  16. 3 points
    Muchos lo sabréis y otros no, pero hay una lista de recursos bastante tocha hecha en zeef.com de recursos para el desarrollador de videojuegos. Espero que os sea de utilidad! https://game-development.zeef.com/daniel.cuadrado.gonzalez
  17. 3 points
    Este código lo hicimos en otro post. Pásale una List de elementos y te los posicionará de manera aleatoria: public void shuffle<T>(IList<T> list) { System.Random random = new System.Random(); int n = list.Count; for (int i = list.Count - 1; i > 1; i--) { int rnd = random.Next(i + 1); T value = list[rnd]; list[rnd] = list[i]; list[i] = value; } }
  18. 3 points
    hola a todos. acabo de subir un nuevo trailer a Youtube
  19. 3 points
    Acabo de subir el siguiente capitulo: Lógica y ciclos. En este video vemos la sentencia if, junto con else. Ademas vemos el ciclo for y el ciclo while. Y por ultimo vemos las sentencias continue y break para ciclos Edit: No quería spamear mucho el post así que agrego el siguiente episodio aqui. En este cuarto capitulo vemos varias cosas: Función Update, Físicas de Unity, Input del jugador, la función GetComponent, framerate-independence y como detectar colisiones entre objetos.
  20. 3 points
    si es el angulo z el que quieres comprobar en vez de "transform.forward.z" pon "transform.right.y"
  21. 3 points
    Buenas gente, Al final no cambie de trabajo y sigo en el actual que me deja tiempo para desarrollar juegos asi que me he decidido a hacer la segunda parte de BLOODSHOT EYES Despues de la buena acogida que tuvo la primera parte me ha dado animos para hacer una segunda. Mi principal premisa es que quede profesional, cosa que en el anterior algunos aspectos dejaba mucho que desear. Quiero abrir este hilo para ir subiendo los avances a modo de devblog, no como en mis otros juegos que abria un hilo cuando ya estaba terminado. El anterior al ser mi primer juego iba improvisando todo y no tenia ningun tipo de concepto previo ni diseño ni nada, era un caos. En este quiero dedicar una buena parte a diseñar el juego antes de ponerme manos a la obra. La historia del anterior juego para los que no lo conociais trataba de una especie de scape room en una casa (escape house quizas se podría llamar). Te despertabas despues de haber estado de fiesta en una casa abandonada y no podias salir de la casa, mientras tres niños satanicos te hacian la vida imposible. Esta segunda parte va a tratar de, de donde salieron esos niños. Estara ambientado en un bunker donde la iglesia trataba de crear tres nuevos profetas con poderes que harian que la iglesia volviese a dominar el mundo, el caso es que les sale mal y los niños se vuelven satanicos. El jugador como protagonista, despierta despues de haber estado de fiesta en una acampada donde el camino de vuelta ha quedado bloqueado por un derrumbe, investigando llegara hasta el bunker, tras entrar en el bunker ya no podrá salir y tendra que averiguar como salir del bunker donde ya se desarrollaran todo el juego. Dejo a continuación algunos puntos que quiero que tenga el juego: -SENSACION DE QUE TE PERSIGUEN: el el primer juego la gente decia en los comentarios que la ambientacion de miedo y suspense era buena pero que luego realmente no sentian la tension de que algo les perseguia y estaban en lo cierto, una vez que tenias la linterna y ya tenias luz todo el rato, podias estar 3 horas parado que no te iba a pasar nada, en este voy a crear unos NPC (los niños) que vayan patrullando y de los que tendras que esconderteen armarios, cajas, etc... -HUMOR NEGRO: esto gusto mucho en el anterior juego y quiero mantenerlo. -GUIÑOS AL ANTERIOR JUEGO: Me gustaria hacer guiños al antiguo juego, como el oso Tommy, los muñecos del kamasutra etc... -FONDO NARRATIVO: En el anterior juego habia unas notas que te contaban un poco la historia de los dueños de la casa, pense que no llamaria mucho la atención porque mucha gente pasa de leer, pero a otra gente les gusto mucho y hacia que el juego tuviese sentido narrativo. En este juego lo voy hacer mediante cintas de cassette. -BUENA CALIDAD GRAFICA: En el anterior juego gracias a gente de este foro me quede bastante contento con los graficos y la iluminacion del juego pero no con los modelos 3D, en este me lo quiero currar y aunque el modelado no es para nada mi fuerte intentare que sean detallados. Los niños estoy probando ha hacerlos un poco etereos, una especie de humo negro o que vayan con una capa que les cubra casi enteros. Tendre que probar ya que no me veo modelando y animando bien tres niños, en el anterior juego quedaron muy cutres. Y por ahora es lo que he pensado. Empezare a conseguir que las mecanicas funcionen y cuando ya funcione todas las mecanicas me pondre con la ambientacion, decorado, iluminacion, modelos etc... Por ahora he conseguido que un humo negro vaya patrullando por un escenario y cuando te vea te persiga y si te pilla mueres. Que vaya patrullando lo consegui con la Navegacion y los agentes de unity. Y para que tuviesen "vision" y te detectaran segui este TUTORIAL muy interesante. Bueno dejo de enrollarme ire actualizando contenido. saludos
  22. 3 points
    La Persistencia Cuántica de Bits o PCB. Es algo muy típico. 😂
  23. 3 points
    Hola Cerpion, Lo primero: No es terrible hacer referencia a otros scripts, pero en un mundo ideal, generalmente es preferible hacer referencias a abstracciones de tus scripts. Esto nos permite que sea más fácil reutilizar y cambiar nuestro código en un futuro. Ahorita me explico más: Supón que tienes un script llamado Player, y un script llamado Joystick, que a su vez tiene un método llamado GetMovement. Algo así: public class Player:MonoBehaviour { //Esta es una manera de obtener la referencia, aquí aparecería un campo para asignar el Joystick en el inspector: public Joystick playerJoystick; //La otra manera sería: private void Start() { playerJoystick = GetComponent<Joystick>(); } } public class Joystick:MonoBehaviour() { public Vector2 GetMovement() { //Supón que aquí regresaramos un movimiento de verdad en lugar de ceros. return new Vector2(0,0); } } Y eso funciona en general. Pero en un futuro tal vez vayas a querer tener players controlados por la computadora, o diferentes scripts para diferentes tipos de control, o qué sé yo que te depare el futuro. Para estar preparado para el futuro, y que te sea más fácil agregar y cambiar cosas, es mejor que nuestras referencias sean más abstractas, que Player en lugar de referirse a un Joystick haga referencia a, por ponerle un nombre, un MovementProvider. Hay dos formas de hacerlo. Una es con clases abstractas: public class Player:MonoBehaviour { //En lugar del Joystick, hacemos referencia a un MovementProvider, que puede ser un Joystick, pero también otra cosa que se te ocurra. public MovementProvider playerMovement; private void Update() { //Aquí usarías el vector que regresa GetMovement de para mover tu jugador alguna manera playerMovement.GetMovement(); } } //La palabra abstract aquí significa que el script no puede ser usado por sí solo, necesita que otro clase herede de ésta para usarlo. public abstract class MovementProvider:MonoBehaviour { //La palabra abstract aquí significa la funcionalidad de este método debe ser definida en las clases que hereden de ésta. public abstract Vector2 GetMovement(); } //Nota como no heredamos de MonoBehaviour esta vez, sino de la clase abstracta MovementProvider. //Cualquier otro script puede hacer lo mismo y definir su propia función para GetMovement public class Joystick:MovementProvider { //Override significa que estamos sobrescribiendo la funcionalidad definida en el padre, en este caso en MovementProvider. //Es cierto que, de hecho, MovementProvider no definió ninguna funcionalidad, lo dejó abstracto, pero igual hay que ponerlo. public override Vector2 GetMovement() { return new Vector2(0,0); } } Y dos es con algo llamado interfaces: public class Player:MonoBehaviour { public IMovementProvider playerMovement; private void Start() { //Como no podemos obtener la referencia a IMovementProvider desde el inspector, hay que obtenerla de otra manera. Puede ser así: playerMovement = GetComponent<IMovementProvider>(); //Si el componente está en otro GameObject, podríamos poner un campo de tipo GameObject en el inspector y luego: playerMovement = otherGameObject.GetComponent<IMovementProvider>(); } private void Update() { //Aquí usarías el vector que regresa GetMovement de para mover tu jugador alguna manera playerMovement.GetMovement(); } } //Las interfaces definen un conjunto de métodos y propiedades que debe implementar una clase. //La ventaja de las interfaces es que puede aplicarse más de una a la misma clase, la desventaja es que no salen en el inspector. //Es común poner una I en el nombre para identificar que es una interfaz. public interface IMovementProvider { Vector2 GetMovement(); } //Nota como avisamos que implementamos la interfaz. Si hay más interfaces, se pueden seguir agregando separadas por comas. public class Joystick:MonoBehaviour, IMovementProvider { //Con las interfaces no tenemos que usar override, basta que el método sea público. public Vector2 GetMovement() { return new Vector2(0,0); } } Respecto a tu segundo punto, generalmente, entre más puedas dividir tus scripts, mejor. La idea es que, entre menos cosas distintas haga un script, más probable es que los puedas reutilizar en varias partes diferentes. Y es menos probable que los tengas que modificar cuando otra cosa cambie en tu código. Cualquier cosa que quede sin explicarse bien, o cualquier duda, tú dime con confianza. Ahm, espero no haber sido demasiado teórico o demasiado confuso; esto de lo que hablé viene de unos principios de programación llamados SOLID, que son muy útiles como guía para facilitarte la vida, pero que luego uno no sabe explicarlos bien porque ya se acostumbró tanto que ya ni piensa en ellos. Por último, estas recomendaciones que te di, no dejes que te atoren mucho; se aprende haciendo y además, en esto de hacer juegos, todo mundo acaba haciendo montón de excepciones a este tipo de reglas. PD Eso del game manager y las referencias estáticas yo realmente te recomendaría evitarlo siempre que puedas. Hay razones para hacerlo, como si nomás es un prototipo rápido, o un juego móvil simple, o ciertas cosas que es mucho más complejo hacer de otra forma. Pero, generalmente, ese patrón de organizar tu código que algunos llaman singleton, acaba dándote muchos más problemas de los que arregla. En el momento en el que decides, por ejemplo, que tu juego es multijugador, tienes que ponerte a rescribir código en todos los lados que usan esa referencia estática, en código que escribiste hace mucho tiempo y que vas a tener que releer completito para entender cómo cambiarlo.
  24. 3 points
    la verdad que estan chulas las fisicas del cable. creo que esto no cuenta como spoiler del juego... o si? si es asi lo siento, cierrenme el tema. pero me gustaria devatir como creen qye funcionan esas fisicas. creen que la manguera esta formada por pequeñas secciones? o es mas bien varios raycast que dividen la manguera en secciones mas grandes cuando colisiona? y el tramo que tiene enrollado en la mano?? forma parte de la misma manguera? o es un objeto adicional para que de la sensacion de que se enrolla.... y miestras tanto la manguera original crece o disminulle su longitud en relacion con la parte que ha enrollado en la mano? ...claro que la parte que tiene enrollada en la mano tiene fisicas tipo "cloth".... pero no reacciona al escenario... eso es lo que me ha hecho pensar que son dos cosas distintas la manguera y lo enrollado... aunque tamvien cuando la lanza cambia un poco el comportamiento... creo que puede ser todo un unico objeto al que le cambian las "layers" de colisiones depemdiendo el momento ...y depemdiendo de que secciones de la manguera sean les ponen unas layers u otras... puede que todo sea una especie de "cloth" gigante... que cuando ha alcanzado su maxima tension (estirado) manda un mensage al personaje para que haga la animacion de "huy, ya no alcanza mas" ustedes que opinan?
  25. 3 points
    Mmm no lo se Rick, parece falso ... Tampoco lo entenderías (sin ser peyorativo), primero porque esto no se explica así. Además de que la pregunta suena a "atajo", que ya es algo incómodo para la persona que pretende ayudarte. No estaría tan seguro de eso, me explico... En mi tiempo en la facultad tuve la suerte de cruzarme con profesores bien hijos de puta, que si les preguntabas algo que estaba en el libro (cosas muy obvias claro) te humillaban (un poco en joda) en frente del grupo. En realidad estaban incentivando a tres cosas muy importantes: Que el alumno siente el culo en la silla, que sepa usar el material disponible (es decir, leerlo al menos). Que el alumno no suelte la lengua por cualquier cosa en clase. Es decir, hay que estar algo preparado (o al menos entender el tema previo) antes de hablar por hablar (sí, había algunos que paraban la clase como 15 veces por día). Que en una consulta, el tiempo empleado realmente valga la pena (para ambos, alumno y profesor). Todo esto desemboca en el respeto al otro (falta de respeto no es necesariamente insultar al otro, aunque podría pasar). Así que, imaginate lo que un "master" siente cuando lee "Si tubierais la amabilidad de hacer un pequeño script... algo fácil de entender" de un tema super básico (que es la base de), y super bien explicado y ejemplificado en casi cualquier medio (blogs, tutoriales, documentación, libros, videos, Unity, etc) como lo son las 👉 clases 👈. Esto a mi me dice que de tu lado estás haciendo cero esfuerzo, y que yo tengo que laburar por vos. Es una relación unidireccional. Si esto pasa seguido, lo más seguro es que empiecen los comentarios un poco desagradables, se empieza a notar ese roce poco a poco. Lo más loco es que seguramente que no surja de malas intenciones tuyas, pero sin darte cuenta estás provocando exactamente esto (y más acá que nos conocemos todos). Mi consejo (en general): Limitar las preguntas (vos mismo dijiste que hacías una tras otra --> "... por aquí mas de un año y sigo haciendo las mismas preguntas idiotas. ") Apuntarlas a algo en concreto, que no sean "Haganme un script que explique el origen del cosmos" ... Por ej: "¿En qué contexto debería utilizar una clase en Unity? Por qué no utilizar una struct para esto?" Preguntar por recursos de ser necesario, si no sabes donde buscar está perfecto. El hecho de preguntar por recursos le dice a quien te ayuda que por lo menos te esforzas en investigar antes. Que no se mal interprete, es no es una evaluación ni nada por el estilo (aunque pueda sonar a una cuando digo "desmuestra a quienes te ayudan tal o tal cosa"). Por ej, yo no sé nada de VR o XR (ni siquiera sé la diferencia entre estos 😆), pero sé que @iRobb la tiene clara (podría decir lo mismo de Networking y @francoe1 ). Sería super irrespetuoso de mi parte inundarlos de preguntas a la primera (ya sea directamente o creando un hilo), por lo menos me dedicaría una semana a investigar por mi cuenta (de ser posible). En caso de no llegar a nada, o verme realmente perdido, bueno ahí sí acudiría a ellos, mencionando mis logros en lo que respecta al tema, mis avances, dónde investigué, qué documentación visité, etc. En fin, mi opinión.
  26. 3 points
  27. 3 points
    Y aquí estamos con más novedades. El "esperado" ciclo día/noche y cambio atmosférico dinámico:
  28. 3 points
    ¿Has probado a juguetear con los distintos parámetros que tiene el NavMeshAgent? https://docs.unity3d.com/ScriptReference/AI.NavMeshAgent.html En el siguiente vídeo de Brackeys muestra un poco alguno de estos parametros
  29. 3 points
    Hola! El curso tiene ya 3 niveles con un total de mas de 130 videos actualemte y aun quedan 3 niveles mas. los invito a que se unan, estoy empezando el nivel 4 del curso. saludos
  30. 3 points
    Espero que no se considere como spam, pero estoy grabando mis progresos aprendiendo Unity a través de un juego de cartas. Está claro que si lo veis las vacas sagradas, me atizais en el lomo, pero igual viene bien para los que son tan inutiles como yo. Pues eso. Aquí lo dejo, por si van apareciendo novatillos en esto. A darle duro.
  31. 3 points
    ¡Buenas! En este post @seimus comentaba sobre una herramienta para exportar un tilemap como PNG, y @pioj también estaba de acuerdo con la idea así que hice una pequeña herramienta y la subí al github. La verdad es que la he testeado muy poco pero en principio debería adaptarse a cualquier tamaño, yo la he estado testeando con sprites de 32x32. Os dejo un vídeo y el enlace a github! https://github.com/leocub58/Tilemap-to-PNG-Unity Espero les sirva de ayuda, yo la verdad es que lo he hecho por simple aburrimiento jajajaja. ¡un saludo!
  32. 3 points
    Buenas tardes a tod@s, Quería plantearos una nueva forma de organizar y mostrar contenidos de la web proporcionándole mayores interacciones y facilidad de visualización de contenidos. Actualmente el sistema foro, desde mi punto de vista, ha quedado limitado y no se adapta a las "nuevas exigencias" y hábitos de los nuevos usuarios que están llegando y que llegarán en el futuro. Los foros tienen una forma de distribución de contenidos basado en subcontenidos en el que el usuario debe ir navegando a través de diferentes topics/contenidos hasta llegar al apartado que le interese y donde se le indica que existe nuevo contenido a través del simple cambio de icono. Como todos sabréis estos últimos años han ido cayendo en desuso y es una realidad de que la mayoría de sistemas de foro integrados en páginas web se parecen más a lo que vemos en redes sociales que al estilo clásico que de hecho todavía se sigue utilizando en UnitySpain (aunque bastantes novedades como sistema de notificaciones). No nos engañemos, antes de que los foros se pusieran de moda como una forma de comunicación existían las listas de correos, las cuales hoy en día son una ventana al pasado y de lo que creo que los foros, tal y como los conocemos, les espera el mismo destino. Los nuevos usuarios, y los que vendrán los próximos años, están habituados a utilizar otros sistemas de comunicación muchos más versátiles, cargados y destacando contenidos multimedia por delante del simple texto y mostrando de forma ordenada "el contenido más nuevo" en detrimento de lo más antiguo para facilitar de un vistazo lo último publicado, comentado, etc. Es mejor mostrar un vídeo o una imagen de lo que acaban de publicar que el simple texto "este es mi proyecto rts", porque atrae mayor interés, o no, según el caso de lo mostrado. No es solamente una nueva forma de mostrar contenidos, sino que abre un nuevo abanico de posibilidades de interacciones entre los usuarios. Ciertamente el foro actualmente tiene algunas funcionalidades que podríamos calificar de sociales, pero la forma de distribución de contenidos no se asemeja a lo que está demostrado que funciona, que incentiva a la comunicación entre usuarios y que mantienen una conexión constante a la web. Podría detallar cada una de las nuevas funcionalidades o estilos de contenidos a los que hago referencia, pero creo que todos conocemos y reconocemos la utilidad de redes sociales como Twitter o Facebook. Cada usuario tendría su propio espacio (estilo muro o blog), podría subir archivos e imágenes y disponer de su propio portafolios y unirse y crear grupos, los cuales podrían sustituir a lo que actualmente conocemos como cada foro. La página principal mostraría directamente los últimos contenidos publicados, comentarios y actividades, no teniendo el usuario que navegar entre subcontenidos para encontrar lo último publicado (siendo algo más llamativo que el recent topics). No digo que este sistema de comunicación y muestra de contenidos sea mejor, sino que es diferente y se adapta a lo que hoy es el resto de la WWW. Por todo ello, creo que podríamos plantearnos cambiar el foro por un sistema como el que os comento utilizando software como Buddypess, elgg u otro que cumpla la misma función. A continuación os dejo algunas imágenes y enlaces para que podáis ver algunos ejemplos de lo que os he relatado. Espero vuestros comentarios sobre esta idea y el debate que aquí se abra. Esto no quiere decir que sea un debate para cambiar lo existente sí o no, sino de abrir esta posibilidad y comentar los pros y los contras del posible cambio. https://olympus.crumina.net/members/dan_cortese/friends/ https://buddy.ghostpool.com/ http://themekitten.com/demo/atlass2/activity/ https://seventhqueen.com/themes/kleo/members/kleoadmin/groups/
  33. 3 points
    Lo primero es aclarar que con este post no pretendo ni faltar, ni empezar ningún tema de discusión, ni causar ningún tipo de enfrentamientos, pero este tipo de cosas me gusta poder expresarme claro, sin ningún tipo de tapujos.Como digo en algunos de mis post...vayamos por parte como dijo el tito jacky. Como bien comenta francoe1 esta conclusión no quiere decir que no compartimos opiniones. peor referente a este post hay algunas cosas desde mi punto de vista que no comparto. 1-Desuso Referente a este punto te puedo asegurar que estas totalmente equivocado, ya que las mayores comunidades y las mas seguras que existen tanto publicas como privadas en el world son el 70% foros, que suelen estar modificados y actualizados por los propios usuarios, incluso yo diría muchos mas antiguos que este sistema de foros, otra cosa es que le buscador de del señor GOOGLE te cape el mas del 75% de todo el internet, para que solo te centres en la moda que suele usar la gente. Vamos... hablando claro y sin faltar al respeto de nadie....es para hacer borregos. Un poquito de humor nunca viene mal. XD -El motivo principal de usar cosas simplificadas es muy fácil.(Menos módulos menos problemas y mas fluidez) simplemente hay que saber usar la herramienta y saber que función tiene, y no pase como esta pasando ahora que tengo amigos con carreras terminadas de informática y no saben que es un disco de 5 y 1/4.(y eso desde mi punto de vista es muy triste) -Por lo que en general contra menos módulos y menos chorradicas tenga mucho mejor, siempre y cuando cumpla la función para la que se usa. 2-Forma de comunicación. -En este tema también te equivocas, pero no lo voy a ampliar porque la verdad no viene al caso para el hilo del post. 3-Lista de correo -Referente a la comunicación de listas de correo no es que estén en desuso para mandar o recibir información, si no todo lo contrario, la única diferencia es que para chorradicas y tonterías ya tenemos el wasap, dejando los correos en una posición mucho mas seria y personal a la hora de comunicarse con alguien. 3-"Simple texto" Aquí reafirmo lo comentado anteriormente con la frase de Joseph Goebbles ministro de propaganda de la Alemania nazi " Una Mentira repetida mil veces...se transformara en verdad" 1 Imagen = 1000 palabras. 1 vídeo = 1000 imágenes. Por lo que la deducción es........... -Con esto no implica que se usen imágenes o vídeos para mostrar o explicar las cosas, pero eso no quita que sea mejor que el texto, simplemente es una herramienta mas que bien usada puede ayudar mucho a la hora de realizar ayudas o comunicaciones, pero solo eso....ayudas en conjunto al texto. 4-Mejor mostrar un vídeo??? Creo que es este caso esta claro, por norma general cuando alguien pide ayuda en algún tema, que es lo que mas se suele usar este tipo de foros desde mi punto de vista, necesitas ayuda a ser posible para ayer, por lo que ponerse a montar un vídeo para una ayuda, sinceramente es una estupidez y una perdida de tiempo ya que casi todo esta en joutube (No se pierde nada por mirar en jotube antes de preguntar por aquí algún problema). Dejando el foro para ayudas o información mas técnicas, le da una profesionalidad que dejaría de tener si nos ponemos a poner corazoncitos y chorradas cada 3 por 4. 4-Demostrando que funciona? Referente a que las redes sociales que comentas como facebook y twitter recordar que las redes sociales "No son foros" las redes sociales son para una cosa y los foros son para otra totalmente distintas. 5-Portafolios propios. -Aquí mas que aclarar una cosa, ya que yo también creía que esa opción podría ser buena en las comunidades hace tiempo, destacar que los portafolios personales en este tipo de comunidades no suelen ser prácticos y dan mareos de cabeza. Para eso ya hay paginas que se dedican a ese tipo de cosas como puede ser arstation, pinterest etc... No es por el echo de subir las cosas en un foro, es simplemente que esa pagina se dedica a eso, por lo que pagara su cuota a los motores de búsqueda para salir en la sección de imágenes de Google, Firefox, etc.. y si lo que te interesa es tener algun tipo de difusión publica, tendrás muchas mas opciones si usas las plataformas que ya hay. Opinión personal referente al foro. -Bueno y ya por ultimo, yo la verdad es que el foro lo veo bien tal y como esta,ya que para mi la función principal la cumple, que se vayan añadiendo alguna que otra cosa que vean los administradores que pueden ser útiles, lo veo bien mientras no pierda la esencia del foro, pero un cambio radical lo veo una cagada, como dicen... si algo funciona, mejor no lo toques, y si no que se lo digan a la de Cazafantasmas 3 xDDD. Bueno pues con esto me despido, espero no haber sido muy pesado y reitero que este post no esta montado para faltar el respeto a nadie y si alguien lo ve así, mis disculpas no era mi intención, pero quería dejar mi opinión clara, se ve que tanto tiempo en casa encerrao me da que pensar . Un saludo a todos 😄
  34. 3 points
    Utilizad el sharedmaterial, no el material.
  35. 3 points
    La última actualización que ya puse vía Telegram. Así se ve la evolución:
  36. 3 points
    En esta entrada vamos a aprender a crear nuestro primer shader Vertex/Fragment en Unity. Iremos paso a paso hasta terminar creando nuestra propia bandera con ondulación: Requisitos Para crear este proyecto podemos usar cualquier versión de Unity 2018/2019/2020 siempre y cuando a la hora de crear el proyecto usemos la plantilla de 3D (Built-in Render Pipeline) Antes de pasar al código, creo que es necesario que definamos qué es un shader y las partes que lo componen. ¿Que es un Shader? Un shader es un contenedor de instrucciones que se envían a la GPU para mostrar los elementos que tenemos en pantalla. Al igual que el script de un personaje contiene las instrucciones para que este se mueva o gire, el shader contiene información sobre el color o los vértices de un objeto. Al igual que para escribir comportamientos Unity usa C#, para escribir shaders Unity usa su lenguaje llamado Shaderlab. A su vez Shaderlab permite escribir fragmentos de código en CG (C for Graphics) que es donde realmente estará el código del shader en sí. El lenguaje CG fue desarrollado por Nvidia y Microsoft y es compatible tanto con OpenGL como con DirectX. Veremos más adelante en profundidad las partes que componen Shaderlab y CG. Tipos de Shaders En Unity tenemos dos opciones a la hora de crear un shader. Surface shaders: podemos definirlo como una "plantilla" creada por Unity para facilitarnos gran parte del trabajo aunque dando menos control sobre el resultado final. Vertex/Fragment shaders: el código que existe bajo la capa de Surface anterior. Tiene mayor complejidad pero ofrece mayor control sobre el resultado. En esta entrada nos centraremos en estos últimos, ya que el paso a Surface (o a ShaderGraph) es mucho más productiva si conocemos los conceptos del Vertex/Fragment. Fases del Pipeline Para conseguir mostrar un objeto de juego (3D) por pantalla (2D) se requiere de un proceso con varias fases. Ese proceso es llamado Rendering Pipeline. Para que sea más sencillo de entender, voy a resumir los pasos para centrarnos en los que nos interesa ahora. Básicamente tenemos dos funciones que podemos modificar: Vertex: En esta función podemos modificar datos relativos al mesh, principalmente la posición de los vértices, de ahí su nombre. Consta de una entrada de datos (como la posición de los vértices mencionada o las uvs) y produce una salida que será el input de la función fragment. Fragment: En esta función obtenemos los datos recibidos después de convertir las coordenadas del objeto en coordenadas de pantalla. Por ello todas las modificaciones aquí son a nivel de coordenadas de pantalla. Por ejemplo el color, su transparencia etc. Esta explicación es muy superficial y muy rápida, puedes encontrar más información aquí: https://en.wikipedia.org/wiki/Graphics_pipeline Una vez explicado esto, vamos a pasar a la parte práctica. Abrimos por fin Unity y creamos el proyecto con la plantilla de 3D que comentamos (Built-in Render Pipeline). Partes de un Shader en Unity Para empezar vamos a crear una nueva escena. La abrimos y creamos un nuevo Shader Unlit: Le ponemos de nombre FlagEffect por ejemplo y creamos un Material que lo use. Ahora crearemos un cubo en la escena y le colocamos las siguiente posición, rotación y escala: Creamos ahora un Plano, le arrastramos nuestro material y lo colocamos en: Si todo ha ido bien deberás tener algo así. Puedes ajustarlo tú a tu gusto (aunque ten cuidado al girarlo ya que podrías no tener el resultado esperado al final) Una vez creada nuestra bandera, vamos a abrir el shader FlagEffect. Vamos a borrar todo el contenido y vamos a ir conociendo sus partes poco a poco. Esta sería la estructura del shader con la que deberías empezar: Shader: La carpeta donde se registrará nuestro shader. Properties: Son las variables que podemos crear y ver a través del inspector del material. Cuando en un inspector ves una cajita para la textura, un botón para el color o un campo con un valor numérico aquí es donde se deben crear. La sintaxis es la siguiente: NombreVar ("TextoInspector",TipoVariable) = ValorPorDefecto Aquí podemos ver las diferentes propiedades que podemos crear en Unity: https://docs.unity3d.com/Manual/SL-Properties.html SubShader: El contenido del shader estará aquí dentro. Pass: Cada llamada de pintado que haremos. Cada una tendrá sus funciones Vertex y Fragment. Por defecto solo tendremos y necesitaremos una. Aquí es donde estará el código, acotado entre la pauta de inicio y de fin de CG que vemos en la imagen. Fallback: no es obligatorio aunque es recomendable. Si nuestro shader no es compatible con la plataforma en la que corra, se llamará a otro shader para evitar que se vea rosa. Pero para nuestras pruebas recomiendo borrar la línea. De esta forma si tenemos algún problema con nuestro shader podremos verlo directamente (de otra forma puede que llame al Fallback y no lo veamos rosa). Una vez tenemos la plantilla básica, vamos a añadir las funciones de Vertex y Fragment y los input/output necesarios. Vamos a empezar creando estos últimos. Como vimos anteriormente vamos a necesitar una entrada a la función Vertex y una salida de ella. También necesitamos una salida de la función fragment. Para esto usaremos struct de C (que se declaran igual que en C#). Ahora vamos a necesitar las funciones Vertex y Fragment. La primera tendrá como parámetro su input y devolverá el output. La Fragment tendrá como parámetro el output del vertex. Hasta aquí simplemente tenemos las funciones creadas con sus correspondientes inputs/ouputs configurados (aunque vacíos). Si vamos a Unity veremos nuestro material rosa y eso es debido a que el shader cree que nuestras funciones son diferentes a las Vertex/Fragment. Tenemos que decirle mediante un #pragma que la función de vertex se llama vert en nuestro código y que la función fragment se llama frag. Puedes ponerle otro nombre a las funciones sin problema, siempre que en esta conexión lo pongas bien: De esta forma ya no tendremos problemas con nuestro shader, salvo por el pequeño problema de que no se ve nada. Inputs y Outputs En este apartado vamos a rellenar nuestros structs de datos con la información que necesitamos en nuestras funciones de vert y frag. Dependiendo del shader que estemos creando vamos a necesitar más o menos datos dentro de los inputs. Por ejemplo si solamente queremos cambiar el color del objeto a rojo, no necesitamos datos de UV. Podemos ver todos los datos que podemos usar en cada función aquí: https://docs.unity3d.com/Manual/SL-VertexProgramInputs.html En nuestro caso vamos a necesitar para las ondulaciones de la bandera, la posición de los vértices y las coordenadas de uv del modelo. Para ello vamos a crear estas dos variables dentro de vertexInput y de vertexOutput. Lo que aparece después de los dos puntos es la semántica y es necesario para conectar los datos. En el artículo anterior de Unity explica esto más detenidamente* * Te darás cuenta de que Unity en el output usa SV_Position, que simplemente es un valor de sistema que lo hace más compatible con los sistemas actuales, para facilitar el entendimiento lo he obviado y he usado el POSITION Llegados a este punto voy a explicar rápidamente los tipos de variables que podemos usar dentro de CG. Como ves he usado fixed2 y fixed4. El número al final hace referencia a vectores de 2 y 4 datos. Sería algo similar a un Vector2 o un Vector4. El tipo fixed es el tipo de menos coste y de menor precisión. Estarás acostumbrado a ver float o int. Estos también pueden ser usados de la misma forma que fixed. Aquí puedes ver los tipos de datos: https://docs.unity3d.com/Manual/SL-DataTypesAndPrecision.html También puedes crear matrices siguiendo la misma lógica, la sintaxis sería “float4x4”,siendo los valores del final las filas y las columnas. Una vez tenemos el vertex con los datos, vamos a pasar al fragment. Este simplemente necesitará un valor, el color final del pixel. En este caso usaremos SV_Target que es el que Unity recomienda por defecto. Como he dicho tienes más información acerca de la semántica en los enlaces anteriores. Como normalmente el fragment solo tiene un valor de devolución, puedes optimizar y borrar el struct de output cambiando el frag de la siguiente manera. El resultado es el mismo que el anterior pero en menos pasos. Ahora vamos a rellenar nuestra función de vertex. Pero antes vamos a necesitar incluir funciones que Unity nos ofrece para facilitarnos el trabajo. Como hemos dicho antes, vamos a convertir la posicion 3D del objeto en posición de pantalla. Para esto vamos a usar una función de Unity llamada UnityObjectToClipPos. Esta función recibe la posición de los vértices y devuelve las posiciones en espacio de pantalla para después usarlas en la función fragment. Para poder usarla vamos a incluir esta línea debajo de los #pragma. El #include sigue la misma lógica que los using en C#, de esta forma podemos hacer uso de funciones que Unity tiene preparadas (como la que hemos comentado antes). Ahora en la función vertex vamos a igualar el output que devolveremos a lo que la función UnityObjectToClipPos nos devuelva. De esta forma convertiremos los vértices para el fragment. También vamos a igualar de momento las uv del input y del output, aunque las usaremos justo ahora. Procedemos ahora a mover por fin los vértices. Para esto vamos a necesitar conocer por un lado la variable interna _Time que posee Unity, similar a Time.deltaTime. Esta es un Vector4 con diferentes tipos de tiempo en cada una. Aquí podemos ver más información de esa y de otras variables internas de Unity: Por otro lado vamos a hacer uso de la función seno de CG para las ondulaciones. Creamos una nueva función en nuestro shader, de nombre flag que devuelva un fixed4. Además tendrá como parámetros la vertexPosition y las uv. Tened en cuenta que el shader compila de arriba hacia abajo, asique si escribís vuestra función al final y la usáis antes, dará error. Siempre tenéis que crear vuestras funciones antes de usarlas (a diferencia de C# por ejemplo). ahora dentro vamos a ir sumando a la vertexPosition el seno de _Time.y (el tiempo por defecto).Lo igualamos en la función vert al o.vertex quedando así: Estamos simplemente moviendo los vértices del input y asignándoles al output. Posteriormente convertimos con el UnityObjectToClipPos y seteamos las uv del input al output. Si probamos el efecto, vemos el movimiento pero no es lo que queremos. Esto es debido a que el seno en Time es constante por lo que siempre se mueve de forma uniforme. Vamos a añadir el valor de uv.x (valor de 0 a 1) y restarle el Time para conseguir el efecto que queremos. De esta forma funciona, pero vamos a necesitar ajustarlo. Para esto vamos a crear tres propiedades de tipo Range. Esto es similar al atributo Range de Unity para los valores numéricos en C#. Te permite mostrar un float en el inspector del material y moverlo con un slider entre dos valores. Ahora podrás ver las tres variables en el editor. Pero para poder usarlas tenemos que declararlas en CG con el mismo nombre que tengan en la propiedad (_Speed,_Frecuency, _Amplitude). Usaremos el tipo fixed. Estas variables las vamos a usar de la siguiente forma: Speed: va a multiplicar al _Time.y para acelerar y reducir la velocidad. Frecuency: va a multiplicar a la resta entre uv.x y la multiplicación del Time y la speed. Justo antes de hacer el seno. Amplitude: multiplica al valor una vez el seno se ha calculado. Estos son los tres cálculos básicos a la hora de modificar la ondulación. Grábalos en tu mente (o apuntalo mejor) porque los usarás muchas más veces en tu vida. Si todo ha ido bien, podrás ajustar los valores como quieras para mejorar la ondulación. Aquí puedes ver mi configuración: Solo nos quedan dos pasos para terminar. El primero es hacer que la bandera se pegue al poste y no ondule. Esto es muy fácil de conseguir teniendo las referencias de uv.x que, como dijimos van de 0 a 1. Solo tenemos que multiplicar el seno que tenemos por la uv.x. De esta forma anclamos la bandera, consiguiendo que la ondulación vaya de mayor a menor fuerza desde el poste (gracias al valor entre 0 y 1 de uv.x) Lo otro que nos queda es añadirle color. Aquí voy a poner dos opciones, la primera es la básica, añadir un color sin más. Si estás cansado y no quieres continuar es la opción que te recomiendo. Podrás volver otro día para ver la segunda opción. En la segunda opción usaré un lerp para darle a la bandera 3 colores diferentes en función de la Y de su UV. Añadir color básico Simplemente tendrás que añadir una propiedad _Color y una variable de CG para conectarla (al igual que la _Speed y los demás valores anteriores). En este caso el color tiene cuatro valores, así que usaremos fixed4. Y en la función frag devolvemos el color a pelo. Añadir color avanzado Si venimos del básico vamos a borrar la propiedad de color (o cambiarle el nombre) y crear otras tres diferentes. Estas se llamarán ColorTop, ColorMiddle, ColorBotton (o el nombre que tu quieras). Estos tres colores serán las tres franjas que tendrá la bandera. Ahora creamos una función nueva encima de frag con el nombre getPixelColor que devolverá un fixed4. Esta función analizará la posición de la uv en Y (la necesita como parámetro) y haciendo uso de la función lerp y step nos devuelve un color u otro. ¿Qué hacen realmente cada una de estas funciones? Puede ser complicado de leer tal y como está, pero solo necesitas saber lo que hace para entenderlo. La función lerp interpola entre dos valores con un valor t. Cuando t es 0 devuelve el primer valor y cuando es 1 devuelve el segundo valor, devolviendo valores intermedios. En nuestro caso no queremos valores intermedios, queremos una interpolación directa dado un valor de referencia. El valor de referencia será ⅓ ya que tenemos 3 franjas. La función step tiene dos parámetros, si el primero es mayor que el segundo, devuelve 1, si es menor devuelve 0. Esto unido al lerp hace que en valores superiores a 0.33 pero inferiores a 0.66 se coloree del color del centro. Y de igual forma en valores superiores e inferiores. Con esto hemos llegado al final de la entrada. Si tienes cualquier duda con esto déjamela en los comentarios. PD: Si queréis que la bandera se muestre en ambas caras, tendréis que cambiar un valor del Cull. Esto es fácil de hacer pero da para otra entrada junto a otros añadidos como el Blend el ZTest o el ZWrite. De momento para que te quede perfecto, solamente tendrás que añadir junto antes del Pass (o dentro del Pass antes de CGPROGRAM) la siguiente linea: Con Cull en Off no ocultará ninguna cara. Nos vemos en la próxima entrada.
  37. 3 points
    El componente button contiene un booleano que se llama Interactable justamente para esta situación.
  38. 3 points
    No está pensado para eso, le estás haciendo un mal terrible al pobre componente. Entiendo el truco, pero no te conviene usar algo así para esto. Hasta que te das cuenta de que el CC no lo podés rotar ... si querés siempre un personaje que tenga el Up = Vector3.up, estonces está bien. Primero lo básico, ir a la documentación: https://docs.unity3d.com/ScriptReference/CharacterController.html Para el callback OnControllerColliderHit tenés un ejemplo que hace exactamente eso: https://docs.unity3d.com/ScriptReference/CharacterController.OnControllerColliderHit.html Y si nada te funciona, bueno, simplemente obtener del asset store el mejor character controller: https://assetstore.unity.com/packages/tools/physics/character-controller-pro-159150
  39. 3 points
    Hola a todos,me alegra volver por aquí. Quería enseñaros el proyecto que tengo entre manos, esta en desarrollo y las texturas ni siquiera están bien tileadas, pero ya tengo el escenario mas o menos montado a falta de muebles, plantas y bastantes detalles. Los sonidos de momento tampoco están, me esta costando bastante encontrar. No tengo prisa en acabarlo así que seguramente va para largo, pero cuando lo acabe quiero que tenga bastantes detalles. Si alguien se le ocurre algo que pueda ir bien en el estilo del juego o alguna sugerencia, se agradecería. Si se os ocurriera también algunos assets de la store que me pudierais recomendar seria estupendo. como ya habréis visto algunos modelos los he descargado y otros los he hecho yo. En principio quiero que el juego se base en encontrar llaves y abrir puertas, rodando el mismo mapa. tambien me falta un adaptador de kineckt para el ordenador para dar vida a las animaciones. Un saludo a todos.
  40. 3 points
    Es lo primero que he hecho pero no me entero porque no explican las cosas paso por paso, por ejemplo, ¿cómo se llega a esta ventana?: Te dejo el link de esta página, no lo compartas, es ultra secreto, lo saque de la deep weeb pero aporta una información vital sobre AnimatioView Link del infierno Link del Infierno X2 También quiero que sepas que existe una web a dia de hoy algo conocida, desarrollada especialmente para buscar eso que no sabemos ni como se llama Link a la página mágica.
  41. 3 points
    muy pro la documentacion, no esperaba menos de @lightbug (no esperaba menos de 200 paginas XD) no sabia que habias continuado con tu character controler (conocia la version 2d) ...pero ahora has completado tu complemento con un completo y funcional 3D... muy pro todo.... ...este @lightbug es muy pro... dan ganas de secuestrarle y encerrarle en una habitacion a teclear codigo... digo... estaria guai colaborar con el en algun proyecto...
  42. 3 points
    Hola @nomoregames te aconsejo que antes de empezar a intentar realizar un juego al 100% aprendas, técnicas, formas, algoritmos que suelen utilizar los desarrolladores de juegos. Aprendizaje Básico: Entender las estructuras de datos simples de C# Entender los delegados y eventos Aprender sobre NameSpace, Clases, Estructuras y Niveles de Accesibilidad. Aprender sobre Clases Abstractas Aprender sobre funciones Virtuales Aprender a utilizar Switch Aprender a utilizar Enumeradores Aprender a utilizar Linq, ventajas y desventajas Entender los vectores Aprender y utilizar vectores de dirección Entender las posiciones, rotaciones, escalas tanto globales como locales Aprender el ciclo de vida de una objecto en C# Aprender el ciclo de vida de un componente Entender MonoBehaviour Aprender a realizar Herencias Aprender a serializar clases Aprender a utilizar BinaryWriter y BinaryReader. Aprender a trasladar objetos a diferentes velocidades. Aprender lo básico sobre componentes físicos (Rigidbody) Aprender fórmula de tiro parabólico. Aprender fórmula de curva bézier. Aprender sobre Raycast, Box , Sphere, Line, Ray y todas sus variantes. Aprender sobre prefabs y el nuevo flujo de trabajo con nested-prefabs. Aprender a utilizar Singleton Aprender a utilizar Atributos de clases. Aprender a utilizar Scriptable Object para la fragmentación de comportamiento datos. Aprender sobre Listas, Arreglas Aprender sobre variables de sólo lectura Aprendizaje Avanzado: Aprender sobre funciones arrow Aprender sobre funciones lambda Aprender a utilizar correctamente Dispose y Garbage Collection Aprender a utilizar Dots. Aprender a utilizar HLSL (Surface Shaders) Aprender a utilizar Partículas Aprender a utilizar Sockets Aprender a utilizar WebClients Aprender a utilizar Threads Aprender algoritmos de búsquedas de camino Pathfinding como A* Actividades: Crear un sistema simple de WayPoints Crear un sistema de seguimientos de WayPoints mediante direcciones y fuerza Hacer un seguimiento de cámara simple Simular la gravedad de una caja sin rigidbody. Calcular la fuerza exacta para lograr el salto de 1 unidad con rigidbody. Generar un Cubo mediante Código con MeshRenderer. Guardar y Cargar datos en formato binario. Simulador de vuelo de un avión sin Rigidbody. Simulador de vuelo de un helicóptero sin Rigidbody. Simulador de vuelo de un avión con Rigidbody. Simulador de vuelo de un helicóptero con Rigidbody. Movimiento simple de jugador 2D sin rigidbody. Movimiento simple de jugador 2D con rigidbody. Movimiento simple de jugador 3D sin rigidbody. Movimiento simple de jugador 3D con rigidbody. Movimiento simple de jugador 3D con CharacterController. Detectar si el Jugador está en contacto con el suelo. Calcular el tiempo que el jugador estuvo en el aire. Calcular el tiempo que el jugador estuvo en el suelo. Calcular la fuerza necesaria vertical y horizontal para que un objeto sin Rigidbody recorra 10 unidades con una fuerza gravitatoria de -10 en el eje Y. Detectar si el Jugador está en contacto con la pared (que se encuentre por delante). Detectar si el Jugador está en contacto o próximo a un objeto sobre su cabeza. Evitar que el Jugador salte si no tiene el espacio suficiente. Generar zonas con diferentes comportamientos físicos, como deslizarse, alentar, acelerar, rebotar. Controlar la velocidad de Jugador para que recorra 100 unidades en línea recta siempre al mismo tiempo. Diseñar UI mediante editor (Edit Mode). Diseñar UI mediante código (Runtime). Proyectos para aprender sobre mecánicas: Intenta replicar las mecánicas de la forma más exacta posible, luego modificarlas para experimentar y entender el por que se llegó a la decisión de mantener esos valores. Memo Puzzle Rompecabeza Pong: https://es.wikipedia.org/wiki/Pong Snake: https://es.wikipedia.org/wiki/La_serpiente_(videojuego) Tetris Arkanoid Pacman Space Invaders Super mario bros (Mecánicas) The legend of zelda (Mecánicas) Infinity Runner (Mecánicas) Half-Life 1 (Mecánicas) Proyectos NO RECOMENDADOS: RPGs MMO ROL el clásico "GTA" Juegos Multiplayer como BF, Fornite, etc.. Links para estudio y practicar: son los que me acuerdo que leí en algún momento y me han servido, los de CEDV son muy buenos, lamentablemente ahora se pasaron a Unreal, pero siguen estando las ediciones del 2015 https://openlibra.com/es/book/download/desarrollo-de-videojuegos-un-enfoque-practico-3a-ed/ https://openlibra.com/es/book/download/desarrollo-de-videojuegos https://openlibra.com/es/book/download/logica-del-videojuego http://cedv.uclm.es/libro2015/M4.pdf Esto está destinado a todos los usuarios que se encuentren estancados.
  43. 3 points
    si quieres hacer que la cabeza mire a un sitio en concreto debes hacerlo en "LateUpdate", ya que el orden seria: -Update -Animacion -LateUpdate entonces si mueves un "hueso" en Update, luego la animacion te lo "pisa", recoloca los huesos como manda la animacion... pero si lo haces en "void LateUpdate()" entonces tu "pisas" la animacion y recolocas el hueso como quieras
  44. 3 points
    Hola Os informo de que Vuforia se está poniendo las pilas con las licencias. Si publicáis un app que les llama la atención, no podréis usar la licencia de developer y os pedirán que paguéis por la licencia. El problema es, si habéis publicado con la de developer, no podréis comprar la standard sino la Pro que vale una pasta al año. Os recomiendo que si empezáis un proyecto de AR, os miréis y lo hagáis con el ARFoundation de Unity. Saludos
  45. 2 points
    Hola, se me ocurren dos formas: 1. Usando un evento de Unity. En cada botón tenés eventos disponibles, pero solamente on click (presionar primero, luego al soltar se dispara el evento). Podés implementar algunas interfaces útiles para estos casos como las "IPointerXXXXX". Vas a tener que implementar dos, IPointerUpHandler e IPointerDownHandler. En donde querés usar el estado del botón (usé el componente "Target", en tu caso será el que tenga que ser): class Target : Monobehaviour { bool pulsado = false; public void Pulsar( bool pulsado ) { this.pulsado = pulsado; } //... } Donde esté el elemento UI, agregás este componente (lo llamé "UIButton"): //... using UnityEngine.EventSystems; //<--- public class UIButton : MonoBehaviour , IPointerUpHandler , IPointerDownHandler { public Target target; public void OnPointerDown(PointerEventData eventData) { if( target == null ) return; target.Pulsar( true ); } public void OnPointerUp(PointerEventData eventData) { if( target == null ) return; target.Pulsar( false ); } } También lo podés hacer desde el inspector, con un evento público creo. 2. La otra forma es simular un input directamente usando el nuevo input system. Para esto vas a tener que instalar el paquete del InputSystem, crear las acciones correspondientes con sus bindings (conexión entre accion y dispositivo de entrada), y agregar donde tengas el elemento UI un componente que basicamente simula uno de estos bindings (perdón no me acuerdo su nombre). Luego en tu "Target" usas el estado de esta acción. Puede sonar a mucho de golpe, si estás familiarizado con el nuevo input system debería ser fácil.
  46. 2 points
    jejeje me he echado las risas con este post misa tusa dolido jejeje es cierto que mucha gente hace preguntas muy ambiguas, muy poco precisas, o igual ni siquiera saben lo que preguntar porque no saben como hacer lo que tienen en mente, o no saben explicarlo porque aun no poseen ese conocimiento para nombrar lo que desean... este mundo es muy amplio y muy tecnico, comenzar puede resultar confuso y dificil.... y puede dar miedo... y el miedo lleva a la ira, la ira lleva al odio, el odio lleva al sufrimiento, y el sufrimiento lleva al lado oscuro... es mejor preguntar, para eso estamos aqui... es cierto que algunos como @lightbug pueden enfadarse y mandar a un maton a tu casa para que te rompa las piernas... 😜 pero de esos hay pocos... la mayoria somos tranquilos y con gusto responderemos a tus preguntas sobre cuantos robles roeria un roedor, si los roedores royesen robles... aunque un roedor no roeria robles, ya que los roedores no roen robles.... pero si un roedor pudiera roer y royera alguna cantidad de robles, yo te responderia gustosamente la pregunta
  47. 2 points
    Navegando en reddit he encontrado el mejor regalo que nos podían hacer en esta cuarentena a los que tenemos problemas de vista. Resulta que un usuario de reddit y programador ha creado un plugin que, según él es totalmente legal, para poner el dark theme o pro theme a unity. Tan solo hay que instalarlo en el proyecto con el package manager y el enlace a github, luego en project settings veremos un apartado que dice "enhancer" donde podremos configurar el tema y añadir una barra que honestamente es super útil para los que tenemos varios custom editors que controlan ciertos aspectos del proyecto. Aquí el enlace, aunque ya lo he explicado, él también dice en el readme como instalarlo. https://github.com/xeleh/enhancer Y así es como queda (captura hecha por mi)
  48. 2 points
    Ostia! *chin *chin hay que brindar señores, miren esos nuevos colores!!! se ven geniales, está todo más suavizado, me encanta! ... Ah si casi me olvido @francoe1 felicitaciones!!! 😃 la verdad tomaste la posta bien seguro y convencido, sinceramente te aplaudo 👏👏👏👏 hay que tener mucho valor para hacer eso. PD: woooow fui a poner un emoticón y casi me caí de la silla! ya arrancaste bien jaja.
  49. 2 points
    Hola, mirá recordé este video de Sebastian Lague, pero hablaba de Ray Marching. Lo sé, está en inglés, pero con el video es muy fácil de seguir (fijate si podés obtener subtítulos, aunque no los recomiendo, muchas veces dicen cualquiera): * Video de ray marching 22/02 - 24/02 R.I.P * El tema es que después me salio en los videos relacionados, uno de Marching cubes jajaj: No he trabajado con estas técnicas, así que más no puedo sumar al tema.
  50. 2 points
    En PC juego con mando o ratón/teclado. Desde el FIFA, Need for Speed, Battlefield V, RDR2, bueno decenas. En Android cero patatero. Mírate esta web que contiene detalles de cada app en steam, sus ventas, jugadores, etc: https://steamdb.info/
×
×
  • Create New...