- Home /
Need help trying to make enemy detect player's projectiles
I'm trying to make an enemy ship to dodge the player projectile when in sight of it and continue to chase after the player. I couldn't find any proper tutorial on how to do this. When tried to get this to work, I ran into trouble with the enemies not tracking the player and following them.
using UnityEngine;
using System.Collections;
public class EnemyControllerBasic : MonoBehaviour {
// The different IDS for the AI states
enum AIMode { Normal, Ramming, SteerTowards, Avoid };
void Start () {
// find the player ship game object by name
GameObject playerShip = GameObject.Find("PlayerShip");
GameObject Bullet = GameObject.Find("PlayerProjectile");
// Acess the player ship's script component by type
PlayerShipCtrl = playerShip.GetComponent<ShipPlayerController>();
// Always start in the normal state
CurrentAIState = AIMode.Normal;
}
// Update is called once per frame
void Update () {
transform.position +=
transform.up * Time.deltaTime * MoveSpeed;
// Decides which AI state should be currently active
DetermineAIState();
EnemyPickup();
// Depending on the current Ai mode
switch (CurrentAIState)
{
// Normal STATE
case AIMode.Normal:
UpdateNormal();
break;
// Rammin State
case AIMode.Ramming:
UpdateRamming();
break;
// STeer towards the player
case AIMode.SteerTowards:
UpdateSteerTowards();
break;
}
}
void UpdateNormal() {
// Move the object in the direction is facing
transform.position +=
transform.up * Time.deltaTime * MoveSpeed;
}
void UpdateRamming() {
// move the object in the direction it's facing
transform.position +=
transform.up * Time.deltaTime * MoveSpeed;
}
void DetermineAIState() {
bool canSee = CanSeeTarget("PlayerShip");
// Subtract the enemy current position from the player
Vector3 directionToPlayer =
PlayerShipCtrl.transform.position - transform.position;
// Dot product of two vectors represent a cosine angle between them
float product = Vector3.Dot(transform.up, directionToPlayer);
// Convert the cosine value to a radian angle
float angle = Mathf.Acos(product);
// Convert the radian angle into a degree angle
angle = angle * Mathf.Rad2Deg;
if (canSee)
{
// If so, change to ramming mode
CurrentAIState = AIMode.Ramming;
}
else if (product > 0 && angle < 90)
{
// Change the state to steertoward
CurrentAIState = AIMode.SteerTowards;
// Change its color to green to enote
renderer.material.color = Color.green;
}
else
{
// If not, return to normal state
CurrentAIState = AIMode.Normal;
renderer.material.color = Color.white;
}
}
// Determines if the this AI can "See" the player
bool CanSeeTarget(string _targetTag)
{
// Contains data about collision
RaycastHit hitInfo;
// Performs a ray cast
bool hitAny = Physics.Raycast(transform.position, transform.up, out hitInfo);
if (hitAny)
{
if (hitInfo.collider.gameObject.tag == _targetTag)
{
return true;
}
}
return false;
}
void UpdateSteerTowards() {
// Subtact the enemies current position from the player
Vector3 directionToPlayer =
PlayerShipCtrl.transform.position - transform.position;
// rotate the enemy's movement direction
transform.up = Vector3.RotateTowards(transform.up,
directionToPlayer,
Time.deltaTime * MoveSpeed,
0.0f);
UpdateNormal();
}
void UpdateAvoid() {
Vector3 directionToProjectile =
Projectile.transform.position + transform.position;
transform.up = Vector3.RotateTowards(transform.up,
directionToProjectile,
Time.deltaTime * MoveSpeed,
0.0f);
}
}
you are not calling UpdateAvoid()
anywhere.
edit : and your code doesn't work in anyway, so many references missing. is this something you have working in any way?
Answer by LeftRight92 · Oct 20, 2014 at 04:21 AM
Fished out what bugs I could, I recommend you look into basic OOP, there are a lot of places where your trying to call a variable out of scope or are trying to create a variable without naming it. Note that in it's current state, the ship will only detect a bullet that existed before the ship did (as you are scanning for bullets in Awake()).
using UnityEngine;
using System.Collections;
public class EnemyControllerBasic : MonoBehaviour {
// The different IDS for the AI states
enum AIMode { Normal, Ramming, SteerTowards, Avoid };
private AIMode currentAIState = AiMode.Normal;
private GameObject playerShip;
private GameObject bullet;
private PlayerShipCtrl playerController;
void Start () {
// find the player ship game object by name
playerShip = GameObject.Find("PlayerShip");
bullet = GameObject.Find("PlayerProjectile");
// Acess the player ship's script component by type
playerController = playerShip.GetComponent<ShipPlayerController>();
}
// Update is called once per frame
void Update () {
transform.position +=
transform.up * Time.deltaTime * MoveSpeed;
// Decides which AI state should be currently active
DetermineAIState();
EnemyPickup();
// Depending on the current Ai mode
switch (currentAIState)
{
// Normal STATE
case AIMode.Normal:
UpdateNormal();
break;
// Rammin State
case AIMode.Ramming:
UpdateRamming();
break;
// STeer towards the player
case AIMode.SteerTowards:
UpdateSteerTowards();
break;
}
}
void UpdateNormal() {
// Move the object in the direction is facing
transform.position +=
transform.up * Time.deltaTime * MoveSpeed;
}
void UpdateRamming() {
// move the object in the direction it's facing
transform.position +=
transform.up * Time.deltaTime * MoveSpeed;
}
void DetermineAIState() {
bool canSee = CanSeeTarget("PlayerShip");
// Subtract the enemy current position from the player
Vector3 directionToPlayer =
playerShip.transform.position - transform.position;
// Dot product of two vectors represent a cosine angle between them
float product = Vector3.Dot(transform.up, directionToPlayer);
// Convert the cosine value to a radian angle
float angle = Mathf.Acos(product);
// Convert the radian angle into a degree angle
angle = angle * Mathf.Rad2Deg;
if (canSee)
{
// If so, change to ramming mode
currentAIState = AIMode.Ramming;
}
else if (product > 0 && angle < 90)
{
// Change the state to steertoward
currentAIState = AIMode.SteerTowards;
// Change its color to green to enote
renderer.material.color = Color.green;
}
else
{
// If not, return to normal state
currentAIState = AIMode.Normal;
renderer.material.color = Color.white;
}
}
// Determines if the this AI can "See" the player
bool CanSeeTarget(string _targetTag)
{
// Contains data about collision
RaycastHit hitInfo;
// Performs a ray cast
bool hitAny = Physics.Raycast(transform.position, transform.up, out hitInfo);
if (hitAny)
{
if (hitInfo.collider.gameObject.tag == _targetTag)
{
return true;
}
}
return false;
}
void UpdateSteerTowards() {
// Subtact the enemies current position from the player
Vector3 directionToPlayer =
playerController.transform.position - transform.position;
// rotate the enemy's movement direction
transform.up = Vector3.RotateTowards(transform.up,
directionToPlayer,
Time.deltaTime * MoveSpeed,
0.0f);
UpdateNormal();
}
void UpdateAvoid() {
Vector3 directionToProjectile =
bullet.transform.position + transform.position;
transform.up = Vector3.RotateTowards(transform.up,
directionToProjectile,
Time.deltaTime * MoveSpeed,
0.0f);
}
}