A video showing my problem (Streamable).
I have written a Plugin script that randomly selects a tree model from 'ReplicatedStorage/Trees', then clones it and places it at the click point in the 3D world (in Roblox Studio Editor, not in game).
The problem seems to be that the trees are not positioned straight — in the video I showed, the trees do not clone straight (up) even on Flat Terrain. I have tried:
setting the CFrame Angles to 0, 90 or 180 etc (I checked all axis) but trees are still not rotated in up direction...
local rotation = CFrame.Angles(math.rad(0), math.rad(0), math.rad(0))
SpawnedTree:PivotTo(position * rotation)
just setting position:
SpawnedTree:PivotTo(position)
AND! I use a tree model named Pine Tree - Pivot is in right place, Orientation and Position is set to (0, 0, 0)
.
Entire script (not localscript) located in workspace
without GUI code:
local NO_TREES_FOUND_ERROR = "No trees found!"
local NO_TREES_FOLDER_FOUND_ERROR = "No 'Trees' folder found!"
-- Tag Log
local TAG = "TPlace: "
-- Spawn tree
local function spawnTree(position)
local treeToSpawn = nil -- Final Tree Model to spawn
local randomInt -- Number of model to pick
local storage = game:GetService("ReplicatedStorage") -- Obvious
if not storage:FindFirstChild("Trees") then -- Just check if 'Trees' folder exist
showError(NO_TREES_FOUND_ERROR) -- In GUI
warn(TAG .. "No 'Trees' folder found! Create this folder in ReplicatedStorage and place trees there!")
else
local children = storage.Trees:GetChildren()
if #children == 0 then -- If 'Trees' folder exist, check if there is tree models
showError(NO_TREES_FOUND_ERROR) -- In GUI
warn(TAG .. "No trees found! They need to be in ReplicatedStorage/Trees")
else
if #children == 1 then -- If there is only one model, select '1'
randomInt = 1
else
local randomInt = math.random(1, #children)
end
treeToSpawn = children[randomInt]
local SpawnedTree = treeToSpawn:Clone() -- Clone Tree
SpawnedTree.Parent = workspace -- Add to workspace
local rotation = CFrame.Angles(math.rad(0), math.rad(0), math.rad(0))
-- Set rotation (does'nt work)
SpawnedTree:PivotTo(position * rotation) -- Transform
end
end
end
-- Get Mouse click positions
local Mouse = plugin:GetMouse()
local target = nil
local function button1Down()
target = Mouse.Target
end
local function button1Up()
if target == Mouse.Target and target.Name == "Terrain" then
spawnTree(Mouse.Hit)
end
end
local ClickEventDown
local ClickEventUp
ClickEventDown = Mouse.Button1Down:Connect(button1Down)
ClickEventUp = Mouse.Button1Up:Connect(button1Up)
plugin:Activate(isConnected)
Something to be careful about it that the Mouse.Hit object is a CFrame, not a Vector3. That means that it comes with positional and rotational information baked in. According to the documentation :
The orientation of the Hit CFrame corresponds with the direction of the Mouse.UnitRay.
That means that the y-axis is likely not straight up, but based on the camera position and mouse position.
So if you want to strip away the rotation information, you can use the .p
or .Position
property of the CFrame to take just the positional information.
So try this :
local function button1Up()
if target == Mouse.Target and target.Name == "Terrain" then
spawnTree(Mouse.Hit.Position)
end
end