Enemy Shooting

Yes, in the class I took with Ben and Rick in Udemy they made the game controller the logic of the player. the only difference of my game and Aragon Assault is the look and feel most of the code comes from their instructions. So should I assign the game controller to the player ship? I provided a screenshot after I added the game controller to the player ship and this is the warnings I got.

1 Like

I’ve just checked the messages. I definitely fixed the issue with the GameController and the NullReferenceException for you. Not sure about the clones. Do you still have that repo? If so, you could check what I did and compare it to the current state of your project.

If you can guide to remove this multiple spawn player objects correctly I would appreciate your help and guidance.

Where do you instantiate the new player?

How can I fix this or how can I remove these clones correctly

In my opinion, the question should rather be: How can I prevent my code from instantiating the clones? Everything else would have a negative impact on the performance of your game. Since you have a 3D game with a terrain, complex meshes, animations and stuff, you should keep an eye on the consumption of resources. However, that’s just my opinion.

If all you want to do is to destroy the instantiated clones, you could implement Ben’s and Rick’s “singleton” solution. Are you also enroled in the 2D course? If so, you probably remember the GameSession class in Block Breaker. If not, you could read the code in Awake and adapt it in your Player class.

Only share the relevant code, please. You have clones, so something must have instantiated them. Look for the Instantiate class in your classes. The EnemyManagement rotates an object. That does not have anything to do with the player or its clones. The same goes for your Projectiles class unless you inadvertently assigned the player prefab to projectile.

If the player object can get destroyed by the enemies, it’s not a good idea to assign a crucial script, that is not supposed to get destroyed along with the player, to it.

1 Like

Honestly, I didn’t start that course/game (Block Breaker) yet. I have to say I believe the game always had clones because the code is mostly the same. I will try and adapt the awake code in the player class as you advise. I removed the game controller from attached to the player ship since it already in the hierarchy. I provided a video for results after I applied the new awake method below. Is it correct?
When I run the game the enemy object that shoots back dies without me shooting it and the playerShip object doesn’t die by enemy bullets. I also added the Projectiles.cs to the enemyShip object and removed it from the playerShip Object now there are no clones for the playerShip. Are we making progress?

I no longer get the error for this:

NullReferenceException: Object reference not set to an instance of an object
PlayerController.OnPlayerDeath () (at Assets/Scripts/PlayerController.cs:48)
UnityEngine.Component:SendMessage(String)
CollisionHandler:StartDeathSequence() (at Assets/Scripts/CollisionHandler.cs:27)
CollisionHandler:OnTriggerEnter(Collider) (at Assets/Scripts/CollisionHandler.cs:16)

Is this how I should write the awake method to destroy the instantiated clones?

 private void Awake()
    {
        int gameStatusCount = FindObjectsOfType<PlayerController>().Length;
        if (gameStatusCount > 1)
        {
            gameObject.SetActive(false);
            Destroy(gameObject);
        }
        else
        {
            DontDestroyOnLoad(gameObject);
        }
        Debug.Log(Time.frameCount + " | " + GetInstanceID() + ": GameController was added to: " + gameObject.name, gameObject);  
} 
1 Like

It probably shot itself. If I remember correctly, I solved that issue by assigning your enemy and your player to different layers and made the layers interact with one another but not with themselves in the collision matrix. Have you ever pulled the commit I made to your Git project?

Is this how I should write the awake method to destroy the instantiated clones?

That’s right. Just the else part is not needed because you do not have multiple levels. The ship does not need to be persistent.


See also:

1 Like

I have been working on the enemy bullets look and feel to look longer could this be the issue why it shoots itself. Because this happened earlier to me when I tried fixing the size of the enemy bullets I may just need to adjust them correct? I will take a look over the * Unity Manual: Layer-based collision detection after I go and come back from physical therapy for my back. Nina, Thank you

1 Like

Hi Nina, I can’t seem to create new layers as the link instructs I gave you a video so you see what I talking about. How can I add new layers for the game objects?https://community.gamedev.tv/uploads/short-url/kWg3Mn3vzKnjSZHxn8o1UD0nXH1.mp4

1 Like

I don’t have sound right now but you could use these layers (8 - 11). Just names into the empty fields.

image

1 Like

Hi Nina, I added both the EnemyShip and the PlayerShip to layer 8 but the EnemyShip still doesn’t kill the PlayerShip.


1 Like

First of all, give the layers meaningful names, e.g. “Enemy” and “Player”.

Secondly, the current settings in your collision matrix makes layer8 interact with layer8, layer9 with layer9 and layer10 with layer10. This means that layer8 will not interact with layer9 and layer10, and so on. Set the ticks correctly, and the collision should hopefully work as intended.

1 Like

I just changed the layer names to enemy and player without the ship at the end but still no reaction from the enemy projectiles shooting at the playership object. I also, check the enemy projectiles they are tagged to the player I provided a screenshot.


1 Like

You want to make the Enemy and the Player layer interact with one another. For this reason, you have to tick off the box where I put the red X:

image

1 Like

Hi Nina, I just made the changes but the enemy ship still doesn’t kill the player ship object I provided a video with the changes made.

1 Like
  1. The enemy ship does seem to have its collider enabled.
  2. Check with a Debug.Log whether the OnParticleCollision method gets called. Before you have not ensured that the method gets called, you don’t have to worry about any destructions. No method call, no destruction.
  3. Assign the correct tag to the game object with the particle system, too.
  4. Screenshots are sufficient because I don’t have sound anyway.
