Unity.Check if object is coliding with another in a function - c#

I'm making a game (similar to Subway Surfers), and I have a floor made of many small cubes. And I want to make my game do something when the player stops colliding with the floor. But when I use OnTriggerExit (Collider other) I never know if the player stops colliding the floor or just moves from one piece of the floor to another:
OnTriggerExit (Collider other){
if (other.tag == "floor") {
if(/*Object isn't coliding with any other object with the tag "floor" (Or simply isn't coliding with the other piece of the floor) */){
//Do something
}
}
}

It depends on the needs of the game. Since you named Subway Surfer, I would go with the z-coordinate of the player.
I would add the heightFromGround field to the player class (calculated as the difference on the z-axis between the player and the platform underneath).
Then, if heightFromGround is higher than a threshold, you know the player is jumping.
This also allows you to control the Animation of the character based on it's height from the ground (so he can prepare to land) and transition to the running state.
To have different platforms at different heights, you need to know the platform currently underneath the player at runtime.
This is just an approach to avoid collision checking.
If you don't need that level of control on Animations and prefer to keep using collisions, you can simply add a field int touchingPlatforms = 1; and add 1 to it OnCollisionEnter, subtract 1 from it OnCollisionExit. The player is jumping if touchingPlatforms is 0.

Related

Making an object move through another and keep going?

I am currently making a sidescrolling game in Unity 2D where an enemy rises up, and then dives down to the player, but then keeps going until it is off screen, like how this image shows. 1 I can get the enemy to collide with the player but I can't make it keeping in that direction until off screen. How would I be able to do this?
You have to make your collider to trigger (it's a checkbox on your collider)
That means your object will not be affected by physics when it touch another collider, but it can calls functions.
You have to replace OnCollisionEnter/OnCollisionEnter2D, etc by OnTriggerEnter/OnTriggerEnter2D, etc.
Be careful, the parameter of the function may change too (Collision/Collider).

Detecting collisions in unity without actually applying force to the object

Hey so i am making a 2d game that is very similar to flappy bird (you jump when tapping the screen). The point of the game is to catch the green squares coming to you.
The problem i am encountering is that when my player hits the green square it seems to collide with it (it throws the player in some random direction or even stop into place like it hit a wall) even if on collision the green square is being destroyed.
So whenever the player hits the green square prefab it increments the score and destroys the square but sometimes when i jump right before hitting the square it stops like it collided with it insted of just passing right through.
The player prefab has got a rigidbody component and a 2d square collider.
The green square prefab has got only a 2d square collider component attached to it.
I am very new to unity and this is the first game i started developing.
If you need any further information please don't hesitate to ask.
Here is the player's rigidbody and 2d collider settings
Here is the green square's 2d collider settings
Maybe this picture of the gameplay can help. Imagine the blue square is the player and the green squares are the points you have to hit the red things are just the enemies that kill you so don't mind them. The player is standing still and the green square prefab have a script attached to it that adds a constant force to them. Hopefully this made it a lot clearer.
There is a really useful unity function that will detect when a collider touches another collider.
It is: void OnCollisionEnter(...)
You also have to pass in a Collider or Collider2d. So it will look like:
void OnCollisionEnter(Collider col)
or void OnCollisionEnter(Collider2D col)
Of course you have to have the necessary import statements for unity engine at the top as well.
You may want to use a trigger on your green Squares. then the bird is allowed to pass true but the square will activate your OnTriggerEnter code in your script.
so what you can try is:
public void OnTriggerEnter(Collider other)
{
if (other.tag == "Player")
{
//Run your code here!!!
//for example
Rigidbody rb = other.gameObject.GetComponent<Rigidbody>();
rb.AddForce(new Vector3(1, 1, 1));
}
}
this will add a force to your player/bird. but you can run any code in that method.
OnTriggerEnter and OnCollisionEnter run both when the object is hit by a rigidbody. but with OntriggerEnter you can pass thru the object. because it does not get effected by other physics objects. but onCollision usually does unless you freeze it in position.
side note OnTriggerEnter runs in FixedUpdate, so it is run at the end of each frame

Unity: Enemy objects passing through box collider on edges of background

I'm developing a simple 2D Unity game (which I'm very new to so sorry if this is a silly question!) in which my player can eat its enemies by colliding with them. This works fine as I'm just selecting the "is trigger" component for the enemies and using this code in my Player class:
private void OnTriggerEnter2D(Collider2D other)
{
Debug.Log("Hit detected");
Destroy(other.gameObject);
transform.localScale += new Vector3(x, y, z);
}
However, this means the colliders placed around the border of my background image aren't stopping the enemies. What's the best fix for this?
I don't understand very well your question. However it seems that your collisions are not working. So, remember that for have collisions actually taking place in your game you need to use colliders and that one of the two elements participating in the collision need to have the rigidbody component.
That will make the physics work in the engine, which triggers dont.
To check if that works you can debug with:
// called on collision
void OnCollisionEnter2D(Collision2D col)
{
Debug.Log("OnCollisionEnter2D");
}
From what I understood, you want only to detect triggers between the player and the enemies, but you still want these to collide with physic objects in your scene, such as background colliders.
One possible way to achieve this is to create a child object for the player object with a collider component with the trigger option set, and attaching a script to it to handle the triggers. Then, with the use of layers to group your player and enemy objects, you can uncheck the collision between them following: Edit -> Project Settings -> Physics 2D: "Layer Collision Matrix".
You can assign a script to any enemy, checking the distance with the player in each frame. Then you can Uncheck "is trigger"
Vector2.Distance

