Dying gives my combat system multiple issues that render combat, broken


Two issues.

  • The first issue I am dealing with, is unfortunately, the hitbox automatically getting deleted, for no apparent reason. There’s no direct correlation with the hitbox deleting, in any other script. No Debris, no Destroy. I’ll check once more, but I’m pretty sure I’m good on the most part, so I have no proper understanding to why it’s getting deleted. Here’s the script for it regardless.
game.Players.PlayerAdded:Connect(function(Player)
	Player.CharacterAdded:Connect(function(Character)
		task.wait()

		Character.Parent = workspace.LivingThings

		local PHB = workspace.PlayerHitboxes


		local CHclone = CH:WaitForChild("CharsHitbox"):Clone()
		CHclone.Parent = PHB
		CHclone.Name = Player.Name.. "Hitbox"

		local Effects = Instance.new("Folder")
		Effects.Parent = Character
		Effects.Name = "StatusFolder"

		local Attach1, Attach2, Attach3, Attach4, Attach5, Attach6 = Instance.new("Attachment"), Instance.new("Attachment"), Instance.new("Attachment"), Instance.new("Attachment"), Instance.new("Attachment"),Instance.new("Attachment")
		Attach1.Parent = Character.HumanoidRootPart
		Attach2.Parent = Character.Head
		Attach3.Parent = Character["Right Leg"]
		Attach4.Parent = Character["Left Leg"]
		Attach5.Parent = Character["Right Arm"]
		Attach6.Parent = Character["Left Arm"]

		local Weld = Instance.new("Motor6D")
		
		local FullStatusFolder = Instance.new("Folder")
		FullStatusFolder.Parent = Character
		FullStatusFolder.Name = "Statuses"
		
		local ISBLOCKING = Instance.new("BoolValue")
		ISBLOCKING.Parent = FullStatusFolder
		ISBLOCKING.Name = "IsBlocking"
		ISBLOCKING.Value = false
		
		local RUNNING = Instance.new("BoolValue")
		RUNNING.Parent = FullStatusFolder
		RUNNING.Name = "Running"
		RUNNING.Value = false
		
		local DASHING = Instance.new("BoolValue")
		DASHING.Parent = FullStatusFolder
		DASHING.Name = "Dashing"
		DASHING.Value = false
		
		local INCOMBAT = Instance.new("BoolValue")
		INCOMBAT.Parent = FullStatusFolder
		INCOMBAT.Name = "In-Combat"
		INCOMBAT.Value = false
		local FSTANCE = Instance.new("StringValue")
		FSTANCE.Parent = FullStatusFolder
		FSTANCE.Name = "FStance"
		FSTANCE.Value = ""
		
		
		local BSTANCE = Instance.new("StringValue")
		BSTANCE.Parent = FullStatusFolder
		BSTANCE.Name = "BStance"
		BSTANCE.Value = ""
		
		local PARRY = Instance.new("BoolValue")
		PARRY.Parent = FullStatusFolder
		PARRY.Name = "Parry"
		PARRY.Value = false
		
		local POSTURE = Instance.new("IntValue")
		POSTURE.Parent = FullStatusFolder
		POSTURE.Name = "Posture"
		POSTURE.Value = 0
		
		
		Character:WaitForChild("Humanoid").WalkSpeed = 13

		Weld.Parent = CHclone

		Weld.Part0 = Character:WaitForChild("HumanoidRootPart")
		Weld.Part1 = PHB:WaitForChild(Player.Name.. "Hitbox")


		CHclone.Char.Value = Player.Character
	end)
end)
  • Blocking is a whole issue in itself, because it EXISTS with it’s folder once I check backpack. So, I’m just confused on it. Honestly, haven’t really spent more than 3 hours on this and it’s just confusing me, so I’m going to take a step back and look towards why would it be deleting while this post is up.
    image

You might want to check if the hitboxes are anchored It might be falling into the void. Also, when you die the backpack is reset so that might be part of the issue?

If I weld it though, it shouldn’t just fall through right? Also, for the backpack, it seems like all the scripts still stay there, at their defaults I believe.

1 Like

