reference to different GameObjects

how can i reference collision of two different GameObject in a manager script class?
like collision of player and enemy in gamemanager class . and then to say reset game . thanks .i did untill this but i dont know how to complete it :

using UnityEngine;
using System.Collections;

public class GameController : MonoBehaviour
{
private GameObject player;
    void Awake()
    {
        anim = GetComponent<Animator> ();
        player = GameObject.Find ("Player");

    }
    void OnCollisionEnter2D(Collision2D col)
    {
        if (col.gameObject.tag == "Enemy")
        {
            StartCoroutine (retro ());

        }
    }
}

The message handling function OnCollisionEnter2D() must be on one of the two objects that collide. It is useless when place in another class altogether.

Thus, there are two main ways to handle this. Option A is that one of the two colliding objects listens for the collision, and when the collision happens, it tells the game controller to restart. This requires that the game object knows about the game controller, which might be a little bit awkward in terms of architecture.

Option B is to trigger an event on the game object listening for collisions. The game controller can then subscribe to receive notifications of that event and react accordingly. This way, the game object does not need to know about the game controller. Additionally, if you use UnityEngine.Events.UnityEvent, you can hook everything up in the editor, rather than in code.

GameController.cs:

using UnityEngine;

public class GameController : MonoBehaviour
{
    public void Restart()
    {
        StartCoroutine (retro ());
    }
}

Player.cs:

using UnityEngine;
using UnityEngine.Events;

public class Player : MonoBehaviour
{
    // In the editor, add a handler for this event,
    // assign the GameController object from the scene,
    // and select its Restart function as the handling function.
    public UnityEvent onEnemyCollision;

    protected void OnCollisionEnter2D(Collision2D col)
    {
        if (col.gameObject.tag == "Enemy")
        {
            onEnemyCollision.Invoke ();
        }
    }
}

my two game objects are player which is a prefab and availabe in the scene directly , but enemy game object is another prefab which is instantiated via object pool class and also GameObjectUtil and only is available on runtime , would you please clarify more how to do the task please? thanks .

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class GameObjectUtil {

    private static Dictionary<RecycleGameObject, ObjectPool> pools = new Dictionary<RecycleGameObject, ObjectPool> ();

    public static GameObject Instantiate(GameObject prefab, Vector3 pos){
        GameObject instance = null;

        var recycledScript = prefab.GetComponent<RecycleGameObject> ();
        if (recycledScript != null) {
            var pool = GetObjectPool (recycledScript);
            instance = pool.NextObject (pos).gameObject;
        } else {

            instance = GameObject.Instantiate (prefab);
            instance.transform.position = pos;
        }
        return instance;
    }

    public static void Destroy(GameObject gameObject){

        var recyleGameObject = gameObject.GetComponent<RecycleGameObject> ();

        if (recyleGameObject != null) {
            recyleGameObject.Shutdown ();
        } else {
            GameObject.Destroy (gameObject);
        }
    }

    private static ObjectPool GetObjectPool(RecycleGameObject reference){
        ObjectPool pool = null;

        if (pools.ContainsKey (reference)) {
            pool = pools [reference];
        } else {
            var poolContainer = new GameObject(reference.gameObject.name + "ObjectPool");
            pool = poolContainer.AddComponent<ObjectPool>();
            pool.prefab = reference;
            pools.Add (reference, pool);
        }

        return pool;
    }

}
using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class ObjectPool : MonoBehaviour {

    public RecycleGameObject prefab;

    private List<RecycleGameObject> poolInstances = new List<RecycleGameObject>();

    private RecycleGameObject CreateInstance(Vector3 pos){

        var clone = GameObject.Instantiate (prefab);
        clone.transform.position = pos;
        clone.transform.parent = transform;

        poolInstances.Add (clone);

        return clone;
    }

    public RecycleGameObject NextObject(Vector3 pos){
        RecycleGameObject instance = null;

        foreach (var go in poolInstances) {
            if(go.gameObject.activeSelf != true){
                instance = go;
                instance.transform.position = pos;
            }
        }

        if(instance == null)
            instance = CreateInstance (pos);

        instance.Restart ();

        return instance;
    }

}

