- Home /
Programming an enemy to shoot upwards
I am trying to program a RayCast enemy that shoots a laser. The problem with this code is that I can't get it to shoot upwards. I know it involves getting the y position of the player, but I just don't know how.
using UnityEngine; using System.Collections; using UnityEngine.AI;
public class EnemyAiTutorial : MonoBehaviour { [SerializeField] Transform enemy;
 [SerializeField] NavMeshAgent agent;
 [SerializeField] Transform player;
 [SerializeField] LayerMask whatIsGround, whatIsPlayer;
 [Space]
 //Patroling
 [SerializeField] Vector3 walkPoint;
 bool walkPointSet;
 [SerializeField] float walkPointRange;
 //Attacking
 [SerializeField] float timeBetweenAttacks;
 [SerializeField] bool isShooting;
 bool alreadyAttacked;
 [Space]
 //States
 [SerializeField] float sightRange, attackRange;
 [SerializeField] bool playerInSightRange, playerInAttackRange;
 [Space]
 [SerializeField] float delaySeconds = 1.5f;
 [SerializeField] bool fire;
 [SerializeField] float range = 100f;
 [SerializeField] float damage = 20f;
 [SerializeField] Vector3 characterOffSet = new Vector3(0f, 0.3f, 0);
 [SerializeField] Vector3 aimOffSet = new Vector3(0, 1, 0);
 private LineRenderer laser;
 bool fireLaser;
 #region Awake & Update functions
 private void Awake()
 {
     player = GameObject.Find("Player").transform;
 }
 public void Start()
 {
     laser = GetComponent<LineRenderer>();
 }
 private void Update()
 {
     //Check for sight and attack range
     playerInSightRange = Physics.CheckSphere(transform.position, sightRange, whatIsPlayer);
     playerInAttackRange = Physics.CheckSphere(transform.position, attackRange, whatIsPlayer);
     if (!playerInSightRange && !playerInAttackRange) Patroling();
     if (playerInSightRange && !playerInAttackRange) ChasePlayer();
     if (playerInAttackRange && playerInSightRange) AttackPlayer();
     laser.SetPosition(0, enemy.transform.position + characterOffSet);
     if (!fireLaser)
     {
         laser.SetPosition(1, enemy.transform.position + characterOffSet);
     }
 }
 #endregion
 #region States
 private void Patroling()
 {
     if (!walkPointSet) SearchWalkPoint();
     if (walkPointSet)
         agent.SetDestination(walkPoint);
     Vector3 distanceToWalkPoint = transform.position - walkPoint;
     //Walkpoint reached
     if (distanceToWalkPoint.magnitude < 1f)
         walkPointSet = false;
 }
 private void SearchWalkPoint()
 {
     //Calculate random point in range
     float randomZ = Random.Range(-walkPointRange, walkPointRange);
     float randomX = Random.Range(-walkPointRange, walkPointRange);
     walkPoint = new Vector3(transform.position.x + randomX, transform.position.y, transform.position.z + randomZ);
     if (Physics.Raycast(walkPoint, -transform.up, 2f, whatIsGround))
     {
         walkPointSet = true;
     }
 }
 private void ChasePlayer()
 {
     agent.SetDestination(player.transform.position);
 }
 private void AttackPlayer()
 {
     //Make sure enemy doesn't move
     agent.SetDestination(transform.position);
     if (!isShooting)
     {
         Vector3 aimPlayer = player.transform.position + aimOffSet;
         transform.LookAt(aimPlayer);
     }
     if (!alreadyAttacked)
     {
         StartCoroutine(Shoot());
     }
 }
 private void ResetAttack()
 {
     alreadyAttacked = false;
 }
 #endregion
 IEnumerator Shoot()
 {
     float totalTime = delaySeconds + timeBetweenAttacks;
     isShooting = true;
     yield return new WaitForSeconds(delaySeconds);
     fireLaser = true;
     RaycastHit Hit;
     while (!alreadyAttacked)
     {
         Vector3 onward = transform.TransformDirection(Vector3.forward) * (range);
         Debug.DrawRay(enemy.transform.position, onward, Color.red, 1f);
         if (Physics.Raycast(enemy.transform.position, enemy.transform.forward, out Hit, range))
         {
             laser.SetPosition(1, Hit.point);
             Debug.Log(Hit.collider.name);
             if (Hit.collider.GetComponent<Damagable>() != null)
             {
                 Hit.collider.GetComponent<Damagable>().TakeDamage(damage, Hit.point, Hit.normal);
             }
             else
             {
                 Hit.collider.GetComponent<mapCollision>().TakeDamage(damage, Hit.point, Hit.normal);
             }
         } else
         {
             laser.SetPosition(1, onward);
         }
         alreadyAttacked = true;
     }
     isShooting = false;
     yield return new WaitForSeconds(totalTime);
     fireLaser = false;
     alreadyAttacked = false;
 }
}
Answer by MegaBomb_Unity · Nov 07, 2021 at 02:18 AM
Took me a while but figured out the answer all by myself. Apparently, my code was inefficient and the AI would not look at the exact point where the player would be. What I did was I created a Vector3 for the player's position
 [SerializeField] Vector3 characterOffSet = new Vector3(0f, 0.3f, 0);
 [SerializeField] Vector3 aimOffSet = new Vector3(0, 1, 0);
 private LineRenderer laser;
 bool fireLaser;
 Vector3 target;
and after that, I made the vector 3 look for the player's position whenever it's not shooting and used transform.LookAt on the Vector3
     if (!isShooting)
     {
         Vector3 aimPlayer = player.transform.position + aimOffSet;
         transform.LookAt(aimPlayer);
         target = aimPlayer;
     } else
     {
         transform.LookAt(target);
     }
     if (!alreadyAttacked)
     {
         StartCoroutine(Shoot());
     }
Your answer
 
 
             Follow this Question
Related Questions
Enemy raycast detection 0 Answers
Enemy AI Script Acting Abnormal 0 Answers
AI script works, when we add a blocked function it stops working HELP 0 Answers
Enemy AI Running Through Wall With Raycast 1 Answer
[SOLVED] using var from another method? 2 Answers
 koobas.hobune.stream
koobas.hobune.stream 
                       
                
                       
			     
			 
                