Scripting is awesome and powerful, the only painful part in it is how you are able to create one that is advanced through sophisticated and intricate thinking. Here’s an example of a camera bobbling effect script made by Roblox.
local RunService = game:GetService("RunService")
local playerModel = script.Parent
local humanoid = playerModel:WaitForChild("Humanoid")
local function updateBobbleEffect()
local now = tick()
if humanoid.MoveDirection.Magnitude > 0 then -- Is the character walking?
local velocity = humanoid.RootPart.Velocity
local bobble_X = math.cos(now * 9) / 5
local bobble_Y = math.abs(math.sin(now * 12)) / 5
local bobble = Vector3.new(bobble_X, bobble_Y, 0) * math.min(1, velocity.Magnitude / humanoid.WalkSpeed)
humanoid.CameraOffset = humanoid.CameraOffset:lerp(bobble, 0.25)
else
-- Scale down the CameraOffset so that it shifts back to its regular position.
humanoid.CameraOffset = humanoid.CameraOffset * 0.75
end
end
RunService.RenderStepped:Connect(updateBobbleEffect)
Yeah it seems complicated, but the part I am most attracted to is the function updateBobbleEffect()
. My question is, how did such scripters manage to know the math and science behind this to create a good bobbling effect?
Another great script I have discovered is AI bots which can be found in the Toolbox. The most interesting part in the script is the part where it computes the path. Although the general idea of computing one should be easy to understand, this script, however, is an exception:
while wait() do
local enemytorso = GetTorso(hroot.Position)
if enemytorso ~= nil then -- if player detected
isWandering = 1
local function checkw(t)
local ci = 3
if ci > #t then
ci = 3
end
if t[ci] == nil and ci < #t then
repeat
ci = ci + 1
wait()
until t[ci] ~= nil
return Vector3.new(1, 0, 0) + t[ci]
else
ci = 3
return t[ci]
end
end
path = pfs:FindPathAsync(hroot.Position, enemytorso.Position)
waypoint = path:GetWaypoints()
oldpoints = waypoint
local connection;
local direct = Vector3.FromNormalId(Enum.NormalId.Front)
local ncf = hroot.CFrame * CFrame.new(direct)
direct = ncf.p.unit
local rootr = Ray.new(hroot.Position, direct)
local phit, ppos = game.Workspace:FindPartOnRay(rootr, hroot)
if path and waypoint or checkw(waypoint) then
if checkw(waypoint) ~= nil and checkw(waypoint).Action == Enum.PathWaypointAction.Walk then
human:MoveTo( checkw(waypoint).Position )
human.Jump = false
end
-- CANNOT LET BALDI JUMPS --
--[[if checkw(waypoint) ~= nil and checkw(waypoint).Action == Enum.PathWaypointAction.Jump then
human.Jump = true
connection = human.Changed:connect(function()
human.Jump = true
end)
human:MoveTo( checkw(waypoint).Position )
else
human.Jump = false
end]]
--[[hroot.Touched:connect(function(p)
local bodypartnames = GetPlayersBodyParts(enemytorso)
if p:IsA'Part' and not p.Name == bodypartnames and phit and phit.Name ~= bodypartnames and phit:IsA'Part' and rootr:Distance(phit.Position) < 5 then
connection = human.Changed:connect(function()
human.Jump = true
end)
else
human.Jump = false
end
end)]]
if connection then
connection:Disconnect()
end
else
for i = 3, #oldpoints do
human:MoveTo( oldpoints[i].Position )
end
end
elseif enemytorso == nil and canWander then -- if player not detected
isWandering = 0
path = nil
waypoint = nil
human.MoveToFinished:Wait()
end
end
Look how complicated it is!
From the two scripts above, I think you should be able to get a general idea of what I am trying to ask:
How did these scripters manage to find the best and efficient yet advance solution of these problems?