Also how would I use ray.Magnitude? Isn’t magnitude a measurement for distance?
yes, i think there was a way to establish a ray’s lenght, and if it touched nothing it would return where the ray would end based on lenght provided. so then you use (origin - hitPosition).Magnitude to get the effective distance between the start and end.
Firstly, why rays? You can just use CFrames.
Im not very good with CFrames how would I do what you suggested?
If you get the relative CFrame of a branch then you can multiply it with half the Y axis size which will get you the tip of the branch then you can create another branch there. Also, you can use CFrame.Angles if you want to rotate the new branch.
alright, thank you for the explanation
Rays are used to check collisions. idk why you need it in this case
you just need to generate a random direction in a 3d cone relative to the previous generated direction.
local rng_v = Random.new()
function RandomVectorOffset(v, maxAngle) --returns uniformly-distributed random unit vector no more than maxAngle radians away from v
return (CFrame.new(Vector3.new(), v)*CFrame.Angles(0, 0, rng_v:NextNumber(0, 2*math.pi))*CFrame.Angles(math.acos(rng_v:NextNumber(math.cos(maxAngle), 1)), 0, 0)).LookVector
end
The function by
you’ll start by getting the first direction from the up vector of the base
local max_angle = math.pi/8
local FirstDirection = RandomVectorOffset(BasePart.CFrame.UpVector, angle)
and then
local SecondDirection = RandomVectorOffset(FirstDirection, angle)
and keep going like that in a loop getting random directions that are limited by the angle you setted up and building the tree trunk
would this allow for a branch off of another branch or just building branches on a trunk
yes for sure
if you want 2 branchs
make 2 directions out of the previous direction instead of 1 direction
I actually just learnt this by researching your problem in a more mathematical way
I’m having troubles understanding, these are just angles right?
It’s not easy btw. basically I gave you just the key to the problem you’re facing
which is generating a random direction in a 3D cone.
I might implement it in my free time
I’ll make sure to share it with you and the community if it is successful
ah alright I’m just very confused as to how you build off of the angles
You can use the angles with CFrame.Angles. But remember it’s in radians.
I faced the same problem when I was younger. but I didn’t had enough math and cframe background to do it.
Now you reminded me of the problem I had. I guess right now I figured out the solution theoretically lol
Here I achieved one branching
this is the code that I used:
local PartTemplate = Instance.new("Part")
PartTemplate.Anchored = true
local function Line(a, b, parent)
local new = PartTemplate:Clone()
new.Size = Vector3.new(1,1, (a-b).magnitude)
new.CFrame = CFrame.new((a+b)/2, b)
new.Parent = parent
return b, new.CFrame.LookVector
end
local vec = Vector3.new
local v = {
ZERO = vec(0,0,0),
UP = vec(0,1,0)
}
local branchHeight = 5
local maxAngle = math.pi/4
local last, lastVec = Line(v.ZERO, v.UP*branchHeight, workspace)
local PartPerBranch = 10
local rng_v = Random.new()
function RandomVectorOffset(v, maxAngle) --returns uniformly-distributed random unit vector no more than maxAngle radians away from v
return (CFrame.new(Vector3.new(), v)*CFrame.Angles(0, 0, rng_v:NextNumber(0, 2*math.pi))*CFrame.Angles(math.acos(rng_v:NextNumber(math.cos(maxAngle), 1)), 0, 0)).LookVector
end
for i=0, PartPerBranch, 1 do
last, lastVec = Line(last, last+RandomVectorOffset(lastVec, maxAngle)*branchHeight, workspace)
end
hm, how would you split the branches though?
That’s what am going to try now
local PartTemplate = Instance.new("Part")
PartTemplate.Anchored = true
local function Line(a, b, parent)
local new = PartTemplate:Clone()
new.Size = Vector3.new(1,1, (a-b).magnitude)
new.CFrame = CFrame.new((a+b)/2, b)
new.Parent = parent
return b, new.CFrame.LookVector
end
local vec = Vector3.new
local v = {
ZERO = vec(0,0,0),
UP = vec(0,1,0)
}
local branchHeight = 5
local maxAngle = math.pi/8
local last, lastVec = Line(v.ZERO, v.UP*branchHeight, workspace)
local PartPerBranch = 1000
local rng_v = Random.new()
function RandomVectorOffset(v, maxAngle) --returns uniformly-distributed random unit vector no more than maxAngle radians away from v
return (CFrame.new(Vector3.new(), v)*CFrame.Angles(0, 0, rng_v:NextNumber(0, 2*math.pi))*CFrame.Angles(math.acos(rng_v:NextNumber(math.cos(maxAngle), 1)), 0, 0)).LookVector
end
for i=0, PartPerBranch, 1 do
last, lastVec = Line(last, last+RandomVectorOffset(lastVec, maxAngle)*branchHeight, workspace)
local branch = math.random(0,1) == 0
if branch then
local last, lastVec = Line(last, last+RandomVectorOffset(lastVec, math.pi/2)*branchHeight, workspace)
for i=0, 3, 1 do
last, lastVec = Line(last, last+RandomVectorOffset(lastVec, maxAngle)*branchHeight, workspace)
end
end
end
I found the pattern. now I just need to generalize it into a function
This is the most beautiful thing I have ever made through a devforum question xD