2
votes

I want to change the colour of a part when a player stands on it but instead of putting the script inside the part can i put the script in the workspace and identify the part from an event, like Humanoid touched or something?

The reason is that i have 100's of parts which need to react to a touch event so i don't want to put the same script in each part.

Pseudo-code might be

Player touch part event fired Identify part from event and change colour of part

Thanks

3

3 Answers

1
votes

As M. Ziegenhorn wrote, you could put the script in the character or in the foot directly. That would be the "easiest" way of achieveing this.

However, you could also connect a function to each part easily. In the code below, we check through a model in workspace named 'TouchParts' which (assumingly) contains the parts you want to tie the touch-function up to.

function Touched(self, Hit)
  if Hit and Hit.Parent and Hit.Parent:FindFirstChildOfClass'Humanoid' then
    -- We know it's a character (or NPC) since it contains a Humanoid
    -- Do your stuff here
    print(Hit.Parent.Name, 'hit the brick', self:GetFullName())
    self.BrickColor = BrickColor.new('Bright red')
  end
end

for _, object in pairs(workspace.TouchParts:GetChildren()) do
   if object:IsA'BasePart' then
     object.Touched:connect(function(Hit)
       Touched(object, Hit)
      end)
   end
end

Doing it this way means anything in your character touching the part(s) will fire the Touched-event, so you would have to add in a check to see whether if tie part touching is a leg or not.

The pros of binding the function to each part instead of to the leg is that the function is only called when you actually touch one of the intended parts, instead of ANYTHING you touch. However, with an increased amount of parts you connect it to, there's also an increased amount of events which will be triggered and is stored in memory. Probably not noticeable on the scale you're working with, but worth keeping in mind.

0
votes

Been a while since I coded something on roblox so please excuse any blunders I make.

local parent = workspace.Model --This is the model that contains all of that parts you are checking.
local deb = 5 --Simple debounce variable, it's the minimum wait time in between event fires, in seconds.
local col = BrickColor.new("White") --The color you want to change them to once touched.

for _,object in next,parent:GetChildren() do --Set up an event for each object
    if object:IsA("BasePart") then --Make sure it's some sort of part
        spawn(function() --Create a new thread for the event so that it can run separately and not yield our code
            while true do --Create infinite loop so event can fire multiple times
                local hit = object.Touched:wait() --Waits for the object to be touched and assigns what touched it to the variable hit
                local player = game.Players:GetPlayerFromCharacter(hit.Parent) --Either finds the player, or nil
                if player then --If it was indeed a player that touched it
                    object.BrickColor = BrickColor.new(col) --Change color; note this is also where any other code that should run on touch should go.
                end
                wait(deb) --Wait for debounce
            end
        end)
    end
end

This is probably one of the most, if not the most efficient way of doing this.

0
votes

When a player stands on a block, the value "FloorMaterial" (which is in Humanoid) will be telling you what material the user is standing on, but if the user isn't standing on anything, this value will be nil.

Another efficient method is to use Rays. You would need to create a ray from your HumanoidRootPart.

Example:

    IsOnGround=function()
    local b=false;
    local range=6;
    local char=game:service("Players").LocalPlayer.Character;
    local root=char:WaitForChild("HumanoidRootPart",1);
    if root then
    local ray=Ray.new(root.CFrame.p,((root.CFrame*CFrame.new(0,-range,0)).p).unit*range);
    local ignore={char};
    local hit,pos=workspace:FindPartOnRayWithIgnoreList(ray,ignore,false,false);
    pcall(function()
    if hit then
    b=true;
    end
    end)
    else
    print("root not found");
    end
    return b;
    end

This would cast a ray from the HumanoidRootPart, towards the direction where the ground should be, with a distance of 6 studs.

Sadly, this method isn't very effective with R15 characters as far as I know.