This is for a 2D game.
I have a Player who can shoot trigger projectiles(with a trigger collider) and Enemies that can do the same. When a Player projectile collides with the Enemy, stuff happens and vice versa. However, when the Player projectile and the Enemy projectiles collide, they just ignore collision, go through each other, and nothing happens. They also have a Rigidbody2D with continuous collision detection.
Is there a way to make it so something happens when these two gameObjects with trigger colliders touch?
Here's what I've got for the Enemy projectile script:
void OnTriggerEnter2D( Collider2D other ){
if (other.gameObject.name == "Ground"){
Destroy (gameObject);
}
else if (other.gameObject.name == "Player"){
other.gameObject.GetComponent<RControlScript>().RHealth = other.gameObject.GetComponent<RControlScript>().RHealth - damage;
Instantiate(transformInto, gameObject.transform.position, gameObject.transform.rotation);
Destroy (gameObject);
}
else if(other.gameObject.name == "Shot"){
Destroy (gameObject);
}
}
"Shot" being the name of the Player projectile being the gameObject not colliding with the Enemy projectile.
Yes.
Here is a graph that tells you what collides with what in Unity3d.
Ok, turns out two trigger colliders do in fact collide. My problem was that the projectiles instantiated were clones, therefore its name = "Shot(clone)". Had to change that in order to make things happen.
Related
For some reason, my player is not colliding with the tilemap walls that have collision on them... Here is my player movement code
void Update()
{
hInput = Input.GetAxisRaw("Horizontal");
vInput = Input.GetAxisRaw("Vertical");
if (Input.GetKeyDown(KeyCode.LeftArrow) || Input.GetKeyDown(KeyCode.RightArrow))
{
transform.Translate(hInput, 0, 0);
}
else if (Input.GetKeyDown(KeyCode.UpArrow) || Input.GetKeyDown(KeyCode.DownArrow))
{
transform.Translate(0, vInput, 0);
}
}
When I move my player they go right through the colliders. They are on the same Layer and both have colliders. Anyone know why this is happening? Thanks!
Edit: So I've tested the collisions with OnCollisionEnter2d like suggested and they are colliding, the problem is my player still walks right through the wall. I have no clue why the collider doesn't stop this from happening.
Collider doesn’t actually perform physics like the aftermath of a collision, it just figures out when things are touching. In order to use physics you need a rigidbody or rigidbody2D, which will actually do something about the collisions the collider detects. Then, instead of setting position you will need to set rb.velocity.
The detection of colliders does not happen in Update() method. To detect collision you need to have OnCollisionEnter(). This method will be called when another object with collider and rigidbody enter in it. See the official example here.
void OnCollisionEnter(Collision collision)
{
Debug.Log(collision.collider.name);
}
Make sure the Z axis values are the same.
And just to check if the collisions are actually taking place, do this:
void OnCollisionEnter(Collision col)
{
Debug.Log(col.collider.name);
}
And make sure that the Collider is not a Trigger.
These are the only possible problems, and their fixes.
I have a game where map/background is made up of prefabs. My player and prefabs both have rigidbodies and colliders. Neither of them have is trigger checked and the prefabs have collision detection set as continuous dynamic. The player's collision detection is set on continuous. Each of the prefabs have a mesh collider and the individual walls of the prefabs have box colliders (none are set to is trigger). I keep trying to test it on my phone using Unity Remote 5, and every time I move the player it goes through the walls. If anyone has any advice on how to prevent my player from going through the walls, I would really appreciate it!
My movement script is:
public class Movement : MonoBehaviour
{
private Touch touch;
private float speedModifier;
void Start()
{
speedModifier = 0.01f;
}
void Update()
{
if(Input.touchCount > 0)
{
touch = Input.GetTouch(0);
if(touch.phase == TouchPhase.Moved)
{ transform.position = new Vector3(transform.position.x + touch.deltaPosition.x * speedModifier,
transform.position.y,
transform.position.z + touch.deltaPosition.y * speedModifier);
}
}
}
}
It would really help to see your movement script however it sounds like you are moving player by manipulating transform.position or using rigidbody.MovePosition() without setting isKinematic to true. The documentation says;
If the rigidbody has isKinematic set to false, it works like transform.position=newPosition and teleports the object to the new position (rather than performing a smooth transition).
This behaviour will ignore the collision. Also you don't need rigidbody on every GameObject in the scene. 1 rigidbody on the player is enough to collide it with other objects.
depend on what I got from your question, when you are playing and the player hit the wall, it goes inside; so the problem might be the mass of the wall. if you must add a Rigidbody to the wall so you need to add more mass to the wall also edit the border of the box collider and make them reasonably a bit wider, otherwise if you dont need a rigidbody on the wall simply keep just the box collider and it will works good. hope this answer help you, and it will be better if you can explain more the situation using some pics.
Using the Rigidbody position or applying force tends to cause the Rigidbody to clip through other colliders. I recommend changing rigidbody.velocity instead of directly changing the position.
In my game a player plants a bomb, the bomb explodes creating a fire effect, I would like my fire to be able to kill the player(blue cylinder) and any boxes it collides with. My box and player have colliders. My fire effect is instantiated when the bomb explodes.
How can I make my fire effect destroy my player and box objects?
Can I say something like if fire collider hits player collider, destroy player?
My code for the bomb is as follows
Instantiate(Firebolt, bomb.gameObject.transform.position, Quaternion.identity);
Game Layout
You can add a collider to Firebolt as well and use OnCollisionEnter on it, checking if the object you hit is a player or a box.
This is a simple example that destroys any player or box it collides with:
void OnCollisionEnter(Collision collision) {
GameObject other = collision.gameObject;
// Here I'm using tag to detect if the hit object is a player or a box
// but you can use name or other methods
if (other.tag == 'Player' || other.tag == 'Box') {
Destroy(other);
}
}
check out https://docs.unity3d.com/ScriptReference/MonoBehaviour.OnParticleCollision.html
you can apply it to the ParticleSystem or to the target GOs that should react to it.
(u also need to activate collision detection on Particle System AND set it to world.
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?
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.