Spawning Grenade causes ammo count to reset to default values

The problem is that my ammo count is derived from a base weapon class I would have to rewrite from the ground up. I really wanna try and implement that though. It makes it more complicated I suppose when my grenade class is derived from a weapon base class.

Would this mean creating a new weapon class not derived from the weapon base class then setting all of the ammo inside of the character then spawning it in the character?

That’s kind of what I was talking about. It does belong there if your grenade is a weapon class, but then, there should be a projectile that comes out of that class and blows up elsewhere. Just some transient class that gets sent toward the enemy. A normal weapon class, like say for an assault rifle doesn’t get launched at the enemy (unless it’s made by Tediore :grinning:) but stays back with the player and is long lived and thus is a good place to put persistent data.

I’m just tossing out ideas to you, because I don’t really like data that is used for the overall player being stored in a fast turnover transient object. Kinda makes it difficult to keep track of. With this current approach, you’re having to pass it from short-lived object to short-lived object.

1 Like

No, I don’t mean that necessarily, it depends on your design. It appeared you had:
Player->Grenade
and I would normally have
Player->Weapon->Projectile (which could be grenade with an invisible weapon).

That way you have consistent variable for all types of weapons. We are even using a weapon class for Melee so everything is consistent. And in fact, the Melee does use a projectile to affect its damage.

If you have a weapon class you normally use for guns, a grenade could use that too and then you have consistent data for that weapon too. But it appears your grenade is a weapon and a projectile and thus it dies frequently, hence having to pass an ammo count between transient objects. Just talking about design that circumvents the sort of thing you are running into. I’m not necessarily right.

1 Like

So just place the ammo count for the grenade inside of the character and use that instead?

That is a quick and dirty way of doing it, but I’m personally not above taking the path of least resistance and doing things like that. If it’s in your player, you know the value/data is going to hang around so it works.

1 Like

Another thing that is bugging me is that my hud is tied to those values in the derived grenade class so they stay static while the player’s grenade ammo value changes. I don’t know how to hide the derived grenade class hud when my grenade is swapped to.

Instead of me using my current weapon variable I am using my enum type for the hud. I did not know you could use enums for the hud!

That would be another reason for moving the ammo count value up the chain a bit. You need something that stays alive to be the one starting and controlling the widget. Very different but related subject though. I’d offer suggestions, but I’m already on very thin ice offering somewhat dubious advice, because I don’t know your architecture/design, and where the widgets are spawned and controlled is another part of that architecture I can’t know.

1 Like

I was getting the weapon array weapon index for the hud now instead I am using the enum the I have set up to swap between weapon animations.

I completely understand your point of view because right now I have a large codebase and I know that you don’t know the full scope of what I am working with. Either way thanks for the advice because the code you provided helped me a ton. It was just the correlation between the hud and the ammo count that was the problem also the ammo count itself. I am just using a grenade ammo count that I placed inside of the character as the quickest solution it made me realize that problem I had with my hud as well.

I had to resort to just reattaching the grenade after the explosion because for some reason when I spawn more grenades and throw them when the idle animation plays the grenade gets stuck in midair. Meaning I suppose that the attachment function plays then the grenade is stuck in limbo midair because as soon as the attachment function plays the grenade does not know whether to be forced forward or held back to the socket. I am playing the anim notify before the explosion event. Holy smokes this is complicated. It seems like reattaching the grenade is the way to go because I can’t destroy the newly spawned grenade because of the nullptr. I don’t know if it is because of engine limitations or what. The idle animation notify plays as soon as the grenade releases then the grenade gets stuck midair it’s very weird working with grenades but I have the ammo problem fixed though thank you.

Is it possible SetSimulatePhysics is being set false on it at that point? I assume you are applying velocity to move the grenade to its target and if physics were turned off, that could explain it. If there is a pointer mixup, possibly the SetSimulatePhysics(false) for the next grenade is actually applying to the one thrown.

1 Like

I have tried setting simulate physics to true and false the same outcome occurs. The grenade gets stuck mid air.

Is it possible to completely detach the grenade from the parent so that when the anim notify is called the grenade thrown has no relation with the grenade spawned?

I noticed only on the final third grenade thrown the physics actually play out and the grenade finally moves forward.

You are right the simulate physics options get switched midair but I am not controlling it.

This is what I have so far. The grenade is not hiding though…

