Basically, I am attempting to create a dragging system that works both in third person and first person. Everything seems to be working fine, until the character starts rotating, which, for some reason, makes the held part go in the same direction???
I am not really experienced at coding lua, so the way I am trying to do it might not be optimal. I did look for solutions, but couldn’t find anybody with the same problem I have.
-- Local script in StarterCharacterScripts
local players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RunService = game:GetService("RunService")
local PickupEvent = ReplicatedStorage.Pickup
local DropEvent = ReplicatedStorage.Drop
local player = players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local mouse = player:GetMouse()
local HRP = character:WaitForChild("HumanoidRootPart")
-- Create a single attachment for both position and orientation targeting
local TargetAttachment = Instance.new("Attachment")
TargetAttachment.Parent = HRP -- Parent to HRP, but its CFrame will be based on the camera
TargetAttachment.Name = "TargetAttachment"
local AlignPos = Instance.new("AlignPosition")
AlignPos.Attachment1 = TargetAttachment -- Align to this attachment
AlignPos.Enabled = false
AlignPos.Responsiveness = 50
AlignPos.MaxForce = 100000 -- Give it enough force to move the object quickly
local AlignOrientation = Instance.new("AlignOrientation")
AlignOrientation.Attachment1 = TargetAttachment -- Align to this attachment
AlignOrientation.Responsiveness = 200
AlignOrientation.Enabled = false
AlignOrientation.MaxTorque = 100000 -- Give it enough torque to rotate the object quickly
-- The offset for the held object relative to the camera
local OFFSET_DISTANCE = 10 -- Adjust this value to set how far in front of the camera the object is held
RunService.RenderStepped:Connect(function()
local camera = workspace.CurrentCamera
if camera then
-- Position TargetAttachment directly in front of the camera's view.
-- This is crucial as the camera's CFrame correctly represents the player's view
-- in both first and third person, regardless of character rotation.
TargetAttachment.WorldCFrame = camera.CFrame * CFrame.new(0, 0, -OFFSET_DISTANCE)
end
end)
PickupEvent.OnClientEvent:Connect(function(objName)
local obj = workspace:FindFirstChild(objName)
if not obj or not obj:IsA("BasePart") then return end
local PosAtt = obj:FindFirstChild("PosAtt")
if not PosAtt then
warn("PosAtt not found on object:", objName)
return
end
AlignPos.Parent = obj
AlignPos.Attachment0 = PosAtt
AlignPos.Enabled = true
AlignOrientation.Parent = obj
AlignOrientation.Attachment0 = PosAtt
AlignOrientation.Enabled = true
mouse.TargetFilter = obj -- Prevent clicking on the held object itself
end)
DropEvent.OnClientEvent:Connect(function(objName)
local obj = workspace:FindFirstChild(objName)
if not obj or not obj:IsA("BasePart") then return end
AlignPos.Enabled = false
AlignOrientation.Enabled = false
-- Reparent Alignments to keep the workspace clean when not in use
AlignPos.Parent = ReplicatedStorage
AlignOrientation.Parent = ReplicatedStorage
mouse.TargetFilter = nil
end)
Script that parent with DragDetector
-- Script under DragDetector under Part (Server Script)
local Det = script.Parent
local Obj = Det.Parent
-- Ensure Pickup and Drop are RemoteEvents in ReplicatedStorage
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local PickupEvent = ReplicatedStorage:WaitForChild("Pickup")
local DropEvent = ReplicatedStorage:WaitForChild("Drop")
local PosAtt = Instance.new("Attachment")
PosAtt.Parent = Obj
PosAtt.Name = "PosAtt"
-- If your part's visual center isn't its origin, you might want to adjust PosAtt's CFrame
-- For example, if you want it to drag from the part's geometric center:
-- PosAtt.CFrame = CFrame.new(Obj.Size.X/2, Obj.Size.Y/2, Obj.Size.Z/2)
-- Or if you want it to drag from its center of mass:
-- PosAtt.CFrame = CFrame.new(Obj:GetMassProperties().CenterOfMass)
Det.DragStart:Connect(function(plr: Player)
Obj:SetNetworkOwner(plr) -- Crucial: gives the client control over the object's physics
PickupEvent:FireClient(plr, Obj.Name)
end)
Det.DragEnd:Connect(function(plr: Player)
Obj:SetNetworkOwner(nil) -- Reset network ownership when dropped
DropEvent:FireClient(plr, Obj.Name)
end)
2. Refined Alignment Properties
While you had Responsiveness, the MaxForce and MaxTorque properties for AlignPosition and AlignOrientation were not explicitly set, or were at default low values. This can lead to the dragged object lagging behind.
3. Improved Reparenting of Alignments
Your AlignPos and AlignOrientation were parented to the object when picked up, but not explicitly reparented back to a neutral place when dropped.
Ok, I just checked out your code, and it works great in first person (also thanks for describing how each line of code works). The problem is that my game idea sort of needs to have the ability to drag objects in third person, so that it would be more comfortable to build and observe everything at the same time. It would be great if you or somebody else could figure out how not to use the camera for it. Not sure if it’s actually possible though.
By default, TargetAttachment.WorldCFrame = CFrame.new(targetPosition, mouseHitPosition) makes the held object look towards where your mouse is pointing, which is very intuitive for aiming and placing things in a building game.
I’ve also included comments in the PickupEvent that offer options to lock the object’s orientation (e.g., always keep it upright or facing a specific way) if you prefer that for building. You’ll likely want to choose one of these for precise placement.
Mouse Controls Depth:
mouse.Hit.Position gives us the exact 3D point where your mouse is pointing in the world.
By calculating the projectedDistance using a dot product with hrpLookVector, we figure out how “deep” into the world, along your character’s forward line, the mouse is pointing. This allows you to control the distance of the held object from your character just by moving your mouse closer to or further from objects.
Character’s Forward Direction: Instead of the camera’s LookVector, we now primarily use HRP.CFrame.LookVector. This gives us the direction your character’s body is facing, which is perfect for placing objects relative to the character in third person.
My bad for replying this late. I did check out the code you sent yesterday (which for some reason got deleted today), but didn’t have time to say anything about it. Sadly the system didn’t feel convinient enough, since you can’t move the part up or down (unless I implemented it wrong). But thanks for letting me know about the combination of shiftlock and HRP.Cframe.LookVector. I will try to use it for another dragging system with the ability of moving the part vertically.
Also, I am in fact going to be very thankful if someone is actually able to find out the reason why the part acts this strange when the character rotates in my original post. I still don’t understand why the part gets offset, even though the attachment doesn’t seem to glitch out.
I still don’t know the issue was, I tried everywhere from research and added LIMIT DISTANCES and UserInputService:GetMouseLocation() but didnt work. I hope someone will help you with the glitching thingy
Here’s the issue if related:
Attachment Issues
Incorrect Positioning/Orientation: Make sure the Attachment is placed correctly and has the right CFrame relative to its parent part. You can use the CFrame property to check the Attachment’s position and orientation.
Dragger Issues in Studio: Try updating to the latest Roblox version, as this issue has been fixed. If you’re still experiencing issues, try deleting the part and re-creating it.
Replication Mismatches: Make sure to handle NetworkOwnership on the server-side to prevent replication mismatches.
AlignOrientation Issues
Slow or Non-Responsive Rotation: Check that MaxTorque, MaxAngularVelocity, and Responsiveness are set to high values. Also, ensure that there are no conflicting forces, like a Humanoid’s physics, that are preventing the rotation.
RigidityEnabled: Disable RigidityEnabled if it’s causing issues, or adjust other properties to
fine-tune the rotation.
Conflicting Physics: Check if there are any other physics elements controlling the part, like a Humanoid or other constraints, that might be conflicting with AlignOrientation.
“Freezing” or Stalling: Try toggling RigidityEnabled or Enabled on and off, or resort to deprecated BodyGyro for temporary fixes.
Unintended Reactions: If ReactionTorqueEnabled is true, ensure that the other attached part is not much lighter than the intended object.
AlignPosition Issues
Heavy Delays and Lag: Check that NetworkOwnership is properly set on the server-side to prevent delays and lag. Also, ensure that MaxForce is sufficient to overcome the object’s mass or gravity.
“Freezing” or “Anchoring” Effect: Check for conflicting physics or replication issues that might be causing the part to freeze or act as if it’s anchored.
Failure to Carry Characters/Objects: Ensure that MaxForce is sufficient to carry the character or object, and that collision group settings are correct.
Overshooting or Jittering: Fine-tune Responsiveness and MaxVelocity to prevent overshooting or jittering.
Humanoid Conflicts: Disable Humanoid.EvaluateStateMachine or adjust MaxForce significantly to prevent conflicts with Humanoid physics.
So uh, I am literally 2 months late, but I figured out the solution. Not sure how optimal it is but I basically created another attachment in terrain that always replicates ClientLookAt’s position and then replaced AlignPos.Attachment1 with it. I am confused with how roblox works.