Angle calculations

Hey , so I have this small script that detects what direction a car should turn to face an object.I am trying to figure out how to calculate the angle between the vehicle and the object so I can make the car rotate by itself to the point where it faces the object. If you have any ideas please let me know.Thanks!

local vehicleSeat = script.Parent.VehicleSeat
local main = script.Parent.Main
local target = game.Workspace.Target






if main.CFrame:ToObjectSpace(target.CFrame).Position.Z < 0 then
	print('Turn to the Right')
else if main.CFrame:ToObjectSpace(target.CFrame).Position.Z > 0 then
		print('Turn to the Left')
	end
end
2 Likes

Please check out this post (an old post of mine), I think it might be what you’re looking for: Best way to get the angle between two vectors? - #4 by ThanksRoBama

EDIT: Changing what’s in that post to fit your use case:

Transforming the target position to the cars object space is a good first step, although it might introduce issues if the car is rolled to the left or right, i.e. not all 4 wheels are touching the ground. Anyway, you can make it work like so:

local relativeTargetPosition = main.CFrame:PointToObjectSpace(target.Position)
local dotToTarget = relativeTargetPosition:Dot( Vector3.new(0, 0, -1) )
local angleToTarget = math.acos(dotToTarget)

This gets the angle to the target, but that’s not always going to be the same as the desired steering angle. Since steering can only turn the car in its local horizontal plane, we only care about the relative target position in the cars local horizontal plane:

local relativeTargetPosition = main.CFrame:PointToObjectSpace(target.Position)
local relativeHorizontalTargetPosition = relativeTargetPosition * Vector3.new(1, 0, 1)
local horizontalDotToTarget = relativeHorizontalTargetPosition:Dot( Vector3.new(0, 0, -1) )
local horizontalAngleToTarget = math.acos(horizontalDotToTarget)

I haven’t tested it, but I think that if you use that angle to set the steering of the car, it should work.

In this case, I would use the dot product to calculate the angle.

local Car = --Car Part
local Target = --Target Part

function GetAngle()
    return math.deg(math.acos(Car.CFrame.LookVector:Dot((Target.Position - Car.Position).Unit))) -- Since both are unit vectors, we won't divide it by each position vector's magnitude's multiplication.
end

Now, it’s time to calculate whether the target is on right or left of the car.

local Car = --Car Part
local Target = --Target Part

function FindDirection()
    local RightVector = Car.CFrame.RightVector
    local LeftVector = (Car.CFrame * CFrame.Angles(0, math.rad(180), 0)).RightVector
    if Target.CFrame.Position - RightVector > Target.CFrame.Position - LeftVector then
        print("Turn Left")
    else
        print("Turn Right")
    end
end

This code creates a virtual unit vector point on the left, right side of the car, and compares its magnitude to determine if the car should turn left or right.

If you have any points you don’t have a clear understanding of, let me know

1 Like