This is going to be a weird request, but I might as well ask. In this game I am making, you need to be able to chase people (kinda like infection) and grab them if you're able to get close enough to them. I already made a tool (that doesn't require a handle and is invisible,) to make the animation go, which is basically the character throwing it's hands in front of themselves. Let's say my arm touches another character in my game, it'll play another animation of them holding them (which I got covered I hope,) but I still need help on how to freeze the person in front of me. I was thinking perhaps constantly tp? I don't think that'd really work. Anyone got tips?
Edit: Thought I made this clearer but then I noticed when I published, I want to still be able to move around while holding them. I would change my walkspeed to be a little lower so it seems a little more realistic.
Edit 2: Sorry for all the edits, if it helps, if there's a way to do an animation without a tool, simply just by clicking your screen, that'd be amazing to know about. To narrow this down to a few selected people, I'll only allow it if they're on a different team.
local deb = false local Tool = script.Parent local Animation = Tool.Animation Tool.Activated:Connect(function() if deb then return end deb = true local Character = Tool.Parent local Humanoid = Character.Humanoid local AnimationTrack = Humanoid:LoadAnimation(Animation) AnimationTrack:Play() wait(2) deb = false end)
Detecting click input without a tool
To be able to detect clicking inputs without a tool, I suggest you use UserInputService
.
local UIS = game:GetService("UserInputService") UIS.InputBegan:Connect(function(input, gpe) if gpe == false then -- checks if input is clear if input.UserInputType == Enum.UserInputType.MouseButton1 then -- checks if the input is a left mouse click print("left mouse clicked!") end end end)
I won't go too in-depth about UserInputService
as it is not your main question, you can check the wiki for more information here.
UIS.InputBegan
is an event that fires whenever you send an input (like mouse clicks, keyboard button presses, etc), and it passes two arguments, an InputObject
instance called input
and a bool value called gameProcessedEvent
.
The input
argument contains Enum values that represent the information of the your input, such as UserInputType
and UserInputState
.
The gameProcessedEvent
argument represents whether or not something got fired with the input.
For example, if the input is a click, and a button or something was pressed with the same input, gameProcessedEvent
would be true. otherwise, it would be false.
Grabbing people
Now your main question. What you want to do is sort of "attach" the RootPart of another character to your character's RootPart, making it look like you've grabbed them.
There are quite a few instances that allow you to attach a Part to another Part, but in this case you'd be using Welds!
All you have to do is assign the Part0
and Part1
property, and the two parts will stick together.
To make them offset from each other, you'll be assigning the C0 and C1 properties.
Let's say we have both you and your opponent's RootParts defined as variables: rootPart
and enemyRootPart
.
local weld = Instance.new("Weld") -- create a new Weld instance weld.Part0 = rootPart -- set your RootPart as Part0 weld.Part1 = enemyRootPart -- set your opponent's RootPart as Part1 weld.C0 = CFrame.new(0, 0, -1) -- offset the two parts from each other, in this case we're offsetting Part1 from Part0 by -1 stud in the Z axis, which is right in front of Part0. weld.Parent = rootPart -- parent the weld
Putting them together
Now we know how to weld the RootParts. To actually make this execute only when you've clicked, we're going to use Remotes.
Remotes will allow communicate between the client (a player) and the server.
Since user input (like clicking) can only be detected on the client (via a LocalScript), and actually applying the Welds must be done of the server (via a ServerScript) for everyone to see, we will require Remotes to connect them together.
-- LocalScript local UIS = game:GetService("UserInputService") local repstore = game:GetService("ReplicatedStorage") local grabRemote = repstore:WaitForChild("GrabRemote") -- assuming the Remote is located in ReplicatedStorage. UIS.InputBegan:Connect(function(input, gpe) if gpe == false then if input.UserInputType == Enum.UserInputType.MouseButton1 then grabRemote:FireServer() -- send a request to the server to grab! end end end) -- ServerScript local repstore = game:GetService("ReplicatedStorage") local grabRemote = repstore:WaitForChild("GrabRemote") grabRemote.OnServerEvent:Connect(function(plr) -- this will fire whenever a player has fired a Remote. Also, when you fire a remote, the first argument will automatically be set to the Player instance who fired the Remote. local char = plr.Character or plr.CharacterAdded:Wait() -- gets the character model of the player (if it isn't there, it will wait and yield the script until it is added) local rootPart = char:WaitForChild("HumanoidRootPart") -- gets the RootPart of your character -- [hitbox detection here] local enemyChar = [insert enemy character model here] -- To detect characters around you, you'll need a hitbox system. once you've gotten the opponent's character model, it should go here. local enemyRootPart = enemyChar:WaitForChild("HumanoidRootPart") -- weld the two RootParts local weld = Instance.new("Weld") weld.Part0 = rootPart weld.Part1 = enemyRootPart weld.C0 = CFrame.new(0, 0, -1) weld.Parent = rootPart -- parent the weld end)
For the hitbox system, I won't cover how to do it here, but I recommend using a GetTouchingParts()
method of doing hitboxes. You can find the article on it here.
Hope this helped, thanks for reading!