Noticias

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

Scripts Problemas3

Iniciado por Pedro, Mayo 19, 2018, 08:36:28 PM

Tema anterior - Siguiente tema
Tengo este script
 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Gif : MonoBehaviour {
    public Button Boton;
    public Sprite[] frames;
    public int FramesPorSegundo = 10;
// Use this for initialization
void Start () {
        Boton = GameObject.Find("Boton").GetComponent<Button>();
}

// Update is called once per frame
void Update () {
        int Index = FramesPorSegundo * Time.deltaTime;
        Index = Index % frames.Length;
        Boton.image.sprite = frames[Index];
}
}

 
Y me lanza el siguiente error:
 
Assets/Scripts/Gif.cs(18,21): error CS0266: Cannot implicitly convert type `float' to `int'. An explicit conversion exists (are you missing a cast?)
 
Es decir el error esta en:
 

int Index = FramesPorSegundo * Time.deltaTime;

 
Pero si cambio estas variables a float, se me quita este error pero me aparece en la linea:
 

Boton.image.sprite = frames[Index];

 
Alguna idea?
 
Lo unico que quiero es insertar un Gif en la imagen de un botton

Podria ser porque no específicas que función realizará esa linea, si bien entiendo intentas hacer que en una función int el index sea igual a la velocidad de tus frames por el tiempo delta, pero el int se usa para almacenar numeros enteros no gameobjects y tu index es un gif (gameobject) una forma fácil de hacer es activando tu gif en el botón que desees, con setactive puedes hacer que tu gif ya antes puesto en la posición que quieres y donde quieres que salga al presionar el botón se reproducirá tu gif y al soltarlo dejara de reproducirse. Sobre tu script prueba buscando variables que almacenen gameobjects.
 
Saludos! 

Cita de: Alex date=1526792972pero el int se usa para almacenar numeros enteros no gameobjects y tu index es un gif (gameobject)
   


index no es un gameObject, es un int, framesPorSegundo es un int también
 
 
 
Cita de: Pedro date=1526754988int Index = FramesPorSegundo * Time.deltaTime;
   


La razón es simple, multiplicar un float * int, se entiende que el resultado dará float, es decir que en teoría te interesaría un numero de punto flotante y estás asignado dicho float a un int, osea estarías perdiendo datos, por eso te está diciendo si te flata algún cast, hay compiladores que ni te avisan de esto y ha joderse (C por ej)... pero bueno más alla de eso ese planteo está mal, y esto es porque (suponiendo que framerPorSegundo es lo que pienso que es):
 

FPS = 1 / ΔT
-->  TuNumero = FPS * ΔT = (1 / ΔT) * ΔT = 1

 
 
 
El segundo error (si los pasas a float) pasa porque no podés acceder con floats en un arreglo, es hasta lógico, no podés acceder al elemento 1.2f.
 
 
 
Es decir el problema viene de que no estás haciendo lo que te está diciendo es decir, no cambiar tipos de variables, sino hacer un simple cast.
 
 
 
si hacés un cast a Time.deltaTime (generalmente valores menores a 1)
 

deltaTime --> 0.006f
(int)deltaTime --> 0

 
pero si tomás en milisegundos:
 

deltaTime_miliSegundos --> 0.006f * 1000 = 6; //sigue float
(int)deltaTime_miliSegundos --> 6

 
Podés hacer el cast a toda la expresión:
 

index = (int)(FPS * Time.deltaTime);

 
... pero de lo de más arriba, estás cayendo muy cerca de 1 (si todo es lo que pienso) a si que ahí me parece que hay algo mal, no en la programación sino en el planteo.
 
 
 
Saludos

Cita de: lightbug date=1526796353....(suponiendo que framerPorSegundo es lo que pienso que es):
   
   

FPS = 1 / ΔT
-->  TuNumero = FPS * ΔT = (1 / ΔT) * ΔT = 1

   
       
   


hola
 
@lightbug, creo que la variable "framesPorSegundo" en esta caso no son los FPS del juego, sino las imagenes por segundo de la animacion ("index" seria el fotograma, la imagen que corresponde) 
 
por ejemplo si mi animacion de andar son 4 fotogramas y quiero que en un segundo haga el ciclo completo la variable "framesPoSegundo" seria 4...
 
ah, para el que no lo sepa "∆T" es "deltaTime"
 
 
 
tu problema @Pedro se soluciona como ha dicho lightbug:
 
Cita de: lightbug date=1526796353 
   
   
      Podés hacer el cast a toda la expresión:
   
   

index = (int)(FPS * Time.deltaTime);

   
       
   


solo que no seria la variable FPS como ha puesto ahi, sino tus "framesPorSegundo" de la animacion....
 
 
 
...aunque tambien esta guai eso de pasar los milisegundos a un "int milisegundos"....

