Well, technically, I should have named this lecture “wield a weapon” but for now its kinda the same thing. If you have any early questions or comments please leave them here.
I’m interested, does anyone have any thoughts on my silly oversized sword that I gave to the characters?
I’m having some trouble. I made a different system, where the weapon has a Collider (not triggered) and the player and enemies have a collider (triggered).
Sometimes, I change the layer and deactivate the collider (because of reasons). I was doing this as a prototype and the weapon was part of the player prefab, instead of a GO that must be instantiated.
The issue is that that game freezes for a few frames when I perform these actions (runtime) (if the item is instantiated) and runs normally if the item is part of the Player prefab (like his fists or head).
Enemies and the Player Character have collider (triggered) for their hitboxes and weapons with their own collider (not triggered).
With this, I’m creating the effect of actually hitting the targets instead of using range (the movement is by using a gamepad, not point and click). I have 2 methods called by an Animator Event (Enable and Disable Weapons) to match the “hitting” part of the animation (I don’t want a sword to be able to hit the target when it is barely starting to swing)
If the attack gets interrupted before disabling the weapon, a state machine calls the method to Disable the weapon, because if an enemy hits the player while the player is attacking another target, the player’s attack is canceled.
So, when the player (or enemy) swings his weapon, during the attack animation (calling 2 animator events, calling Enable and Disable Weapon) if the weapon is instantiated instead of being part of the player’s prefab, it freezes for some frames.
The Methods are very simple, they change the layer of the weapon (to avoid the player and enemy colliding with themselves) and enable/disable the collider.
This happens at one specific frame when the player/enemy attacks.
public void EnableWeaponDamage()
{
m_collider.enabled = true;
if (thisIsThePlayer) m_Weapon.layer = playerWeaponLayer;
else m_Weapon.layer = enemyWeaponLayer;
}
public void DisableWeaponDamage()
{
m_collider.enabled = false;
m_Weapon.layer = propsLayer; //Weapon goes to the Props layers
}```
It may well have to do with changing the layers within the game. I haven’t experimented with this, and truth be told, this is a case where a simple boolean would suffice…
public void EnableWeaponDamage()
{
attackIsActive=true;
}
public void DisableWeaponDamage()
{
attackIsActive=false;
}
void OnTriggerEnter()
{
if(!attackIsActive) return;
}
I was thinking that since enemy and player weapons are in different layers, I could just ignore those layers from colliding in the settings, that way I would just stop the necessity to change layers.
Yes, but set those layers preferably in the prefabs, but if you must set a layer on a weapon that could be either one, do it when it’s equipped, once and once only. Even then, you still may get a slowdown while the physics system adjusts itself for the changed layers. The bool can quickly discard hits that aren’t “legal”
I fixed the layers and changed the collision in the Project Setting - Physics. Worked perfectly.
And changed the logic to check a bool, and it works amazing. Now the entire system feels more light.
Something weird is happening, this should be simple right, i follow the step one by one and when i run the game, it spawn the sword in the player prefabs hand and then throws the following error:
UnassignedReferenceException: The variable weaponPrefab of Fighter has not been assigned.
You probably need to assign the weaponPrefab variable of the Fighter script in the inspector.
UnityEngine.Object.Instantiate (UnityEngine.Object original) (at <53aac14d88ba4477acc998b039cfd73a>:0)
UnityEngine.Object.Instantiate (UnityEngine.Object original, UnityEngine.Transform parent, System.Boolean instantiateInWorldSpace) (at <53aac14d88ba4477acc998b039cfd73a>:0)
UnityEngine.Object.Instantiate[T] (T original, UnityEngine.Transform parent, System.Boolean worldPositionStays) (at <53aac14d88ba4477acc998b039cfd73a>:0)
UnityEngine.Object.Instantiate[T] (T original, UnityEngine.Transform parent) (at <53aac14d88ba4477acc998b039cfd73a>:0)
RPG.Combat.Fighter.SpawnWeapon () (at Assets/Scripts/Combat/Fighter.cs:57)
RPG.Combat.Fighter.Start () (at Assets/Scripts/Combat/Fighter.cs:18)
Im using Unity 2021.3.33f1, so if there is any mistake or glitch that someone can see, that i can’t i would be thankful. I will keep trying, but i just don’t get it.
So i have been checking and the problem is for the enemies for some reason, they don’t like not having a weapon… They don’t like to be unhanded. Any ideas of what i can do to fix it, again the set up im using, it’s on the post i made above.
Btw, i just realize why probably i have not gotten an answer, the problem is im not getting warnings, it’s errors. The game it’s not running if the enemies don’t have weapons, and i don’t know if this could be a big problem.
I just added a check similar to what we do with weapon later on, on the scriptable objects and it works now… So yeah, you have through of that. Thanks for the attention daberny, and if i sounded… Less then plesent,i apologies, this has been going around my head all weekend and just today i decided to keep going and now im just facepalming hard.
Sorry for the delay on my end. I tend to see new Ask topics much easier than Talk topics, so I didn’t notice this one.
Any character with a Fighter component (that’s the Player and the Enemies) must have their Hand Transforms set, and must have a default weapon assigned.
One unfortunate feature of the Missing Reference Exception is that it doesn’t tell you which character is missing the reference, which means sometimes we have to go hunting (or Debug.Log with the character’s name, something like
if(weaponPrefab==null)
{
Debug.LogError($"{gameObject.name}'s Fighter component has no WeaponPrefab assigned!");
return;
}
What I did was checking if the Fighter was properly configured and only equip the weapon if there is actually one and the hand to put it into is set as well: