Detecting collisions in unity without actually applying force to the object - c#

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

Related

How do I add multiple animators to my character

I have my main character and added a capsule collider 2d so he would take damage when attacked. When the character is attacking, for example his body is out of the collider space and won’t take damage when hit. Please may you help me solve this issue, I’m very new to unity
One way of doing it is having two different hitboxes that does the same thing but with different shapes so they match two different states of your character.
Enable and disable them in a script when calling the attack using:
Public Collider2D attackCollider; //Drag your attack collider here in the inspector
Public Collider2D idleCollider; //Drag your idle collider here in the inspector
void AttackCollider() //call this fucntion to change to attack collider
{
attackCollider.enabled == true;
idleCollider.enabled == false;
}
void IdleCollider() //call this function to go back to normal collider.
{
attackCollider.enabled == false;
idleCollider.enabled == true;
}
If you want to I'm sure you can incorporate these two functions into an already existing attack function if you have one.
In 3D, you could simply make the Collider a child of any of your bones, it would get animated altogether.
But you mentioned Collider2D, so:
If you have a 2D Rig with bones, you can do the same as obove
If you have a Keyframe Animation, you could animate the collider to match your animation

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?

Why don't I get a collision?

I have a cube tagged "player", which needs to jump at certain locations, represented by Empty GameObjects.
I want to make a point system and that why I put on some of the places other game objects tagged "Coin"
The cube has an animation which plays each time it moves to another point recognized by clicking with the mouse on it.
When I jump on the coin location I want the Coin object to get destroyed.
I use this function:
void OnTriggerEnter(Collider col){
if (col.gameObject.tag == "Coin") {
Debug.Log ("Plm");
stroy (col.gameObject);
}
The problem is that when I'm jumping at the Coin location nothing happens.
I have box colliders on both objects and OnTrigger checked on both.
1) Make sure one gameobject has a rigidbody
To have the OnTriggerEnter happen you need at least one of the two object to have a RigidBody attached to it.
2) Static Trigger Collider
An object that has a collider and isTrigger checked but no rigibBody is considered a Static Trigger Collider which are From Unity Documentation:
This is a GameObject that has a Collider but no Rigidbody. Static colliders are used for level geometry which always stays at the same place and never moves around. Incoming rigidbody objects will collide with the static collider but will not move it.
This type of collider interactions is perfect for your coins because they do not move and stay static.
3) Rigidbody Trigger Collider
The next type of collider interactions is a Rigidbody Trigger Collider which are :
This is a GameObject with a Collider and a normal, non-kinematic Rigidbody attached. Rigidbody colliders are fully simulated by the physics engine and can react to collisions and forces applied from a script. They can collide with other objects (including static colliders)
This type of collider is what you need on your player and as it says in the Unity Documentation it will be able to collide with the Static trigger collider.
Important observation:
Having IsTrigger set to true on your player collider will cause your player to not respond as a solid object
A collider configured as a Trigger (using the Is Trigger property) does not behave as a solid object and will simply allow other colliders to pass through.
which might not be the most optimal solution for you because most of the time you want your player to be able to collide with other things like the ground. So you can set the isTrigger to false and just have a rigidbody on you player and it will react to the coins if they're set as Static Trigger Collider.
If you want an easy way to know what can collide with what Read the colliders documentation and take a look at this chart that shows it in a more simpler way.

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

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.

Categories

Resources