Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by billy_moreno · May 02, 2014 at 07:50 PM · gameobjectphysicsinstantiatestartoverlapsphere

How do I reference a GameObject after finding its collider with Physics.OverlapSphere()?

Currently I have a Player game object placed in the scene with a script that generates TerrianCubes (just built in Cubes) underneath the player, places some other WorldFeatures (spheres) randomly around the scene, and then places TerrainCubes forming a path connecting that WorldFeature back to the player. It's rudimentary. The path isn't always player navigable, but it does what I want which is to start the scene with a bunch of Terrain Cubes connecting WorldFeatures back to the Player.

Now I'm trying to add a script to the TerrainCubes so that they instantiate with different colors. My goal is to have TerrainCubes with no neighbors start with a random color and for those with neighbors to derive their color from those neighbors. The code runs (I can play the Scene), but only a few blocks around the Player change color and I get this error msg ("NullReferenceException: Object reference not set to an instance of an object.")

Here's the DefineTerrainScript I'm using for that:

 using UnityEngine;
 using System.Collections;
 using System.Collections.Generic;
 
 public class DefineTerrainScript : MonoBehaviour {
 
     int rColor = 0,
         gColor = 0,
         bColor = 0,
         aColor = 0;
 
     Collider[] hitTerrainCubes = Physics.OverlapSphere(new Vector3(0.5f,0.5f, 0.5f), 1f);
 
     // Use this for initialization
     void Start () {
 
         if (hitTerrainCubes.Length == 0){
 
             rColor = Random.Range (0,3);
             gColor = Random.Range (0,3);
             bColor = Random.Range (0,3);
             aColor = Random.Range (0,3);
 
         }
         else {
 
             for (int i = 0; i < hitTerrainCubes.Length; i++){
 
                 GameObject hitTerrainCube = hitTerrainCubes[i].transform.gameObject;
 
                 rColor += hitTerrainCube.GetComponent<DefineTerrainScript>().rColor;
                 gColor += hitTerrainCube.GetComponent<DefineTerrainScript>().gColor;
                 bColor += hitTerrainCube.GetComponent<DefineTerrainScript>().bColor;
                 aColor += hitTerrainCube.GetComponent<DefineTerrainScript>().aColor;
 
             }
         
         }
 
         this.gameObject.renderer.material.color = new Color(rColor%4,
                                                             gColor%4,
                                                             bColor%4,
                                                             aColor%4);
 
     }

  • I had some trouble finding the center and radius of the current TerrainCube to use for Physics.OverlapSphere so I just put in fixed numbers for now :(

My understanding is that the TerrainCubes will instantiate in order, so that later TerrainCubes will be able to see earlier ones. Here's my GenerateTerrainScript for reference:

     public GameObject terrainCube;
     public GameObject player;
     public float gridX;
     public float gridZ;
     public float spacing;
     public int startingFeatures;
     public GameObject worldFeatures;
     public float worldSize;
 
     // Use this for initialization
     void Start () {
 
         Vector3 playerStart = new Vector3(player.transform.position.x, player.transform.position.y, player.transform.position.z) * spacing;
         AddInitialTerrain(playerStart);
 
         for (int i = 0; i < startingFeatures; i++){
 
             Vector3 pos = (Vector3)PlaceWorldFeatures(worldFeatures);
             AddInitialTerrain(pos);
             ConnectAtoB(pos, playerStart);
 
         }
     
     }
     
 
     // Update is called once per frame
     void Update () {
 
         //SearchForThisHere(emptySpaces, player);
         //FillEmptySpace();
 
     }
 
 
     // Adds terrain around worldFeatures at start of new level
     private void AddInitialTerrain(Vector3 pos){
 
         pos.x -= (int)(gridX/2);
         pos.y--;
         pos.z -= (int)(gridX/2);
 
         for(int z = 0; z < gridZ; z++){
             
             for(int x = 0; x < gridX; x++){
 
                 Vector3 placeHere;
                 placeHere.x = pos.x + x;
                 placeHere.y = pos.y;
                 placeHere.z = pos.z + z;
                         
                 Instantiate(terrainCube, placeHere, Quaternion.identity);
                     
             }
         }
 
     }
 
     // Instantiates worldFeatures and returns position for adding terrain around.
     private Vector3? PlaceWorldFeatures(GameObject placeThis){
 
         Vector3 pos = new Vector3(Mathf.Round(Random.Range(-worldSize, worldSize)),
                                   Mathf.Round(Random.Range(-worldSize, worldSize)),
                                   Mathf.Round(Random.Range(-worldSize, worldSize))) * spacing;
         Instantiate(placeThis, pos, Quaternion.identity);
 
         return pos;
 
     }
 
     private void ConnectAtoB(Vector3 a, Vector3 b){
 
         Vector3 newB = new Vector3(b.x-1, b.y-1, b.z-1);
         while(a != newB){
 
             if(a.x < newB.x){a.x++;}
             if(a.x > newB.x){a.x--;}
 
             if(a.y < newB.y){a.y++;}
             if(a.y > newB.y){a.y--;}
 
             if(a.z < newB.z){a.z++;}
             if(a.z > newB.z){a.z--;}
 
             Instantiate(terrainCube, a, Quaternion.identity);
         }
     }

Comments about best practices, optimization, and alternative code are appreciated.

Comment
Add comment · Show 2
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image NoseKills · May 02, 2014 at 11:22 PM 0
Share

Didn't have time yet to figure out the problem but a few remarks:

1) calling GetComponent is relatively slow so it's usually better to ins$$anonymous$$d of

 rColor += hitTerrainCube.GetComponent().rColor;
           gColor += hitTerrainCube.GetComponent<DefineTerrainScript>().gColor;
           bColor += hitTerrainCube.GetComponent<DefineTerrainScript>().bColor;
           aColor += hitTerrainCube.GetComponent<DefineTerrainScript>().aColor;

to do

 DefineTerrainScript dtScript = hitTerrainCube.GetComponent();
 
         rColor += dtScript.rColor;
         gColor += dtScript.gColor;
         bColor += dtScript.bColor;
         aColor += dtScript.aColor;

2) What kind of colors are you trying to get ? The GRBA values of a Color should be from 0 to 1 (new Color(0, 0, 0) => black, new Color(1, 1, 1) => white) but you are randomizing from 0 to 3 and then adding those values together even.

