Lets say I have three parts: The base, independent, and dependent. Imagine the base has it's own grid. It's impervious to rotation and translation on it's grid; it's position is always at the origin: (0,0,0). Realistically, in worldspace, it can be manipulated as any other part. The dependent lies on this grid. The independent lies in worldspace, unaffected by the base's grid. The dependent relies on both the base and the independent for it's position in the worldspace. It's position on the base's grid mirrors that of the independent's position on the base's grid, so if the grids were aligned they'd be in the exact same position. My question is what equation could I use to get the position of the dependent? I want this equation to work universally, so that the base and the independent can be manipulated in any shape or form and the results will always be accurate. I've tried several times to accomplish this and came close, though I lost my data.
You can find a visual for my question here.
Try using some CFrame methods
supplied by Roblox rather than doing all the math.
In the following code, I used vectorToWorldSpace
http://wiki.roblox.com/index.php?title=CFrame#Methods
To try and test out a situation, I made the Independent part called Independent and the Dependent Part called Part.
I start the Dependent Part about 5 studs over the Independent Part. Both are anchored.
Here is my code:
local part = workspace.Independent; local part2 = workspace.Part; while true do local fromUp = part.CFrame:vectorToWorldSpace(Vector3.new(0,1,0)) --Top Face part2.CFrame = CFrame.new(part.Position + (fromUp * 5)) -- Move wait(1) end
While the loop is running, I dragged around the Independent Part and rotated it to test it.
Not only does the code maintain the dependents orientation, but moves it accordingly.
If you need an explanation:
Vectors keep ONLY the parts position
CFrame keeps the parts position AND CFrame
Also, as per your comment; You can do this if you wanna do it without a number constant:
local part = workspace.Independent local part2 = workspace.Part function distance(part1,part2) local x1 = part1.Position.X; local x2 = part2.Position.X; local y1 = part1.Position.Y; local y2 = part2.Position.Y; local z1 = part1.Position.Z; local z2 = part2.Position.Z; return math.sqrt((math.pow((z2-z1),2) + math.pow((x2-x1),2) + math.pow((y2-y1),2))) end local Dis = distance(part,part2) while true do local fromUp = part.CFrame:vectorToWorldSpace(Vector3.new(0,1,0)) --Top Face part2.CFrame = CFrame.new(part.Position + (fromUp * Dis)) -- Move wait(1) end
The following code will take the two parts, calculate the distance between them, and keep that distance throughout.
I've had to do just this for my Dungeon Dice Monsters game to handle the fields being rotated to fit in with the surrounding terrain.
There are two key methods to making this work: CFrame.toWorldSpace
and CFrame.toObjectSpace
First, the independent
part doesn't matter here. You'll manage it's position directly, in reference to the Origin, so let's look at the dependent
part.
EDIT: Misread your wall-o-text.
local base = workspace.Base local dep = workspace.Dependent local ind = workspace.Independent dep.CFrame = base.CFrame:toWorldSpace(ind.CFrame) --Assuming `ind`'s "grid position" is with respect to (0, 0, 0) with no rotation, otherwise: local indBase = workspace.IndependentBase dep.CFrame = base.CFrame:toWorldSpace(indBase.CFrame:toObjectSpace(ind.CFrame))
End edit.
local base = workspace.Base local dep = workspace.Dependent -- We want `dep` to be 1 Stud directly above `Base`, along the `Top` surface's axis: local newCF = CFrame.new(0, 1, 0) dep.CFrame = base.CFrame:toWorldSpace(newCF)
If you already have dep
at a location, and simply want to translate it, no problem!
local base = workspace.Base local dep = workspace.Dependent -- We want to translate `dep` by (2, 15, -7), with respect to the orientation of `base` local newCF = base.CFrame:toObjectSpace(dep.CFrame) --The argument CFrame here is important! newCF = newCF + Vector3.new(2, 15, -7) dep.CFrame = base.CFrame:toWorldSpace(newCF)
Since these are all CFrames and not Vector3s, Rotation is supported as well:
local base = workspace.Base local dep = workspace.Dependent -- Rotate `dep` to point in the direction of `base`'s Top surface normal, with `dep`'s Bottom surface normal pointing in the direction of `base`'s Front surface normal. local newCF = CFrame.new(base.CFrame:toObjectSpace(dep.CFrame).p) --first, cancel the current rotation. newCF = newCF*CFrame.Angles(math.pi/2, 0, 0) dep.CFrame = base.CFrame:toWorldSpace(newCF)
I assume the last example can be rewritten using vectorToWorldSpace
and the like, but these methods are tricky to figure out the usage of.