OnCollisionExit not called when parenting object - unity3d

Basically, I am trying to implement very simple event system for player to interact with different objects.
Right now, I have three states:
OnCollisionEnter, OnCollisionStay and OnCollisionExit and when my player is standing on top of the pressure plate It calls OnCollisionStay and everything is working properly. When the player gets off the pressure plate OnCollisionExit is called.
The problem comes when an Item is picked up and placed on the pressure plate.
I am using simple parenting approach - just parent item on my players hand on the desired position using this piece of code:
ObjectIwantToPickUp.pickupRigidbody.isKinematic = true; //makes the rigidbody not be acted upon by forces
ObjectIwantToPickUp.transform.SetParent(myHands.transform); // sets the position of the object to your hand position
ObjectIwantToPickUp.transform.localPosition = ObjectIwantToPickUp.pickPosition; //makes the object become a child of the parent so that it moves with the hands
ObjectIwantToPickUp.transform.localEulerAngles = ObjectIwantToPickUp.rotatePosition;
After that, if I pick up the item again, the item is parented, but the pressure plate stays active, since OnCollisionExit does not being called.
I tried replacing OnCollision methods with OnTrigger but the issue still persists.
Am I missing something?

OnCollisionEnter, OnCollisionExit and OnCollisionStay will only call on components that share the same GameObject as the collider and a non-kinematic Rigidbody.
Make sure the instance of your script is on the right GameObject.
You could try attaching an EventTrigger and dynamically add event hooks after your reparenting (not recommended).

Related

How do I use Is Valid check for completing my scoring system in UE4?

I'm having trouble finding the missing piece of the puzzle with my blueprint here. Under my turret blueprint, I'm trying to check if the turret is dead, if it is, then it executes the scoring system and adds some points. What I have here is not working though. Can someone help me find what I'm missing? Thanks.
Turret Blueprint
You've attached your code to the Event BeginPlay node which means your game will only check the turret and try to add points once, which will happen as soon as the game starts. We would need to know what causes your turret to "die" to give you a more accurate answer, E.g. is it hit by a projectile or a melee weapon, or does the player have to find their way to a switch to turn the turret off or blow it up etc.
You first need to identify the cause of the turrets death and trigger your score update from there. If for example your turret is destroyed by a projectile which the player shoots at it, you could check when another actor overlaps (I.e. hits) your turret and then check if the other actor is the player's projectile. If it is, you can then update the player's score and destroy the turret.
It is also usually best to store the player's score in the PlayerState instead of the GameMode. You would need to create your own PlayerState blueprint and configure your GameMode to use that blueprint. This can be done in the properties of the GameMode or in the project settings under Maps and Modes.
Below is a basic example of destroying a turret with a projectile and updating the player's score. But I would recommend searching YouTube for something like "ue4 damage enemy" or "ue4 dealing damage". There are loads of tutorials which will show you how to implement a damage system step by step.
Turret Blueprint
This blueprint uses the Event ActorBeginOverlap node to detect when another actor overlaps/hits the turret (both the turret and the other actor will need to have a collision box or sphere etc). Then it casts the other actor to BP_Projectile (a custom blueprint/actor which you would need to create). If the cast fails, the 'other actor' isn't a projectile so we don't want to destroy the turret. If the cast is successful, we can then get the player state from the player controller and call Update Score which is a custom event I've made in my PlayerState blueprint, passing the number of points killing the turret will give you. After updating the score we can destroy the projectile and then the turret itself.
Player State Blueprint
This blueprint just has a custom event which updates the PlayerScore variable.

Is there a way for a gameobject's collider to only respond to a pinch gesture?

I have a collider that when grabbed (pinch gesture), it runs a method. However, I don't want the collider react to select events. Right now, the collider prevents buttons behind it being pressed. So when the pointer is coming from the hand, the ray stops at the collider and doesn't reach to the button behind it.
From my understanding, if there is a collider, the hand interaction ray stops at it, no matter what components it has. My guess is that I need to have a layer that ignores these colliders that still allows for a grab event to be registered. But when I added a layer for the Pointing Raycast Layer Mask, it correctly ignores the collider for the far interactions, but fails to recognize a grab event.
This is how my interactable component looks:Interactable Component
I appreciate any help! Thank you
In the input settings, change the size of Pointing Raycast Layer Masks. Set UI to be element 0 so that pointing events react to that first. documentation

World space button click event to take priority over the collider's click event it's inside?

