How to Make plant shoot things at enemy

This is a support category for asking questions about how to get something done on the Roblox websites or how to do something on Roblox applications such as Roblox Studio.

You can write your topic however you want, but you need to answer these questions:
I’m trying to make a peashooter that shoots peas at zombies but when i run the script, it animates but doesn’t do the shooting tween and fire the pea i’ve tried asking ai for help but nothing’s working help!

here’s the script:
local TweenService = game:GetService(“TweenService”)
local RunService = game:GetService(“RunService”)
local Peashooter = script.Parent
local Humanoid = Peashooter:FindFirstChildOfClass(“Humanoid”)
local Animator = Humanoid:FindFirstChildOfClass(“Animator”)
local PeaTemplate = workspace:FindFirstChild(“Pea”)
local ShootInterval = 1.5
local Damage = 20
local AnimationId = “rbxassetid://108587954936313”

local function playAnimation()
local animation = Instance.new(“Animation”)
animation.AnimationId = AnimationId
local track = Animator:LoadAnimation(animation)
track:Play()
end

local function animateHeadAndParts()
local head = Peashooter:FindFirstChild(“FakeHead”)
local hole = Peashooter:FindFirstChild(“Hole”)
local mouth = Peashooter:FindFirstChild(“Mouth”)
if head and hole and mouth then
local originalSize = head.Size
local targetSize = originalSize + Vector3.new(0, 0, originalSize.Z)

    local tweenInfo = TweenInfo.new(0.5, Enum.EasingStyle.Quad, Enum.EasingDirection.InOut)
    local headTween = TweenService:Create(head, tweenInfo, {Size = targetSize})
    local holeTween = TweenService:Create(hole, tweenInfo, {Size = targetSize})
    local mouthTween = TweenService:Create(mouth, tweenInfo, {CFrame = mouth.CFrame * CFrame.new(0, 0, 1)})

    headTween:Play()
    holeTween:Play()
    mouthTween:Play()

    headTween.Completed:Connect(function()
        local returnTween = TweenService:Create(head, tweenInfo, {Size = originalSize})
        local returnHoleTween = TweenService:Create(hole, tweenInfo, {Size = originalSize})
        returnTween:Play()
        returnHoleTween:Play()
    end)
end

end

local function shootPea()
local pea = PeaTemplate:Clone()
pea.CFrame = Peashooter.HumanoidRootPart.CFrame
pea.Parent = workspace

local direction = Peashooter.HumanoidRootPart.CFrame.LookVector
local raycastParams = RaycastParams.new()
raycastParams.FilterDescendantsInstances = {Peashooter}
raycastParams.FilterType = Enum.RaycastFilterType.Exclude

local raycastResult = workspace:Raycast(pea.Position, direction * 100, raycastParams)

if raycastResult and raycastResult.Instance.Parent:FindFirstChildOfClass("Humanoid") then
    local zombieHumanoid = raycastResult.Instance.Parent:FindFirstChildOfClass("Humanoid")
    zombieHumanoid:TakeDamage(Damage)
    animateHeadAndParts()
end

pea:Destroy()

end

local function startShooting()
while true do
playAnimation()
shootPea()
task.wait(ShootInterval)
end
end

startShooting()

1 Like

do you need help with the closest enemy or no?

it needs to shoot down the lane at whatever zombie is there

so you want to check if a zombie is in there lane?

can you send me a video? or not because that can help me understand this more.

The zombie just walks towards the peashooter and it doesn’t shoot at all

here’s the zombiebehavior script for more information: local zombie = script.Parent
local humanoid = zombie:FindFirstChildOfClass(“Humanoid”)
local animator = humanoid:FindFirstChildOfClass(“Animator”)
local house = workspace:FindFirstChild(“House”)

local walkAnimations = { – Add your walk animation IDs here
“rbxassetid://137545334964529”,
“rbxassetid://140723213087927”
}

local eatAnimationId = “rbxassetid://83489481475373” – Add your eat animation ID here
local killedAnimations = { – Add your killed animation IDs here
“rbxassetid://138427626345650”,
“rbxassetid://98721502213748”
}

local currentWalkTrack

