Trying to place part directly on other parts face/surface

Ive tried everything, and ive about given up. Hoping you guys can swoop in and save me now. I have this part of my script:

local Zpos = Tree.Position.Z
	local Xpos = Tree.Position.X
	local Ypos = Hit.Position.Y
	
	if Surface == Enum.NormalId.Front then
		Zpos = Tree.Position.Z - (Tree.Size.Z/2)
	elseif Surface == Enum.NormalId.Back then
		Zpos = Tree.Position.Z + (Tree.Size.Z/2)
	elseif Surface == Enum.NormalId.Left then
		Xpos = Tree.Position.X - (Tree.Size.X/2)
		Line.Orientation = Vector3.new(0,90,0)
	elseif Surface == Enum.NormalId.Right then
		Xpos = Tree.Position.X + (Tree.Size.X/2)
		Line.Orientation = Vector3.new(0,90,0)
	end

	Line.Position = Vector3.new(Xpos,Ypos,Zpos)

Its purpose is to position “Line” onto the face/surface of a tree that the player clicks with a tool. This actually works perfectly… on completey straight trees. If you rotate the tree then it just brakes, as expected. I need it to orient the “Line” on the “Tree” no matter what way it is standing, even if the tree fell over and isnt aligned on the grid. FYI Tree is just a plain ol’ part in a model and line is an instanced part from only a few lines up. FYI 2, my goal is just to get a tree chopping mechanic similar to Lumber Tycoon 2. (If you never played then your missing out on a childhood) Thank you, and let me know if you have further questions or want to ridicule me for my code.

1 Like

The issue is you’re calculating based solely on coordinates.

You will receive not only your solution, but also a math lesson.

  • Review this image. When objects have different Orientations, their coordinates are not enough to determine their appearance.
  • This is why CFrames were developed, they include rotations (qw, qx, qy, etc) and also positions (x, y, z) so a part’s position and rotation can be defined by one value.
    • However, CFrame often is too complicated to be used in simple functions. This is why orientation exists as a property. `Orientation is simply the value a part is rotated relative to the (X, Y, and Z) axis.
    • Vector3s are simply the X, Y, and Z torn out of a CFrame. They work in positions and orientations for this reason, because two Vector3s of Position and Orientation (kinda) essentially makes a CFrame.

With all of that understood, your code only accounts for the Vector3 Position of the tree’s CFrame.

  • You are getting lines appearing in strange positions because your code is doing exactly what it is told to do.
  • The code maps the line to the proper coordinates, but does not match the trees Orientation.

Now, to actually fix the code:

  • It’s late and I can’t test this, so if it doesn’t work feel free to let me know.
  • Quite honestly I just threw this into ChatGPT and told it to calculate it. In cases like these, I can explain it to you but at 12 AM i will be unable to calculate it for you.
local TreeCFrame = Tree.CFrame -- The tree's CFrame, which includes position and orientation
local size = Tree.Size
local halfSize = size / 2 -- Half the size of the tree for later reference

local bisectPoint = Vector3.new(0, 0, 0) -- variable point, means nothing as of now

if Surface == Enum.NormalId.Front then
    bisectPoint = Vector3.new(0, 0, -halfSize.Z) -- Front edge of the tree in local space
elseif Surface == Enum.NormalId.Back then
    bisectPoint = Vector3.new(0, 0, halfSize.Z) -- Back edge of the tree in local space
elseif Surface == Enum.NormalId.Left then
    bisectPoint = Vector3.new(-halfSize.X, 0, 0) -- Left edge of the tree in local space
elseif Surface == Enum.NormalId.Right then
    bisectPoint = Vector3.new(halfSize.X, 0, 0) -- Right edge of the tree in local space
end

local bisectedPosition = TreeCFrame:pointToWorldSpace(bisectPoint) -- now take the fake bisection and make it into a useable value

Line.Position = Vector3.new(bisectedPosition.X, Hit.Position.Y, bisectedPosition.Z) -- potion the line at the bisect


Line.Orientation = TreeCFrame:ToEulerAnglesXYZ() -- make the line point correctly
  • If you have issues, please reply. Also consider using AI sources if you have struggles like this. You can learn a lot from ChatGPT or other resources without having to wait hours for it to be explained.
3 Likes

Wow, thank you, very very helpful. I’ll test it out soon and let you know, but I can tell it’ll work. And dont worry about ChatGPT, he’s practically my teacher. I love learning about the mechanics so I can understand this stuff instead of copying and pasting so again, thank you for your time and this in depth explanation.

Of course, often times people suggest against using AI but when you’re a new developer you either are forced to read, use youtube, or go to AI. Pick one that works for you and keep experimenting until things click.

I’d also ask you mark my previous message as the Solution so that others know this thread is answered

1 Like

Tweaked it a bit and this is the final-ish script:

local TreeCFrame = Tree.CFrame
	local size = Tree.Size
	local halfSize = size/2

	local bisectPoint = Vector3.new(0, 0, 0)
	local X,Y,Z = TreeCFrame:ToOrientation()
	local Y2
	
	if Surface == Enum.NormalId.Front then
		bisectPoint = Vector3.new(0, 0, -halfSize.Z)
		Y2 = 0		
	elseif Surface == Enum.NormalId.Back then
		bisectPoint = Vector3.new(0, 0, halfSize.Z)
		Y2 = 0		
	elseif Surface == Enum.NormalId.Left then
		bisectPoint = Vector3.new(-halfSize.X, 0, 0)
        Y2 = 90		
	elseif Surface == Enum.NormalId.Right then
		bisectPoint = Vector3.new(halfSize.X, 0, 0)
		Y2 = 90		
	end
		
	local bisectedPosition = TreeCFrame:PointToWorldSpace(bisectPoint) 

	Line.Position = Vector3.new(bisectedPosition.X, Hit.Position.Y, bisectedPosition.Z) 
	
	Line:PivotTo(CFrame.new(Line.Position)*CFrame.Angles(X,Y,Z))
	Line.Orientation = Line.Orientation + Vector3.new(0,Y2,0)
	

still doesnt work when the tree part isnt aligned on the grid but I think thats a separate problem for me to solve.

For beginners I suggest using AI. After years of scripting it comes to the point where you CAN find these hidden math functions that solve your problem, but when you’re a beginner it’s much easier to just get your answers THEN understand it.

I firmly believe that once you solve this issue once, you’ll have no problems with it in the future. So just persevere until you find a fix, because ultimately this has been done before (in a fairly old game too) and is fixable!

and if i just research and give you the code you won’t get what it means.

1 Like

everythings working now, solution: Position really sucks >:( CFrame is my new god.

Yep, c frame has way more usage and capabilities but also costs time to understand.

Keep working with it and it will speed up much of your work.

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