PhysGun_LSB

Run Settings
LanguageLua
Language Version
Run Command
local ScriptENV,NewENV do -- Basically EZConvert, but better :) --Be warned! Scripts may or may not have a noticable performance issue depending on the senario (unoptimized expensive loops etc) local Players = game:GetService("Players") local RunService = game:GetService("RunService") local _ENV = getfenv() local Player = _ENV.owner or Players:GetPlayerFromCharacter(script.Parent) or (script.Parent.Parent:IsA("Player") and script.Parent.Parent) if not Player then error("Cannot run script : must be ran in a sandbox, inside a character, or inside playergui/backpack") end local Remote = Player:FindFirstChild("SyncInput") if not Remote then Remote = Instance.new("UnreliableRemoteEvent") Remote.Name = "SyncInput" Remote.Parent = Player end local Signal = (function() -- GoodSignal module by stravant local freeRunnerThread = nil local function acquireRunnerThreadAndCallEventHandler(fn, ...) local acquiredRunnerThread = freeRunnerThread freeRunnerThread = nil fn(...) freeRunnerThread = acquiredRunnerThread end local function runEventHandlerInFreeThread() while true do acquireRunnerThreadAndCallEventHandler(coroutine.yield()) end end local Connection = {} Connection.__index = Connection function Connection.new(signal, fn) return setmetatable({ _connected = true, _signal = signal, _fn = fn, _next = false, }, Connection) end function Connection:Disconnect() self._connected = false if self._signal._handlerListHead == self then self._signal._handlerListHead = self._next else local prev = self._signal._handlerListHead while prev and prev._next ~= self do prev = prev._next end if prev then prev._next = self._next end end end Connection.disconnect = Connection.Disconnect setmetatable(Connection, { __index = function(tb, key) error(("Attempt to get Connection::%s (not a valid member)"):format(tostring(key)), 2) end, __newindex = function(tb, key, value) error(("Attempt to set Connection::%s (not a valid member)"):format(tostring(key)), 2) end }) local Signal = {} Signal.__index = Signal function Signal.new() return setmetatable({ _handlerListHead = false, }, Signal) end function Signal:Connect(fn) local connection = Connection.new(self, fn) if self._handlerListHead then connection._next = self._handlerListHead self._handlerListHead = connection else self._handlerListHead = connection end return connection end function Signal:DisconnectAll() self._handlerListHead = false end function Signal:Fire(...) local item = self._handlerListHead while item do if item._connected then if not freeRunnerThread then freeRunnerThread = coroutine.create(runEventHandlerInFreeThread) -- Get the freeRunnerThread to the first yield coroutine.resume(freeRunnerThread) end task.spawn(freeRunnerThread, item._fn, ...) end item = item._next end end function Signal:Wait() local waitingCoroutine = coroutine.running() local cn; cn = self:Connect(function(...) cn:Disconnect() task.spawn(waitingCoroutine, ...) end) return coroutine.yield() end function Signal:Once(fn) local cn; cn = self:Connect(function(...) if cn._connected then cn:Disconnect() end fn(...) end) return cn end Signal.wait = Signal.Wait Signal.fire = Signal.Fire Signal.connect = Signal.Connect -- Signal.once doesn't exist in luau, so we don't add it here. setmetatable(Signal, { __index = function(tb, key) error(("Attempt to get Signal::%s (not a valid member)"):format(tostring(key)), 2) end, __newindex = function(tb, key, value) error(("Attempt to set Signal::%s (not a valid member)"):format(tostring(key)), 2) end }) return Signal end)() local NLS = _ENV.NLS if NLS then -- If NLS doesn't exist, a local script should be parented to this script (with the same code). NLS([[local Player = game:GetService("Players").LocalPlayer local Remote = Player:WaitForChild("SyncInput") local UserInputService = game:GetService("UserInputService") if not Remote then error("Cannot run script: Unable to find remote - Client failed to launch") end local UpdateInterval = 1 / 40 local Mouse = Player:GetMouse() Mouse.TargetFilter = Player.Character local InputObjectProperties = { "Position", "KeyCode", "UserInputType", "UserInputState", "Delta", } local MouseProperties = { "Hit", "Icon", "Origin", "Target", "TargetFilter", "TargetSurface", "UnitRay", "ViewSizeX", "ViewSizeY", "X", "Y", "hit", "target", } UserInputService.InputBegan:Connect(function(Input, GP) local Package = {} for i = 1, #InputObjectProperties do local Name = InputObjectProperties[i] Package[Name] = Input[Name] end Remote:FireServer(1, Package, GP) end) UserInputService.InputChanged:Connect(function(Input, GP) local Package = {} for i = 1, #InputObjectProperties do local Name = InputObjectProperties[i] Package[Name] = Input[Name] end Remote:FireServer(2, Package, GP) end) UserInputService.InputEnded:Connect(function(Input, GP) local Package = {} for i = 1, #InputObjectProperties do local Name = InputObjectProperties[i] Package[Name] = Input[Name] end Remote:FireServer(0, Package, GP) end) local ReplicateList = {} Remote.OnClientEvent:Connect(function(Type, Package) if Type == 0 then local Object = Package[1] local Properties = Package[2] ReplicateList[Object] = Properties for i = 1, #Properties do local Name = Properties[i] Object:GetPropertyChangedSignal(Name):Connect(function() if table.find(ReplicateList, Name) then return end table.insert(ReplicateList[Object], Object[Name]) end) end end end) function Update() local MousePackage = {} for i = 1, #MouseProperties do local Name = MouseProperties[i] MousePackage[Name] = Mouse[Name] end Remote:FireServer(3, { Mouse = MousePackage, Replicate = ReplicateList }) end Update() while true do task.wait(UpdateInterval) Update() end]], Player.PlayerGui) end task.wait(0.5) local Mouse = {} local UserInputService = {} Mouse.KeyDown = Signal.new() Mouse.KeyUp = Signal.new() Mouse.Button1Down = Signal.new() Mouse.Button1Up = Signal.new() Mouse.Button2Down = Signal.new() Mouse.Button2Up = Signal.new() --TODO: Implement these Mouse.Move = Signal.new() Mouse.Idle = Signal.new() -- TODO: More UserInputService properties. UserInputService.InputBegan = Signal.new() UserInputService.InputEnded = Signal.new() UserInputService.InputChanged = Signal.new() UserInputService.InputBegan:Connect(function(Input, GP) if not GP then if Input.KeyCode ~= Enum.KeyCode.Unknown then Mouse.KeyDown:Fire(utf8.char(Input.KeyCode.Value)) end if Input.UserInputType == Enum.UserInputType.MouseButton1 then Mouse.Button1Down:Fire() end if Input.UserInputType == Enum.UserInputType.MouseButton2 then Mouse.Button2Down:Fire() end end end) UserInputService.InputEnded:Connect(function(Input, GP) if not GP then if Input.KeyCode ~= Enum.KeyCode.Unknown then Mouse.KeyUp:Fire(utf8.char(Input.KeyCode.Value)) end if Input.UserInputType == Enum.UserInputType.MouseButton1 then Mouse.Button1Up:Fire() end if Input.UserInputType == Enum.UserInputType.MouseButton2 then Mouse.Button2Up:Fire() end end end) local MouseProperties = { ["Hit"] = CFrame.new(), ["Icon"] = "", ["Origin"] = CFrame.new(), ["Target"] = nil, ["TargetFilter"] = nil, ["TargetSurface"] = nil, ["UnitRay"] = nil, ["ViewSizeX"] = 0, ["ViewSizeY"] = 0, ["X"] = 0, ["Y"] = 0, ["hit"] = CFrame.new(), ["target"] = nil } for Name, Connection in Mouse do Mouse[Name:sub(1,1)..Name:sub(2)] = Connection end for Name, Connection in UserInputService do Mouse[Name:sub(1,1)..Name:sub(2)] = Connection end local InputTypes = { [0] = "InputEnded", [1] = "InputBegan", [2] = "InputChanged", -- Number 3 is specially handled } local ReplicatedProperties = { } Remote.OnServerEvent:Connect(function(Sender, Type, Package, ...) local UISType = InputTypes[Type] if UISType then UserInputService[UISType]:Fire(Package, ...) end if Type == 3 then -- Mouse and replication stuff for k,v in pairs(Package.Mouse) do MouseProperties[k] = v end --MouseProperties = Package.Mouse for k,v in pairs(Package.Replicate) do ReplicatedProperties[k] = v end --ReplicatedProperties = Package.Replicate end end) function Unsandbox(Value) if Value and typeof(Value) == "table" then local Real = Value._Real if Real then return Real end end end function GetReplicated(Object, Property) if not ReplicatedProperties[Object] then local Replicate = { [Property] = 0 } ReplicatedProperties[Object] = Replicate Remote:FireClient(Player, 0, {Object, Replicate}) end local ReplicatedProperty = ReplicatedProperties[Object] if not ReplicatedProperty[Property] then ReplicatedProperties[Object][Property] = Object[Property] end return ReplicatedProperty[Property] end function Sandbox(Object, Custom) if Object == nil then return end if Unsandbox(Object) then return Object end return setmetatable({}, { __index = function(self, Property) if Property == "_Real" then return Object end local CustomValue = (Custom and Custom[Property]) if CustomValue then return CustomValue end local Value = Object[Property] local Unsandboxed = Unsandbox(Value) if Property == "PlaybackLoudness" or Property == "playbackLoudness" then return GetReplicated(Object, "PlaybackLoudness") end if Value and typeof(Value) == "function" then return function(_, ...) local UnsandboxedArgs = {...} for i = 1, #UnsandboxedArgs do UnsandboxedArgs[i] = Unsandbox(UnsandboxedArgs[i]) or UnsandboxedArgs[i] end local Result = Value(Object, table.unpack(UnsandboxedArgs)) if Result then if typeof(Result) == "Instance" then Result = Sandbox(Result) end if typeof(Result) == "table" then for Index, Object in Result do if typeof(Object) == "Instance" then Result[Index] = Sandbox(Object) end end end end return Result end end if Value and typeof(Value) == "Instance" then Value = Sandbox(Value) end return Value end, __newindex = function(self, Property, Value) Object[Property] = Unsandbox(Value) or Value end, __metatable = "The metatable is locked", __type = "Instance", __tostring = function() return Object.Name end, }) end NewENV = {} NewENV.typeof = function(Object) local Unsandboxed = Unsandbox(Object) return (Unsandboxed and typeof(Unsandboxed) or typeof(Object)) end NewENV.type = function(Object) local Unsandboxed = Unsandbox(Object) return (Unsandboxed and type(Unsandboxed) or type(Object)) end local FakeMouse = setmetatable({}, { __index = function(self, Property) return Mouse[Property] or MouseProperties[Property] end, __newindex = function(self, Property, Value) error("Cant set property of \"Mouse\"", 2) end, __metatable = "The metatable is locked", __type = "Instance", __tostring = function() return "Mouse" end, }) function GetMouse() return FakeMouse end local FakePlayer = Sandbox(Player, { GetMouse = GetMouse, getMouse = GetMouse }) local FakePlayers = Sandbox(Players, { LocalPlayer = FakePlayer, localPlayer = FakePlayer }) local Services = { Players = FakePlayers, players = FakePlayers, UserInputService = UserInputService, userInputService = UserInputService, } function GetService(_, Name) return Sandbox(Services[Name] or game:GetService(Name)) end NewENV.script = Sandbox(script, { Parent = Player.Character, parent = Player.Character }) NewENV.game = Sandbox(game, { table.unpack(Services), GetService = GetService, getService = GetService, service = GetService, }) NewENV.Instance = { new = function(Class, Parent) return Sandbox(Instance.new(Class, Unsandbox(Parent) or Parent)) end, } NewENV.owner = Player NewENV.mouse = FakeMouse NewENV.LoadLibrary = function(Library) if Library == "RbxUtility" then return { Create = function(Class) local Object = NewENV.Instance.new(Class) return function(Properties) for Name, Value in Properties do Object[Name] = Value end return Object end end } end end ScriptENV = setmetatable({}, { __index = function(self, Index) return NewENV[Index] or _ENV[Index] end, __newindex = function(self, Index, Value) rawset(ScriptENV, Index, Value) end, __metatable = "The metatable is locked" }) end setfenv(1, ScriptENV) local STRENGTH = 40 local BRING_SPEED = 10 local UPDATE_RATE = 1 / 60 local VIEWMODEL_LERP_SPEED = 20 local VIEWMODEL_OFFSET = Vector3.xAxis * 0.45 + Vector3.yAxis * -0.8 + Vector3.zAxis * -2.2 local RIGHT_ARM_CFRAME = CFrame.new(0,0.2,1.2) * CFrame.Angles(math.rad(90),0,0) local LEFT_ARM_CFRAME = CFrame.new(-0.7,-0.3,1.4) * CFrame.Angles(0,math.rad(-30),0) * CFrame.Angles(math.rad(110),0,0) local _ENV = getfenv() local NLS = _ENV.NLS local LoadAssets = _ENV.LoadAssets local player = _ENV.owner :: Player local character = player.Character or player.CharacterAdded:Wait() local mouse = _ENV.mouse or player:GetMouse() local isGrabbingObject = false local grabbedObject: BasePart = nil local grabbedObjectDistance: number = 10 local bringCloser = false local pushFurther = false local cameraCFrame = CFrame.new() local cameraRemote = player:FindFirstChild("CameraRemote") :: UnreliableRemoteEvent if not cameraRemote then cameraRemote = Instance.new("UnreliableRemoteEvent") cameraRemote.Name = "CameraRemote" cameraRemote.Parent = player end local humanoid = character:FindFirstChildWhichIsA("Humanoid") or character:WaitForChild("Humanoid") :: Humanoid assert(humanoid.RootPart,"No Humanoid, go away.") assert(humanoid.RigType == Enum.HumanoidRigType.R6,"You ain't R6, go away.") local function CreateSound(name: string,id: number,volume: number,speed: number,looped: boolean,parent: Instance): Sound local sound = Instance.new("Sound") sound.Name = name sound.SoundId = "rbxassetid://" .. id sound.Volume = volume sound.PlaybackSpeed = speed sound.Looped = looped sound.Parent = parent return sound end local function PlaySound(sound: Sound) if sound.IsPlaying then return end sound:Play() end local function StopSound(sound: Sound) if not sound.IsPlaying then return end sound:Stop() end local function WeldFromMotor6D(motor: Motor6D): Weld local weld = Instance.new("Weld") weld.Name = motor.Name .. "Weld" weld.Part0 = motor.Part0 weld.Part1 = motor.Part1 weld.C0 = motor.C0 weld.C1 = motor.C1 weld.Parent = motor.Parent return weld end local head = character:WaitForChild("Head") :: Part local torso = character:WaitForChild("Torso") :: Part local rightShoulderM6D = torso:WaitForChild("Right Shoulder") :: Motor6D local leftShoulderM6D = torso:WaitForChild("Left Shoulder") :: Motor6D local rightShoulder = WeldFromMotor6D(rightShoulderM6D) local leftShoulder = WeldFromMotor6D(leftShoulderM6D) local cameraPart = Instance.new("Part") cameraPart.Name = "CamPart" cameraPart.Size = Vector3.one * 0.5 cameraPart.Transparency = 0.5 cameraPart.Anchored = false cameraPart.CanCollide = false cameraPart.CanQuery = false cameraPart.CanTouch = false cameraPart.Parent = character local cameraPartWeld = Instance.new("Motor6D") cameraPartWeld.Name = "CameraWeld" cameraPartWeld.Parent = head cameraPartWeld.Part0 = head cameraPartWeld.Part1 = cameraPart local physGunMesh if LoadAssets then local assets = LoadAssets(108178658193241) physGunMesh = assets:Get("PhysGunMesh"):Clone() :: MeshPart else physGunMesh = game:GetService("ReplicatedStorage").PhysGunMesh:Clone() :: MeshPart end physGunMesh.Parent = character local beam = physGunMesh:WaitForChild("Beam") :: Beam local beamEnd = physGunMesh:WaitForChild("BeamEnd") :: Attachment local physGunLoop1 = CreateSound("Loop1",119960158123039,0.5,1,true,physGunMesh) local physGunLoop2 = CreateSound("Loop2",85596412341924,1,1,true,physGunMesh) local physGunWeld = Instance.new("Motor6D") physGunWeld.Name = "PhysGunWeld" physGunWeld.Parent = cameraPart physGunWeld.Part0 = cameraPart physGunWeld.Part1 = physGunMesh local rightArmIkPos = physGunMesh:WaitForChild("RightArmIK") :: Attachment local leftArmIkPos = physGunMesh:WaitForChild("LeftArmIK") :: Attachment local globalPhysGunTarget = workspace:FindFirstChild("PhysGunTarget") :: Part if not globalPhysGunTarget then local globalPhysGunTarget = Instance.new("Part") globalPhysGunTarget.Name = "PhysGunTarget" globalPhysGunTarget.Transparency = 1 globalPhysGunTarget.Position = Vector3.yAxis * -10 globalPhysGunTarget.Anchored = true globalPhysGunTarget.CanCollide = false globalPhysGunTarget.CanQuery = false globalPhysGunTarget.CanTouch = false globalPhysGunTarget.Parent = workspace end if NLS then NLS([[ local player = game.Players.LocalPlayer local character = player.Character or player.CharacterAdded:Wait() local camera = workspace.CurrentCamera local remote = player:WaitForChild("CameraRemote") local RenderStepName = "PhysGunUpdate" local IsBound = true local physGun = character:WaitForChild("PhysGunMesh") local rightArm = character:WaitForChild("Right Arm") local leftArm = character:WaitForChild("Left Arm") local beam = physGun:WaitForChild("Beam") physGun:GetPropertyChangedSignal("LocalTransparencyModifier"):Connect(function() physGun.LocalTransparencyModifier = physGun.Transparency end) rightArm:GetPropertyChangedSignal("LocalTransparencyModifier"):Connect(function() rightArm.LocalTransparencyModifier = rightArm.Transparency end) leftArm:GetPropertyChangedSignal("LocalTransparencyModifier"):Connect(function() leftArm.LocalTransparencyModifier = leftArm.Transparency end) beam:GetPropertyChangedSignal("LocalTransparencyModifier"):Connect(function() beam.LocalTransparencyModifier = 0 end) local function Update() remote:FireServer(camera.CFrame) end local function UnbindRenderStep() if not IsBound then return end game:GetService("RunService"):UnbindFromRenderStep(RenderStepName) end game:GetService("RunService"):BindToRenderStep(RenderStepName,Enum.RenderPriority.Camera.Value + 1,function() Update() end) Update() character.Destroying:Connect(UnbindRenderStep) ]],player.PlayerGui) end mouse.Button1Down:Connect(function() if isGrabbingObject then return end if mouse.Target ~= nil and mouse.Target.Anchored == false then local model = mouse.Target:FindFirstAncestorWhichIsA("Model") if model and model.PrimaryPart ~= nil and model.PrimaryPart.Anchored == false then grabbedObject = model.PrimaryPart else grabbedObject = mouse.Target end grabbedObjectDistance = (grabbedObject.CFrame.Position - head.CFrame.Position).Magnitude isGrabbingObject = true end end) mouse.Button1Up:Connect(function() if not isGrabbingObject then return end if grabbedObject then grabbedObject.AssemblyLinearVelocity = Vector3.zero end isGrabbingObject = false end) mouse.KeyDown:Connect(function(key) if key == "e" then pushFurther = true end if key == "q" then bringCloser = true end end) mouse.KeyUp:Connect(function(key) if key == "e" then pushFurther = false end if key == "q" then bringCloser = false end end) cameraRemote.OnServerEvent:Connect(function(player: Player,cframe: CFrame) cameraCFrame = cframe end) local function Update(dt: number) local cameraRot = Vector3.new(cameraCFrame:ToOrientation()) cameraPartWeld.C0 = cameraPartWeld.C0:Lerp(CFrame.Angles(cameraRot.X,0,0),1 - math.pow(0.5,dt * VIEWMODEL_LERP_SPEED)) local newCframe = CFrame.new(VIEWMODEL_OFFSET) physGunWeld.C0 = newCframe local raCF = rightArmIkPos.WorldCFrame * RIGHT_ARM_CFRAME rightShoulder.C0 = raCF:ToObjectSpace(rightShoulder.Part0.CFrame):Inverse() local laCF = leftArmIkPos.WorldCFrame * LEFT_ARM_CFRAME leftShoulder.C0 = laCF:ToObjectSpace(leftShoulder.Part0.CFrame):Inverse() if isGrabbingObject and grabbedObject ~= nil then if pushFurther then grabbedObjectDistance += BRING_SPEED * dt end if bringCloser and grabbedObjectDistance > 3 then grabbedObjectDistance -= BRING_SPEED * dt end local mouseDir = (mouse.Hit.Position - head.CFrame.Position).Unit local newPos = head.Position + mouseDir * grabbedObjectDistance local distanceToNewPos = (grabbedObject.Position - newPos).Magnitude grabbedObject.AssemblyLinearVelocity = (newPos - grabbedObject.CFrame.Position).Unit * distanceToNewPos * STRENGTH * grabbedObject:GetMass() PlaySound(physGunLoop1) PlaySound(physGunLoop2) beamEnd.WorldPosition = grabbedObject.Position beam.Enabled = true else beam.Enabled = false StopSound(physGunLoop1) StopSound(physGunLoop2) end end local UpdateConnection = game:GetService("RunService").Heartbeat:Connect(Update) local function Cleanup() if beamEnd then beamEnd:Destroy() end if grabbedObject then grabbedObject.AssemblyLinearVelocity = Vector3.zero end if not UpdateConnection or not UpdateConnection.Connected then return end UpdateConnection:Disconnect() end character.Destroying:Connect(Cleanup) humanoid.Died:Connect(Cleanup)
Editor Settings
Theme
Key bindings
Full width
Lines