Mrxtz

Fighting-Drone

Aug 9th, 2025 (edited)
66
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 16.48 KB | Source Code | 0 0
  1. -- // CLIENT-SIDE //
  2.  
  3.  
  4. --[[
  5.     ==========================================================
  6.     DRONE CONTROL & SHOOTING SYSTEM - CLIENT SIDE
  7.     ==========================================================
  8.     PLACE THIS LOCALSCRIPT HERE:
  9.         StarterPlayer > StarterPlayerScripts
  10.  
  11.     ==========================================================
  12.     PRE SETUP GUIDE:
  13.     ==========================================================
  14.  
  15.     1. BUILDING THE DRONE (in Workspace):
  16.        - Create a Model called "Drone".
  17.        - Inside it, add the following Parts:
  18.          1. "Main"       → Main body of drone. (Set PrimaryPart to this!)
  19.          2. "Camera"     → Part for player camera positioning.
  20.          3. "Propeller"  → Will spin when drone is active.
  21.          4. "CanonTip"   → Bullets spawn from here.
  22.  
  23.     2. REPLICATEDSTORAGE SETUP:
  24.        Inside ReplicatedStorage:
  25.          - Folder "Remotes":
  26.              RemoteEvent "StartDrone"
  27.              RemoteEvent "Shoot"
  28.          - Folder "Sounds":
  29.              Sound "Shoot"
  30.              Sound "Reload"
  31.          - Folder "Clones":
  32.              Part "Bullet" (Small, CanCollide=true, Anchored=false, Neon works well)
  33.  
  34.     3. UI SETUP (StarterGui):
  35.        - ScreenGui "DroneUI"
  36.          Inside it:
  37.            TextLabel "TextLabel" (crosshair display - optional)
  38.            TextLabel "Ammo" (ammo counter)
  39.  
  40.     4. CONTROLS:
  41.        W/S → Forward / Backward
  42.        A/D → Strafe left / right
  43.        Space → Ascend
  44.        LeftShift → Descend
  45.        Left Mouse Button → Shoot
  46.  
  47.     ==========================================================
  48. ]]
  49.  
  50.  
  51. --// SERVICES
  52.  
  53. local Players = game:GetService("Players")  
  54. local ReplicatedStorage = game:GetService("ReplicatedStorage")
  55. local UserInputService = game:GetService("UserInputService")
  56. local RunService = game:GetService("RunService")
  57. local TweenService = game:GetService("TweenService")  
  58. local Debris = game:GetService("Debris")          
  59. local Workspace = game:GetService("Workspace")  
  60.  
  61.  
  62. --// PLAYER REFERENCES
  63.  
  64. local player = Players.LocalPlayer -- Get the current player running this script
  65. local character = player.Character or player.CharacterAdded:Wait() -- Player's character model in the world
  66. local humanoid = character:WaitForChild("Humanoid") -- Controls character movement and properties
  67.  
  68. --// REMOTE EVENTS
  69.  
  70. local remotes = ReplicatedStorage:WaitForChild("Remotes")  -- Folder containing all remote events
  71. local startDrone = remotes:WaitForChild("StartDrone") -- Event to begin drone control mode
  72. local shootRemote = remotes:WaitForChild("Shoot") -- Event to sync shooting with server
  73.  
  74.  
  75. --// AUDIO ASSETS
  76. local sounds = ReplicatedStorage:WaitForChild("Sounds") -- Folder containing all sound effects
  77. local shootSFX = sounds:WaitForChild("Shoot") -- Sound played when firing bullets
  78. local reloadSFX = sounds:WaitForChild("Reload") -- Sound played during ammo reload
  79.  
  80.  
  81. --// OBJECT TEMPLATES
  82.  
  83. local clones = ReplicatedStorage:WaitForChild("Clones") -- Folder containing template objects
  84. local bulletTemplate = clones:WaitForChild("Bullet") -- Template bullet part to clone when shooting
  85.  
  86.  
  87. --// DRONE MODEL PARTS
  88.  
  89. local drone = Workspace:WaitForChild("Drone") -- Main drone model in the world
  90. local cameraPart = drone:WaitForChild("Camera") -- Part that camera follows for first-person view
  91. local mainPart = drone:WaitForChild("Main") -- Main body part (should be set as PrimaryPart)
  92. local propeller = drone:WaitForChild("Propeller") -- Part that spins to show drone activity
  93. local canonPart = drone:WaitForChild("CanonTip") -- Point where bullets spawn from
  94.  
  95.  
  96. --// USER INTERFACE
  97.  
  98. local playerGui = player:WaitForChild("PlayerGui") -- Player's GUI container
  99. local droneUi = playerGui:WaitForChild("DroneUI") -- Main drone control interface
  100. local crosshair = droneUi:WaitForChild("TextLabel") -- Crosshair display (optional visual aid)
  101. local ammoLabel = droneUi:WaitForChild("Ammo") -- Shows current ammo count and reload status
  102.  
  103.  
  104. --// CAMERA SYSTEM
  105. local camera = Workspace.CurrentCamera -- Main game camera
  106. local originalFOV = camera.FieldOfView -- Store original field of view to restore later
  107. local originalMouseBehavior = UserInputService.MouseBehavior -- Store original mouse behavior for restoration
  108.  
  109. --// CONFIGURATION TABLE - Easily adjustable settings
  110.  
  111. local CONFIG = {
  112.     -- Movement physics and feel
  113.     Movement = {
  114.         MinAcceleration = 1, -- Base acceleration when no input
  115.         MaxForwardAcceleration = 5, -- Maximum forward speed multiplier
  116.         MaxSidewardAcceleration = 2.5, -- Maximum side movement speed
  117.         AccelerationIncrease = 1.025, -- How quickly acceleration builds up (per frame)
  118.         AccelerationDecrease = 0.965, -- How quickly acceleration decays when not accelerating
  119.         VerticalSpeed = 0.25, -- Up/down movement speed (Space/Shift keys)
  120.         HorizontalSpeed = 0.5, -- Left/right strafe speed (A/D keys)
  121.         BackwardSpeed = 0.25 -- Backward movement speed (S key)
  122.     },
  123.     -- Shooting mechanics and bullet behavior
  124.     Shooting = {
  125.         BulletSpeed = 500, -- How fast bullets travel (studs per second)
  126.         BulletLifetime = 5, -- How long bullets exist before auto-destruction
  127.         MaxAmmo = 30, -- Maximum ammunition capacity
  128.         ReloadTime = 2 -- Time in seconds to reload (handled server-side)
  129.     },
  130.     -- Visual effects and feedback
  131.     Visuals = {
  132.         PropellerSpinSpeed = 5, -- Degrees per frame the propeller rotates
  133.         FOVIncreaseRate = 0.2, -- How fast FOV increases when accelerating
  134.         FOVReturnSpeed = 0.15 -- How fast FOV returns to normal when decelerating
  135.     }
  136. }
  137.  
  138.  
  139. --// INTERNAL STATE VARIABLES - Runtime tracking
  140.  
  141. local acceleration = CONFIG.Movement.MinAcceleration -- Current forward acceleration multiplier
  142. local isReloading = false -- Track if player is currently reloading
  143. local connections = {} -- Store all event connections for cleanup
  144.  
  145. --// UTILITY FUNCTIONS
  146.  
  147. --// Safely disconnect all active event connections to prevent memory leaks
  148. local function cleanupConnections()
  149.     -- Loop through all stored connections
  150.     for _, conn in ipairs(connections) do
  151.         -- Check if connection exists and has Disconnect method
  152.         if conn and conn.Disconnect then
  153.             conn:Disconnect()  -- Safely disconnect the event
  154.         end
  155.     end
  156.     -- Clear the connections table for reuse
  157.     table.clear(connections)
  158. end
  159.  
  160. --// Update the ammo counter display based on current state
  161. local function updateAmmoLabel()
  162.     if isReloading then
  163.         -- Show reload status instead of numbers
  164.         ammoLabel.Text = "Reloading..."
  165.     else
  166.         -- Show current ammo / maximum ammo format
  167.         ammoLabel.Text = string.format("%d/%d", player:GetAttribute("Ammo"), CONFIG.Shooting.MaxAmmo)
  168.     end
  169. end
  170.  
  171. --// BULLET SYSTEM - Projectile creation and physics
  172.  
  173. --// Create a physical bullet and launch it toward target
  174. local function createBullet(origin, target)
  175.     -- Clone the bullet template to create a new projectile
  176.     local bullet = bulletTemplate:Clone()
  177.     bullet.Parent = Workspace -- Place bullet in the world
  178.     bullet.Position = origin -- Start bullet at firing position
  179.  
  180.     -- Create physics body to control bullet movement
  181.     local bodyVelocity = Instance.new("BodyVelocity")
  182.     bodyVelocity.MaxForce = Vector3.new(4000, 4000, 4000)  -- Maximum force in all directions
  183.     -- Calculate direction and apply speed
  184.     bodyVelocity.Velocity = (target - origin).Unit * CONFIG.Shooting.BulletSpeed
  185.     bodyVelocity.Parent = bullet -- Attach physics to bullet
  186.  
  187.     -- Track if bullet has been destroyed to prevent double-destruction
  188.     local destroyed = false
  189.     local touchConn
  190.  
  191.     -- Handle bullet collision with objects
  192.     touchConn = bullet.Touched:Connect(function(hit)
  193.         -- Ignore if already destroyed or hitting the drone itself
  194.         if destroyed or hit:IsDescendantOf(drone) then return end
  195.  
  196.         -- Only collide with actual parts (not accessories, etc.)
  197.         if hit:IsA("BasePart") then
  198.             destroyed = true -- Mark as destroyed
  199.             bullet:Destroy() -- Remove from world
  200.         end
  201.     end)
  202.  
  203.     -- Clean up connection if bullet is removed from world
  204.     bullet.AncestryChanged:Connect(function(_, parent)
  205.         if not parent then  -- Bullet was removed from workspace
  206.             destroyed = true
  207.             if touchConn then touchConn:Disconnect() end
  208.         end
  209.     end)
  210.  
  211.     -- Auto-destroy bullet after specified lifetime to prevent lag
  212.     Debris:AddItem(bullet, CONFIG.Shooting.BulletLifetime)
  213. end
  214.  
  215. --// MOVEMENT SYSTEM - Drone position control
  216.  
  217. --// Handle all drone movement based on current key presses
  218. local function moveDrone()
  219.     -- VERTICAL MOVEMENT - Up and down controls
  220.     if UserInputService:IsKeyDown(Enum.KeyCode.Space) then
  221.         -- Move drone upward by vertical speed amount
  222.         drone:SetPrimaryPartCFrame(drone.PrimaryPart.CFrame * CFrame.new(0, CONFIG.Movement.VerticalSpeed, 0))
  223.     end
  224.     if UserInputService:IsKeyDown(Enum.KeyCode.LeftShift) then
  225.         -- Move drone downward by vertical speed amount
  226.         drone:SetPrimaryPartCFrame(drone.PrimaryPart.CFrame * CFrame.new(0, -CONFIG.Movement.VerticalSpeed, 0))
  227.     end
  228.  
  229.     -- HORIZONTAL MOVEMENT - Left and right strafe
  230.     if UserInputService:IsKeyDown(Enum.KeyCode.A) then
  231.         -- Strafe left relative to drone's current facing direction
  232.         drone:SetPrimaryPartCFrame(drone.PrimaryPart.CFrame * CFrame.new(-CONFIG.Movement.HorizontalSpeed, 0, 0))
  233.     end
  234.     if UserInputService:IsKeyDown(Enum.KeyCode.D) then
  235.         -- Strafe right relative to drone's current facing direction
  236.         drone:SetPrimaryPartCFrame(drone.PrimaryPart.CFrame * CFrame.new(CONFIG.Movement.HorizontalSpeed, 0, 0))
  237.     end
  238.  
  239.     -- FORWARD MOVEMENT - Accelerating forward motion with visual feedback
  240.     if UserInputService:IsKeyDown(Enum.KeyCode.W) then
  241.         -- Build up acceleration if not at maximum
  242.         if acceleration < CONFIG.Movement.MaxForwardAcceleration then
  243.             acceleration *= CONFIG.Movement.AccelerationIncrease  -- Increase acceleration
  244.             camera.FieldOfView += CONFIG.Visuals.FOVIncreaseRate  -- Widen FOV for speed effect
  245.         end
  246.         -- Move forward with current acceleration multiplier
  247.         drone:SetPrimaryPartCFrame(drone.PrimaryPart.CFrame * CFrame.new(0, 0, -CONFIG.Movement.BackwardSpeed * acceleration))
  248.     else
  249.         -- DECELERATION - Slow down when not pressing forward
  250.         if acceleration > CONFIG.Movement.MinAcceleration then
  251.             acceleration *= CONFIG.Movement.AccelerationDecrease -- Reduce acceleration
  252.             -- Return FOV to normal, but don't go below original
  253.             camera.FieldOfView = math.max(originalFOV, camera.FieldOfView - CONFIG.Visuals.FOVReturnSpeed)
  254.         end
  255.     end
  256.  
  257.     -- BACKWARD MOVEMENT - Simple reverse motion
  258.     if UserInputService:IsKeyDown(Enum.KeyCode.S) then
  259.         -- Move backward at constant speed (no acceleration)
  260.         drone:SetPrimaryPartCFrame(drone.PrimaryPart.CFrame * CFrame.new(0, 0, CONFIG.Movement.BackwardSpeed))
  261.     end
  262. end
  263.  
  264. --// SHOOTING SYSTEM - Weapon firing mechanics
  265.  
  266. --// Handle shooting logic with raycasting for accuracy
  267. local function handleShooting()
  268.     -- Prevent shooting if reloading or out of ammo
  269.     if isReloading or player:GetAttribute("Ammo") <= 0 then
  270.         return  -- Exit early, no shooting allowed
  271.     end
  272.  
  273.     -- RAYCASTING SETUP - Determine where player is aiming
  274.     local cameraRayOrigin = cameraPart.CFrame.Position -- Start from camera position
  275.     local rayOrigin = canonPart.Position -- Bullets spawn from canon tip
  276.     local rayDirection = camera.CFrame.LookVector * 1000  -- Ray direction based on camera look
  277.  
  278.     -- FIRST RAYCAST - Where is the crosshair pointing?
  279.     local crosshairHit = Workspace:Raycast(cameraRayOrigin, rayDirection)
  280.     if crosshairHit then
  281.         -- SECOND RAYCAST - Can we actually hit that point from the gun?
  282.         local targetPosition = crosshairHit.Position
  283.         local bulletDirection = (targetPosition - rayOrigin).Unit * 1000  -- Direction from gun to target
  284.         local aimedHit = Workspace:Raycast(rayOrigin, bulletDirection)
  285.  
  286.         if aimedHit then
  287.             -- SUCCESSFUL SHOT SETUP
  288.             local finalTarget = aimedHit.Position
  289.             createBullet(rayOrigin, finalTarget) -- Create the visual bullet
  290.             shootSFX:Play() -- Play shooting sound effect
  291.             -- Notify server about the shot for other players to see
  292.             shootRemote:FireServer(rayOrigin, finalTarget)
  293.         end
  294.     end
  295. end
  296.  
  297. --// MAIN UPDATE LOOP - Per-frame processing
  298.  
  299. --// Called every frame while drone is active - handles real-time updates
  300. local function onRenderStep()
  301.     -- DRONE ORIENTATION - Make drone face the camera's look direction
  302.     local currentPos = drone.PrimaryPart.Position
  303.     local lookCF = CFrame.new(currentPos, currentPos + camera.CFrame.LookVector)
  304.     drone:SetPrimaryPartCFrame(lookCF)
  305.  
  306.     -- PROPELLER ANIMATION - Spin the propeller for visual effect
  307.     propeller.CFrame = propeller.CFrame * CFrame.Angles(0, math.rad(CONFIG.Visuals.PropellerSpinSpeed), 0)
  308.  
  309.     -- MOUSE CONTROL - Keep mouse locked to center for FPS-style control
  310.     UserInputService.MouseBehavior = Enum.MouseBehavior.LockCenter
  311.  
  312.     -- MOVEMENT UPDATE - Process all movement input
  313.     moveDrone()
  314. end
  315.  
  316. --// DRONE CONTROL INITIALIZATION
  317.  
  318. --// Set up drone control mode - called when drone starts
  319. local function startDroneControl()
  320.     -- UI SETUP - Show drone interface
  321.     droneUi.Enabled = true -- Make drone UI visible
  322.     UserInputService.MouseIconEnabled = false -- Hide mouse cursor for immersion
  323.  
  324.     -- CAMERA SETUP - Switch to drone's perspective
  325.     camera.CameraSubject = cameraPart -- Camera follows drone's camera part
  326.  
  327.     -- CHARACTER LOCKDOWN - Prevent normal character movement
  328.     humanoid.WalkSpeed = 0 -- Can't walk while controlling drone
  329.     humanoid.JumpHeight = 0  -- Can't jump while controlling drone
  330.  
  331.     -- EVENT CONNECTIONS - Set up all input handlers
  332.     -- Connect the main update loop to run every frame
  333.     table.insert(connections, RunService.RenderStepped:Connect(onRenderStep))
  334.  
  335.     -- Connect input handling for shooting
  336.     table.insert(connections, UserInputService.InputBegan:Connect(function(input, gpe)
  337.         if gpe then return end  -- Ignore if GUI processed the input
  338.         -- Handle left mouse button for shooting
  339.         if input.UserInputType == Enum.UserInputType.MouseButton1 then
  340.             handleShooting()
  341.         end
  342.     end))
  343. end
  344.  
  345. --// EVENT LISTENERS - React to game state changes
  346.  
  347. -- Listen for changes to player's ammo attribute and update display
  348. table.insert(connections, player:GetAttributeChangedSignal("Ammo"):Connect(updateAmmoLabel))
  349.  
  350. -- Listen for changes to player's reloading status
  351. table.insert(connections, player:GetAttributeChangedSignal("Reloading"):Connect(function()
  352.     isReloading = player:GetAttribute("Reloading")  -- Update local reload state
  353.     if isReloading then
  354.         reloadSFX:Play()  -- Play reload sound when starting to reload
  355.     end
  356.     updateAmmoLabel()     -- Update the ammo display
  357. end))
  358.  
  359. --// MAIN ENTRY POINT - Start the system
  360.  
  361. -- Listen for the server's signal to start drone control
  362. table.insert(connections, startDrone.OnClientEvent:Connect(startDroneControl))
  363.  
  364.  
  365.  
  366.  
  367.  
  368. -- // SERVER-SIDE //
  369.  
  370.  
  371. --[[
  372.     ==========================================================
  373.     DRONE SHOOTING SYSTEM - SERVER SIDE
  374.     ==========================================================
  375.     PLACE THIS SCRIPT HERE:
  376.         ServerScriptService
  377.  
  378.     PURPOSE:
  379.         - Keeps ammo count secure on the server
  380.         - Handles reloads
  381.         - Detects hits & applies damage
  382.  
  383.     ==========================================================
  384. ]]
  385.  
  386. local Players = game:GetService("Players")
  387. local ReplicatedStorage = game:GetService("ReplicatedStorage")
  388.  
  389. --// Remote events
  390. local remotes = ReplicatedStorage:WaitForChild("Remotes")
  391. local shoot = remotes:WaitForChild("Shoot")
  392.  
  393. --// Assign ammo attributes to new players
  394. Players.PlayerAdded:Connect(function(player)
  395.     player:SetAttribute("Ammo", 30)
  396.     player:SetAttribute("Reloading", false)
  397. end)
  398.  
  399. --// Reload function
  400. local function reload(player)
  401.     player:SetAttribute("Reloading", true)
  402.     task.spawn(function()
  403.         task.wait(2) -- Reload duration
  404.         player:SetAttribute("Ammo", 30)
  405.         player:SetAttribute("Reloading", false)
  406.     end)
  407. end
  408.  
  409. --// Handle shooting from client
  410. shoot.OnServerEvent:Connect(function(player, rayOrigin, targetPosition)
  411.     -- Ignore if reloading
  412.     if player:GetAttribute("Reloading") then return end
  413.  
  414.     local ammo = player:GetAttribute("Ammo")
  415.  
  416.     -- Deduct ammo
  417.     if ammo > 0 then
  418.         player:SetAttribute("Ammo", ammo - 1)
  419.         if ammo - 1 <= 0 then
  420.             -- Reload when empty
  421.             reload(player)
  422.         end
  423.     else
  424.         reload(player)
  425.         return
  426.     end
  427.  
  428.     -- Raycast for hit detection
  429.     local bulletDirection = (targetPosition - rayOrigin).Unit * 10000
  430.     local result = workspace:Raycast(rayOrigin, bulletDirection)
  431.  
  432.     if result then
  433.         local hitPart = result.Instance
  434.         local character = hitPart.Parent
  435.         local humanoid = character:FindFirstChild("Humanoid")
  436.         -- Check if hit is a humanoid
  437.         if humanoid and character ~= player.Character then
  438.             humanoid.Health -= 10 -- Damage per bullet
  439.         end
  440.     end
  441. end)
  442.  
Advertisement
Add Comment
Please, Sign In to add comment