Cita de: Igor date=1526822743hola
   
   
      @lightbug, creo que la variable "framesPorSegundo" en esta caso no son los FPS del juego, sino las imagenes por segundo de la animacion ("index" seria el fotograma, la imagen que corresponde) 
   
   
      por ejemplo si mi animacion de andar son 4 fotogramas y quiero que en un segundo haga el ciclo completo la variable "framesPoSegundo" seria 4...
   
   
      ah, para el que no lo sepa "∆T" es "deltaTime"
   


Apa, sí tenés razón, me olvidé que era de un gif, tanto game engine y sus fps se me pasó
 
 

yo habitualmente las animaciones de imagenes las hago asi:
 

int frame = 0;
int totalFrames = 8;
float timePerFrame = 0.2f;//por ejemplo
float timeR = 0f;
void Update() {  
   timeR += Time.deltaTime;
   if (timeR > timePerFrame) {
      frame++;
      timeR -= timePerFrame;  
      if (frame > totalFrame - 1) {
         frame = 0;
      }
   }
}

 
 
 
Cita de: lightbug date=1526823041Apa, sí tenés razón, me olvidé que era de un gif, tanto game engine y sus fps se me pasó
   
       
   


jejeje, yo a veces tambien me lio con las preguntas... 
 
oye, deltaTime va un poco como quiere en los moviles? va mal? o es mi paranoia?

Cita de: Igor date=1526823257oye, deltaTime va un poco como quiere en los moviles? va mal? o es mi paranoia?
   


habría que ver el "va mal", que te está pasando?

 
 
Cita de: lightbug date=1526851314habría que ver el "va mal", que te está pasando?
   


no lo tengo muy claro
 
primero, el metodo de contar FPS que llevaba utilizando toda la vida va mal en moviles... me marcaba todo el rato 60.... y he tenido que usar el timeSinceStart, o como se llame, para que se muestre bien...
 
luego las "fisicas" y movimientos en los que uso el deltaTime en los moviles van diferente que en el PC... y si uso el fixedUpdate para ver si lo arreglo.... pues tambien va diferente... ademas en fixedUpdate el deltaTime es fijo, no? entonces no tiene sentido usar deltaTime en los calculos si usas el fixedUpdate, no?
 
nose... a veces creo que es algun error en algun "calculo" ... pero luego repaso el codigo y no veo de donde puede venir... igual es que estoy acostumbrado a hacerlo de una forma... y resulta que es incorrecta...
 
pues algunos "controladores de personajes" o fisicas o asi, van diferente en el movil.... y el movimiento, velocidad de avance u otras cosas tambien difieren... un pelin... en algunos proyectos que pruebo...
 
pero porejemplo en el juego de coches si que va igual en el PC y en el movil...
 
pero en algunos otros proyectos me he rallao un rato con el tema... 
 
y creo que en algun lao lei que el "Time" funcionaba diferente en android o algo asi.... pero no me entere que era lo diferente

Cita de: Igor date=1526852817luego las "fisicas" y movimientos en los que uso el deltaTime en los moviles van diferente que en el PC... y si uso el fixedUpdate para ver si lo arreglo.... pues tambien va diferente... ademas en fixedUpdate el deltaTime es fijo, no? entonces no tiene sentido usar deltaTime en los calculos si usas el fixedUpdate, no?
   


llamar a deltaTime en fixed es equivalente a llamar a fixedDeltaTime , estoy casi seguro (un 99.5%), probá de ultima .
 
Para físicas (Physics.AddForce.... por ej) siempre usar el fixedUpdate (30 o 40 fps no recuerdo), ya que este update tiene el mismo step que la parte física (el fixedStep). Fijate que si tocás el fixedStep estás bajando el fixedDeltaTime (también, si querés probá a ver que sale). Solo los "comandos físicos" van en Fixed, no las inputs, se va a notar mucho el "lag".
 
Cita de: Igor date=1526852817pues algunos "controladores de personajes" o fisicas o asi, van diferente en el movil.... y el movimiento, velocidad de avance u otras cosas tambien difieren... un pelin... en algunos proyectos que pruebo...
   
   
      pero porejemplo en el juego de coches si que va igual en el PC y en el movil...
   
   
      pero en algunos otros proyectos me he rallao un rato con el tema... 
   
   
      y creo que en algun lao lei que el "Time" funcionaba diferente en android o algo asi.... pero no me entere que era lo diferente


Cuando llamas a una función de algo se puede traducir difente segun la plataforma, así que puede ser posible que las cosas cambien, ahora por ej, llamar al Time.time, que tiene determinada funcionalidad no puede variar demasiado de dispositivo en dispositivo, es el tiempo desde el inicio (si mal no recuerdo) sería algo totalmente inaceptable que cambie su funcionalidad, el como cada Sistema operativo interpreta el inicio de una aplicación o proceso o thread etc dependerá de la plataforma seguramente, ya que la parte de manejo de Eventos en general : tiempos, ventanas, teclado, mouse, etc pasa por la API de cada uno.
 
 
 
