Ello, I’m trying to create a server script that chooses one player randomly to become the killer, and morphs them into a new model.
However, upon changing their character, the script no longer recognizes the chosen player as the killer.
I’ve tried researching DataStores and MemoryStores, but I’m not 100% sure that’s what I need.
Morph script:
local MorphEvent = game.ReplicatedStorage:FindFirstChild("MorphEvent")
MorphEvent.OnServerEvent:Connect(function(player, requestedMorphName)
print(player.Name, "wants to morph into a ",requestedMorphName)
if requestedMorphName == "testkiller" then
local oldCharacter = player.Character
local morphModel = game.ServerStorage.Killers:FindFirstChild(requestedMorphName)
local newCharacter = morphModel:Clone()
newCharacter.HumanoidRootPart.Anchored = false
newCharacter:SetPrimaryPartCFrame(oldCharacter.PrimaryPart.CFrame)
player.Character = newCharacter
newCharacter.Parent = workspace
oldCharacter:Destroy()
end
end)
Server script:
Note: I removed some code that I believe is unnecessary for the forum post,
but if you need more context/code, let me know!
local Players = game:GetService('Players')
local ServerStorage = game:GetService('ServerStorage')
local mapFolder = ServerStorage:WaitForChild('Maps')
local buttonevent = game.ReplicatedStorage:WaitForChild("ButtonsEvent")
local roundActive = false
function GetPlayers()
local list = {}
for _, player in pairs(Players:GetPlayers()) do
if player.Character then
table.insert(list, player)
end
end
return list
end
function GetPlayersInGame()
local list = {}
for _, character in pairs(workspace:GetChildren()) do
if not character:IsA('Model') then continue end
if character:GetAttribute("Survivor") then
table.insert(list, Players:GetPlayerFromCharacter(character))
end
end
return list
end
function SetUpKiller(Player : Player)
local Character = Player.Character
Character:SetAttribute("Killer", true)
script:WaitForChild("killerValues"):Clone().Parent = Character
buttonevent:FireClient(Player) -- (enables killer menu, where they can choose who to be)
task.wait(10)
SpawnCharacters(Character)
end
i’m believe the reason why this is happening is because you’re setting the killer attribute and value to the player’s old character then you delete it.
Instead, I think you should just do this:
player:SetAttribute("Killer", true) script:WaitForChild("killerValues"):Clone().Parent = Player
that way, the attribute persist even when you delete the character
Edit: I should mention that the code you provided doesn’t actually show where/how you’re checking for the killer attribute so this may not be the solution
while task.wait() do
local playerList = GetPlayers()
if #playerList >= amountToStart then
local index = math.random(1, #playerList)
roundActive = true
Intermission()
local chosenKiller = playerList[index]
table.remove(playerList, index)
workspace:SetAttribute("Status", "Loading Map...")
CreateMap()
for _, player in pairs(playerList) do
SetUpSurvivor(player)
end
workspace:SetAttribute("Status", "The KILLER will be coming soon...")
SetUpKiller(chosenKiller)
workspace:WaitForChild('CurrentMap'):WaitForChild('MapData'):WaitForChild('Spawn'):Remove()
currentCountdownValue = ROUND_TIME
task.spawn(RunGame)
repeat task.wait()
until (#GetPlayersInGame() <= 0) or (currentCountdownValue == 0)
roundActive = false
print("game end")
workspace:SetAttribute("Status", "Game ended")
task.wait(5)
CleanGame()
else
print("waiting for players")
workspace:SetAttribute("Status", "Waiting for players...")
task.wait(1)
end
end
thanks for sending your code. I’m reading it right now and I can’t seem to find where/how its checking for the killer attribute/value. Is it possible if you could show where its being checked?
I am really sorry. This code uses multiple tutorials in which I combined, and while I tried to understand their code to the fullest, I’m not the best at it.
local chosenKiller = playerList[index]
table.remove(playerList, index) -- remove killer from player list
If I’m not mistaken, this is where it checks for the killer(?) (unless the code doesn’t check for the killer, I don’t really know.)
Don’t be sorry, I’m happy to help you with whatever you need!
The code you posted is where the killer is selected and then removed from the survivor list, but it doesn’t necessarily check whether a player is the killer.
I should have clarify sooner, but when I said "where/how its checking for the killer", im mostly interested in what you do with the Killer attribute and killerValues value after setting them in the SetUpKiller() function because that might help us find where the issue is coming from.
Currently, the killerValues folder has no use, and the Killer attribute only gets checked in the CleanGame() function, where their values get reset after the game ends.
That means my initial assumption regarding the attribute/value were wrong.
I’m not exactly sure what the issue is. Would it be possible if you could explain how you figured out the script no longer recognizes the chosen player as the killer like do you get an error message, does the round system stops working, does a ui not show or is it something else?
The killer ui is supposed to wait 10 seconds before being disabled, yet it goes away as soon as the player clicks the button. Additionally, after the player morphs into the killer model, their Killer attribute and killerValues folder gets deleted, and they don’t get teleported into the map or get reset by the CleanGame() function.
I’d also like to mention that these issues happen permanently. Even if you wait for a game to start while already in the killer morph, it doesn’t give any attributes or folders. (Even the survivor attribute).
local Random = Random.new() at the top script, and everytime you use random below use local index = Random:NextInteger(1, #playerList), because math.random sometimes isn’t random. You could use math.randomseed(tick() * time()) but this is the better solution.
function SetUpKiller(Player : Player)
buttonevent:FireClient(Player)
task.wait(10)
local Character = Player.Character
Character:SetAttribute("Killer", true)
script:WaitForChild("killerValues"):Clone().Parent = Character
SpawnCharacters(Character)
end
Using what klrh said about setting the attributes to the old character then deleting it, all I changed was move the buttonevent and task.wait(10) before it defined what the character was. Now the script works perfectly.