OnCollisionEnter somehow not working [duplicate] - c#

i am bloody beginner with Unity and i am currently working on a 2D Brawler. The movement works perfectly but my colliders don't do what they should... I want to detect if two GameObjects Collide (Spear and Player2) and if the collide Player2s healthPoints should decrease by Spears AttackDamage.
The names of the GameObjects are also their tags. The Spears Prefab has following configuration: SpriteRendered(Material Sprites-Default), BoxCollider2D(Material None Physics Material 2D, IsTrigger(not activated), UsedByEffector(also not activated) Rigidbody2D(Kinematic, None Material, Simulated(Activated), KinematicContacts(activated), Standard configs for the rest))
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SpearCtr : MonoBehaviour {
public Vector2 speed;
public float delay;
Rigidbody2D rb;
void Start ()
{
rb = GetComponent<Rigidbody2D>();
rb.velocity = speed;
Destroy(gameObject, delay);
}
void Update ()
{
rb.velocity = speed;
}
}
The Players Configurations
The Spears Configurations
This was the code i have tried before
OnCollision2D(Collision2D target);
{
if (target.gameObject.tag == "Spear")
{
hp = -1;
if (hp <= 0)
{
alive = false;
}
}
}
I hope someone can tell me how to get this working
Thanks for all the answers
(BTW sorry for my bad english I am austrian)
enter image description here
enter image description here

Reasons why OnCollisionEnter() does not work:
Collison:
1.Rigidbody or Rigidbody2D is not attached.
At-least, one of the two GameObjects must have Rigidbody attached to it if it is a 3D GameObject. Rigidbody2D should be attached if it is a 2D GameObject/2D Collider.
2.Incorrect Spelling
You failed to spell it right. Its spelling is also case sensitive.
The correct Spellings:
For 3D MeshRenderer/Collider:
OnCollisionEnter
OnCollisionStay
OnCollisionExit
For 2D SpriteRenderer/Collider2D:
OnCollisionEnter2D
OnCollisionStay2D
OnCollisionExit2D
3.Collider has IsTrigger checked. Uncheck this for the OnCollisionXXX functions to be called.
4.The script is not attached to any of the Colliding GameObjects. Attach the script to the GameObject.
5.You provided the wrong parameter to the callback functions.
For 3D MeshRenderer/Collider:
The parameter is Collision not Collider.
It is:
void OnCollisionEnter(Collision collision) {}
not
void OnCollisionEnter(Collider collision) {}
For 2D SpriteRenderer/Collider2D:
6.Both Rigidbody that collides has a isKinematic enabled. The callback function will not be called in this case.
This is the complete collison table:

Related

Unity3D: Having player light torches using ParticleSystem and OnCollisionEnter?

