How to convert unit vector into CFrame for use in BodyGyro


Yeah I used a lineforce already, it’s just the gyro part that’s making me a N g r y


For the last option, all I did was rotate the first option (facing towards the planet’s center) 90 degrees on the Z axis.

To achieve this, you can apply the following CFrame to the CFrame you create from my example before: CFrame.Angles(0, 0, math.pi / 2) (±pi, I’ve closed roblox studio now, so if it’s upside-down, just use -math.pi / 2).

Though as I stated before, this won’t account for letting your character control turning - so it’s quite basic for now. IdiomicLanguage might have more first-hand experience with how that’s done.


Ah, I see. I also made a maze world on a geodome. I had to ditch Humanoids because they like orienting characters upright and messing with physics. I also had to write a custom controller. Given a vector direction to the point on the surface, there is an infinite number of CFrames which will make the character stand on the surface. Given the character’s current position and current look vector however, there is only one. Here is some code:

local planetCenter =, 0, 0)
local planetRadius = 100

local function toCFrame(pos, look)
	local up = pos.Unit
	local right = look:Cross(up)
	local forward = up:Cross(right)
	return CFrame.fromMatrix(pos, right, up, forward)

local function rotate(cframe, angle)
	return cframe * CFrame.fromAxisAngle(cframe.Position - planetCenter, angle)

Disclaimer: this is untested code, but conceptually should be correct.

The first function, toCFrame, takes in a position on the surface of the planet and the character’s desired looking direction. It then through some cross products finds the right vector of the desired CFrame on the surface of the planet (which is orthogonal to the look and up vectors) and then uses that do find the proper forward direction (which is orthogonal to the up and right vectors, and roughly the same direction as the look vector but tangent to the planet’s surface at the position).

The second function is how you rotate a character who is already cframed correctly on the surface of the planet. Looking left or right simply means positive or negative angles (which are in radians).

To implement walking you could simply perform a straight line distance in the forward direction and then clamp it onto the planet, but this makes the actual distance moved dependent on how often the movement is done. Replicating this movement across client would be a nightmare and cause all sorts of rubber banding. Instead, walking needs to be done by finding the endpoint of an arc on the planet surface which is the desired walking distance’s length. The walking distance’s length should be a function of the walkspeed and the time since the last move. This is easy to replicate between clients and will minimize rubber banding. If you want, I could spend a minute or two and write up a function to find the endpoint of that arc.


Now that’s how you answer a question.