GetPlayerFromCharacter() returns nil

I want to create a stagger system for my combat and I currently am using remove events to handle when it should stagger and who, only problem was I had to get the hit player as the first argument in the removeEvent:FireClient() and I used GetPlayerFromCharacter to get the player from the hithumanoid, but its returning nil and I do not know why.

I use a hitbox system called ClientCast for hit detection by the way, here is the code:

slashCaster.HumanoidCollided:Connect(function(result, hithumanoid)
	if script.Parent.Equipped then
		if Debounce[hithumanoid] then
			return
		end
		Debounce[hithumanoid] = true
		print("Hit:" .. result.Instance.name)
		game.ReplicatedStorage.Events.GoreEvent:FireAllClients(math.random(config.MinBlood.Value, config.MaxBlood.Value), result.Instance.Position)
		hithumanoid:TakeDamage(config.Damage.Value)
		script.Parent.Handle.Hit:Play()
		local hal = Instance.new("Animation")
		hal.AnimationId = "http://www.roblox.com/asset/?id=7747707560"
		local har = Instance.new("Animation")
		har.AnimationId = "http://www.roblox.com/asset/?id=7747710892"
		local hurtAnimLeft = hithumanoid:LoadAnimation(hal)
		local hurtAnimRight = hithumanoid:LoadAnimation(har)
		local ranMath = math.random(1, 2)
		if ranMath == 1 then
			hurtAnimLeft:Play()
		elseif ranMath == 2 then
			hurtAnimRight:Play()
		end
		local player = players:GetPlayerFromCharacter(hithumanoid.Parent)
1 Like

Print the hithumanoid and the parent because it may not be a character model, if it is then their should be no problem.

It prints the name of the character, in this case dummy:

print(hithumanoid)
print(hithumanoid.Parent)

image

So it is working.

GetPlayerFromCharacter only returns a player if the charter it’s hitting is a actual players character. So it’s functioning properly

So what would I do if its not a player? Would I need an additional check before I fire the stagger event or something else? Because I have dummies that I would like to be staggered as well.

1 Like

If getplayerfromcharacter then

treat it like player

else

do the same just using the hithumanoid.Parent

But I can’t, because the first arg has to be a player object in the remote event.

Well what does staggered mean? Like a client screen effect? If it’s a NPC than it wouldn’t have a client or screen to effect anyway so I am confused?

1 Like

It slows the players walkspeed, then waits the staggertime then goes back to normal walkspeed. Here is the stagger code(its a localscript in startercharacterscripts, I know its not safe to handle this on the client but I’m not sure how else to handle something like this):

local ReplicatedStorage = game:GetService("ReplicatedStorage")

ReplicatedStorage.Events.Stagger.OnClientEvent:Connect(function(hum, staggertime, staggeramount)
	local OldWalkSpeed = hum.WalkSpeed
	hum.WalkSpeed = staggeramount
	wait(staggertime)
	hum.WalkSpeed = OldWalkSpeed
end)
1 Like

Well just copy the code to server and put it in a corotine. I am also confused how a NPC would react to just getting the walk speed lowered?

I haven’t really thought this through honestly, I have no idea how coroutines work so I’ll look at the API and see if it works, thanks for the help.

But wait, you can’t use onclientevent in a server script right? So what do I do then?

Don’t use a remote lmao.

If it’s all on the server than no client communication.

Then what would I do? Should I handle the stagger in the hit function of the weapon?

slashCaster.HumanoidCollided:Connect(function(result, hithumanoid)
	if script.Parent.Equipped then
		if Debounce[hithumanoid] then
			return
		end
		Debounce[hithumanoid] = true
		print("Hit:" .. result.Instance.name)
		game.ReplicatedStorage.Events.GoreEvent:FireAllClients(math.random(config.MinBlood.Value, config.MaxBlood.Value), result.Instance.Position)
		hithumanoid:TakeDamage(config.Damage.Value)
		script.Parent.Handle.Hit:Play()
		local hal = Instance.new("Animation")
		hal.AnimationId = "http://www.roblox.com/asset/?id=7747707560"
		local har = Instance.new("Animation")
		har.AnimationId = "http://www.roblox.com/asset/?id=7747710892"
		local hurtAnimLeft = hithumanoid:LoadAnimation(hal)
		local hurtAnimRight = hithumanoid:LoadAnimation(har)
		local ranMath = math.random(1, 2)
		if ranMath == 1 then
			hurtAnimLeft:Play()
		elseif ranMath == 2 then
			hurtAnimRight:Play()
		end
        local OldWalkSpeed = hithumanoid.WalkSpeed
	    hithumanoid.WalkSpeed = staggeramount
        wait(staggertime)
    	hithumanoid.WalkSpeed = OldWalkSpeed

This should work both on an NPC and a real Player. If it worked, it would be appreciated to be set as solution :slight_smile:

Still doesn’t seem to work, I’m not sure why. I had to put the walkspeed changes closer to the end of the function so it wouldn’t make the hit debounce longer, since it gets changed at the end of the function.

Can you give me the whole script? Because you shouldn’t use remote event for this kind of things (changing character’s walkspeed )

Here is the entire function that handles hit detection:

slashCaster.HumanoidCollided:Connect(function(result, hithumanoid)
	if script.Parent.Equipped then
		if Debounce[hithumanoid] then
			return
		end
		Debounce[hithumanoid] = true
		print("Hit:" .. result.Instance.name)
		game.ReplicatedStorage.Events.GoreEvent:FireAllClients(math.random(config.MinBlood.Value, config.MaxBlood.Value), result.Instance.Position)
		hithumanoid:TakeDamage(config.Damage.Value)
		script.Parent.Handle.Hit:Play()
		local hal = Instance.new("Animation")
		hal.AnimationId = "http://www.roblox.com/asset/?id=7747707560"
		local har = Instance.new("Animation")
		har.AnimationId = "http://www.roblox.com/asset/?id=7747710892"
		local hurtAnimLeft = hithumanoid:LoadAnimation(hal)
		local hurtAnimRight = hithumanoid:LoadAnimation(har)
		local ranMath = math.random(1, 2)
		if ranMath == 1 then
			hurtAnimLeft:Play()
		elseif ranMath == 2 then
			hurtAnimRight:Play()
		end
		if config.CanSeverLimbs.Value == true then
			if result.Instance.name == "Left Arm" or result.Instance.name == "LArmGore"  then
				LimbHandler.DamageLimb(hithumanoid.Parent, "Left Arm", LimbDamage * config.LArmMulti.Value)
			elseif result.Instance.name == "Right Arm" or result.Instance.name == "RArmGore" then
				LimbHandler.DamageLimb(hithumanoid.Parent, "Right Arm", LimbDamage * config.RArmMulti.Value)
			elseif result.Instance.name == "Left Leg" or result.Instance.name == "LLegGore" then
				LimbHandler.DamageLimb(hithumanoid.Parent, "Left Leg", LimbDamage * config.LLegMulti.Value)
			elseif result.Instance.name == "Right Leg" or result.Instance.name == "RLegGore" then
				LimbHandler.DamageLimb(hithumanoid.Parent, "Right Leg", LimbDamage * config.RLegMulti.Value)
			elseif result.Instance.name == "Head" or result.Instance.name == "HeadGore" then	
				LimbHandler.DamageLimb(hithumanoid.Parent, "Head", LimbDamage * config.HeadMulti.Value)
			end
		end
		wait(.5)
		Debounce[hithumanoid] = false
		local OldWalkSpeed = hithumanoid.WalkSpeed
		hithumanoid.WalkSpeed = config.StaggerAmount
		wait(config.StaggerTime)
		hithumanoid.WalkSpeed = OldWalkSpeed
	end
end)

What exactly doesn’t work? walkspeed not changed?

Yes, the walkspeed doesn’t seem to change at all.