Good question.
For my projects, I do something by the lines of this;
using UnityEngine;
using System.Collections;
public class ExampleClass : MonoBehaviour {
public Transform target;
public float closeDistance = 25.0F;
void Update() {
if (target) {
Vector3 offset = target.position - transform.position;
float sqrLen = offset.sqrMagnitude;
if (sqrLen < closeDistance)
//If the [target] is closer than [closeDistance] away from me,
//execute code here.
}
}
}
Make sure closeDistance is the squared amount of the distance you want. Usually, the magnitude script performs the sqrt function which is quite memory expensive, so sqrMagnitude is a faster alternative. I’m sure computers can do maths without eating your memory away unlike calculating multiple raycasts on a 3D or 2D space. Hopefully, that helps
Hey I had a similar situation earlier today. I was able to solve it by using Physics.OverlapSphere. This allows you to detect objects around you 360 degrees. If you don’t want to call this method every frame, you can call it in a coroutine instead of update. Here is a code example.
using UnityEngine;
using System.Collections;
public class Raycast_ToJump : MonoBehaviour {
float distanceToCheckForEnemy = 1;
// Update is called once per frame
void Update () {
DetectEnemy(transform.position, 1);
}
private void DetectEnemy(Vector3 center, float radius) {
var hitColliders = Physics.OverlapSphere(center, radius);
for (var i = 0; i < hitColliders.Length; i++) {
// collect information on the hits here
print(hitColliders*.tag);*
Here is an optimized solution that allows you to set how often to run a check “findDelay”.
I’m using the optimized Vector3.SqrMagnitude instead of Vector3.Distance because we only need to know which enemy is closest, not the exact meter distance (which would need Square-Root).
The list of enemies is stored at start so you may need to update the list if an enemy is added or removed.
Attach on any GameObject in scene, and from any script:
EnemyFinder.closestEnemy
to access current closest enemy.
Hope it helps!
using UnityEngine;
using System.Collections;
public class EnemyFinder : MonoBehaviour {
public float findDelay=0.25f;//updates 4 times per second
public static GameObject closestEnemy;
GameObject[] enemies;
void Start () {
enemies=GameObject.FindGameObjectsWithTag("Enemy");
InvokeRepeating("findClosestEnemy",0f,findDelay);
}
public void findClosestEnemy(){
float smallestDist=float.MaxValue;
Vector3 playerPos=Camera.main.transform.position; // assuming player is in same position as main camera
GameObject newClosestEnemy=closestEnemy;
foreach(GameObject enemyObj in enemies){
float dist=Vector3.SqrMagnitude(enemyObj.transform.position-playerPos);
if(dist<smallestDist){
newClosestEnemy=enemyObj;
smallestDist=dist;
}
}
if(newClosestEnemy!=closestEnemy){
closestEnemy=newClosestEnemy;
print("NEW Closest Enemy = "+closestEnemy);
}
}
}