For blocking in your script is it getting the blocking with a variable like:

local blockScript = someplace.blockscript

use blockscript

or are u referencing it each time like:

use someplace.blockscript

I decided to reference each time (I don’t know my own decisions sometimes).

1 Like

Ok I think I’ve found the solution to the hitboxes falling, around this part in the code:

Weld.Part0 = Character:WaitForChild("HumanoidRootPart")
Weld.Part1 = PHB:WaitForChild(Player.Name.. "Hitbox")

instead of doing

PHB:WaitForChild(Player.Name.. "Hitbox")

Do

Weld.Part1 = CHclone

In my testing it fixed it. Whats happening is when you reset and use WaitForChild It welds the old part. Because the new part isn’t welded it falls into the void and the weld gets destroyed then the old part also gets unwelded and falls into the void.
BTW, set the parent after everything else this post explains it well.

Are u getting the folders under the blockscript like so? If not could I see the blockscript code?

local idkstance = someplace.blockscript.idkstances

The Folder is directly just in the BlockLocal Script. Also, I’ll check this post out, this seems pretty interesting.

are u getting the folders like this?

local idkstance = someplace.blockscript.idkstances

get somestance in idkstance

Don’t do that because you are trying to get the old stance folder which has already been deleted
instead just do:

get somestance in someplace.blockscript.idkstances

Yeah, I was doing the variable variant. Learned something new today at least, no using variables if you plan to have it directly related to the character (In StarterPack). Actually, the local blocking might be a bit weird. Let me send the script to give further insight.

-- \\ Player-Related Variables // --

local Players = game:GetService("Players");
local Player = Players.LocalPlayer;
local Character = Player.Character or Player.CharacterAdded:Wait();



-- \\ Services // --

