1

At the start, the object adds a link to it to the list. Then when i click on this object, i need to get index reference of this object. How to do it? Little example what i need:

public static List<GameObject> myObjects = new List<GameObject> ();
public GameObject ObjectA; //this is prefab
void Start(){
    for (int i = 0; i < 10; i++) {
        GameObject ObjectACopy = Instantiate (ObjectA);
        myObjects.Add (ObjectACopy);
    }
}   

ObjectA script:

void OnMouseDown(){
    Debug.Log(//Here i need to return index of this clicked object from the list);
}
Fan4i
  • 115
  • 1
  • 8

1 Answers1

2

Loop through the Objects List. Check if it matches with the GameObject that is clicked. The GameObject that is clicked can be obtained in the OnMouseDown function with the gameObject property. If they match, return the current index from that loop. If they don't match, return -1 as an error code.

void OnMouseDown()
{
    int index = GameObjectToIndex(gameObject);
    Debug.Log(index);
}

int GameObjectToIndex(GameObject targetObj)
{
    //Loop through GameObjects
    for (int i = 0; i < Objects.Count; i++)
    {
        //Check if GameObject is in the List
        if (Objects[i] == targetObj)
        {
            //It is. Return the current index
            return i;
        }
    }
    //It is not in the List. Return -1
    return -1;
}

This should work but it is better that you stop using the OnMouseDown function and instead use the OnPointerClick functions.

public class Test : MonoBehaviour, IPointerClickHandler
{
    public static List<GameObject> Objects = new List<GameObject>();

    public void OnPointerClick(PointerEventData eventData)
    {
        GameObject clickedObj = eventData.pointerCurrentRaycast.gameObject;

        int index = GameObjectToIndex(clickedObj);
        Debug.Log(index);
    }

    int GameObjectToIndex(GameObject targetObj)
    {
        //Loop through GameObjects
        for (int i = 0; i < Objects.Count; i++)
        {
            //Check if GameObject is in the List
            if (Objects[i] == targetObj)
            {
                //It is. Return the current index
                return i;
            }
        }
        //It is not in the List. Return -1
        return -1;
    }
}

See this post for more information on OnPointerClick.

EDIT:

Objects.IndexOf can also be used for this. This answer is here to make you understand how to do it yourself so that you can solve similar issues in the future.

Programmer
  • 121,791
  • 22
  • 236
  • 328
  • You don't need to write your own `Objects.IndexOf(gameObject)`. see https://msdn.microsoft.com/en-us/library/48z14dbs(v=vs.110).aspx and https://github.com/mono/mono/blob/master/mcs/class/corlib/System/Array.cs#L147 – cwharris Mar 16 '18 at 20:15
  • 1
    @ChristopherHarris Yes, I know. In Unity, you will need to do stuff like this and sometimes, built-in function is not available for it. I wanted to show OP how to do it so that OP can apply it to his/her possible next issue. For example, [this](https://stackoverflow.com/questions/49290510/how-do-i-select-call-an-instantiated-gameobject-within-an-array-without-usind-in/49291622#49291622) asked yesterday is very similar but no built in function to handle it. It's the-same technique but `Objects.IndexOf` wouldn't have solved it. – Programmer Mar 16 '18 at 20:23
  • Except there are built in functions for that too. I went ahead and provided an alternative for that answer as well. – cwharris Mar 16 '18 at 20:31
  • 1
    I don't get it, there is a built-in function for retrieving an item in a list. Why reinventing a wheel that is working just fine? Or are we all missing something here? I understand you explain the concept but then you should also say it boils down to list.IndexOf(reference); – Everts Mar 16 '18 at 20:31
  • Because some people like to writing code more than making things with it. – cwharris Mar 16 '18 at 20:32
  • I have modified added the `IndexOf` function reference. Hopefully, everyone is happy. @ChristopherHarris See the comment I left in your [other](https://stackoverflow.com/a/49329039/3785314) answer. – Programmer Mar 16 '18 at 20:43
  • My only qualm is that you intentionally avoided the simplest answer in favor of teaching inexperienced developers to employ early optimization and write bloated code. The question is not about optimization, and even if it were, the for loop wouldn't matter because the speed at which a user can click is not nearly fast enough to effect the performance in a tangible way. You know, unless the list of objects is like SUPER big, in which case there's a design problem, not a performance problem. – cwharris Mar 16 '18 at 21:39
  • @ChristopherHarris No. I did not mention about performance, speed or optimization in this answer or comment. I only talked about showing OP how to do this kind of stuff so that OP can apply it to his/her future problems. There might be a performance difference but my only intent was to show OP how to do it which I do not regret doing. – Programmer Mar 16 '18 at 21:51
  • When one of my employees wants to rewrite existing code from the core .NET, my question is "Are you also going to maintain it?". Then I know if I should definitely get rid of him. :) – Everts Mar 17 '18 at 09:25
  • @Programmer I understand the purpose of teaching but one major problem I see with your code over IndexOf, yours is limited to GameObject only. You'd need to rewrite or create a second method for another type. The generic not only works for any type but does even more when it comes to inheritance (covariance, contravariance and so on). Well you know. – Everts Mar 17 '18 at 09:29
  • @Programmer I'm sure everyone (including me) really appreciates the time and effort you put for the community, but sometimes I have difficulties to understand your reasoning. You may righteously close a question for being duplicated and then you take the time to answer this one which is clearly a duplicate too. But we're getting off topic now... – Everts Mar 17 '18 at 09:37