This is my third time talking about NPC kart issues. Because the last two threads I posted had been neglected without any reply. Anyway, back onto main topic.
Before this and the two other threads existed, I had been thinking about kart with AI feature for it and had researched by looking for some useful threads on DevForum page, but only found very few of them (the people from there mostly marked Roblox’s built-in pathfinding, which is only for humanoid, as solutions for the whole NPC kart) and yet they weren’t good for my taste.
A while later, I stumbled upon this video on YouTube and made up main tasks for NPC kart. They would be:
- Always set its Throttle value to 1 (forward)
- Force it to drive on first node point of track then check next node by using magnitude (depends on kart’s top speed)
- Use signed angle to check angles between kart and current node points, while it depends on kart’s facing direction. If angle is positive, its Steer value will be set to -1 (left) and vice versa
These tasks did good job for NPC kart, but then I realized that it did not reach the goal like what I saw from that video I showed above. Here’s the only problem: Its steering behavior always turned left and right, and barely drove straight (sometimes got stuck when hit wall), which caused unnatural driving
local function GetHeadingToPoint(point) local cframe = DriveSeat.CFrame - DriveSeat.Position + Vehicle.PrimaryPart.Position return cframe:PointToObjectSpace(point) end --Middle of update section if currentNode then --print("Go") while IsAlive() do task.wait(Rate) local heading = GetHeadingToPoint(currentNode.Position) if heading.Magnitude > GetMaxSpeed() / 2 then local dirToMovePosition = (Vehicle.PrimaryPart.Position - currentNode.Position).Unit local angleToDir = Math.SignedAngle(Vehicle.PrimaryPart.CFrame.LookVector.Unit, dirToMovePosition, Vector3.FromNormalId(Enum.NormalId.Top)) --print(angleToDir) --[[if angleToDir > 0 then DriveSeat.SteerFloat = 1 else DriveSeat.SteerFloat = -1 end]] --[[if angleToDir > 5 then DriveSeat.SteerFloat = 1 elseif angleToDir < -5 then DriveSeat.SteerFloat = -1 else riveSeat.SteerFloat = 0 end]] heading = GetHeadingToPoint(currentNode.Position) if heading.Unit.Z < -0.25 then if math.abs(math.deg(math.atan2(heading.X, -heading.Z))) > 5 then DriveSeat.SteerFloat = -math.sign(heading.Z) * math.deg(math.atan2(heading.X, -heading.Z)) else DriveSeat.SteerFloat = 0 end else if angleToDir > 0 then DriveSeat.SteerFloat = 1 else DriveSeat.SteerFloat = -1 end end else break end end end --
local Movement = Vector2.new() Main.DriveSeat.Changed:Connect(function(property) if property == "Steer" then Movement = Vector2.new(Main.DriveSeat.Steer, Movement.Y) elseif property == "Throttle" then Movement = Vector2.new(Movement.X, Main.DriveSeat.Throttle) end end) local Rotate = 0 local function Steer(direction, amount) Rotate = (MaxSpeed.Turn.Value * direction) * amount end --Middle of update section if Movement.X ~= 0 then local dir = Movement.X > 0 and (Values.IsCursed.Value and 1 or -1) or (Values.IsCursed.Value and -1 or 1) local amount = math.abs(Movement.X) Steer(dir, amount) end --if not (Values.IsStunned.Value or Values.IsFlying.Value or Finished.Value) and IsGoing.Value then BodyAngularVelocity.AngularVelocity = Vector3.new(0, CurrentSpeed.Turn, 0) CurrentSpeed.Turn = Math.Lerp(CurrentSpeed.Turn, Rotate * (CurrentSpeed.Movement < 0 and -1 or 1) * (not hit and Stats.TurnSpeed.AerialTurnFactor.Value or 1), dt * Stats.TurnSpeed.TurnTorque.Value) Rotate = 0 --end --
To be summarized, comparing my NPC kart to the one from YouTube video, it has unnatural steering behavior. And if you guys understand what topic says, what alternate methods to improve NPC kart’s steering?
p/s: I used BodyAngularVelocity to make it steer, with these following properties:
- MaxTorque: Vector3.new(0, math.huge, 0)
- P: 3000