Before I start, I'm not asking for a script given to me at all. Just merely concepts or ideas.
But I'm sure most of you have played Defaultios, Lumber Tycoon 2. The dragging system is great and would be really useful in a new game of mine that I'm currently developing. I've tried multiple ways of going around it and all of them are quite poor. Such as when a player grabs a block it moves it 5 studs above the floor and allows them to drag it, and when they released it the block goes back down 5 studs.
It's a really bad way of going about it I know, but I can't quite put my finger on it. Anyways, if you got any ideas or examples or even snippets if possible, that would be great!
Many thanks, Cuvette
It seems to be a pretty simple system. You've probably noticed the little blue sphere that appears at your mouse click point. From what I can see, it looks like that sphere is welded to whatever part you click on, at that point. The sphere then is given a BodyPosition and BodyGyro, which update to place the part in the correct direction and orientation.
So, we can keep a variable of the sphere and a function to create a unique one:
local dragSphere; local function CreateDragger() if (dragSphere) then dragSphere:Destroy(); end dragSphere = Instance.new("Part", workspace); -- If FilteringEnabled is on, this could be a little more complex to implement dragSphere.Shape = "Ball"; dragSphere.Size = Vector3.new(); -- Smallest size possible dragSphere.CanCollide = false; local bp = Instance.new("BodyPosition", dragSphere); bp.MaxForce = Vector3.new(10000, 10000, 10000); local bg = Instance.new("BodyGyro", dragSphere); bg.MaxTorque = Vector3.new(10000, 10000, 10000); return bp, bg; end
Then, when the moues clicks something, we do something like:
local distance = (mouse.Hit.p - characterPosition).magnitude; local bp, bg = CreateDragger(); dragSphere.CFrame = CFrame.new(mouse.Hit.p); local weld = Instance.new("Weld"); weld.Part0 = mouse.Target; weld.Part1 = dragSphere; weld.C0 = mouse.Target.CFrame:inverse() * dragSphere.CFrame; weld.Parent = dragSphere; local rotOffset = CFrame.new(characterPosition, mouse.Hit.p):inverse() * dragSphere.CFrame;
Once we've attached ourselves, we can do this every frame:
bp.Position = characterPosition + (mouse.Hit.p - characterPosition).unit*distance; bg.CFrame = CFrame.new(characterPosition, mouse.Hit.p) * rotOffset;
Of course, a bit more implementation needs to be done to create a fully working system, but that's the main gist of it I think.