I am making an ability with a weapon that lets you shoot a fireball that tweens 200 studs in the direction that the player is facing, and explodes when it touched anything, but touched events can be quite unreliable with tweens, so are there any other ways I can do this?
the script button on here is gone for some reason so i just have to write it normally
script.Parent.AbilityEvent.OnServerEvent:Connect(function(plr,ability)
if ability == “Q” then
if cd1 == false then
cd1 = true
local char = plr.Character
local hrp = char:WaitForChild(“HumanoidRootPart”)
local fireball = game.ServerStorage.AbilityObjects.Fireball:Clone()
fireball.Touched:Connect(function(hit)
print(“put code here”)
end)
fireball.CFrame = hrp.CFrame + hrp.CFrame.LookVector * 5
fireball.Orientation = Vector3.new(0,fireball.Orientation.Y + 90,90)
fireball.Parent = workspace
local goal = hrp.Position + hrp.CFrame.LookVector * 200
ts:Create(fireball,TweenInfo.new(3,Enum.EasingStyle.Linear),{Position = goal}):Play()
game:GetService(“Debris”):AddItem(fireball,3)
wait(1)
wait(5)
cd1 = false
end
You shouldn’t be using Touched when working with projectiles. Touched works by firing when two surfaces connect, which means an object can phase through the other object (or be inside it) and no surfaces connect, and as such the event wont fire. (also changing CFrame wont fire Touched events anyway, because it doesn’t update the collision part of the physics engine on its own)
You should use raycasting instead on each step while the object is moving, then used the return result to figure out what was hit.
Oh and for the Tween thing, consider looking into TweenService:GetValue, which lets you use the interpolation functions between the time alphas 0 and 1. (for custom tweening implementations, which may be useful here, where the goal is moving)
If you’re doing CFrames, you can make a simple while loop that takes the delta from a task.wait, and iterate a counter, then lerp between the start and current goal CFrame.
local time = 0
local MAX_TIME = 5
while time < MAX_TIME do
time = math.clamp(t + task.wait(), 0, MAX_TIME)
local tweenAlpha = TweenService:GetValue(time / MAX_TIME, Enum.EasingStyle.Quad)
-- you dont need to use this if you want a linear tween, just put time / MAX_TIME in the lerp directly
newPosition = origin:Lerp(goal, tweenAlpha)
end
I’d use raycasts and cframe the fireball. Shoot rays as the projectile moves, and if it touches something, then do something.
If you’re fireball is big tho, you might want a bigger hitbox, so maybe shapecasts are better. But then there’s the fact that margins aren’t considered with shapecasts, which is when you cast a shape within a part and it doesn’t count bc the shapecast is already within the part.
So then the other option is casting multiple rays to simulate a bigger hitbox.
This kinda worked, but it is still very inconsistent
script.Parent.AbilityEvent.OnServerEvent:Connect(function(plr,ability)
if ability == “Q” then
if cd1 == false then
cd1 = true
local char = plr.Character
local hrp = char:WaitForChild(“HumanoidRootPart”)
local function fireball()
local fireball = game.ServerStorage.AbilityObjects.Fireball:Clone()
fireball.CFrame = hrp.CFrame + hrp.CFrame.LookVector * 5
fireball.Orientation = Vector3.new(0,fireball.Orientation.Y + 90,90)
fireball.Parent = workspace
local goal = hrp.Position + hrp.CFrame.LookVector * 200
ts:Create(fireball,TweenInfo.new(3,Enum.EasingStyle.Linear),{Position = goal}):Play()
game:GetService("Debris"):AddItem(fireball,3)
game:GetService("RunService").Heartbeat:Connect(function()
local pos = fireball.Position
local direction = fireball.CFrame.LookVector
local distance = .5
local result = workspace:Raycast(pos,direction * distance)
if result then
print(result.Instance)
local explosion = Instance.new("Explosion")
explosion.Parent = fireball
end
end)
end
fireball()
wait(1)
cd1 = false
end
Try adding a RaycastParams to your raycast, setting it’s FilterType to Enum.RaycastFilterType.Include and adding the fireball to it’s FilterDescendantsInstances?