Using magnitude to detect players?

I’m looking to create a player launchpad that doesn’t suffer from the delays inherent to .Touched. I’ve seen that apparently Magnitude can be used for this, but I’m having trouble figuring out exactly how I can use magnitude to detect the presence of a player.

What kind of logic do I need to use magnitude to detect a player that is touching a launchpad?

1 Like

So what you can do alternatively to .Touched is iterate through the workspace, going through each and every character in the game, while finding the magnitude from the player to the launchpad. (CharactersPrimaryPartsPos - LaunchPadPos).magnitude. Then if a player is within a certain magnitude of the launchpad, you can run the function that launches the player.

1 Like

That seems like it would be slower than using .Touched, especially since that loop would have to be running constantly.

Have you considered using the .Touched event on the client, then firing a function to the server? There aren’t really many other ways to use magnitude other than repeatedly looping through the players in the game. You can even do a sanity check on the server to make sure that the clients request is reasonable.

(I agree using magnitude in the manner I explained can be slow)

3 Likes

That’s a clever idea - put a local script in the client that detects when a booster is touched, have it fire an event that the server listens for, and use that to bounce the player. I’ll have to give that a try and see if it works better.

1 Like

So I’m trying to make this work, but I’m running into a strange problem. The bouncer is going to pass two pieces of data: the player’s name, and the bouncer’s orientation to the server script so that it knows which direction to bounce the player. The problem is that when I pass this data, I get two instances of the player instead of one instance of the player and a number.

The code, for reference:

LocalScript

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local bounceEvent = ReplicatedStorage:WaitForChild("bounceEvent")
local player = game.Players.LocalPlayer
local character = player.Character
if not character or not character.Parent then
	character = player.CharacterAdded:wait()
end
local humanoid = character:WaitForChild("Humanoid")
local cooldown = .2
local isTouched = false

humanoid.Touched:connect(function(hit)
	if not isTouched then
		if hit.Name == "bouncer" then
			isTouched = true
			local direction = hit.Orientation.Y
			bounceEvent:FireServer(player, direction)
			print("local side " .. direction .. " bouncer fired by " .. character.Name)
			wait(cooldown)
			isTouched = false
		end
	else
	end
end)

Server script:

local ReplicatedStorage = game:GetService("ReplicatedStorage")

local bounceEvent = Instance.new("RemoteEvent", ReplicatedStorage)

bounceEvent.Name = "bounceEvent"

local function onBounceFired(player, direction)

print(player)

print(direction)

end

bounceEvent.OnServerEvent:Connect(onBounceFired)

The result I’m expecting from the server script is:

ObsidianRook
0

But I’m getting

ObsidianRook
ObsidianRook

Why is this happening? How else could I pass these two bits of data?

1 Like

The player is automatically passed as an argument from the client to the server, you don’t need to pass the player again. Just do :FireServer(direction)

I’ve made that change, but I’m still getting

ObsidianRook

instead of the expected

0

You are waiting for the humanoid to get touched instead of the launchpad? The humanoid I don’t think can be touched.

The LocalScript needs to be in the player, so it can’t watch for a launchpad to be touched. Also, if Humanoid couldn’t be touched I wouldn’t be getting anything back, right?

Hmm, I suppose your right, I just have never done something like that.
I did find a API Reference Article on it though.
https://developer.roblox.com/en-us/api-reference/event/Humanoid/Touched
I will try to look into some other problems you may be having :slight_smile:

Alrighty, so I just tested the scripts, as well as the humanoid touched event (super cool)
and everything works as is supposed to?
Client:

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local bounceEvent = ReplicatedStorage:WaitForChild("bounceEvent")
local player = game.Players.LocalPlayer
local character = player.Character
local humanoid = character:WaitForChild("Humanoid")
local cooldown = .2
local isTouched = false

humanoid.Touched:connect(function(hit)
	if not isTouched then
		if hit.Name == "bouncer" then
			isTouched = true
			local direction = hit.Orientation.Y
			bounceEvent:FireServer(direction)
			print("local side " .. direction .. " bouncer fired by " .. character.Name)
			wait(cooldown)
			isTouched = false
		end
	else
	end
end)

Server:

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local bounceEvent = ReplicatedStorage:WaitForChild("bounceEvent")

bounceEvent.Name = "bounceEvent"

local function onBounceFired(player, direction)
	
	print(player)

	print(direction)

end

bounceEvent.OnServerEvent:Connect(onBounceFired)

Really the only change I made was the FireServer one, and instead of instancing a remote event, I added it to the replicated storage beforehand. (Shouldn’t really matter)

The output is:
local side 2.039999961853 bouncer fired by TheAnimeDev28 - Client - LocalScript:15
12:29:30.292 TheAnimeDev28 - Server - Script:8
12:29:30.292 2.039999961853 - Server - Script:10

I tried using the scripts you posted, but I get

Players.ObsidianRook.PlayerScripts.LocalScript:5: attempt to index nil with 'WaitForChild'

and nothing works. Where are you putting the client-side script? Mine is in StarterPlayerScripts.

Make sure the client script is in StarterCharacterScripts. Server Script I placed in Server Script Service and the Remote event in Replicated Storage.

Okay, got it! The problem is that the localscript was in StarterPlayerScripts, not StarterCharacterScripts.

I’m so glad that worked! Does everything else work properly? (You can just like this post if everything does work and if I answered your question fully, mark a solution).

All I need to figure out now is how to figure out how to actually make the player bounce how I want. In the old bounce pad, I used a BodyForce with hardcoded values, but since this script will have to work on all bounce pads, I need to figure out some way to mathematically generate a Vector3 - or rather, the X and Z values of one - based on the orientation value passed into the function. I have no idea how I’m going to do that yet.

I’m sure you can find other forum posts on things similar to this, but it seems that your original question was answered which is great :slight_smile: . Just keep practicing and improving!