Alternatives for Touched Events?

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

1 Like

I mean you could shoot a ray 200 studs. And you could also use velocity instead of a tween as well (thhis one is optional)

1 Like

The ray could work, but if it hit a player, then the player moves away, it would just tween to where the player was and not hit anything

Then what i’d do is wait until the ray hit something and then tween the fireball over to the player.

The problem is that the player might keep moving which then youd need another solution

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

(idk if the math for this is correct)

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.

You could even use GetPartBoundsInBox()
WorldRoot | Documentation - Roblox Creator Hub

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?

I don’t see how this would work, but i tried it anyways, still very inconsistent

i played around with some of the values in the raycast and fixed it

1 Like

Your fireball is probably bigger than a single raycast, hence why it might seem “inconsistent”.

Try looking into shapecasts – might work better for your usecase?

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.