how to access A Gameobject's component

Hi , i have a Gameobject in Hierarchy which has a script and inside the script is this component : publicGameObject[ ]prefabs; .

i have another Gameobject which is simply my player . my player also has a script attached to . how i can after colliding my player and any member of above array , stop them both ? at the moment after collision my player and prefabs members move to the left of screen .

    void OnCollisionEnter2D(Collision2D col)
    {
        if (col.gameObject.tag == "Enemy")
        {
          
            bgs.speed = 0;
            spawner.active = false;

        }
    }

Well I’m assuming that this line here:

publicGameObject[]prefabs;

Is a list of prefabs you’ve dragged into the inspector. Then as your code starts up you instantiate objects from these prefabs. If this is the case then when your player collides with one of these objects, the object he collided with will NOT be one of the objects in the prefabs array. It will be an instanced copy of one of them. The reference to the collided with object will be different than a reference into that prefab array.

But you can still stop your player and whatever he collides with because your collision2d variable col has a gameObject reference to what you collided with:

    void OnCollisionEnter2D(Collision2D col)
    {
        if (col.gameObject.tag == "Enemy")
        {
        
            bgs.speed = 0;
            spawner.active = false;

            // if your enemies have rigidbodies on them?
            RigidBody2d rigid = col.gameObject.GetComponent<RigidBody2D>();
            rigid.velocity = Vector2.zero;

            // or if you enemies have animations
            Animator anim = col.gameObject.GetComponent<Animator>();
            anim.speed = 0;
    
           // Or if the enemy has some Script attached to it you need to access
          EnemyScript script = col.gameObject.GetComponent<EnemyScript>();
          script.SomeMethod();
          script.someVariable = 0f; 
        }
    }
1 Like

Yes , that is the case and your thought is correct . My prefabs instantiate with another script too :

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;
    }

}

and this script :

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;
    }

}

my question is which way is the best way to manage player and collision with obstacles and show game info panel . this is only an endless runner game in 2d . simply you run game play scene. with the first collision with enemy or an obstacle the game is over and pause info pops up . then may you further more explain how i handle this collision and thanks for you codes too .
i have also an empty gamemanger object in hierarchy which has a script attached to . but i could not before talking with you access and reference to other game objcts…other components and scripts . but using your comment above , will help to do so . then please help me more to overcome this challenge .

Also There is an error which says :
Assets/Scripts/PlayerMovement.cs(18,17): error CS0029: Cannot implicitly convert type UnityEngine.Rigidbody2D' to UnityEngine.GameObject’
Assets/Scripts/PlayerMovement.cs(80,25): error CS0246: The type or namespace name `RigidBody2d’ could not be found. Are you missing a using directive or an assembly reference?

Well if any collision causes the game to end, then you don’t need to worry about anything that I posted. Since you don’t care about modifying things that you collide with. If you get a collision you just need to pause the game and load up your end of game screen. One way to freeze this game is like this, just add this line to your OnCollisionEnter

Time.timeScale = 0.0f;

Then you can call a function to load up some kind of end of game sequence.
Just be sure to set it back to 1.0 when your restarting game.

Or you could just have a bool called gameOver = false. And set it to true when the collision happens

void Update()
{
        if (gameOver)
               return;

This would stop handling any movement or input while gameOver was true.

To end the game there is a lot of ways you could go about. You could create a canvas in screen Overlay mode that has some kind of Game Over and Score Text printed on it. You can enable it

i have all canvas things . please tell me how to fix those errors?

I’d have to see code you’ve written to really help with any errors but its probably just typos. RigidBody2d should by RigidBody2D The first error i’d definitely need to see the line to see how to fix it

Forget all above things . please say me how to access to an array members which are instantiated on runtime . thanks .

I’m not sure what you mean. Could you post code on how you instantiate things. And exactly what you are trying to acess

yes , this code instantiate an array with its member on runtime , i mean without playing game , i cannot access it and also its childeren :

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;
    }

}

the below code also instantiate array members :

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;
    }

}

And also this code :

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();
        }
    }

}

, lastly i created and empty gameobject and an empty script attached to .i renamed both GameController and inside GameController Script i have these codes :

using UnityEngine;
using System.Collections;

public class GameController : MonoBehaviour {

    public Spawner spawner;
    public GameObject player;
    public BackgroundScrolling bgs;

    void Awake()
    {
        spawner = GameObject.Find ("Spawner").GetComponent<Spawner>();
        player = GameObject.Find ("Player");

    }
    void Start ()
    {
       
    }
   
    void Update ()
    {
       
    }
    void OnCollisionEnter2D(Collision2D col)
    {
       
    }


}

i am trying to access to member of array which are created on runtime and by colliding of player and each of those member finish the game level . but i dont know which of above code exactly instantiate that array and of course its members . long post , na?