Can you give provide feedback/insight on the gameplay of my game Portal Reign?

Controls Below: Thank you :slight_smile:
A - Left
W - Up
D - Right
S - Down
Space Bar Fire/Shoot
URL: To play the game.
https://www.dmmsdi.com/prweb/index.html

Hi Martin,

Feedback as requested;

  • Title UI

    • The green writing on the yellow of the planet makes it quite difficult to read. You could consider using TextMeshPro instead of the standard Text UI which would enable you to add an outline/shadowing or something to just make it stand out a little more.
    • The title doesn’t appear in your current build (Edge or Chrome)
  • Progress/loading bar

    • It’s a little arbitrary - it’s not actually displaying the progress of the game loading - I’d opt to remove this until you are in a position to add it and have it report the progress of the game load
  • Music

    • There’s some odds things happening with this. I often get a delay before any music plays. In testing I can start the browser, browse to your game, let it start, not press anything and I hear no audio. I press space, the audio begins. If I F5 the page I will get random results, sometimes it starts when the planet appears, other times when the game starts, other times only when I press a key.
  • Enemies

    • First two enemies look better moving in and over the player
    • The ones before the purple ones just sit still and stop moving
  • Player Movement

    • Still not feeling that smooth flow, it speeds up, slows down, and stops, corners feel like they are an effort. When you’ve done a complete loop the player stops before the landing pad goes a little sides ways, and back and forth. If you’ve not killed one set of enemies before the last, they tend to collide into the player and destroy it and there isn’t anyway to shoot them at this point.
  • Player Death

    • When the player collides with an enemy ship, the particle effects are instantiated but the player ship is still visible, momentarily before the scene reloads.
  • Shooting

    • The angle of the player ship makes it very difficult to accurately hit enemies. I miss most every time I play because I cannot tell which direction they are going to head in.
    • After further testing I think I may have been hitting some of the enemies, but because of their health values, the shots bounce off and give the illusion of missing.
  • Landing

    • It’s a nice touch to land the player after the circuit, however, as you haven’t disabled the controls, it is possible for the player to move the ship down and crash, which then kicks off the level all over again.
    • As the player no longer gets looped around and just sits on the landing pad, you can see how the first two enemies do not actually move out of shot, they just stop above the player;
      image

Other things to consider adding;

  • Main menu

    • Start option as a minimum
    • You could consider Options to allow the player to set the volume levels for SFX and Music
    • Quit option, although redundant for a WebGL build to be fair
  • Player lives

    • Perhaps give the player three ships
    • When all of the player ships have been used, load a “Game Over” scene
      • This should have the ability to return to the Main Menu, and optionally Restart (which would load the first playable scene without going to the Main Menu)
      • Display the score the player obtained on the “Game Over” scene, it will give the player the sense of achievement, its easy to not see the score during the game at the moment.
  • Score

    • Allow the player to score points for destroying enemy ships
    • Display the score during the game, somewhere obvious to the player
  • Game Over

    • There is currently no concept of the end of the game, if you make it all the way around you do land, but then nothing happens. If this is going to be the trigger for the end of the level then I think you could add these;
      • disable the player controls just before they get to the landing pad, e.g. they can’t nose dive it into the landing page, assume some form of auto-pilot has taken control.
      • once the player ship has landed, end the level, that might be taking the player to a “Game Over - You Won” scene, or a subsequent level

I hope the above is of use and will keep you going for a few days :slight_smile:

I will look into this, it’s kind of difficult for me on my end the player flies fine. I know I have to close out the game with a win ending. Sometimes leaving Unity alone helps to focus better. A lot of these fixes are working on my end like allowing the player to score for destroying enemies. I starting think it may be real issues with your browsers I left using google for browsing purposes and analytics for a lot of reasons like the ones you are having. I will go to a library tomorrow and try the game from there I will get back to you. I like the idea of giving the player more ship choices that sound amazing to do.
Btw, what kind of Computer t do you own? Thank you I appreciate all your feedback. :slight_smile:

Rob, I really do not know where to start to fix the browser errors. After following your instructions when building the game in debug mode. I uploaded the zipped game to sharemygame.com. then I opened the game in web developers mode I seen all the errors you discussed. I don’t understand that you open the game and find all these errors. Why don’t I see them when I don’t use web developer mode? Do you notice these errors when playing the game just in the browser or when you choose web developer in the browser your using? and are all these errors playing like this in the browser without using web developer? This is how the game plays for me in any browser not in web developer mode in any browser and sharemygame.com I attached a video. Thank you for your feedback. :confused:

