Issue with 3DTextLabel that's ment to vanish with a timer.
#1

So, I want to have a 3DTextLabel that triggers OnPlayerSpawn and says "I recently spawned." for 20 seconds. However, it only seems to delete the label after 20 seconds for the first player that has it, and for the rest, it remains permanently.

See the code below:

Код:
new Text3D:PlayerLoginLabel[MAX_PLAYERS]; // //So each player has it's own 3DTextLabel.
new ExistentPlayerLoginLabels; // In order to know which label is which. 
new LoginLabelDespawnTimer[MAX_PLAYERS]; // A timer for each label to despawn

public OnPlayerSpawn(playerid)
{
        new LoginLabelid; // A variable to define label ID's (used for the timers)
    	ExistentLoginLabels++;
    	LoginLabelid = ExistentPlayerLoginLabels;
    	LoginLabelDespawnTimer[LoginLabelid] = SetTimerEx("LabelTimer", 20000, false, "i", LoginLabelid);
        return 1;
}

forward LabelTimer(LoginLabelid);
public LabelTimer(LoginLabelid)
{
    Delete3DTextLabel(PlayerLoginLabel[LoginLabelid]);
}
Reply
#2

I feel like you're over complicating things for no reason. It looks like you're manually trying to keep track of 3D Text IDS when Create3DText already returns it's corresponding ID.

Something like this should work:
PHP код:
new
    
Text3D:PlayerLoginLabel[MAX_PLAYERS] = { Text3D:INVALID_3DTEXT_ID, ... }, // So each player has it's own 3DTextLabel.
    