Instantiate and Fire Object, when OnTriggerEnter or OnCollisionEnter

I would like a bullet that is fired from the Enemy, to bounce back off my Players shield.
I have set up my character and the enemy fires towards me at time intervals.
I can then activate my players shield (turning on a BoxCollider) and pressing a button.
So when the Bullet (IsTrigger) collides with my Players Shield (IsNotTrigger) I want to remove this Bullet and then Instantiate a new Bullet from the shield, in the direction of the Enemy.
I am also having an issue destroying the Bullet.
When the OnTriggerEvent or OnColliderEvent occurs (tried both), hundreds of bullets will appear from my Shield. How do I only allow one bullet to be fired towards the enemy?
Below is part of my script, which is located in the GameObject of my Players Shield.
Ideally I would like to destroy the bullet once it has collided with an object.
void OnTriggerEnter(Collider col) {
if (col.tag == "Weapon") {
attack();
}
}
private void attack() {
if (!GameManager.instance.GameOver) {
bulletReturnClone = Instantiate(bulletReturn, transform.position, transform.rotation) as GameObject;
bulletReturnClone.GetComponent<Rigidbody>().velocity = transform.forward * 25f;
Strachan,
That's not how I would approach the problem but I will stick to your desired solution then share some ideas for improvement.
void OnTriggerEnter(Collider col) {
if (col.tag == "Weapon") {
attack(col);
}
}
private void attack(Collider col) {
if (!GameManager.instance.GameOver) {
bulletReturnClone = Instantiate(bulletReturn, transform.position, transform.rotation) as GameObject;
bulletReturnClone.GetComponent<Rigidbody>().velocity = transform.forward * 25f;
// the following line of code should remove the bullet from the shield collider in order to prevent any future problems like spawning multiple bullets or instantly destroying the newly created bullet
bulletReturnClone.GetComponent<Transform>().position *= bulletReturnClone.GetComponent<Rigidbody>().velocity;
Destroy(col.gameObject);
}
}
If your trigger(Bullet) is tagged as weapon this code should achieve your intentional goal of reflecting the bullet in the direction of your shield pointing to by destroying the bullet and instantiating a new one and modifying it's velocity. It works but it's kind of sloppy development. It can be much better if you approach the problem from a different perspective - the one of the Bullet not the Shield.
Let's pretend for a moment you are a Bullet. All you do is fly in the direction you are shot. Once you collide with a terrain you stop/disappear. If this terrain is a shield you don't stop/disappear but change your direction (you get reflected).
So... long story short... the one who should have a trigger collider is the bullet not the shield. OnTriggerEnter(Collider col) for the bullet script will destroy it but if col.tag == "Shield" the bullet will only change its direction without all the useless instantiations and transformations.
I'm too lazy to write the code for the 2nd solution. If you got my point you should be able to easily write it down. Also learning through trials and errors helps you develop (excuse for me being lazy).
Im not really sure why you would want to despawn and respawn the bullet with a new velocity?
Depending on the shield geometry you could look up Coefficients of Restitution and therefore reflect the kinetic energy of the bullet into a realistic velocity.
Note the complexity of that maths will be proportional to the complexity of your shield geometry depending on the different collision primitives.
Sphere-sphere
Sphere-plane
Sphere-terrain (terrain could represent any un-even surface)
Or are you trying to collect the bullets in some sort of "charge" mechanic to release them back at a different time?

How to allow an object to move within a collider?

I am trying to have a block that can only be pushed inside of a rectangular collider. The player has to be able to move through the collider in order to push the block. I have tried to affect the mass upon the block being pushed into the edge collider, the drag, the angular drag, the velocity, isKinematic but nothing will stop the cube from moving when it hits the collider. It is really confusing, any help would really be appreciated...Here is the code:
public class pushBlock2 : MonoBehaviour {
public Rigidbody2D pBlock2;
void OnTriggerEnter2D(Collider2D col)
{
if (col.tag == "edge") {
Debug.Log ("pushblock2 touched edge");
pBlock2.isKinematic = true;
pBlock2.isKinematic = false;
}
}
void OnTriggerStay2D(Collider2D col)
{
if (col.tag == "edge") {
pBlock2.isKinematic = true;
}
}
Why don't you try and create four colliders around the area you want to move your block within? This way you'll have to stop the block from entering those which is much easier task than trying to prevent an item from leaving the collider.
I am pretty sure you will be able to pull this off without any code at all, you just need to setup a couple of static colliders to collide with objects on certain layer and put the cube you wanna move on that layer.
More info on Layer-based collisions can be found here: http://docs.unity3d.com/Manual/LayerBasedCollision.html
The way I understood, you're trying to use the volume defined by a collider as a delimiter for movement. I'm supposing you also desire "realistic" collisions when the object attempts to go outside said volume. That being the case, I'm afraid it is not possible.
The whole physics simulation is made by assuming some rules. Whenever two colliders intersect, the physics follows the rule that two objects should not occupy the same space (just like the real world), and thus it will try to figure out how to separate them again.
You can somewhat work around this by using a set of colliders that defines an hollow object, such as a barrel or box, but its more likely you'll turn off physics simulation for the box and roll up your own algorithm if consistent behavior is needed.
Many things in games are actually "fake" behaviors. Perhaps you can achieve what you want by faking physics or faking collisions?

Categories

Resources