How to have enemy only shoot when they are within a certain range?
I have my Enemy Tank setup to only shoot when they are within 25 units of the Player Tank, but I want the Enemy Tank to also only shoot if they are greater than 10 Units and Less than 25 units of the Player Tank (since the bombs do damage based on how close you are, it wouldn't seem realistic to have the enemy shoot if it's going to cause damage on the enemy as well). Here is my class setup currently, and it doesn't seem to be working too well. (the main part is at the end of the code)
using UnityEngine;
using System.Collections;
using PlayerInfo;
using Shell;
namespace EnemyInfo
{
public class EnemyMovement : MonoBehaviour
{
public Transform player;
public Transform EnemyTank;
public int AttackRange = 35;
public bool inRange;
public int TooClose = 10;
NavMeshAgent agent;
static PlayerHealth pHealth;
static EnemyHealth eHealth;
Rigidbody Rigidbody;
void Awake ()
{
player = GameObject.FindWithTag ("Player").transform;
pHealth = player.GetComponent<PlayerHealth> ();
eHealth = GetComponent<EnemyHealth> ();
Rigidbody = GetComponent<Rigidbody> ();
}
void OnEnable ()
{
Rigidbody.isKinematic = false;
}
void OnDisable ()
{
Rigidbody.isKinematic = true;
}
void Update ()
{
NavMeshAgent agent = GetComponent<NavMeshAgent> ();
if (pHealth.CurrentHealth > 0 && eHealth.CurrentHealth > 0)
{
agent.SetDestination (player.position);
transform.LookAt (player.position);
}
else
{
agent.enabled = false;
}
if (Vector3.Distance (player.position, EnemyTank.position) < AttackRange) {
if (Vector3.Distance (player.position, EnemyTank.position) > TooClose)
{
inRange = true;
}
}
else if (Vector3.Distance (player.position, EnemyTank.position) > AttackRange)
{
inRange = false;
}
}
}
}
@dhore , since you help me with everything else I thought I would tag you :)
Answer by dhore · Jan 08, 2016 at 02:03 AM
I made a few changes to your code, hopefully it works...
Changes start at lines 20, 32 & 61 and all have comments explaining them.
using UnityEngine;
using System.Collections;
using PlayerInfo;
using Shell;
namespace EnemyInfo
{
public class EnemyMovement : MonoBehaviour
{
public Transform player;
public Transform EnemyTank;
public int AttackRange = 35;
public bool inRange;
public int TooClose = 10;
NavMeshAgent agent;
static PlayerHealth pHealth;
static EnemyHealth eHealth;
// change the name of the Rigidbody variable to have a lower case 'r' so that the compiler won't confuse it with the Type Rigidbody
// (variable type names are reserved words, so you should never use these words with the exact capitalization for a variable name)
// remember to change the name where you use it below too
Rigidbody rigidbody;
void Awake ()
{
player = GameObject.FindWithTag ("Player").transform;
pHealth = player.GetComponent<PlayerHealth> ();
eHealth = GetComponent<EnemyHealth> ();
rigidbody = GetComponent<Rigidbody> ();
// EnemyTank is never initialized (unless you did that from the inspector)
// assuming this script is attached to the EnemyTank, if so then this would work:
EnemyTank = transform;
}
void OnEnable ()
{
rigidbody.isKinematic = false;
}
void OnDisable ()
{
rigidbody.isKinematic = true;
}
void Update ()
{
NavMeshAgent agent = GetComponent<NavMeshAgent> ();
if (pHealth.CurrentHealth > 0 && eHealth.CurrentHealth > 0)
{
agent.SetDestination (player.position);
transform.LookAt (player.position);
}
else
{
agent.enabled = false;
}
// ok, so this part needs to be changed just a little bit
// firstly we're going to store the Distance in a variable to avoid multiple calls to the exact same function
float distance = Vector3.Distance (player.position, EnemyTank.position);
// there's no need to use nested if statements here - you could just check both conditions in the same IF
// BUT there's an even quicker way to do what you want:
// inRange will be True if the condition is True - otherwise it will be False
// therefore just do this:
inRange = ((distance < AttackRange) && (distance > TooClose));
}
}
}
Let me know if this fixes your problem :)
Doesn't seem to work. The enemy is still shooting no matter how close he is.
Ok, well which script controls the shooting? Because the above script only seems to control the decision making, but not the actual shooting.
@ltrout1999 I know what you mean, but without knowing how all of your code works together I may not be able to give you any exact working code. Though the following code should give you your random percent that you want:
int missChance = 45; // chance of missing
float distance = Vector3.Distance (player.position, EnemyTank.position);
int randPercent = Random.Range(1,100); // random number for percent chance
if (randPercent <= missChance)
{
// bullet misses
LaunchForce = 0; // probably wouldn't work - read below
}
else
{
// bullet hits
LaunchForce = distance; // may not work either - read below
}
So yeah, I don't expect that to work.... but it may....
I'm not sure exactly how you want to accomplish hitting & missing the target... will the bullet just fall short? Or do you want it to shoot off to the side? The above code should just make it fall short, but depending on how your bullet collisions and such are handled that could cause lots of unforeseen issues...
Anyway, get back to me if you decide what you need and want some more help - I'm quite happy to help you out :)
Your answer
![](https://koobas.hobune.stream/wayback/20220612055355im_/https://answers.unity.com/themes/thub/images/avi.jpg)