I am on Roblox again, and I wanna make a script where when a part is touched, if the player name is lorenzoomh, set the brickcolor to green. But if not, set it to red. my current code:
script.Parent.Touched:Connect(function(igottouched)
if game.Players.LocalPlayer.Name == "lorenzoomh" then
script.Parent.BrickColor = BrickColor.Green()
else
script.Parent.BrickColor = BrickColor.Red()
end
end)
which doesnt work btw
The answer to your question, "can I use a player's name in an if-statement" is yes. Your problem is that the LocalPlayer doesn't exist where you're trying to use it from.
See the docs for Players.LocalPlayer :
This property is only defined for LocalScripts ... as they run on the client. For the server (on which Script objects run their code), this property is nil.
You need to access the Player object a different way. The Touched event on a Part gives you access to the other object that touched it. You can use that to check if the other part belongs to a player's character model.
local target = game.Workspace.Part
-- listen for a player touching a block
target.Touched:Connect( function(otherPart)
-- check that the thing that touched is a character model
local character = otherPart.Parent
local isCharacter = character:FindFirstChild("Humanoid") ~= null
if isCharacter then
-- the character model name is usually the name of the player so use that
if character.Name == "lorenzoomh" then
target.BrickColor = BrickColor.Green()
else
target.BrickColor = BrickColor.Red()
end
end
end)
The Players service has a method for correlating a character model with a Player object specifically if a simple name check is not sufficient for your use case.
Related
I'm trying to test out a game that gives coins to the player(via leaderstats) when you touch this block. When I touch the block though, my leaderstats don't change and I don't get any errors. Heres my Script
enter image description here
game.Players is a service and is not the Player who owns the Character that touched TestPart. The Players service provides a method to get the Player from a Character called GetPlayerFromCharacter(character).
TestPart.Touched:Connect(function(hit)
local plr = game.Players:GetPlayerFromCharacter(hit.Parent)
if plr then
plr.leaderstats.Coins.Value += 1
end
end)
Luau supports increments (+=) but not lua.
I use MoveTo for following the position and change the CFrame for rotation but it looks supper jaggy. I think the problem is that the code is on the server-side and not on the client-side since I want other players to be able to see the object following the player
Try using weldConstrain. You can create it by code and connect 2 parts to it. The parts are going to stay at the same relative position from each other. Here is a link for the API reference about the subject: https://developer.roblox.com/en-us/api-reference/class/WeldConstraint
Here is an example code that adds a part at the top of a player's head when it joins the game:
local Players = game:GetService('Players') -- get's the players service
local function OnPlayerAdded(player)
local PlayerCharacter = player.Character
-- waits until the player's character loads
while PlayerCharacter == nil do
wait(1)
PlayerCharacter = player.Character
end
-- Get's the player's model in workspace
local PlayerModel = workspace:WaitForChild(PlayerCharacter.Name)
-- Get's the player's head inside it's model
local PlayerHead = PlayerModel:WaitForChild('Head')
-- Write the path to the part you want to follow the player, bellow
local FollowPartOriginal = workspace:WaitForChild('Part')
-- If you want to clone the part, so more players can be followed by it,
-- don't delete the line below, if you want only 1 part, delete the line below.
local FollowPart = FollowPartOriginal:Clone()
-- set's the part position on top of the player's head, with an offset
FollowPart.Position = PlayerHead.CFrame.p + Vector3.new(0,2,0)
FollowPart.Parent = workspace
-- creates a weldconstrain
local WeldConstraint = Instance.new('WeldConstraint')
-- connect's the weld to the player's head and the other part
WeldConstraint.Part0 = PlayerHead
WeldConstraint.Part1 = FollowPart
WeldConstraint.Parent = PlayerHead
end
Players.PlayerAdded:Connect(OnPlayerAdded)
Place this code in a script(not a local script).
If you use the function separately, don't forget to put the player parameter. The parameter needs to contain the player Instance(ex: game.Players.PlayerName)
To change the part position, use the offset in this line of the code:
FollowPart.Position = PlayerHead.CFrame.p + Vector3.new(write offset here)
If you want the part the stop following the player, make a script to delete the part, or the weld constrain(child of the player's head)
When trying to create a code, that on FireServer with Specific Player chosen a GUI would've been cloned into their PlayerGui, But instead I get a nil value.
Code:
local Blinder = game.ReplicatedStorage.RCD.Blind
Blinder.OnServerEvent:Connect(function(player, PlayerToBlind)
if not player:IsInGroup(7465879) then return false end;
script.BL:Clone().Parent = PlayerToBlind:WaitForChild("PlayerGui")
print("Done")
end)
Basically what I try to reach is if my Admin Panel Remoteevent is fired, and a Target has been chosen, the Targeted Player will become a Cloned GUI into their PlayerGui
Any fix on this error?
The error message itself is telling you that you are calling a function that doesn't exist. This issue is caused by an object not being the type you expect.
Unfortunately, the message is pointing at a line that has a few function calls, so it's difficult to say what is causing the exact error. Either script.BL isn't an object with a Clone() function, or PlayerToBlind isn't an object with a WaitForChild() function.
If you can break the operations into a few different lines and add safety checks along the way, you can guarantee that your code is safe and being called properly.
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local Blinder = ReplicatedStorage.RCD.Blind
local BL = script.BL
Blinder.OnServerEvent:Connect(function(player, PlayerToBlind)
-- check that the person calling Blinder:FireServer actually provided a PlayerToBlind
assert(type(PlayerToBind) == "string", "Blinder expects PlayerToBind to be the name of a player")
-- escape if the player is not in the appropriate group
if not player:IsInGroup(7465879) then
return
end
-- find the Player object based on the name provided from PlayerToBlind
local blindedPlayer = Players:FindFirstChild(PlayerToBlind)
if not blindedPlayer then
warn("Could not find player named : ", PlayerToBlind)
return
end
-- create a blinding UI on the other player
local targetGui = blindedPlayer:WaitForChild("PlayerGui")
local newBL = BL:Clone()
newBL.Parent = targetGui
print("Done")
end)
By adding asserts into your code, it won't stop your code from breaking, in fact it will force your code to break faster and in expected ways.
The issue has been fixed,
I have been setting up the LocalScript wrong.
(I grabbed the Text from a TextButton, Instead of the TextBox)
Im trying to create a light when the player spawns in but im running into multiple problems
I've tried many formats and functions always keep getting either
"Attempt to index nil value"
"[head(and other things)] is not a member of [humanoid(and other things)]"
game.Players.PlayerAdded:Connect(function(playersdude)
playersdude.CharacterAdded:Connect(function(char)
local humanoid = char:WaitForChild("Humanoid")
local light = Instance.new("PointLight")
light.Parent = game.Players.LocalPlayer.HumanoidRootPart
end)
end)
You're running into the same problem as this guy : (attempt to index field 'LocalPlayer' (a nil value))
I'm assuming that you've written this in a Script somewhere. LocalPlayercan only be accessed in a LocalScript. Trying to access it from a server Script will result in LocalPlayer being nil. Luckily, you don't need to use LocalPlayer at all!
You can use the char provided in the CharacterAdded connection to find the player's head.
game.Players.PlayerAdded:Connect(function(playersdude)
playersdude.CharacterAdded:Connect(function(char)
-- search through the character model to find the head
local head = char:FindFirstChild("Head", true)
-- add a light bright enough to make them glow like the mid-morning sun
local light = Instance.new("PointLight", head)
light.Brightness = 100
end)
end)
I want there to be a "Quickmatch" mode in my turn-based game, where the player gets automatically matched with the first player to become available. I'm using my own custom UI. My code so far looks like this:
- (void)quickMatch {
GKMatchRequest *request = [[GKMatchRequest alloc] init];
request.minPlayers = 2;
request.maxPlayers = 2;
request.playersToInvite = nil;
[GKTurnBasedMatch findMatchForRequest:request withCompletionHandler:^(GKTurnBasedMatch *match, NSError *error) {
NSLog(#"MATCH: %# %# %# %d",error,match,match.matchID,(int)match.status);
}];
This successfully creates a match, but the 2nd participant in the match has a null ID (playerID:(null) status:Matching).
I thought that if I ran this same code on another instance, using a different Game Center ID, then the two users would be matched against each other... but that does not appear to be correct. Whenever I call the GKTurnBasedMatch loadMatchesWithCompletionHandler function, I continue to retrieve the same matches, each with only 1 valid participant (the local player).
This question appears to be similar to iOS Development: How do I auto match players in Game Center? which does indicate that setting request.playersToInvite = nil; should accomplish auto-matching, yet this doesn't appear to be working for me.
How can I cause Game Center to automatically match these players against each other?
Let me address the issues you are seeing here. First off, it is not necessary to set the playersToInvite property to nil, as that is the default state unless players are assigned to it, however that is not causing your "issue". I put that in quotes because you actually did the code correctly, and only perceive a problem that isn't there. Let me walk you through what happens when findMatchForeRequest is completed.
When the completion block is called, Game Center has created a new GKTurnBasedMatch object with two participants, the first is the local player (you), and the second is actually an empty participant with a nil playerID. The reason for this is that Game Center does not assign all participants when a match is created with random (unassigned) opponents. A random participant is assigned when the turn is sent to them. In your game, that match will not show up in the cloud for others to play in until you take your first turn.
Now, calling loadMatchesWithCompletionHandler on your other device/Game Center ID will not automatically display the match UNLESS you specifically invited that player with playersToInvite (and have already taken your turn as specified above). Think about it like this: if it worked that way, every player in the world would see every auto-match in existence when they called loadMatchesWithCompletionHandler.
The other Game Center ID must actually call findMatchForRequest with no playersToInvite property set in order to be matched into the empty seat available in the game your other ID created. This way the paradigm of "it's always your turn" when creating a match is preserved, but that player is now in the second slot, not the first. Simply create a game on the second ID in the exact same way you did on the first, and your game will be created with two participants, the first being from the ID that originally created it, and the second being the ID that joined the match by calling findMatchForRequest. The key here is findMatchForRequest doesn't ALWAYS create a new match if playersToInvite is nil. If there is an existing match with an open seat, it will simply match the local player into that.
Happy Coding!
Corbin