Problem with Project Movement Direction along Sphere

Hi everyone. Honestly, i resisted asking for help about this. But i have long time finding a solution, and how i don’t know Math beyond some stuffs, i’m stuck on this.

local function Aligned_MoveDir(moveDirection : Vector3, surfaceNormal : Vector3) : Vector3
	surfaceNormal = surfaceNormal.Unit

	if surfaceNormal.Magnitude == 0 then
		return moveDirection
	end

	local upVector = Vector3.yAxis
	local Axis = upVector:Cross(surfaceNormal)

	if Axis.Magnitude < 1e-5 then
		Axis = upVector:Cross(Vector3.zAxis)
	end

	Axis = Axis.Unit
	local dotProduct = upVector:Dot(surfaceNormal)
	dotProduct = math.clamp(dotProduct, -1, 1)

	local angle = math.acos(dotProduct)

	local rotation = CFrame.fromAxisAngle(Axis, angle)
	local alignedMoveDirection = rotation:VectorToWorldSpace(moveDirection)

	return alignedMoveDirection
end

Works perfectly on plane surfaces, ramps, and plane ceilings… but not in sphere, especially when are Upside Down.

this is beacause Axis is product of UpVector and Normal, UpVector is yAxis (a global axis), when the normal is opposite to UpVector (upside down), the direction can be anything (or so i understand).

I tried to detect when Normal is upper than 90°, and flip upVector to -UpVector, and works when are upside down… but when you want to walk around the sphere, you cannot pass the “equator”, because the input be inverted in some decimal upper 90°. Example: W becomes S… but in one decimal lower than 90° the input be W again… and that be a loop.

Sorry if i write this like someone what doens’t know the english gramatic, i dont know fully english. And i dont have anyone what have knowledge about scripting or math to talk about.

theres a bit of a makeshift soloution to this, if upvector < 0 then offset the initial calculations by say 90 degrees, do calculations, then account for the offset before returning the result, this will keep your axis relevant and prevent it going haywire as it crosses -1,1 on the y axis.

this is something ive encountered before on a different project but when cframe calculations are rotated on certain axis and nears -1,1 it can get a little messy.

Theres a different soloution which is using orientation as it doesnt have the same issue around -1,1 which is probably more stable but means translating between cframe and orient a little bit.