Hi Martin,

I did mention in our discussion last night that the errors I was seeing reported in Chrome disappeared after I had cleared the cache/temporary internet files. Is it these errors you are referring to?

The screenshot I provided of the error was just a modal pop-up that appears in the browser when there is an exception. In order to then view that in more detail I used the developer tools within the browser and viewed its console.

As mentioned above and as shown in the previous screenshot, I wasn’t using the developer tools until the error appeared.

As mentioned above and yesterday though, once the cache/temporary internet files were cleared, these errors went away.

The only issues/critique since then are listed above. :slight_smile:

Oh okay I just build it for mobile but there are no option for controls like on a PC can you guide where to set these option for controls ? if I attach the MobileControlRig script to the player will this give controls to android phones after building?

I’m assuming you want to create a kind of virtual joystick and perhaps fire button? If so take a look at this;

It’s a little old now, and talks about Unity 5 a few times, but you should get a good overview.

Rob, you are the best really I commend you :slight_smile:
I thought I leave that project alone and work on this here any insight to these minor errors is appreciated, Pal.

I’m working on adding a restart button an game over when the player shoots all the enemies I getting stuck with these to compiler errors I did some google searching on it but can use some insight. I provide a video to explain. Any feedback will be commended.:confused:

https://www.dmmsdi.com/images/Adobe%20Premiere%20Pro%20Auto-Save/compilererror.mp4

I fixed it. It was a typo error I needed to add Game to Object like so (GameObject) to this line public.

GameObject Other { get; private set; } I had it like so: other { get; private set; } . please view the video to see my results Unity can’t find (gameControlller.cs) I don’t know exactly where to attach this script to? to the player-rig, the play-ship, the enemy instance or every individual enemy. Thank you for responding :wink:

Hi Martin,

Are you using a FindObjectOfType<GameController> approach to find your GameController.cs script?

I note that you have a GameObject named “Game Controller” but then you have the GameController.cs script on an enemy?

If your GameController.cs script is something which is managing the game, it shouldn’t need to be on every object. It may need references to things in the game but only select things I would imagine, such as the score text and so on.

Well done on resolving your error also.

Hi Rob,
This is the error I receive: I will try to fix with your suggestions :slight_smile:

NullReferenceException: Object reference not set to an instance of an object

Enemy.KillEnemy () (at Assets/Scripts/Enemy.cs:57)

Enemy.OnParticleCollision (UnityEngine.GameObject other) (at Assets/Scripts/Enemy.cs:46)

…without seeing the code too there isn’t much I can help you with that, I would only be repeating what these errors are already stating. :slight_smile:

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;
    

    ScoreBoard scoreBoard;
    private GameController gameController;

    public GameObject Other { get; private set; }

    void Start()
    {
        GameObject gameControllerObject = GameObject.FindWithTag("GameController");
        if (gameControllerObject != null)
        {
            gameController = gameControllerObject.GetComponent<GameController>();
        }
        if (gameController == null)
        {
            Debug.Log("Cannot find 'GameController' script");
        }
        AddBoxCollider();
        scoreBoard = FindObjectOfType<ScoreBoard>();
    }

    private void AddBoxCollider()
    {
        Collider boxCollider = gameObject.AddComponent<BoxCollider>();
        boxCollider.isTrigger = false;
    }

    void OnParticleCollision(GameObject other)
    {
        ProcessHit();
        if (hits <= 1)
        {
            KillEnemy();
        }
    }
    private void ProcessHit()
    {
        scoreBoard.ScoreHit(scorePerHit);
        hits = hits - 1;
        // todo consider hit FX
    }
    void KillEnemy()
    {
        if (Other.tag == "Boundary")
        {
            return;
        }
        GameObject fx = Instantiate(deathFX, transform.position, Quaternion.identity);
        fx.transform.parent = parent;
        if (Other.tag == "Enemy")
        {
            Instantiate(deathFX, transform.position, Quaternion.identity);
            fx.transform.parent = parent;
            gameController.GameOver();
        }
        gameController.AddScore(scorePerHit);
        Destroy(Other.gameObject);
        Destroy(gameObject);
    }

}
using UnityEngine;
using UnityEngine.UI;
using System.Collections;