Your enemy object pooling shouldn’t be an issue. You just need to make a custom script for your player that includes the UnityEvent field and OnCollisionEnter2D() function, attach it to the player prefab, and add a Reset() function to your game controller script. Then in the editor, select the player object and within the inspector you should be able to find the onEnemyCollision event. Click the plus on the bottom right of that field’s panel, drag your game controller object onto the object reference field that was added, and then from the dropdown on the right, you can navigate to your game controller’s script and find the Reset() function. Now, whenever your player invokes the onEnemyCollision event, the game controller’s Reset() function will be executed.

Right . and now whenever game is over , some panel appears , but when i click on replay game button , the game cycle does not work . here is the most difficult problem , would you please guide me through how to restart game correctly ?

using UnityEngine;
using System.Collections;

public class GameController : MonoBehaviour
{

    public GameObject GameoverPanel;
    public GameObject Buttons;
    public PlayerMovement pm;
    public bool notcrashed = true;
    public Animator anim;


    void Awake()
    {
        anim = GameObject.Find ("Player").GetComponent<Animator> ();
    }
    void OnPlayerKilled()
    {
       
    }
    void OnGameReset()
    {
       
    }

    public void Restart()
    {
        StartCoroutine (retro ());
    }
    IEnumerator retro()
    {
        pm.isPaused = false;
        notcrashed = false;
        var running = false;
        anim.SetBool ("Running", running);
        yield return new WaitForSeconds(2f);
        Time.timeScale = 0;
        gameoverPanel ();

    }
        public void gameoverPanel()
        {
            GameoverPanel.SetActive (true);
            Buttons.SetActive (false);
   
        }
}

You didn’t show any code that attempts to actually do the game reset to beginning. You mentioned that the game over panel includes a replay button. Is that button hooked up to any function? GameController.OnGameReset() seems like a logical choice, but it’s empty.

Once you have the button hooked up to a function (if you don’t already), the easiest way to restart is probably to simply reload the scene.

UnityEngine.SceneManagement.SceneManager.LoadScene("scene name goes here");

It also looks like you’ll need to reset Time.timeScale back to 1; I don’t think that gets automatically reset on scene load, since it is a global property.

allright , all good , but the problem is that gamerecycle script does not act correctly :

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public interface IRecyle{

    void Restart();
    void Shutdown();

}

public class RecycleGameObject : MonoBehaviour {

    private List<IRecyle> recycleComponents;

    void Awake(){

        var components = GetComponents<MonoBehaviour> ();
        recycleComponents = new List<IRecyle> ();
        foreach (var component in components) {
            if(component is IRecyle){
                recycleComponents.Add (component as IRecyle);
            }
        }
    }


    public void Restart(){
        gameObject.SetActive (true);

        foreach (var component in recycleComponents) {
            component.Restart();
        }
    }

    public void Shutdown(){
        gameObject.SetActive (false);

        foreach (var component in recycleComponents) {
            component.Shutdown();
        }
    }

}

becuase of this error :

MissingReferenceException: The object of type 'RecycleGameObject' has been destroyed but you are still trying to access it.
Your script should either check if it is null or you should not destroy the object.
ObjectPool.NextObject (Vector3 pos) (at Assets/Scripts/ObjectPool.cs:26)
GameObjectUtil.Instantiate (UnityEngine.GameObject prefab, Vector3 pos) (at Assets/Scripts/GameObjectUtil.cs:15)
Spawner+<EnemyGenerator>c__Iterator1.MoveNext () (at Assets/Scripts/Spawner.cs:24)
UnityEngine.SetupCoroutine.InvokeMoveNext (IEnumerator enumerator, IntPtr returnValueAddress) (at C:/buildslave/unity/build/Runtime/Export/Coroutines.cs:17)