Getting the direction a part is moving in?

To be simple I want my car to drift only if the direction it’s steering is not equal to the direction it’s moving. So it would only drift if the wheel is facing sideways relative to the steering direction of the car. It seems simple but I have been stuck on this for the past 2 hours and all I figured out was getting the steer direction.

Diagram of what I mean

I have tried multiple times but this is what I am at right now and still doesn’t work. The velocity is the direction relative to the world and not relative to the direction it’s moving in so doesn’t work in this scenario.

local SteerDirection = math.floor((steer * throttle) + 0.5)
local VelocityDirection = Center.Velocity.X

if SteerDirection ~= VelocityDirection then
		smokeBL.Enabled = true
		smokeBR.Enabled = true
	else
		smokeBL.Enabled = false
		smokeBR.Enabled = false
	end

Any help would be appreciated!

1 Like

If you compare your car’s CFrame.LookVector to its velocity, you can then get an idea of its relative direction. I’m not very good at vector math, so I’m just pulling from an old project that normalizes the direction vectors along a plane that is parallel to the ground, meaning the results are 2D, but this should be a good jumping-off point since, unless you need to be able to drift inside a loop or something.

local V3_101 = Vector3.new(1,0,1)

local center_direction = (center.CFrame.LookVector * V3_101).Unit
local velocity_direction = (center.AssemblyLinearVelocity * V3_101).Unit
local delta_angle = math.deg(math.acos(center_direction:Dot(velocity_direction)))
local relative_direction = center_direction:Cross(velocity_direction).Unit.Y

In this code, delta_angle will be the number of degrees away from the center’s forward vector the velocity is. This number will always be positive. If you need to know which direction the velocity is, that is where relative_direction comes in. It is supposed to be -1 for a clockwise angle and 1 for an anti-clockwise angle, but it’s susceptible to floating point errors, so you’re best off just comparing the signs.

Also, if you run this function while the vehicle is not moving at all, delta_angle and relative_direction will both be NaN, so make sure your code can handle that.

7 Likes

Thanks, I’ll try that and see if it will work.

Unfortunately, it didn’t work. I tried printing out the relative direction every second to check but just printed either -1 or -0.99999999999

Actually, nevermind! I got it to work the majority of the time by removing the V3_101. It does keep switching between drifting and not drifting when not moving?

If the left-right direction of the movement doesn’t matter, you can ignore relative_direction altogether, but if you do need it, it’s better to check if the value is less than or greater than 0. To prevent weird behavior, you can also add some additional limits, such as a minimum delta_angle or speed, like this:

local V3_101 = Vector3.new(1,0,1)
local MIN_ANGLE = 30
local MIN_SPEED = 15

if center.AssemblyLinearVelocity.Magnitude >= MIN_SPEED then
	local center_direction = (center.CFrame.LookVector * V3_101).Unit
	local velocity_direction = (center.AssemblyLinearVelocity * V3_101).Unit
	local delta_angle = math.deg(math.acos(center_direction:Dot(velocity_direction)))
	local relative_direction = center_direction:Cross(velocity_direction).Unit.Y

	if delta_angle >= MIN_ANGLE then
		smokeBL.Enabled = true
		smokeBR.Enabled = true
		if relative_direction > 0 then
			--Anti-clockwise, left
		else
			--Clockwise, right
		end
	else
		smokeBL.Enabled = false
		smokeBR.Enabled = false
	end
end

One last thing to mention is that because this code relies on the LookVector of center, that part needs to be aligned so that it faces the front of the vehicle, although you’ve probably already set it up that way, I would think.

1 Like