So! Im trying to make a tower defence game where bots smothly move across the track using bezier curves.. however.. this happens..
It creates 2 tracks for some reason and the enemys go on the track witch does not curve.. Why i this?
Here is my scripts that control this!
Script 1:
-- Starts the track and makes the course.
local lod = 105
local course = require(game.ReplicatedStorage.Modules.OtherStuff.Course)
local events = game.ReplicatedStorage.Events
local signal = events:WaitForChild("Signal")
local nodes = course:spawnNodes(workspace.Course,lod)
Script 2:
-- Spawns nodes into the game.
function course:spawnNodes(t,l)
local bezier = require(game.ReplicatedStorage.Modules.OtherStuff.Bezier)
local nodes = {}
for _,n in pairs(t.Paths:GetChildren()) do
nodes[tonumber(n.Name)] = n
end
for i,n in pairs(nodes) do
if nodes[i+1] and nodes[i+2] and (tonumber(n.Name)) ~= 0 then
local pda = Vector3.new(0,game.ReplicatedStorage.Assets.Enemies.Regular.Position.Y-n.Position.Y,0)
local z,z1,z2 = n.Position+pda,nodes[i+1].Position+pda,nodes[i+2].Position+pda
nodes[i]=bezier:curve(z,z1,z2,l,true,n) -- This creates the curve.
end
end
return nodes
end
Bezier Script
-- Somehow this get run twice and creates two lines and the bot does not go on the right track.
local bezier = {__type="Bezier"}
function GetCorners(part)
local corners = {}
for x= -1,1,2 do
for y= -1,1,2 do
for z= -1,1,2 do
corners[#corners+1] = part.CFrame:pointToWorldSpace(Vector3.new(part.Size.X/2*x,part.Size.Y/2*y,part.Size.Z/2*z))
end
end
end
return corners
end
function getTopCorner(p)
local c = GetCorners(p)
local tc = CFrame.new((c[3].x+c[8].x)/2,(c[3].y+c[8].y)/2,(c[3].z+c[8].z)/2)*CFrame.Angles(math.rad(p.Rotation.X),math.rad(p.Rotation.Y),math.rad(p.Rotation.Z))
return c,tc
end
function line3D(o,o2,n,p)
local surfaces = {
"BackSurface",
"FrontSurface",
"RightSurface",
"LeftSurface",
"TopSurface",
"BottomSurface"
}
local mag = (o-o2).magnitude
local l = Instance.new("Part")
if n then
l.Name = n
else
l.Name = "Line3D"
end
l.Material = Enum.Material.DiamondPlate
l.BrickColor = BrickColor.new("Bright green")
l.Anchored = true
l.Locked = true
l.Size = Vector3.new(0.3,0.3,mag)
l.CFrame = CFrame.new(o,o2)*CFrame.new(0,0,-mag/2)
for n,d in pairs(surfaces) do
l[d] = Enum.SurfaceType.SmoothNoOutlines
end
l.Parent = p
return l
end
function bezier:curve(x,y,z,l,d,pa)
local lastPoint
local points = {}
for t= 0,1,1/l do
local p = (1-t)^2*x+2*(1-t)*t*y+t^2*z
if (lastPoint and d~= false)then
local v = line3D(lastPoint,p,"line",pa)
local c,tc = getTopCorner(v)
points[#points+1] = tc
elseif lastPoint and not d then
local v = line3D(lastPoint,p,"line",pa)
local c,tc = getTopCorner(v)
v:Destroy()
points[#points+1] = tc
end
lastPoint=p
end
return points
end
return bezier
Bot Script:
-- Controls the enemies.
local self = {}
local ai = {}
function self:StartEnemy(source, enemy, bl)
local stats = require(game.ReplicatedStorage.Modules.Types.EnemyStats)
stats = stats[enemy]
local st = {paused=false,destroyed=false,body=nil}
local obj = game.ReplicatedStorage.Assets.Enemies[enemy]:Clone()
obj.CFrame = bl.Parent.Other:WaitForChild("StartPath").CFrame
obj.Parent = bl
st.body = obj
ai[obj] = st
spawn(function()
for i=1,#source,1 do
if i%2 ~= 0 and ai[obj] ~= nil and not source[i].ClassName then
for n,v in pairs(source[i]) do
if ai[obj] ~= nil then
local scf = obj.CFrame
for j=0,1,stats.Speed*0.005 do
obj.CFrame = scf:lerp(v,j)
wait(0.01)
end
end
end
else
break
end
end
end)
end
function self:EndLife(enemy)
ai[enemy].destroyed = true
ai[enemy].body:Destroy()
ai[enemy] = nil
end
return self
Start Script:
-- This starts the bot.
enemyai:StartEnemy(nodes, "Regular", workspace.Course.Enemies)
I have sat trying to fix this for 4 hours.. I have no idea whats wrong with it. If you know whats wrong please let me know! Thanks!
