- What do you want to achieve?
To make the grabbing mesh no longer twitch
- What is the issue?
When I grab a food mesh in my cooking game out of a box and get close to wall/part, it twiches and noclips through it sometimes. The scroll is messing with this and do not know how to solve it
- What solutions have you tried so far?
I have tried fixing it by calculating how far the banana is to the part but did not work
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local UserInputService = game:GetService("UserInputService")
local RunService = game:GetService("RunService")
local player = Players.LocalPlayer
local mouse = player:GetMouse()
local event = ReplicatedStorage:WaitForChild("HoldItemEvent")
local camera = workspace.CurrentCamera
local holding = false
local heldPart = nil
local minDistance = 5
local maxDistance = 15
local distance = 5
local targetDistance = distance
local currentRotation = CFrame.Angles(0,0,0)
local targetRotation = CFrame.Angles(0,0,0)
local ROTATION_LERP_ALPHA = 0.25
local ROTATION_AMOUNT_DEGREES = 45
mouse.Button1Down:Connect(function()
if not player.Character or not player.Character:FindFirstChild("HumanoidRootPart") then return end
local target = mouse.Target
if not target then return end
local model = target:FindFirstAncestor("Bananas")
if model and model:FindFirstChildWhichIsA("ClickDetector") then
if not holding then
local modelCenter = model:GetBoundingBox().Position
local charPos = player.Character.HumanoidRootPart.Position
local distFromCharToModel = (charPos - modelCenter).Magnitude
targetDistance = math.clamp(distFromCharToModel, minDistance, maxDistance)
distance = targetDistance
event:FireServer("pickup", {position = mouse.Hit.Position})
holding = true
currentRotation = CFrame.Angles(0,0,0)
targetRotation = CFrame.Angles(0,0,0)
end
elseif holding then
event:FireServer("drop")
holding = false
targetDistance = 5
heldPart = nil
end
end)
event.OnClientEvent:Connect(function(action, data)
if action == "heldModel" then
heldPart = data
end
end)
UserInputService.InputBegan:Connect(function(input, gameProcessed)
if gameProcessed or not holding then return end
if input.KeyCode == Enum.KeyCode.T then
local direction = camera.CFrame.LookVector
local charPos = player.Character.HumanoidRootPart.Position
local throwPosition = charPos + direction * targetDistance
holding = false
targetDistance = 5
heldPart = nil
event:FireServer("throw", {pos = throwPosition, dir = direction})
end
end)
UserInputService.InputChanged:Connect(function(input)
if not holding then return end
if input.UserInputType == Enum.UserInputType.MouseWheel then
targetDistance = math.clamp(targetDistance + input.Position.Z, minDistance, maxDistance)
end
end)
RunService.RenderStepped:Connect(function()
if holding and player.Character and player.Character:FindFirstChild("HumanoidRootPart") then
distance = distance + (targetDistance - distance) * 0.25
local isFirstPerson = (camera.CFrame.Position - camera.Focus.Position).Magnitude < 1
local root = player.Character.HumanoidRootPart
local origin, direction
if isFirstPerson then
local ray = camera:ScreenPointToRay(mouse.X, mouse.Y)
origin = ray.Origin
direction = ray.Direction.Unit
else
origin = root.Position + Vector3.new(0, 2.5, 0)
if mouse.Target and mouse.Hit then
direction = (mouse.Hit.Position - origin).Unit
else
direction = root.CFrame.LookVector
end
end
local rayParams = RaycastParams.new()
rayParams.FilterDescendantsInstances = {player.Character}
if heldPart then
table.insert(rayParams.FilterDescendantsInstances, heldPart)
end
rayParams.FilterType = Enum.RaycastFilterType.Blacklist
local function raycastIgnoreNonCollidable(origin, direction, distance, params)
local raycastParams = params or RaycastParams.new()
local currentOrigin = origin
local maxDistance = distance
while maxDistance > 0 do
local result = workspace:Raycast(currentOrigin, direction * maxDistance, raycastParams)
if not result then
return nil
end
if result.Instance and result.Instance.CanCollide then
return result
else
local traveled = (result.Position - currentOrigin).Magnitude
maxDistance -= traveled + 0.01
currentOrigin = result.Position + direction * 0.01
end
end
return nil
end
local raycast = raycastIgnoreNonCollidable(origin, direction, distance, rayParams)
local finalPos = origin + direction * distance
if raycast then
finalPos = raycast.Position
end
currentRotation = currentRotation:Lerp(targetRotation, ROTATION_LERP_ALPHA)
local desiredObjectCFrame
if isFirstPerson then
desiredObjectCFrame = CFrame.new(finalPos) * CFrame.fromMatrix(
Vector3.new(0,0,0),
camera.CFrame.RightVector,
camera.CFrame.UpVector,
-camera.CFrame.LookVector
) * currentRotation
else
desiredObjectCFrame = CFrame.new(finalPos) * CFrame.fromMatrix(
Vector3.new(0,0,0),
camera.CFrame.RightVector,
camera.CFrame.UpVector,
-camera.CFrame.LookVector
) * currentRotation
end
event:FireServer("update", {
position = desiredObjectCFrame.Position,
rotationCFrame = desiredObjectCFrame
})
end
end)
Just offset the finalPos by the scale of the object. The entire reason its “twitching” is because its attempting to be forced into another object.
finalPos = raycast.Position + (raycast.Normal * heldObject.Size.Magnitude)
You may have to divide the size, but overall that should majorly reduce jittering. Of course though, there will still be some cases where it’ll happen but they’ll be somewhat forced, such as holding an item right in the corner between 2 adjacent walls/floors/ceilings.
If it jitters with the player, then use CollisionGroups that have no collision with the player and that’ll fix it.
I’ll also add that to avoid it jittering though objects when you move it under something, you should maybe make the item auto-drop itself if the player loses line-of-sight to it.
I tried it and it is still glitching a lot. I am trying to replicate a cooking game that fixes this issue by making it not move any more in the direction its trying to go to. So imagine a flat part and I put the food on top and try to drag it through it. It should not try to move downwards since it would clip through it