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 :slight_smile: Thanks for helping out.

1 Like

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