UE4 -ApplyDamage to specific Actor - unreal-engine4

I have an issue I've been trying to fix for about a week now, but for the life of me cannot figure it out.
I have a function
DamageOnOverlap(AActor* HitActor, AActor* OtherActor
which deals damage on overlap. Within that function, I have the following function
UGameplayStatics::ApplyDamage(OtherActor, 25.0f, GetWorld()->GetFirstPlayerController(), this, UDamageType::StaticClass());
which deals damage to the overlapped actor. These two functions are in my
ZombieBasic.cpp
so then they overlap each other, they take damage and Destroy when their health is 0.
Is there a way to do a check or something so they're unable to cause damage to themselves?
I have done the following check
if(OtherActor == mainCharacter)
{
UGameplayStatics::ApplyDamage(OtherActor, 20.f, GetWorld()->GetFirstPlayerController(), this, UDamageType::StaticClass());
}
But either the they all still take damage or no damage is applied at all.
OtherActor will call AMainCharacter (AMainCharacter* mainCharacter is defined in the header file for ref).
So, I'm basically trying to stop ApplyDamage OR DamageOnOverlap from damaging other actors of the same type, which in this case, stop AZombieBasic from damaging another ABasicZombie.
Sorry if this is a rubbish explanation.

With some investigation, I have managed to fix the problem.
TL;DR
I added an Actor Tag to the mainCharacter class and did a check in ZombieBasic to see if an actor has the specified tag.
Read if you're interested
Adding an Actor tag to 'AMainCharacter' within the Blueprint Class under the Actor section and adding a new tag of Player. In ZombieBasic.cpp, in the DamageOnOverlap function I did a basic check of
if(OtherActor->ActorHasTag("Player")
{
// Deal Damage
}
Now when BP_BasicZombie overlap with themselves they no longer deal damage to themselves.

Related

How to run Unreal blueprint nodes on BeginPlay that depend on another blueprint

I need blueprint A to run nodes in BeginPlay which rely on a variable in blueprint B, but that variable is null until set in B's BeginPlay function. Of course, A's BeginPlay could run before B's and I would run into errors. I can think of two ways to get around this, but neither feel like a proper approach:
In A's BeginPlay, add a Delay node with a second or less duration in the hopes that B's variable has been initialized by then. It seems like this could easy break things and isn't smooth.
Have an Event Dispatcher in B called "VariableSet". A binds an event to it in BeginPlay and that event runs the dependent code. This usually works but I haven't heard of anyone doing this.
Is there a proven, documented method to avoid null pointers in BeginPlay?
I've faced the similar problem in the past.
And in my case I just used Event Dispatchers. I'm not too proud of that aproach but It did a job.
Parent is calling ED at the end of BeginPlay execution flow
Child is binding ED to CustomEvent at the beggining of its own BeginPlay execution flow
When Parent's BeginPlay is finished (which calls ED), logic in Child's CustomEvent runs
For me it worked really well because one Parent had a lot of Childs and these Childs had their own Childs, etc, etc...
and due to Dispatchers and Events I was able to easily track what was going on.

Is there a way to get an information who started a collision?

I have two actors in my project, sometimes AI Pawn is causing a collision and sometimes a Player is causing it. Is there a way to distinguish it?
Have you checked the onHit function for the AI Pawn and Player?
Both in C++ and Blueprint, collision events give you a FHitResult (displayed as just HitResult in BP). Here is reference.
This result contains both the Actor and Component that was hit/overlapped/traced.
So, the object calling the collision event is first object, and YourFHitResult.Actor is the other object.
In BP, you can use the break hit result node to get the actor/component.

Unreal Engine 4 - which class spawned the shot?

In Unreal Engine 4 I have two different classes (Player and Enemy) that spawn the same type of Actor (Shot). From within the newly created Shot, how can I find out which of those two classes spawned it?
I am sure there is a pretty straightforward answer to it, but I can't seem to phrase it properly when searching, as I am not getting any helpful hits.
Note: I have started digging into UE4 very recently, so it is quite possible that I have found the answer already but am just not sure what I am looking for. Or that I should simply have two different classes (Player Shot and Enemy Shot). Any help appreciated!
Edit: GetInstigator() gets me the values I expected but the description gives me the impression this is not necessarily what I am looking for: The APawn that is responsible for damage done by the spawned Actor. (Can be left as NULL).
If you're using BP, in the Shot class, create a variable (actor reference). When you spawn the actor, cast to the Shot reference, using the Return Value from the SpawnActor node as the object. After making this cast, SET the actor reference variable you created to the Self reference of what pawn spawned it.
Basically, what you are doing here is when the Shot is spawned, a reference to the pawn (player or enemy) is created within it. Hope this helps!

Unity 3D: what is the correct way to detect that the collision has already been processed for another collision participant?

I have a class CollisionHandler which has the OnCollisionEnter method. Each collideable entity in the game has CollisionHandler as a component. So, when 2 objects collide the OnCollisionEnter method is called twice and it's ok because the damage and other things are processed as a result of touching object "B" by object "A" and vice versa.
In addition, each collision creates a flash effect and plays a sound of impact and of course, these effects are also played twice for each collision. Although it wouldn't be imperceptible to the player it doesn't seem to be correct anyway. In order to prevent it, I came up with the following solution: I save the current frame number in another collision participant so it will know that these effects have been played already by the first one.
private void OnCollisionEnter(Collision collision)
{
// Calculate the damage caused by `this.gameObject` to `collision.gameObject`.
// ...
// Play an impact sound and show a visual effect.
if (thisObject.CollisionFrameId != Time.frameCount)
{
otherObject.CollisionFrameId = Time.frameCount;
// play sound
// show hit effect
}
}
Although it works I'm not sure (I'm a novice in Unity) that it's the best practice and if so please suggest other possible solutions.
Note that I didn't ask "Why is OnCollisionEnter getting called twice?". I know why it happens. My question is about the other, though it does mention the name of the same function it still doesn't asks the same.
You could do a GetComponent on the other object with one of your scripts (or the same script) and set the RecentCollisionObject to the current script or gameObject (and maybe a given time frame just for additional safety (if only one triggers it, but not the other for some reason)).
On each collision you check if RecentCollisionObject is the other object (and if no more than ~0.01 seconds has passed). If true, you know that particular collision must already have been processed by the other object just now, so reset all values from that other object and do nothing else. So the next collision which occurs, no matter how soon, will do this cycle anew and work as expected.
This way you let only the first to trigger the collide code execute your code (like a sound). The point is that both collision events are ran in the same frame, so no matter which triggers first, you can prevent the second from running.
You can use the Unity Tag System, you tag action to occur when colliding with that specific tagged object.
As example:
internal void OnTriggerEnter(Collider other) {
if (other.gameObject.tag == "Oject Tag") {
this.GetComponent<AudioSource> ().PlayOneShot (objectTagSoundClip);
}
Just need a audio to play placed in game object.
Maybe you have 2 Colliders. If so you could check if boxcollider for example is colliding only. You could also try on Collision leave. Hope it helps.

Interacting with events and listeners in MATLAB

I want to write GUI code that is orthogonal. Lets say I have a circle class and a square class and they need to interact. Right now, to get the circle and square talking to each other - say the circle object sends a message to the square object, I would use something like square_obj.listen_for_circle(circle_obj) where listen_for_circle is a method that implements an addlistener.
This is a problem for me since now the two objects are linked - and removing one object from my code would break it. What I am looking to do is for the circle_obj to be able to broadcast a global message say 'CIRCLE_EVENT'. Additionally square_obj would be listening for global message broadcasts of type 'CIRCLE_EVENT', and upon hearing the event - does some action.(Ahhh, now the objects have no links to each other in the code base!)
Is this possible or even reasonable in MATLAB? (or maybe i'm just going crazy).
As always, advice much appreciated.
I'm not really sure why addlistener is problematic for you. It basically just adds an event listener that doesn't do anything if the event-origin object (the circle) is deleted.
Alternately you can use event.listener or handle.listener. They are undocumented but work well, and are widely used within the Matlab codebase (m-files). See explanation here: http://UndocumentedMatlab.com/blog/continuous-slider-callback/#Event_Listener