So! Im trying to make a tower defence game where bots smothly move across the track using bezier curves.. however.. this happens..
http://prntscr.com/l7bom5
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!