Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

How can I make this script more simple and efficient?

Hi, thank you for reading. As you can see, all three of them are the except the Name part. What I'm trying to do is that when there is no object in workspace called "Wood" or "Foil" or Nail", then it will spawn into the workspace from Lighting.

local Loot = game.Lighting.Loot:GetChildren()
local Name = "Wood"

while wait(.1) do
 if not game.Workspace:findFirstChild(Name) then
	    for i = 1, #Loot do
 	       if Loot[i] and Loot[i].Name == Name then
    	        local Add = Loot[i]:Clone()
     	       Add.Parent = game.Workspace
     	       if game.Workspace.Part then
				Part = workspace.Part
           	     Add:MoveTo(Part.Position)
         	   end
      	  end
 	   end
	end	
end

local Loot = game.Lighting.Loot:GetChildren()
local Name = "Foil"

while wait(.1) do
   if not game.Workspace:findFirstChild(Name) then
     for i = 1, #Loot do
   	     if Loot[i] and Loot[i].Name == Name then
    	        local Add = Loot[i]:Clone()
      	      Add.Parent = game.Workspace
       	     if game.Workspace.Part then
				Part = workspace.Part
            	    Add:MoveTo(Part.Position)
        	    end
     	   end
 	   end
	end	
end

local Loot = game.Lighting.Loot:GetChildren()
local Name = "Wood"

while wait(.1) do
    if not game.Workspace:findFirstChild(Name) then
 	   for i = 1, #Loot do
         if Loot[i] and Loot[i].Name == Name then
      	      local Add = Loot[i]:Clone()
         	   Add.Parent = game.Workspace
         	   if game.Workspace.Part then
				Part = workspace.Part
            	    Add:MoveTo(Part.Position)
       	     end
            end
	    end
	end	
end

3 answers

✓ Accepted answer

A note from the Context Help (in ROBLOX Studio): The Lighting service was commonly used for storage since scripts did not run and models weren't rendered. However, ServerStorage and ReplicatedStorage should now be used for this purpose instead.

First the code:

local loot = game.ServerStorage.Loot:GetChildren()
local names = {"Wood", "Foil", "Nail"}

while wait(.1) do
	for n = 1, #names do
		local currentName = names[n]
		if not game.Workspace:FindFirstChild(currentName) then
			for i = 1, #loot do
				if loot[i] and loot[i].Name == currentName then
					local lootItemToAdd = loot[i]:Clone()
					lootItemToAdd.Parent = game.Workspace
					if workspace.Part then
						local part = workspace.Part
						if lootItemToAdd:IsA("Part") then
							print "Moving a part"
							lootItemToAdd.CFrame = CFrame.new(part.Position)
						elseif lootItemToAdd:IsA("Model") then
							print "Moving a model"
							lootItemToAdd:MoveTo(part.Position)
						end
					end
				end
			end
		end
	end
end

I pretended that your parts or whatever it is that you have should live in the ServerStorage area.

It can be helpful to distinguish between variables and function names by starting variables with lowercase letters. ROBLOX function names begin with uppercase letters. I've made those changes. Now when you look at your code, you can more easily tell the difference between a variable and a function.

Next, you need to start with a for loop to iterate through the names in your names table ("Wood", "Foil", "Nail"). Then assign a new variable "currentName" to the current value in the table. We did this with the variable "n". Now we know which name to look for.

Remember that function names begin with uppercase letters. So "findFirstChild" should be "FindFirstChild" to be proper. Yes, it does work without proper capitalization, but we are trying to get this right. Right?

I added "local" in front of the "part" variable to be consistent with your use of local in other places.

Depending on what Wood, Foil, and Nail are, they are positioned differently. You can see the if statement that checks to see if it "IsA" Part or Model and handles them appropriately. You can remove the print statements in there. Those are just fun to watch while debugging to see where the code is being executed.

I tested this with a Model named Loot, made up of Parts (Wood, Foil, and Nail).

Happy Coding, debugd

No offense, I'm trying to as well, but please tab your code correctly. :)

There is no reason why you should be re-doing the same code over-and-over again, why not just make it all into one code? Also, from past experience, it is not best to use the For Number loop to loop through a Table of Children. Lastly, why is Loot in Lighting? Models, Parts, ect. are meant to be stored and used in the ServerStorage service of the game; It prevents Client-Sided codes from getting anything from it, it only replicates to the Server, and, what happens if Loot is not existant at time of execution? This can be solved by using the WaitForChild method/function.

local matchName = {"Wood","Foil"}; --This is the Table of 'Strings' that which will be used in the code to check the Name of a Instance within the Workspace
local ServerStorageService = game:GetService("ServerStorage"); --Variable 'ServerStorageService ' is identifying the Service 'ServerStorage'; 'ServerStorage' is a Service in the game that is not Replicated to a Client (LocalScripts, LocalPlayer, ect.) preventing some Client-Sided exploits to access certain Models
local Loot = ServerStorageService:WaitForChild("Loot"):GetChildren(); --Variable 'Loot' is specifying the 'Model' instance 'Loot' within 'ServerStorage'; The 'WaitForChild' will yield the code/script until a Child with the matching Name as the Argument is existant, then will return the Child

