I’ve been working on a world generation script for fun which uses 2d perlin noise to generate a heightmap, and then randomly places objects such as trees, rocks and cacti. To make things look a bit more natural, I am also slightly rotating each object so that it comes out of the ground at a slightly different angle and faces a slightly different direction.
The code to do so is pretty simple:
local rotation = CFrame.Angles(math.rad(math.random(0,10)), math.rad(math.random(0,10)), math.rad(math.random(0,360))) obj:SetPrimaryPartCFrame(obj.PrimaryPart.CFrame:ToWorldSpace(rotation))
I am rotating by 10 degrees on the x and y axis, which is what gives the objects a slightly different angle as they come out of the ground. The rotation around the Z axis determines which direction the object faces perpendicular to the ground. Here’s how it looks with some rocks and trees:
So far, so good. However I get some unexpected behaviour when I try it with this cactus model:
I tried changing the 360 degree rotation from around the Z axis to the Y axis, and now it works as expected for the cacti but I get the same problem with the other models:
So it seems that if I want to rotate the cactus perpendicular to the ground I have to do so around the Y axis, yet for every other model I have to do so around the Z axis. What I don’t understand is what determines which axis I should be rotating around, and how I can determine this for every model i’m using, preferably at runtime.
tl;dr: How can I consistently rotate an object perpendicular to the ground?