Hi, I'm a novice scripter, and the rocket launchers in my game aren't working properly. They used to, but...
Anyway, I tried making the projectile "canCollide", but then the rockets just bounced off objects.
Obviously, I used Roblox's rocket.
Here's the first script, called "Launcher" from the rocket.
local GRAVITY_ACCELERATION = 196.2 local RELOAD_TIME = 3 -- Seconds until tool can be used again local ROCKET_SPEED = 50 -- Speed of the projectile local MISSILE_MESH_ID = 'http://www.roblox.com/asset/?id=2251534' local MISSILE_MESH_SCALE = Vector3.new(0.35, 0.35, 0.25) local ROCKET_PART_SIZE = Vector3.new(1.2, 1.2, 3.27) ----------------- --| Variables |-- ----------------- local DebrisService = Game:GetService('Debris') local PlayersService = Game:GetService('Players') local MyPlayer = PlayersService.LocalPlayer local Tool = script.Parent local ToolHandle = Tool.Handle local RocketScript = script:WaitForChild('Rocket') local SwooshSound = script:WaitForChild('Swoosh') local BoomSound = script:WaitForChild('Boom') --NOTE: We create the rocket once and then clone it when the player fires local Rocket = Instance.new('Part') do -- Set up the rocket part Rocket.Name = 'Rocket' Rocket.FormFactor = Enum.FormFactor.Custom --NOTE: This must be done before changing Size Rocket.Size = ROCKET_PART_SIZE Rocket.CanCollide = true -- Add the mesh local mesh = Instance.new('SpecialMesh', Rocket) mesh.MeshId = MISSILE_MESH_ID mesh.Scale = MISSILE_MESH_SCALE -- Add fire local fire = Instance.new('Fire', Rocket) fire.Heat = 5 fire.Size = 2 -- Add a force to counteract gravity local bodyForce = Instance.new('BodyForce', Rocket) bodyForce.Name = 'Antigravity' bodyForce.force = Vector3.new(0, Rocket:GetMass() * GRAVITY_ACCELERATION, 0) -- Clone the sounds and set Boom to PlayOnRemove local swooshSoundClone = SwooshSound:Clone() swooshSoundClone.Parent = Rocket local boomSoundClone = BoomSound:Clone() boomSoundClone.PlayOnRemove = true boomSoundClone.Parent = Rocket -- Attach creator tags to the rocket early on local creatorTag = Instance.new('ObjectValue', Rocket) creatorTag.Value = MyPlayer creatorTag.Name = 'creator' --NOTE: Must be called 'creator' for website stats local iconTag = Instance.new('StringValue', creatorTag) iconTag.Value = Tool.TextureId iconTag.Name = 'icon' -- Finally, clone the rocket script and enable it local rocketScriptClone = RocketScript:Clone() rocketScriptClone.Parent = Rocket rocketScriptClone.Disabled = false end ----------------- --| Functions |-- ----------------- local function OnActivated() local myModel = MyPlayer.Character if Tool.Enabled and myModel and myModel:FindFirstChild('Humanoid') and myModel.Humanoid.Health > 0 then Tool.Enabled = false -- Create a clone of Rocket and set its color local rocketClone = Rocket:Clone() DebrisService:AddItem(rocketClone, 30) rocketClone.BrickColor = MyPlayer.TeamColor -- Position the rocket clone and launch! local spawnPosition = (ToolHandle.CFrame * CFrame.new(2, 0, 0)).p rocketClone.CFrame = CFrame.new(spawnPosition, myModel.Humanoid.TargetPoint) --NOTE: This must be done before assigning Parent rocketClone.Velocity = rocketClone.CFrame.lookVector * ROCKET_SPEED --NOTE: This should be done before assigning Parent rocketClone.Parent = Workspace wait(RELOAD_TIME) Tool.Enabled = true end end -------------------- --| Script Logic |-- -------------------- Tool.Activated:connect(OnActivated)
Here's the second script, called "Rocket."
local BLAST_RADIUS = 8 -- Blast radius of the explosion local BLAST_DAMAGE = 100 -- Amount of damage done to players local BLAST_FORCE = 1000 -- Amount of force applied to parts local IGNORE_LIST = {rocket = 1, handle = 1, effect = 1, water = 1} -- Rocket will fly through things named these --NOTE: Keys must be lowercase, values must evaluate to true ----------------- --| Variables |-- ----------------- local DebrisService = Game:GetService('Debris') local PlayersService = Game:GetService('Players') local Rocket = script.Parent local CreatorTag = Rocket:WaitForChild('creator') local SwooshSound = Rocket:WaitForChild('Swoosh') ----------------- --| Functions |-- ----------------- -- Removes any old creator tags and applies a new one to the target local function ApplyTags(target) while target:FindFirstChild('creator') do target.creator:Destroy() end local creatorTagClone = CreatorTag:Clone() DebrisService:AddItem(creatorTagClone, 1.5) creatorTagClone.Parent = target end -- Returns the ancestor that contains a Humanoid, if it exists local function FindCharacterAncestor(subject) if subject and subject ~= Workspace then local humanoid = subject:FindFirstChild('Humanoid') if humanoid then return subject, humanoid else return FindCharacterAncestor(subject.Parent) end end return nil end -- Customized explosive effect that doesn't affect teammates and only breaks joints on dead parts local function OnExplosionHit(hitPart, hitDistance, blastCenter) if hitPart and hitDistance then local character, humanoid = FindCharacterAncestor(hitPart.Parent) if character then local myPlayer = CreatorTag.Value if myPlayer and not myPlayer.Neutral then -- Ignore friendlies caught in the blast local player = PlayersService:GetPlayerFromCharacter(character) if player and player ~= myPlayer and player.TeamColor == Rocket.BrickColor then return end end end if humanoid and humanoid.Health > 0 then -- Humanoids are tagged and damaged if hitPart.Name == 'Torso' then ApplyTags(humanoid) humanoid:TakeDamage(BLAST_DAMAGE) end else -- Loose parts and dead parts are blasted if hitPart.Name ~= 'Handle' then hitPart:BreakJoints() local blastForce = Instance.new('BodyForce', hitPart) --NOTE: We will multiply by mass so bigger parts get blasted more blastForce.force = (hitPart.Position - blastCenter).unit * BLAST_FORCE * hitPart:GetMass() DebrisService:AddItem(blastForce, 0.1) end end end end local function OnTouched(otherPart) if Rocket and otherPart then -- Fly through anything in the ignore list if IGNORE_LIST[string.lower(otherPart.Name)] then return end local myPlayer = CreatorTag.Value if myPlayer then -- Fly through the creator if myPlayer.Character and myPlayer.Character:IsAncestorOf(otherPart) then return end -- Fly through friendlies if not myPlayer.Neutral then local character = FindCharacterAncestor(otherPart.Parent) local player = PlayersService:GetPlayerFromCharacter(character) if player and player ~= myPlayer and player.TeamColor == Rocket.BrickColor then return end end end -- Fly through terrain water if otherPart == Workspace.Terrain then --NOTE: If the rocket is large, then the simplifications made here will cause it to fly through terrain in some cases local frontOfRocket = Rocket.Position + (Rocket.CFrame.lookVector * (Rocket.Size.Z / 2)) local cellLocation = Workspace.Terrain:WorldToCellPreferSolid(frontOfRocket) local cellMaterial = Workspace.Terrain:GetCell(cellLocation.X, cellLocation.Y, cellLocation.Z) if cellMaterial == Enum.CellMaterial.Water or cellMaterial == Enum.CellMaterial.Empty then return end end -- Create the explosion local explosion = Instance.new('Explosion') explosion.BlastPressure = 0 -- Completely safe explosion explosion.BlastRadius = BLAST_RADIUS explosion.ExplosionType = Enum.ExplosionType.NoCraters explosion.Position = Rocket.Position explosion.Parent = Workspace -- Connect custom logic for the explosion explosion.Hit:connect(function(hitPart, hitDistance) OnExplosionHit(hitPart, hitDistance, explosion.Position) end) -- Move this script and the creator tag (so our custom logic can execute), then destroy the rocket script.Parent = explosion CreatorTag.Parent = script Rocket:Destroy() end end -------------------- --| Script Logic |-- -------------------- SwooshSound:Play() Rocket.Touched:connect(OnTouched)