I have started a script that I find off Roblox Models. I redone the coding at lest I thought I was making it better which I was till I run in to problems. Let me explain what the code I have linked below should be doing and what I want it to do.
How the code works and should work: The code should create Trees. and grow the tree from the bottom up like a real tree should do. How ever I only got it to make the tree but the code is not doing what I need it to do It was working fine then it started doing strange things. It should create branches the more Complex meaning higher number means the more branches are groing to be added on to other branches but its limited to 2 - 4 pre branch and it then should rotate at a angle like real tree does with the branches randomly angles/rotations. It does do that how ever for some reason it just keeps putting them closer and closer together till the tree looks like one huge blob of just leaves and branches get to small they should only be allowed to go to the max size of Wide 1 and hieght 1 and length is random. I am not asking for anyone to up and create a complex tree system. That not why I am here just like to get help and maybe learn new stuff. I do give credits inreturn and If I can Vote on your Answer if it helps me out at all. The script I am trying to make is like Lumber Tycoon 2. At first I thought it was going to be easy how ever that turned out to be a LIE well at lest for me it did. Here example of how it should work. VIDEO: https://pbs.twimg.com/tweet_video/CIk5GizUkAEmrdi.mp4 Don't know If I am allowed to post links if not then I'll remove it but its from one of Defaultio post on Josh Twitter.
My Code:
local spawnedTrees = {} local treeTypes = { [0] = { ["TreeClass"] = "Generic", ["Regions"] = { [0] = game.Workspace.Region_Main }, ["Size"] = { ["Min"] = Vector2.new(1,7), ["Max"] = Vector2.new(2,11) }, ["Branches"] = { ["Min"] = 2, ["Max"] = 4, ["Color"] = BrickColor.new("Bright red"), ["Material"] = Enum.Material.Concrete }, ["Leaves"] = { ["Color"] = BrickColor.new("Really red"), ["Material"] = Enum.Material.Grass }, ["Complex"] = { ["Min"] = 2, ["Max"] = 3 }, ["Config"] = { ["Min"] = 100, ["Max"] = 150, ["Growth"] = { ["FastMode"] = false, ["Hours"] = 0, ["Minutes"] = 0, ["Seconds"] = 10 }, ["Decay"] = { ["FastMode"] = false, ["Hours"] = 0, ["Minutes"] = 20, ["Seconds"] = 0 } }, ["Current"] = { ["Model"] = nil, ["Branch"] = nil, ["Branches"] = 0, ["Complex"] = 0, ["Width"] = 0, ["Heigth"] = 0 }, }, } function getTreeParts(part, basePart) local tree = nil if part ~= nil and basePart == false and part == "T" then tree = Instance.new("Model") local cutEvent = Instance.new("BindableEvent",tree) cutEvent.Name = "CutEvent" local Owner = Instance.new("ObjectValue",tree) Owner.Name = "Owner" local LastInteraction = Instance.new("IntValue",Owner) LastInteraction.Name = "LastInteraction" local TreeClass = Instance.new("StringValue",tree) TreeClass.Name = "TreeClass" local Leaves = Instance.new("Model",tree) Leaves.Name = "Leaves" return tree elseif part ~= nil and basePart == true and part == "WS" then tree = part local ID = Instance.new("IntValue",tree) ID.Name = "ID" local ParentID = Instance.new("IntValue",tree) ParentID.Name = "ParentID" local ChildIDs = Instance.new("IntValue",tree) ChildIDs.Name = "ChildIDs" local Child = Instance.new("IntValue",ChildIDs) Child.Name = "Child" local Angle = Instance.new("CFrameValue",Child) Angle.Name = "Angle" return tree end return nil end -- get dot product of yz angles function dot(c1,c2) local m = CFrame.Angles(math.pi/2,0,0) return (c1*m).lookVector:Dot((c2*m).lookVector) end -- multiplier for various sizes of foliage local leaf_mult = { Vector3.new(1.5,1.5,1.2); Vector3.new(1.5,1,1.5); Vector3.new(1.2,1.5,1.5); Vector3.new(1.5,1.5,1.5); } function setSurfaceType(part) part.Anchored = true part.BackSurface = Enum.SurfaceType.SmoothNoOutlines part.FrontSurface = Enum.SurfaceType.SmoothNoOutlines part.RightSurface = Enum.SurfaceType.SmoothNoOutlines part.LeftSurface = Enum.SurfaceType.SmoothNoOutlines part.TopSurface = Enum.SurfaceType.SmoothNoOutlines part.BottomSurface = Enum.SurfaceType.SmoothNoOutlines end function Branch(tree, complexity, treeM) if complexity <= 0 then -- if the complexity has run out, generate some foliage local leaves = Instance.new("Part") setSurfaceType(leaves) leaves.CanCollide = false leaves.Material = treeM["Leaves"]["Material"] leaves.BrickColor = treeM["Leaves"]["Color"] local vol = tree.Size.x + tree.Size.y + tree.Size.z -- determine size based on branch size leaves.Size = (leaf_mult[math.random(1,#leaf_mult)]*math.random(vol/3*10,vol/3*12)/10)*0.75 leaves.CFrame = tree.CFrame * CFrame.new(0,tree.Size.y/2,0) -- center foliage at top of branch leaves.Parent = treeM["Current"]["Model"].Leaves else -- otherwise, make some more branches local pos = tree.CFrame*CFrame.new(0,tree.Size/2,0) local height = tree.Size.y local width = tree.Size.x local branches = treeM["Current"]["Branches"] -- # of possible branches (2 seems to work fine for now) local rotation = math.random(45,135) -- rotation of branches on y axis -- branch split angle difference -- the less complexity, the greater the possible angle -- minimum: 20-75; maximum: 40-80 -- local da = math.random(20+55/complexity,40+40/complexity) local differenceAngle = math.random(75/complexity,80/complexity) -- branch angle (overall angle of all branches) local branchAngle = math.random(-differenceAngle/3,differenceAngle/3) print("Name : " .. treeM["TreeClass"] .. " Angle : " .. branchAngle+differenceAngle/2) -- branchAngle+differenceAnge/2 shouldn't be near or greater than 90 degrees for i = 0, branches-1 do -- for each branch local branch = tree:Clone() branch.Name = "WoodSection" local h = height*math.random(95,115)/100 -- height .95 to 1.15 of original -- make new cframe -- move new to top of base, then apply branch angle (ba) local new = branch.CFrame * CFrame.new(0,height/2,0) * CFrame.Angles(0,0,math.rad(branchAngle)) -- next, rotate branch so that it faces away from others, also apply overall rotation (r) -- also, apply the split angle (da) -- finally, move branch upward by half it's size new = new * CFrame.Angles(0,i*(math.pi*2/branches)+rotation,math.rad(differenceAngle/2)) * CFrame.new(0,h/2,0) -- determine width by branch's final angle; greater the angle, smaller the width -- also shave off a bit of width for more dramatic change in size -- a frustum cone mesh would really help here local w = dot(new,branch.CFrame)*width*0.9 branch.Size = Vector3.new(w,h,w) branch.CFrame = new branch.Material = treeM["Branches"]["Material"] branch.BrickColor = treeM["Branches"]["Color"] branch.Parent = treeM["Current"]["Model"] -- create the next set of branches with one less complexity Branch(branch, complexity-1, treeM) end end wait() -- remove to generate faster end -- Main Function ---------------- function _G.GenerateTree(location, treeTypeID) local tree = treeTypes[treeTypeID] tree["Current"]["Model"] = getTreeParts("T", false) tree["Current"]["Model"].Parent = game.Workspace tree["Current"]["Width"] = math.random(tree["Size"]["Min"].x, tree["Size"]["Max"].x) tree["Current"]["Heigth"] = math.random(tree["Size"]["Min"].y, tree["Size"]["Max"].y) tree["Current"]["Complex"] = math.random(tree["Complex"]["Min"], tree["Complex"]["Max"]) tree["Current"]["Branches"] = math.random(tree["Branches"]["Min"], tree["Branches"]["Max"]) local WoodSection = Instance.new("Part", tree["Current"]["Model"]) setSurfaceType(WoodSection) WoodSection.Name = "WoodSection" WoodSection.BrickColor = tree["Branches"]["Color"] WoodSection.Material = tree["Branches"]["Material"] WoodSection.Size = Vector3.new(tree["Current"]["Width"], tree["Current"]["Heigth"], tree["Current"]["Width"]) -- move up by half its height, and rotate randomly WoodSection.CFrame = CFrame.new(location) * CFrame.new(0,tree["Current"]["Heigth"]/2,0) * CFrame.Angles(0,math.rad(math.random(1,360)),0) tree["Current"]["Branch"] = WoodSection -- start branching Branch(WoodSection, tree["Current"]["Complex"], tree) return tree end function snapToGrid(p, gH, gW, gD) return p.x - (p.x % gW), p.y - (p.y % gH), p.z - (p.z % gD) end function clamp(n, a, b) local temp = a; a, b = math.min(a, b), math.max(temp, b) return math.min(math.max(n, a), b) end local pos = game.Workspace.Region_Main.Ground.Position local size = game.Workspace.Region_Main.Ground.Size/2.04 local pos1 = Vector3.new((pos.X + size.X)-0.01, pos.Y, (pos.Z - size.Z)+0.01) local pos2 = Vector3.new((pos.X - size.X)+0.01, pos.Y, (pos.Z + size.Z)-0.01) local highBounds = Vector3.new(pos2.X, pos2.Y, pos2.Z) local lowBounds = Vector3.new(pos1.X, pos1.Y, pos1.Z) local minX = math.min(lowBounds.X, highBounds.X); local minZ = math.min(lowBounds.Z, highBounds.Z); local maxX = math.max(lowBounds.X, highBounds.X); local maxZ = math.max(lowBounds.Z, highBounds.Z); function setupTreeeRegion() local x = minX local z = minZ for x = minX, maxX, 30 do for z = minZ, maxZ, 30 do if math.random() < 0.09 then local xx, yy, zz = snapToGrid(Vector3.new(x,pos.Y,z), 1, 30, 30) xx = clamp(xx, lowBounds.X, highBounds.X) yy = clamp(yy, lowBounds.Y, highBounds.Y) zz = clamp(zz, lowBounds.Z, highBounds.Z) print(math.floor(xx), math.floor(yy), math.floor(zz)) _G.GenerateTree(Vector3.new(xx,yy,zz), 0) end end end end setupTreeeRegion()