- Home /
Self Answered
[SOLVED]Object selection scrip doesn't work.
I'm trying to create script that'll find objects with tag "Enemies" and put them into array, then get their transforms and put it in other array, then find the one with is nearest and finaly lookAt at this object. When i click "Play", NullReferenceExceptions start to show up and nothing happends. Please, help me get this script working!
Script:
using UnityEngine;
using System.Collections;
public class TurretScript : MonoBehaviour {
private Transform target;
private GameObject[] enemies1;
private Transform[] enemies2;
private int counter;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
transform.LookAt (target.position);
enemies1 = GameObject.FindGameObjectsWithTag ("Enemy");
foreach(var Entities in enemies1){
enemies2[counter] = Entities.transform;
counter++;
}
target = GetClosestEnemy (enemies2);
}
Transform GetClosestEnemy(Transform[] enemies)
{
Transform tMin = null;
float minDist = 10;
Vector3 currentPos = transform.position;
foreach (Transform t in enemies)
{
float dist = Vector3.Distance(t.position, currentPos);
if (dist < minDist)
{
tMin = t;
minDist = dist;
}
}
return tMin;
}
}
This line:
transform.LookAt (target.position);
If that executes before you have a target
set, you'll get a NullReferenceException
. Once that happens, the rest of your Update
function won't execute.
So... on the first frame, you don't seem to have a target, yet. Because the exception stops script execution, you won't be able to set one, either.
Fix might be as simple as a null check:
if (target != null) {
transform.LookAt(target.position);
}
Checking if "target" isn't null kind of helped - but now other reference exception show up every frame saying that "Object reference not set to an instance of an object". It shows that the error is in line 38: "foreach (Transform t in enemies)"
Answer by markedagain · Jul 23, 2014 at 12:37 AM
you have many issues here, one big issue is you are not reseting your "counter" that means the 2nd time it updates u are adding the same enemies over and over again and the array will keep getting bigger until it overflows.
so at some point you have to add counter = 0
another issue with this method is how would you handle once u remove enemies from the list. the array will still hold a reference to the enemy and when u try to get its position it will give u a null exception.
Answer by Vertedex · Jul 30, 2014 at 08:06 AM
After writing it again (with much bigger knowledge), i made this:
using UnityEngine;
using System.Collections;
using System;
public class IfCloseEnought : MonoBehaviour {
public GameObject[] enemies;
public float range = 10;
public float minimalDistance = 65879;
public float measureDistance;
public GameObject target;
private int number;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
enemies = GameObject.FindGameObjectsWithTag ("Enemy");
foreach (GameObject enemy in enemies) {
measureDistance = Vector3.Distance (gameObject.transform.position, enemy.transform.position);
if (measureDistance < minimalDistance && measureDistance < range) {
target = enemy;
minimalDistance = measureDistance;
number++;
}
}
if(target == null){
minimalDistance = 65879;
}
if(target != null){
if(Vector3.Distance(gameObject.transform.position, target.transform.position) > range){
target = null;
}
}
Array.Clear(enemies, 0, enemies.Length);
number = 0;
Debug.Log(target);
Debug.Log(minimalDistance);
}
}
It works.
great work on grasping the concept and thank you for closing ticket and putting proper answer :) good luck with the rest of the project
Follow this Question
Related Questions
A problem with arrays 1 Answer
properly initializing my arrays (C#) 2 Answers
Picking a Random Order for Levers 1 Answer
Instantiate duplicates script in subsequent Objects 2 Answers