local function playAnimation(animationId)
local animation = Instance.new(“Animation”)
animation.AnimationId = animationId
local track = animator:LoadAnimation(animation)
track:Play()
return track
end

local function playWalkAnimation()
if currentWalkTrack then
currentWalkTrack:Stop()
end
currentWalkTrack = playAnimation(walkAnimations[math.random(#walkAnimations)])
end

local function moveToHouse()
if house then
local direction = (house.Position - zombie.HumanoidRootPart.Position).Unit
local targetPosition = zombie.HumanoidRootPart.Position

    -- Move in a straight line along one axis at a time
    if math.abs(direction.X) > math.abs(direction.Z) then
        targetPosition = Vector3.new(house.Position.X, zombie.HumanoidRootPart.Position.Y, zombie.HumanoidRootPart.Position.Z)
    else
        targetPosition = Vector3.new(zombie.HumanoidRootPart.Position.X, zombie.HumanoidRootPart.Position.Y, house.Position.Z)
    end

    -- Rotate to face the house
    zombie.HumanoidRootPart.CFrame = CFrame.lookAt(zombie.HumanoidRootPart.Position, house.Position)
    humanoid:MoveTo(targetPosition)
end

end

local function onTouch(other)
local otherHumanoid = other.Parent:FindFirstChildOfClass(“Humanoid”)
if otherHumanoid and otherHumanoid ~= humanoid and not other.Parent.Name:find(“Zombie”) then
if currentWalkTrack then
currentWalkTrack:Stop()
end
local eatTrack = playAnimation(eatAnimationId)
humanoid:MoveTo(humanoid.RootPart.Position) – Stop moving

    -- Inflict 5 or 10 damage per second
    while otherHumanoid.Health > 0 and eatTrack.IsPlaying do
        local damage = math.random(50)
        otherHumanoid:TakeDamage(damage)
        task.wait(1) -- Inflict damage every second
    end

    eatTrack:Stop() -- Stop the eat animation
    task.wait(1) -- Wait one second before resuming walk animation
    playWalkAnimation() -- Resume walk animation
    moveToHouse() -- Resume moving to the house
end

end

local function onHealthChanged(health)
if health <= humanoid.MaxHealth / 2 then
local leftArm = zombie:FindFirstChild(“LeftArm”)
if leftArm then
leftArm:Destroy() – Detach left arm
local bone = zombie:FindFirstChild(“Bone”)
if bone then
bone.Transparency = 0 – Set Bone transparency to 0
end
end
end
if health <= 0 then
local fakeHead = zombie:FindFirstChild(“FakeHead”)
if fakeHead then
fakeHead:BreakJoints() – Detach head
fakeHead.Parent = nil – Remove head from the zombie model
end
local killedTrack = playAnimation(killedAnimations[math.random(#killedAnimations)])
killedTrack.Stopped:Wait() – Wait for the killed animation to finish
zombie:Destroy() – Despawn the zombie
end
end

humanoid.HealthChanged:Connect(onHealthChanged)
zombie.HumanoidRootPart.Touched:Connect(onTouch)

humanoid.MoveToFinished:Connect(function(reached)
if not reached then
moveToHouse() – Retry moving to the house if not reached
end
end)

playWalkAnimation() – Start with a walk animation

while true do
moveToHouse()
task.wait(1) – Adjust the wait time as needed
end

1 Like

I just figured it out but now when i place multiple plants and zombies, they all attack the same zombie i started with how do i fix this?

1 Like

Here’s the new script:

local TweenService = game:GetService(“TweenService”)
local RunService = game:GetService(“RunService”)
local Peashooter = script.Parent
local Humanoid = Peashooter:FindFirstChildOfClass(“Humanoid”)
local Animator = Humanoid:FindFirstChildOfClass(“Animator”)
local PeaTemplate = workspace:FindFirstChild(“Pea”)
local ShootInterval = 1.5
local Damage = 20
local AnimationId = “rbxassetid://108587954936313”
local Sidewalk = workspace:FindFirstChild(“SIdewalk”)
local Zombie = workspace:FindFirstChild(“Zombie”)
local shootingStarted = false

local function playAnimation()
local animation = Instance.new(“Animation”)
animation.AnimationId = AnimationId
local track = Animator:LoadAnimation(animation)
track.Looped = true
track:Play()
end

local function animateHeadAndParts()
local head = Peashooter:FindFirstChild(“FakeHead”)
local mouth = Peashooter:FindFirstChild(“Mouth”)
local hole = Peashooter:FindFirstChild(“Hole”)
if head and mouth and hole then
local originalSize = head.Size
local targetSize = originalSize + Vector3.new(0, 0, originalSize.Z)

    local tweenInfo = TweenInfo.new(0.5, Enum.EasingStyle.Quad, Enum.EasingDirection.InOut)
    local headTween = TweenService:Create(head, tweenInfo, {Size = targetSize})
    local mouthTween = TweenService:Create(mouth, tweenInfo, {CFrame = mouth.CFrame * CFrame.new(0, 0, 2)})

    -- Tween for the Hole part
    local originalHoleSize = hole.Size
    local targetHoleSize = Vector3.new(originalHoleSize.X, originalHoleSize.Y, head.Size.Z + 2) -- Slightly longer than FakeHead's Z-axis
    local holeTween = TweenService:Create(hole, tweenInfo, {Size = targetHoleSize})

    headTween:Play()
    mouthTween:Play()
    holeTween:Play()

    headTween.Completed:Connect(function()
        local returnTween = TweenService:Create(head, tweenInfo, {Size = originalSize})
        returnTween:Play()
    end)

    mouthTween.Completed:Connect(function()
        local returnMouthTween = TweenService:Create(mouth, tweenInfo, {CFrame = mouth.CFrame * CFrame.new(0, 0, -2)})
        returnMouthTween:Play()
    end)

    holeTween.Completed:Connect(function()
        local returnHoleTween = TweenService:Create(hole, tweenInfo, {Size = originalHoleSize})
        returnHoleTween:Play()
    end)
end

end

local function resetHeadSize()
local head = Peashooter:FindFirstChild(“FakeHead”)
if head then
local originalSize = head.Size
local tweenInfo = TweenInfo.new(0.5, Enum.EasingStyle.Quad, Enum.EasingDirection.InOut)
local resetTween = TweenService:Create(head, tweenInfo, {Size = originalSize})
resetTween:Play()
end
end

local function shootPea()
local pea = PeaTemplate:Clone()
local mouth = Peashooter:FindFirstChild(“Mouth”)
if mouth and Zombie then
pea.CFrame = mouth.CFrame
pea.Parent = workspace

    local direction = (Zombie.HumanoidRootPart.Position - mouth.Position).Unit
    local bodyVelocity = Instance.new("BodyVelocity")
    bodyVelocity.Velocity = direction * 50 -- Adjust speed as needed
    bodyVelocity.MaxForce = Vector3.new(1e5, 1e5, 1e5)
    bodyVelocity.Parent = pea

    pea.Touched:Connect(function(hit)
        if hit:IsDescendantOf(Zombie) then
            local zombieHumanoid = hit.Parent:FindFirstChildOfClass("Humanoid")
            if zombieHumanoid then
                zombieHumanoid:TakeDamage(Damage)
                animateHeadAndParts()
                if zombieHumanoid.Health <= 0 then
                    shootingStarted = false
                    resetHeadSize()
                end
            end
            pea:Destroy()
        end
    end)

    task.delay(5, function() -- Destroy the pea after 5 seconds if it doesn't hit anything
        if pea and pea.Parent then
            pea:Destroy()
        end
    end)
end

end

local function startShooting()
while shootingStarted do
shootPea()
task.wait(ShootInterval)
end
end

– Continuously play animation
playAnimation()

if Sidewalk and Zombie then
Sidewalk.Touched:Connect(function(hit)
if hit:IsDescendantOf(Zombie) then
if not shootingStarted then
shootingStarted = true
task.spawn(startShooting)
end
end
end)
end

1 Like

i just lost all the code for the peashooter how am i gonna make it shoot whenever there’s a zombie, have its head and hole part play a stretch tween

and animate at the same time I can’t code!