if (Player->GrenadeAmmo < 1)
{
if (AGrenade* Grenade = Cast<AGrenade>(Player->CurrentWeapon))
{
UE_LOG(LogTemp, Warning, TEXT("SetGrenadeHidden!!"));
Grenade->GetWeaponMesh()->SetHiddenInGame(true);
Grenade->GetWeaponMesh()->SetVisibility(false);
Player->GrenadeAmmo = 0;
}
}
else if (Player->GrenadeAmmo == 3)
{	
AGrenade* Grenade = GetWorld()->SpawnActorDeferred<AGrenade>(Player->ThirdWeaponClass, Player->GetMesh()->GetSocketTransform("GrenadeSocket"));
Grenade->GetWeaponMesh()->SetSimulatePhysics(true);		Grenade->FinishSpawning(Player->GetMesh()->GetSocketTransform("GrenadeSocket"));
Grenade->AttachToComponent(Player->GetMesh(), FAttachmentTransformRules::SnapToTargetIncludingScale, FName("GrenadeSocket"));
this->GetWeaponMesh()->SetCollisionEnabled(ECollisionEnabled::NoCollision);
Player->CurrentWeapon = Grenade;
Grenade = nullptr;
}
else if(Player->GrenadeAmmo == 2) 
{
AGrenade* Grenade = GetWorld()->SpawnActorDeferred<AGrenade>(Player->ThirdWeaponClass, Player->GetMesh()->GetSocketTransform("GrenadeSocket"));
Grenade->GetWeaponMesh()->SetSimulatePhysics(true);
Grenade->FinishSpawning(Player->GetMesh()->GetSocketTransform("GrenadeSocket"));
Grenade->AttachToComponent(Player->GetMesh(), FAttachmentTransformRules::SnapToTargetIncludingScale, FName("GrenadeSocket"));
this->GetWeaponMesh()->SetCollisionEnabled(ECollisionEnabled::NoCollision);
Player->CurrentWeapon = Grenade;
Grenade= nullptr;
}
else if (Player->GrenadeAmmo == 1)
{	
AGrenade* Grenade = GetWorld()->SpawnActorDeferred<AGrenade>(Player->ThirdWeaponClass, Player->GetMesh()->GetSocketTransform("GrenadeSocket"));
Grenade->GetWeaponMesh()->SetSimulatePhysics(true);
Grenade->FinishSpawning(Player->GetMesh()->GetSocketTransform("GrenadeSocket"));
Grenade->AttachToComponent(Player->GetMesh(), FAttachmentTransformRules::SnapToTargetIncludingScale, FName("GrenadeSocket"));
this->GetWeaponMesh()->SetCollisionEnabled(ECollisionEnabled::NoCollision);
Player->CurrentWeapon = Grenade;
Grenade= nullptr;
}

I’d put my money on out of sync pointers. It’s a natural problem when the grenades are responsible for spawning more copies of themselves. CurrentWeapon is possibly not what you think it is at some point in time. Say for example, you are working on Grenade A but CurrentWeapon is set to Grenade B or some such thing, and you end up setting the wrong one. I can’t know that, it’s just very confusing to have the grenades spawning their peers except under very specific circumstances.

I guess what I’m saying is CurrentWeapon is supposed to be your active grenade, but it isn’t, it’s one of two active grenades at any point where player has thrown one. That’s one of those “What could go wrong?” things. Just shotgunning because I can’t actually help you without taking your project and seeing the architecture to make more meaningful recommendations. It’s complex if you are having to ask “which one am I” within the code of the grenade and that is what having the ammo count did, and likewise having the spawns there. It’s a temporal object and I don’t think should be responsible for the flow of your game mechanics.

To drone on about that, I would recommend that your grenade be a projectile of sorts. Something only responsible for going out and causing damage to the enemy. This would allow the Weapon Class of “Grenade” to be a persistent object. Then it can keep the ammo count and can manage the spawns without multiple copies of itself ever existing at the same time. This would allow the grenade to do its specific job (take its path, collide with the enemy (or not), explode and die). Meanwhile, the weapon class of “grenade” is a rather static class (similar to how you use a gun weapon class) tied to the player that can orchestrate the activity of its grenade projectiles.

I don’t like to say “do it this way” because architecture is something the person doing it has to be comfortable with. If you are understanding the method you are using, then that is the right way, not my way. Just telling you how I would do it.

1 Like

I am just trying to do it in a way that it works in it’s simplest form. I don’t want to complicate it because I would be out of my depth and I am trying to keep it simple in terms of how the logic is executed. Thank you for your help I really appreciate it though.