I am having an issue with vector 3 angles when multiple game objects are involved
This reference from unity works perfectly; however, it only works when trying to detect the angle of a single game object. Is there some way to make this into an array, so that it detects whether or not any game objects are within a certain degrees? As of now, it only detects the angle of a single game object and ignores any others. C# only please, THANKS!!!!
using UnityEngine;
using System.Collections;
public class ExampleClass : MonoBehaviour {
public Transform target;
void Update() {
Vector3 targetDir = target.position - transform.position;
Vector3 forward = transform.forward;
float angle = Vector3.Angle(targetDir, forward);
if (angle < 5.0F)
print("close");
}
}
Answer by Justice-V18 · Feb 18, 2016 at 12:30 PM
You could use a for loop to achieve this:
using UnityEngine;
using System.Collections;
public class ExampleClass : MonoBehaviour {
public Transform[] target;//add all objects here
private int i;//Made it global so when I can make it 0 easily and start for loop again.
float angle;
void Update()
{
for (i = 0; i < target.Length; i++)//go from through whole array.
{
Vector3 targetDir = target [i].position - transform.position;
Vector3 forward = transform.forward;
angle = Vector3.Angle (targetDir, forward);
if (angle < 5.0F)
{
print ("Close" + target [i].name);
}
}
if(i == target.Length - 1)//This happens after the for loop has gone through all of them.
i = 0;//rest "i" back to 0 so we can start the for loop again.
}
}
two things, why not just declare the variable in the for syntax, each frame that invokes the Update method would reset the i variable each invocation. Second, unless you know the size of the loop when deter$$anonymous$$ing things like distance or in the case angle it's a good idea to put a WaitForSeconds or yield out of the Update method so it's not iterating over the loop, you can introduce lag when a pause can occur from being in the loop. If the game had 100 Transform objects in that array and the game ran @ 60fps you would be looping over the array and deter$$anonymous$$ing the angle of 6000 transform objects(which may not change all that much within that second) times per second, chances are you can optimize this to say only run through the array 4 times a second(400 transform/angle considerations), or perhaps 1 time per second is enough...
That is true, this code isn't supposed to be used for 100's of objects. Also thanks for pointing out i that can reset 0 to if declared before the for loop. The code bellow does what the script above does, but waits for x number of seconds before searching again:
public Transform[] target;//add all objects here
public float waitSec;
float angle;
void Start()
{
StartCoroutine (CheckDistance());
}
IEnumerator CheckDistance()
{
int i;
for (i = 0; i < target.Length; i++)//go from through whole array.
{
Vector3 targetDir = target [i].position - transform.position;
Vector3 forward = transform.forward;
angle = Vector3.Angle (targetDir, forward);
print (target [i].name);
if (angle < 5.0F)
{
print ("Close to: " + target [i].name);
}
}
yield return new WaitForSeconds (waitSec);
StartCoroutine (CheckDistance());
}
Also I'm not 100% sure if this is the best way to restart the Coroutine. But i did test it and it works.