I'm making a platformer (sidescroller), and right now I'm making a grenade-launcher for the player.
It spawns grenades which is a prefab, this prefab has a Circle Collider 2D which is the blast radius for the explosion.
When a grenade is spawned I run this (amongst other things);
// Add the initial force
rBody.AddForce(new Vector2(forceX, forceY) *300f);
Invoke("Explode", 2.5f);
I'm having trouble figuring out how I should handle the Explode function.
I would like to find all the GameObjects that are colliding with the Circle Collider 2D at that point, but I can't find a way to do it.
I would like to be able to do something like this (not real code but you understand what I'm trying to do)
void Explode () {
collidingObjects = circleCollider.getCollisions();
foreach(collidingObject as entity) {
if(entity = 'player')
player.pushLeftOrRight()
elseif(entity = 'enemy')
grenade.dealDamage(grenade.damage)
}
Debug.Log("Explode");
Destroy(gameObject);
}
I'm guessing that it wouldn't work so can anyone point me in the right direction?
In your grenade's script, use OnTriggerEnter or OnCollisionEnter to log collisions; basically just have a HashSet for each grenade that is updated and keeps track of what it is colliding with. Then Explode just has to iterate through this set when you call it.
Related
I am making a 2D game and have a basic weapon which I decided to call a pistol. I want to make a shotgun next and I have all of the work done except for the fact that they are all spawned in the same place and they all collide with each other.
I've had a few ideas like trying to turn off collisions for the rigidbodies (Didn't work), applying force without a rigidbody (Didn't work). I've done one game before this which was through a tutorial so this is my first real game and I just need help. If you need more details I can always send more. Thank you.
Jump into the Physics2D settings and make sure that the layer you’ve set for your “bullets” is not colliding with itself.
The one you’ll want to turn off for self collision is usually the one on the end, that intersects with itself on the row and column:
The script you need is the following line. In this line, Unity physics renders one collider ineffective against another.
Physics2D.IgnoreCollision(collider, ignoreCollider);
Also, with the algorithm below, you can neutralize all colliders at the moment of the bullet shot.
[SerializeField] private GameObject bulletType;
private List<Collider2D> _tempCollides;
void ShotBullets()
{
_tempCollides.Clear();
for (int i = 0; i < 4; i++)
{
// Instantiate and catch all colliders in a List
var collider = Instantiate(bulletType, AnyPlace, AnyRotation).GetComponent<Collider2D>();
_tempCollides.Add(collider);
}
foreach (var _collider in _tempCollides) // For Every Bullet Collider...
{
foreach (var _subCollider in _tempCollides) // .. Define to Ignore other Colliders..
{
if (_collider != _subCollider) Physics2D.IgnoreCollision(_collider, _subCollider);
}
}
}
I have two scripts, one attached to a gameobject and the other attached to an enemy prefab that is instantiated over time. The script attached to the gameobject uses OnTriggerEnter2D to detect when the enemy has entered, then the health bar for the object goes down by one. Iit works, the only problem is now is that because of the fact that the enemy comes up then walks back down, the enemy is colliding with the objects more than once which is not what I want.
I have tried things like using booleans to stop it colliding more than once but other prefabs enemies isn't able to collide with the gameobject because of the boolean is being set to true and not being set back to false. I don't want to use yield wait for seconds because enemies do spawn often and so it won't really look normal; I also tried onTriggerExit2D but you get the idea if I try that method. Is there any other way of detecting if an enemy has entered the objects collider damaging the object once but then when the enemy comes back down he ignores the collision (without turning off the enemies or the gameobject's collider) aka all instantiated enemies is able to collide with the gameobject when they are going up but not when they are coming back down.
Your best bet is to simply do a bool check on the monsters if they're going north or not. There are several ways to go about this. If you know where they are going you can simply compare where they are going to where they are and compare the y vector values. so something like this:
public bool monsterNorthChecker(){
if(monsterDestination.y > currentLocation.y){
return true;
}
else{
return false;
}
}
Then you can simply call that function OnTriggerEnter and verify if the monster is going north or not, if he is, take away his health. If you don't know his destination, you'll probably have to resort to more tedious means of determining destination direction. Something like comparing the y values of last frame's vector2 to this one and see which way he's moved.
I am learning to create a simple fps game in unity the problem is that the collision does not update itself for example initially when my player is on the ground console prints "floor" by "Debug.log(collision.gameObject)" but when it intersects other objects such as a cube console will print out "cube" but when I walk away from it , console does not change back to "floor" Why????
I am using transform.translate to move and jump and using method OnCollisionEnter for collision detection
OnCollisionEnter is triggered only when object enters the collider.
A) Make a list of all encountered objects by adding them when OnCollisionEnter happens and removing when OnCollisionExit happens. Then whenever you need to make sure you are on "floor" check it in the list.
B) Use OnCollisionStay and every frame you will be notified if you are touching the "floor".
Remember one thing, the other object you want to collide with need to have a collider component asigned, make sure of it. Join this with the previous answer.
I recommend to verify collision.
Here on simple example:
void OnCollisionEnter (Collision col){
if (col.gameObject){
Debug.Log("Object name : "+ col.gameObject.name);
}
}
I'm making a 2D game, there is one player with two collider : a box collider 2D on top and a small circle collider 2D bottom. When the player jump on the box he will be ok, but when he collide with the box with his face(box collider 2D) he will die ? How can I do that? I tried the following code , but it not work. Please help me.Thanks!
if (GetComponent<Collider2D>().GetType() == typeof(BoxCollider2D))
{
//do something
}
if (GetComponent<Collider2D>().GetType() == typeof(CircleCollider2D))
{
//do something
}
If you want to get a certain BoxCollider, you can use GetComponent<BoxCollider2D>() and GetComponent<CircleCollider2D>()
However, I am not sure how to take this information and check which one fired the the OnCollisionEnter, unless you set one collider to a trigger, and use OnTriggerEnter for one, and OnCollisionEnter for the other.
What I would recommend is having two child game objects on the player and put both colliders on each game object, and handle each event in their own OnCollisonEnter
I have a prefab NPC which has a physics rig attached to it (to do some specific rag-doll stuff with). I need to avoid the various colliders on the same rig (arms, legs etc) from colliding with each other, but they have to be able to collide with the rigs of other instantiated NPCs.
Is there a way to do this? I know I can avoid all the colliders from colliding by putting them on a separate layer, but I cant create a new layer for every NPC.
Thanks
You can do by setting up IgnoreCollision on your NPC class if you have any
http://docs.unity3d.com/ScriptReference/Physics.IgnoreCollision.html
So simple loop through all colliders in the rig and set up to ignore each other
void Start() {
colliders = GetComponentsInChildren<Collider>();
foreach(Collider collider in colliders) {
otherColliders = GetComponentsInChildren<Collider>();
foreach(Collider otherColider in otherColliders) {
if (collider != otherColider) {
Physics.IgnoreCollision(collider, otherColider);
}
}
}
}
It looks like the only way to ignore collisions without using layers is to use Physics.IgnoreCollision() between a pair of colliders, for each pair.
You can write some code that would automatically register a newly instantiated game object and create these pairs between the new object and the other ones that were registered before, so you wouldn't need to call this method for each pair yourself.
Or, you can use this code that does that for you :) It has its own representation of layer to control how the objects should ignore each other.