function startProcessToCloneObjects(objName) --Here is our new function; functions perform specific tasks in codes; This function will be used to Add the new Instance to the game (More details and understanding further down in the code)
	local foundObj = nil; --Variable 'foundObj' is set to 'nil', I do this to prevent some errors sometimes
	for i,v in pairs(Loot) do --This will loop through the Children with Variable 'Loot'; The Generic 'for' loop is looping through a table
		if  (v.Name == objName) then --This will check to see if the current Child's name is equal to 'objName'; Variable 'objName' is specifying the 'String' Argument for the function
			foundObj = v --If the name Matches, then 'foundObj' will be set to the Child
			break --And will break the loop
		end --This ends the chunk for the 'if' statement
	end --This ends the chunk for the 'for' loop
	if foundObj ~= nil then --This will check to see if 'foundObj' is not equal to true
		local Object = foundObj:Clone() --If not, then it will clone 'foundObj'; Variable 'Object' is specifying the Cloned 'Model' Instance
		Object .Parent = game.Workspace --Sets the Parent property of 'Object' to 'game.Workspace'
		Object:MakeJoints() --I assume it's attempting to Clone a 'Model'? --Makes Joints on the 'Model' instance, preventing it to fall apart
		return Object --Will return Variable 'Object', or the Cloned 'Model' Instance
	else --But, if 'foundObj' is equal to 'nil', then
		return (foundObj or false) --It will return 'foundObj', which is nil, or will return 'false'
	end --Ends the chunk for the 'if' statement
end --Ends the chunk for the function

while wait(2) do --Here is the 'while' loop; The loop will fire every 2 seconds; the 'wait' function waits in seconds, basically, it yields the code for a certain amount of time
	if not game.Workspace:FindFirstChild(matchName[1]) then --If there is not a Child in the 'Workspace' with the matching name as the first 'String' within the Table 'matchName' (Wood) then
		local Object = startProcessToCloneObjects(matchName[1]) --It will call the function, with the 'String' Argument (Bad explanation :c); It will call function 'startProcessToCloneObjects' with the first 'String' within Table 'matchName' (Wood)
		if Object then --If Variable 'Object' is not equal to 'false' or 'nil' then
			Object:MoveTo(Vector3.new(0,0,0)) --I assume it's a 'Model'? --Moves the Object to a Location; 'MoveTo', as far as I know, only accepts 'Vector3''s
		end --Ends the chunk for the 'if' statement
	elseif not game.Workspace:FindFirstChild(matchName[2]) then --But, if there is not a Child in the 'Workspace' with the matching name as the second 'String' within the Table 'matchName' (Foil) then
		local Object = startProcessToCloneObjects(matchName[2]) --Same process
		if Object then --Same process
			Object:MoveTo(Vector3.new(0,0,0)) --I assume it's a 'Model'? --Same process
		end --Ends the chunk for the 'if' statement
	else --But, if both, I'm guessing, are existant then
		print("Both existant, I guess?") --Prints 'Both existant, I guess?' in the Output
	end --Ends the chunk for the 'if' statement
end --Ends the chunk for the 'while' loop

Information left out:

  1. The WaitForChild method yields the code until a Child with the matching name as the Argument is existant within the Parent (E.x.: Parent:WaitForChild(Child))

  2. The MoveTo method is used to Move a 'Model' instance to a certain Position, and will only take a Vector3 (E.x.: Model:MoveTo(Vector3.new(X,Y,Z)))

  3. nil is a key-word refers itself to void, or as programs like C call it null.

  4. Functions are used to perform specific tasks, depending on how it is used, and coded; It can also be re-ran, or used again, unlike Coroutines, where they return dead when they finished their task, or finished what they were supposed to do.

  5. ServerStorage is a Service that only Replicates itself to the Server, not a Client (Meaning won't Replicate itself to LocalScripts, LocalPlayers (Player-Clients), and such).

If I did not give a good explanation, or I left some-sort of information out, just let me know. :)

Hope this helped!

I see your error its on line 02, You might want to use the Table in cases like this, Example:

group={"Name1","Name2"}--This is what a Table looks like

print(group)

Now lets import it to your script.

local Loot = game.Lighting.Loot:GetChildren()
local Name = {"Wood","Foil"}

while wait(.1) do
  if not game.Workspace:findFirstChild(Name) then
     for i = 1, #Loot do
           if Loot[i] and Loot[i].Name == Name then
                local Add = Loot[i]:Clone()
               Add.Parent = game.Workspace
               if game.Workspace.Part then
                Part = workspace.Part
                   Add:MoveTo(Part.Position)
             end
         end
     end
    end 
end

Note that This was not Properly tested, if any errors please Comment.

8 comments

0

When the "Wood" part doesn't have those parantheses part, it works. But when I put it into a table, it doesn't work.

0

In line 7, you made the name equivalent to a table value, which is incorrect. Create a function with some "return" to verify if the name of "Loot's" stuff is equivalent to the argument.

0

Um, how would I do that? I'm kind of confused to what your saying.

0

Error on line 7: Attempt to compare 'Loot[i].Name' to 'Name' (A Table Value)'

0

Can someone show and explain to me how to fix it? It'll help me a lot right now and in the future.

0

I'd love to but, thats the only thing I saw(Tables).

0

How do you make those big letters...

0

@TeenyTanks, I just add 5 of these "-"

This discussion is preserved as it was. New answers, comments, and votes are closed.