1 Like

Hi, Nina, results for the OnParticleCollision . I also assigned Player tag to the particles system.

   void OnParticleCollision(GameObject other)
     
    {
        ProcessHit();
        if (hits <= 1 && gameObject.activeSelf)
        {
            KillEnemy();
        }
       Debug.Log("Particle Collision!");
    }

1 Like

According to your console, the OnParticleCollision method was called. This means that there is either a problem with ProcessHit, the if-condition or KillEnemy. Add more Debug.Logs to narrow down the issue a bit further.

1 Like

Nina, these debug are in the enemy.cs shouldn’t we test projectiles.cs since it’s not shooting and killing the player ship because the player ship object can kill the enemy ship object it the enemy ship object that can’t kill the player ship object? the results are below for the kill method and process hit.

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

public class Enemy: MonoBehaviour
{

    [SerializeField] GameObject deathFX;
    [SerializeField] Transform parent;
    [SerializeField] int scorePerHit = 100;
    [SerializeField] int hits = 6;


    private GameController gameController;

    void Start()

    {
        AddBoxCollider();
        gameController = FindObjectOfType<GameController>();
    }
    private void AddBoxCollider()
    {
        Collider boxCollider = gameObject.AddComponent<BoxCollider>();
        boxCollider.isTrigger = false;
    }
    void OnParticleCollision(GameObject other)
     
    {
        ProcessHit();
        if (hits <= 1 && gameObject.activeSelf)
        {
            KillEnemy();
        }
       Debug.Log("Particle Collision!");
    }
    private void ProcessHit()
    {
        gameController.AddScore(scorePerHit);
        hits = hits - 1;
        // todo consider hit FX
    
        Debug.Log("Process Hit!");
    }

    private void KillEnemy()
    {
        GameObject fx = Instantiate(deathFX, transform.position, Quaternion.identity);
        fx.transform.parent = parent;

        gameObject.SetActive(false);

        gameController.DecreaseEnemyCount();

        Destroy(gameObject);

        Debug.Log("Killed Player!");
    }
}

I added a debug to the projectiles in the shooting method. results below screenshot.

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

public class Projectiles : MonoBehaviour
{
    public Transform playerShip;
    public float range = 20.0f;
    public float enemyGunImpulse = 10.0f;
    bool onRange = false;
    public Rigidbody projectile;
    

   void Start()
    {
        float rand = Random.Range(1.0f, 2.0f);
        InvokeRepeating("Shoot", 2, rand);
      
    }
    void Shoot()
    {

        if (onRange)
        {

            Rigidbody enemyGun = (Rigidbody)Instantiate(projectile, transform.position + transform.forward, transform.rotation);
            enemyGun.AddForce(transform.forward * enemyGunImpulse, ForceMode.Impulse);
        }
        Debug.Log("Shoot Player!");
    }

    void Update()
    {
        onRange = Vector3.Distance(transform.position, playerShip.position) < range;

        if (onRange)
            transform.LookAt(playerShip);
    }
}

1 Like

Generally, test everything what you think makes sense. You don’t have to ask for my permission. You know your project better than I, so my suggestions are not necessarily the best.

Why are you posting your Enemy if you think that the problem could be in the Player class? If the Player is supposed to get hit, start at its OnParticleCollision method. Does it get called?

1 Like

Hi Nina, I debugged what I felt needed to be tested these are the results.
Screenshot%20(170)

1 Like

And what do the messages tell me who does not know where they are? Which of them is the one that is generated by the OnParticleCollision method of the Player instance? Did you spell-check the method name?

Is the collider of the Player a trigger?

Bear in mind that I’m not going to debug your game. You have to do that. I can help you a bit but you’ll have to do the work. What did you learn from the messages in your console?

1 Like

Okay, Nina, I don’t know how to debug them.I looked it up online and that’s all I see how to debug the methods you ask me too. I will try looking for how to do this correctly. This below is how I debugged it. Is this correct?

Enemy.cs

  void OnParticleCollision(GameObject other)
     
    {
        ProcessHit();
        if (hits <= 1 && gameObject.activeSelf)
        {
            KillEnemy();
        }
        Debug.Log(GetInstanceID() + ": OnParticleCollision() called.");
        Debug.Log("Particle Collision!");

    }
    private void ProcessHit()
    {
        gameController.AddScore(scorePerHit);
        hits = hits - 1;
        // todo consider hit FX

        Debug.Log(GetInstanceID() + ": ProcessHit() called.");
        Debug.Log("Process Hit!");
    }

    private void KillEnemy()
    {
        GameObject fx = Instantiate(deathFX, transform.position, Quaternion.identity);
        fx.transform.parent = parent;

        gameObject.SetActive(false);

        gameController.DecreaseEnemyCount();

        Destroy(gameObject);

        Debug.Log(GetInstanceID() + ": KillEnemy() called.");
        Debug.Log("Killed Enemy!");
    }

Projectiles.cs

 void Shoot()
    {

        if (onRange)
        {

            Rigidbody enemyGun = (Rigidbody)Instantiate(projectile, transform.position + transform.forward, transform.rotation);
            enemyGun.AddForce(transform.forward * enemyGunImpulse, ForceMode.Impulse);
        }

        Debug.Log(GetInstanceID() + ": Shoot() called.");
        Debug.Log("Shoot Player!");
    }

This was the results:

1 Like

Privacy & Terms