Damage done unintentionally

I have recently encountered this problem: Damage is done to an object unintentionally, here’s what i mean:


heres my script:

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Dmg = ReplicatedStorage:WaitForChild("Damage")
local Child = script.Parent.Parent:GetChildren()
local db = false

script.Parent.Touched:Connect(function(hit)
	if hit.Parent:FindFirstChild("Tool") then
		if hit.Parent:FindFirstChild("Damage") then
			local tool = hit.Parent:FindFirstChild("Tool")
			local damage = hit.Parent:FindFirstChild("Damage")
			Dmg.OnServerEvent:Connect(function()
				if db == false then
					db = true
					if tool.Value == "Rock" then
						if script.Parent.Health.Value > 0 then
							script.Parent.Health.Value = script.Parent.Health.Value - damage.Value
							print(damage.Value)
						end
						if script.Parent.Health.Value <= 0 then
							for i, v in pairs(Child) do
								if v:IsA("Part") then
									v:Destroy()
								end
							end
						end
						wait(0.85)
						db = false
						else
							if script.Parent.Health.Value > 0 then
							print("s")
							script.Parent.Health.Value = script.Parent.Health.Value - 1
						end
							if script.Parent.Health.Value <= 0 then
								for i, v in pairs(Child) do
									if v:IsA("Part") then
										v:Destroy()
									end
								end
							end
						wait(0.85)
						db = false
					end
				end
			end)
		end
	end
end)

I am wondering what is wrong with the script. I can’t seem to figure it out. I would be thankful if anyone helped me out.

3 Likes

The Dmg.OnServerEvent is never disconnected or stopped, once the Touched has connected it will continue to connect to the Dmg OnServerEvents.

One way you could get around this is that you connect on Dmg OnServerEvents already before touching, check that they’re wielding the tool and calculate their Magnitude between the object and the Rock if it’s close enough.

1 Like

The problem is because of how your scripting the event connection on the server once its get fired once it gets to the event connection line it can keep being fired. Also, this is not the best way to script tools, what you should do is script each individual tool itself and use raycasting or hitboxes to detect the what the tool is touching and then deal the appropriate damage. The method you are currently using can easily be exploited by a hack unless you store a table on the server the last time when the event was fired by a player and wait a certain amount of time before allowing them to fire it again. Instead what i recommend you do is use various tool events on the server such as the equipped and activated events when dealing damage.
You can read about them here under the events section:
https://developer.roblox.com/en-us/api-reference/class/Tool

How do you script Magnitude? If you can, can you give me an example? Sorry, I’m not so good at scripting, I learn from tutorials from YT.

I’m relatively new to studio, so I really need some help on what raycasting is and how to use it, sometimes the information ROBLOX provides about it doesn’t make any sense. In this case, it doesn’t, so can you explain or give and example?

The best option for raycasting would be to add attachments to the tool and cast the a small ray from each attachment on every heartbeat or rendered frame, but since your new to scripting i would recommend you start off with hitboxes. What you essentially do is set up an invisible box around the part and use the GetTouchingParts() function everytime the tool is activated and check if anyone of the touching parts is a part the can be damaged that is not the player’s character, or you can opt to use Region3. I would love to help more but I am really busy working on a game at the moment, I just came on forum for a few mins. Nevertheless here are some posts I have compiled that helped me to understand and should help you:

2 Likes

As Romeo has said, GetTouchingParts/Region3 is a better method however to calculate magnitude you can minus two Vectors and Magnitude it like so:

(Part1.Position - Part2.Position).Magnitude

This is returned in studs.
If you’d like to read more about it, there’s an article here:

Since Romeo is busy right now, can you teach me a bit about raycasting and magnitude? I just watched some tutorials and I just have zero understanding of what they are.

I have many questions:

Is magnitude the distance between objects?
What is raycasting?
How do you use raycasting and magnitude?
How do I incorporate raycasting to my tool?
What is DebrisService?

Yep, it’s the distance between parts measured in studs.

Think about it like this: A straight line is fired in a direction, the first thing it hits it stops at (Unless you’re using an IgnoreList).