LoginLabelDespawnTimer[MAX_PLAYERS]; // A timer for each label to despawn. (Although technically, unless you specifically need to use the timer ids somewhere else in your code; you don't even need a variable to store all the timer ids.)
public OnPlayerSpawn(playerid)
{
    if(!
IsValid3DTextLabel(PlayerLoginLabel[playerid])) // In case someone spawns multiple times while the 3D Text is valid/created.
    
{
        
PlayerLoginLabel[playerid] = Create3DTextLabel(. . . ); // Put your Create3DTextLabel here.
        
LoginLabelDespawnTimer[playerid] = SetTimerEx("SpawnLabelTimer"20000false"i"playerid);
    }
    return 
1;
}
forward SpawnLabelTimer(playerid);
public 
SpawnLabelTimer(playerid)
{
    if(
IsValid3DTextLabel(PlayerLoginLabel[playerid]))
    {
        
Delete3DTextLabel(PlayerLoginLabel[playerid]);
        
PlayerLoginLabel[playerid] = Text3D:INVALID_3DTEXT_ID;
    }

Reply
#3

Quote:
Originally Posted by CantBeJohn
Посмотреть сообщение
I feel like you're over complicating things for no reason. It looks like you're manually trying to keep track of 3D Text IDS when Create3DText already returns it's corresponding ID.

Something like this should work:
PHP код:
new
    
Text3D:PlayerLoginLabel[MAX_PLAYERS] = { Text3D:INVALID_3DTEXT_ID, ... }, // So each player has it's own 3DTextLabel.
    
LoginLabelDespawnTimer[MAX_PLAYERS]; // A timer for each label to despawn. (Although technically, unless you specifically need to use the timer ids somewhere else in your code; you don't even need a variable to store all the timer ids.)
public OnPlayerSpawn(playerid)
{
    if(!
IsValid3DTextLabel(PlayerLoginLabel[playerid])) // In case someone spawns multiple times while the 3D Text is valid/created.
    
{
        
PlayerLoginLabel[playerid] = Create3DTextLabel(. . . ); // Put your Create3DTextLabel here.
        
LoginLabelDespawnTimer[playerid] = SetTimerEx("SpawnLabelTimer"20000false"i"playerid);
    }
    return 
1;
}
forward SpawnLabelTimer(playerid);
public 
SpawnLabelTimer(playerid)
{
    if(
IsValid3DTextLabel(PlayerLoginLabel[playerid]))
    {
        
Delete3DTextLabel(PlayerLoginLabel[playerid]);
        
PlayerLoginLabel[playerid] = Text3D:INVALID_3DTEXT_ID;
    }

Even though the timer isn't set to repeat, you should still kill it
Reply
#4

Quote:
Originally Posted by CantBeJohn
Посмотреть сообщение
I feel like you're over complicating things for no reason. It looks like you're manually trying to keep track of 3D Text IDS when Create3DText already returns it's corresponding ID.

Something like this should work:
PHP код:
new
    
Text3D:PlayerLoginLabel[MAX_PLAYERS] = { Text3D:INVALID_3DTEXT_ID, ... }, // So each player has it's own 3DTextLabel.
    
LoginLabelDespawnTimer[MAX_PLAYERS]; // A timer for each label to despawn. (Although technically, unless you specifically need to use the timer ids somewhere else in your code; you don't even need a variable to store all the timer ids.)
public OnPlayerSpawn(playerid)
{
    if(!
IsValid3DTextLabel(PlayerLoginLabel[playerid])) // In case someone spawns multiple times while the 3D Text is valid/created.
    
{
        
PlayerLoginLabel[playerid] = Create3DTextLabel(. . . ); // Put your Create3DTextLabel here.
        
LoginLabelDespawnTimer[playerid] = SetTimerEx("SpawnLabelTimer"20000false"i"playerid);
    }
    return 
1;
}
forward SpawnLabelTimer(playerid);
public 
SpawnLabelTimer(playerid)
{
    if(
IsValid3DTextLabel(PlayerLoginLabel[playerid]))
    {
        
Delete3DTextLabel(PlayerLoginLabel[playerid]);
        
PlayerLoginLabel[playerid] = Text3D:INVALID_3DTEXT_ID;
    }

This code looks great, thank you so much for your assistance. But I can't compile the code.

Код:
error 017: undefined symbol "IsValid3DTextLabel"
Also, I've found that chat bubbles can overlap the label at OnPlayerText, any way to kill it at OnPlayerText if it's still enabled?
Reply
#5

So I installed YSF and compiled the code, but now the labels won't appear at all.

My current code:

Код:
new 
    Text3D:PlayerLoginLabel[MAX_PLAYERS] = { Text3D:INVALID_3DTEXT_ID, ... }, // So each player has it's own 3DTextLabel. 
    LoginLabelDespawnTimer[MAX_PLAYERS]; // A timer for each label to despawn. (Although technically, unless you specifically need to use the timer ids somewhere else in your code; you don't even need a variable to store all the timer ids.) 

public OnPlayerSpawn(playerid)
{
    	if(!IsValid3DTextLabel(PlayerLoginLabel[playerid]))
    	{ 
        	PlayerLoginLabel[playerid] = Create3DTextLabel("I just spawned.", COLOR_YELLOW, 0, 0, 0, 20, 0);
        	LoginLabelDespawnTimer[playerid] = SetTimerEx("SpawnLabelTimer", 20000, false, "i", playerid); 
    	}
	return 1;
}

forward SpawnLabelTimer(playerid); 
public SpawnLabelTimer(playerid) 
{ 
    if(IsValid3DTextLabel(PlayerLoginLabel[playerid])) 
    { 
        Delete3DTextLabel(PlayerLoginLabel[playerid]); 
        PlayerLoginLabel[playerid] = Text3D:INVALID_3DTEXT_ID; 
    } 
}
Anyone, please help me out.
Reply
#6

Quote:
Originally Posted by Stefhan
Посмотреть сообщение
So I installed YSF and compiled the code, but now the labels won't appear at all.

My current code:

Код:
new 
    Text3D:PlayerLoginLabel[MAX_PLAYERS] = { Text3D:INVALID_3DTEXT_ID, ... }, // So each player has it's own 3DTextLabel. 
    LoginLabelDespawnTimer[MAX_PLAYERS]; // A timer for each label to despawn. (Although technically, unless you specifically need to use the timer ids somewhere else in your code; you don't even need a variable to store all the timer ids.) 

public OnPlayerSpawn(playerid)
{
    	if(!IsValid3DTextLabel(PlayerLoginLabel[playerid]))
    	{ 
        	PlayerLoginLabel[playerid] = Create3DTextLabel("I just spawned.", COLOR_YELLOW, 0, 0, 0, 20, 0);
        	LoginLabelDespawnTimer[playerid] = SetTimerEx("SpawnLabelTimer", 20000, false, "i", playerid); 
    	}
	return 1;
}

forward SpawnLabelTimer(playerid); 
public SpawnLabelTimer(playerid) 
{ 
    if(IsValid3DTextLabel(PlayerLoginLabel[playerid])) 
    { 
        Delete3DTextLabel(PlayerLoginLabel[playerid]); 
        PlayerLoginLabel[playerid] = Text3D:INVALID_3DTEXT_ID; 
    } 
}
Anyone, please help me out.
What's your define of COLOR_YELLOW? What alpha are you using? E.G. 0xFFFF00FF . Also add KillTimer(LoginLabelDespawnTimer[playerid]); at the end of the timer.
Reply
#7

Quote:
Originally Posted by BeckzyBoi
Посмотреть сообщение
What's your define of COLOR_YELLOW? What alpha are you using? E.G. 0xFFFF00FF . Also add KillTimer(LoginLabelDespawnTimer[playerid]); at the end of the timer.
I added it, but I want to know why it's important. Isn't the fact that the timer is on "false" enough to kill it?

Anyways, my current issue is that it only works for the first player that gets the label. The other players, all have the label above their head until they logout instead of after 20 seconds.

The code right now:

Код:
new 
    Text3D:PlayerSpawnLabel[MAX_PLAYERS] = { Text3D:INVALID_3DTEXT_ID, ... }, // So each player has it's own 3DTextLabel. 
    SpawnLabelDespawnTimer[MAX_PLAYERS]; // A timer for each label to despawn. (Although technically, unless you specifically need to use the timer ids somewhere else in your code; you don't even need a variable to store all the timer ids.)

public OnPlayerSpawn(playerid)
{
         if(!IsValid3DTextLabel(PlayerSpawnLabel[playerid]))
	    	{ 
	        PlayerSpawnLabel[playerid] = Create3DTextLabel("I just spawned.", COLOR_YELLOW, 0, 0, 0, 20, 0);
	        Attach3DTextLabelToPlayer(PlayerSpawnLabel[playerid], playerid, 0.0, 0.0, 0.27);
	        SpawnLabelDespawnTimer[playerid] = SetTimerEx("SpawnLabelTimer", 20000, false, "i", playerid); 
	        }
	return 1;
}

forward SpawnLabelTimer(playerid); 
public SpawnLabelTimer(playerid) 
{ 
    if(IsValid3DTextLabel(PlayerSpawnLabel[playerid])) 
    { 
        Delete3DTextLabel(PlayerSpawnLabel[playerid]); 
        PlayerSpawnLabel[playerid] = Text3D:INVALID_3DTEXT_ID; 
        KillTimer(SpawnLabelDespawnTimer[playerid]);
    } 
}
Thanks a lot for your help so far.
Reply
#8

Quote:
Originally Posted by Stefhan
Посмотреть сообщение
I added it, but I want to know why it's important. Isn't the fact that the timer is on "false" enough to kill it?
No it doesn't kill it, it just stops it from repeating.

Quote:
Originally Posted by Stefhan
Посмотреть сообщение
Anyways, my current issue is that it only works for the first player that gets the label. The other players, all have the label above their head until they logout instead of after 20 seconds.
Код:
new Text3D:PlayerSpawnLabel[MAX_PLAYERS] = {Text3D:INVALID_3DTEXT_ID, ...};
new SpawnLabelDespawnTimer[MAX_PLAYERS];

public OnPlayerSpawn(playerid)
{
    if (!IsValid3DTextLabel(PlayerSpawnLabel[playerid]))
    { 
        PlayerSpawnLabel[playerid] = Create3DTextLabel("I just spawned.", COLOR_YELLOW, 0, 0, 0, 20, 0);
        SpawnLabelDespawnTimer[playerid] = SetTimerEx("SpawnLabelTimer", 20000, false, "i", playerid);
    }
    // attach it regardless of whether it already existed
    Attach3DTextLabelToPlayer(PlayerSpawnLabel[playerid], playerid, 0.0, 0.0, 0.27);
    return 1;
}

public OnPlayerDisconnect(playerid, reason)
{
    if (IsValid3DTextLabel(PlayerSpawnLabel[playerid]))
    {
        Delete3DTextLabel(PlayerSpawnLabel[playerid]); 
        PlayerSpawnLabel[playerid] = Text3D:INVALID_3DTEXT_ID;
        KillTimer(SpawnLabelDespawnTimer[playerid]);
    }
    return 1;
}

public OnPlayerDeath(playerid)
{
    if (IsValid3DTextLabel(PlayerSpawnLabel[playerid]))
    {
        Delete3DTextLabel(PlayerSpawnLabel[playerid]); 
        PlayerSpawnLabel[playerid] = Text3D:INVALID_3DTEXT_ID;
        KillTimer(SpawnLabelDespawnTimer[playerid]);
    }
    return 1;
}

forward SpawnLabelTimer(playerid);

public SpawnLabelTimer(playerid) 
{ 
    Delete3DTextLabel(PlayerSpawnLabel[playerid]); 
    PlayerSpawnLabel[playerid] = Text3D:INVALID_3DTEXT_ID; 
    KillTimer(SpawnLabelDespawnTimer[playerid]);
}
Reply
#9

Quote:
Originally Posted by BeckzyBoi
Посмотреть сообщение
No it doesn't kill it, it just stops it from repeating.



Код:
new Text3D:PlayerSpawnLabel[MAX_PLAYERS] = {Text3D:INVALID_3DTEXT_ID, ...};
new SpawnLabelDespawnTimer[MAX_PLAYERS];

public OnPlayerSpawn(playerid)
{
    if (!IsValid3DTextLabel(PlayerSpawnLabel[playerid]))
    { 
        PlayerSpawnLabel[playerid] = Create3DTextLabel("I just spawned.", COLOR_YELLOW, 0, 0, 0, 20, 0);
        SpawnLabelDespawnTimer[playerid] = SetTimerEx("SpawnLabelTimer", 20000, false, "i", playerid);
    }
    // attach it regardless of whether it already existed
    Attach3DTextLabelToPlayer(PlayerSpawnLabel[playerid], playerid, 0.0, 0.0, 0.27);
    return 1;
}

public OnPlayerDisconnect(playerid, reason)
{
    if (IsValid3DTextLabel(PlayerSpawnLabel[playerid]))
    {
        Delete3DTextLabel(PlayerSpawnLabel[playerid]); 
        PlayerSpawnLabel[playerid] = Text3D:INVALID_3DTEXT_ID;
        KillTimer(SpawnLabelDespawnTimer[playerid]);
    }
    return 1;
}

public OnPlayerDeath(playerid)
{
    if (IsValid3DTextLabel(PlayerSpawnLabel[playerid]))
    {
        Delete3DTextLabel(PlayerSpawnLabel[playerid]); 
        PlayerSpawnLabel[playerid] = Text3D:INVALID_3DTEXT_ID;
        KillTimer(SpawnLabelDespawnTimer[playerid]);
    }
    return 1;
}

forward SpawnLabelTimer(playerid);

public SpawnLabelTimer(playerid) 
{ 
    Delete3DTextLabel(PlayerSpawnLabel[playerid]); 
    PlayerSpawnLabel[playerid] = Text3D:INVALID_3DTEXT_ID; 
    KillTimer(SpawnLabelDespawnTimer[playerid]);
}
Thank you so much, it finally works like a charm!

One last question, should I always killtimers? Even those that are ment to loop?
Reply
#10

Quote:
Originally Posted by BeckzyBoi
Посмотреть сообщение
Even though the timer isn't set to repeat, you should still kill it
Why would you have to kill a timer that is not repeating when its function gets called. That is already handled by the timer itself after completing the function right.
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)