Part Touched event not triggered while tweening

I have encountered some awkward behaviour and I would appreciate any help in dealing around this.

local TweenService = game:GetService("TweenService")

local tweenInfo = TweenInfo.new(2, Enum.EasingStyle.Linear, Enum.EasingDirection.Out, -1, true, 0 ) -- infinite tween

-- dummy part which will be tweened, positioned at 0,-5,0
local dummyPart = Instance.new("Part", workspace)
dummyPart.Position = Vector3.new(0,-5,0)
dummyPart.Anchored = true
dummyPart.CanCollide = true

dummyPart.Touched:Connect(function(touchedPart) -- action taken when touch detected
   print('touch detected: ', touchedPart.Name) -- print something for testing purposes
end)

local tweenGoal = {}
tweenGoal.Position = Vector3.new(0,5,0)
TweenService:Create(dummyPart, tweenInfo, tweenGoal):Play() -- create & play tween

Looking at the above code, a dummy part is being tweened through the baseplate and back infinitely. But the Touched event is fired when my Humanoid touches the part but not when the baseplate is touched.

How can I get the Touched event to fire when baseplate is touched?

It works when I make one of the parts (baseplate or dummy part) as not anchored, but I want both to be anchored. Some people have suggested to use an inifinite loop and use the GetTouchingParts() to understand if there is a touching part or not but this is really odd - it is a hack. I want to get the Touched event to fire.

What are my options?

4 Likes

In order for a .Touched event to fire, the physics engine has to be detecting the collision. There is no way around this. By making both the Baseplate and the character anchored, the physics engine will not be simulating them, which means that the physics engine can’t detect any collision from it. :GetTouchingParts still works for this because it is essentially checking intersecting hitboxes, not for the collisions themselves.
As for your options, it depends on the kind of behavior you want, but it will not include interaction from the physics engine if both parts are anchored.

12 Likes

Can I force the physics engine to detect the collision anyway despite anchoring? The reason for anchoring is so that parts stay in place as I get unpredictable behaviour on parts which are not anchored.

You could try using AlignPositions and AlignOrientations to simulate an anchored state without actually anchoring them, but this would not allow for predictable behavior when moving CanCollide == true objects inside each other.

1 Like

Might I ask what your use case for this is?

I find that I would like my tweened parts to perform some action when touched, for example, I would like a twened part to stop tweening when it touches something.

Why do you want the part to interact with the baseplate if you said you wanted the part to travel through the baseplate and back infinitely?

Try Tweening CFrame instead of Vector3

I have not stated that I want the part to tween through the baseplate and back indefinitely; I have only done this to set up a clear demo of what is happening. Anyway this does not matter, what matters is that if I wanted to take some action e.g. play a new tween or stop the old tween when the baseplate is detected, this is not possible without taking some really awkward steps outlined in previous posts.

I don’t see any difference using CFrame.

You could use raycasting. This is probably the only answer to this problem since its not physics based. You could also use Region3 to detect whether or not the part is still within the baseplate using a raycast activated loop. And if the detection loop returns false, you can just break it, stopping it until the raycast fires the checking loop again.

Since no solution apart from hacking around seems possible, what do you guys think about adapting this into a feature request?

I think if you want this to be adapted into a feature request, you should follow the post approval guidelines and make a thread for that yourself.

2 Likes

There’s a sorta a hacky way to do this, if you used the stepped function in RunService, you could probably just check whether the block is touching the Baseplate using the :GetTouchingParts function.

This would probably be very laggy though.

yeah… I will implement this and see how much it will actually lag. I just wish we didn’t have to bend over so much for this requirement.

Unanchor and set velocity to 0,0,0 every frame when moving

2 Likes

What feature would you ask for though? Non-physics parts that are overlapping can be found by GetTouchingParts and physics parts that begin touching can be found by the Touched event.

Your part is not moving as far as Roblox physics is concerned. It’s very much an edge-case where you have a part that you are pretending is moving and want to act like it is for some things but not for others.

I am interested in dealing with such intersections via an event and if possible in a fashion as clean as using the Touched event.
I have just posted a feature request now and I have asked for some parameter to configure such detections or a new event to capture this currently uncaptured behaviour, thus not resorting to having to call GetTouchingParts() or ray casting as the programmer, but instead relying on the event.

The best way currently is probably to connect the position changed event and check GetTouchingParts when it fires. I’d do something like this if it was me:

local currentlyTouchingParts = {}

YourPart:GetPropertyChangedSignal( 'Position' ):Connect( function ()
    processTouch( YourPart:GetTouchingParts() )
end )

function processTouch( parts )
    -- do stuff with the parts here
end
1 Like

You have quite a wide variety of options. All of these would work:

  • Using Region3s to detect parts
  • Using ray casting to detect parts
  • Using :GetTouchingParts() to detect parts

All of these options except Get Touching Parts have whitelists and blacklists you can add.

A feature request is really not needed; This functionality already exists.