- Home /
how do I restrict my shooting script's raycast to a certain range?
hello, I have a tower script that allows the object it is attached to to rotate towards the nearest enemy with a certain tag and shoot a raycast at that object. however, I have a problem! the tower will rotate towards the object with the tag on it no matter where it is and will shoot a raycast at that object. I am making a MOBA game (like league of legends or Dota 2) and I need the raycast or the tag detection to have a certain range to it so that the tower will only shoot at the enemy with the tag if the enemy is within its range. please help! here is my script:
using System.Linq;
using UnityEngine;
public class Tower : MonoBehaviour
{
public ParticleSystem MuzzleFlash;
private void Update()
{
MuzzleFlash.Play();
var objects = GameObject.FindGameObjectsWithTag("Enemy");
if (!objects.Any())
return;
var distances = objects.Select(s => Vector3.Distance(transform.position, s.transform.position)).ToArray();
var first = distances.First();
var index = 0;
var index1 = 0;
foreach (var distance in distances)
{
if (distance < first)
{
index1 = index;
break;
}
index++;
}
var target = objects[index1];
if (target == null)
return;
var p1 = transform.position;
var p2 = target.transform.position;
var position = new Vector3(p2.x, p1.y, p2.z); // does not bend to target
transform.LookAt(position);
RaycastHit hit;
if (Physics.Raycast(transform.position, transform.forward, out hit))
{
if (hit.collider.gameObject.tag == "Enemy")
{
hit.collider.gameObject.transform.GetComponent<EnemyHealth>().HEALTH -= 1f;
}
}
}
}
It would be much faster for you to look up the docs on Raycast then wait for an answer:
https://docs.unity3d.com/ScriptReference/Physics.Raycast.html
Answer by Llama_w_2Ls · Apr 29, 2021 at 06:19 AM
There is the range parameter on a raycast, but I believe that your code would be a lot more efficient if you used Physics.CheckSphere
to get all nearby enemies, within a radius, instead of looping through all enemies, and checking the distance. Here's an example:
public class Tower : MonoBehaviour
{
public float Range;
void Update()
{
var colliders = Physics.OverlapSphere(transform.position, Range);
var enemies = colliders.Where(x => x.CompareTag("Enemy"));
if (!enemies.Any())
return;
// Do your distance checking and tower locking here,
// with the 'enemies' collection
}
}
Also, be wary of Vector3.Distance
, because I believe it does sometimes return a negative value.
Answer by WerewoofPrime · Apr 29, 2021 at 03:45 PM
hello, llama! I have tried something like this when following a tutorial, ( I was using bullets instead of raycasts at this point) and it did not work because the tower would only shoot one bullet every time an enemy came within its range, and would not shoot at the same target more then once...