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

[HELP] Help with Dynamic tree growth and recycling?

Asked by 7 years ago

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()
0
Hey mob <3 lol DanzLua 2879 — 7y
0
Hey. Just having bit of hard time figuring out how to make the trees grow with out adding scripts to each tree. I know their has to be a way. xxmobkiller 5 — 7y

Answer this question