How To Access Children of a Parent Object

Hi all,

I’m trying to build something that looks for the closest gameobject to the player (in this case a weapon) and fulfilling a set of conditions draws a ray between two ‘attach points’.

What I’ve done doesn’t seem to work, so how best might I access the children of my known objects ‘player’ and ‘closest_weapon’?

The end result will create a force to drag the weapon to the player, align the gun to the player, and set the gun as a child of the player (much easier than rebuilding the floating physics wow-factor script I did for the main player for each weapon I make).

At the moment the code properly recognises the nearest weapon object, but freezes the player in place with no visible ray being drawn upon setting the boolean to be true. I assume this is because it’s getting confused as to where to draw the line or something.

Cheers for your time!

Popupirate

using UnityEngine;
using System.Collections;

public class Weapon_Control_Script : MonoBehaviour {

	public GameObject closest_weapon; 
	public bool attach_weapon;
	public float distance;


	// Use this for initialization
	void Start () {
		
}
	
	// Update is called once per frame
	void Update () {
		if (attach_weapon == false) {
			SearchForWeapons();		
		}

		if (attach_weapon == true) {
			AttachWeapon();	
		}

}


void AttachWeapon(){ //Look Here!
		Transform p_trans = transform.FindChild ("PlayerAttachPoint"); 
		Transform w_trans = closest_weapon.transform.FindChild ("WeaponAttachPoint");

		Vector3 player_attach_vect = new Vector3 (p_trans.position.x, p_trans.position.y, p_trans.position.z);
		Vector3 weapon_attach_vect = new Vector3 (w_trans.position.x, w_trans.position.y, w_trans.position.z);
		Vector3 direction = weapon_attach_vect - player_attach_vect;
		Debug.DrawRay (player_attach_vect, direction, Color.green);
		//closest_weapon.rigidbody.AddForce (-direction * 4);
}


void SearchForWeapons(){ //This works lovely jubly
	GameObject[] weapons = GameObject.FindGameObjectsWithTag ("Weapon"); 					
	distance = Mathf.Infinity;															
	for (int i=0; i<weapons.Length; i++) { 												
		Vector3 diff_vect = weapons *.transform.position - transform.position;			*
  •  float diff_abs = Mathf.Abs (diff_vect.sqrMagnitude);								*
    
  •  if (diff_abs < distance) {															*
    

closest_weapon = weapons ;
distance = diff_abs;
_
}
_
* }*
* Debug.Log (closest_weapon.name);
_
}*_

}

I see a couple issues. You are calling GameObject.Find every single frame (this is very slow and will cause lag in larger projects) and I don’t see where you set attach_weapon to true or false. I would start by altering the script like this to run faster. I also added a Debug after DrawRay to check for expected values and set the fifth argument in DrawRay to show through any foreground. Also just to be sure, you know DrawRay only shows in the scene view, not the game window?

using UnityEngine;
using System.Collections;
 
public class Weapon_Control_Script : MonoBehaviour {
 
public GameObject closest_weapon;
public bool attach_weapon;
public float distance;

private Transform p_trans;
private Transform w_trans;
private GameObject[] weapons;

void Start () { //I'm assuming these wont change at runtime.
    p_trans = transform.FindChild ("PlayerAttachPoint");
    weapons = GameObject.FindGameObjectsWithTag ("Weapon");
}
 
// Update is called once per frame
void Update () {
    if (attach_weapon == false) {
        SearchForWeapons();
    }
 
    if (attach_weapon == true) {
        AttachWeapon();
    }
}
 
void AttachWeapon(){ //Look Here!
    Vector3 player_attach_vect = p_trans.position;
    Vector3 weapon_attach_vect = w_trans.position;
    Vector3 direction = weapon_attach_vect - player_attach_vect;
    Debug.DrawRay (player_attach_vect, direction, Color.green, 1.0f, false);
    //closest_weapon.rigidbody.AddForce (-direction * 4);
    Debug.Log(player_attach_vect+", "+direction);
}
 
 
void SearchForWeapons(){ //This works lovely jubly
    distance = Mathf.Infinity;
    for (int i=0; i<weapons.Length; i++) {
        Vector3 diff_vect = weapons *.transform.position - transform.position;*

float diff_abs = Mathf.Abs (diff_vect.sqrMagnitude);
if (diff_abs < distance) {
closest_weapon = weapons ;
distance = diff_abs;
}
}
if (w_trans == null || w_trans.parent.name != closest_weapon.name) w_trans = closest_weapon.transform.FindChild(“WeaponAttachPoint”);
Debug.Log (closest_weapon.name+" distance: "+distance);
}

}
I tested this script in a project with only the necessary elements and it worked as expected. Let me know if you have any questions about what I changed. Also, if the weapons are created dynamically, I can suggest alternatives to assigning them at the start.