Search Unity

Space Shooter Tutorial Q&A

Discussion in 'Community Learning & Teaching' started by Adam-Buckner, Mar 26, 2015.

  1. TrickyV

    TrickyV

    Joined:
    Nov 19, 2013
    Posts:
    3
    Hi there!

    I began learning Unity, and by extension, C#, just two days ago.

    I have done some coding before, so I followed about 80% of the lesson, I'd say. I successfully reached the end of the lesson and produced the expanded game in a single day. Now I am attempting to fiddle around with the game in an attempt to learn more about C# by implementing my own ideas into the game.

    I decided to make the game start off very easy and ramp up in difficulty as the player survives waves. I decided to do this by counting waves, and using that wave count to increase the number of enemies spawned, as well as their speed and aggression.

    I have successfully added a wave counter to my game that counts up using a private int called "wave" and outputs the new number every wave. Each wave, this int adds to the previous value of "hazardCount" in order to add more enemies.

    Now I am stuck in regards to increasing speed and aggression. I am sure I have been given the tools to do this, I just am not mentally making the connections on how to proceed.

    I am thinking that each cycle of spawning enemies, I should call a function that will increase the "speed" value on all enemy "Mover" scripts, as well as increasing the "fireRate" and decreasing the "delay" on the enemy "Weapon Controller" scripts. How do I go about doing this? I'd think that each enemy spawn would have to use.... find? Since each enemy is just a copy of the prefab in our assets, we can't just update that number directly, right?
     
  2. Adam-Buckner

    Adam-Buckner

    Joined:
    Jun 27, 2007
    Posts:
    5,664
    When you spawn your hazards, you can get a reference to the object being spawned. iIRC, this is covered in the lesson. Use the reference to the spawned hazard to get the component you want on that hazard, and then push the values you need to that hazard.
     
  3. Cedrei

    Cedrei

    Joined:
    Nov 25, 2015
    Posts:
    2
    In the middle of the "Moving the player" section, I ran into this error in the PlayerController script:
    NullReferenceException: Object reference not set to an instance of an object PlayerController.FixedUpdate () (at Assets/Scripts/PlayerController.cs:18)

    I think I followed the video's script but with the 5.0 changes, although apparently I'm not.

    My code in PlayerController is:

    using UnityEngine;
    using System.Collections;

    public class Boundary {
    public float xMin, xMax, zMin, zMax;
    }

    public class PlayerController : MonoBehaviour {
    private Rigidbody rb;
    public float speed;
    public Boundary boundary;
    void FixedUpdate() {
    rb = GetComponent<Rigidbody>();
    float moveHorizontal = Input.GetAxis ("Horizontal");
    float moveVertical = Input.GetAxis ("Vertical");
    Vector3 movement = new Vector3 (moveHorizontal, 0.0f, moveVertical);
    rb.velocity = movement * speed;
    rb.position = new Vector3(Mathf.Clamp(rb.position.x, boundary.xMin, boundary.xMax), 0.0f, Mathf.Clamp(rb.position.z, boundary.zMin, boundary.zMax));
    }
    }
     
  4. OboShape

    OboShape

    Joined:
    Feb 17, 2014
    Posts:
    836
    Morning @Cedrei,

    Looks like the error is pointing to this line is it?
    Code (CSharp):
    1. rb.position = new Vector3(Mathf.Clamp(rb.position.x, boundary.xMin, boundary.xMax), 0.0f, Mathf.Clamp(rb.position.z, boundary.zMin, boundary.zMax));
    I cant tell exactly, but if you could, please use code tags when posting code, just makes it a whole lot easier to read and tell line numbers ;)

    Looks like you may have missed out the System.Serializable above the Boundary class declaration.
    pop it in and set your values up in the inspector, then try again.
    Code (CSharp):
    1. [System.Serializable]
    2. public class Boundary
    3. {
    4.     public float xMin, xMax, zMin, zMax;
    5. }
     
  5. Cedrei

    Cedrei

    Joined:
    Nov 25, 2015
    Posts:
    2
    Didn't realise how to use the tags until now... Oh well. The reason I hadn't those was that I hadn't came that far in the video, but I added those now. The error is gone now. Thanks!
     
  6. Deleted User

    Deleted User

    Guest

    Hello!
    I have a question about some code.
    When spawning random Asteroids type we have this code to chose Asteroid type

    Code (CSharp):
    1. GameObject hazard = hazards[Random.Range(0, hazards.Length)];
    I think we have here Index out of bounds sometimes, shouldn't we have instead, because Random.Range returns inclusive min and inclusive max:

    Code (CSharp):
    1. GameObject hazard = hazards[Random.Range(0, hazards.Length - 1)];
     
  7. TrickyV

    TrickyV

    Joined:
    Nov 19, 2013
    Posts:
    3
    I think I follow, and I think I am very close to achieving this goal. I'm running into a problem with syntax that I don't quite understand.

    Here is the snippet of code, with a few of the changes I have made.


    for (int i = 0; i < hazardCount; i++)
    {
    GameObject hazard = hazards[Random.Range (0,hazards.Length)];
    Vector3 spawnPosition = new Vector3(Random.Range(-spawnValues.x, spawnValues.x), spawnValues.y, spawnValues.z);
    Quaternion spawnRotation = Quaternion.identity;
    Instantiate(hazard, spawnPosition, spawnRotation);
    GameObject instance = (GameObject)hazard;
    Debug.Log (instance);
    instance.GetComponent(Mover).speed = wave;

    yield return new WaitForSeconds(spawnWait);
    }

    I have the wave variable incrementing already as an int in a different part of my script, and this code runs the debug log into my console, showing me that each time I spawn a hazard, it's temporarily stored in my "instance" variable. Yes, I know that having my wave count be my speed would make the hazards terribly slow and move in the wrong direction, but I'm just poking around and trying to get this to work.

    Now, by the accounts online, I should be using GetComponent to get Mover off of my instance, then adjust my speed attribute. I keep seeing different uses of this with either () or <> containing the component to be fetched. In this case, though, neither one works, as it produces glaring errors in my console claiming I can't use a type.

    What does this mean? I apologize in advance for asking such trivial questions!
     
  8. Adam-Buckner

    Adam-Buckner

    Joined:
    Jun 27, 2007
    Posts:
    5,664
    Are you actually getting these index out of bounds? Or are you imagining you should? That code will work as stated in the video lesson. (And it has worked for years now!) Don't forget that when dealing with int range, the last number is not included and that lists and arrays a zero based. The int range is designed for zero based lists and arrays, which is why that last number in not included.

    If you're getting out of bounds errors in random range, please give us more detail, as there is an implementation issue somewhere.
     
  9. Adam-Buckner

    Adam-Buckner

    Joined:
    Jun 27, 2007
    Posts:
    5,664
    Can you please learn to use code tag properly?
    http://forum.unity3d.com/threads/using-code-tags-properly.143875/
     
  10. Adam-Buckner

    Adam-Buckner

    Joined:
    Jun 27, 2007
    Posts:
    5,664
    This line is wrong:
    Code (CSharp):
    1. GameObject instance = (GameObject)hazard;
    It doesn't make any sense, actually. You are setting a new GameObject reference variable to the value of a temporary reference that is pointing to the prefab asset in your project window. The GameObject variable "hazard" is a reference to the prefab asset in your project that you want to copy/duplicate into the scene with instantiate function, not the newly instantiated GameObject.

    Don't guess. As I suggested earlier, follow where in the lesson we discuss this, or check out the documentation on the instantiate function in the scripting documentation:
    http://docs.unity3d.com/ScriptReference/Object.Instantiate.html

    This has an example of setting rigidbody velocity.
     
  11. Deleted User

    Deleted User

    Guest

    i thought :)
    On the website manual there is only Range(float min, float max); but in editor code completion there is also Range(int min, int max); and have max exclusive.

    Thanks, have a good day!
     
  12. Adam-Buckner

    Adam-Buckner

    Joined:
    Jun 27, 2007
    Posts:
    5,664
    If you look here:
    http://docs.unity3d.com/ScriptReference/Random.Range.html

    ... You'll see two signatures:
    public static float Range(float min, float max);
    public static int Range(int min, int max);

    The description of the int Range() is:

    Description
    Returns a random integer number between min [inclusive] and max [exclusive] (Read Only).
    If max equals min, min will be returned. The returned value will never be max unless min equals max.

    This is essentially just for lists and arrays, so you can say: Random.Range (0, list.length) and get a good zero based range.

    It is worth noting that float Random.Range is different and returns the full range requested.
     
    Deleted User likes this.
  13. TrickyV

    TrickyV

    Joined:
    Nov 19, 2013
    Posts:
    3
    I was able to do it! Thank you so much for helping me hrough this! It feels very empowering to manage to type the code out properly.
     
  14. Adam-Buckner

    Adam-Buckner

    Joined:
    Jun 27, 2007
    Posts:
    5,664
    Great!

    In the end it's pretty straight forward if you break things down into little tiny pieces. If there is anything you are not sure what it means, then find out! Each variable represents "something" - a number, a reference to an object, etc. Once you know what all the little pieces are, you can assemble great things.
     
  15. Deleted User

    Deleted User

    Guest

    Hi! I encountered a little problem at the end of Space Shooter to mobile!
    When I try to move and to fire at the same time something goes wrong.
    I described the problem in a video. What it can be?
    Thanks in advance!
     
  16. Adam-Buckner

    Adam-Buckner

    Joined:
    Jun 27, 2007
    Posts:
    5,664
    Try deploying to the device. If it works well on the device, but not on the remote it's a know issue with the remote and the UI. If his is true, we could use the data. Could you file a bug report, describe the issue in detail and make sure you state that this is an incompatibility between the UI and the Unity Remote when testing in the editor. If you can get me the bug number, that would be good.
     
  17. bluedragon2k9

    bluedragon2k9

    Joined:
    Dec 20, 2013
    Posts:
    1
    I am brand new to unity and trying to follow this space shooter tutorial and I have tried using the upgrade gudie but it has me all kind of confused.Can someone pls show me a completed Playercontroller script so i can see just what I am doing wrong.Thanks
     
  18. WhySoSeriousGuys

    WhySoSeriousGuys

    Joined:
    Oct 28, 2015
    Posts:
    18
    Here you can get all scripts from this project, just scroll down
    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. [System.Serializable]
    6. public class Done_Boundary
    7. {
    8. public float xMin, xMax, zMin, zMax;
    9. }
    10.  
    11. public class Done_PlayerController : MonoBehaviour
    12. {
    13. public float speed;
    14. public float tilt;
    15. public Done_Boundary boundary;
    16.  
    17. public GameObject shot;
    18. public Transform shotSpawn;
    19. public float fireRate;
    20.  
    21. private float nextFire;
    22.  
    23. void Update ()
    24. {
    25. if (Input.GetButton("Fire1") && Time.time > nextFire)
    26. {
    27. nextFire = Time.time + fireRate;
    28. Instantiate(shot, shotSpawn.position, shotSpawn.rotation);
    29. GetComponent<AudioSource>().Play ();
    30. }
    31. }
    32.  
    33. void FixedUpdate ()
    34. {
    35. float moveHorizontal = Input.GetAxis ("Horizontal");
    36. float moveVertical = Input.GetAxis ("Vertical");
    37.  
    38. Vector3 movement = new Vector3 (moveHorizontal, 0.0f, moveVertical);
    39. GetComponent<Rigidbody>().velocity = movement * speed;
    40.  
    41. GetComponent<Rigidbody>().position = new Vector3
    42. (
    43. Mathf.Clamp (GetComponent<Rigidbody>().position.x, boundary.xMin, boundary.xMax),
    44. 0.0f,
    45. Mathf.Clamp (GetComponent<Rigidbody>().position.z, boundary.zMin, boundary.zMax)
    46. );
    47.  
    48. GetComponent<Rigidbody>().rotation = Quaternion.Euler (0.0f, 0.0f, GetComponent<Rigidbody>().velocity.x * -tilt);
    49. }
    50. }


    @Topic
    I'm on my way to finishing this project the way I wanted, but I want to ask about one last thing (ok, 3 things xD).
    I would like to change that boring background texture into something more fancy. Maybe some actual 3d maps or something. Or maybe some maps generated in real time.
    Is it possible? Are there any tutorials that would work with this idea?
    If 3d maps are possible, is there a way to make them "infinite/endless" like we used to do with scrolling background texture

    And my second question. Is there a fast way to implement pause menu with volume settings? I've got a problem with AudioListener.volume. I've read that it's just the matter of setting this value, but it doesn't work for me :/

    Last question. Do you have any ideas what powerups should I make? I've got:
    -healing powerup
    -tripple-shot powerup
    -shield powerup
    -helper powerup (small "ship" joins to player and shots enemies for 10 seconds)
     
    Last edited: Nov 29, 2015
  19. OboShape

    OboShape

    Joined:
    Feb 17, 2014
    Posts:
    836
    Morning.

    I'm not at my pc as I'm at work, but... For the scrolling background have a look through the live training archive as Adam done a session on 2d scrolling backgrounds. For the pause menu check out Matt's game jam template I'm sure Tha implements the volume change within the pause menu.
    I cant help out just now with the powerups as I'm still offshore grafting away :)
     
  20. WhySoSeriousGuys

    WhySoSeriousGuys

    Joined:
    Oct 28, 2015
    Posts:
    18
    I have scrolling background (from Adam's extending guide), but I wanted something better :p
     
  21. CatherineHP

    CatherineHP

    Joined:
    Nov 29, 2015
    Posts:
    1
    I've been trying to follow the Space Shooter tutorial using the Unity 5.1 upgrade guide. I'm having trouble with the first script. This is what I have:

    using UnityEngine;
    using System.Collections;

    public class PlayerController : MonoBehaviour
    {

    private Rigidbody rb;

    void start()
    {
    rb = GetComponent<Rigidbody>();
    }
    void FixedUpdate()
    {
    float moveHorizontal = Input.GetAxis ("Horizontal");
    float moveVertical = Input.GetAxis ("Vertical");

    Vector3 movement = new Vector3(moveHorizontal, 0.0f, moveVertical);
    rb.velocity = movement;
    }

    }

    This compiles, but when I try to run the game Unity tells me that the last line (rb.velocity=movement) has this error:
    NullReferenceException: Object reference not set to an instance of an object
    PlayerController.FixedUpdate () (at Assets/Scripts/PlayerController.cs:19)


    Can anyone please help me figure out what is wrong? Unfortunately I'm on a deadline.
     
  22. Adam-Buckner

    Adam-Buckner

    Joined:
    Jun 27, 2007
    Posts:
    5,664
    Can you please use code tags when posting code.
     
  23. Adam-Buckner

    Adam-Buckner

    Joined:
    Jun 27, 2007
    Posts:
    5,664
    Start needs a Capital "S", as in "Start" not "start". You're getting a null ref as "start" will never get called.
     
  24. DougMan

    DougMan

    Joined:
    Nov 30, 2015
    Posts:
    3
    I greatly appreciated having this tutorial to work through. I helped me understand the basics of Unity programming.

    I extended my copy of the game to add player lives. I'm uploading my code here in case anyone else is interested. It involves changes to GameController, PlayerController and DestroyOnContact.

    I put //ADD at the end of each line that I had to add to implement players lives.

    The codes changes implement creating a public variable on the GameController ( so be sure to set it) for how many lives the player will have. There is variable provided to achieve extra lives every XX points called NewLifePointRange. When a player is destroyed by contact, the game will prevent firing bolts until the end of the wave and no further damage will occur until the wave is over, then everything is reset to start working again.

    I hope others will find these changes useful. My way of giving back for having the original to work on.

    Doug
     

    Attached Files:

  25. Adam-Buckner

    Adam-Buckner

    Joined:
    Jun 27, 2007
    Posts:
    5,664
    Can you post this code inline as well, using code tags? This makes it much easier to read.
    http://forum.unity3d.com/threads/using-code-tags-properly.143875/
     
  26. Adam-Buckner

    Adam-Buckner

    Joined:
    Jun 27, 2007
    Posts:
    5,664
    I did briefly but not in-depth scan over the scripts, and I have a couple of comments.

    DestroyByContact will be present and attached to every hazard object, so this is probably not the best place to store player lives. Try moving all of this code to the GameController. This makes more sense. The GameController can handle everything related to the score and lives of the player.

    You could put a new text field in the upper center of the screen with lives, so you don't have to concatenate the string for score with scoreText.text = "(" + lifeCount + ") Score: " + score; . You could update them in the same function, but with a line of it's own. To be really clever, try adding mini ship icons.

    Instead of stopping the guns from firing, try "destroying" the player ship and "creating" a new one at the end of the wave. Now, don't actually destroy it, but make it invisible: Instantiate the player explosion like normal, but call a public function on the PlayerController that turns the renderer for the ship off, resets the player's position to origin and also removes the ability to move the ship. You'll probably need a dead or disabled boolean on the player that gets set to true and you check this before allowing any movement. At the beginning of the next wave, in the GameController check to see if the player is dead or disabled, and if so, call another public function on the player to show the player by turning the renderer back on. If you really want to be clever, instantiate another VFX element (just like was done with the explosion on destruction, but different in look and feel) that is the ship respawning.

    If you scroll back, we had a discussion with @Yeoli_Livunts and @johnleonard who did something similar with destroying player ships. You can take a look at that discussion and see if it helps you here.
     
  27. DougMan

    DougMan

    Joined:
    Nov 30, 2015
    Posts:
    3
    Adam, thanks for your comments. I'll see what I can pull off. I admit that I got lazy going back through the many prior pages, so I can zero on in the two you suggested.

    One additional caveat to anyone that just drops my files in without looking (always a bad idea) I forgot to mention that I also added a shotExpense to the PlayerController which I forgot to comment with //ADD. I played with the points to get a good balance on what should constitute enough for a new life and ended up with asteroids score 100, enemy ships 500 and made each shot cost 1 point to try to dissuade just keeping the fire button down.

    Thanks again for your comments.

    Doug
     
  28. DougMan

    DougMan

    Joined:
    Nov 30, 2015
    Posts:
    3
    Here is my attempt at using code tags to paste the code in line that I uploaded a few posts ago...

    PlayerController.cs
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. [System.Serializable]
    5. public class Boundary
    6. {
    7.     public float xMin, xMax, zMin, zMax;
    8.  
    9. }
    10.  
    11. public class PlayerController : MonoBehaviour {
    12.  
    13.     public float speed;
    14.     public float tilt;
    15.     public Boundary boundary;
    16.     public GameObject shot;
    17.     public Transform shotSpawn;
    18.  
    19.     public float fireRate;
    20.     private float nextFire;
    21.     public int shotExpense; //ADD
    22.     private GameController gameController; //ADD
    23.  
    24.     void Start()
    25.     {
    26.         GameObject gameControllerObject = GameObject.FindWithTag("GameController");
    27.         if (gameControllerObject != null)
    28.         {
    29.             gameController = gameControllerObject.GetComponent<GameController>();
    30.         }
    31.         if (gameController == null)
    32.         {
    33.             Debug.Log("Cannot find 'GameController' script.");
    34.         }
    35.     }
    36.  
    37.     void Update()
    38.     {
    39.         if (Input.GetButton("Fire1") && Time.time > nextFire && gameController.playerHit==false) //ADD stop firing when player hit until next wave
    40.         {
    41.             nextFire = Time.time + fireRate;
    42.             Instantiate(shot, shotSpawn.position, shotSpawn.rotation);
    43.             AudioSource audio = GetComponent<AudioSource>();
    44.             audio.Play();
    45.             gameController.AddScore(shotExpense);   //ADD I have my set to cost 1 point per shot
    46.  
    47.         }
    48.  
    49.     }
    50.  
    51.     void FixedUpdate ()
    52.     {
    53.         float moveHorizontal = Input.GetAxis("Horizontal");
    54.         float moveVeritcal = Input.GetAxis("Vertical");
    55.  
    56.         Rigidbody rb = GetComponent<Rigidbody>();
    57.         Vector3 movement = new Vector3(moveHorizontal, 0.0f, moveVeritcal);
    58.  
    59.         rb.velocity = movement * speed;
    60.  
    61.         rb.position = new Vector3(
    62.             Mathf.Clamp(rb.position.x, boundary.xMin, boundary.xMax),
    63.             0.0f,
    64.             Mathf.Clamp(rb.position.z, boundary.zMin, boundary.zMax)
    65.             );
    66.         rb.rotation = Quaternion.Euler(0.0f, 0.0f, rb.velocity.x*-tilt);
    67.     }
    68. }
    69.  
    GameController.cs
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class GameController : MonoBehaviour {
    5.  
    6.     public GameObject[] hazards;
    7.     public int hazardCount;
    8.     public Vector3 spawnValues;
    9.     public float startWait;
    10.     public float spawnWait;
    11.     public float waveWait;
    12.     public GUIText scoreText;
    13.     public GUIText restartText;
    14.     public GUIText gameOverText;
    15.  
    16.     public int lifeCount; //ADD
    17.     public int newLifePointRange;//ADD
    18.     public bool playerHit;//ADD
    19.  
    20.     private int lastNewLifeRange;//ADD
    21.  
    22.     private int score;
    23.     private bool gameOver;
    24.     private bool restart;
    25.    
    26.  
    27.     void Start()
    28.     {
    29.         gameOver = false;
    30.         restart = false;
    31.         restartText.text = "";
    32.         gameOverText.text = "";
    33.  
    34.         lastNewLifeRange = 0; //ADD start counter at zero to determine when next new life available
    35.         playerHit = false;//ADD default status is NOT hit so everything behaves normally, when HIT some things will be disabled till end of wave
    36.  
    37.         score = 0;
    38.         UpdateScore();
    39.         StartCoroutine(SpawnWaves());
    40.     }
    41.  
    42.     void Update()
    43.     {
    44.         if (restart)
    45.         {
    46.             if (Input.GetKeyDown(KeyCode.R))
    47.             {
    48.                 Application.LoadLevel(Application.loadedLevel);
    49.             }
    50.         }
    51.     }
    52.  
    53.     public void AddScore(int newScoreValue)
    54.     {
    55.         score += newScoreValue;;
    56.         if ((score - lastNewLifeRange) > newLifePointRange)//ADD
    57.         {                                                       //ADD
    58.             lastNewLifeRange =  score - (score % newLifePointRange) ; //ADD this will set the last new life to the last even newLifePointRange
    59.             lifeCount++;                                        //ADD
    60.         }                                                       //ADD
    61.         UpdateScore();
    62.     }
    63.  
    64.     public void GameOver()
    65.     {
    66.         gameOverText.text = "Game Over!";
    67.         gameOver = true;
    68.  
    69.     }
    70.  
    71.     IEnumerator SpawnWaves()
    72.     {
    73.         yield return new WaitForSeconds(startWait);
    74.         while (true)
    75.         {
    76.             if (playerHit==true)//ADD
    77.             {                   //ADD
    78.                 playerHit = false; //turn off hit flag at beginning of new wave so everything starts working again
    79.             }                      //ADD
    80.  
    81.             for (int i = 0; i < hazardCount; i++)
    82.             {
    83.                 GameObject hazard = hazards[Random.Range(0,hazards.Length)];
    84.                 Vector3 spawnPosition = new Vector3(Random.Range(-spawnValues.x, spawnValues.x), spawnValues.y, spawnValues.z);
    85.                 Quaternion spawnRotation = Quaternion.identity;
    86.                 Instantiate(hazard, spawnPosition, spawnRotation);
    87.  
    88.                 yield return new WaitForSeconds(spawnWait);
    89.  
    90.             }
    91.             yield return new WaitForSeconds(waveWait);
    92.  
    93.             if (gameOver)
    94.             {
    95.                 restartText.text = "Press 'R' for Restart";
    96.                 restart = true;
    97.                 break;
    98.             }
    99.         }
    100.     }
    101.  
    102.     void UpdateScore()
    103.     {
    104.         if (score < 1)
    105.         {
    106.             score = 0;
    107.         }
    108.         scoreText.text = "(" + lifeCount + ") Score: " + score; //ADD show remaining lives in parentheses at beginning of text
    109.     }
    110.  
    111.     public int LooseLife() //ADD
    112.     {                               //ADD
    113.         lifeCount = lifeCount - 1;  //ADD
    114.         if (lifeCount < 1)          //ADD
    115.         {                           //ADD
    116.             lifeCount = 0;          //ADD to ensure does not go negative
    117.         }                           //ADD
    118.         UpdateScore();              //ADD show change to lives count
    119.  
    120.         playerHit = true;           //ADD
    121.         return lifeCount;           //ADD tell the calling routine how many lives remaining in case they need to perform logic
    122.     }                               //ADD
    123.  
    124. }
    125.  
    DestroyByContact.cs
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class DestroyByContact : MonoBehaviour {
    5.  
    6.     public GameObject explosion;
    7.     public GameObject playerExplosion;
    8.     public int scoreValue;
    9.     private GameController gameController;
    10.  
    11.     private int currentLives; //ADD will hold the current number of lives the player has
    12.  
    13.     void Start()
    14.     {
    15.         GameObject gameControllerObject = GameObject.FindWithTag("GameController");
    16.         if (gameControllerObject != null)
    17.         {
    18.             gameController = gameControllerObject.GetComponent<GameController>();
    19.         }
    20.         if (gameController == null)
    21.         {
    22.             Debug.Log("Cannot find 'GameController' script.");
    23.         }
    24.     }
    25.  
    26.     void OnTriggerEnter(Collider other)
    27.     {
    28.         if (gameController.playerHit == false)//ADD  stop collisions for remainder of wave since a life has already been lost when playerHit==true
    29.         {                                       //ADD
    30.  
    31.             if (other.CompareTag("Boundary") || other.CompareTag("Enemy"))
    32.             {
    33.                 return;
    34.             }
    35.  
    36.             if (explosion != null)
    37.             {
    38.                 Instantiate(explosion, transform.position, transform.rotation);
    39.             }
    40.  
    41.             if (other.CompareTag("Player"))
    42.             {
    43.                     Instantiate(playerExplosion, other.transform.position, other.transform.rotation);
    44.                     currentLives = gameController.LooseLife();//ADD
    45.                     if (currentLives < 1)                     //ADD game will be over when all lives lost
    46.                     {                                       //ADD
    47.                
    48.                         Destroy(other.gameObject);
    49.                         gameController.GameOver();
    50.                     }                                       //ADD
    51.             }
    52.            gameController.AddScore(scoreValue);
    53.            Destroy(gameObject);
    54.         }                                                   //ADD
    55.     }
    56. }
    57.  
    Doug
     
  29. Adam-Buckner

    Adam-Buckner

    Joined:
    Jun 27, 2007
    Posts:
    5,664
    Now that I can read the code, I have a couple more shotgun comments. In DestroyByContact you don't need if (gameController.playerHit == false) as a block. There is already the test: if (other.CompareTag("Boundary") || other.CompareTag("Enemy")) and you just need to add to this with: if (other.CompareTag("Boundary") || other.CompareTag("Enemy" || gameController.playerHit == false)). This is because with the empty return; used in this way in a Unity script, we are simply returning the control or flow of logic back to Unity. Unity called the OnTriggerEnter, and we are just returning nothing and handing the control back. Note that this is not false as we are indicating when we don't want to execute the following code, rather than when we do.

    In PlayerController this code is optional:
    Code (CSharp):
    1.  
    2.     void Start()
    3.     {
    4.         GameObject gameControllerObject = GameObject.FindWithTag("GameController");
    5.         if (gameControllerObject != null)
    6.         {
    7.             gameController = gameControllerObject.GetComponent<GameController>();
    8.         }
    9.         if (gameController == null)
    10.         {
    11.             Debug.Log("Cannot find 'GameController' script.");
    12.         }
    13.     }
    It will work just fine and there is not reason not to have it. Just for the sake of complete explanation: This is necessary in the hazards, as they are spawned from prefabs and cannot hold a reference to a scene object. The player, however, is in the scene, so for the player this could simply be another public variable that you drag to associate the reference in the editor.
     
  30. crouzilles

    crouzilles

    Joined:
    Nov 21, 2015
    Posts:
    25
    Hi,

    I have been able to follow everything so far, I have a player able to destroy waves of asteroid.

    The only problem I am getting is that when I use the arrow keys to move the ship, the ship seems to accelerate until it reaches its top speed and seems to decelerate to zero when I stop pressing the keys. This is annoying because it is hard to control and I keep hitting asteroids, my ability to anticipate isn't great I must say :)
    This acceleration and deceleration happens quickly, within 1 second either way of releasing the key(s), but it is enough to make it unplayable really.

    Does anyone have any idea as to why this would take place? I used Unity3d 5.2.2f1
    I am using the stock code as it is provided in the tutorials.

    Regards
    Crouz
     
  31. Adam-Buckner

    Adam-Buckner

    Joined:
    Jun 27, 2007
    Posts:
    5,664
    Take a look at the documentation and look at the difference between Input.GetAxis and Input.GetAxisRaw.
     
  32. crouzilles

    crouzilles

    Joined:
    Nov 21, 2015
    Posts:
    25
    Thanks for the answer. Is there a way to use Input.GetAxis and turn down the smoothing a little bit. GetAxisRaw is a little too raw for my liking.

    Regards
     
  33. Adam-Buckner

    Adam-Buckner

    Joined:
    Jun 27, 2007
    Posts:
    5,664
    As far as I know, Input.GetAxis is set internally. You could google around to try and prove me wrong, as I don't know this for sure, but my assumption is that this is not modifiable. The other solution is that you roll your own smooth damping on the value. Look in the scripting manual for things like Lerp, MoveTowards, SmoothDamp, etc., as these can all be used in some form to take a value and smoothly change it to another value.
     
  34. crouzilles

    crouzilles

    Joined:
    Nov 21, 2015
    Posts:
    25
    Thanks for you time replying Adam, I may attempt this at some point.

    Regards
    Crouz
     
  35. crouzilles

    crouzilles

    Joined:
    Nov 21, 2015
    Posts:
    25
    Hi all,

    Does anyone know of good tutorials, paid or free, where I could learn how to achieve similar particle effects used in the space shooter? I really don't mind paying for good tutorials, so don't be shy :p

    Regards
    Crouz
     
  36. Adam-Buckner

    Adam-Buckner

    Joined:
    Jun 27, 2007
    Posts:
    5,664
    First, I'd just open up the particle systems From Space Shooter in a new empty project and see how they are constructed. Have the manual open to the particle system page so if you are unclear what a setting does, you can check. Then, I'd start changing out things like the sprite graphics, changing the values on the properties and seeing his it affects the system when you play it. You may find that thus is enough to make your own.
     
  37. Pragyansh_ThriDeeGamer

    Pragyansh_ThriDeeGamer

    Joined:
    Dec 2, 2015
    Posts:
    2
    2015-12-02 (2).png 2015-12-02 (3).png 2015-12-02 (1).png hey I hv a problem
    plz see this
    I think the script is fine
    my tag is Boundary tagged only on Boundary
    both the bolt and asteroid capsule colliders are set to is trigger
    both the spaceship and the asteroid are at same level
    my asteroid is rotating fine.
    but whenever I change the Boundary tag to Bounds in both unity and script, the bolts never destroy by Boundary.
     

    Attached Files:

  38. crouzilles

    crouzilles

    Joined:
    Nov 21, 2015
    Posts:
    25
    Why would you change the tag to Bounds, and when you do so, do you change the code to reflect the tag change?
     
  39. GameBlaster

    GameBlaster

    Joined:
    Nov 14, 2015
    Posts:
    11
    Well my game was going good tell I got up to the EvasiveManeuver Script I changed the Z orientation to = X and the X to =Y in my game, but I am not sure what I want to change because it just wants to spawn in the middle of the screen and stay in a straight line and spawn many enemy ships on top of each other.... please help remember my game is scrolling lift to right in a 2d orthographic mode.
     

    Attached Files:

    Last edited: Dec 3, 2015
  40. Adam-Buckner

    Adam-Buckner

    Joined:
    Jun 27, 2007
    Posts:
    5,664
    The evasive maneuver script is designed to work in a top down game on the x-z plane. You will have to reconstruct this to work in a side scrolling game along the x-y plane. When I discuss the script, I also try to discuss how it works and why. Review this section and try to translate this into a new orientation by taking these notes into account.
     
    GameBlaster likes this.
  41. oferlip

    oferlip

    Joined:
    Dec 6, 2015
    Posts:
    3
    I have a problem with create shot. i did everything acording to the video and the shot doesn't move forward.
    it is stuck.

    this is my code:
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class Mover : MonoBehaviour {
    5.     private Rigidbody rb;
    6.     public float speed;
    7.  
    8.     void start()
    9.     {
    10.         rb = GetComponent<Rigidbody>();
    11.         rb.velocity = transform.forward * speed;
    12.     }
    13. }
    the use gravity and is kinematic are not marked.
    i saw the video twice and deleted everything and did agein.
    i dont know why the bolt doesn't move.

    evey time that i create the script "move" , it say that there is warning about the endings of the code, and the unity ask me if I want to change everything to one OS.
    i press yes to windows.
     
  42. Adam-Buckner

    Adam-Buckner

    Joined:
    Jun 27, 2007
    Posts:
    5,664
    The line endings warning is just a warning, not an error. It is a standard warning, but unity can use mixed line endings.

    Do you have:
    • Any errors in the console?
    • The script attached to the GameObject?
    • A value for speed, one that is not 0, in the speed property in the inspector?
     
  43. oferlip

    oferlip

    Joined:
    Dec 6, 2015
    Posts:
    3
    1.no errors in console when i press play
    2. the script is attached to the GameObject- when i mark the gravity, the bolt falls down
    3.the speed value is set to 20.

    and still the bolt doesn't move
     
  44. Adam-Buckner

    Adam-Buckner

    Joined:
    Jun 27, 2007
    Posts:
    5,664
    FWIW: The "use gravity" property is on the rigidbody component, not the Mover script component, so that is not relevant to the mover script. If you have a working mover script, and use gravity in the rigidbody, the bolt will move forward due to the mover script, and fall down due to gravity.

    But - missed the fact that your "start" function should be "Start" with a capital "S". C# is case sensitive.
     
  45. spromise2007

    spromise2007

    Joined:
    Dec 6, 2015
    Posts:
    21
    I hope this is the proper place to post this question.

    I'm trying to modify Space Shooter to be able to be controlled by the mouse. Basically i want the ship to follow the mouse around. At first i tried turning on the mouse in the Input settings. However, even with the clamping to try to force it to stay in bounds, it would sometimes escape and get destroyed by Boundary's On Exit trigger. So i tried writing the code below. i found the ScreenToWorldPoint code while searching the forums to see if this question had already been answered. Below is the code from the PlayerController script. This almost works. But the ship is jittery and doesn't always follow the mouse. It will keep going past the x position if you stop moving the mouse instead of stopping when it gets aligned with it, or at least jittering back and forth near the aligned x position as you might expect because of the movement * speed code. Any help or hints would be greatly appreciated.


    Thank you,

    Sean

    Code (CSharp):
    1.     void FixedUpdate(){
    2.         float moveHorizontal = Input.GetAxis ("Horizontal");
    3.         float moveVertical = Input.GetAxis ("Vertical");
    4.          
    5.         targetPosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
    6.         targetPosition.z -= 5; // Compensate for Main Camera shift in order to keep player position at origin even though it's nearer
    7.                                 // the bottom of the screen.
    8.         if (targetPosition.z > rb.position.z) {
    9.             moveVertical=1;
    10.         }
    11.         if (targetPosition.z < rb.position.z) {
    12.             moveVertical=-1;
    13.         }
    14.         if (targetPosition.x > rb.position.z) {
    15.             moveHorizontal = 1;
    16.         }
    17.         if (targetPosition.x < rb.position.z) {
    18.             moveHorizontal = -1;
    19.         }
    20.  
    21.         Vector3 movement = new Vector3 (moveHorizontal, 0.0f, moveVertical);
    22.         rb.velocity = movement * speed;
    23.  
    24.         rb.position = new Vector3
    25.         (
    26.             Mathf.Clamp (rb.position.x, boundary.xMin, boundary.xMax),
    27.             0.0f,
    28.             Mathf.Clamp (rb.position.z, boundary.zMin, boundary.zMax)
    29.         );
    30.         rb.rotation = Quaternion.Euler (0.0f, 0.0f, rb.velocity.x * -tilt);
    31.     }
     
  46. spromise2007

    spromise2007

    Joined:
    Dec 6, 2015
    Posts:
    21
    I am doing the audio part of the tutorial and got ahead of the video. i attached the ship's firing sound to bolt, figuring that would was the best place. I played it and it works fine. is there a reason to attach it to the player instead? The only reason that i can think of is that if you're near the top of the screen, the audio might get destroyed by the boundary or an asteroid before it finishes playing.

    Thank you,
    Sean
     
  47. Adam-Buckner

    Adam-Buckner

    Joined:
    Jun 27, 2007
    Posts:
    5,664
    If I remember correctly, when dealing with rigid body position, you were giving the rigidbody an inherent velocity. The code that we have used in the original tutorial is not meant for following the mouse around. If you are changing the game to follow the mast around, you may also have to change the way that you move the ship. Look into transform translate or Transform position.
     
  48. Adam-Buckner

    Adam-Buckner

    Joined:
    Jun 27, 2007
    Posts:
    5,664
    There are a few reasons for attaching the audio source to the player ship. The first one is that the sound should come from the location that is creating the sound, which to me is the gun port on the ship. I could imagine attaching another audio source to the bolt, which is the sound of the bolt travelling away from the ship. Imagine a real gun where there is the explosive sound of the gunshot and then there is the whistle that follows the bullet as it travels. It would be the same for an arrow being shot from the bow. There would be the twang of the string at the bow, and the whistle from the feathers of the arrow as it travelled. So all of this put together leaves me to say that the audio source should be on the player's ship because the player's ship has the gun's muzzle.

    Another reason is that we are not using any 3-D sound in the game, so there's no reason to hear the sound of are going away from the player. This means the audio source could be anywhere in the game, so why not on the player?

    Lastly, we can conserve resources by having one single audio source on the player. If we had one on the bolt, it would have to instantiate a new component with each bolt, which will get destroyed when the bolt is described, she we might as well simply attach on the player.
     
  49. spromise2007

    spromise2007

    Joined:
    Dec 6, 2015
    Posts:
    21

    Thanks for the explanation. I had just assumed that since 3D sound was turned off that the source didn't matter. However, i see your point. Having the sound come from the source makes more sense, especially looking forward to future game ideas. I can see that repeated instantiation and destruction would also add to garbage collection. Is that a consideration that i should be aware of regarding Unity and C#?

    One problem that i see arising is that you need to limit the firing speed to allow the sound to finish before allowing another shot to be fired. You wouldn't want the previous shot sound to be cut off and replaced by a new one. For this game i don't think that's a problem. For games with faster firing it might come up. I can see an easy solution would to be to create a small array of associated sound sources that you cycle through instead of just the one used in this case. Would that be the proper approach? i'm planning ahead for future games.

    BTW, i am totally new to Unity. I'm good with C++ and VB, so the C# seems pretty straightforward. The last time i had anything to do with games was a DOS based Bust-a-Move clone and a couple of online adventure games for BBSs. Recently, i've been playing around with HTML5 a bit and saw it as a way to write multi-platform games and apps. i didn't want to write my own game engine and started searching. i came across Unity and at first dismissed it as too complex and beyond the scope of what i wanted to do. A while later i was talking to the developers of a game that i bought and found out they used Unity. They encouraged me to look again and here i am. i'm very surprised at how easy it is to do some very sophisticated tasks. The ease of dealing with 3D rendered objects, collision detection, etc... like that in Space Shooter is amazing. i can see that i have a lot to learn, but tutorials like yours are a lot of help.

    Thank you,
    Sean Price
     
  50. spromise2007

    spromise2007

    Joined:
    Dec 6, 2015
    Posts:
    21
    I'm looking into those now. Thanks for the tip. i understand the jitteriness now. i think it has to do with the velocity routine being set by movement * speed and updating it too fast.

    Thank you,
    Sean