Reputation: 41
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
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
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