Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice

Question Fixing CS0039

Discussion in 'Scripting' started by YooOwnIt, Jul 5, 2020.

  1. YooOwnIt

    YooOwnIt

    Joined:
    Jul 3, 2020
    Posts:
    23
    I have an error CS0039, and I'm not sure how to fix it.
    It says, "cannot convert type 'Rocks' to 'UnityEngine.GameObject' via a reference conversion, boxing conversion, unboxing conversion, wrapping conversion, or null type conversion".
    I'm trying to respawn random sprites (Rocks) and have them move again after the first wave of sprites is destroyed. The line with the error is labeled below (RockSpawner.cs, line 71).
    Code (CSharp):
    1.  
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using System.Threading;
    5. using UnityEngine;
    6. /// <summary>
    7. /// A rock spawner
    8. /// </summary>
    9. public class RockSpawner : MonoBehaviour
    10. {
    11.     // needed for spawning
    12.     [SerializeField]
    13.     GameObject prefabRocks;
    14.     // saved for efficiency
    15.     [SerializeField]
    16.     Sprite greenrock0;
    17.     [SerializeField]
    18.     Sprite magentarock1;
    19.     [SerializeField]
    20.     Sprite whiterock2;
    21.     // spawn control
    22.     const float MinSpawnDelay = 1;
    23.     const float MaxSpawnDelay = 2;
    24.     Timer spawnTimer;
    25.     // spawn location support
    26.     const int SpawnBorderSize = 100;
    27.     int minSpawnX;
    28.     int maxSpawnX;
    29.     int minSpawnY;
    30.     int maxSpawnY;
    31.     /// <summary>
    32.     /// Use this for initialization
    33.     /// </summary>
    34.     void Start()
    35.     {
    36.         // save spawn boundaries for efficiency
    37.         minSpawnX = SpawnBorderSize;
    38.         maxSpawnX = Screen.width - SpawnBorderSize;
    39.         minSpawnY = SpawnBorderSize;
    40.         maxSpawnY = Screen.height - SpawnBorderSize;
    41.         // create and save timer
    42.         spawnTimer = gameObject.AddComponent<Timer>();
    43.         spawnTimer.Duration = Random.Range(MinSpawnDelay, MaxSpawnDelay);
    44.         spawnTimer.Run();
    45.     }
    46.     /// <summary>
    47.     /// Update is called once per frame
    48.     /// </summary>
    49.     void Update()
    50.     {
    51.         // check for time to spawn a new random rock
    52.         if (spawnTimer.Finished)
    53.         {
    54.             SpawnRock();   // change spawn timer duration and restart
    55.             spawnTimer.Duration = Random.Range(MinSpawnDelay, MaxSpawnDelay);
    56.             spawnTimer.Run();
    57.         }
    58.  
    59.     }
    60.     /// <summary>
    61.     /// spawns a new rock at a random location
    62.     /// </summary>
    63.  
    64.     public void SpawnRock()
    65.     {
    66.         // generate random location and create a new rock
    67.         Vector3 location = new Vector3(Random.Range(minSpawnX, maxSpawnX),
    68.         Random.Range(minSpawnY, maxSpawnY),
    69.         -Camera.main.transform.position.z);
    70.         Vector3 worldLocation = Camera.main.ScreenToWorldPoint(location);
    71.         GameObject Rock = Instantiate(new Rocks()) as GameObject; // error is here
    72.         Rock.transform.position = worldLocation;
    73.         // set random sprite for new rock
    74.         SpriteRenderer spriteRenderer = prefabRocks.GetComponent<SpriteRenderer>();
    75.         int SpriteNumber = Random.Range(0, 3);
    76.         if (SpriteNumber == 0)
    77.         {
    78.             spriteRenderer.sprite = greenrock0;
    79.         }
    80.         else if (SpriteNumber == 1)
    81.             spriteRenderer.sprite = magentarock1;
    82.         else
    83.         {
    84.             spriteRenderer.sprite = whiterock2;
    85.         }
    86.         Rock.SetActive(true);
    87.     }
    88.  
    89.  
    90. }
    Code (CSharp):
    1.  
    2. <summary>
    3. Rocks.cs
    4. </summary>
    5. using System.Collections;
    6. using System.Collections.Generic;
    7. using UnityEngine;
    8. using UnityEngine.VFX;
    9. public class Rocks : MonoBehaviour
    10. {
    11.     // death support
    12.  
    13.     //Timer deathTimer;
    14.     void Start()
    15.     {
    16.         /// <summary>
    17.         /// Use this for initialization
    18.         /// </summary>
    19.         // apply impulse force to get the object moving
    20.         const float MinImpulseForce = 2f;
    21.         const float MaxImpulseForce = 3f;
    22.         float angle = Random.Range(0, 2 * Mathf.PI);
    23.         Vector2 direction = new Vector2(
    24.             Mathf.Cos(angle), Mathf.Sin(angle));
    25.         float magnitude = Random.Range(MinImpulseForce, MaxImpulseForce);
    26.         GetComponent<Rigidbody2D>().AddForce(
    27.             direction * magnitude,
    28.             ForceMode2D.Impulse);
    29.         ///<summary>
    30.         ///Use this for initialization
    31.         ///</summary>
    32.         // create and start timer
    33.         //deathTimer = deathTimer = gameObject.AddComponent<Timer>();
    34.         //deathTimer.Duration = greenrocklifeseconds;
    35.         //deathTimer.Duration = magentarocklifeseconds;
    36.         //deathTimer.Duration = whiterocklifeseconds;
    37.         //deathTimer.Run();
    38.     }
    39.     // Update is called once per frame
    40.     void Update()
    41.     {
    42.         //if (deathTimer != null && deathTimer.Finished)
    43.         //{
    44.         //    Destroy(gameObject);
    45.         //}
    46.     }
    47.     ///<summary>
    48.     ///Self-destruct when sprites leave scene
    49.     ///</summary>
    50.    void OnBecameInvisible()
    51.     {
    52.         //Destroy(gameObject);
    53.    
    54.  
    55.         }
    56.  
    57.  }
     
    Last edited: Jul 5, 2020
  2. You can't use the new keyword on any MonoBehaviours.
    Make the rock a prefab, put it in a class member at the beginning of your SpawnRock class just like the prefabRocks and then Instantiate that prefab. It will create separate game objects out of it.

    Unless the prefabRocks is the very same thing. It's hard to tell.
     
  3. YooOwnIt

    YooOwnIt

    Joined:
    Jul 3, 2020
    Posts:
    23
    Forgot to add - in Unity I have a prefabRocks folder and I put in greenrocks0, magentarock1, and whiterock2. I attached both scripts to all three sprites in the prefab folder and the main camera.

    I put "GameObject PrefabRocks" because that's the name of the prefab folder in unity.

    I removed "new" and put in "prefabRocks" and it gives me CS1955.

    I'm new to C# so I have no idea how to put in a class member at the beginning of the spawnrock class
     
    Last edited: Jul 5, 2020
  4. Elango

    Elango

    Joined:
    Jan 27, 2016
    Posts:
    107
    Did you put it like that?
    Instantiate(prefabRocks())

    It must be:
    GameObject Rock = Instantiate(prefabRocks);

    No need in "as GameObject".
     
  5. YooOwnIt

    YooOwnIt

    Joined:
    Jul 3, 2020
    Posts:
    23
    If I put in both then
    Instantiate(prefabRocks())
    gives CS1955: "Non-invocable member 'RockSpawner.prefabRocks' cannot be used as a method."

    GameObject Rock = Instantiate(prefabRocks);
    alone gives no errors in Visual Studio but when I run unity then it says that all my sprites and "prefabRocks" is never assigned to, which makes its default value null.
     
    Last edited: Jul 5, 2020
  6. YooOwnIt

    YooOwnIt

    Joined:
    Jul 3, 2020
    Posts:
    23
  7. Vryken

    Vryken

    Joined:
    Jan 23, 2018
    Posts:
    2,106
    Yes.
     
  8. YooOwnIt

    YooOwnIt

    Joined:
    Jul 3, 2020
    Posts:
    23
  9. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    39,006
    You really gotta push through this sorta stuff... it's like forgetting to dot your i or cross your t... you will do it FOREVER into the future. It's part of software engineering. I've been doing this for 41 years and I still forget to drag references in, literally over once an hour usually (!!!) when I'm working fast.

    The good news is that you almost always can help yourself to find it quickly, and get onto real work not dotting is and crossing ts.

    Some notes on how to fix a NullReferenceException in Unity3D (also Unassigned Reference errors):

    http://plbm.com/?p=221

    You can do it.
     
  10. Elango

    Elango

    Joined:
    Jan 27, 2016
    Posts:
    107
    Instantiating/Destroying objects seems overkill for this task. Is this really needed?
    You can just make Reset() method that will reset position/movement/sprite/whatever of the rock when it reaches screen edge/timer.
    Also google "Object Pooling". It's more efficient technique for this.
     
  11. YooOwnIt

    YooOwnIt

    Joined:
    Jul 3, 2020
    Posts:
    23
    Ok, now I managed to respawn sprites after the previous ones are destroyed. The new ones just don't move.

    Is there a way to move the cloned sprites at a random velocity?
    Updated C#:
    Code (CSharp):
    1.  
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using System.Threading;
    5. using UnityEngine;
    6. /// <summary>
    7. /// A rock spawner
    8. /// </summary>
    9. public class RockSpawner : MonoBehaviour
    10. {
    11.     // needed for spawning
    12.     [SerializeField]
    13.     GameObject prefabRocks;
    14.     // saved for efficiency
    15.     [SerializeField]
    16.     Sprite greenrock0;
    17.     [SerializeField]
    18.     Sprite magentarock1;
    19.     [SerializeField]
    20.     Sprite whiterock2;
    21.     // spawn control
    22.     const float MinSpawnDelay = 1;
    23.     const float MaxSpawnDelay = 2;
    24.     Timer spawnTimer;
    25.     // spawn location support
    26.     const int SpawnBorderSize = 100;
    27.     int minSpawnX;
    28.     int maxSpawnX;
    29.     int minSpawnY;
    30.     int maxSpawnY;
    31.     /// <summary>
    32.     /// Use this for initialization
    33.     /// </summary>
    34.  void Start()
    35.     {
    36.      
    37.     // save spawn boundaries for efficiency
    38.     minSpawnX = SpawnBorderSize;
    39.         maxSpawnX = Screen.width - SpawnBorderSize;
    40.         minSpawnY = SpawnBorderSize;
    41.         maxSpawnY = Screen.height - SpawnBorderSize;
    42.         // create and save timer
    43.         spawnTimer = gameObject.AddComponent<Timer>();
    44.         spawnTimer.Duration = Random.Range(MinSpawnDelay, MaxSpawnDelay);
    45.         spawnTimer.Run();
    46.     }
    47.     /// <summary>
    48.     /// Update is called once per frame
    49.     /// </summary>
    50.     void Update()
    51.     {
    52.         // check for time to spawn a new random rock
    53.         if (spawnTimer.Finished)
    54.         {
    55.             SpawnRock();
    56.         }
    57.         // change spawn timer duration and restart
    58.         spawnTimer.Duration = Random.Range(MinSpawnDelay, MaxSpawnDelay);
    59.         spawnTimer.Run();
    60.     }
    61.     /// <summary>
    62.     /// spawns a new rock at a random location
    63.     /// </summary>
    64.     void SpawnRock()
    65.     {
    66.         // generate random location and create a new rock
    67.         Vector3 location = new Vector3(Random.Range(minSpawnX, maxSpawnX),
    68.             Random.Range(minSpawnY, maxSpawnY),
    69.             -Camera.main.transform.position.z);
    70.         Vector3 worldLocation = Camera.main.ScreenToWorldPoint(location);
    71.      
    72.         GameObject Rocks = Instantiate(prefabRocks);
    73.         prefabRocks.transform.position = worldLocation;
    74.      
    75.         // set random sprite for new rock
    76.         SpriteRenderer spriteRenderer = Rocks.GetComponent<SpriteRenderer>();
    77.         int SpriteNumber = Random.Range(0, 3);
    78.         if (SpriteNumber == 0)
    79.         {
    80.             spriteRenderer.sprite = greenrock0;
    81.         }
    82.      
    83.         else if (SpriteNumber == 1)
    84.                 spriteRenderer.sprite = magentarock1;
    85.         else
    86.         {
    87.             spriteRenderer.sprite = whiterock2;
    88.         }
    89.      
    90.     }
    91.     }
    92.  
    93.  
    94.  
    95. ///<summary>
    96. /// Spawns a new rock at a random location
    97. ///</summary>
    Code (CSharp):
    1.  
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5. /// <summary>
    6. /// Rocks script
    7. /// </summary>
    8. public class Rocks : MonoBehaviour
    9. {
    10.  
    11.     void Start()
    12.     {
    13.      
    14.         /// <summary>
    15.         /// Use this for initialization
    16.         /// </summary>
    17.         // apply impulse force to get the object moving
    18.      
    19.         const float MinImpulseForce = 2f;
    20.         const float MaxImpulseForce = 3f;
    21.         float angle = Random.Range(0, 2 * Mathf.PI);
    22.         Vector2 direction = new Vector2(
    23.             Mathf.Cos(angle), Mathf.Sin(angle));
    24.         float magnitude = Random.Range(MinImpulseForce, MaxImpulseForce);
    25.         GetComponent<Rigidbody2D>().AddForce(
    26.             direction * magnitude,
    27.             ForceMode2D.Impulse);
    28.      
    29.         ///<summary>
    30.         ///Use this for initialization
    31.         ///</summary>
    32.      
    33.     }
    34.     // Update is called once per frame
    35.     void Update()
    36.     {
    37.      
    38.        
    39.    
    40.     }
    41.     ///<summary>
    42.     ///Self-destruct when sprites leave scene
    43.     ///</summary>
    44.  
    45.     void OnBecameInvisible()
    46.     {
    47.         Destroy(gameObject);
    48.         Instantiate(gameObject, new Vector3(), new Quaternion());
    49.      
    50.     }
    51.  
    52. }
     
  12. YooOwnIt

    YooOwnIt

    Joined:
    Jul 3, 2020
    Posts:
    23
    I updated the code now:
    Code (CSharp):
    1.  
    2.  void SpawnRock()
    3.     {
    4.         Vector3 location = new Vector3(Random.Range(minSpawnX, maxSpawnX),
    5.             Random.Range(minSpawnY, maxSpawnY),
    6.             -Camera.main.transform.position.z);
    7.         Vector3 worldLocation = Camera.main.ScreenToWorldPoint(location);
    8.         //spawn random prefab
    9.         int prefabNumber = Random.Range(0, 3);
    10.         if (prefabNumber == 0)
    11.         {
    12.             Instantiate<GameObject>(prefabgreenrock, worldLocation, Quaternion.identity);
    13.         }
    14.         else if (prefabNumber == 1)
    15.         {
    16.             Instantiate<GameObject>(prefabmagentarock, worldLocation, Quaternion.identity);
    17.         }
    18.         else if (prefabNumber == 2)
    19.         {
    20.             Instantiate<GameObject>(prefabwhiterock, worldLocation, Quaternion.identity);
    21.         }
    22.     }
    23. }
    24.  
    I've also tried putting
    Code (csharp):
    1.  
    2.        const float MinImpulseForce = 2f;
    3.         const float MaxImpulseForce = 3f;
    4.         float angle = Random.Range(0, 2 * Mathf.PI);
    5.         Vector2 direction = new Vector2(
    6.             Mathf.Cos(angle), Mathf.Sin(angle));
    7.         float magnitude = Random.Range(MinImpulseForce, MaxImpulseForce);
    8.         GetComponent<Rigidbody2D>().AddForce(
    9.             direction * magnitude,
    10.             ForceMode2D.Impulse);
    11.  
    below each GameObject to move the newly spawned rocks at random velocity & direction but it made no difference. I removed the GameObject prefabRocks cause it was redundant since GameObject prefabgreenrock, prefabmagentarock, and prefabwhiterock already exist.