I’m making tile based movement, and to detect whether a tile is occupied by the player, I’m using attributes. Now with the enemies, this works fine and it only sets the desired attributes to the enemies occupied tile.
But for some weird reason when I use the exact same mechanic for the player; Instead of setting the desired attributes for the players occupied tile to only that tile, it sets that attribute to every single tile possible.
Here is the code I’m using to set the attribute:
local dungeonLevel = GetDungeonLevel(self)
local tiles = dungeonLevel:WaitForChild("Tiles")
local playerPokemon = utilities.GetPokemon(playerData.PlayerPokemon)
local pokemonFolder = Instance.new("Folder", workspace)
pokemonFolder.Name = "Pokemon"
do
playerPokemon.Name = "Player"
playerPokemon.PrimaryPart.Anchored = true
playerPokemon.Parent = pokemonFolder
while true do
local playerTile = tiles:GetChildren()[math.random(1, #tiles:GetChildren())]
if not playerTile:GetAttribute("occupied") then
playerPokemon.PrimaryPart.CFrame = playerTile.CFrame
playerTile:SetAttribute("occupied", true)
playerTile:SetAttribute("occupiedBy", "pokemon")
break
else
playerTile = tiles:GetChildren()[math.random(1, #tiles:GetChildren())]
end
end
playAnimation(playerPokemon, animations[playerData.PlayerPokemon.."Idle"])
end
FYI: I am very much aware that Nintendo and Roblox do not like pokemon games, I do NOT intend for this to be released, this is being made purely for my enjoyment.
Here is the line that causes this issue:
local playerTile = tiles:GetChildren()[math.random(1, #tiles:GetChildren())]
And here is what all the empty tile parts look like when this line is being used:
V.S. what they look like without that line being used. (E.G. changing it to a random part)
It literally looks like the script is just changing any pokemon which isn’t occupied because you never told the script to stop or even yield (I don’t see wait() or task.wait())
Edit: break will just cancel the if statement, not the while true do loop
Somewhere inside the while true do but not inside the if statement, but you may place it wherever you want
local dungeonLevel = GetDungeonLevel(self)
local tiles = dungeonLevel:WaitForChild("Tiles")
local playerPokemon = utilities.GetPokemon(playerData.PlayerPokemon)
local pokemonFolder = Instance.new("Folder", workspace)
pokemonFolder.Name = "Pokemon"
do
playerPokemon.Name = "Player"
playerPokemon.PrimaryPart.Anchored = true
playerPokemon.Parent = pokemonFolder
while true do
task.wait() -- Put it somewhere here, and change the wait time to your needs, no yield will lag a lot.
local playerTile = tiles:GetChildren()[math.random(1, #tiles:GetChildren())]
if not playerTile:GetAttribute("occupied") then
playerPokemon.PrimaryPart.CFrame = playerTile.CFrame
playerTile:SetAttribute("occupied", true)
playerTile:SetAttribute("occupiedBy", "pokemon")
break
else
playerTile = tiles:GetChildren()[math.random(1, #tiles:GetChildren())]
end
end
playAnimation(playerPokemon, animations[playerData.PlayerPokemon.."Idle"])
end
I’ve done what you said but it still is setting the attribute to every tile. It’s definitely not lagging when I enter, but it still adds the attribute to every tile.
And I’ve added another break to break the while true do loop, so this doesn’t make much sense.
while true do
task.wait()
local playerTile = tiles:GetChildren()[math.random(1, #tiles:GetChildren())]
if not playerTile:GetAttribute("occupied") then
playerPokemon.PrimaryPart.CFrame = playerTile.CFrame
playerTile:SetAttribute("occupied", true)
playerTile:SetAttribute("occupiedBy", "pokemon")
break
else
playerTile = tiles:GetChildren()[math.random(1, #tiles:GetChildren())]
end
break
end