A game I’m working on involves the player having to cross the street to get to the objective. One way a player can die is by being run over by a car (I’m not sure if this is allowed on Roblox). The issue stems from the fact that the way the cars are scripted makes it so that they travel back and forth, continuously exiting and entering the main map. This makes the cars visually unpleasing and unnatural to look at for the players. Is there a way to make the car do a 180-degree turn before entering the map again so that it would look as if the car was being driven forward instead of backward? A short video regarding the issue is provided at the end of the paragraph.
I forgot to add the code for the car so here it is;
while true do
wait()
for i= 1, 250 do
script.Parent.CFrame = script.Parent.CFrame * CFrame.new(0,0,-2)
wait()
end
for i= 1, 250 do
script.Parent.CFrame = script.Parent.CFrame * CFrame.new(0,0,2)
wait()
end
end
local tService = game:GetService("TweenService")
local car = script.Parent:WaitForChild("Car") -- Location of you car
local p1 = script.Parent:WaitForChild("Point1") -- Location of your 1st part
local p2 = script.Parent:WaitForChild("Point2") -- Location of your 2nd part
local tween1 = tService:Create(car,TweenInfo.new(2),{Position = p2.Position})
local tween2 = tService:Create(car,TweenInfo.new(2),{Position = p1.Position})
tween1:Play()
tween1.Completed:Connect(function()
car.Orientation = Vector3.new(0,0,0)
tween2:Play()
end)
tween2.Completed:Connect(function()
car.Orientation = Vector3.new(0,-180,0)
tween1:Play()
end)
local tService = game:GetService("TweenService")
local car = script.Parent:WaitForChild("Moving brick") -- Location of you car
local p1 = script.Parent:WaitForChild("PointA") -- Location of your 1st part
local p2 = script.Parent:WaitForChild("PointB") -- Location of your 2nd part
local tween1 = tService:Create(car,TweenInfo.new(2),{Position = p2.Position})
local tween2 = tService:Create(car,TweenInfo.new(2),{Position = p1.Position})
tween1:Play()
tween1.Completed:Connect(function()
car.Orientation = Vector3.new(0,0,0)
tween2:Play()
end)
tween2.Completed:Connect(function()
car.Orientation = Vector3.new(0,-180,0)
tween1:Play()
end)
Instead of Handling the Cars using a for loop, you can use RunService to Determine the exact amount of Time that has passed, WIth this you can Interpolate the Car a Certain Amount of times and when it reaches a certain point, you can “change a state” to tell it to go back.
For Performance Purposes, I recommend handling this for ALL Vehicles with their own Respective Data, as Connecting Multiple of these Events can Potentially cause Lag due to how fast the run each second, but for this example, it will be based on a Single Model for Obvious Reasons.
local RunService = game:GetService("RunService")
-- The RunService Instance
-- Commonly used to Run Events within Frames
local Rotation = CFrame.Angles(0, math.pi, 0)
-- CFrames use Radians as a Unit of Measure for Rotations
-- math.pi with this logic would be exactly 180 degrees when converted
-- using math.rad() or the formula 'x(pi/180)'
local Model = script.Parent
-- This works by Interpolating the Model itself instead of a Part inside
-- of the Model
local BaseCFrame = Model:GetPivot() -- This is the Starting CFrame
local StepCFrame = CFrame.new(0,0, 500) -- This is your Expected Position
-- Your for loop is iterating 250 times
-- your CFrame steps 2 times i the Z Axis when this happens
-- 250 * 2 is 500
-- Expected Time to Reach this Point: 2.5 Seconds
-- Feel free to Modify these to your Liking
local WillReverse = false -- TO Check if we should Reverse the Value
local alpha = 0 -- This is to keep track of how much we want to interpolate
local duration = 2.5 -- the time that it takes to complete the action
RunService.Heartbeat:Connect(function(deltaTime)
alpha = math.min(1, alpha + (deltaTime/duration))
-- I'll Explain the math here
-- math.min is used to set a limit to the Current Value we have
-- so it does not go over 1, because Interpolation works by
-- setting a position within a Time Frame (0 to 1)
-- DeltaTime means "The Difference in Time" or in this case Frames
-- DeltaTime/Duration has the Value move within that duration
local FowardInterpolation = BaseCFrame:Lerp(StepCFrame, alpha) -- The Foward Interpolation (Going Foward)
local ReverseInterpolation = StepCFrame:Lerp(BaseCFrame, alpha) -- The Reserve Interpolation (Going Back)
local Current = if not WillReverse then -- This will Determine which method will be chosen if 'WillReserve' is set
FowardInterpolation * Rotation -- a Still Touch of Rotation
else
ReverseInterpolation
-- if these arent going to the Right way you want them too
-- you can always modify the Values, or Swap these values
Model:PivotTo(Current) -- Moves the Model based off of Interpolated Points
if alpha == 1 then -- if the time frame is exactly 1 (meaning 2.5 Seconds has passed)
WillReverse = not WillReverse
-- if this value is false, it will become true,and vice versa
alpha = 0 -- Resets the Timer this time going in Reverse
end
print(alpha, WillReverse) -- for Debugging Purposes, Feel free to remove this
end)