Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

Anyway to "grab" a player with a tool in a script?

Asked by
z_lm 9
4 years ago
Edited 4 years ago

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)

1 answer

Log in to vote
0
Answered by
oilsauce 196
4 years ago

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!

0
Thank you so much! I'll accept the answer at the end of the day, just trying to edit all of this into my game. So far I made the remoteevent and made the animation play with no tool! That's insane! I'm pretty new to scripting so im glad I got something done from all this for now. Once again, thank you! z_lm 9 — 4y
0
I've made the GetTouchingParts() detection, im able to return the table and all that, but how would I use the TouchingParts and filter out everything else but the enemy'sChar? z_lm 9 — 4y
0
Loop through each part inside the table, and check if they are apart of a character model. To do this you could get the Parent of the part (part.Parent) and check if the Parent has a Humanoid in one of its children (if part.Parent:FindFirstChild("Humanoid") then). oilsauce 196 — 3y
0
if you have found a Humanoid, that means the "part.Parent" is the "character model" of that character. If you want the character model to be of a specific player, you can check if the character model and the opponent player's "Character" property are the same. (if part.Parent == [insert enemy player instance here].Character) oilsauce 196 — 3y
Ad

Answer this question