Qual método mais eficiente? - tylerthecreator - 09/03/2023
Galera, dúvida básica.
Qual melhor método de criar o famoso "carregando" para jogadores mobiles não caírem no limbo?
Sei que existe a forma mais simples do SetPlayerPosEx, que coloca um timer congelando e ao final, descongelar.
Mas haveria outra forma mais eficaz? Dessa forma, ainda alguns jogadores sofrem com esse problema e acabam caindo com os objetos carregando.
Se aumentar bastante o timer, até que resolve, mas deixar os caras carregando por 5/7 segundos acho muito. Quebra demais a dinâmica.
Tentei o " Streamer_UpdateEx(playerid, X, Y, Z, GetPlayerVirtualWorld(playerid), GetPlayerInterior(playerid)); ", mas não funcionou mt bem.
RE: Qual método mais eficiente? - strelo - 09/03/2023
Uma alternativa ao uso do timer congelante é o uso de threads para carregar os recursos do jogo em segundo plano, permitindo que o jogo continue a funcionar enquanto os recursos são carregados. Aqui está um exemplo de como isso pode ser:
Código: // Define uma variável global para controlar a thread
new g_ThreadRunning = false;
// Função da thread para carregar os recursos do jogo
forward thread_LoadResources();
// Função para mostrar a mensagem de carregamento na tela do jogador
forward ShowLoadingScreen(playerid);
public OnPlayerConnect(playerid)
{
// Inicia a thread para carregar os recursos do jogo
g_ThreadRunning = true;
thread thread_LoadResources();
}
public OnPlayerSpawn(playerid)
{
// Mostra a tela de carregamento enquanto a thread estiver em execução
while(g_ThreadRunning)
{
ShowLoadingScreen(playerid);
Sleep(1000);
}
}
public thread_LoadResources()
{
// Carrega os recursos do jogo aqui, por exemplo:
LoadMyTextures();
LoadMyModels();
LoadMySounds();
// Marca a thread como concluída
g_ThreadRunning = false;
}
public ShowLoadingScreen(playerid)
{
// Mostra a mensagem de carregamento na tela do jogador aqui, por exemplo:
SendClientMessage(playerid, 0xFFFFFFFF, "Carregando...");
}
Neste exemplo, a função thread_LoadResources() é chamada quando o jogador se conecta ao servidor, e carrega os recursos do jogo em segundo plano. Enquanto a thread estiver em execução, a variável g_ThreadRunning é definida como verdadeira e a função OnPlayerSpawn() é executada para mostrar a tela de carregamento para o jogador. A função ShowLoadingScreen() é chamada a cada segundo para atualizar a mensagem de carregamento na tela do jogador. Quando a thread de carregamento de recursos for concluída, a variável g_ThreadRunning é definida como falsa e a tela de carregamento é removida.
Espero que isso ajude a resolver o problema de carregamento em seu jogo. Se tiver alguma dúvida, sinta-se à vontade para perguntar!
RE: Qual método mais eficiente? - tylerthecreator - 09/03/2023
(09/03/2023 18:23)strelo Escreveu: Uma alternativa ao uso do timer congelante é o uso de threads para carregar os recursos do jogo em segundo plano, permitindo que o jogo continue a funcionar enquanto os recursos são carregados. Aqui está um exemplo de como isso pode ser:
Código: // Define uma variável global para controlar a thread
new g_ThreadRunning = false;
// Função da thread para carregar os recursos do jogo
forward thread_LoadResources();
// Função para mostrar a mensagem de carregamento na tela do jogador
forward ShowLoadingScreen(playerid);
public OnPlayerConnect(playerid)
{
// Inicia a thread para carregar os recursos do jogo
g_ThreadRunning = true;
thread thread_LoadResources();
}
public OnPlayerSpawn(playerid)
{
// Mostra a tela de carregamento enquanto a thread estiver em execução
while(g_ThreadRunning)
{
ShowLoadingScreen(playerid);
Sleep(1000);
}
}
public thread_LoadResources()
{
// Carrega os recursos do jogo aqui, por exemplo:
LoadMyTextures();
LoadMyModels();
LoadMySounds();
// Marca a thread como concluída
g_ThreadRunning = false;
}
public ShowLoadingScreen(playerid)
{
// Mostra a mensagem de carregamento na tela do jogador aqui, por exemplo:
SendClientMessage(playerid, 0xFFFFFFFF, "Carregando...");
}
Neste exemplo, a função thread_LoadResources() é chamada quando o jogador se conecta ao servidor, e carrega os recursos do jogo em segundo plano. Enquanto a thread estiver em execução, a variável g_ThreadRunning é definida como verdadeira e a função OnPlayerSpawn() é executada para mostrar a tela de carregamento para o jogador. A função ShowLoadingScreen() é chamada a cada segundo para atualizar a mensagem de carregamento na tela do jogador. Quando a thread de carregamento de recursos for concluída, a variável g_ThreadRunning é definida como falsa e a tela de carregamento é removida.
Espero que isso ajude a resolver o problema de carregamento em seu jogo. Se tiver alguma dúvida, sinta-se à vontade para perguntar!
Mas tipo, geralmente os interiores personalizados de objetos são no céu e muito distantes das cidades. Existe a possibilidade de carregar em segundo plano objetos streamer de longe? E caso seja possível, não causaria lag?
E outro detalhe, por eles serem no céu(interiores), se não carregar os objetos na hora, os jogadores caem e morrem. O tal do "limbo"
RE: Qual método mais eficiente? - xbruno1000x - 09/03/2023
Uma possibilidade seria criar o chão dos interiores com CreateObject. CreateObject não necessita tempo de carregamento.
RE: Qual método mais eficiente? - tylerthecreator - 10/03/2023
(09/03/2023 23:42)xbruno1000x Escreveu: Uma possibilidade seria criar o chão dos interiores com CreateObject. CreateObject não necessita tempo de carregamento.
Interessante, Bruno. Testarei dessa forma, tomara que dê certo.
RE: Qual método mais eficiente? - strelo - 10/03/2023
(09/03/2023 22:10)tylerthecreator Escreveu: (09/03/2023 18:23)strelo Escreveu: Uma alternativa ao uso do timer congelante é o uso de threads para carregar os recursos do jogo em segundo plano, permitindo que o jogo continue a funcionar enquanto os recursos são carregados. Aqui está um exemplo de como isso pode ser:
Código: // Define uma variável global para controlar a thread
new g_ThreadRunning = false;
// Função da thread para carregar os recursos do jogo
forward thread_LoadResources();
// Função para mostrar a mensagem de carregamento na tela do jogador
forward ShowLoadingScreen(playerid);
public OnPlayerConnect(playerid)
{
// Inicia a thread para carregar os recursos do jogo
g_ThreadRunning = true;
thread thread_LoadResources();
}
public OnPlayerSpawn(playerid)
{
// Mostra a tela de carregamento enquanto a thread estiver em execução
while(g_ThreadRunning)
{
ShowLoadingScreen(playerid);
Sleep(1000);
}
}
public thread_LoadResources()
{
// Carrega os recursos do jogo aqui, por exemplo:
LoadMyTextures();
LoadMyModels();
LoadMySounds();
// Marca a thread como concluída
g_ThreadRunning = false;
}
public ShowLoadingScreen(playerid)
{
// Mostra a mensagem de carregamento na tela do jogador aqui, por exemplo:
SendClientMessage(playerid, 0xFFFFFFFF, "Carregando...");
}
Neste exemplo, a função thread_LoadResources() é chamada quando o jogador se conecta ao servidor, e carrega os recursos do jogo em segundo plano. Enquanto a thread estiver em execução, a variável g_ThreadRunning é definida como verdadeira e a função OnPlayerSpawn() é executada para mostrar a tela de carregamento para o jogador. A função ShowLoadingScreen() é chamada a cada segundo para atualizar a mensagem de carregamento na tela do jogador. Quando a thread de carregamento de recursos for concluída, a variável g_ThreadRunning é definida como falsa e a tela de carregamento é removida.
Espero que isso ajude a resolver o problema de carregamento em seu jogo. Se tiver alguma dúvida, sinta-se à vontade para perguntar!
Mas tipo, geralmente os interiores personalizados de objetos são no céu e muito distantes das cidades. Existe a possibilidade de carregar em segundo plano objetos streamer de longe? E caso seja possível, não causaria lag?
E outro detalhe, por eles serem no céu(interiores), se não carregar os objetos na hora, os jogadores caem e morrem. O tal do "limbo"
Sim, é possível carregar objetos streamer de longe em segundo plano usando threads, mas pode haver um risco de lag se houver muitos objetos sendo carregados simultaneamente. Portanto, é importante usar um número limitado de threads para carregar os objetos.
Para lidar com interiores personalizados no céu e evitar que os jogadores caiam no "limbo", você pode considerar o uso de teleportes para permitir que os jogadores se movam para o interior apenas quando o carregamento estiver concluído. Isso pode ser feito em conjunto com o uso de threads para carregar os objetos em segundo plano.
Aqui está um exemplo de como isso pode ser feito:
Código: // Define uma variável global para controlar a thread
new g_ThreadRunning = false;
// Função da thread para carregar os objetos do interior
forward thread_LoadInteriorObjects(int interiorid);
// Função para mostrar a mensagem de carregamento na tela do jogador
forward ShowLoadingScreen(playerid);
public OnPlayerConnect(playerid)
{
// Inicia a thread para carregar os objetos do interior em segundo plano
g_ThreadRunning = true;
thread thread_LoadInteriorObjects(interiorid);
}
public OnPlayerInteriorChange(playerid, interiorid, oldinteriorid)
{
// Verifica se o jogador está entrando no interior personalizado
if(interiorid == MEU_INTERIOR_PERSONALIZADO)
{
// Mostra a tela de carregamento enquanto a thread estiver em execução
while(g_ThreadRunning)
{
ShowLoadingScreen(playerid);
Sleep(1000);
}
// Teleporta o jogador para o interior personalizado
SetPlayerPos(playerid, MEU_INTERIOR_PERSONALIZADO_X, MEU_INTERIOR_PERSONALIZADO_Y, MEU_INTERIOR_PERSONALIZADO_Z);
// Marca a thread como concluída
g_ThreadRunning = false;
}
}
public thread_LoadInteriorObjects(int interiorid)
{
// Carrega os objetos do interior personalizado aqui, por exemplo:
LoadMyInteriorObjects(interiorid);
// Marca a thread como concluída
g_ThreadRunning = false;
}
public ShowLoadingScreen(playerid)
{
// Mostra a mensagem de carregamento na tela do jogador aqui, por exemplo:
SendClientMessage(playerid, 0xFFFFFFFF, "Carregando...");
}
Neste exemplo, a função thread_LoadInteriorObjects() é chamada quando o jogador se conecta ao servidor e começa a carregar os objetos do interior personalizado em segundo plano. Quando o jogador entra no interior personalizado, a função OnPlayerInteriorChange() é chamada e verifica se o jogador está entrando no interior personalizado. Se for o caso, a função mostra a tela de carregamento até que a thread de carregamento de objetos seja concluída. Em seguida, o jogador é teleportado para o interior personalizado e a tela de carregamento é removida.
Lembre-se de que, para evitar o risco de lag, é importante usar um número limitado de threads para carregar os objetos. Além disso, você pode usar técnicas de otimização, como culling e LOD (nível de detalhe), para reduzir o número de objetos que precisam ser carregados.
RE: Qual método mais eficiente? - Dr Editor - 10/03/2023
Existe uma forma de resolver e do meu ponto de vista não tem opção melhor e mais simples que essa: TogglePlayerControllable
Com essa função o jogador congela mesmo no ar, ou seja, num ambiente onde demora para carregar você consegue controlar exatamente quando deve descongelar para garantir que não caia no limbo.
RE: Qual método mais eficiente? - Device-Black - 14/03/2023
Isso sempre funcionou para mim:Código PHP: #define UPDATE_TIME (1500) // Tempo que o jogador deve ser congelado
TeleportarJogador(playerid, Float:x, Float:y, Float:z, Float:angle, worldid, interiorid) { SetPlayerPos(playerid, x, y, z); SetPlayerFacingAngle(playerid, angle); SetPlayerInterior(playerid, interiorid); SetPlayerVirtualWorld(playerid, worldid); // quanto mais especifico, melhor o resultado Streamer_UpdateEx(playerid, x, y, z, worldid, interiorid, STREAMER_TYPE_OBJECT, UPDATE_TIME); }
|