2

I have the following script that is supposed to detect the collision between two objects (BoxCollider2D is a trigger and CircleCollider2D is a normal collider)

public class ArcadeScore : MonoBehaviour {

    public BoxCollider2D bc;
    public CircleCollider2D cc;

    private int score;

    // Use this for initialization
    void Start () {
        score = 0;
    }

    // Update is called once per frame
    void Update ()
    {
        if (bc.IsTouching(cc))
        {
            Debug.Log("collision detected");
            score++;
        }
    }
}

But the script doesn't print anything in the console, so I was wondering if it was possible to detect a collision between a trigger and a normal collider from an external script?

John
  • 23
  • 1
  • 4
  • *"External Script"*..... What does that even mean? – Programmer Jul 14 '17 at 07:27
  • @Programmer To add an empty GameObject, attach a script to it and use it to detect collision – John Jul 14 '17 at 07:49
  • @Programmer I also tried by using OnTriggerEnter2D() and making a public Collider2D and attaching my trigger there, but still nothing. – John Jul 14 '17 at 07:50
  • It's simple called "script". Did you check "is trigger" on the colliders? – Programmer Jul 14 '17 at 07:53
  • @Programmer Yes I did – John Jul 14 '17 at 07:54
  • Did you attach the script to the object with the collider? ...not empty gameobject.... – Programmer Jul 14 '17 at 07:57
  • @Programmer I made an empty GameObject and attached the script to it, since I'm trying to detect collision without directly adding the script to the Object – John Jul 14 '17 at 07:58
  • No. attach it to the object with the collider then `OnTriggerEnter2D` should work.. – Programmer Jul 14 '17 at 08:00
  • @Programmer the problem is that I constantly destroy that object and all the values revert back to 0 – John Jul 14 '17 at 08:02
  • dont "constantly destroy" stuff. read into object pooling. https://unity3d.com/de/learn/tutorials/topics/scripting/object-pooling - also sadly the script with the OnTrigger callbacks need to go onto the object with the trigger (i mean, it sounds logical doesnt it?). what hinders you to call a function on yet another object from there? like create a, idk, collision manager (yes im bad with names ^^) – yes Jul 14 '17 at 08:31

1 Answers1

0

You have to use OnCollisionEnter2D not IsTouching. IsTouching is used to detect when they are touching over frames and this may not be true. The script with OnCollisionEnter2D function must be attached to the GameObject with the collider not to an empty GameObject.

the problem is that I constantly destroy that object and all the values revert back to 0

You have to separate your game logic, score system code with the objects that destroys during run-time. Basically, your game logic, score system code should not be attached to the object that destroys itself. They should be attached to an empty GameObject.

The trick is to find the score system Object, get its script then update the score before destroying the object that collided.

The ScoreSystem script(Attach to an empty GameObject):

public class ArcadeScore : MonoBehaviour 
{
    public int score;

    // Use this for initialization
    void Start () {
        score = 0;
    }
}

The Collsion script(Attach to the GameObject with the Collider):

public class CollsionScript: MonoBehaviour 
{
    ArcadeScore scoreSys;

    void Start()
    {
        //Find the ScoreSystem GameObject
        GameObject obj = GameObject.Find("ScoreSystem");
        //Get the ArcadeScore script
        scoreSys = obj.GetComponent<ArcadeScore >();
    }

    void OnCollisionEnter2D(Collision2D coll) 
    {
        if (coll.gameObject.tag == "YourOtherObject")
        {
            scoreSys.score++;
            //You can now destroy object
            Destroy(gameObject);
        }
    }
}
Programmer
  • 121,791
  • 22
  • 236
  • 328
  • One more question, whenever I try to store the latest score and display in the next scene, I always get 0. I used this in the ArcadeScore class, svScore = PlayerPrefs.GetInt(score.ToString());. So I thought this would always store the latest value, since I use it in Update() – John Jul 14 '17 at 09:14
  • That's wrong. You store with a key and retrieve with a key. Let's use **"John"** as the key for this example. Store: `PlayerPrefs.SetInt("John",score); PlayerPrefs.Save();` then retrieve the John key: `score = PlayerPrefs.GetInt("John");` – Programmer Jul 14 '17 at 09:18
  • Why does is always revert the value to 0 when I switch the scene. I Debug.Log the score and everything seems fine, but then when I switch the score is 0 although I save it – John Jul 14 '17 at 09:25
  • Because everything is reloading which resorts back to their default values. You are responsible for saving it before switching scene and loading it back after switching scene. – Programmer Jul 14 '17 at 09:27
  • I'll try to do it. Thank you so much for helping me – John Jul 14 '17 at 09:28
  • You are welcome. If you need to save more than one variable such as game settings then use more advance method. See [this](https://stackoverflow.com/questions/40965645/what-is-the-best-way-to-save-game-state/40966346#40966346) code I made for that. Happy coding! – Programmer Jul 14 '17 at 09:30