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 Hiilo · Jul 31, 2013 at 05:41 PM · gameobjectarraytoggleextension-methodsradio

Radio button like toggle behaviour on gameobjects

Hi. Heres what I would like to achieve. I have at least three gameobjects. If I click on one object(out of three) it would have arbitrary boolean value wasClicked set true. If I click on any other gameobject then the boolean for the previously clicked object gets set to false and gets set true for the last object that was clicked. So all the three gameobjects would use the wasClicked boolean but it would be true for only one gameobject at a time.

So far my idea was to

  1. collect the gameobjects in to array

  2. Create a extension method for the wasClicked boolean

  3. Somehow do the radio button like behaviour???

Heres some cut outs from my code

Game object array

 private GameObject[] players; // Create array for gameobjects
 
 
 void Start ()
     {    
         players = GameObject.FindGameObjectsWithTag("Player");//Collect all the right gameobjects
     }
 
 void OnMouseDown()
     {
             RaycastHit hit ;//Set up new raycasthit
             Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);//Set up new ray shooting out of the camera from where the mouse is
             
             if (Physics.Raycast(ray, out hit))
             {    
                 int i = 0;
                 players[i] = hit.transform.gameObject;//The Parent object that was hit by ray
                 GameObject myObj = players[i];//Convert array object to parentObject for nicer syntax
                 
                 if (myObj.wasClicked)//if == true
                 {
                     //do something with the gameobject
                 }
                 
                 else if (/*Another object was clicked */)
                 {
                     //Set wasClicked false for the object that was clicked first and do something
                 }
             
         }
         
 }

Extension method code

 using UnityEngine;
 using System.Collections;
 public static class toggleObject {
     
 public static void wasClicked(this GameObject go, bool clickState ){
         
         clickState=false;
     }
     
 }

If anybody could at least tell me if I'm on the right way with using array's that would be awesome.

And for the boolean... I think my gameobjects (myObj) will end up having child objects added to them when they are clicked... so i think i could use something like

 bool hasChild = myObj.transform.hasChildren();//Pseudo code

But I would like to avoid that if possible.

Comment
Add comment
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

1 Reply

· Add your reply
  • Sort: 
avatar image
1
Best Answer

Answer by Jamora · Jul 31, 2013 at 06:30 PM

You seem like the kind of person who likes to think about these things, so I won't give you any working code. Instead, I will tell you where you're going wrong with this approach.

The way you explain using one boolean to mark the state for multiple objects cannot work. A boolean is just true of false, you cannot infer the object it is pointing to. What you could do is use an int to mark which object it is pointing to in the array. So when changing the boolean you would also change the int. But on further thought the boolean is then irrelevant, as it's always true. Following this trail of thought, why not keep a reference to the currently selected GameObject itself instead of an int. This way, the radio button effect will have been achieved, because only one GameObject can be pointed to at any given time.

The current way you're using your array overrides some references to players, namely to the player #0. So you will not be able to reference that player again unless you regain the reference. It puzzles me why you modify the array at all, because you already have the reference to the clicked object from hit.transform.gameObject.

Finally, your extension method doesn't actually do anything. clickState will be a local variable within the method, so changing it will not have any effect globally. If you feel the need to use this approach (I think it's overcomplicating things) you need to do some research on how to pass variables by reference.

To check for children, you'll need to use transform.childCount. I'd imagine there isn't a better way.

Comment
Add comment · Show 7 · 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 Hiilo · Jul 31, 2013 at 07:13 PM 0
Share

Thanks for the answer. About using int's. I was previously fiddling with gameobject id-s. I guess I could(maybe should?) also use array id-s. I had something like this int hitID = players[i].GetInstanceID(); This gave me nice numbers, but I ran out of ideas how to check the numbers against each other. Lets say I have objects A B and C. All of those objects are red by default. When I click on any of them the one clicked turns green. But how could i let object C know that object A is already green?

avatar image Jamora · Jul 31, 2013 at 07:45 PM 0
Share

$$anonymous$$y point is that you shouldn't be using ints. Ins$$anonymous$$d store a reference to the GameObject that is currently selected. Then anyone who wants to know which object is selected simply checks if they equal the current selection.

I don't know your use case, but I would solve this problem like this (I know I said no code, but it's easier to show than explain):

 public class SelectableCube{
   private static GameObject selectedObject = null;
 
   void Update(){
     if(selectedObject == gameObject){
       renderer.materal.color = Color.Red;
     }else{
       renderer.material.color = Color.Green;
     }
   }
 
   void On$$anonymous$$ouseDown(){
     selectedObject = gameObject;
   }
 }

It's not very performant, because the material is changed every frame. A more efficient version would be to only do changes when a new cube has been selected.

avatar image Hiilo · Jul 31, 2013 at 09:46 PM 0
Share

Super. You definitely got me in the right $$anonymous$$d set... I think :) This is what I made now

 public GameObject[] players;
 
 void Start ()
     {    
         players = GameObject.FindGameObjectsWithTag("Player");
     
     }
 
 void On$$anonymous$$ouseDown()
         {
             RaycastHit hit ;
             Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
             
                 foreach(GameObject player in players)
                 {
                     player.renderer.material.color = Color.green;//Set all the objects to green
                 }
         
                 if (Physics.Raycast(ray, out hit))
                 {    
                     renderer.material.color = Color.red;//Set the object that was clicked red
                 }
         
         }

And this basically does what I want but it seems a little bit wasteful.

avatar image Jamora · Aug 01, 2013 at 06:21 AM 0
Share

The only way to make this less wasteful is to use a static variable like in my example. So get rid of the foreach, and before you set the current selection's color to red, you set the old selection's color to green and update the reference.

avatar image Hiilo · Aug 01, 2013 at 06:26 AM 0
Share

Based on your example I made another version.(It's amazing what 8 hours of sleep can do) Here's the code

 public GameObject[] players;
 private GameObject selectedPlayer = null;
 
 void Start ()
     {    
         players = GameObject.FindGameObjectsWithTag("Player");
     
     }
 
 void On$$anonymous$$ouseDown()
         {
             RaycastHit hit ;
             Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
             
             selectedPlayer = hit.transform.gameObject;//Set selected player equal to clicked gameobject
             foreach(GameObject player in players)
             {
                 if(player == selectedPlayer)
                 {
                     selectedPlayer.renderer.material.color = Color.red;//Set selected player color red
                 }
                 else
                 {
                 player.renderer.material.color = Color.green;//Set color green for all the other elements
                 }
             }
         } 

But what I'm wondering about is that is it a good Idea to run through all the other objects in my array? Because I would actually need to set color = green for only one object. I guess i could add more conditions to the else statement. something like this

 else if (player == ! selectedPlayer && player.renderer.material.color == Color.red)
 {
  //Do my thing
 }

Is it something I should do? I'm just asking because I want to get in to "good habits" and learn and understand correct program$$anonymous$$g concepts.

Show more comments

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

16 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

Related Questions

Get all other GameObjects (not the one script is attached to) 2 Answers

Adding GameObject to GameObject[] array 1 Answer

Array out of index? 1 Answer

HELP Find gameObject With tag in another array 1 Answer

Load Prefabs in Array with Javascript 1 Answer


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