El calculo de los fps como los realizas? osea como lo puse arriba es demasiado brusco, eso lo tenés que "suavizar", yo por ej los calculo en una ventana de tiempo, cada ∆T guardo el FPS = 1/ ∆T acumulativamente, esto en una ventana de 1 segundo (por ej) y al final simplemente promedio el resultado, y da muy bien (o por lo menos es coherente)
 
 

Cita de: lightbug date=1526856432El calculo de los fps como los realizas? osea como lo puse arriba es demasiado brusco, eso lo tenés que "suavizar", yo por ej los calculo en una ventana de tiempo, cada ∆T guardo el FPS = 1/ ∆T acumulativamente, esto en una ventana de 1 segundo (por ej) y al final simplemente promedio el resultado, y da muy bien (o por lo menos es coherente)
   


solia "contar" frames....
 

int frames = 0;
float timeR = 0f;
string fps = "0";
 
void Update () {
frames++;
timeR += Time.deltaTime;
if (timeR > 1f) {
   timeR -= 1f;
   fps = "" + frames;
   frames = 0;
}
}

 
 cada frame añado 1 a la cuenta...  y al llegar a un segundo paso el numero de frames a un texto...
 
y reinicio la cuenta... 

Mayo 21, 2018, 05:14:45 PM #10 Ultima modificación: Mayo 21, 2018, 06:04:41 PM por pioj
a claro, mira, que pasa si tuvieras 3 fps fijos inventados (por simplicidad) , o 0.333s de deltaTime, te queda:
 



   
       
   
   
      frame = 1 , timer = 0.33
   
   
      frame = 2 , timer = 0.66
   
   
      frame = 3 , timer = 0.99
   
   
      frame = 4 , timer  = 1.22 (se mete en if) (ya los fps te dieron 4, y no 3)
   
   
      ---------------------------------------------------------------------------------------------------
   
   
      frame = 1 , timer = 0.22 + 0.33 = 0.55
   
   
      frame = 2 , timer = 0.88
   
   
      frame = 3 , timer = 1.11 --> se mete , peegaste los FPS = 3
   
   
      ---------------------------------------------------------------------------------------------------
   
   
      frame = 1 , timer = 0.11 + 0.33 = 0.44
   
   
      frame = 2 , timer = 0.77
   
   
      frame = 3 , timer = 1.00 --> no se mete
   
   
      frame = 4 , timer = 1.33 --> se mete , tenes 4 FPS
   
   
       
   

[/quote]
 
... osea va oscilando aun con unos fps = 3 congelados inventados, y eso es logico porque la condición de mayor a 1 y los deltaTime desparejos con 1 seg te hacen caer dentro, fuera, dentro , fuera, quizás para algunos valores esto ni se vea.
 
 
 
Si hubieras calculado la "frecuencia cuadro a cuadro" (o el 1/dt), luego sacas la media de todo lo acumulado te daría siempre 1/0.3333 = 3 fps, ahora tenés que llevar cuenta de cuantas muestras vas haciendo.
 
 
 
 

si, se que me paso de un segundo.... igual acaba en 1.09f o asi.... (por ejemplo)... pero luego NO lo pongo a cero... lo que hago es: le resto 1f... y entonces la cuenta de tiempo empezaria en 0.09f.... no en cero...
 
pero bueno... asi lo hacia antes... 
 
ahora lo hago con timeSinceStartup... algo asi:
 

int fps = 0;
float timeR = 0f;
void start () {
   timeR = Time.timeSinceStartup;
}
 
void Update () {
   float dTime = Time.timeSinceStartup - timeR;
   fps = (int)(1f / dTime);
   timeR = Time.timeSinceStartup;
}

 
 

Cita de: Igor date=1526991761si, se que me paso de un segundo.... igual acaba en 1.09f o asi.... (por ejemplo)... pero luego NO lo pongo a cero... lo que hago es: le resto 1f... y entonces la cuenta de tiempo empezaria en 0.09f.... no en cero...
   


Si claro, fijate que en ejemplo inventado arranco de 0.0f , 0.11f , 0.22f etc lo va acumulando. Claro que con 3 fps es muy notable el error vs tener 60 (16 ms) asi que ni lo notas tanto, pero bueno siempre está.
 
Fijate que para el timeSinceStartup(tss) no lo vas a poder hacer en cualquier lado, osea no hay problema lo que no refleja en un cuadro lo hace en el siguiente (por timeR), pero puede quedar todo atrasado. Lo ideal sería usarlo ultimo en la ejecución o en un LateUpdate (y ultimo también), osea el ojo humano no lo nota, sos humano no? jeje . Acordate que tss se renueva siempre (por eso se usa para medir partes de código, util para benchmarks), a diferencia del DeltaTIme que corresponde al frame anterior entero, entonces si medis al principio del frame (antes de que se dispare algunos calculos pesados por ej) te va a dar que está todo bien, cuando el cuadro ese en realidad tardó más, por supuesto esto lo compensa en el siguiente cuando quizás no hubo nada pesado, pero el tss refleja que estuvo pesado, un detallecito nada más, nada grave.
 
salute

Etiquetas: