Shoot a Bullet in player direction Unity - c#

I'm trying to shot a bullet in player direction but the bullet is instatiated but dont leave the initial position, not sure why, heres the code:
using UnityEngine;
using System.Collections;
public class AtackPlayer : MonoBehaviour {
public string playerTag = "Player";
public AnimationClip startAtack;
public AnimationClip endAtack;
public float atackInterval = 2f;
public GameObject enemyBullet;
public float bulletSpeed = 20f;
private Animator _anim;
private Transform _transform;
// Use this for initialization
void Start () {
_anim = GetComponentInParent<Animator>();
_transform = GetComponent<Transform>();
}
private IEnumerator Atack(Vector2 playerPosition)
{
_anim.Play(startAtack.name);
yield return new WaitForSeconds(startAtack.length); // executa o clipe e ataca
GameObject thisBullet = Instantiate(enemyBullet, _transform.position, Quaternion.identity) as GameObject; //instancia o bullet prefab
thisBullet.transform.position = Vector2.Lerp(thisBullet.transform.position, playerPosition, bulletSpeed * Time.deltaTime);
_anim.Play(endAtack.name);
yield return new WaitForSeconds(endAtack.length); // executa o clipe de finalização do ataque
yield return new WaitForSeconds(atackInterval); // executa o clipe de finalização do ataque
}
// Update is called once per frame
void Update () {
}
void OnTriggerEnter2D(Collider2D player)
{
if (player.gameObject.tag == playerTag)
{
Vector2 playerPos = player.transform.position;
StartCoroutine(Atack(playerPos));
}
}
}
The bullet prefab have a rigidbody2d and a circle collider, also sprite renderer and a animator to handle its animation.
Any help?

thisBullet.transform.position = Vector2.Lerp(thisBullet.transform.position, playerPosition, bulletSpeed * Time.deltaTime);
t = bulletSpeed * Time.deltaTime
When t = 0 returns a. When t = 1 returns b. When t = 0.5 returns the point midway between a and b.
In your game probably t has a value very close to 0. It means your
bullet's position stays almost the same position. Also you need a
loop in Atack function to make bullet has the same position with
bullet.
while (thisBullet.transform.position != playerPosition)
{
thisBullet.transform.position = Vector2.Lerp(thisBullet.transform.position, playerPosition, bulletSpeed * Time.deltaTime);
yield return new WaitForSeconds(0.1f);
}
You can set while condition here however you want for your game. In this code it move to player's position every 0.1f.

Related

In Unity player movement speed is not being added to the first bullet fired

I'm trying to make a 2D top-down shooter in Unity. I want it so when the you hold down the left mouse button the player fires a series of bullets until you run out of ammo. The player's movement speed is slowed while firing and the players movement speed should be added to the bullet's movement speed. For some reason the players movement speed is only applied to the bullets AFTER the first bullet is fired. The first bullet always seems to keep the slightly faster 'sprint' movement speed.
Weapon script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Weapon : MonoBehaviour
{
private GameObject bulletPrefab;
private Transform firePoint;
private PlayerControls player;
public float fireForce = 10f;
private bool cooldown = false;
private int bullets;
public int bulletDamage;
public int maxAmmo;
public float fireRate = 0.5f;
public float reloadRate = 2.5f;
public bool noAmmo = false;
public float walkSpeed = 2f;
private float timeSinceLastShot = 0f;
void Update()
{
// increase time since last shot
timeSinceLastShot += Time.deltaTime;
// if left-click is held down
if (Input.GetMouseButton(0))
{
// if enough time has passed since last shot
if (timeSinceLastShot >= fireRate && noAmmo == false)
{
player.moveSpeed = walkSpeed;
bullets -= 1;
cooldown = true;
if (bullets <= 0)
{
noAmmo = true;
player.moveSpeed = player.baseSpeed;
}
// instantiate a bullet
GameObject bullet = Instantiate(bulletPrefab, firePoint.transform.position, Quaternion.identity);
bullet.GetComponent<Bullet>().bulletDamage = bulletDamage;
// add player movement speed to bullet's speed
bullet.GetComponent<Rigidbody2D>().velocity = player.GetComponent<Rigidbody2D>().velocity;
bullet.GetComponent<Rigidbody2D>().AddForce(transform.up * fireForce, ForceMode2D.Impulse);
// reset time since last shot
timeSinceLastShot = 0f;
}
}
// if left-click is not held down
else
{
cooldown = false;
// restore player movement speed
player.moveSpeed = player.baseSpeed;
}
}
public void FillMag()
{
bullets = maxAmmo;
noAmmo = false;
}
}
PlayerControls:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerControls : MonoBehaviour
{
public float moveSpeed = 5f;
public float baseSpeed = 5f;
public int health;
public Weapon weapon;
private Rigidbody2D rb;
Vector2 mousePosition;
Vector2 moveDirection;
public float walkSpeed = 2f;
void Update()
{
float moveX = Input.GetAxisRaw("Horizontal");
float moveY = Input.GetAxisRaw("Vertical");
moveDirection = new Vector2(moveX, moveY).normalized;
mousePosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
rb.velocity = new Vector2(moveDirection.x * moveSpeed, moveDirection.y * moveSpeed);
Vector2 aimDirection = mousePosition - rb.position;
float aimAngle = Mathf.Atan2(aimDirection.y, aimDirection.x) * Mathf.Rad2Deg - 90f;
rb.rotation = aimAngle;
}
}
The player is moving from left to right.
Player firing
According to Unity's lifecycle, inputs are only calculated just before the Update method is called, but physics are applied during the FixedUpdate method. Is this what is causing my problems? I've tried moving some calculations into FixedUpdate and LateUpdate but nothing seems to make any difference.
Any help is appreciated. I've been banging my head against this for a few days now. I'm an amature, so feel free to explain like I'm 5.
So there are 2 problems with your code:
if you are not holding down left mouse, but multiple click instead:
the else statement in the Update() will immediately set it player back to base speed, which is not really matter if you intent to holding your mouse.
There are 2 concurrent things happen
first, you set player moveSpeed in Weapon Update()
at the same time, you calculate player velocity in Player Update()
But it TAKES TIME for player to update velocity before you get it right to your weapon.
Therefore, I recommend you to use IEnumerator to delay the fire action.
public class Weapon : MonoBehaviour
{
void FixedUpdate()
{
// increase time since last shot
timeSinceLastShot += Time.deltaTime;
// if left-click is held down
if (Input.GetMouseButton(0))
{
// if enough time has passed since last shot
if (timeSinceLastShot >= fireRate && noAmmo == false)
{
//player.moveSpeed = walkSpeed;
StopAllCoroutines();
StartCoroutine(SetSpeed());
bullets -= 1;
cooldown = true;
if (bullets <= 0)
{
noAmmo = true;
player.moveSpeed = player.baseSpeed;
}
// instantiate a bullet
StartCoroutine(FireBulelt());
// reset time since last shot
timeSinceLastShot = 0f;
}
}
// if left-click is not held down
}
IEnumerator SetSpeed()
{
player.moveSpeed = walkSpeed;
yield return new WaitForSeconds(0.5f);
cooldown = false;
// restore player movement speed
player.moveSpeed = player.baseSpeed;
yield return null;
}
IEnumerator FireBulelt()
{
yield return new WaitForSeconds(0.05f);
GameObject bullet = Instantiate(bulletPrefab, player.transform.position, Quaternion.identity);
print(" player.GetComponent<Rigidbody2D>().velocit " + player.GetComponent<Rigidbody2D>().velocity);
// add player movement speed to bullet's speed
Rigidbody2D bulletRB = bullet.GetComponent<Rigidbody2D>();
print(" bulletRB.velocit " + bulletRB.velocity);
bulletRB.velocity = player.GetComponent<Rigidbody2D>().velocity;
print(" after bulletRB.velocit " + bulletRB.velocity);
bulletRB.AddForce(transform.up * fireForce, ForceMode2D.Impulse);
}
}
And you should add print() like I did to keep track of code behavior when you're debugging.

Destroy not destroying after delay

Hi I am currently learning from the book (Learning c# by developing games with unity 2021).
1.Right now in the game I have created a bullet object this object is supposed to be destroyed after being created.
2.But since I want to display it in the scene for a time I created a floating point to see how much time I can give. I applied these are parameters in the destroy utility function.
problem:-
1.Instead of destroying it after a certain time it deleted it entirely after it was created.
This is a problem the code I wrote to create the bullet is attached to my player.
2.It deletes the prefab in the starting of the game itself
Player action:-
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerBehavoiur : MonoBehaviour
{
//this is a bullet made and used
public GameObject Bullet;
//the speed with the bullet
public float BulletSpeed = 100f;
//checks if our player is shooting
private bool _isShooting;
//stores the desired distance to ground
public float distanceToGround = 0.1f;
//creates a reference variable of type layermask
public LayerMask GroundLayer;
//gets the collider stored in a variable that will be used to access it
private CapsuleCollider _col;
void Update()
{
/*MoveForward(_hInput1);
RotateUpWards(_vInput1);
*/
_isJumping |= Input.GetKeyDown(KeyCode.Space);
PrintIfJumping(_isJumping);
//this sets it to a method that checks if the key in the
//arguments pressed down on
IsFalling |= Input.GetKeyDown(KeyCode.G);
//scans for mouse input and sets the isShooting field to that value
//if that value is true or when the mouse is clicked then run the shoot method
//this is through prefabs which are are used
_isShooting |= Input.GetMouseButtonDown(0);
}
void PrintIfJumping(bool _isJumping)
{
if (_isJumping == true)
{
Debug.Log("Time to take a leap of faith!");
}
else
{
Debug.Log("Im on the ground this sucks!");
}
}
void Start()
{
_rb = GetComponent<Rigidbody>();
_rb.useGravity = true;
//sets isJumping to keycode.space which checks wether the key space is pressed
//gets the collider component and stores inside a variable for later use
_col = GetComponent<CapsuleCollider>();
}
void SetVerticalDirection()
{
_vInput1 = Input.GetAxis("Vertical") * MoveSpeed;
}
void SetHorizontalDirection()
{
_hInput1 = Input.GetAxis("Horizontal") * RotateSpeed;
}
public float MoveSpeed = 10f;
public float RotateSpeed = 75f;
public int hp = 0;
/// <summary>
/// stores a rigidbody component for a gameobject
/// </summary>
private Rigidbody _rb;
public float JumpVelocity = 5f;
private bool _isJumping;
private bool IsFalling;
public float FallVelocity;
/// <summary>
/// Start is called before the first frame update
/// </summary>
private float _hInput1;
private float _vInput1;
/// <summary>
/// Update is called once per frame
/// </summary>
/*public void MoveForward(float _vInput)
{
_vInput = Input.GetAxis("Vertical") * MoveSpeed;
this.transform.Translate()
}
public void RotateUpWards(float _hInput)
{
_hInput = Input.GetAxis("Horizontal") * RotateSpeed;
this.transform.Translate(Vector3.forward * _hInput * Time.deltaTime);
}
*/
void FixedUpdate()
{
SetVerticalDirection();
SetHorizontalDirection();
//makes the object move by horizontal input in the up direction
Vector3 rotation = Vector3.up * _hInput1;
/*this is the rotation of the game object
* moving up and then going at a fixed frame rate
*/
Quaternion angleRotation = Quaternion.Euler(rotation * Time.fixedDeltaTime);
//this takes vertical input and addes the position and makes it move forward
//the vertical input is the vertical axis whihc moves at a defined rate tht we can define
_rb.MovePosition(this.transform.position +
this.transform.forward * _vInput1 * Time.fixedDeltaTime);
/*the move rotation moves using the rigibody rotation times the
* horizontal input times and moves up and rotates at the rotate speed rate
*/
_rb.MoveRotation(_rb.rotation * angleRotation);
//performs a jump if object is in collision with ground and isJumping
if(IsGrounded() && _isJumping)
{
/*while(JumpVelocity > 0)
{
--JumpVelocity;
}
*/
_rb.AddForce(Vector3.up * JumpVelocity, ForceMode.Impulse);
}
Fall(IsFalling);
Shoot(_isShooting, Bullet);
}
private bool IsGrounded() {
//this defines the bottom of the capsule or the end
Vector3 capsuleBottom = new Vector3(_col.bounds.center.x, _col.bounds.min.y, _col.bounds.center.z);
//this checks if a object is touching start or bottom of a capsule and the raduis is distance to ground
//this sets the ground layer to the phy-system
bool grounded = Physics.CheckCapsule(_col.bounds.center, capsuleBottom, distanceToGround, GroundLayer, QueryTriggerInteraction.Ignore);
return grounded;
}
public void Fall(bool grounded)
{
bool Gpressed = Input.GetKeyDown(KeyCode.G);
Debug.Log("G is pressed");
Debug.LogFormat("The down direction is {0}", Vector3.down);
if (Gpressed ==true & grounded == false)
{
_rb.AddForce(Vector3.down * FallVelocity, ForceMode.Impulse);
}
else
{
Debug.Log("No falling allowed!");
}
}
public void Shoot(bool _isShooting,GameObject Bullet)
{
if (_isShooting == true)
{
//this is the instance of the prefab bullet which is created using the unity editor
//builds
GameObject newBullet = Instantiate(Bullet, this.transform.position + new Vector3(1, 0, 0), this.transform.rotation);
//create a new bullet rigidbody which captures the component rb
Rigidbody BulletRB = newBullet.GetComponent<Rigidbody>();
//set the velocity (speed x direction) basically
//so we want our bullet to go forward x a certian speed so...
BulletRB.velocity = this.transform.forward * BulletSpeed;
}
_isShooting = false;
}
/*Horizontal: ad
* Vertical: ws */
}
Its pretty long I know just read the shoot function and the stuff in update on shooting
So the bullet behaviour is:-
public class BulletBehaviour : MonoBehaviour
{
float OnScreenDelay = 3f;
void Start()
{
Destroy(this.gameObject,OnScreenDelay);
}
// Update is called once per frame
void Update()
{
}
public void Scale(float x, float y, float z)
{
this.transform.localScale = new Vector3(x, y, z);
}
}

Cannot convert type `UnityEngine.Rigidbody' to `ProjectileController' via a built-in conversion

This has been asked about 1 million times, yet I can't find a solution to my issue, rather to my annoyance.
Help is very much appreciated as I'm not sure whats going wrong and how to solve it any more.
Script 1:
public class Something : MonoBehaviour {
[SerializeField]
private Rigidbody cannonballInstance;
public ProjectileController projectile;
public Transform firePoint;
[SerializeField]
[Range(10f, 80f)]
private float angle = 45f;
private void Update()
{
if (Input.GetMouseButtonDown(0))
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hitInfo;
if (Physics.Raycast(ray, out hitInfo))
{
FireCannonAtPoint(hitInfo.point);
}
}
}
private void FireCannonAtPoint(Vector3 point)
{
var velocity = BallisticVelocity(point, angle);
Debug.Log("Firing at " + point + " velocity " + velocity);
ProjectileController newProjectile = Instantiate(cannonballInstance, transform.position, transform.rotation) as ProjectileController;
//cannonballInstance.transform.position = transform.position;
//cannonballInstance.velocity = velocity;
}
private Vector3 BallisticVelocity(Vector3 destination, float angle)
{
Vector3 dir = destination - transform.position; // get Target Direction
float height = dir.y; // get height difference
dir.y = 0; // retain only the horizontal difference
float dist = dir.magnitude; // get horizontal direction
float a = angle * Mathf.Deg2Rad; // Convert angle to radians
dir.y = dist * Mathf.Tan(a); // set dir to the elevation angle.
dist += height / Mathf.Tan(a); // Correction for small height differences
// Calculate the velocity magnitude
float velocity = Mathf.Sqrt(dist * Physics.gravity.magnitude / Mathf.Sin(2 * a));
return velocity * dir.normalized; // Return a normalized vector.
}
The following is called from the previos when instansiated, causes error is this due to the type i'm trying to create or what?
Script 2:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ProjectileController : MonoBehaviour {
public float speed;
private Vector3 oldVelocity;
private Rigidbody rigidbodyTemp;
private int bounceLimit = 3;
// Use this for initialization
void Start () {
rigidbodyTemp = GetComponent<Rigidbody>();
rigidbodyTemp.isKinematic = false;
rigidbodyTemp.freezeRotation = true;
rigidbodyTemp.detectCollisions = true;
}
// Update is called once per frame
void FixedUpdate () {
rigidbodyTemp.AddForce(transform.forward * speed);
oldVelocity = rigidbodyTemp.velocity;
}
private void OnCollisionEnter(Collision collision)
{
bounceLimit -= 1;
if (collision.gameObject.tag == "Bulllet") // Check if hit another bullet
{
Destroy(this.gameObject);
}
else if (collision.gameObject.tag == "Crate") // Check if a Crate has been hit, will hold power ups
{
Destroy(this.gameObject);
Destroy(collision.gameObject);
PickUUpBounce.isActive = true;
}
else if (collision.gameObject.tag == "Player") // Check if hit a player
{
Destroy(this.gameObject);
}
else if (collision.gameObject.tag == "Enemy") // Check if enemy is hit
{
Destroy(this.gameObject);
Destroy(collision.gameObject);
}
else if (bounceLimit == 0) // check if bounce limit is reached
{
Destroy(this.gameObject);
}
else // bounce
{
Vector3 reflectedVelocity;
Quaternion rotation;
ContactPoint contact = collision.contacts[0]; // stores contact point for reflected velocity
reflectedVelocity = Vector3.Reflect(oldVelocity, contact.normal); // reflected velocity equals a reflection of the old velocity around the contact point
rigidbodyTemp.velocity = reflectedVelocity; // Change rigidbody velocity
rotation = Quaternion.FromToRotation(oldVelocity, reflectedVelocity); // old directyion -> new direction
transform.rotation = rotation * transform.rotation; // front face always facing the front
}
}
}
The prefab (cannonballInstance) you are instantiating is declared as Rigidbody. When you call the Instantiate function and pass cannonballInstance to it, it will return a Rigidbody not ProjectileController.
ProjectileController is a script. You can't cast the returned Rigidbody to ProjectileController. You have to use GetComponent to retrieve the ProjectileController instance that is attached to your prefab(cannonballInstance) .
ProjectileController newProjectile = Instantiate(cannonballInstance, transform.position, transform.rotation).GetComponent<ProjectileController>();
It's better to break that line of code into pieces to make it easier to debug just in case anything is null.
Rigidbody rg = Instantiate(cannonballInstance, transform.position, transform.rotation);
ProjectileController newProjectile = rg.GetComponent<ProjectileController>();

Detect if enemy is facing Player

I am making a game in which if the distance is less than 2 and the enemy is facing the player, text comes up with a restart option. In the update there is an if and else statement which should detect if the enemy is behind or in front of the player. However, the in front option seems to be called once the distance is less than 2, regardless of if the player is facing the npc.
This script is attached to the Enemy:
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class EnemyFollow : MonoBehaviour {
Transform player;
Transform enemy;
public GameObject EnemyCaughtCam;
public Text SheCaughtYou;
public GameObject Restart;
public float Speed = 3f;
public float rotS = 3f;
public float sT = 3f;
NavMeshAgent nav;
float timeTillOptionsMenu = 3.0f;
// Use this for initialization
void Awake() {
player = GameObject.FindGameObjectWithTag ("MainCamera").transform;
//enemy = GameObject.FindGameObjectWithTag ("Enemy").transform;
nav = GetComponent<NavMeshAgent> ();
EnemyCaughtCam.SetActive(false);
SheCaughtYou.text = "";
}
// Update is called once per frame
void Update () {
nav.SetDestination (player.position);
DistanceDeath();
if (npcIsFacingPlayer (player)&& !playerIsFacingNpc(player))
print ("Behind");
else if (npcIsFacingPlayer (player)&& playerIsFacingNpc(player))
print ("In Front");
DistanceDeath ();
}
public void DistanceDeath(){
float distance = Vector3.Distance(player.transform.position,
transform.position);
if (distance < 2 ){
EnemyCaughtCam.SetActive(true);
SheCaughtYou.text = "SHE CAUGHT YOU!";
timeTillOptionsMenu -= Time.deltaTime;
if(timeTillOptionsMenu < 0)
{
Restart.SetActive(true);
}
}
}
public bool npcIsFacingPlayer(Transform other)
{
Vector3 toOther =
other.position - transform.position;
return (Vector3.Dot(toOther, transform.forward) > 0);
}
public bool playerIsFacingNpc(Transform other)
{
Vector3 toOther =
transform.position - other.position;
return (Vector3.Dot(toOther, other.forward) > 0);
}
}
First, you are missing some brackets, second there is an stra DistanceDeathcall, here is how your function Update is read:
// Update is called once per frame
void Update () {
nav.SetDestination (player.position);
/** what does the call do here? */
DistanceDeath();
if (npcIsFacingPlayer (player)&& !playerIsFacingNpc(player))
print ("Behind");
else if (npcIsFacingPlayer (player)&& playerIsFacingNpc(player))
print ("In Front");
/** are you missing brackets here? Distance Death is always called */
DistanceDeath ();
}

Unity 3D How to setup Turret Auto Aim? C#

what i't trying to achieve is have my turrent rotate and follow an "Enemy".
At the moment it detects the enemy but it is not rotating and I don't know why.
The bullet it a prefab i drag in, there has to be a better way to do this? Anyone have any suggestions please?
At the moment the bullet never triggers, but the log Shoot and does...and the rotate doesn't work.
Here is what i have
using UnityEngine;
using System.Collections;
public class TurretController : MonoBehaviour {
public Rigidbody bulletPrefab;
private Transform target;
private GameObject bullet;
private float nextFire;
private Quaternion targetPos;
void OnTriggerEnter(Collider otherCollider) {
if (otherCollider.CompareTag("Enemy"))
{
Debug.Log ("in");
target = otherCollider.transform;
StartCoroutine ("Fire");
}
}
void OnTriggerExit(Collider otherCollider) {
if (otherCollider.CompareTag("Enemy"))
{
Debug.Log ("out");
target = null;
StopCoroutine("Fire"); // aborts the currently running Fire() coroutine
}
}
IEnumerator Fire()
{
while (target != null)
{
nextFire = Time.time + 0.5f;
while (Time.time < nextFire)
{
// smooth the moving of the turret
targetPos = Quaternion.LookRotation (target.position);
transform.rotation = Quaternion.Slerp(transform.rotation, targetPos, Time.deltaTime * 5);
yield return new WaitForEndOfFrame();
}
// fire!
Debug.Log ("shoot");
bullet = Instantiate(bulletPrefab, transform.position, transform.rotation) as GameObject;
//bullet.rigidbody.velocity = transform.forward * bulletSpeed;
}
}
}
I tried to change the instantiate part by using this instead
bullet = (GameObject)Instantiate(bulletPrefab, transform.position, transform.rotation);
bullet.GetComponent<Bullet>().target = target.transform;
But then i just get errors like "InvalidCastException: Cannot cast from source type to destination type.
TurretController+c__Iterator0.MoveNext () (at Assets/Scripts/TurretController.cs:44)"
BTW, here's the turret rotation code I used in my project (shared with permission):
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class Turret : MonoBehaviour
{
[SerializeField]
private float turnRateRadians = 2 * Mathf.PI;
[SerializeField]
private Transform turretTop; // the gun part that rotates
[SerializeField]
private Transform bulletSpawnPoint;
private Enemy target;
void Update()
{
TargetEnemy();
}
void TargetEnemy()
{
if (target == null || target.health <= 0)
target = Enemy.GetClosestEnemy(turretTop, filter: enemy => enemy.health > 0);
if (target != null)
{
Vector3 targetDir = target.transform.position - transform.position;
// Rotating in 2D Plane...
targetDir.y = 0.0f;
targetDir = targetDir.normalized;
Vector3 currentDir = turretTop.forward;
currentDir = Vector3.RotateTowards(currentDir, targetDir, turnRateRadians*Time.deltaTime, 1.0f);
Quaternion qDir = new Quaternion();
qDir.SetLookRotation(currentDir, Vector3.up);
turretTop.rotation = qDir;
}
}
}
class Enemy : MonoBehaviour
{
public float health = 0;
private static HashSet<Enemy> allEnemies = new HashSet<Enemy>();
void Awake()
{
allEnemies.Add(this);
}
void OnDestroy()
{
allEnemies.Remove(this);
}
/// <summary>
/// Get the closest enemy to some transform, optionally filtering
/// (for example, enemies that aren't dead, or enemies of a certain type).
/// </summary>
public static Enemy GetClosestEnemy(Transform referenceTransform, System.Predicate<Enemy> filter=null)
{
// Left as an exercise for the reader.
// Remember not to use Vector3.Distance in a loop if you don't need it. ;-)
// return allEnemies[0];
}
}
First problem: the bullet prefab. The variable type is RigidBody. If you want to treat it as a game object, the variable must be a game object. Or you can instantiate it, cast to RigidBody, then use the .gameObject accessor. Like this:
((RigidBody)Instantiate(theRigidbody)).gameObject
Second problem: start simple with the rotation. If it's not working, don't get fancy yet. Start with something like this (an instant rotation toward the target):
Vector3 targetDirection = target.transform.position - transform.position;
targetDirection.y = 0; // optional: don't look up
transform.forward = targetDirection;
If it works, then add small pieces of additional complexity until it does exactly what you want. And if you don't get things figured out, give me a shout (a comment) on Monday. I've written turret-aiming code (including a maximum rotation speed), and I don't think my boss would mind if I upload it.

Categories