Jump to content

lightbug

Registrados
  • Content Count

    2,394
  • Joined

  • Last visited

  • Days Won

    206

Everything posted by lightbug

  1. Hola, eso pasa porque al exportar, tu "screen" es distinta a la que te puede ofrecer el editor (game view). Seguramente eso se deba a que: no estás definiendo correctamente la posición/anclaje de tus elementos UI (botón, panel, etc) con respecto al canvas. No es lo mismo colocar un elemento en la parte superior derecha con anclaje a la esquina más próxima (superior derecha) que con anclaje en el centro de la pantalla (por defecto). Si el canvas sufre modificaciones el rect transform se re-calculará en base a este punto de anclaje. El modo de renderizado del canvas no sea el indicado, por ejemplo podés elegir si querés un canvas con elementos de tamaño fijo (ej: si un botón es de 12x12 será siempre así, sin importar si la pantalla es gigante o diminuta) o podés escalar los elementos en base a las dimensiones de pantalla (los elementos se agrandan/achican dependiendo de las dimensiones de la pantalla). Te recomiendo leer esto: https://docs.unity3d.com/Packages/com.unity.ugui@1.0/manual/UIBasicLayout.html Ah y me olvidaba, siempre jugá con el tamaño del mismo Game View (usando otras resoluciones o manualmente con el puntero) para ver si tu UI responde bien. Saludos.
  2. Hola, en mi opinión la parte gráfica la veo algo mal, es que no me termina de cerrar el "setting" por ningún lado. Entiendo que esté saliendo el proyecto, pero hay cosas básicas que podés mejorar: Los UVs! lo más obvio quizás. Basado en la última imagen, juraría que esos enemigos son miniaturas (si fueran verde serían los soldaditos de Toy Story). Las texturas de los pisos y las paredes están todas estiradas y/o mal escaladas. Metele sombras a esos enemigos (en la imagen parecen que están flotando). Estoy 99.99% seguro que desactivaste las sombras de la spot ya que te metía una sombra por el player (debido a su ubicación), si es así, meté al player en una capa dedicada y usa las propiedades de la luz para filtrar a dicha capa. Los enemigos (al menos en la imagen) brillan demasiado, quizás te convenga usar un espacio de color "Linear" y no "Gamma". Puede que también sea algo del shader/material. Usá un Normal map para piso y paredes, esto te ayuda muchísimo. Incluí detalles de ser posible, sócalos a las paredes, pisos levantados, escombros, muebles, "cosas de laboratorio". En definitiva, buscale una estética al juego, para este "setting" me parece que algo tirando a lo Grim Dawn te iría genial: Un truco es usar el mismo terrain como suelo, te olvidas de las UVs y además podés pintar detalles encima (texturas y/u objetos). Saludos.
  3. Es imposible saber qué está fallando y cuándo lo está haciendo. Para eso tenés herramientas como el profiler, que te dice cuanta memoria estás usando, procesamiento en general (script por script, por ej podés hasta sacar cuando tarda un Raycast en procesar una order, usando Deep Profile) y más. Existen cosas generales que podés hacer, como por ejemplo: Usar un sprite atlas (o sheet?) en vez de muchos sprites por separado. Si un sprite es muy pequeño no necesita estar super detallado (alta resolución). usar físicas menos complejas donde no se requieran (si fuera el caso). Ej no es lo mismo evaluar cientos de circulos vs circulos que evaluar polígonos vs polígonos. No generar basura constantemente (por ej llamar a Camera.main o GetComponent cuadro a cuadro).
  4. Ah ok ahora tiene más sentido. De lo que sé, un prefab como asset puede tomar referencias solo de assets, por ejemplo de otros prefabs. Si querés meter objetos de la escena (o componentes de estos) no te va a dejar. Al revés sí podés hacerlo, es decir que si el prefab está instanciado o metido en la escena (tecnicamente sigue siendo un prefab, ya no un asset (?)) podés asignar cualquier tipo de referencia, de escena o cargarla desde assets. No se si podés imponerle a Unity que asigne cualquier tipo de objeto en cualquier lado. En principio no tendría sentido, ya que los prefabs (assets) van a ser compartidos durante todo el juego, si uno de ellos pierde la referencia de uno de sus objetos (por ej porque la escena cambió) sería catastrófico. El tema es que podés tener prefabs en escena, o prefabs en el proyecto, por eso no me queda en claro bien de donde a donde querés hacer lo que querés hacer. Asumo que querés asignar de escena a asset. Saludos.
  5. Hola, vos podés asignar cualquier cosa, siempre y cuando sea del mismo tipo(referencia) o derivado(podés meter un Transform en un Component, un Monobehaviour en un Behaviour, etc), desde ya que no esperés meter un Transform en un Component y operar ese component como un Transform, para eso vas a tener que hacer un "cast". Lo mismo obviamente se puede hacer mediante código ("="). GameObject y posición no tienen nada que ver, para eso tenés que acceder al componente Transform. Por si solo el GameObject no sabe donde debería estar posicionado.
  6. xD es buenardo ... la parte de los UVs, odio los UVs!
  7. Yo después de leer este hilo:
  8. Agrego otra a las que puso @francoe1, si estás dentro de un Monobehaviour podés usar un "print", hace lo mismo: // // Summary: // Logs message to the Unity Console (identical to Debug.Log). // // Parameters: // message: public static void print(object message);
  9. Puede representar también varios "if else" en una sola línea. Por ejemplo: int resultado = a > 1 ? 3 : a > 0 ? 2 : a > -2 ? 1 : 0; Es equivalente a: if( a > 1 ) resultado = 3; else if( a > 0 ) resultado = 3; else if( a > -2 ) resultado = 1; else resultado = 0;
  10. una de dos: Te falta el material (missing material). Estás trabajando en una scriptable render pipeline que tu material no es compatible.
  11. 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.
  12. Sí, desde ya. Decime, ¿Donde está tu pregunta? Porque no la veo por ningun lado. Asumo que (salvo que el admin y la reglas del foro expresen lo contrario) vos sos totalmente libre de crear X cantidad de hilos por día, y cada usuario es libre de contestar a tus preguntas con Y cantidad de post también. En lo personal me da exactamente igual, era solo un consejo.
  13. El mismo admin ni sabe de qué va el foro ...mal por vos francoe1, muy mal 🤣 A ver, otra vez este tipo de hilos, creo que por año contesto dos o tres de estos. Usar un foro se aprende (igual que conducir o tocar la guitarra), no se necesita tener "nivel" para saber preguntar o no. A mi me parece que nos estás mandando regla tras regla de lo que va a ser tu juego (un objeto A que haga X cosa con el objeto B, mismo patrón), y esperas que alguien te envíe el código en bandeja para todas y cada una de ellas. Una vez está bien, dos quizás, pero una tras otra ya denota falta de esfuerzo. Mi consejo es que te hagas un tiempo entre hilos (ponele unos 3 días, o una semana) entre duda y duda, así vas a tener tiempo de investigar bien a fondo, leer documentación, bibliografía, etc. Con suerte esas dudas van a ir desapareciendo, de lo contrario ¿de qué sirve todo esto? Y por favor tratá de que no suenen a demanda, no existe cosa más fea que leer un "Necesito esto... chau ... gracias". Espero que se entienda, lo digo con la mejor de las intenciones.
  14. Ahhh cierto, perdón. Sí, vas a tener que usar cualquier dirección del target como referencia. Por ejemplo target.forward. En vez de guardar prevRotation vas a tener que guardar el prevForward (Vector3 en vez de Quaternion): void Start() { prevForward = target.forward; diff = distance * ( target.position - transform.position ).normalized } void LateUpdate() { ... // Calculo la rotación Quaternion rotDif = Quaternion.FromToRotation( prevForward , target.forward ); // Ya calculé la diferencia de rotación, ahora actualizo prevRotation prevForward = target.forward; ... } Agrego: se puede calcular la diferencia de rotaciones así: Quaternion deltaRotation = rotationA * Quaternion.Inverse( rotationB ); Hacelo como quieras, con Vector3 o con Quaternions.
  15. Bueno, no se si te entendí bien, pero creo que simplemente buscas rotar un vector. Para eso podés aplicar alguna rotación (Quaternion) al vector deseado. Voy a suponer que tu objeto tiene un componente separado que hace de "voy a seguir a este objeto en base a la distancia que tengo a él, y además voy a rotar con él". Como el objeto va a seguir a otro, podés ir pensando en actualizarlo después de este. Esto lo podés hacer mediante ExecutionOrder (en las opciones), un atributo llamado DefaultExecutionOrder, o simplemente usar LateUpdate. En este caso uso LateUpdate: [SerializeField] Transform target = null; [SerializeField] float distance = 2f; [SerializeField] Transform target = null; Quaternion prevRotation; Vector3 diff; void Start() { prevRotation = target.rotation; diff = distance * ( target.position - transform.position ).normalized } void LateUpdate() { // El target ya se movió y rotó // Calculo la rotación Quaternion rotDif = Quaternion.FromToRotation( prevRotation , target.rotation ); // Ya calculé la diferencia de rotación, ahora actualizo prevRotation prevRotation = target.rotation; // Calculo diff rotado diff = rotDif * diff; // Posiciono este objeto en base a diff transform.position = target.position + diff; } (para rotar un vector siempre la expresión debe quedar en "sanguchito" --> Vector3 = Quaternion * Vector3 ) Seguramente haya una forma más fácil.
  16. Vector3 newPos = Dir * distance; Eso está mal, estás usando la diferencia (deseada) entre los dos objetos como posición absoluta.
  17. Poder se puede. Tiro ideas al aire (no he probado ninguna). Podés crear el gameplay y renderizarlo en una imagen (RenderTarget), mezclandolo todo te quedaría como en Undertale. No se que tal se verá la textura final, si mantendrá la calidad o no. Acá no dependes del cuadro del gameplay, sino de la cámara. Otra es usar una máscara, como dice iRobb. Para instanciar sprites necesitas un Vector2 (o 3), que lo vas a tener que calcular en base al famoso cuadro del gameplay. Podés calcular sus extremos usando el RectTransform, la posición se medirá desde el pivot ( <0.5,0.5> significa centro del objeto ) y posX y posY se calculan en base al anchor. Tenés que hacer el camino inverso, calcular los extremos del cuadro (no se si existe una manera fácil de hacer, si no un poco de matemática de UI y listo), luego pasar esos puntos al world position. Si no me falla la memoria con Camera.ScreenToWorldPoint (?) podés hacer esto. El resto es instnaciar a tus enemigos dentro del cuadro. Si no te querés enquilombar tanto, simplemente meté unas variables públicas, como xMin, xMax, yMin e yMax, e instanciá a tus enemigos dentro de estos límites. Para mantener las dimensiones necesitas tener un cuadro con tamaño constante, es decir que si tener un canvas que se escala (dependiendo de la resolución) la vas a cagar.
  18. Hola, solamente para agregar algo al hilo. Si querés lograr eso vas a tener que trabajar siempre sobre la velocidad actual de alguna manera, nunca escribirla directamente (a menos que esto sea lo que busques). Por escribirla directamente me refiero a que la velocidad sea igual a algo que la tenga en cuenta. // No va a funcionar // El rb puede sufrir modificaciones (debido a la simulación), pero en el FIxedUpdate siguiente estás pisando el valor. // ----------------- // velocidad de 5 m/s rb.velocity = Vector3.right * 5f; // Va a funcionar // el rb va a modificar una velocidad en base a la actual. La velocidad del RB va a estar afectada por la simulación. // ----------------- // aceleración de 5 m/(s*s) (ta en otra escala, lo sé) rb.velocity += Vector3.right * 5f * dt; Más formas de mover un rb con velocity: // Acelerando, podés emplear el mismo drag del RB para lograr una aceleración y velocidad final deseada. rb.velocity += aceleración * dt; // Acelerando, esta vez podés usar un drag dinámico (en tu propio código) y poner el drag del rb a 0. rb.velocity += aceleración * dt * (1 - drag); // Usando SmoothDamp rb.velocity = Vector3.SmoothDamp( rb.velocity , targetVelocity , ref currentAcceleration , smoothTime ); // Usando MoveTowards rb.velocity = Vector3.MoveTowards( rb.velocity , targetVelocity , acceleration ); // Usando Lerp rb.velocity = Vector3.Lerp( rb.velocity , targetVelocity , t ); ─────────────────────────────────────────────────────────────────────────── En el momento de llamar a la fuerza, la velocidad no se modifica, lo que esta llamada hace es avisar al motor de físicias la modifique (le agregue velocidad) en la simulación (con MovePosition/Rotation pasa lo mismo). El tema está en que él no está reflejando dicho cambio en el cuadro siguiente. Pero sí, te entiendo. ──────────────────────────────────────────────────────────────────────────────── Si se mueve y colisiona, o necesita valerse de queries para hacerlo (raycast, sphere cast, etc) ... bye bye transform! bueno no bye bye del todo, todavía es muy importante, pero nada de modificar transforms como sustituto de velocity, force, position, o similar. En estos casos el transform hace de elemento visual (como debería ser), jugar a "dos puntas" con el rb y el transform va a traer posiblemente malos resultados y dolor de cabeza (dependiendo de los casos). En estos casos conviene usar RB para todo, y valerse de la interpolación (para que lo visual se actualice correctamente). Se suele también usar el transform al final de la simulación (LateFixedUpdate) para acomodar (si fuera necesario) la posición "deseada" del jugador (rb.position) y su elemento visual (transform.position). Que dicho sea de paso, una vez que te metés con las físicas estos dos componentes (Rb y T) viven en su mundo y hacen cosas diferentes. Los dos se suelen amigar luego de la simulación (Con un Sync). Saludos.
  19. Quizás el temita de las oscilaciones se deba al "Apply root motion" del componente Animator (?). Fijate si desactivando el bool ese se va eso. La otra que se me ocurre es algún problema con el Avatar en sí, andá a las opciones de importación del modelo animado (cliqueando sobre el modelo), luego rig. Te debería decir "Humanoid", que está bien, luego dale al botón "Configure...". Fijate si están todos los huesos en verde, si no, reiniciá la pose en T pose. Si bajás te debería decir en "Pose" algo como "Enforce T-Pose" o similar. Dale a eso, y aplicá. Ya que estás acá, no estaría mal revisar la definición de los huesos, asegurate que el hombro esté como hombro, la pierna derecha como pierna derecha, y así. Con "jerarquía" me refería al panel "Hierarchy" del editor de Unity, especificamente al objeto de tu personaje (con todos sus hijos, nietos, etc). Igual, no es que sea determinante a la hora de encontrar el problema (probablemente no aporte nada relevante), pero es que muchas veces en vez de "hablar" acerca del problema es mejor mostrar la escena desde donde se pueda, de esa forma te van a poder ayudar mejor. Sí, excelente 👌
  20. Podrías subir más info? Dónde está el pivot (blender y Unity)?, ¿Cómo posicionas el personaje? ¿Cómo es la jerarquía? ¿Es un humanoide o un generic? etc etc etc.
  21. Eso está mal, nunca vas a cambiar de Vector3.down de gravedad. El raycast (aunque prefiero un sphere cast) tiene que darte solamente la normal. Una vez que tengas esto es cuestión de hacer gravityDirection = - normal (tenés bastantes problemas con esto, pero para arrancar ta bien). gravity = gravityMagnitude * gravityDirection; Luego para rotar el personaje: Quaternion targetDeltaRotation = Quaternion.FromToRotation( transform.up , - gravityDirection ); (definí "deltaRotation" como privado de la clase, slerpSpeed y suavizar también ) deltaRotation = suavizar ? Quaternion.Slerp( deltaRotation , targetDeltaRotation , slerpSpeed * Time.deltaTime ) : targetDeltaRotation; transform.rotation = deltaRotation * transform.rotation; Fijate que la multiplciación de Quaternions no es conmutativa, es decir que Qa * Qb != Qb * Qa . Me pasa todo el rato que algo debería funcionar y simplemente no lo hace porque las puse alrevés. Como dice @Igor no uses Physics.gravity, vas a cambiar la gravedad de todo cuerpo rígido en la escena. Aplicá tu propia gravedad: rigidbody.velocity += gravity * Time.deltaTime;
  22. Hacé un tatetí y presentalo, luego un tetris y presentalo, luego X y presentalo, te vas a dar cuenta que esas preguntas son producto de la falta de resultados. Y ojo que yo soy el peor en dar este consejo, estoy igual que vos, terminé con varios proyectos en la nada, pero un poco intencionalmente, nunca prentendí terminar nada. Más bien lo hice para chocarme con los problemas del desarrollo, esto siempre me interesó más que el juego en sí, incluso te diría que me aburre un poco la parte de desarrollo de juegos.
UnitySpain © Todos los derechos reservados 2020
×
×
  • Create New...