I’m working on creating a Mario Kart themed game, and I’m working on programming the hovercar, so you can drive around on sideways or upside-down grounds.
It’s working well enough, although I can’t get the car to turn on its local axis.
I’ve tried a few things, looked for similar posts on the DevForum, looked at CFrame and Vector3 on the Developer Hub, and even looked on a few other websites too. I’ve done all I can think of to do this, but I’ve never done anything specifically like this before so I have no examples to help me.
As said in the title, the car is set up with Body Movers. I have a single script called ‘Engine’ that runs the whole thing. In the car’s seat is a BodyGyro and BodyVelocity. My problem is with the BodyGyro, since it uses a global CFrame to function.
---- Body Mover Goals (section of setting physic variables)
local xv = velocity.Velocity.X
local yv = velocity.Velocity.Y
local zv = velocity.Velocity.Z
local xg = base.Orientation.X
local yg = base.Orientation.Y
local zg = base.Orientation.Z
local hoverTurn = function() -- This is the function for turning the car
yg = yg + turn -- This turns it on the global axis, when I want the local axis.
turn = turn*0.9
end
while wait() do
if not script.HoverWheels.Value then
--(Code for normal car)
else
-- Float
hoverFloat()
-- Accewhilellerate
hoverAccellerate()
-- Turn
hoverTurn() -- Here's the turn function
-- Gravity
hoverGravity()
-- Apply
velocity.Velocity = Vector3.new(xv, yv, zv)
gyro.CFrame = CFrame.new(gyro.CFrame.Position) * CFrame.Angles(math.rad(xg), math.rad(yg), math.rad(zg)) -- Apply physics for BodyGyro
end
This looks like it would probably work, but since that post is solving a different problem, and providing examples for your code, could you help explain where what lines go and all? It’s getting very confusing dealing with 3 problems right now in this game.
It could also be that I’m newer to Roblox Lua than you are.
Okay! So the code snippet given by sircfenner there lets you construct a CFrame given a forward vector (in this case the camera’s LookVector), an upwards pointing vector (the ground surface normal, which you can get from raycasts) and a right-pointing vector, which you just get by crossing the look and up vectors as shown there.
Here’s an example:
local camera = game.Workspace.CurrentCamera
local ray = Ray.new(cartChassis.Position,-cartChassis.CFrame.UpVector*32) -- Create a ray from the kart chassis that points downwards relative to the cart to check for ground. Shorter raycasts use less resources.
local hit,position,upVector,material = game.Workspace:FindPartOnRay(ray)
if upVector then -- Make sure there is a normal, and thus also ground.
local lookVector = camera.CFrame.LookVector
local rightVector = lookVector:Cross(upVector)
local gyroGoal = CFrame.new(
0, 0, 0
rightVector.x, upVector.x, -lookVector.x,
rightVector.y, upVector.y, -lookVector.y,
rightVector.z, upVector.z, -lookVector.z
) -- Credit to sircfenner for this!
cartChassis.Gyro.CFrame = gyroGoal
end
Of course, you can substitute the camera’s LookVector for the mouse’s pointing vector instead. If you want a better explanation, just say the word.
@Auhrii and @ADUPS, thanks for the help, but I must not have made the title specific enough. What I need help with is making the car turn (as if with a steering wheel) on the car’s local axis instead of the game’s.
The info you have already given me was good though, I used it and it is a lot better than what i had already!
Sadly, while using it I have encountered another problem other than the inability to turn the car. Now, when the car hits a wedge, it stops and does not turn to go up. I have tested in run mode with having the car above a wedge, then fall onto it, and it does change to the ground’s surface. So, at least we know it works and I typed it correctly.
So now I have to problems (which are pretty relative, if I figure out one I could probably do the other in a similar way) which I would like help with. More specifically, I need help with turning and moving the car on its local axis using a BodyGyro and BodyVelocity.
Here’s the updated hoverFloat function:
function hoverFloat()
local hoverFloat = function()
local ray = Ray.new(base.Position, -base.CFrame.UpVector*32)
local hit, position, upvector, material = workspace:FindPartOnRay(ray)
if upvector then
local lookvector = base.CFrame.LookVector
local rightvector = lookvector:Cross(upvector)
local gyroGoal = CFrame.new(
0, 0, 0,
rightvector.X, upvector.X, -lookvector.X,
rightvector.Y, upvector.Y, -lookvector.Y,
rightvector.Z, upvector.Z, -lookvector.Z
)
gyro.CFrame = gyroGoal
end
end
Ah, I see! There are functions you can use to convert a world space CFrame into an object space CFrame and vice-versa, as luck would have it! Check here, under Functions - specifically you’re probably after CFrame:ToObjectSpace and CFrame:ToWorldSpace (the latter to convert your object-aligned rotation to world CFrame for the BodyGyro):
I’m a little pressed for time right now, but if you need anything further, don’t hesitate to ask!