I have been trying to do this for a couple of days now and cant seem to get this to work so went back to the drawing board and realised that the “enemy” does move towards the player when player is in range but when the enemy attempts to shoot the player the ray just shoots down through the ground(See attached image)
![using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
public class EnemyAI : MonoBehaviour {
Transform target;
public float aggro_radius = 250f;
NavMeshAgent mesh_agent;
public GameObject mesh_carrier;
public LineRenderer laser;
public float laser_shoot_intervals;
public float laser_damage;
public GameObject enemy_ship;
public bool in_range = false;
// Use this for initialization
void Start () {
target = PlayerManager.instance.player.transform;
mesh_agent = mesh_carrier.GetComponent<NavMeshAgent> ();
laser.useWorldSpace = true;
}
// Update is called once per frame
void Update () {
float distance = Vector3.Distance (target.position, transform.position);
if (distance <= aggro_radius) {
Ray Laser = new Ray (laser.transform.position, target.position);
Debug.DrawRay (transform.position, target.position);
Debug.Log ("Drawing Ray from " + transform.position + " to " + target.position);
}
}
void OnDrawGizmosSelected()
{
Gizmos.color = Color.red;
Gizmos.DrawWireSphere (transform.position, aggro_radius);
}
void checkForCollision(Ray _laserRay)
{
RaycastHit hit;
if (Physics.Raycast (_laserRay, out hit, 100F)) {
if (hit.rigidbody) {
Debug.Log ("We hit " + hit.collider.tag);
}
}
}
}][1]
As you can see the raycast is drawing below the ground, Am not sure why this is when it is receivng the same values as mesh_agent.SetDestination() which seems to work fine.
You give the constructor wrong parameters. Your assumption is that the second argument is the target position, but it’s not. It’s the direction.
Change it to
Ray laser = new Ray(laser.transform.position, (laser.transform.position - target.position))
and see if it works (do the same in the Debug.DrawRay call). If it goes the opposite direction just swap it to (target.position - laser.transform.position)
Ray laser = new Ray (laser.transform.position, (laser.transform.position - target.position));
but i get an error
Assets/EnemyAI.cs(46,31): error CS1061: Type `UnityEngine.Ray' does not contain a definition for `transform' and no extension method `transform' of type `UnityEngine.Ray' could be found. Are you missing an assembly reference?
Any ideas why it doesnt seem to recognise a transform.position in the Ray declaration??
Was silly not to notice the laser declaration… This is only my 1st 3d project in Unity so am trying to learn.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
public class EnemyAI : MonoBehaviour {
Transform target;
public float aggro_radius = 10f;
NavMeshAgent mesh_agent;
public GameObject mesh_carrier;
public LineRenderer laser;
// Use this for initialization
void Start () {
target = PlayerManager.instance.player.transform;
mesh_agent = mesh_carrier.GetComponent<NavMeshAgent> ();
//Start The Coroutine for firing at the player.
StartCoroutine (fire ());
}
// Update is called once per frame
void Update () {
float distance = Vector3.Distance (target.position, transform.position);
if (distance <= aggro_radius) {
mesh_agent.SetDestination (target.position);
}
}
void OnDrawGizmosSelected()
{
Gizmos.color = Color.red;
Gizmos.DrawWireSphere (transform.position, aggro_radius);
}
IEnumerator fire()
{
Ray laser_ray= new Ray (transform.position, ( target.position - laser.transform.position));
//This goes from the ship object position to the target and then back again.
Debug.DrawRay (laser.transform.position, ( target.position - laser.transform.position));
laser.SetPosition (0, transform.position);
laser.SetPosition (1, new Vector3(Random.Range(target.position.x,target.position.x + 100f),target.position.y,target.position.z));
//Did we hit the player??
checkForCollision (laser_ray);
//Wait for 1 second before running the laser script again and regenerating another random X location to fire the laser.
yield return new WaitForSeconds (1);
}
void checkForCollision(Ray arg_laserRay)
{
RaycastHit hit;
if (Physics.Raycast (arg_laserRay, out hit, 100F)) {
if (hit.rigidbody) {
Debug.Log ("We hit " + hit.collider.tag);
}
}
}
}
I am finding it really hard to implement CoRoutines and use them as required, As you can see I am looking to make the enemy fire at the player and then adjust the enemys fire trajectory otherwise the enemy would have an instant “lock-on” effect on the player.
If someone can point out where this is going wrong it would be muchly appreciated!
Example : Player comes too close to enemy, enemy then faces towards the player and starts firing every 1 second or a “variable” duration.
1st laser fire goes to the left of the player and misses.
2nd laser fire goes to the right of player and misses.
3rd one manages to hit the player.
Hope this gives enough infomration as to what im trying to do ! : )