# Orienting controls relative to rotation

So I am trying to make it so that the player is perpendicular to a sphere and can walk around it. So far the orbiting works (gravitational force with non euler integration) however aligning, not so much. I am using quaternions to align it. I don’t really understand what it does other than align 2 vectors together. It works okay if I am going along a certain direction however the same problem still persists. Roblox is applying forces to move on 1 world axis and is not changing it dependent on the players rotation. Any ideas on how to fix this? My code

``````local function getMass(char)
local mass = 0
for _, v in pairs(char:GetDescendants()) do
if v:IsA("BasePart") then
mass += v:GetMass()
end
end
return mass
end

local function getClosestFaux(char, fauxs)
local closest = 0
local faux = nil
for i, v in pairs(fauxs:GetChildren()) do
if v:IsA("BasePart") then
local dif = (v.Position - char.HumanoidRootPart.Position).Magnitude
if dif > closest then
closest = dif
faux = v
end
end
end
return closest, faux, faux:GetMass()
end

local function getScalar(char)
local m1 = getMass(char)
local difference, faux, m2 = getClosestFaux(char, workspace.Fauxs)
return m1 * m2 / difference^2, faux, difference
end

local function getNormal(char, faux)
return (faux.Position - char.HumanoidRootPart.Position).Unit
end

local function getRotationBetween(u, v, axis)
local dot, uxv = u:Dot(v), u:Cross(v)
if (dot < -0.99999) then return CFrame.fromAxisAngle(axis, math.pi) end
return CFrame.new(0,0,0, uxv.x, uxv.y, uxv.z, 1 + dot)
end

char.Humanoid.PlatformStand = false
local attractor = script.attractor:Clone()
attractor.Parent = char.HumanoidRootPart
game:GetService("RunService").Heartbeat:Connect(function()
local scalar, faux, difference = getScalar(char)
local normal = getNormal(char, faux)
local force = scalar * normal
attractor.Force = force
local u = char.HumanoidRootPart.CFrame.UpVector
local axis = u:Cross(normal)
char.LowerTorso.Root.C0 = CFrame.new(0,-1,0,1,0,0,0,1,0,0,0,1) * getRotationBetween(u, -normal, axis)
end)
end)
end)
``````

[fauxGravity.rbxl|attachment]

1 Like

You can transform the normal to the HumanoidRootPart’s rotation like so:

``````local normal = getNormal(char, faux)
normal = char.HumanoidRootPart.CFrame:VectorToObjectSpace(normal)``````

Here’s a video of what the result looks like

Thanks that worked. But can you expand on what VectorToObjectSpace really does? I don’t really understand this concept of transforming normals to a rotation

Sorry, I’m not really good at explaining stuff, but basically the normal is a vector in world space, and VectorToObjectSpace sorta shifts the world space orientation to match whatever CFrame you call :VectorToObjectSpace on. Sorry if that doesn’t make much sense, maybe someone else can provide a more elaborate explanation… Here is the wiki’s explanation and the formula they use: `VectorToObjectSpace` takes in a vector as an argument and returns that vector rotated to match the rotation of the CFrame in world space.

1 Like