local UserInputService = game:GetService("UserInputService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerScriptService = game:GetService("ServerScriptService")

-- \\ Modules // --

local AnimationModule = require(ReplicatedStorage.Modules.GeneralModules.AnimModule)

-- \\ Misc. Variable // --

local Debounce = false
local Count = 0
local ButtonDown = false

local Anim : Animation = {
	AnimationModule.getSingleAnimation(Character:WaitForChild("Humanoid"), script.BlockStances.BaseStance),
	AnimationModule.getSingleAnimation(Character:WaitForChild("Humanoid"), script.BlockStances.UpperStance),
	AnimationModule.getSingleAnimation(Character:WaitForChild("Humanoid"), script.BlockStances.LowerStance),
	AnimationModule.getSingleAnimation(Character:WaitForChild("Humanoid"), script.ParryStances.BaseStance),
	AnimationModule.getSingleAnimation(Character:WaitForChild("Humanoid"), script.ParryStances.UpperStance),
	AnimationModule.getSingleAnimation(Character:WaitForChild("Humanoid"), script.ParryStances.LowerStance),
	
}

-- \\ Functions // --

local CountChanger = function()
	print(Count)
	if Count <= 3 then
		Count += 1

	elseif Count == 4 then
		Count = 1

	end

end

local AnimationChanger = function()
	
	
	if Count == 1 then
	Anim[1].Looped = true
	Anim[1]:Play()
		
	elseif Count == 2 then
	Anim[2].Looped = true
	Anim[2]:Play()	
	elseif Count == 3 then
	Anim[3].Looped = true
	Anim[3]:Play()	
		
	end
end

local AnimationStopper = function()
	if Count == 1 then
		Anim[1].Looped = false
		Anim[1]:Stop()

	elseif Count == 2 then
		Anim[2].Looped = true
		Anim[2]:Stop()	
		
	elseif Count == 3 then
		Anim[3].Looped = true
		Anim[3]:Stop()	

	end
	
end

UserInputService.InputBegan:Connect(function(Input, GPE)
	
	
	if GPE == true then return end
	
	
	
	

	if Character:WaitForChild("StatusFolder"):FindFirstChild("Stunned") then
		print('loser')
		return
	end

	if Character:FindFirstChildOfClass("Tool") then
		print('toolienotallowed')
		return
	end

	
	if Input.KeyCode == Enum.KeyCode.F then
		if Debounce == false then
			Debounce = true
			ButtonDown = true
			if Character.Statuses.BStance.Value == "Body-Block" then
				Anim[1].Looped = true
				Anim[1]:Play()
			elseif Character.Statuses.BStance.Value == "Face-Block" then
				Anim[2].Looped = true
				Anim[2]:Play()
			elseif Character.Statuses.BStance.Value == "UpperCut-Block" then
				Anim[3].Looped = true
				Anim[3]:Play()
			end
			
			
			ReplicatedStorage.RemoteEvents.CombatEvents.Blocking:FireServer()
		end
	end
	
	if UserInputService:IsKeyDown(Enum.KeyCode.F) and Input.UserInputType == Enum.UserInputType.MouseButton1 then
		if Character.Statuses.BStance.Value == "Body-Block" then
			Anim[4].Looped = false
			Anim[4]:Play()
		elseif Character.Statuses.BStance.Value == "Face-Block" then
			Anim[5].Looped = false
			Anim[5]:Play()
		elseif Character.Statuses.BStance.Value == "UpperCut-Block" then
			Anim[6].Looped = false
			Anim[6]:Play()
		end
		
		ReplicatedStorage.RemoteEvents.CombatEvents.Parrying:FireServer()
	end
	
	
end)

UserInputService.InputEnded:Connect(function(Input, GPE)
	if GPE == true then return end

	if Character:WaitForChild("StatusFolder"):FindFirstChild("Stunned") then
		print('loser')
		return
	end

	if Character:FindFirstChildOfClass("Tool") then
		print('toolienotallowed')
		return
	end
	
	if Input.KeyCode == Enum.KeyCode.F and ButtonDown == true then
	ReplicatedStorage.RemoteEvents.CombatEvents.Release:FireServer()
		
		Character.Statuses.IsBlocking.Value = false
		ButtonDown = false
		
		if Character.Statuses.BStance.Value == "Body-Block" then
			Anim[1].Looped = false
			Anim[1]:Stop()
		elseif Character.Statuses.BStance.Value == "Face-Block" then
			Anim[2].Looped = false
			Anim[2]:Stop()
		elseif Character.Statuses.BStance.Value == "UpperCut-Block" then
			Anim[3].Looped = false
			Anim[3]:Stop()
		end
		wait(.9)
		Debounce = false
	end
	
end)

@ninjamaster5355 ah, before you go! It’s just the issue that I need to use a module to load the animations, just makes it neater and for various other modular reasons I go with it, but I could still just directly call for the block stance? (Nevermind, I already directly call for it, so I don’t know what’s the issue)

1 Like

Yeah, be careful variables don’t update. Anyways good luck with your game :smile: :+1:

Ah, ninja before you go, would you mind me asking for you to check out the edits I made.

yeah, I don’t mind show me them.

Just check this one out @ninjamaster5355.

There’s not much improvements you can make it looks pretty good. But here are some things I would do:

  • In the count changer function I would change it to
if count < 3 then
 count += 1
else
 count = 1

You don’t really need the Count == 4 because it is already greater than 3. Its not really something you have to change its just a nitpick.

  • Everytime you are using if count == number or randomvalue.Value == “some-block” I would put it in a dictionary like:
stopblocks = {
["some-block"] = Anim[1]
["block"] = Anim[2]
}

if F then
      if stopblock[somevalue.Value] then
          -- stopblock[somevalue.Value].Looped = false (I don't see the point of changing the
          -- changing the looped variable when its gonna stop anyways
          stopblock[somevalue.Value]:Stop()
      end
end

It just makes the code more readable.

  • Also around the place where you are stopping block animations there is a wait don’t use wait use task.wait

Ah, thank you, but this is also where the issue is. Once I die, I cannot block at all, because apparently, the block folder doesn’t exist. I was asking how would I fix this?

What folder? the statuses or animations?

The Animations. charrrrrrrrrrrrr

Is it each time you are getting it from the module? or when you are trying to give the animation to the module? if it’s getting it from the module could I see the code for the function getsingleanimation?

I’m giving it to the module, that’s it.

It might be trying to get it before the animation has finished loading in try a WaitForChild.