Tree cutting system calculations

1. What do you want to achieve? Keep it simple and clear!
I want to create a wood cutting system which creates a new part above and below exactly where you cut the wood part.

2. What is the issue? Include screenshots / videos if possible!
My brain can’t figure out how to calculate the position and size of the new parts. I am using `treePart.CFrame:pointToObjectSpace(mouseClickPos)` to get where the player clicked the tree part relative to the tree part.

3. What solutions have you tried so far? Did you look for solutions on the Developer Hub?
I tried looking at these posts:
How to make a choppable tree like in lumber tycoon 2?
Chopping tree exactly where you clicked
I have also tried asking around in the roblox studio discord asking for some help and got this very nicely drawn picture:

Furthermore, I am working with cylinder unions (so I can stretch them freely), but that also means that the X and Y position is basically swapped in relative space to the cylinder. I don’t know if it supposed to be like that but when I scale a cylinder to make it longer, the X value is what changes.

This is the closest I have gotten to solving this but I just can’t figure it out. It is probably really easy, especially with all the resources and help I have gotten but I just for the life of me can’t figure it out.

``````local function chop(Player : Player, Target : BasePart, CutLine : Vector3)
if Player:DistanceFromCharacter(Target.Position) < 10 then
-- Calculate the Y value of the cutline relative to the tree part
local cutY = CutLine.X

-- Calculate the sizes of the upper and lower tree parts
local treeXSize = Target.Size.X
local lowerSize = Vector3.new(cutY, Target.Size.Y, Target.Size.Z)
local upperSize = Vector3.new(treeXSize - lowerSize.X, Target.Size.Y, Target.Size.Z)

-- Clone the initial target for the upper tree part
local upperPart = Target:Clone()
upperPart.Size = upperSize
upperPart.CFrame = Target.CFrame:ToWorldSpace(CFrame.new((treeXSize - cutY) / 2, 0, 0))
upperPart.Parent = Target.Parent

-- Clone the initial target for the lower tree part
local lowerPart = Target:Clone()
lowerPart.Size = lowerSize
lowerPart.CFrame = Target.CFrame:ToWorldSpace(CFrame.new(-cutY / 2, 0, 0))
lowerPart.Parent = Target.Parent

-- Remove the original part
Target:Destroy()
end
end
``````
5 Likes

What exactly is `CutLine`? Is it the mouse click position?

The chopping and new part creation works perfectly fine for me when I test your script, so I would imagine the issue is with the Vector3 CutLine parameter you send. Without seeing how it’s stored or calculated I have no idea what could be wrong.

I have a module where I send the mouse.Target and mouse.Hit.Position, and that module in turn sends information to the server.

Here is my modulescript and how CutLine is calculated (it is the y position, or well, X position relative to the tree part. Sorry for any confusion and let me know if there is any more information needed.

``````function Resources:chop(Target : BasePart, ClickPosition : Vector3)
self = setmetatable({}, Resources)

self.TreeTarget = Target
self.ClickPosition = ClickPosition
self.Cut = Target.CFrame:PointToObjectSpace(ClickPosition)

if player:DistanceFromCharacter(Target.Position) < 10 then
ChopRE:FireServer(Target, self.Cut)
end

return self
end
``````

Okay since it’s implemented like that, then it is actually your chopping and new part creation that’s causing the issue. The way you calculate the new positions and the lower and uppersize doesn’t work for the cut value which is a relative value. This relative value doesn’t go from 0 to the size of the part like you expect, instead it originates from the middle of the part, and can go in either direction, giving it a positive or negative value relative to the middle of the object.

For the positions, it’s partly the same issues.

The below will work, so you can modify it to fit with your structure.

``````local function chop(Target: BasePart, Cut: Vector3)
local cutLocalPosition = Target.CFrame:PointToObjectSpace(Cut)
local cutX = cutLocalPosition.X

local lowerSize = Vector3.new(Target.Size.X / 2 + cutX, Target.Size.Y, Target.Size.Z)
local upperSize = Vector3.new(Target.Size.X / 2 - cutX, Target.Size.Y, Target.Size.Z)

local lowerPosition = Target.CFrame * CFrame.new(cutX - lowerSize.X / 2, 0, 0)
local upperPosition = Target.CFrame * CFrame.new(cutX + upperSize.X / 2, 0, 0)

local lowerPart = Target:Clone()
lowerPart.Size = lowerSize
lowerPart.CFrame = lowerPosition
lowerPart.Anchored = Target.Anchored
lowerPart.Parent = Target.Parent

local upperPart = Target:Clone()
upperPart.Size = upperSize
upperPart.CFrame = upperPosition
upperPart.Anchored = false
upperPart.Parent = Target.Parent

Target:Destroy()
end

local player = game.Players.LocalPlayer
local mouse = player:GetMouse()

mouse.Button1Down:Connect(function()
local clickTarget = mouse.Target
local clickPosition = mouse.Hit.Position

if clickTarget then
chop(clickTarget, clickPosition)
end
end)
``````

This works like a charm Thanks for helping out.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.