Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

How can I make this script more simple and efficient?

Asked by
Yeevivor4 155
9 years ago

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

Log in to vote
0
Answered by
debugd 5
9 years ago

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

Ad
Log in to vote
3
Answered by 9 years ago

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!

Log in to vote
1
Answered by
woodengop 1134 Moderation Voter
9 years ago

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.

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. Yeevivor4 155 — 9y
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. Redbullusa 1580 — 9y
0
Um, how would I do that? I'm kind of confused to what your saying. Yeevivor4 155 — 9y
0
Error on line 7: Attempt to compare 'Loot[i].Name' to 'Name' (A Table Value)' TheeDeathCaster 2368 — 9y
View all comments (4 more)
0
Can someone show and explain to me how to fix it? It'll help me a lot right now and in the future. Yeevivor4 155 — 9y
0
I'd love to but, thats the only thing I saw(Tables). woodengop 1134 — 9y
0
How do you make those big letters... TeenyTanks 30 — 9y
0
@TeenyTanks, I just add 5 of these "-" woodengop 1134 — 9y

Answer this question