My fire system is EXACTLY like your code and… the fire still on the ship .
Welcome to the community, @Antonio_Durao
You have posted the coroutine and that looks fine, so maybe the problem is elsewhere. Can you post the whole Shooter
class?
Also, check this post on how to format code instead of screenshots: How to apply code formatting within your post
Hello and THANKS for the rapid intervention. Here it is
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Shooter : MonoBehaviour
{
[SerializeField] GameObject projectilePrefab; // Para instanciar o Prefab no local que queremos
[SerializeField] float projectileSpeed = 10f; // A clássica velocidade
[SerializeField] float projectileLifeTime = 2f; // Quanto tempo dura em cena
[SerializeField] float firingRate = 0.2f; // O tempo entre disparos para a COROTINA
public bool isFiring; // Para saber se estamos ou não a disparar.
// AGORA PARA O INIMIGO USAMOS O MESMO SCRIPT MAS METEMOS Esta variável
[SerializeField] bool useIA;
Coroutine firingCoroutine;
// A LOGICA DO FIRE.
// Vamos iniciar e parar a corotina dentro do UPDATE.
// Se o nosso PlayerScript diz-nos que estamos a disparar, então é aqui que
// temos também que INICIAL a coRotina caso contrário temos que a parar
void Start()
{
// Para diferenciar o fogo da nava ou do inimigo basta criar a variável useIA e agora
// no Start fazer uma simples coisa
if (useIA)
{
isFiring = true; // E ativa sempre o script sem intervenção nossa
}
}
void Update()
{
Fire(); // Chamada SEMPRE E SEMPRE em cada FRAME e chamo aqui a COROTINA
}
void Fire() // É aqui que temos que parar a Corotina
{
if(isFiring && firingCoroutine == null) // Se não a iniciarmos não a podemos parar
{
firingCoroutine = StartCoroutine(FireContinuosly()); // Se não estiver ativa, liga-a
}
else if(!isFiring && firingCoroutine != null) // Caso contrário PARAR
{
StopCoroutine(firingCoroutine);
// Mesmo depois de a parar tenho que dizer que é NULL pois a lógica é isso mesmo.
firingCoroutine = null;
}
}
IEnumerator FireContinuosly()
{
// Criar o loop infinito
while(true)
{
GameObject instance = Instantiate(projectilePrefab,
transform.position,
Quaternion.identity); // Sem rotação esta última
// Como o projeto tem um RigidBody associado vamos dar-lhe velocidade.
// Vamos armazenar numa variável temporária
Rigidbody2D rb = instance.GetComponent<Rigidbody2D>();
// 2ª checkagem. Se não for diferente de NULL
if(rb != null)
{
rb.velocity = transform.up * projectileSpeed;
}
Destroy(instance, projectileLifeTime);
yield return new WaitForSeconds(firingRate);
}
}
}
This also looks fine. The shooting is triggered by the Player
. Can you show what’s happening in the Player.cs
?
Thanks Of course. Here it is:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
public class Player : MonoBehaviour
{
public float moveSpeed = 5f;
Vector2 rawInput;
// Para o Viewport
Vector2 minBounds; // Below Left
Vector2 maxBounds; // Top right
[SerializeField] float paddingLeft;
[SerializeField] float paddingRight;
[SerializeField] float paddingTop;
[SerializeField] float paddingBottom;
Shooter shooter; // Para ter acesso ao ficheiro Shooter.CS
void Awake()
{
shooter = GetComponent<Shooter>(); // Para ir buscar logo o componente.
}
void Start()
{
InitBounds(); // Para quando iniciar ele definir logo os limites
}
// Update is called once per frame
void Update()
{
Move();
}
void Move()
{
Vector2 delta = rawInput * moveSpeed * Time.deltaTime;
Vector2 newPos = new Vector2(); // Será para a nova posição. Um novo Vector
// Calculo das novas posições
// CLAMP
newPos.x = Mathf.Clamp(transform.position.x + delta.x, minBounds.x + paddingLeft, maxBounds.x - paddingRight);
newPos.y = Mathf.Clamp(transform.position.y + delta.y, minBounds.y + paddingBottom, maxBounds.y - paddingTop);
// Atualização da posição final (x,y)
transform.position = newPos;
}
// O Unity vai reconhecer esta função OnMove e precisamos de um valor de INPUT para que ele o processe
// Basicamente fazer o que faziamos mas agora de forma um pouco mais profissional :-)
// Vai detetar as teclas automaticamente. A função só é chamada quando carregarmos nas teclas.
// Se carregarmos sempre ele faz, naturalmente, o movimento contínuo.
void OnMove(InputValue value)
{
rawInput = value.Get<Vector2>();
Debug.Log(rawInput);
}
void OnFire(InputValue value) // Porque no input actions metemos o tipo como value
{
// Verificamos se temos acesso ao script do Shooter de uma maneira simples
if(shooter != null) // Se encontrámos o ficheiro.
{
shooter.isFiring = value.isPressed;
}
}
// Vamos então tratar do Viewport.
void InitBounds()
{
// Inicializar os valores que a nossa câmara tem
Camera mainCamera = Camera.main;
minBounds = mainCamera.ViewportToWorldPoint(new Vector2(0,0));
maxBounds = mainCamera.ViewportToWorldPoint(new Vector2(1,1));
}
}
Hi Sorry, I was away from my laptop for a while.
I don’t see anything very wrong with the code. In the inspector, can you check on the shooter component if isFiring
is checked? It shouldn’t be. In fact, the code in the repo has [HideInInspector]
so that you can’t set it there.
If that’s all good, can you put a debug log inside
if(shooter != null) // Se encontrámos o ficheiro.
{
Debug.Log($"OnFire: {value.isPressed}");
shooter.isFiring = value.isPressed;
}
this will let us see what we get from the input system
No problem I’ll test and tell you if worked.
So… The logic is WORKING but the laser don’t go UP. Stays on the side of the ship, and the clone is destroyed normally.
Can u send me all the code so i can test in another unity instance? This is very strange.
Thanks
António
The code is here in the repository: GameDev.tv / Complete Unity 2D 2021 / Laser Defender · GitLab
Rigidbody2D rb = instance.GetComponent<Rigidbody2D>();
if (rb != null)
{
rb.velocity = transform.up * projectileSpeed;
}
This is the code that makes the projectile move. Does your laser have a Rigidbody2D
, and if it does, is it on the root of the prefab?
AHHH!!!MY GOD!!
It was that the "error. No it wasn’t…
DAMN!
Sorry for the time i make you spend! My mistake.
It’s now working PERFECTLY.
António