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 FadyDev · Dec 13, 2012 at 07:08 AM · hashtable

One script on multiple game objects problem

I have a script attached to three similar game objects. These game objects have to check if another game object is within reach using Physics.CheckSphere. The problem is that if only one game object checks that there is no enemy in reach the condition is met. What I want is for all three game objects to detect that there is no enemy in reach to meat the condition.

 function Start () {
     InvokeRepeating("CheckReach",0.0,2.0);
 }
 
 function CheckReach(){
     if(!Physics.CheckSphere(transform.position,10.0,sphereIn)&& SphereLogic.fuel<=0.0){ 
     gameOverGUI.active=true; 
     } 
 }

the problem is that the condition is met if only one game object is true. I want the condition to be met only if all three game objects return true.

Thanks.

Comment
Add comment · Show 3
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 AlucardJay · Dec 13, 2012 at 07:18 AM 0
Share

From the API : Returns true if there are any colliders touching the sphere defined by position and radius in world coordinates

so by this, all you need is one collider. It sounds like you want to find if all three are within the sphere, and then check if a variable on each object is true, is this correct?

sorry, I was looking at the code more than the text. I think you are going to need a manager that has a reference to all three objects, and if all report no enemies, then initiate gameOverGUI.

Either that, or have every object find every other object, and when the condition is met they all agree to gameOverGUI. The problem there is you have 3 scripts calling the same thing. I would think about the manager approach =]

avatar image FadyDev · Dec 13, 2012 at 07:28 AM 0
Share

Hi alucardj,sorry for the unformatted code. Let's say we have 3 radars at different places checking for planes within a radius using CheckSphere. $$anonymous$$y problem is that when just one radar returns that there is no plane in reach the condition is met(even though the remaining 2 have planes within reach). What I want is that all 3 radars return no planes in reach for the condition to be met. Thank you.

avatar image AlucardJay · Dec 13, 2012 at 07:32 AM 0
Share

yep, I thought as much. $$anonymous$$y last comment and the answer is basically saying that you need a manager, a master script that looks at all the radars, and checks if all of them are saying "nope, all clear". The answer is in C#, if you need help I can convert it.

3 Replies

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

Answer by FadyDev · Dec 13, 2012 at 10:15 AM

SOLVED Ok, thanks guys. I couldn't make it with classes. So I created an empty gameObject exposed an array of gameObjects to represent the radars and a hashtable to check for boolean values like this

 var radars:GameObject[];
 var gameOverGUI:GameObject;
 private var sphereIn:LayerMask=1<<21;
 
 
 
 function Start () {
 
     InvokeRepeating("CheckReach",0.0,2.0);
 
 }
 
 
 function CheckReach(){
 
     var noReach=new boolean[radars.Length];
     
     var h:Hashtable;
     
     h=new Hashtable();
     
     for(var i:int=0;i<radars.Length;i++){
 
         if(!Physics.CheckSphere(radars[i].transform.position,10.0,sphereIn)&& SphereLogic.fuel<=0.0){
 
             noReach[i]=true;
             
             }
             
             h.Add(radars[i],noReach[i]);
             
      }
             
             if(h.ContainsValue(false)){
         
                 gameOverGUI.active=false;}
         
             else{
         
                 gameOverGUI.active=true;
         
         }
         
 }

The good thing about this script is that you can specify the number of radars in the inspector. I used a hashtable to store keys and values, then I checked if for "false" values to see if every radar can't reach any plane.

Comment
Add comment · Show 5 · 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 fafase · Dec 13, 2012 at 07:59 PM 0
Share

Note that active is deprecated and you might prefer to use enabled.

Also, why not returning the function once you get one false since that is enough to stop?

avatar image fafase · Dec 14, 2012 at 08:17 AM 0
Share

Just for info, this answer has a worst case of 2*O(n) meaning that for an array of 10 radars you get a worst case of 20 cycles because you iterate twice through the whole array. You can actually reduce it to O(n) and iterate only to the point where you hit a false. But are you interested in knowing how?

avatar image FadyDev · Dec 14, 2012 at 08:29 AM 0
Share

It will never exceed 4 radars. It is always between 1 and 4. But hey it is always good to learn new tricks.

avatar image fafase · Dec 14, 2012 at 08:40 AM 0
Share

As I said, you are iterating through the whole array here:

  for(var i:int=0;i<radars.Length;i++)

and then again here:

   if(h.ContainsValue(false))

Actually the second one iterates all over only in the worst case but in algorithm you always consider the worst case.

The common notation is O(n) meaning the number of cycles is depending on n. There may be O(n^2) or O(log n) or O(n^n) or else. They only define how good is your algorithm. Yours are O(n) + O(n) = 2O(n) That is because they both only depends on how many elements in the array.

