Well, I’m programming a skill system and I’m currently working on a Gojo skill, aka “Hollow Purple”, all vfx are replicated to the clients through a replicator module script, however the hitbox is 100% done on the server, the big problem is that since Hollow Purple is launched by the client, the server doesn’t really know the exact position it is in to move the hitbox along with it, so I ended up opting for the option of using the tweenservice to move the hitbox along with a loop, I wanted to know if there is a more optimized way to do this.
ServerCode:
["Hollow Purple"] = {
SkillName = "Hollow Purple";
Input = Enum.KeyCode.V;
CooldownTime = 2; -->> Debug Only
InCooldown = false;
IsHoldSkill = false;
Action = function(Character : Model)
local Player = Players:GetPlayerFromCharacter(Character)
local Humanoid = Character:WaitForChild("Humanoid")
if Character:GetAttribute("UsingSkill") then
return
end
--// Animations
local PurpleAnimation = Humanoid:FindFirstChildWhichIsA("Animator"):LoadAnimation(LimitlessAnimations:FindFirstChild("HollowPurple"))
--// Attributes
Character:SetAttribute("CanRun",false)
Character:SetAttribute("CanDash",false)
Character:SetAttribute("IFrames",true)
Character:SetAttribute("UsingSkill",true)
Humanoid.WalkSpeed = 2
Humanoid.JumpPower = 0
--// Purple VFX
PurpleAnimation:Play()
Events:FindFirstChild("CameraShaker"):FireClient(Player,"StartShake",1.5,3,0.1,1,6)
PurpleAnimation:GetMarkerReachedSignal("Blue"):Wait()
Replicator:FireAllDistanceClients(Character,500,{Folder = Modules:WaitForChild("VisualEffects"):FindFirstChild("Skills"),ModuleName = "Limitless_Effects",FunctionName = "HollowPurple_ShowBlue"},Player)
PurpleAnimation:GetMarkerReachedSignal("Red"):Wait()
Replicator:FireAllDistanceClients(Character,500,{Folder = Modules:WaitForChild("VisualEffects"):FindFirstChild("Skills"),ModuleName = "Limitless_Effects",FunctionName = "HollowPurple_ShowRed"},Player)
--red
PurpleAnimation:GetMarkerReachedSignal("Release"):Wait()
Replicator:FireAllDistanceClients(Character,500,{Folder = Modules:WaitForChild("VisualEffects"):FindFirstChild("Skills"),ModuleName = "Limitless_Effects",FunctionName = "HollowPurple"},Player)
local HumanoidRootPart = Character:FindFirstChild("HumanoidRootPart")
if not HumanoidRootPart then return end
local AllHitboxCharacters = {}
local Hitbox = HitboxModule.RealTimeHitbox(
CFrame.new((HumanoidRootPart.Position + Vector3.new(0,5,0)) + HumanoidRootPart.CFrame.LookVector * 20).Position,
Character,
35,
{Character},
false
)
local Direction = HumanoidRootPart.CFrame.LookVector
Hitbox.PhysicPart.CFrame = CFrame.new(Hitbox.PhysicPart.Position, Hitbox.PhysicPart.Position + Direction)
local TweenCompleted = false
local HitboxTween = TweenService:Create(
Hitbox.PhysicPart,
TweenInfo.new(2.5),
{CFrame = Hitbox.PhysicPart.CFrame + (Direction * 400)}
)
HitboxTween:Play()
task.spawn(function()
HitboxTween.Completed:Wait()
TweenCompleted = true
end)
repeat
local PartsInside = Hitbox.GetPartsInside()
for index, Parts in PartsInside do
if Parts and Parts.Parent then
local Humanoid = Parts.Parent:FindFirstChild("Humanoid")
if Humanoid then
local HitCharacter = Parts.Parent
if HitCharacter:IsA("Model") and not table.find(AllHitboxCharacters, HitCharacter) then
table.insert(AllHitboxCharacters, HitCharacter)
RagdollModule:Ragdoll(HitCharacter)
CombatModule.LocalFunctions:StunCharacter(HitCharacter, 5)
local KnockbackForce = (Hitbox.PhysicPart.Position - HumanoidRootPart.Position).Unit * math.random(600,1200)
local UpwardForce = Vector3.new(0, math.random(1200,1600), 0)
HitCharacter.PrimaryPart:ApplyImpulse(KnockbackForce + UpwardForce)
task.delay(5, function()
RagdollModule:unRagdoll(HitCharacter)
end)
end
end
end
end
task.wait(0.15)
until (TweenCompleted or not Hitbox.PhysicPart.Parent)
Hitbox.DestroyHitbox()
AllHitboxCharacters = nil
Character:SetAttribute("CanRun",true)
Character:SetAttribute("CanDash",true)
Character:SetAttribute("IFrames",false)
Character:SetAttribute("UsingSkill",false)
Humanoid.WalkSpeed = 14
Humanoid.JumpPower = 50
end
}
External Media
Video