Short story:
I have a button on a world space canvas with a click event handler. This is inside (in 3d space not parenting) of a 3d collider with it's own click event.
The collider always gets the click event as expected as it's nearer the camera.
I want the button to get the event.
Long Story:
I have a person mesh with a collider. You can click on them and the OnPointerClick triggers to do something.
I have a button that sits in a world space canvas which itself is located just above the mesh and is pointed towards the orthographic camera. You click on the coin and the OnClick event triggers to do something else.
Both events work as expected until the coin is inside the mesh's collider (which it is a lot of the time). At which point it's ONLY the mesh collider's OnPointerClick event triggers, not the button.
However, I ALWAYS want the button to take priority over the collider, and any other collider. This is easier when the canvas is screen space, but it's not (with reason).
How do I do this?
NOTES:
The button never gets the onclick event, so any filtering on the containing collider won't help
I've fiddled with the world space canvas and camera ray filtering settings to no effect.
The coin has to be a world space canvas for automatic tracking and because I use text too
IsPointerOverGameObject doesn't help as it's true for any collider, not just UI elements. Not to mention it wont stop the collider consuming the click anyway. A custom version of this that works via a layer wont help either, because again the OnPointerClick on the collider GO stil consumes the click.
I don't want either event to have to do any event filtering & passing on if possible, they should be atomic. Any filtering should be via setting properties in objects and inherent functionality of Unity if possible
Just to reiterate, writing a function to find all objects in the ray and then selecting ones that are on the UI layer first wont help. Because that does not change the fact that the collider still is the only thing that gets the event, which then you'd have to manually propagate down to the button.. which I don't want to do.
I've been able to fix this by putting the button's world space canvas on a sorting layer of 1. That way, even if it's behind colliders, it will register first.
Nice and clear solution that I was hoping would exist.

Unity trigger detect if player is completely out of collider

I use OnTriggerEnter and OnTriggerExit to simulate ladders. When i climb up a ladder the OnTriggerExit is fireing as soon as the top of the player collider is outside of the ladder collider while the bootom of the plyer collider is still inside of it. The same when climbing down, the OnTriggerExit fires as soon as the bottom of the player collider is out of the ladder collider while the rest is still inside. Can i (and how) detect if the colliders bottom or top is completely out of the ladder collider and not only starts to get out?
We would need more info like some code or at the very least some screenshots of your setup,
However i think you can tackle this 2 ways:
Instead of seperate triggers for each body part, instead create one big one.
Or you could chain your triggers together. In this case each trigger should call the parent component, and increment an integer (int TotalAmountOfCollidersTriggered = 0) in onTriggerExit you decrease this value. Then when the value is positive, you know one of your colliders triggers something, and when the value is 0 you know that no collider is triggered anywhere.

Unity particle system only plays if i hit SIMULATE button

I have a prefab with a particle system attached. In the code I play the particle by using this code
ps.enableEmission = true;
When i run the game, and that code executes, the particle emitter does not emit anything in the "game" window unless i press simulate button in the "scene" window.
Anybody knows why?
For the emission property to work the particle system has to actually be playing. To do this you can either enable Play On Awake in the ParticleSystem component or you use the Play method on an instance of the ParticleSystem component.
As a side note, if you are using 5.3+ the enableEmission property is now obsolete and you may want to consider using the emission property. One thing to keep in mind when using this property is you have to assign it to a variable before attempting to modify it:
public ParticleSystem _ps;
...
private void Update()
{
ParticleSystem.EmissionModule module = _ps.emission;
module.enabled = true;
}
UPDATE #1
In response to your tractor beam example in the comments I would probably suggest using SetActive on the game object that has the ParticleSystem component. By using SetActive it will prevent extra particles being emitted and will destroy any that are active, i.e. those currently in the scene.
If you use the Emission property, then it will prevent the emission of extra particles, but it will not destroy any that have already been emitted.
One other approach would be to use Play and Stop methods but these, as with the emission property, will not destroy any active particles. If you use these methods, then some things to watch out for are:
If the Prewarm option is not enabled, then Play does not start
emitting particles (not sure why this happens)
The isPlaying property will remain true as along as there are
active particles in the scene. Once these die, then it will
be set to false
The Stop method will not destroy particles active in the scene
If the ParticleSystem has stopped and you call Play while there are particles active
in the scene, then all active particles are destroyed and the
ParticleSystem starts emitting a new set of particles
Check out to see if particle GameObject is active when you call ps.enableEmission = true; on it. To show or hide particles i normally use gameObject.setActive() not ps.enableEmission.
My particle was not simulating and after I changed the culling Mode to Automatic everything worked. The default is pause and catch-up.