public class GameController : MonoBehaviour
{
    public GameObject hazard;
    public Vector3 spawnValues;
    public int hazardCount;
    public float spawnWait;
    public float startWait;
    public float waveWait;

    public Text scoreText;
    public Text restartText;
    public Text gameOverText;

    private bool gameOver;
    private bool restart;
    private int score;

    void Start()
    {
        gameOver = false;
        restart = false;
        restartText.text = "";
        gameOverText.text = "";
        score = 0;
        UpdateScore();
        StartCoroutine(SpawnWaves());
    }

    void Update()
    {
        if (restart)
        {
            if (Input.GetKeyDown(KeyCode.R))
            {
                Invoke("LoadFirstScene", 2f);
            }
        }
    }

    IEnumerator SpawnWaves()
    {
        yield return new WaitForSeconds(startWait);
        while (true)
        {
            for (int i = 0; i < hazardCount; i++)
            {
                Vector3 spawnPosition = new Vector3(Random.Range(-spawnValues.x, spawnValues.x), spawnValues.y, spawnValues.z);
                Quaternion spawnRotation = Quaternion.identity;
                Instantiate(hazard, spawnPosition, spawnRotation);
                yield return new WaitForSeconds(spawnWait);
            }
            yield return new WaitForSeconds(waveWait);

            if (gameOver)
            {
                restartText.text = "Press 'R' for Restart";
                restart = true;
                break;
            }
        }
    }

    public void AddScore(int newScoreValue)
    {
        score += newScoreValue;
        UpdateScore();
    }

    void UpdateScore()
    {
        scoreText.text = "Score: " + score;
    }

    public void GameOver()
    {
        gameOverText.text = "Game Over!";
        gameOver = true;
    }
}

The error relates to the Other variable/property. You declare it as public in this line;

public GameObject Other { get; private set; }

You are seeing the error message because it is null, e.g. it doesn’t have a reference to anything, you then try to access a member of it, in this case the tag property.

I think you may be mixing up this with the other parameter of the OnParticleCollision method, e.g.

void OnParticleCollision(GameObject other)  // <-- this "other" is not the same as the "Other" 
{
    ProcessHit();
    if (hits <= 1)
    {
        KillEnemy();
    }
}

Are you trying to determine what has made the collision by checking it’s tag?

Yes, I that’s what I’m trying to do I will uppercase that other and get back to you. :wink:

I still get this error:

NullReferenceException: Object reference not set to an instance of an object
Enemy.KillEnemy () (at Assets/Scripts/Enemy.cs:57)
Enemy.OnParticleCollision (UnityEngine.GameObject other) (at Assets/Scripts/Enemy.cs:46)

This is the line the error is referring to:

  if (Other.tag == "Boundary")

The problem isn’t the case, its the use of the variable…

The one you have declared at the top of your script is never used, it will always be null.

Just to check, is there a reason you are checking the tag of the thing that has collided with it? What is the use case scenario here?

For example, the OnParticleCollision is only going to be invoked if a particle has hit the collider, which this script is attached to, e.g. your enemy. As such, what is “boundary” in this scenario?

What is the check for that you are trying to perform? Also, why in KillEnemy are you then testing to see if the tag of the GameObject that made the collision was an enemy? Are you trying to detect if enemies have shot enemies? If so, why go to a Game Over? I’m a bit confused as to what you are trying to achieve here. Can you outline the objective please.

I’m trying to detect I the player has shot all the enemies which then the game will be over. Should I change this back to the player like so?

GameObject fx = Instantiate(deathFX, transform.position, Quaternion.identity);
fx.transform.parent = parent;
if (Other.tag == “Player”)
{
This is the set of instructions I’m following here: remember very new at this and a light programmer in c# :confused:

If that is the only thing you are trying to do then that should really be being handled by your GameController class.

Your GameController would need to have a concept of knowing how many enemies there are in the level for the player to destroy.

When you destroy an enemy, that needs to be reported back to the GameController so that it can reduce the count of enemies that remain. As a part of that logic, it should check to see if that was the last enemy that just got destroyed, if so, load the “Game Over” scene.

I’m still unclear as to what the “boundary” check is in your KillEnemy method?

I think you also have the score being set twice too, once in ProcessHit and then again in KillEnemy.

You are doing fine and making good progress, keep going :slight_smile:

Thank you that’s exactly what I trying to do. We have been at this all day I will take a breather and leave you to your work other responsibilities. I will get back to you a little later okay. Thank you, Pal :slight_smile:

1 Like