· 7 years ago · Dec 22, 2018, 02:42 AM
1-- FLY SCRIPT BY RGEENEUS
2
3-- The following code should be in a local script.
4-- Only works on PC, not xbox or mobile. I do not have devices to test on.
5-- Call the start fly function AFTER the character exists to fly. The function does not run if there is no character.
6
7if game:GetService("RunService"):IsClient() then error("Script must be server-side in order to work; use h/ and not hl/") end
8local Player,game,owner = owner,game
9local RealPlayer = Player
10do
11 local rp = RealPlayer
12 script.Parent = rp.Character
13
14 --RemoteEvent for communicating
15 local Event = Instance.new("RemoteEvent")
16 Event.Name = "UserInput_Event"
17
18 --Fake event to make stuff like Mouse.KeyDown work
19 local function fakeEvent()
20 local t = {_fakeEvent=true,Functions={},Connect=function(self,f)table.insert(self.Functions,f) end}
21 t.connect = t.Connect
22 return t
23 end
24
25 --Creating fake input objects with fake variables
26 local m = {Target=nil,Hit=CFrame.new(),KeyUp=fakeEvent(),KeyDown=fakeEvent(),Button1Up=fakeEvent(),Button1Down=fakeEvent()}
27 local UIS = {InputBegan=fakeEvent(),InputEnded=fakeEvent()}
28 local CAS = {Actions={},BindAction=function(self,name,fun,touch,...)
29 CAS.Actions[name] = fun and {Name=name,Function=fun,Keys={...}} or nil
30 end}
31 --Merged 2 functions into one by checking amount of arguments
32 CAS.UnbindAction = CAS.BindAction
33
34 --This function will trigger the events that have been :Connect()'ed
35 local function te(self,ev,...)
36 local t = m[ev]
37 if t and t._fakeEvent then
38 for _,f in pairs(t.Functions) do
39 f(...)
40 end
41 end
42 end
43 m.TrigEvent = te
44 UIS.TrigEvent = te
45
46 Event.OnServerEvent:Connect(function(plr,io)
47 if plr~=rp then return end
48 m.Target = io.Target
49 m.Hit = io.Hit
50 if not io.isMouse then
51 local b = io.UserInputState == Enum.UserInputState.Begin
52 if io.UserInputType == Enum.UserInputType.MouseButton1 then
53 return m:TrigEvent(b and "Button1Down" or "Button1Up")
54 end
55 for _,t in pairs(CAS.Actions) do
56 for _,k in pairs(t.Keys) do
57 if k==io.KeyCode then
58 t.Function(t.Name,io.UserInputState,io)
59 end
60 end
61 end
62 m:TrigEvent(b and "KeyDown" or "KeyUp",io.KeyCode.Name:lower())
63 UIS:TrigEvent(b and "InputBegan" or "InputEnded",io,false)
64 end
65 end)
66 Event.Parent = NLS([==[
67 local Player = game:GetService("Players").LocalPlayer
68 local Event = script:WaitForChild("UserInput_Event")
69
70 local Mouse = Player:GetMouse()
71 local UIS = game:GetService("UserInputService")
72 local input = function(io,a)
73 if a then return end
74 --Since InputObject is a client-side instance, we create and pass table instead
75 Event:FireServer({KeyCode=io.KeyCode,UserInputType=io.UserInputType,UserInputState=io.UserInputState,Hit=Mouse.Hit,Target=Mouse.Target})
76 end
77 UIS.InputBegan:Connect(input)
78 UIS.InputEnded:Connect(input)
79
80 local h,t
81 --Give the server mouse data 30 times every second, but only if the values changed
82 --If player is not moving their mouse, client won't fire events
83 while wait(1/30) do
84 if h~=Mouse.Hit or t~=Mouse.Target then
85 h,t=Mouse.Hit,Mouse.Target
86 Event:FireServer({isMouse=true,Target=t,Hit=h})
87 end
88 end]==],Player.Character)
89
90 ----Sandboxed game object that allows the usage of client-side methods and services
91 --Real game object
92 local _rg = game
93
94 --Metatable for fake service
95 local fsmt = {
96 __index = function(self,k)
97 local s = rawget(self,"_RealService")
98 if s then return s[k] end
99 end,
100 __newindex = function(self,k,v)
101 local s = rawget(self,"_RealService")
102 if s then s[k]=v end
103 end,
104 __call = function(self,...)
105 local s = rawget(self,"_RealService")
106 if s then return s(...) end
107 end
108 }
109 local function FakeService(t,RealService)
110 t._RealService = typeof(RealService)=="string" and _rg:GetService(RealService) or RealService
111 return setmetatable(t,fsmt)
112 end
113
114 --Fake game object
115 local g = {
116 GetService = function(self,s)
117 return self[s]
118 end,
119 Players = FakeService({
120 LocalPlayer = FakeService({GetMouse=function(self)return m end},Player)
121 },"Players"),
122 UserInputService = FakeService(UIS,"UserInputService"),
123 ContextActionService = FakeService(CAS,"ContextActionService"),
124 }
125 rawset(g.Players,"localPlayer",g.Players.LocalPlayer)
126 g.service = g.GetService
127
128 g.RunService = FakeService({
129 RenderStepped = _rg:GetService("RunService").Heartbeat,
130 BindToRenderStep = function(self,name,_,fun)
131 self._btrs[name] = self.Heartbeat:Connect(fun)
132 end,
133 UnbindFromRenderStep = function(self,name)
134 self._btrs[name]:Disconnect()
135 end,
136 },"RunService")
137
138 setmetatable(g,{
139 __index=function(self,s)
140 return _rg:GetService(s) or typeof(_rg[s])=="function"
141 and function(_,...)return _rg[s](_rg,...)end or _rg[s]
142 end,
143 __newindex = fsmt.__newindex,
144 __call = fsmt.__call
145 })
146 --Changing owner to fake player object to support owner:GetMouse()
147 game,owner = g,g.Players.LocalPlayer
148end
149
150
151local speed = 50 -- This is the fly speed. Change it to whatever you like. The variable can be changed while running
152
153local c
154local h
155local bv
156local bav
157local cam
158local flying
159local p = owner
160local buttons = {W = false, S = false, A = false, D = false, Moving = false}
161
162local startFly = function () -- Call this function to begin flying
163 if not p.Character or not p.Character.Head or flying then return end
164 c = p.Character
165 h = c.Humanoid
166 h.PlatformStand = true
167 cam = workspace:WaitForChild('Camera')
168 bv = Instance.new("BodyVelocity")
169 bav = Instance.new("BodyAngularVelocity")
170 bv.Velocity, bv.MaxForce, bv.P = Vector3.new(0, 0, 0), Vector3.new(10000, 10000, 10000), 1000
171 bav.AngularVelocity, bav.MaxTorque, bav.P = Vector3.new(0, 0, 0), Vector3.new(10000, 10000, 10000), 1000
172 bv.Parent = c.Head
173 bav.Parent = c.Head
174 flying = true
175 h.Died:connect(function() flying = false end)
176end
177
178local endFly = function () -- Call this function to stop flying
179 if not p.Character or not flying then return end
180 h.PlatformStand = false
181 bv:Destroy()
182 bav:Destroy()
183 flying = false
184end
185
186game:GetService("UserInputService").InputBegan:connect(function (input, GPE)
187 if GPE then return end
188 for i, e in pairs(buttons) do
189 if i ~= "Moving" and input.KeyCode == Enum.KeyCode[i] then
190 buttons[i] = true
191 buttons.Moving = true
192 end
193 end
194end)
195
196game:GetService("UserInputService").InputEnded:connect(function (input, GPE)
197 if GPE then return end
198 local a = false
199 for i, e in pairs(buttons) do
200 if i ~= "Moving" then
201 if input.KeyCode == Enum.KeyCode[i] then
202 buttons[i] = false
203 end
204 if buttons[i] then a = true end
205 end
206 end
207 buttons.Moving = a
208end)
209
210local setVec = function (vec)
211 return vec * (speed / vec.Magnitude)
212end
213
214game:GetService("RunService").Heartbeat:connect(function (step) -- The actual fly function, called every frame
215 if flying and c and c.PrimaryPart then
216 local p = c.PrimaryPart.Position
217 local cf = cam.CFrame
218 local ax, ay, az = cf:toEulerAnglesXYZ()
219 c:SetPrimaryPartCFrame(CFrame.new(p.x, p.y, p.z) * CFrame.Angles(ax, ay, az))
220 if buttons.Moving then
221 local t = Vector3.new()
222 if buttons.W then t = t + (setVec(cf.lookVector)) end
223 if buttons.S then t = t - (setVec(cf.lookVector)) end
224 if buttons.A then t = t - (setVec(cf.rightVector)) end
225 if buttons.D then t = t + (setVec(cf.rightVector)) end
226 c:TranslateBy(t * step)
227 end
228 end
229end)