Roblox released a new constraint recently, the RigidConstraint
Simply put, you have to place an attachment inside of the sticky grenade and then place an attachment at the position of collision.
And then set the att0 and att1 of the RigidConstraint to those attachments. Also, make sure the sticky grenade remains unanchored when you are attaching it to the wall.
But how do we get the position of the collision? That’s a bit tougher, and studio doesn’t exactly have a built in function for it either.
However, I’ve figured out that raycasting towards to hitPart works effectively. Since we are only casting one ray we don’t have to worry about performance either!
Judging by your current work, I assume you’re quite skilled with Lua as is so I’m only going to gleam over the details.
local rayParams = RaycastParams.new()
rayParams.FilterType = Enum.RaycastFilterType.Whitelist
rayParams.IgnoreWater = true
local function CreateSticky(pos)
local sticky = Instance.new("Part")
sticky.TopSurface = Enum.SurfaceType.Smooth
sticky.BottomSurface = Enum.SurfaceType.Smooth
sticky.Size = Vector3.new(1,1,1)
sticky.Position = pos
sticky.Parent = workspace
sticky.Color = Color3.new(0,0,0)
local att0 = Instance.new("Attachment")
att0.Parent = sticky
att0.Name = "att0"
local att1 = Instance.new("Attachment")
att1.Parent = sticky
att1.Name = "att1"
local rigid = Instance.new("RigidConstraint")
rigid.Attachment0 = att0
rigid.Attachment1 = att1
rigid.Parent = sticky
return sticky
end
local function CalculateCollision(sticky, hitPart)
local stickyPos = sticky.Position
local targetPos = hitPart.Position
local distance = (stickyPos - targetPos).magnitude
rayParams.FilterDescendantsInstances = {hitPart}
local rayResult = workspace:Raycast(stickyPos, (targetPos - stickyPos).Unit*distance, rayParams)
if rayResult then
return rayResult.Position, rayResult.Normal
end
end
local sticky = CreateSticky(Vector3.new(21, 9, -45))
sticky.Touched:Connect(function(hitPart)
local hitPos, hitNormal = CalculateCollision(sticky, hitPart)
local att1 = sticky:FindFirstChild("att1")
if att1 then
att1.Parent = hitPart
att1.WorldPosition = hitPos + (sticky.Size/2*hitNormal)
print(hitPart, hitPos)
end
end)
This script I’ve written here performs perfectly and even calculates for angled surfaces (calculating for mesh-based collisions is difficult so concave objects present bugs).
When the sticky grenade hits a part it sends a ray towards the hit part. Then that ray returns the nearest surface point (a.k.a. the most likely point of collision). After that it assigns att1 to the object we collided with and changes the worldposition of said attachment to the raycast result.
And since the grenade is unanchored, we can reposition the hit object and the grenade will follow suit.
Meaning you can have sticky grenades attach to moving cars and rotating objects!
Hope this helped!