I'm trying to get my player to light torches in a scene, but not quite sure how to do this.
I have a torch prefab that has a particle system. Each time the player's torch collides into an unlit torch, I would like that torch to start burning.
I have been trying to follow the docs but have not been able to understand (https://docs.unity3d.com/ScriptReference/ParticleSystem.html, https://docs.unity3d.com/ScriptReference/ParticleSystem.Play.html).
Also have this question posted here: https://answers.unity.com/questions/1491419/having-player-light-torches-using-particle-system.html
My current code is below. I have each torch object tagged as torch, and my player tagged as Player. All particle systems, except the player's torch, have 'Play on Awake' off and prewarm on.
Any advice or tips?
Thanks!
/*
* Attach this script to all the torches. It will be used to start the fire
using OnCollision?/OnTrigger? See which is better
* Start with the particle effect/light being off, get all the components
* Turn the torches on when the player's torch collides with them
* 1.) Must make sure each torch object has a collider
* */
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class StartFire : MonoBehaviour
{
public GameObject torch;
public ParticleSystem fireParticleSystem;
bool lightOn;
void Start()
{
lightOn = false; //Start with the light off
fireParticleSystem = GetComponent<ParticleSystem>(); //get Particle System
torch = GetComponent<GameObject>(); //get Torch
}
/*
* if player's torch hits this torch (that is not lit)
* Turn on the fire
* Set the light being on to true
* */
private void OnCollisionEnter(Collision collision)
{
if(this.gameObject.tag==("torch") && collision.gameObject.tag==("Player") && lightOn==false)
{
fireParticleSystem.Play(); //start the particle system
lightOn = true;
}
}
}
1.Create your ParticleSystem and change the tag of its GameObject to "torch".
2.Attach BoxCollider to the SphereCollider to that GameObject with the ParticleSystem.
3.Mark the IsTrigger of the collider created from #2 to be true because it doen't make sense to collide with a touch. It seems like you just want to detect when the player is touching it.
4.The touch script should attached to the player instead of the touch. Use OnTriggerEnter to handle the detection and detect when player touches the touch-light then use GetComponent to get the ParticleSystem and play it. Stop the particle in OnTriggerExit.
If you actually want player to collide and be stopped by the touch then ignore #2 and also use OnCollisionEnter and OnCollisionExit instead of OnTriggerEnter and OnTriggerExit.
Attach to the Player:
public class ParticlePlayer : MonoBehaviour
{
void OnTriggerEnter(Collider other)
{
//Make sure player is touching a touch
if (other.CompareTag("torch"))
{
//Get ParticleSystem from the Gameobject the player collided with
ParticleSystem ps = other.GetComponent<ParticleSystem>();
//Play Particle
ps.Play();
}
}
void OnTriggerExit(Collider other)
{
//Make sure player is touching a touch
if (other.CompareTag("torch"))
{
//Get ParticleSystem from the Gameobject the player collided with
ParticleSystem ps = other.GetComponent<ParticleSystem>();
//Stop Particle
ps.Stop();
}
}
}
I've used the following code in some of my projects:
private ParticleSystem _particleSystem;
private ParticleSystem.EmissionModule _emissionModule;
private void Awake()
{
_particleSystem = GetComponent<ParticleSystem>();
_emissionModule = _particleSystem.emission;
_emissionModule.enabled = false;
}
private void OnCollisionEnter(Collision collision)
{
_emissionModule.enabled = true;
_particleSystem.Play();
}
I believe you're missing the emission module.

Bug in Unity 2D gravity?

I'm writing a script in C# in Unity that essentially functions as a switch to turn gravity on or off for a 2D Rigidbody. When the game starts, gravity should be 0 for the Rigidbody. Then when the user taps the space bar, gravity is supposed to increase to 3 (which is does). Then, however, when the player collides with a gameObject labeled 'InvisGoal', the player should teleport to another location and then gravity should be 0 again. However, the player always falls after coming in contact with InvisGoal and teleporting and I can't figure out why. This is my first project in C# so sorry for any obvious errors.. The script is here:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BallLaunch : MonoBehaviour {
private Rigidbody2D myRigidBody;
public GameObject Ball;
// Use this for initialization
void Start ()
{
myRigidBody = GetComponent<Rigidbody2D> ();
GetComponent<Rigidbody2D>().gravityScale = 0f;
}
// Update is called once per frame
void Update ()
{
if (Input.GetButtonDown ("Jump"))
{
GetComponent<Rigidbody2D> ().gravityScale = 3f;
}
}
void OnTriggerEnter2D(Collider2D other){
if (other.tag == "InvisGoal")
{
Ball.gameObject.GetComponent<Rigidbody2D>().gravityScale = 0f;
transform.position = new Vector3 (0.61f, 1.18f, 0f);
return;
}
}
}
Ball.gameObject.GetComponent<Rigidbody2D>().gravityScale = 0f;
This is likely what is causing the problem.
It sounds like the RigidBody2D you are referencing to in this line is not the same as the one you retrieved beforehand with GetComponent().
GetComponent returns the component of the GameObject you call it from. Therefore in the code I mentioned above,
Ball.gameObject.GetComponent<RigidBody2D>()
and
GetComponent<RigidBody2D>()
would give you an two different RigidBody2D component if the field Ball does not refer to the same GameObject your BallLaunch script is attached to.
[
Supposing BallLaunch script is attached to the Ball you want to set the gravity of (As picture above)
Simply change:
Ball.gameObject.GetComponent<Rigidbody2D>().gravityScale = 0f;
To
GetComponent<Rigidbody2D>().gravityScale = 0f;
Also, since you already referenced your RigidBody2D in your Start method to the field myRigidBody, you can replace all subsequent GetComponent with myRigidBody.
GetComponent<Rigidbody2D>().gravityScale = 0f;
To
myRigidBody.gravityScale = 0f;

How can I make a game object jump when I press a key (preferably space)?

I have this C# script attached to my main camera game object which also has a capsule collider attribute. However, it doesn't seem to do anything. How should I modify/add to this to make the camera "jump" and fall down to the ground again?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Jump : MonoBehaviour {
[HideInInspector] public bool jump = false;
public float jumpForce = 1000f;
public Transform groundCheck;
private bool grounded = false;
private Rigidbody rb;
// Use this for initialization
void Awake ()
{
rb = GetComponent<Rigidbody>();
}
// Update is called once per frame
void Update ()
{
grounded = Physics2D.Linecast(transform.position, groundCheck.position, 1 << LayerMask.NameToLayer("Ground"));
if (Input.GetButtonDown("Jump") && grounded)
{
jump = true;
}
}
void FixedUpdate()
{
if (jump)
{
rb.AddForce(new Vector2(0f, jumpForce));
jump = false;
}
}
}
Also, I would like to have the key for this be the spacebar if possible, but whatever key works or is there already is fine. I am still learning C#, so please forgive me if the solution is obvious.
This line is most likely causing the problem:
grounded = Physics2D.Linecast(transform.position, groundCheck.position, 1 << LayerMask.NameToLayer("Ground"));`
There are 2 reason that it wont produce proper results:
You haven't setup your ground tiles or the place where you character moves to the "Ground" layer. You wont have this by default but you can add it from the Project Settings->Tags and Layers menu.
Your colliders are not close enough to the ground thus not causing collision.
Besides that it should work fine.

Tank does not shoot instantiated bullet

I started making a simple game in Unity3d: a tank to shoot at a wall (see image).
A GameObject is attached to the turret of the tank, and to this GameObject is attached the following script :
using UnityEngine;
using System.Collections;
public class Shooter : MonoBehaviour {
public Rigidbody bullet;
public float power = 1500f;
void Update () {
if (Input.GetButtonDown ("Fire1")) {
Rigidbody bulletRB = Instantiate (bullet, transform.position, transform.rotation) as Rigidbody;
Vector3 fwd = transform.TransformDirection(Vector3.forward);
bulletRB.AddForce(fwd*power);
}
}
}
When I press on the Fire1 button the bullet does not shoot. I put (for test) a Debug.Log("BULLET SHOOT") after bulletRB.addForce(). The message is displayed, so the script reached this point. What is wrong with my code?
Based on this somewhat similar question on Unity Answers, you should probably be instantiating the GameObject of the bullet prefab/instance, rather than its Rigidbody directly. Then, access the Rigidbody component of that new bullet and add the force.
Your adjusted Update() method would then look like:
void Update () {
if (Input.GetButtonDown ("Fire1")) {
GameObject newBullet = Instantiate (bullet.gameObject, transform.position, transform.rotation) as GameObject;
RigidBody bulletRB = newBullet.GetComponent<Rigidbody>();
Vector3 fwd = transform.TransformDirection(Vector3.forward);
bulletRB.AddForce(fwd*power);
}
}
Another thing you may want to change is using transform.forward (aka. Forward vector of the turret) rather than Vector3.forward (global forward vector Vector3(0, 0, 1), which may not match the direction of the turret).
Hope this helps! Let me know if you have any questions.
Force can be applied only to an active rigidbody. If a GameObject is inactive, AddForce has no effect.
Wakes up the Rigidbody by default. If the force size is zero then the Rigidbody will not be woken up.
The above description is taken from Unity
Therefore, I would suggest to check if the GameObject is active first.
You can test it by doing the following:
if (newBullet.activeInHierarchy === true)
{
//active
}else{
//inactive
}

2D Collision & Stop in Unity 3D

I have a simple scene in 2D. The right yellow box is the "Player", while the green & brown thing is the "Obstacle".
Player has a BoxCollider2D, RigidBody2D and a C# script named Hero.cs attached to it. BoxCollider2D enabled Is Trigger; RigidBody2D enabled Is Kinematics; other settings are left in default values.
Obstacle has only a BoxCollider2D with Is Trigger enabled.
and here is the Hero.cs:
using UnityEngine;
using System.Collections;
public class Hero : MonoBehaviour {
public float moveSpeed = 0.1f;
private Vector3 moveDirection;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
Vector3 currentPos = transform.position;
if(Input.GetKey("left")) {
transform.Translate(new Vector3(-1, 0, 0));
} else if(Input.GetKey("right")) {
transform.Translate(new Vector3(1, 0, 0));
}
}
void OnCollisionEnter2D(Collision2D collision) {
Debug.Log("Colliding");
}
void OnTriggerEnter2D(Collider2D other) {
Debug.Log("Triggering");
}
}
Only "Triggering" appears in Console Log.
My question is: What should I add to make the "Player" inaccessible to the "Obstacle" (no need to bounce away)?
Note: Using Unity 4.5
Update: After I set Gravity Scale to 0, collision detection works, but in a strange way. The "Player" go sideway during collision. Watch this YouTube video for action.
I expect the Player only go along X or Y axis. What did I miss ?
IsTrigger
Triggers let other colliders pass through without any collision happening. They are only triggering an event, hence the name.
If you disable IsTrigger for both objects, you will get collisions and the corresponding events are fired.
More infos here: http://docs.unity3d.com/Manual/CollidersOverview.html
IsKinematic
Kinematic rigidbody colliders will only collide with other non-kinematic rigidbody colliders.
Have a look at this matrix http://docs.unity3d.com/Manual/CollisionsOverview.html
Disable IsKinematic and move the player with MovePosition if you don't want to use force values to move the player.

Categories