Character keeps glitching when on ramp

I dont know the orientZ and orientX thing is using the normal but that was the point of the hnX and hnZ

Does it work with a set value (like 7) like you originally had?

What do you mean 7? the pid needs kind of like a zero point that it aims to go to and im not sure how a vector would work with that

Is the first argument of your PID script not the proportion, kp?

kP = 0.9
kI = 0
kD = 0.2
min = -100
max = -min
local bpidZ =,kI,kD,min,max)
local bpidX =,kI,kD,min,max)

	local dotX = Board.CFrame.LookVector:Dot(normalVector)
	local hnX = (math.deg(math.acos(dotX))-90)*math.sign(dotX)
	local dotZ = Board.CFrame.rightVector:Dot(normalVector)
	local hnZ = (math.deg(math.acos(dotZ))-90)*math.sign(dotZ)
	local orientX = hrp.Orientation.X
	local orientZ = hrp.Orientation.Z
	--if kl == true then
	--	hnX = hnX + 0.22
	--elseif kr == true then
	--	hnX = hnX + 0.22
	--elseif manual == true then
	--	hnX = hnX + 0.22
	local balanceForceZ = bpidZ:Calculate(hnZ*100,orientZ,dt)
	local balanceForceX = bpidX:Calculate(hnX*100,orientX,dt)
	vf.Force =,0,balanceForceX)*75

What does


value represent in your pid script?
Is it the target angle? Target direction? or some other thing?

ok so its like;
(where you want it to go), (where it is), (then some time thing)

Ok replace the stuff with




Making sure to not use the humanoidrootparts orientation, but using the weird calculations above

that really messes with it, it wont even stay upright while standing still

Try printing orientX and orientZ, to see what kind of values the math is even giving

-0.052869226845331 -0.76771894619267
-0.15107310055818 -0.85165093588492
-0.055940015246833 -0.96567267652574
just stuff like that

Would you say the angle printed seems to accurately represent the actual angle of the skateboard? Is it reversed? 90 degrees off?

yeah i suppose its the right angle

Ok I made a little bit of an oopsie, sorry for the wait

local dotX = lookVector:Dot(normalVector) 
local dotY = upVector:Dot(normalVector)
local dotZ = rightVector:Dot(normalVector) 

local orientX = math.deg( math.atan2(dotX, dotY) )
local orientZ = math.deg( math.atan2(dotZ, dotY) )

Try this

You might have to reverse the force or whatever cause it might be the opposite of what youre currently trying, just try messing with it since I cant

it doesnt seem like it even knows where it is so it just flings you around the place

using the humanoidrootpart was good i thought, cause i enable platformstand so i can put that in the PID loop so it knows what orientation it is

Have you tried it with the PID set back to what it was before?
Just the old hnZ and -hnX
I might have the wrong idea about what it is, but the angle thing should be pretty much the same just relative to the normal now

Do you have the code for the :Calculate() function by any chance?

function RoPID:Calculate(setPoint: number, processValue: number, deltaTime: number): number
  local err = setPoint - processValue
	local pOut = self.Gains.kP * err
	local iOut = 0
  if not self.IntegratorOff then
    self._integral += err * deltaTime
    iOut = self.Gains.kI * self._integral
	local dOut = self.Gains.kD * (err - self._pastErr) / deltaTime
	local rawOutput = pOut + iOut + dOut
  local output = math.clamp(rawOutput, self.Bounds.Min, self.Bounds.Max)

  self.IntegratorOff = self:_shouldClamp(rawOutput, output, err)

	self._pastErr = err
  return output

Can you set the first arguments back to 0 and then:
Can you print out:

print(orientX..", "..orientZ..", "..balanceForceX..", "..balanceForceZ)

And let it run for a little bit then paste the entire output of data here so I can copy it into a graphing program to see what in the world its doing?