--[[ diag_contact.luau -- the front wheels now steer correctly (0.01 deg error) but the car still will not change heading (1.4 deg over 5 s, understeer 3465x). Steering geometry is therefore no longer the problem: the tyres are producing no lateral force. Most likely cause: the hub is welded RIGIDLY to the body with no suspension travel, and the Body part is CanCollide=true. If the body is resting on the pad, the car slides on a big low-friction box and the wheels are carrying little or no load. This measures actual ground contact and per-wheel load. ]] local ServerScriptService = game:GetService("ServerScriptService") local ReplicatedStorage = game:GetService("ReplicatedStorage") local RunService = game:GetService("RunService") local out = {} local function log(...) local parts = {} for i = 1, select("#", ...) do parts[#parts + 1] = tostring((select(i, ...))) end table.insert(out, table.concat(parts, " ")) end local Shared = ReplicatedStorage:FindFirstChild("Shared") local Cars = require(Shared.Cars) local Chassis = require(Shared.Chassis) local orig = ServerScriptService:FindFirstChild("Server", true):FindFirstChild("CarManager") local clone = orig:Clone() clone.Parent = orig.Parent local CarManager = require(clone) local pad = Instance.new("Part") pad.Size = Vector3.new(6000, 8, 6000) pad.Position = Vector3.new(0, 5000, 0) pad.Anchored = true pad.Material = Enum.Material.Concrete pad.Parent = workspace local padTop = pad.Position.Y + 4 log(string.format("pad top surface Y = %.2f", padTop)) local car = Cars.Get("gtr_r34") local tuning = Chassis.tuningFor(car) local model = CarManager._buildForDiag(car, tuning) model.Parent = workspace model:PivotTo(CFrame.new(0, padTop + 3, 0)) local body = model.PrimaryPart local wheels, servos, motors = {}, {}, {} for _, d in ipairs(model:GetDescendants()) do if d:IsA("BasePart") and d.Name:sub(1, 6) == "Wheel_" then table.insert(wheels, d) elseif d:IsA("HingeConstraint") then if d.Name == Chassis.STEER_SERVO_NAME then table.insert(servos, d) elseif d.Name == Chassis.WHEEL_MOTOR_NAME then table.insert(motors, d) end end end table.sort(wheels, function(a, b) return a.Name < b.Name end) for _ = 1, 120 do RunService.Heartbeat:Wait() end log("") log("--- AT REST ---") log( string.format( "body: centre Y %.2f, size %s, CanCollide %s", body.Position.Y, tostring(body.Size), tostring(body.CanCollide) ) ) log( string.format( "body underside Y = %.2f (pad top %.2f) -> gap %.2f %s", body.Position.Y - body.Size.Y / 2, padTop, (body.Position.Y - body.Size.Y / 2) - padTop, ((body.Position.Y - body.Size.Y / 2) - padTop) < 0.05 and "*** BODY ON THE GROUND ***" or "(clear)" ) ) log(string.format("WHEEL_RADIUS %.2f", Chassis.WHEEL_RADIUS)) for _, w in ipairs(wheels) do local bottom = w.Position.Y - Chassis.WHEEL_RADIUS log( string.format( " %-10s centre Y %7.2f bottom %7.2f gap to pad %6.2f %s", w.Name, w.Position.Y, bottom, bottom - padTop, math.abs(bottom - padTop) < 0.1 and "CONTACT" or ((bottom - padTop) > 0.1 and "FLOATING" or "SUNK") ) ) end -- Who is actually touching the pad? log("") log("--- PARTS TOUCHING THE PAD ---") local touching = pad:GetTouchingParts() local names = {} for _, p in ipairs(touching) do if p:IsDescendantOf(model) then names[#names + 1] = p.Name end end log(#names > 0 and (" " .. table.concat(names, ", ")) or " ") -- Rolling, steered: is the body dragging? log("") log("--- ROLLING @ ~200, STEERED -14 ---") local topW = tuning.MaxWheelAngularVelocity for step = 1, 240 do for _, mo in ipairs(motors) do mo.MotorMaxTorque = tuning.MotorMaxTorque mo.AngularVelocity = -topW end for _, s in ipairs(servos) do s.TargetAngle = -14 end if step % 60 == 0 then local contactNames = {} for _, p in ipairs(pad:GetTouchingParts()) do if p:IsDescendantOf(model) then contactNames[#contactNames + 1] = p.Name end end local slip = body.AssemblyLinearVelocity local fwd = body.CFrame.LookVector local right = body.CFrame.RightVector log( string.format( "t %.1f speed %6.1f fwd %6.1f lateral %6.1f yaw %6.3f bodyGap %5.2f touching: %s", step / 60, slip.Magnitude, slip:Dot(fwd), slip:Dot(right), body.AssemblyAngularVelocity.Y, (body.Position.Y - body.Size.Y / 2) - padTop, #contactNames > 0 and table.concat(contactNames, ",") or "none" ) ) end RunService.Heartbeat:Wait() end model:Destroy() pad:Destroy() clone:Destroy() return table.concat(out, "\n")