So I am trying to make it so that when you press Y then the trailer will unhook and when you are close to the trailer and it is detached then if you press Y then it will attach the trailer. The script is a server script inside of the semi truck. There are no errors.
Code
local IsDetached = false
local trailer = script.Parent.Parent.Trailer
local Body = script.Parent.Parent.Body
local TrailerHook = Body["Meshes/Semitruck1_hitch"]
local Detector = script.Parent.Parent.Chassis.Detector
local Main = trailer.Chassis.Main
trailer.PrimaryPart = Main
script.Parent.Parent.Chassis.VehicleSeat.Touched:Connect(function(hit)
if hit.Parent:FindFirstChild("Humanoid") then
local UserInputService = game:GetService("UserInputService")
UserInputService.InputBegan:Connect(function(input)
if input.KeyCode == Enum.KeyCode.Y then
if IsDetached == false then
trailer:SetPrimaryPartCFrame(TrailerHook.Cframe * CFrame.new(0, -0.016, -15))
IsDetached = true
elseif IsDetached == true then
Detector.Touched:Connect(function(hit)
if hit == Main then
trailer:SetPrimaryPartCFrame(TrailerHook.Cframe * CFrame.new(0, -0.016, 0))
IsDetached = false
end
end)
end
elseif input.KeyCode == Enum.KeyCode.ButtonY then
if IsDetached == false then
trailer:SetPrimaryPartCFrame(TrailerHook.Cframe * CFrame.new(0, -0.016, -15))
IsDetached = true
elseif IsDetached == true then
Detector.Touched:Connect(function(hit)
if hit == Main then
trailer:SetPrimaryPartCFrame(TrailerHook.Cframe * CFrame.new(0, -0.016, 0))
IsDetached = false
end
end)
end
end
end)
end
end)
Updated Code
Server Script:
local Workspace = game:GetService("Workspace")
local RunService = game:GetService("RunService")
local UserInputService = game:GetService("UserInputService")
local PackagedScripts = script.Parent
local PackagedVehicle = PackagedScripts.Parent
local constraints = PackagedVehicle:WaitForChild("Constraints")
local VehicleConfig = PackagedVehicle:WaitForChild("Configuration", 10)
if not VehicleConfig then
warn("No vehicle configuration present, will use default values")
end
local mphConversion = 0.6263 -- using a 28cm = 1stud conversion rate
-- local kphConversion = 1.008 -- using the same conversion rate, but if you prefer KPH, replace mphConversion with kphConversion wherever it appears in the code
--[[ Chassis Variables ]]--
local VehicleParameters = { -- These are default values in the case the package structure is broken
MaxSpeed = 75/mphConversion,
ReverseSpeed = 45/mphConversion,
DrivingTorque = 30000,
BrakingTorque = 70000,
StrutSpringStiffnessFront = 28000,
StrutSpringDampingFront = 1430,
StrutSpringStiffnessRear = 27000,
StrutSpringDampingRear = 1400,
TorsionSpringStiffness = 20000,
TorsionSpringDamping = 150,
MaxSteer = 0.55,
WheelFriction = 2
}
local Chassis = nil
local LimitSteerAtHighVel = true
-- Limits the amount you can steer based on velocity. Helpful for keyboard/non-analog steer inputs
local SteerLimit = 0.2 -- Max amount the steering float (-1 to 1) will be limited by if limitSteerAtHighVel is true
local DoGravityAdjust = true -- Adjust chassis values based on the current gravity setting.
local ActualDrivingTorque
local ActualBrakingTorque
local ActualStrutSpringStiffnessFront
local ActualStrutSpringDampingFront
local ActualStrutSpringStiffnessRear
local ActualStrutSpringDampingRear
local ActualTorsionSpringStiffness
local ActualTorsionSpringDamping
-- Adjust torque and springs based on gravity to keep the car drivable
local function gravityAdjust()
local defaultGravity = 196.2
local actualGravity = Workspace.Gravity
local gravityChange = actualGravity / defaultGravity
-- Speed is adjusted so that the height of jumps is preserved
-- So maxSpeed is scaled proportionally to the sqrt of gravity
ActualDrivingTorque = VehicleParameters.DrivingTorque * gravityChange
ActualBrakingTorque = VehicleParameters.BrakingTorque * gravityChange
ActualStrutSpringStiffnessFront = VehicleParameters.StrutSpringStiffnessFront * gravityChange
ActualStrutSpringDampingFront = VehicleParameters.StrutSpringDampingFront * math.sqrt( gravityChange )
ActualStrutSpringStiffnessRear = VehicleParameters.StrutSpringStiffnessRear * gravityChange
ActualStrutSpringDampingRear = VehicleParameters.StrutSpringDampingRear * math.sqrt( gravityChange )
ActualTorsionSpringStiffness = VehicleParameters.TorsionSpringStiffness * gravityChange
ActualTorsionSpringDamping = VehicleParameters.TorsionSpringDamping * math.sqrt( gravityChange )
end
local function updateFromConfiguration()
for property, value in pairs(VehicleParameters) do
local configProp = VehicleConfig:FindFirstChild(property)
if configProp then
if property == "MaxSpeed" or property == "ReverseSpeed" then
VehicleParameters[property] = configProp.Value/mphConversion -- convert to studs/sec
else
VehicleParameters[property] = configProp.Value
end
end
end
end
local updateEvents
if VehicleConfig then
updateFromConfiguration()
updateEvents = {}
local props = VehicleConfig:GetChildren()
for i = 1, #props do
updateEvents[props[i].Name] = props[i].Changed:connect(function(value)
VehicleParameters[props[i].Name] = value
if DoGravityAdjust then
gravityAdjust()
end
if Chassis then
Chassis.InitializeDrivingValues() -- reinitialize chassis so that changes are reflected in the rig
end
end)
end
end
if DoGravityAdjust then
gravityAdjust()
end
workspace.Changed:Connect(function(prop)
if prop == "Gravity" then
if DoGravityAdjust then
gravityAdjust()
end
if Chassis then
Chassis.InitializeDrivingValues() -- reinitialize chassis so that changes are reflected in the rig
end
end
end)
local Motors
local SteeringPrismatic
local RedressMount
--[[ Private Functions ]]--
local function getVehicleMotors()
local motors = {}
for _, c in pairs(constraints:GetChildren()) do
if c:IsA("CylindricalConstraint") then
table.insert(motors, c)
end
end
return motors
end
local function getSprings(springType)
local springs = {}
local trailer = PackagedVehicle:FindFirstChild("Trailer")
local function search(children)
local searchStrutSpring = "StrutSpring"
local searchFrontSpring = "StrutSpringF"
local searchTorsionSpring = "TorsionBarSpring"
for _, c in pairs(children) do
if c:IsA("SpringConstraint") then
if springType == "StrutFront" then
if string.find(c.Name, searchFrontSpring) then
table.insert(springs, c)
end
elseif springType == "StrutRear" then
if (not string.find(c.Name, searchFrontSpring)) and string.find(c.Name, searchStrutSpring) then
table.insert(springs, c) -- we have option of Mid and Rear for these
end
elseif springType == "TorsionBar" then
if string.find(c.Name, searchTorsionSpring) then
table.insert(springs, c)
end
end
end
end
end
search(constraints:GetChildren())
if trailer then
trailer.Body["Meshes/Trailer1_Trailer1.010"].Touched:Connect(function(hit)
if hit.Parent == trailer.Parent.Body["Meshes/Semitruck1_hitch"] then
UserInputService.InputBegan:Connect(function(key)
if not key.KeyCode == Enum.KeyCode.Y then
search(trailer.Constraints:GetChildren())
end
end)
end
end)
end
return springs
end
local function getMotorVelocity(motor)
return motor.Attachment1.WorldAxis:Dot( motor.Attachment1.Parent.RotVelocity )
end
local function adjustSpring( spring, stiffness, damping )
spring.Stiffness = stiffness
spring.Damping = damping
end
local function setMotorTorque(torque)
for _, motor in pairs(Motors) do
motor.MotorMaxTorque = torque
end
end
local function setMotorTorqueDamped(torque, velocityDirection, accelDirection)
for _, motor in pairs(Motors) do
if VehicleParameters.MaxSpeed == 0 then
motor.MotorMaxTorque = 0
else
local maxSpeed = VehicleParameters.MaxSpeed
if accelDirection < 0 and velocityDirection < 0 then
maxSpeed = VehicleParameters.ReverseSpeed
end
local r = math.abs(Chassis.driverSeat.Velocity.Magnitude / maxSpeed)
motor.MotorMaxTorque = math.exp( -3 * r * r ) * torque
end
end
end
local function setMotorMaxAcceleration(acceleration)
for _, motor in pairs(Motors) do
motor.MotorMaxAngularAcceleration = acceleration
end
end
--[[ Module Functions ]]--
Chassis = {}
Chassis.root = PackagedVehicle:FindFirstChild("Chassis") --the root of the Chassis model
Chassis.driverSeat = Chassis.root:FindFirstChildOfClass("VehicleSeat")
Chassis.passengerSeats = {
Chassis.root:FindFirstChild("SeatFR"),
Chassis.root:FindFirstChild("SeatRL"),
Chassis.root:FindFirstChild("SeatRR")
}
local randomSuspension = Chassis.root:FindFirstChild("SuspensionFL")
local wheelRadius = randomSuspension.Wheel.Size.y/2
Chassis.driverSeat.MaxSpeed = VehicleParameters.MaxSpeed * wheelRadius
function Chassis.InitializeDrivingValues()
-- Constraint tables always ordered FL, FR, RL, RR
Motors = getVehicleMotors()
local strutSpringsFront = getSprings("StrutFront")
local strutSpringsRear = getSprings("StrutRear")
local torsionSprings = getSprings("TorsionBar")
RedressMount = Chassis.root:WaitForChild("RedressMount")
SteeringPrismatic = constraints:FindFirstChild("SteeringPrismatic")
SteeringPrismatic.UpperLimit = VehicleParameters.MaxSteer
SteeringPrismatic.LowerLimit = -VehicleParameters.MaxSteer
for _,s in pairs(strutSpringsFront) do
adjustSpring(s, ActualStrutSpringStiffnessFront, ActualStrutSpringDampingFront)
end
for _,s in pairs(strutSpringsRear) do
adjustSpring(s, ActualStrutSpringStiffnessRear, ActualStrutSpringDampingRear)
end
for _,s in pairs(torsionSprings) do
adjustSpring(s, ActualTorsionSpringStiffness, ActualTorsionSpringDamping)
end
local chassisChildren = Chassis.root:GetChildren()
for i = 1, #chassisChildren do
local model = chassisChildren[i]
if model:IsA("Model") then
local wheel = model:FindFirstChild("Wheel")
if wheel then
local old = wheel.CustomPhysicalProperties
local new = PhysicalProperties.new(old.Density, VehicleParameters.WheelFriction, old.Elasticity, old.FrictionWeight, old.ElasticityWeight)
wheel.CustomPhysicalProperties = new
end
end
end
setMotorTorque(10000)
end
function Chassis.GetDriverSeat()
return Chassis.driverSeat
end
function Chassis.GetPassengerSeats()
return Chassis.passengerSeats
end
function Chassis.GetBase()
return Chassis.root.PrimaryPart or Chassis.root:FindFirstChild("FloorPanel")
end
--Set target angular velocity for all 4 wheels.
function Chassis.SetMotorVelocity(vel)
for _, motor in pairs(Motors) do
motor.AngularVelocity = vel
end
end
--Get average angular velocity from all 4 wheels
function Chassis.GetAverageVelocity()
local t = 0
for _, motor in pairs(Motors) do
t = t + getMotorVelocity(motor)
end
return t * (1/#Motors)
end
--Set braking torque and stop back 2 wheels
function Chassis.EnableHandbrake()
setMotorMaxAcceleration(math.huge)
Motors[3].MotorMaxTorque = ActualBrakingTorque
Motors[4].MotorMaxTorque = ActualBrakingTorque
Motors[3].AngularVelocity = 0
Motors[4].AngularVelocity = 0
end
--Set target steering position based on current velocity
function Chassis.UpdateSteering(steer, currentVel)
local baseSteer = steer
local targetSteer = 0
local vehicleSeat = Chassis.GetDriverSeat()
local maxSpeed = VehicleParameters.MaxSpeed
local maxSteer = VehicleParameters.MaxSteer
local currentVelocity = vehicleSeat.Velocity
if LimitSteerAtHighVel then
local c = SteerLimit * (math.abs(currentVel)/VehicleParameters.MaxSpeed) + 1
--decrease steer value as speed increases to prevent tipping (handbrake cancels this)
steer = steer/c
end
SteeringPrismatic.TargetPosition = steer * steer * steer * maxSteer
end
function Chassis.UpdateThrottle(currentVel, throttle)
local targetVel = 0
if math.abs(throttle) < 0.1 then
-- Idling
setMotorMaxAcceleration(math.huge)
setMotorTorque(2000)
elseif math.sign(throttle * currentVel) > 0 or math.abs(currentVel) < 0.5 then
setMotorMaxAcceleration(math.huge)
local velocityVector = Chassis.driverSeat.Velocity.Unit
local directionalVector = Chassis.driverSeat.CFrame.lookVector
local dotProd = velocityVector:Dot(directionalVector) -- Dot product is a measure of how similar two vectors are; if they're facing the same direction, it is 1, if they are facing opposite directions, it is -1, if perpendicular, it is 0
setMotorTorqueDamped(ActualDrivingTorque * throttle * throttle, dotProd, math.sign(throttle))
-- Arbitrary large number
local movingBackwards = dotProd < 0
local acceleratingBackwards = throttle < 0
local useReverse = (movingBackwards and acceleratingBackwards)
targetVel = math.sign(throttle) * (useReverse and VehicleParameters.ReverseSpeed or VehicleParameters.MaxSpeed)
else
-- Braking
setMotorMaxAcceleration(100)
setMotorTorque(ActualBrakingTorque * throttle * throttle)
targetVel = math.sign(throttle) * 500
end
Chassis.SetMotorVelocity( targetVel )
end
local redressingState = false
local targetAttachment
function Chassis.Redress()
if redressingState then
return
end
redressingState = true
local p = Chassis.driverSeat.CFrame.Position + Vector3.new( 0,10,0 )
local xc = Chassis.driverSeat.CFrame.RightVector
xc = Vector3.new(xc.x,0,xc.z)
xc = xc.Unit
local yc = Vector3.new(0,1,0)
if not targetAttachment then
targetAttachment = RedressMount.RedressTarget
end
targetAttachment.Parent = Workspace.Terrain
targetAttachment.Position = p
targetAttachment.Axis = xc
targetAttachment.SecondaryAxis = yc
RedressMount.RedressOrientation.Enabled = true
RedressMount.RedressPosition.Enabled = true
wait(1.5)
RedressMount.RedressOrientation.Enabled = false
RedressMount.RedressPosition.Enabled = false
targetAttachment.Parent = RedressMount
wait(2)
redressingState = false
end
function Chassis.Reset() --Reset user inputs and redress (For when a player exits the vehicle)
Chassis.UpdateThrottle(1, 1) --Values must be changed to replicate to client.
Chassis.UpdateSteering(1, 0) --i.e. setting vel to 0 when it is 0 wont update to clients
Chassis.EnableHandbrake()
setMotorTorque(ActualBrakingTorque)
Chassis.SetMotorVelocity(0)
Chassis.UpdateSteering(0, 0)
RedressMount.RedressOrientation.Enabled = true
RedressMount.RedressPosition.Enabled = true
RedressMount.RedressOrientation.Enabled = false
RedressMount.RedressPosition.Enabled = false
redressingState = false
end
return Chassis
second Server Script:
local IsDetached = false
local trailer = script.Parent.Parent.Trailer
local Body = script.Parent.Parent.Body
local TrailerHook = Body["Meshes/Semitruck1_hitch"]
local Detector = script.Parent.Parent.Chassis.Detector
local Main = trailer.Chassis.Main
local ComputerEvent = script.Parent.FireSever.DetachAttachTrailerComputer
local XboxOneEvent = script.Parent.FireSever.DetachAttachTrailerXboxOne
trailer.PrimaryPart = Main
ComputerEvent.OnServerEvent:Connect(function()
if IsDetached == false then
trailer:SetPrimaryPartCFrame(TrailerHook.Cframe * CFrame.new(0, -0.016, -15))
print("Should be detached...")
IsDetached = true
elseif IsDetached == true then
Detector.Touched:Connect(function(hit)
if hit == Main then
trailer:SetPrimaryPartCFrame(TrailerHook.Cframe * CFrame.new(0, -0.016, 0))
IsDetached = false
end
end)
end
end)
XboxOneEvent.OnServerEvent:Connect(function()
if IsDetached == false then
trailer:SetPrimaryPartCFrame(TrailerHook.Cframe * CFrame.new(0, -0.016, -15))
IsDetached = true
elseif IsDetached == true then
Detector.Touched:Connect(function(hit)
if hit == Main then
trailer:SetPrimaryPartCFrame(TrailerHook.Cframe * CFrame.new(0, -0.016, 0))
IsDetached = false
end
end)
end
end)
Local Script:
script.Parent.Parent.DriverDetecter.Touched:Connect(function(hit)
if hit.Parent:FindFirstChild("Humanoid") then
local UserInputService = game:GetService("UserInputService")
UserInputService.InputBegan:Connect(function(input)
if input.KeyCode == Enum.KeyCode.Y then
script.DetachAttachTrailerComputer:FireServer()
print("Should be working...")
elseif input.KeyCode == Enum.KeyCode.ButtonY then
script.DetachAttachTrailerXboxOne:FireServer()
end
end)
end
end)
Help would be much appreciated.