Jump to content
Pedro

Scripts Problemas3

Recommended Posts

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

Share this post


Link to post
Share on other sites

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! 

Share this post


Link to post
Share on other sites
34 minutes ago, Alex said:

pero 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

 

11 hours ago, Pedro said:

int 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

Share this post


Link to post
Share on other sites
hace 7 horas, lightbug said:

....(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:

hace 7 horas, lightbug said:

 

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"....

Share this post


Link to post
Share on other sites
1 minute ago, Igor said:

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"

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

 

Share this post


Link to post
Share on other sites

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;
      }
   }
}

 

hace 2 minutos, lightbug said:

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

 

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?

Share this post


Link to post
Share on other sites
7 hours ago, Igor said:

oye, 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?

Share this post


Link to post
Share on other sites

 

hace 22 minutos, lightbug said:

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

no lo tengo muy claro:7_sweat_smile:

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:7_sweat_smile:

Share this post


Link to post
Share on other sites
38 minutes ago, Igor said:

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?

llamar a deltaTime en fixed es equivalente a llamar a fixedDeltaTime , estoy casi seguro (un 99.5%), probá de ultima :12_slight_smile:.

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".

41 minutes ago, Igor said:

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:7_sweat_smile:

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)

 

Share this post


Link to post
Share on other sites
hace 11 horas, lightbug said:

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)

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... 

Share this post


Link to post
Share on other sites

a claro, mira, que pasa si tuvieras 3 fps fijos inventados (por simplicidad) , o 0.333s de deltaTime, te queda:

Cita

 

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

 

... 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.

 

 

Share this post


Link to post
Share on other sites

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;

}

 

Share this post


Link to post
Share on other sites
9 hours ago, Igor said:

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...

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

Share this post


Link to post
Share on other sites

UnitySpain © Todos los derechos reservados 2020
×
×
  • Create New...