You’ve met car before:
So, I need to get onto this type of terrain:
And this type:
But there is an issue, You see I use a global turn value:
local turn = 0
--later
if scal == 1 then --because this is in a change steering function
if turn + tSpeed.Value < math.rad(360) then
turn = turn + tSpeed.Value
else
turn = math.rad(360) - (turn + tSpeed.Value)
end
elseif scal == -1 then
if turn - tSpeed.Value > 0 then
turn = turn - tSpeed.Value
else
turn = (turn - tSpeed.Value) + math.rad(360)
end
end
And how I calculate my new perpendicular angle is using the detected RightVector of the block its under:
local uAve = normAve:Cross(fRay.CFrame.RightVector).Unit
--norm average being the average of all the normals detected when raycasting downwards
So, the turn global value gets messed up because it is only calculating from the new perpendicular vector we found.
Problem: When a new perpendicular vector is found, the turn angle is too big, so the car turns to a weird angle without the player telling it to move
What I want to do is make the turn value change according to the new perpendicular vector with relation to the last perpendicular vector. So if the angle between both vectors (on the x/z plane) is 90, then it subtracts 90 from the turn value.
Methods that didnt work:
- Making an average of the right vectors from all raycast points on the craft and use the angle between the last and the new right vector
- Getting the perpendicular vectors for the new and the last and determine the angle between both on the x/z plane
1 for some reason gets me -nan(ind) and 2 makes my car go upside down
Current Code
local function changeSteer(scal)
local backPerc
local stabFold = car.StabilityPoints
llAV = normAve
for _, poin in pairs(stabFold:GetChildren()) do
local h,_, fN = castRay(poin, (-1 * poin.CFrame.UpVector), 500000)
if h then
normAve = ((normAve.Unit + fN.Unit)/2).Unit
--lAngleVec = ((h.CFrame.RightVector + lAngleVec)/2).Unit
--print(h.CFrame.RightVector)
end
end
--print(normAve)
local fRay = castRay(stabFold.FPoint, (-1 * stabFold.FPoint.CFrame.UpVector), 500000)
if fRay == nil then
fRay = castRay(physRoot, (-1 * physRoot.CFrame.UpVector), 500000)
if fRay == nil then
fRay = castRay(stabFold.BPoint, (-1 * stabFold.BPoint.CFrame.UpVector), 500000)
end
end
local uAve = normAve:Cross(fRay.CFrame.RightVector).Unit
local xAve = llAV:Cross(fRay.CFrame.RightVector).Unit
local calcableAngleThing = Vector3.new(uAve.X, 0, uAve.Z)
local calcableAngleThing2 = Vector3.new(xAve.X, 0, xAve.Z)
--print(math.deg(math.acos(calcableAngleThing:Dot(calcableAngleThing2))))
turn = turn - math.acos(calcableAngleThing:Dot(calcableAngleThing2))
--print(math.deg(turn))
if scal == 1 then
if turn + tSpeed.Value < math.rad(360) then --because radians, ugh...
turn = turn + tSpeed.Value
else
turn = math.rad(360) - (turn + tSpeed.Value)
end
elseif scal == -1 then
if turn - tSpeed.Value > 0 then
turn = turn - tSpeed.Value
else
turn = (turn - tSpeed.Value) + math.rad(360)
end
end
--backPerc changes
if turn > math.rad(180) then
backPerc = (math.rad(180) - (turn - math.rad(180)))/ math.rad(180)
else
backPerc = turn/math.rad(180)
end
local dAve = -uAve
local yDif = dAve.Y - uAve.Y
local fVec = Vector3.new(0,0,-1)
--rotate it with the angle of turn
local px = (uAve.X * math.cos(turn)) - (uAve.Z * math.sin(turn))
local pz = (uAve.Z * math.cos(turn)) + (uAve.X * math.sin(turn))
uAve = Vector3.new(px, (uAve.Y + (yDif * backPerc)), pz)
--change that, broth
gyro.CFrame = CFrame.new(physRoot.Position, (physRoot.Position + uAve))
end