Weird Problem with Touched Event & Anchoring

Hey!

I have been trying to experimenting with this. I found some weird problems with Touched Event with the use of anchoring.

As you can see this only occurs when anchoring is done on local script while touch event is done on server script.

The weird problem is it triggers touch event every time it is anchored & unanchored on local script.

PROPER EDITED VIDEO ON HOW TO REPRODUCE THIS WEIRD PROBLEM


Do anyone know why this is happening? I’ve been trying to fix the weird problem for hours on my main game.

4 Likes

I’m guessing this is because touched events are usually handled on the client, and when it gets unanchored on the client and the part moves slightly and the touched event gets fired, but when it’s unanchored on the server, the tiny position changes don’t get replicated on the client, which means it doesn’t recognise the part being touched.

I’m interested to know how this could be a problem.

By the way, why is your character walking so strangely?

4 Likes

Interesting, though I think that doesn’t really make sense why Touched Event would be handled on client, that could be security issues (let’s say it’s used for combat stuff).

The reason my character is walking strangely is pretty obvious, because there’s the script loop in the video I provided above that sets my character to be anchored and unanchored every few seconds.

But yeah, I am also interested to know that too! I’d like to receive a reply from official Roblox staff member who works for Roblox Studio. :pray:

This is the problem that I’ve been trying to fix for weeks on my main game until I finally identified how it occurs. This is really… WEIRD!!!

4 Likes

Replicating the entire character is a lot of data and takes time.
On the server the player is always a few steps behind what they are on the client.
A touch event can be fired to the server much quicker than the entire character can be replicated/updated.
So the server can act upon the event faster by the client handling it.
This is for better responsiveness for the player, as the server would have a larger delay if it did the touch events.

To add, due to this delay difference between client and server and how replication functions, it could actually make false detections or miss detections. Relying on the server with this can create inaccuracies. So these reasons are ultimately why the client handles touch.

6 Likes

That’s pretty interesting, that somewhat makes sense. But I would personally say this is not really somewhat just inaccurate but rather a problem that was not supposed to happen?

Like, sure if you anchor and unanchor, it should cause delay but instead creates false detection? I think that’s not just inaccurate due to delays but rather a potential bug? I am not really sure.

I was saying the problem should never happen in the first place regardless of whether it is handled in server or client.

unless, was everyone advised to handle touch events stuff on client-sided…?

I really wanted to handle touch events on server due to security concerns.

3 Likes

In this case I’m assuming by “handling” you mean registering?

That wouldn’t really work for the reasons @MineJulRBX has stated earlier, you’d have to replicate the player character to the server every time, and since there’s a significant delay, that would cause lots of desync and headaches. The reason the client controls the player character is so the player doesn’t have to wait 50-100ms after pressing a key to get a response from the server and see their character react. That’d be very noticeable and annoying.

2 Likes

When I say handling, I mean connecting (registering sure) to the Touched event on server and simply print when the player touches the big part.

I understand the reason why it happens but what I don’t understand is how some delay could cause it to trigger the touched event multiple times.

As you can see, when I am not moving at all for long time, it still constantly triggers, meaning that delay isn’t the issue, replication is probably also not issue. There has to be something else.

If it is true about some delay, it could have triggered late sure? But instead it triggers many times, even if you aren’t moving at all (as long as you’re inside the big part). That does not make sense.

Once again, this is more related to anchoring & unanchoring that causes the above issue, so remember that.

1 Like

That’s not what I was talking about, I was explaining why touched events register on the client instead of the server.

2 Likes

But I’m curious, why is this such a big issue? Could you explain how you’re using this?

1 Like

Oh alright, I was a bit confused. Alright thanks for the above explanation. Though that is probably not necessary?

Soooo about the “big issue”, I was considering using the Touched event for creating parts used to name locations in my main game. It was originally for tracking how many players are in certain areas. If one touches another area, it adds the player to the record list.

With this potential issue, it could cause serious problems such as triggering too many times and will cause the function to be confused.

Unless there is a better solution for that, unfortunately I had to complain about this and get more information so that it can be resolved.

It was used for something like giving certain rewards, etc. Therefore, I cannot handle areas & Touched events on client-side script.

Furthermore, I used anchoring & unanchoring as the way of preventing players from moving, I can not use other solutions of prevent players from moving such as Humanoid & Moved event as it can cause conflict with my other scripts. Therefore, anchoring is the only way I can reliably prevent the player from moving.

1 Like

Instead of using touch events, you could check which players are inside a part.

To do this, you could use WorldRoot:GetPartsInPart(). It returns a table with all the parts inside, which you can go through to find any humanoidrootparts.

1 Like

I’ve already considered that but unfortunately, there is no way to trigger events when players begins getting inside the part as I need that for my other events such as OnEnteringArea

1 Like

You could have a loop which checks every second or so

1 Like

Are you sure? Using that to check GetPartsInPart() Also that wouldn’t allow me to immediately get the player who entered the area, imagine knowing that someone entered but you have so many players that you don’t even know who entered.

1 Like

So first of all, as it has been mentioned before, player’s humanoids touch events are generated on client, even when you are connecting to that event on server.

That means server depends on the client to provide it with the accurate touch events. There is no need to set up touch event on client and fire remote to notify the server. If you need to know where players are, set up proper function in the server script.

Now for player area detection.

This is a system that I use and is a touch/polling hybrid. It works like this:

  1. Detection detects touch event from player’s character.
  2. Player is added to that area dictionary, and further touch events from this player are ignored.
  3. Polling starts and keeps checking player distance from the middle of area. Break away distance should be slightly larger than the area radius.
  4. Once player leaves, they are removed from the dictionary and script waits for the next touch event from the player, should player wishes to re-enter.

By having separate dictionary and function for each area, I can even have intersecting areas:

Example code (server script). This works best if the areas are circular.
For rectangular areas, escape should be calculated with math.abs separately for x and z:

local Register = {}
local ESCAPE_RADIUS = 100 --should be larger than area

for _, area in pairs(workspace.Areas) do
	
	Register[area] = {}
	
	area.Touched:Connect(function(hit)
		
		local root = hit.Parent:FindFirstChild("HumanoidRootPart")
		
		if not root then return end
		
		local plr = game.Players:GetPlayerFromCharacter(hit.Parent)
		
		if not plr then return end
		
		if Register[area][plr] then return end
		
		Register[area][plr] = true
		
		while plr.Character == hit.Parent and (area.Position - root.Position).Magnitude < ESCAPE_RADIUS do
			
			task.wait(1)
			
		end
		
		Register[area][plr] = nil
				
	end)
	
end

Hope this helps.

2 Likes

You can get the player who entered the region by checking for any humanoids in the table, then run :GetPlayerFromCharacter on its parent.

I’m sure there are much better ways to detect whether a player is inside a region.

1 Like

I just did some more digging and found this module called ZonePlus. It lets you see when players enter & leave zones, without a big performance cost. You can also use it to spawn different items in certain zones, such as coins. Here’s an introduction video.

Awesome! I already found that and it solved my problem a while ago.

Meanwhile I’ve already filed the bug report for that. I guess we should consider this as the workaround :+1:

1 Like

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