Well, I’ve used raycasting for battles where the character spots you walk infront of them.
For magnitude I’ve used it for interactions (E to interact etc).

When they go to move the tool, fire infront of the tool in multiple directions. If it hits the rock calculate that the magnitude is close enough. I haven’t really used raycasting for this so I haven’t had much experience.

Debris service allows for delayed :Destroy()s without yielding the thread.
For example, in wait() and destroy cases it’d be like:

wait(2)
Instance:Destroy()
--Stuff down here would have to wait 2 seconds too! Unless you coroutined the wait(2) and destroy!

Whereas Debris would be like:

local debris = game:GetService("Debris")
debris:AddItem(Instance, 2)
--Stuff down here doesn't have to wait!
1 Like

Most of these terms can be answered through searching their related APIs, documentation or any articles on the Developer Hub. Feel free to perform a little research there. I could still answer your questions.


Magnitude

Magnitude is the distance between two vectors. It is a scalar quantity and it will never be negative. This is often good for cases when you want to compare how far apart two points are from each other. It is the property of a vector, so any vector will have a magnitude: in your case, you are dealing with Vector3 (a vector created on a 3D axis). To use it, you simply need to type .Magnitude on a vector.

local newVector = Vector3.new(0, 0, 0)
print(newVector.Magnitude)

In the case of a vector equation as mentioned in return’s post, subtracting two vectors gives you a vector as well. Therefore, when you perform a vector subtraction, you can also access the resultant vector’s magnitude.

local firstVector = Vector3.new(50, 50, 50)
local secondVector = Vector3.new(100, 100, 100)
local resultantVector = firstVector - secondVector
print(resultantVector.Magnitude)

Raycasting

Raycasting is the creation of a line segment from an origin to a target direction. Raycasts can be used for a large number of cases, though most often it is used to check whether a part intersects the created line segment (meaning the raycast passes through your target points). Ordinarily, a ray is comprised of three parts: the origin (where the ray begins) and the direction (where the ray points towards). Creating a ray is simple and done through the Ray.new constructor.

local originVector = Vector3.new(0, 0, 0)
local directionVector = Vector3.new(50, 50, 50)
local ray = Ray.new(originVector, directionVector)

Keep this in mind: larger rays are more expensive. Expensive means that it could have more impact on performance, which means lag for your game. Short rays have very small costs to perform and usually they won’t do anything to your game. You can use hundreds of them very quickly.


Using Raycast and Magnitude

There are cases where you’ll encounter the need to use a raycast or magnitude, not necessarily together though. In order to use raycasting, you will need to construct a ray (as mentioned above) and use one of the methods responsible for returning intersecting parts. A common example is FindPartOnRay: it is responsible for finding the first part that intersects a ray.

As for magnitude, again, it’s straight forward: use it for cases where you need to compare the distance between two points. Parts in the workspace have their positions represented by vectors, so you can use vector subtraction and access the magnitude to check how far apart positions are.

Note: You can use this to check a character’s distance from something as well, but you really shouldn’t. The engine offers a quick way to do this already, Player.DistanceFromCharacter. That way, new rig constructs won’t affect your calculations and you can have a simple way to check distances.


Incorporating Raycasting

This too is also explained pretty much with the segments above. In your case, with melee, you’ll probably be looking to construct a ray that starts at the tool’s handle, is directed a few studs out (you can use Handle.LookVector for this, which is a vector describing where the part is pointed in relative space to the part) and a length of 1-3.


DebrisService

Answered by reading the documentation for Debris. It allows you to queue the removal of an object after a given interval It’s essentially like calling wait and then Destroy on an instance. That’s it, really.

1 Like

How will I do that? If it is possible, can you provide examples? Sorry if I’m asking for too much.

You could use the Raycasting: Making a laser gun tutorial on the Developer Hub for reference. I wouldn’t recommend using the code as it is, just take parts out of it and drop it into your model.

The concept is relatively the same, just that for the ray’s length (the equation where the unit of the ray is multiplied by 300) you’d be multiplying by a significantly smaller value. You’d also remove any parts of the code that have to do with creating a beam.