Now this:

 for(var tr : Transform in go){
     if((tr.position-_transform.position).sqr$$anonymous$$agnitude>distSqr){
          gameOverGUI.active=false;
          return;
       }
 }
 gameOverGUI.active=false;

has a maximum of O(n) only. You will only iterate once through the whole array and only if all of them are true or the last one is false. Simply because if one of them is not within range,, the function is returned.

On top of that I do not know the implementation of SphereCast but I would think it might be slightly more expensive that a simple sqr$$anonymous$$agnitude since it needs to check the distance to get collider components, check the layer.

Now your game might not need all that now, but one day you might create the next WoW...:)

avatar image FadyDev · Dec 14, 2012 at 08:58 AM 0
Share

Yes , I moved "if(h.ContainsValue(false))" out of the loop. Thanks for the info.

avatar image
1

Answer by jogo13 · Dec 13, 2012 at 07:20 AM

You may want to create a 'manager' type gameobject class who oversees all three gameobjects. If you change `CheckReach()` to return a `bool` it could call all three at once.

Rough Example Class:

 public class manager : MonoBehaviour {
 
 radar r1;
 radar r2;
 radar r3;
  
 void Update(){
 
      if(r1.CheckReach() && r2.CheckReach() && r3.CheckReach()) //condition met
         {
                handle_conditions_met();
         }
 }
     
Comment
Add comment · Show 3 · 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 fafase · Dec 14, 2012 at 06:42 AM 0
Share

I am a little confused on the double upvote and answer for that one...

the question is " I want the condition to be met only if all three game objects return true." so in a way what is the function to get all three to be checked. This answer is just putting the three functions in a row but no particular implementation of the CheckReach...at least it seems to me.

Also, he says," I wanted a script to work no matter what the number of radars is in each level", this is working for 3 and if you add any, you need to modify the script.

Now what if one of the radar is destroyed? You script crashes and you get Null reference exception.

avatar image Eric5h5 · Dec 14, 2012 at 07:09 AM 1
Share

Also the code is wrong since CheckReach is not a function of GameObject.

avatar image jogo13 · Dec 14, 2012 at 04:33 PM 0
Share

I updated the code to be radars and not gameobjects, that was a mistake. :)

avatar image
0

Answer by fafase · Dec 13, 2012 at 01:05 PM

You could simply check from the guy itself

 import System.Collections.Generic;
 var go = new List.<Transform>();
 var distSqr:float = 100;
 var _transform:Transform;
 var within :boolean;
 
 function Start(){
     var gos = GameObject.FindGameObjectsWithTag("GO");
     for(var g : GameObject in gos)
        go.Add(g.GetComponent(Transform));
     _transform = GetComponent(Transform);
     InvokeRepeating("Check",0.01f,2.0f);  
 }
 function Update(){
     if(within)print("All in");
     else print("Not in all");
 }
 function Check(){
     for(var tr : Transform in go){
           if((tr.position-_transform.position).sqrMagnitude>distSqr){
              within = false;
              return;
           }
     }
     within = true;return;
 }

EDIT: Now it will go for as many items you can add. The function simply iterate through the list of transform. When the distance is too large, within is set to false, the function returns. If all are smaller than distSqr, the whole loop iterates, the function leaves the for loop and ends up with within = true;.

EDIT AGAIN: Ok I tested it now and it does work for sure. My bad, I had a few typos mistakes... But now it is 100% working. I can even remove radars at runtime, it s still running. Concerning distSqr, you need to think in terms of squared value. So if you want to check a distance of 5m, distSqr is 5*5 = 25.

Comment
Add comment · Show 4 · 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 fafase · Dec 13, 2012 at 01:06 PM 0
Share

Note that in the answer everything is optimized with caching of the transform, use of sqr$$anonymous$$agnitude to avoid sqr root and time-spaced calls with InvokeRepeating.

avatar image FadyDev · Dec 13, 2012 at 01:34 PM 0
Share

This script will work for a constant number of radars. I wanted a script to work no matter what the number of radars is in each level.If someone could help in iterating through the boolean array to negate the condition if only one "false" value is found.

avatar image FadyDev · Dec 13, 2012 at 04:22 PM 0
Share

fafase thanks for your effort but the script above gave me a long list of errors for reasons I am not sure about,especially in the List declaration line.

avatar image fafase · Dec 13, 2012 at 04:25 PM 0
Share

I changed it. I was missing the dot. Also make sure to add the import at the top.

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

13 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

Related Questions

Finding if a specific key contains a specific value in a Hashtable? 1 Answer

How to check collision with specific object 1 Answer

Scripting error! 1 Answer

Performance of Mathf.Clamp vs if-else statement? 1 Answer

Destroy "Don'tDestroyOnLoad" script in a specific scene ?? 3 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