- Home /
Enemy BulletSpread
Hey Im developing a top down rpg and am currently making an AI and I need to make the bullets spread like a shotgun. I've watched many tutorials but those only explain how to make this for the player, and it doesnt work for me. Sorry in advance about the comments if u cant understand them
This is where I have tried to make the bullet spread
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GolemFollowPlayer : MonoBehaviour
{
private float speed;
public float lineOfSite;
private Transform player;
public float shootingRange;
public GameObject bullet;
public GameObject bulletParent;
public float fireRate = 1f;
private float nextFireTime;
private bool right = true;
public Animator animator;
public Golem golem;
public int bulletCount;
public float spreadAngle;
List<Quaternion> bullets;
public float bulletSpeed;
void Awake()
{
bullets = new List<Quaternion>(bulletCount);
for (int i = 0; i < bulletCount; i++)
{
bullets.Add(Quaternion.Euler(Vector2.zero));
}
}
//Esta função é chamada logo que o script é ativado antes de qualquer função de update
void Start()
{
//Encontrar o player
player = GameObject.FindGameObjectWithTag("Player").transform;
}
//Esta função é executada em cada frame
void Update()
{
do
{
//Variável igual à distância entre o player e o inimigo
float distanceFromPlayer = Vector2.Distance(player.position, transform.position);
//Para o inimigo começar a andar a partir de uma certa distância com o player
if (distanceFromPlayer < lineOfSite && distanceFromPlayer > shootingRange)
{
//nova velocidade do inimigo
speed = 0.7f;
//Inimigo começa a andar em direção ao player
transform.position = Vector2.MoveTowards(this.transform.position,player.position,speed * Time.deltaTime);
}
//Para o inimigo parar e poder disparar a partir de uma certa distância com o player
else if(distanceFromPlayer <= shootingRange & nextFireTime < Time.time)
{
fire();
nextFireTime = Time.time + fireRate;
}
//Para que o inimigo não tenha nenhuma animação enquanto estiver a uma certa distância do player
else if(distanceFromPlayer > lineOfSite)
{
//nova velocidade do inimigo
speed = 0f;
}
//Para rodar o inimigo no eixo do y dependendo da posição do player e do inimigo
if(player.position.x > transform.position.x && !right)
{
flip();
}
else if (player.position.x < transform.position.x && right)
{
flip();
}
//Velocidade do inimigo é igual a um parâmetro da animação
animator.SetFloat("enemySpeed", speed);
}while (golem.golemHealth > 0);
}
//Função para desenhar as circunferências de detecção do inimigo
private void OnDrawGizmosSelected()
{
//Cor da circunferência
Gizmos.color = Color.green;
//Circunferência de detecção para começar a andar
Gizmos.DrawWireSphere(transform.position, lineOfSite);
//Circunferência de detecção para parar e disparar
Gizmos.DrawWireSphere(transform.position, shootingRange);
}
//Função para rodar no eixo do y
void flip()
{
//Igual ao seu contrário
right = !right;
//Rodar 180 graus no eixo do y
transform.Rotate(0f, 180f, 0f);
}
void fire()
{
for (int i = 0; i < bulletCount; i++)
{
float ang = i * spreadAngle * 3;
float random = Random.Range(1, 3);
GameObject p = Instantiate(bullet, bulletParent.transform.position, Quaternion.Euler(ang, ang, ang));
p.GetComponent<Rigidbody2D>().AddForce(bulletParent.transform.right * bulletSpeed, ForceMode2D.Impulse);
if(i > 0)
{
p.GetComponent<Rigidbody2D>().AddForce(p.transform.position * random);
}
}
}
}
This is my bullet script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GolemBullet : MonoBehaviour
{
//Declaração de variáveis
GameObject target;
public float speed;
Rigidbody2D bulletRB;
public Collider2D col2d;
public Animator animator;
//Esta função é chamada logo que o script é ativado antes de qualquer função de update
void Start()
{
//Inicializar o rigidbody da bala
bulletRB = GetComponent<Rigidbody2D>();
//Encontrar o alvo
target = GameObject.FindGameObjectWithTag("Player");
}
//Função de quando se entra em colisão
private void OnCollisionEnter2D(Collision2D collision2D)
{
//Ao entrar numa colisão com o player
if (collision2D.gameObject.tag == "Player")
{
//Dano ao player através de um evento
collision2D.gameObject.GetComponent<PlayerHealth>().TakeDamage(1);
//Destruir o collider
Destroy(col2d);
//Bool é true
animator.SetBool("onImpact", true);
//Destruir o rigidbody
Destroy(GetComponent<Rigidbody2D>());
//Destruir a bala com um delay de 0.3 segundos
this.Wait(0.3f, Delete);
}
//Ao entrar em colisão com a parede
if (collision2D.gameObject.tag == "Walls")
{
//Bool é true
animator.SetBool("onImpact", true);
//Destruir o rigidbody
Destroy(GetComponent<Rigidbody2D>());
//Destruir a bala com um delay de 0.3 segundos
this.Wait(0.3f, Delete);
}
}
//Função de destruir a bala
void Delete()
{
//Destruir a bala
Destroy(gameObject);
}
}
What do you mean by "it does not work for me"?
If you try something and fail doing it then please try to post why it fails. What did you do? What did you expect to happen? What happened instead?
Apart from that i see a whileloop in your Update function that does not exit until the health is < 0.
given this your game will freeze whenever golem.golemHealth is larger than 0.
I expected it to spread the bullets when the enemy shoots, and no matter what value I use on the spreadAngle it still shoots all the bullets in the same direction. About the whileloop, it was something I tried to use so that when the golem would get to 0 health or less and started its death animation, it would stop every action that he does
okay, sorry for the late reply and thx for the clarification.
So what you currently do is that you just add a sideways force based on the bullets position. So basically the further you get away from the central origin (0, 0, 0) the more spread you will have:
p.GetComponent<Rigidbody2D>().AddForce(p.transform.position * random);
What you want to do instead i guess would be the following:
p.GetComponent<Rigidbody2D>().AddForce(bulletParent.transform.up * random * bulletspeed * 0.05f);
So you get a sideaxis of your bulletspawn that is perpendicular to your shooting direction. (there is a 50:50 chance that i hit the wrong one and instead of up
it needs to be forward
- you'll figure that out)
I also added a factor of 5% of your bullet speed so that the change is at all noticable. I guess that your earlier version did apply a spread but it was just not visible.
You'll also notice that your current random number is between 1 and 3. So it will only ever spread in one direction. You might want to change that to an interval between -2 and 2 for example.
to make it simple what I want to fix is the function fire()
Your answer
Follow this Question
Related Questions
Why is my enemy stopping before it reaches the player? 1 Answer
Taking a hit 3 Answers
Spawning enemy mobs .......... Instantiate woe ? 2 Answers
Any one have an AI spaceship script 1 Answer