I’m mading spells power for one of my game project, and i got a problem with tween position and damages.
When i’m using Tween Service, the MeshPart need to be anchored, when i move the spell forward the character, it work and the movement is smooth but it do no damage, i don’t understand why.
When i’m using BodyVelocity, the MeshPart isn’t anchored, Damages work but spell movement isn’t smooth, it’s a bit laggy.
So here i want to keep a smooth movement for my spell, but fix this damage problem
TweenService
BodyVelocity
Here is the main script [Tween Service]:
local Module = {}
Module.QSpell = function(Player)
local Character = Player.Character
local Slash = game.ReplicatedStorage.Spells.Knight.Slash
if Character ~= nil and Slash ~= nil then
local TweenService = game:GetService("TweenService")
local TweenInfos = TweenInfo.new(1)
local Clone1 = Slash:Clone()
local Clone2 = Slash:Clone()
local Clone3 = Slash:Clone()
Clone1.Touched:Connect(function(Part)
if Part.Parent:FindFirstChild("Humanoid")and not game.Players:FindFirstChild(Part.Parent.Name)then
Part.Parent.Humanoid:TakeDamage(15)
Clone1:Destroy()
end
end)
Clone2.Touched:Connect(function(Part)
if Part.Parent:FindFirstChild("Humanoid")and not game.Players:FindFirstChild(Part.Parent.Name)then
Part.Parent.Humanoid:TakeDamage(15)
Clone2:Destroy()
end
end)
Clone3.Touched:Connect(function(Part)
if Part.Parent:FindFirstChild("Humanoid")and not game.Players:FindFirstChild(Part.Parent.Name)then
Part.Parent.Humanoid:TakeDamage(15)
Clone3:Destroy()
end
end)
Clone1.Parent = game.Workspace
Clone1.CFrame = Character.Torso.CFrame
local Goal1 = {}
Goal1.CFrame = Clone1.End.CFrame
local Tween1 = TweenService:Create(Clone1, TweenInfos, Goal1)
Tween1:Play()
wait(0.2)
Clone2.Parent = game.Workspace
Clone2.CFrame = Character.Torso.CFrame
local Goal2 = {}
Goal2.CFrame = Clone2.End.CFrame
local Tween2 = TweenService:Create(Clone2, TweenInfos, Goal2)
Tween2:Play()
wait(0.2)
Clone3.Parent = game.Workspace
Clone3.CFrame = Character.Torso.CFrame
local Goal3 = {}
Goal3.CFrame = Clone3.End.CFrame
local Tween3 = TweenService:Create(Clone3, TweenInfos, Goal3)
Tween3:Play()
wait(1)
if Clone1 ~= nil then
Clone1:Destroy()
end
wait(0.2)
if Clone2 ~= nil then
Clone2:Destroy()
end
wait(0.2)
if Clone3 ~= nil then
Clone3:Destroy()
end
end
end
return Module
Here is the main script [Body Velocity]:
local Module = {}
Module.QSpell = function(Player)
local Character = Player.Character
local Slash = game.ReplicatedStorage.Spells.Knight.Slash
if Character ~= nil and Slash ~= nil then
local Clone1 = Slash:Clone()
local Clone2 = Slash:Clone()
local Clone3 = Slash:Clone()
local BodyVel1 = Instance.new("BodyVelocity", Clone1)
local BodyVel2 = Instance.new("BodyVelocity", Clone2)
local BodyVel3 = Instance.new("BodyVelocity", Clone3)
Clone1.Touched:Connect(function(Part)
if Part.Parent:FindFirstChild("Humanoid")and not game.Players:FindFirstChild(Part.Parent.Name)then
Part.Parent.Humanoid:TakeDamage(15)
Clone1:Destroy()
end
end)
Clone2.Touched:Connect(function(Part)
if Part.Parent:FindFirstChild("Humanoid")and not game.Players:FindFirstChild(Part.Parent.Name)then
Part.Parent.Humanoid:TakeDamage(15)
Clone2:Destroy()
end
end)
Clone3.Touched:Connect(function(Part)
if Part.Parent:FindFirstChild("Humanoid")and not game.Players:FindFirstChild(Part.Parent.Name)then
Part.Parent.Humanoid:TakeDamage(15)
Clone3:Destroy()
end
end)
Clone1.Parent = game.Workspace
Clone1.CFrame = Character.Torso.CFrame
BodyVel1.Velocity = Character.Torso.CFrame.lookVector * 50
wait(0.2)
Clone2.Parent = game.Workspace
Clone2.CFrame = Character.Torso.CFrame
BodyVel2.Velocity = Character.Torso.CFrame.lookVector * 50
wait(0.2)
Clone3.Parent = game.Workspace
Clone3.CFrame = Character.Torso.CFrame
BodyVel3.Velocity = Character.Torso.CFrame.lookVector * 50
wait(1)
if Clone1 ~= nil then
Clone1:Destroy()
end
wait(0.2)
if Clone2 ~= nil then
Clone2:Destroy()
end
wait(0.2)
if Clone3 ~= nil then
Clone3:Destroy()
end
end
end
return Module
Nop touched function not work with CFraming, i got help on discord.
“Thats probably because CFraming doesnt take into account touch connections, because technically you are teleporting the part small distances, whereas BodyVelocity actually moves the part through the 3D space, which allows for touch connections to happen.”
I will try to use magnitude to cast the spell damage instead of touched function
Use raycasting for the trajectory instead of touched with tweenservice.
local params = RaycastParams.new()
params.FilterDescendantsInstances = {character, script.Parent}
params.FilterType = Enum.RaycastFilterType.Blacklist
local ray = workspace:Raycast(origin, direction * range, params)
if ray then
local hit, pos = ray.Instance, ray.Position
end
Alright, it work with magnitude, i just need to find a better optimisation by replacing the loop
while wait(0.1)do
for _,Child in pairs(game.Workspace.Enemies:GetChildren())do
if Child:IsA("Model") then
local EnemiesHumanoid = Child:FindFirstChild("Humanoid")
local EnemiesTorso = Child:FindFirstChild("Torso")
local Part = script.Parent
if EnemiesHumanoid ~= nil and EnemiesTorso ~= nil and (EnemiesTorso.Position - Part.Position).magnitude < 5 then
EnemiesHumanoid:TakeDamage(15)
script.Parent:Destroy()
end
end
end
end
Tween’s don’t trigger a .touched if the other player is not moving. Something needs to interact with it/ touch it. Try using raycasting like @8_8io said, using magnitude to check if it’s in distance and giving it damage. Here’s some more info on it: Raycasting | Roblox Creator Documentation. Unsure if you’re familiar with it, so just sending it just in case. You can then delete the spell or make it transparent once you’re done.
TLDR: Tweens dont work with .touched because it’s not movement. Use raycasting. check if player close, give damage. delete spell thingy majig
As far as detecting “touch”, I would recommend using Region3 as it’s far better at detecting part intersections. However, you’ll probably want to use RotatedRegion3.
You can also try GetTouchingParts, but I doubt that’ll work as well, if at all.
Do not recommend magnitude detection for every enemy count, as the count increases the performance is severely affected from continuous loops. Raycast instead for one time detection.
Alright, thanks for your help everyone
Here is my new codes, and it perfectly work now
Main Script
local Module = {}
Module.QSpell = function(Player)
local Character = Player.Character
local Slash = game.ReplicatedStorage.Spells.Knight.Slash
if Character ~= nil and Slash ~= nil then
local TweenService = game:GetService("TweenService")
local TweenInfos = TweenInfo.new(1)
for Count = 1, 3 do
local Clone = Slash:Clone()
Clone.Parent = game.Workspace.Spell
Clone.Name = "KnightSlash"
Clone.CFrame = Character.Torso.CFrame
local Goal = {}
Goal.CFrame = Clone.End.CFrame
local Tween = TweenService:Create(Clone, TweenInfos, Goal)
Tween:Play()
wait(0.2)
end
end
end
return Module
Raycast script
script.Parent.Changed:Connect(function()
if script.Parent.Parent.Name == "Spell" then
local rayOrigin = script.Parent.Position
local rayDirection = Vector3.new(20, 20, 20)
local raycastParams = RaycastParams.new()
raycastParams.FilterDescendantsInstances = {game.Workspace.Enemies}
raycastParams.FilterType = Enum.RaycastFilterType.Whitelist
local raycastResult = workspace:Raycast(rayOrigin, rayDirection, raycastParams)
if raycastResult then
local Part = raycastResult.Instance
if Part.Parent:FindFirstChild("Humanoid") and not game.Players:FindFirstChild(Part.Parent.Name) then
local Humanoid = Part.Parent:FindFirstChild("Humanoid")
if Humanoid ~= nil then
Humanoid:TakeDamage(15)
script.Parent:Destroy()
end
end
end
wait(0.9)
script.Parent:Destroy()
end
end)