# How to access specific child indices (directly, not using tags or searches)?

I have a game object whose prefab is structured a very specific way. It is a conveyor belt. I intend to arrange them end-to-end and animate them all at once using a script. Right now I am trying to get the normalized heading vector between two children, TargetStart and TargetEnd (see images below):

You can see that both of these objects are children of the prefab's first child. Because all of these instances will be structured the same, I want to compute the heading for the conveyor belt by accessing the locations of these children by their indices relative to the parent (which sounds like it should be simple and should be more efficient than searching by name or tag). I am anticipating a structure like this (pseudo-code):

// heading = targetEnd's position - targetStart's position
vector3 heading = gameObject.GetChild[0][1].position - gameObject.GetChild[0][0].position;


How can this be done? I would like to know this so I can access any child I need to for any object by the child's index.

Accessing by index is a little fragile, if the structure of your prefab were ever to change.

As your object is a prefab, you might consider adding fields to your ConveyorBelt script for the start and end position objects instead, like so:

public class ConveyorBelt : MonoBehaviour
{
[SerializeField] private Transform targetStart;
[SerializeField] private Transform targetEnd;
// . . .
}


You'd then access targetStart.position and similar, caching the values as you are already if it becomes a performance concern.

Unity will persist references to objects which are part of the same prefab, so every instance will reference its own start / end points. This allows a bit more flexibility for any future changes to your object structure.

Whelp, I feel silly now. I thought I kept stumbling over this before but the answer is in the documentation example. This is how I am doing it:

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

public class ConveyorBelt : MonoBehaviour
{
public bool isMoving = true;
public float speed = 0.1f;
private float offset = 0f;
private Vector3 targetStart;
private Vector3 targetEnd;
private Vector3 direction;
// Start is called before the first frame update
void Start()
{
targetStart = gameObject.transform.GetChild(0).GetChild(0).position;
targetEnd = gameObject.transform.GetChild(0).GetChild(1).position;
}

// Update is called once per frame
void Update()
{
if (isMoving == true)
{
MoveBelt();
}
}

public void MoveBelt()
{
offset += (Time.deltaTime * speed);
if (Mathf.Abs(offset) > 999)
{
offset %= 1f; //thought this might save memory, maybe not
}
gameObject.GetComponent<Renderer>().material.SetTextureOffset("_MainTex", new Vector2(0, offset));
}

public void StopBelt()
{
isMoving = false;
}

public void OnTriggerStay(Collider other)
{
if (other.attachedRigidbody && isMoving == true)
{
other.transform.position = other.transform.position + direction * Time.deltaTime / (2 * Mathf.PI * 0.25f + 3f);
}
}
public void SetSpeed(float newSpeed)
{
speed = newSpeed;
}
}