Problem with my ability

I tried to make my own ability but for some reason It freezes me mid air and it doesn’t do 50 dmg it just 1 shots??

Classic Baseplate.rbxl (71.5 KB)

Would absolutely love some code reviewing for my first ability too ^^

(I have no idea AT ALL how to make abilities and so I just winged it)

1 Like

As far as functionality goes you did a pretty good job making this ability especially considering you’re new to it :+1:, although there are a couple things I’ll suggest at the end for making the code cleaner.

But first, both of the problems you mentioned come from the Script:

The reason you freeze midair is because you are anchoring the character’s HumanoidRootPart when the ability is activated: hrp.Anchored = true. I’m unsure if you want the character to be anchored to some extent while casting the ability, but if not you can just remove this line and other the line hrp.Anchored = false to stop the ability from freezing you in place.

If you do want the character to be anchored for the duration of the explosion effect (which is 2 seconds according to the wait(2)), the problem with your current code is that the line to unanchor the character is inside of the .Touched event, meaning the character will only be unfrozen if the explosion hits something (also the explosion effect ever being deleted also depends on if it hits something or not, for the same reason). To fix this, just move the last 3 lines in the .Touched event to be outside:

The reason the explosion is 1-shotting the dummies is because the .Touched event is firing for every part in the model. For an R6 model like the dummies, there are 7 body parts meaning the damage is applied 7 times for a total of 350 damage which is why its getting 1 shot. To make sure the damage is only applied once per humanoid you need to keep track of which have already been hit and only apply damage if the current touched part is not in the list:

In this code, hitList is a dictionary for recording the characters that have been damaged. If a character has been damaged then the character model instance is used as a key for the dictionary with the entry set to true (hitList[hitChar] == true), otherwise the entry for the key is nil (hitList[hitChar] == nil) which is a falsy value. This way whether or not the hit character has already been damaged can be determined just by checking their entry in the hitList.

Edited code
local remote = script.Parent.Parent.RemoteEvent
local replicated =  game:GetService("ReplicatedStorage")

remote.OnServerEvent:Connect(function(char, player, tool)
	print("Server Recieved Call From Client . . . Initiating")
	
	
	local explosion = replicated.FX.template:Clone()
	
	local hrp = player:WaitForChild("HumanoidRootPart")
	
	hrp.Anchored = true
	
	explosion.Parent = workspace
	
	explosion.CFrame = CFrame.new((hrp.CFrame*CFrame.new(0, 0, 0)).Position)
	
	local hitList = {}
	
	explosion.Touched:Connect(function(hit)
		if hit.Parent:FindFirstChild("Humanoid") then
			local hitChar = hit.Parent --the character associated with the hit part
			
			if hitChar == char or hitList[hitChar] then return end --dont damage if hitChar is you or if hitChar has already been hit
			
			hitList[hitChar] = true --record that hitChar has been hit
			
			hitChar.HumanoidRootPart.CFrame = CFrame.lookAt(hitChar.HumanoidRootPart.Position, explosion.Position) * CFrame.Angles(0, math.pi, 0)
			
			local Damage = 50 -- Damage Amount
			hitChar.Humanoid:TakeDamage(Damage)
		end
	end)
	
	wait(2)
	hrp.Anchored = false
	explosion:Destroy()
end)

There’s another problem I noticed in the Local Script

One thing you left out is the gameProcessedEvent parameter that the InputBegan and InputEnded events provide, which tells you whether or not the input was actually used for the game. One common use of this is determining whether the player is typing in chat (gameProcessedEvent == true) or not (gameProcessedEvent == false). As you have it now, typing the letter “e” (or “E”) into chat will fire the ability, which is probably not something you want. The fix is simply to check if the input is processed or not:

And that’s all for fixing the bugs. For general practices you can use to make your code cleaner, first I suggest keeping the indents of the scopes consistent. This means all the code inside something like an if statement or a function definition should be spaced one indent past the header:

Good:

if this then
	that()
end

Not good:

if this then
that()
end

Also not good:

if this then
			that()
end

Also I noticed in your original code that your ends were kinda scattered (I fixed them in the edited code). They should always be lined up with the header that they are ending:

Good:

if this then
	that()
end

Not good:

if this then
	that()
		end

These are small details that don’t affect the functionality of the code but as things get more and more complex and you start nesting lots of if statements and other things it’s really important for the sake of readability that everything is lined up properly.

Lastly I suggest sticking to one naming convention inside of scripts. This is probably the least important for readability but it is good practice. In the context of programming, the naming convention refers to how the names of things like variables and functions are formatted. The 3 main ones are:

  1. Snakecase, where words are all lowercase and separated by underscores. Example: humanoid_root_part
  2. Pascalcase, where all words are capitalized. Example: HumanoidRootPart.
  3. Camelcase, where the first word is lowercase and all others are capitalized. Example: humanoidRootPart.

Personally for Roblox I use Camelcase for naming things in scripts and Pascalcase when naming instances in the workspace (like parts), but you can choose whatever you like as long as it’s consistent.

Hope this helps

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