Albert
Albert

Reputation: 41

Turret bullet follows the player

Currently, my turret bullet follows my player. How to stop it and make it only move forward of the last position of my player? Here is my code currently:

TurretBullet Class:

using UnityEngine;
using System.Collections;

public class TurretBullet : MonoBehaviour {
    private Transform target;
    public float speed = 70f;
    public void Seek(Transform _target) {
        target = _target;
    }

    void Update() {
        if (target == null) {
            Destroy(gameObject);
            return;
        }
        float distanceThisFrame = speed * Time.deltaTime;
        Vector3 dir = target.position - transform.position;


        if(dir.magnitude <= distanceThisFrame) {
            HitTarget();
            return;
        }

        transform.Translate(dir.normalized * distanceThisFrame, Space.World);
    }

    void HitTarget() {
        Debug.Log("Player Hit!");
        Destroy(gameObject);
    }
}

I saw somewhere that I need to use Vector3.forward I tried experimenting but I couldn't make it work. How do I properly implement it?

Turret Class:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Turret : MonoBehaviour {

    private Transform target;

    [Header("Attributes")]
    public float range = 15f;
    public float fireRate = 1f;
    private float fireCountdown = 0f;

    [Header("Unity Setup Fields")]
    string playerTag = "Player";

    public Transform partToRotate;

    public float turnSpeed = 10f;

    public GameObject bulletPrefab;
    public Transform firePoint;

    // Use this for initialization
    void Start () {
        InvokeRepeating("UpdateTarget", 0f, 0.5f);
    }

    void UpdateTarget() {
        GameObject[] players = GameObject.FindGameObjectsWithTag(playerTag);
        float shortestDistance = Mathf.Infinity;
        GameObject nearestPlayer = null;

        foreach(GameObject player in players) {
            float distanceToPlayer = Vector3.Distance(transform.position, player.transform.position);

            if(distanceToPlayer < shortestDistance) {
                shortestDistance = distanceToPlayer;
                nearestPlayer = player;
            }
            else {
                target = null;
            }
        }

        if(nearestPlayer != null && shortestDistance <= range) {
            target = nearestPlayer.transform;
        }
    }

    // Update is called once per frame
    void Update () {
        if(target == null)
            return;

        Vector3 dir = target.position - transform.position;
        Quaternion lookRotation = Quaternion.LookRotation(dir);
        Vector3 rotation = Quaternion.Lerp(partToRotate.rotation, lookRotation, Time.deltaTime * turnSpeed).eulerAngles;
        partToRotate.rotation = Quaternion.Euler(0f, rotation.y, 0f);


        if(fireCountdown <= 0f) {
            Shoot();
            fireCountdown = 1f / fireRate;
        }

        fireCountdown -= Time.deltaTime;
    }

    void Shoot() {
        GameObject bulletGO = (GameObject)Instantiate(bulletPrefab, firePoint.position, firePoint.rotation);
        TurretBullet bullet = bulletGO.GetComponent<TurretBullet>();

        if (bullet != null)
        bullet.Seek(target);
    }

    void OnDrawGizmosSelected() {
        Gizmos.color = Color.red;
        Gizmos.DrawWireSphere(transform.position, range);
    }
}

Upvotes: 0

Views: 141

Answers (2)

enkryptor
enkryptor

Reputation: 1673

The bullet follows the player because you compare the bullet position with the current player position every time:

Vector3 dir = target.position - transform.position;

Transform is a reference type, so your target field gets the same object instead of its copy.

You should copy the original position instead. To make a copy, assign target.position - Vector3 is struct, hence, is a value type:

private Vector3 position;

public void Seek(Transform _target)
{
    position = _target.position;
}

More info: Value Type and Reference Type

Upvotes: 1

Adrian Michalski
Adrian Michalski

Reputation: 31

Maybe something like that? TurretBullet Class:

private bool aimed = false;
public void Seek(Transform _target) {
if(!aimed){
    target = _target;
    aimed = true;
}

}

Upvotes: 0

Related Questions