For example, suppose I have a 4 by 1 by 2 part. Position returns the center. Suppose I want to get the exact position of the upper north east corner. I might want to add the vector (2, 0.5, -1) to the part. However, if the part rotates, it will screw stuff up, how can I add a position relative to the part rather than relative to world space. How should I proceed?
I am doing this in the context of gun barrels in a tool. I want to create the bullet at the end of the barrel. However, simply adding the length of the barrel divided by two will only work if the gun happens to be facing forward.
I found something promising here but how do I apply it for this purpose?
I don't think that any of the answers solved the problem, that if the part is rotated, the part should still remain at the upper north east corner.
Your question is basically asking how to convert a point from the coordinate frame of the barrel to the coordinate frame of the world. In particular, the vector you might be working with is part.Size / 2
. CFrames, which stands for coordinate frame, are made for this purpose. Multiplying a vector with a CFrame
converts that vector from the cframe's coordinate frame to the world coordinate frame.
local offset = part.Size / 2 local cornerPosition = part.CFrame * offset
There is also a function called PointToWorldSpace
that makes the purpose of the calculation more clear. It is exactly equivalent to the line above.
local cornerPosition = part.CFrame:PointToWorldSpace(offset)
As you mentioned, taking into account the part's cframe is not necessary if the part is not rotated. When the part isn't rotated, the position is simply part.Position + offset
. In fact, adding the offset to the part's position is analogous to converting coordinate frames as well if the coordinate frames couldn't be rotated (in general they can).
In my example, I'm going to have two parts as a visual: a blue part
that is representing our part we want to get the position of and a red part
that represents our position we want to get. links are visuals of each step.
Picture of the two parts
originalPart
is our blue part
positionPart
is our red part
Anyway, you didn't specify which direction was north, so I'm going to say the front face of the blue part is north.
We first want to put the red part at the cframe of the blue part so they have the same rotation:
positionPart.CFrame = originalPart.CFrame
We first want to shift the red part forward originalPart.Size.Z/2
studs on the z axis:
positionPart.CFrame = positionPart.CFrame * CFrame.new(0,0,-originalPart.Size.Z/2)
Then we'd want to shift the part to the right originalPart.Size.X/2
studs in the x-axis:
positionPart.CFrame = positionPart.CFrame * CFrame.new(originalPart.Size.X/2,0,0)
and then lastly, shift the red part up originalPart.Size.Y/2
studs in the y-axis
positionPart.CFrame = positionPart.CFrame * CFrame.new(0,originalPart.Size.Y/2,0)
You end up with the red part in the north east corner
You can do this all in one step by saying:
positionPart.CFrame = originalPart.CFrame * CFrame.new(originalPart.Size.X/2,originalPart.Size.Y/2,-originalPart.Size.Z/2)
local originalPart = Instance.new("Part") originalPart.CFrame = CFrame.Angles(math.rad(20),0,math.rad(5)) --rotating the part to show it works when originalPart is rotated originalPart.Parent = workspace originalPart.Color = Color3.fromRGB(0,0,255) local positionPart = Instance.new("Part") positionPart.Parent = workspace positionPart.Color = Color3.fromRGB(255,0,0) positionPart.Size = Vector3.new(.5,.5,.5) positionPart.CFrame = originalPart.CFrame * CFrame.new(originalPart.Size.X/2,originalPart.Size.Y/2,-originalPart.Size.Z/2)
99% Sure this is a troll. It's really easy just do
print(workspace.part.Position) workspace.part1.Position = workspace.part2.Position
Try harder and look at the wiki next time.
You can use lookVector, rightvector and upvectors from the part cframe and multiply it by the part size/2. You can also just get part.position+(part.Size/2) for that specific point i think.