Kantus
1
(Apologies for the useless tags, but this site seems not to accept “spring”, “trampoline” or “collision” as valid tags, even though results for them came up when I entered those words in the tag suggestion box!)
Hi all,
I’ve got a 2D Game with a player and a trampoline, and I want the player to bounce up when he lands on the trampoline. However, when I tried this:
using UnityEngine;
using System.Collections;
public class Springy : MonoBehaviour {
public int springForce;
public Collision collision;
public GameObject subject;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
OnCollisionEnter ();
}
void OnCollisionEnter()
{
collision.gameObject.rigidbody2D.AddForce(new Vector2(0f, springForce));
Debug.Log("We bounced...or did we?");
}
}
it compiles correctly, but running the game immediately causes the following error:
NullReferenceException: Object reference not set to an instance of an object
Springy.OnCollisionEnter () (at Assets/Springy.cs:18)
Springy.Update () (at Assets/Springy.cs:14)
I am a little bamboozled by the Collision object, and am not sure what I’m doing wrong. Can someone else shed some light on this?
Thanks.
I have been working on a Trampoline class based on a few answers in this forum. If you want a consistent bounce every time, I found it works better if you set the velocity of the colliding object to 0 and then add the force right after. I know this has already been answered, but I figured this might help those who are finding this question on Google.
using UnityEngine;
using System.Collections;
public class Trampoline : MonoBehaviour {
public float springForce = 1000;
private Collision2D collision;
private bool bouncing = false;
void OnCollisionEnter2D(Collision2D coll) {
if (!bouncing) {
bouncing = true;
collision = coll;
}
}
void FixedUpdate () {
if (bouncing) {
var rb = collision.gameObject.GetComponent<Rigidbody2D> ();
rb.velocity = new Vector3 (0, 0, 0);
rb.AddForce (new Vector2 (0f, springForce));
bouncing = false;
}
}
}
pako
2
- You should not call OnCollisionEnter from inside Update()!!! OnCollisionEnter gets automatically called if there’s a collision on a MonoBehaviour (see Note below)
- OnCollisionEnter has one parameter of type “Collision”. So, when this method gets automatically called, the system provides the Collision object parameter, which contains several useful info about the collision:
So, you should declare in your code OnCollisionEnter together with its parameter. Otherwise, it’s not the same as the OnCollisionEnter that gets called automatically, i.e. OnCollisionEnter(Collision collision){}
Accordingly, this is how your code should look like:
using UnityEngine;
using System.Collections;
public class Springy : MonoBehaviour {
public int springForce;
public Collision collision;
public GameObject subject;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
void OnCollisionEnter(Collision collision)
{
collision.gameObject.rigidbody2D.AddForce(new Vector2(0f, springForce));
Debug.Log("We bounced...or did we?");
}
}
Like this, collision.* (just above the Debug.Log statement) refers to the parameter “collision”, of type “Collision” that is passed by the system, when it automatically calls OnCollisionEnter.
I hope this makes it clear now.
Note: collision events are only sent if one of the colliders also has a non-kinematic rigidbody attached: