When I place a LocalScript called MyScript in StarterPlayer → StarterPlayerScripts programatically from a Script under ServerScriptService my hope is that MyScript will be placed inside that player’s character model and run whenever she joins the game, and this seems to be the case.
However, if the server places MyScript there AFTER the player joined, the script will NOT be run.
So my question is, how can I make MyScript script run for existing players in the game?
Example code:
MyScript.Parent = game.StarterPlayer.StarterPlayerScripts
MyScript.Enabled = true -- Set to disabled in editor
“Name” is the player name …
The scripts in game.StarterCharacterScripts go to game.Workspace.Name.Animate
Scripts cloned running or not, to game.Workspace.Name.Animate would use:
local scriptParent = script.Parent.Parent
local Humanoid = scriptParent:WaitForChild("Humanoid")
You can leave the code dormant in the local script and trigger it via a RemoteEvent, that prevents you from needing to move the script around. There seem to be weird rules about scripts running based on where they are and its best to avoid having to deal with them.
I use events other places in my code, but this is part of bootstrapping (placing the only local script I have on the player) and so I would like to actually place the script somehow. Are the funny rules documented anywhere?
Not that I know of. My understanding is that the game checks where a script is located and runs it if appropriate, but only one time. StarterPlayerScripts and StarterCharacterScripts handle this for you correctly.
My understanding is that the game.workspace.<name> folder you mention is just the character model which can be found more reliably with local character = player.Character or player.CharacterAdded:Wait(), isn’t that correct?
Further, placing scripts in the character folder will re-start the scripts every time the character dies which is not what I want. I need the script to launch when the player loads the game and run until she leaves.
The thing is when you cloned the script and moved it, the script initialization started in a different place. Any calls to parent would end up a level off. Even though the script ends up there normaly, it wasn’t initialized there.
Why do you need to move a Local Script to run the code? Couldn’t you use Remote Events as @azqjanna suggested instead?
Regardless, you could move the script to the PlayerScripts folder. This can be found in the player’s respective Player object inside game.Players at runtime, and is where scripts in StarterPlayerScripts are copied to when a player joins the game.
Unfortunately, PlayerScripts can only be accessed from the client, so you’d have to move it using another Local Script, not a Server Script. You could have a Server Script fire a remote event signal that is received by another Local Script to then move the script.
The setup below would work:
-- SERVER SCRIPT CODE (in ServerScriptService)
local targetPlayer = "GreatPanda3"
local event = game.ReplicatedStorage.TestEvent
local player = game.Players:WaitForChild(targetPlayer)
-- ^ lazy but works for the sake of the example
if player then
print("Telling Local Script to move the script...")
event:FireClient(player)
else
print("Could not find player "..targetPlayer)
end
-- LOCAL SCRIPT CODE (in StarterPlayerScripts)
-- * think of this as a "manager" script
-- which will move the other local script
local event = game.ReplicatedStorage.TestEvent
local scriptToMove = game.ReplicatedStorage.ScriptToMove
event.OnClientEvent:Connect(function()
print("Moving local script...")
scriptToMove.Parent = game.Players.LocalPlayer.PlayerScripts
print("Local Script moved")
end)
-- LOCAL SCRIPT TO MOVE (in ReplicatedStorage)
print("Hey, I got moved!")
I did some tests to find out for sure, when I seen this. It’s just a matter of adding a .Parent if you’re going to call things from the script location.