GameObject.Find always returns null even when the object exists
Hello I am working on a typing game where the player enters a string into an inputfield and once the string is submitted, the player will find an enemy of that name and shoot at it (enemies randomly spawn with a name that is a word from a text file) In my script for shooting the enemies I use a GameObject.Find function but it always returns null. Here is my script :
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class KillTarget : MonoBehaviour {
public bool isSent;
public GameObject shot;
public string nameToFind;
public float speed;
private Quaternion rot;
public Transform shotspawn;
public Transform turret;
void Start () {
isSent = false;
}
void Update () {
if (isSent == true) {
nameToFind = TextInput.newText;
GameObject go = GameObject.Find(nameToFind.ToLower());
if (go != null)
{
if(go.GetComponent<SpriteRenderer>().isVisible)
{
Debug.Log("The Target is : " + go.name);
Explode(go);
}
else
{
Miss (go);
}
}
else
{
Miss (go);
}
}
}
void Explode(GameObject go)
{
rot = Quaternion.LookRotation (turret.position - go.transform.position, Vector3.forward);
turret.rotation = rot;
turret.eulerAngles = new Vector3 (0, 0, turret.eulerAngles.z);
GameObject clone = Instantiate (shot, shotspawn.position,Quaternion.identity) as GameObject;
clone.GetComponent<Rigidbody2D> ().velocity = clone.transform.up * speed;
isSent = false;
}
void Miss(GameObject go)
{
Destroy (go);
Debug.Log ("No Target");
isSent = false;
}
}
the newText string is from the text input and isSent is also from the text input
Any Ideas on how I could make this work?
If the object is instantiated via code, it could be that the "(Clone)" extension is appended to the name. A a result:
myObject is not myObject(Clone)
You would need to rename the object on creation.
I do change the name when the object is instantiated so there is no (Clone) on the end This is the spawner code :
using UnityEngine;
using System.Linq;
using System.Collections.Generic;
using System.IO;
using System.Text;
public class GameplayEngine : $$anonymous$$onoBehaviour {
public List<string> fileLines;
public Transform[] SpawnPoints;
public GameObject[] prefab;
public string[] words;
public string fileDestination;
void Start ()
{
var sr = File.OpenText(Application.dataPath + fileDestination);
fileLines = sr.ReadToEnd().Split('\n').ToList();
words = fileLines.ToArray ();
sr.Close();
InvokeRepeating("SpawnEnemy", 3, 5);
}
void SpawnEnemy(){
int enemyIndex = Random.Range(0, prefab.Length);
string unitname = words[(int)Random.Range(0,words.Length)];
Transform spawnPoint = SpawnPoints[(int)Random.Range(0,SpawnPoints.Length)];
Vector3 pos = spawnPoint.position;
GameObject clone = Instantiate(prefab[enemyIndex], pos, Quaternion.identity) as GameObject;
clone.name = unitname.ToLower();
clone.GetComponentInChildren<GUIText>().text = unitname;
clone.SetActive (true);
}
}
so the enemies in the hierarchy have names like "goose" and "halibut" all are in lower case.
Cool concept with having the player type in the name of the target @Tobalation
$$anonymous$$y guess would be what @fafase said, about having "(clone)" at the end of the instantiated object.
But you should still be able to target the first spawned object because it wouldn't have "(clone)" at the end.
Cheers!
Well, are you sure the "No target" is because it was not found or because it was not visible?
if (go != null) {
if(go.GetComponent<SpriteRenderer>().isVisible){
Debug.Log("The Target is : " + go.name);
Explode(go);
} else {
$$anonymous$$iss (go); // here if go found but renderer is not visible
}
}else {
$$anonymous$$iss (go); // here if no go found
}
You use the same method for two totally different actions, you should pass a parameter to define where you are.
void $$anonymous$$iss(GameObject go, string message)
{
Destroy (go);
Debug.Log (message);
isSent = false;
}
Answer by Positive7 · Aug 25, 2015 at 09:30 AM
TextInput.cs should have a get/set value and it works like charm here :
using UnityEngine;
using UnityEngine.UI;
public class TextInput : MonoBehaviour {
public static string newText;
public string _newText{
get {return newText;}
set {newText = value;}
}
void Update () {
_newText = GetComponent<Text> ().text;
}
}
I tried using the get/set value like @Positive7 said but it still won't work.
I get the value nameToFind
but GameObject.Find
doesnt't return anything.
Hmmm... I'll check my test scene again and let you know, if I found somethig.
Your answer
Follow this Question
Related Questions
Move gameObject on UI Button Press 2 Answers
Object looses Inspector properties When Scene returns 1 Answer
Revers Object Transfrom using an array problem in UI !! 0 Answers
What to use instead of GameObject.Find and GetComponent 2 Answers
"cannot implicitly convert type `UnityEngine.GameObject' to `UnityEngine.UI.Text' 2 Answers