- Home /
Make an Enemy Shoot through Raycast
Hello fellow developers,
How do I make an enemy shoot via Raycast? I tried for hours and I didn't came to a solution, even using allmighty Google I haven't found anything. I had some ideas, but I don't know how to realise these. The enemy should turn towards the player, then "shoot" a ray. Has anyone a better approach on doing that, or any helpful documentation?
Thank you in advance, everyone!
-Cheatsrichter-
nvm solved it by using not this ray Ray ray = new Ray(transform.position, target.position);
Ins$$anonymous$$d this: Ray ray = new Ray(transform.position, transform.TransformDirection(Vector3.forward));
... Yes? Is there any kind of question co$$anonymous$$g? Please give more information, what are you trying to do? Do you need help with using the Physics.Raycast function?
No, there are no new questions, but thanks for your reply! Solved it through some trial and error.
Answer by MegaBomb_Unity · Oct 18, 2021 at 04:54 PM
How convenient. I almost successfully programmed my enemy raycast was planning to ask people how to add an ability to shoot upwards. Alright, so how about this, copy my code and see if you can find a way to shoot upwards 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;
}
}
Your answer
Follow this Question
Related Questions
Raycast damage script 2 Answers
change to raycast shooting instead of rigidbody shooting 1 Answer
Raycast Shooting problem 2 Answers
Raycast Shooting Help 1 Answer
NEED HELP WITH RAYCAST SHOOTING !!! 1 Answer