avatar image billy_moreno · May 05, 2014 at 04:40 PM 0
Share

Thanks for the suggestions, Nose$$anonymous$$ills. Updated the GetComponent suggestion to this:

 DefineTerrainScript dtScript = hitTerrainCube.GetComponent<DefineTerrainScript>();
 
             rColor += dtScript.rColor;
             gColor += dtScript.gColor;
             bColor += dtScript.bColor;

Note that when I actually assign the Color to the gameObject, I modulus the added up values so that each ends up between 0 and 3:

 gameObject.renderer.material.color = new Color(rColor%4,
                                                        gColor%4,
                                                        bColor%4);

It continues to work. I'll take your word on the optimization benefits for now, although I'd appreciate if you could link or otherwise point me to resources/search terms so I can read up on it.

As far as what colors I'm ai$$anonymous$$g for, nothing really. I put together this code as a test run for figuring out how to define a terrainCube based on its neighbors. Color combining just seemed like the easiest starting point. I just started plugging numbers in until I was getting output that wasn't all black or white or grayscale.

I tried initializing to random floats between 0 and 1 after reading your comment and ran into two problems. First, I was only getting grayscale blocks. Second, I got a new error "transform.rotation assigned is not valid (0.0, 0.0, 0.0, NaN)". That error resolved when I went back to assigning a random Int between 0 and 3. Thoughts on either of those issues?

Thanks again.

1 Reply

· Add your reply
  • Sort: 
avatar image
0

Answer by robertbu · May 02, 2014 at 11:09 PM

You need to move the OverlapSphere() into Start(). That is you declare the variable:

  Collider[] hitTerrainCubes;

Then in Start():

  hitTerrainCubes = Physics.OverlapSphere(new Vector3(0.5f,0.5f, 0.5f), 1f);

While you appear to be doing everything in Start(), any time object move or are removed, you need to call OverlapSphere() again.

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image billy_moreno · May 05, 2014 at 04:29 PM 0
Share

Updated to this, which I believe takes your suggestion into account, while also moving from fixed values for OverlapSphere() to values derived from gameObject:

 public class DefineTerrainScript : $$anonymous$$onoBehaviour {
     
     int rColor = Random.Range (0,3),
         gColor = Random.Range (0,3),
         bColor = Random.Range (0,3);
 
     Collider[] hitTerrainCubes;
 
     // Use this for initialization
     void Start () {
 
         hitTerrainCubes = Physics.OverlapSphere(gameObject.transform.position,
                                                            gameObject.transform.localScale.x);
         
         if (hitTerrainCubes.Length > 0){
             
             rColor = 0;
             gColor = 0;
             bColor = 0;
                     
             for (int i = 0; i < hitTerrainCubes.Length; i++){
                 
             GameObject hitTerrainCube = hitTerrainCubes[i].transform.gameObject;
             
             DefineTerrainScript dtScript = hitTerrainCube.GetComponent<DefineTerrainScript>();
 
             rColor += dtScript.rColor;
             gColor += dtScript.gColor;
             bColor += dtScript.bColor;
             
             }
             
         }
         
         this.gameObject.renderer.material.color = new Color(rColor%4,
                                                             gColor%4,
                                                             bColor%4);
     }
         
 }

Things seem to work finealt text. I have a full range of colored blocks that seem to be affected by their neighbors (although I'm not sure how to debug this to be sure), but I still get the "NullReferenceException: Object reference not set to an instance of an object" error message.

I also tried assigning values to the array during Awake() which ends up creating cubes that are all in grayscale and I still get the NRE error. I'm assu$$anonymous$$g this has something to do with a difference in the ti$$anonymous$$g between Awake() and Start() but I'm still fuzzy on the details of that.

coloredcubes.png (249.6 kB)

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

21 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

MonoBehavior.Start() called infinite times? 1 Answer

Instantiate a prefab and parenting it? 1 Answer

I'm attempting to instantiate a prefab GameObject, but it just won't show up!! 1 Answer

Instantiate problem with multiple objects from an array 0 Answers

OverlapSphere Doesn't Return Objects Inside? 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges