Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 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 Topthink · May 14, 2018 at 07:08 PM · c#instantiateclasseswaypointsclass object

All Units Go to Same Waypoint

I create a certain number of Objects (primitive spheres in my test), and I place them at random locations on a terrain. They are instantiated objects in a Custom Class. I have it coded so that if I click the primitive sphere, it turns from Blue to Cyan, and then I click on a location on my terrain it adds that location to a waypoint list (vector3 list that is part of the custom class). The sphere will then move from point to point on the waypoint list. And everything works like magic -- as long as I have only ONE sphere on the terrain. If I have more than one, they all go to the same waypoints. I'm having a hard time figuring out where I'm going wrong. Hmmmm. I'd greatly appreciate it if someone might take a peek and point out to me my error. Thanks.

Here's my Custom Class:

 public class UnitSphere
 {
     public string uName{ get; set; }
     public float uStrength{ get; set; }
 
     public List<Vector3> waypoint { get; set; } 
     public UnitSphere()
     {
         waypoint = new List<Vector3> (); 
     }
 
     public UnitSphere(string name, float strength)
     {
         uName = name;
         uStrength = strength;
     }
 }

Heres' where I intiate the prefabs -- I don't think the problem is here.

     void Start ()  
     {
         Random.InitState ((int)System.DateTime.Now.Ticks); // Makes things more random
 
         for (int i = 0; i < totalUnits; i++)  
         {
             GameObject cloneGameUnit = Instantiate (GameUnit);
             cloneGameUnit.transform.position = new Vector3 (Random.Range (5f, 45f), .5f, Random.Range (5f, 45f));
             cloneGameUnit.gameObject.GetComponent<Renderer> ().material.color = Color.blue;
             string tempString = i.ToString ();
             string tempName = tempString + tempString + tempString + tempString + tempString;
             float tempStrength = Random.Range (80f, 95f);
             unit.Add(new UnitSphere(tempName,tempStrength));
         }
     }

Here's movement, works if there is only one sphere -- I think the problem is here ???

         GameObject[] fooThree;
         fooThree = GameObject.FindGameObjectsWithTag ("Friendly");
         tempIndex = 0;
         foreach (GameObject twit in fooThree)  
         {
             if (unit[tempIndex].waypoint==null){unit [tempIndex].waypoint = new List<Vector3> ();}
 
             if (unit[tempIndex].waypoint.Count > 0)  
             {
                 agent.destination = unit[tempIndex].waypoint[0];
                 agent.speed = 3.5f;
             }
             else
             {
                 agent.speed = 0;
             }
 
             if (unit[tempIndex].waypoint.Count > 0 && agent.remainingDistance < 0.5f) {unit [tempIndex].waypoint.RemoveAt(0);}
             tempIndex++;
         }
 

And here is adding the waypoints to the list -- Right click for single waypoint --- shift/right for multi-waypoints.

         if (Input.GetKey (KeyCode.LeftShift))   
         {
             shiftIsPressed = true;
         } 
         else  
         {
             shiftIsPressed = false;
         }
 
         if (Input.GetMouseButtonDown (1) && isSelected == true && shiftIsPressed == true)  // left shift, right mouse, object == cyan --- for adding multiple waypoints
         {
             Ray ray = Camera.main.ScreenPointToRay (Input.mousePosition);
             RaycastHit hit;
 
             if (Physics.Raycast (ray, out hit))  
             {
                 Collider col = hit.collider;
 
                 if (col.gameObject.tag == "Terrain")  
                 {
                     Debug.Log (hit.point);
 
                     GameObject[] fooOne;
                     fooOne = GameObject.FindGameObjectsWithTag ("Friendly");
                     tempIndex = 0;
                     foreach (GameObject twit in fooOne)  
                     {
                         if (twit.GetComponent<Renderer>().material.color==Color.cyan)   
                         {
                             indexNumber = tempIndex;
                             unit[indexNumber].waypoint.Add(hit.point);
                         }
                         tempIndex++;
                     }
                 }
             }
         }
         else if (Input.GetMouseButtonDown (1) && isSelected == true && shiftIsPressed == false)  // right click plus unit == cyan, --- clears waypoints and adds one new waypoint
         {
             Ray ray = Camera.main.ScreenPointToRay (Input.mousePosition);
             RaycastHit hit;
 
             if (Physics.Raycast (ray, out hit))  
             {
                 Collider col = hit.collider;
 
                 if (col.gameObject.tag == "Terrain")  
                 {
                     Debug.Log (hit.point);
 
                     GameObject[] fooOne;
                     fooOne = GameObject.FindGameObjectsWithTag ("Friendly");
                     tempIndex = 0;
                     foreach (GameObject twit in fooOne)  
                     {
                         if (twit.GetComponent<Renderer>().material.color==Color.cyan)   
                         {
                             indexNumber = tempIndex;
                             unit[indexNumber].waypoint.Clear();
                             unit[indexNumber].waypoint.Add(hit.point);
                             ResetAll ();
                         }
                         tempIndex++;
                     }
                 }
             }
         }
 
         if (Input.GetKeyUp(KeyCode.LeftShift))  
         {
             ResetAll ();
         }


     void ResetAll()
     {
         GameObject[] fooTwo;
         fooTwo = GameObject.FindGameObjectsWithTag ("Friendly");
         tempIndex = 0;
         foreach (GameObject twit in fooTwo)  
         {
             twit.GetComponent<Renderer> ().material.color = Color.blue;
             isSelected = false;
         }
     }

Comment
Add comment · Show 9
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 BPR · May 14, 2018 at 09:54 PM 0
Share

Well one problem might be that you rely soley on the order of the order returned by FindGameobjectsWithTag to map it to the classes in your list, would propose to use a monobehaviour there and also keep the gameobjects in a list ins$$anonymous$$d of searching them everytime btw.

Also what might be an issue is that you are using material color as an selection indicator, in the past I had mixed results with relying on that (instanced materials) so adding a „isSelected“ property to your unitsphere class (and hopefully monobehaviour soon).

Did you try to Debug how often the condition for adding waypoints in your foreavh loop is executed?

avatar image Topthink BPR · May 14, 2018 at 10:23 PM 0
Share

BRP, thanks for your response. I'm a solo programmer and I'm totally self taught and I always appreciate other suggestions. On keeping the gameobjects in a list, this isn't a game that relies on high fps so frequent searches shouldn't be a problem, regardless, I'll consider how I might improve things with your thought. In regard to the color check, that was the only way I could get things to work at the time...I already partly use an "IsSelected" and I'll see if I can more fully utilize that. As for the Debug, uhhh, no I haven't done that and that is an excellent suggestion that I will immediately put to good use. Again, thanks for your response.

avatar image Topthink BPR · May 15, 2018 at 03:47 AM 0
Share

Went through the debugging, looks like it's going through properly every place I checked. I'm still looking at it though. I'm going to restructure things a teenie bit and see if I can narrow down where the shortco$$anonymous$$g is located.

avatar image kskjadav007 · May 15, 2018 at 05:54 AM 0
Share

See this link

avatar image Topthink kskjadav007 · May 15, 2018 at 01:45 PM 0
Share

Thank you. I will look at your link. I appreciate your help.

avatar image Harinezumi · May 15, 2018 at 11:20 AM 0
Share

The code you posted seems to be correct to me. I think the problem is in code that you didn't post, the part where you mark a unit selected: I think you might turn all of them the selected color. Could you post that code as well, please?

Note that even though this code might work, you would be a lot better off if you made your UnitSphere class into an actual $$anonymous$$onoBehaviour, and handled selecting, setting waypoints, and going to waypoints in it. Right now you are controlling everything from "outside" of UnitSphere, violating what is called in object oriented languages like C# "encapsulation" or "separation of responsibilities". What I'm saying is that you could move most of the blocks that are after foreach (GameObject twit ...) into functions in SphereUnit, those loops.
Tell me if you are interested in this refactor, and I'll help you do the transition.

avatar image Topthink Harinezumi · May 15, 2018 at 01:42 PM 0
Share

Yes, I would very much be interested in that. I'm an old guy, completely self taught. I always appreciate when someone takes the time to $$anonymous$$ch me something.

avatar image Topthink Harinezumi · May 15, 2018 at 01:50 PM 0
Share

Note: I'm not 100% sure that I understand the first sentence in your second comment. How would I make this into an actual "$$anonymous$$onobehaviour" and control it from within? Regardless, I always welcome any sort of suggestions as to how I can make my code cleaner and more effective. Thanks.

avatar image Harinezumi Topthink · May 15, 2018 at 02:11 PM 0
Share

I meant to make UnitSphere derive from $$anonymous$$onoBehaviour, so that it has its own Update() call and other variables. But I'm writing a more exhaustive answer, I think it will make more sense there.

1 Reply

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

Answer by Harinezumi · May 15, 2018 at 03:21 PM

@Topthink, as a response to your interest in learning a different approach, here is what I would do to control the agents.
If I understood it correctly, the functionality you want is to be able to select each unit, assign it one or more waypoints, and let each unit follow through its list until the. As each unit is independent, they can be modelled with independent instances of a class that gets updated - a perfect candidate for a script (that is, a class derived of MonoBehaviour)!
When I think of classes, I think about what data and behaviour belongs into it, and what kind of "orders" should be possible to give them. For example, UnitSphere should know what its waypoints are, should update where it should move and move itself, and it should be possible to add a new waypoint or clear all waypoints and set a new one, as well as change its color when it is selected. From this, you can create the following class:

 using System.Collections.Generic;
 using UnityEngine;
 using UnityEngine.AI;
 
 public class UnitSphere : MonoBehaviour {
 
     private List<Vector3> waypoints = new List<Vector3>();
 
     private Renderer ownRenderer;
     private NavMeshAgent agent;
 
     private void Awake () {
         ownRenderer = GetComponent<Renderer>();
         agent = GetComponent<NavMeshAgent>();
 
         SetSelected(false);
     }
 
     private void Update () {
         // if arrived at first waypoint, remove it
         if (waypoints.Count > 0 && !agent.isStopped && agent.remainingDistance < 0.5f) {
             waypoints.RemoveAt(0);
         }
 
         if (waypoints.Count > 0) {
             // if the first waypoint changed...
             if (waypoints[0] != agent.destination) {
                 // set as new destination
                 agent.destination = waypoints[0];
                 // make sure to start agent
                 agent.isStopped = false;
             }
         }
         // if there is no waypoint, stop
         else { agent.isStopped = true; }
     }
 
     public void AddWaypoint (Vector3 newPoint) {
         waypoints.Add(newPoint);
     }
 
     public void SetWaypoint (Vector3 newPoint) {
         waypoints.Clear();
         waypoints.Add(newPoint);
     }
 
     public void SetSelected (bool value) {
         // this is the same as "if (value) { ...color = Color.cyan; } else { ...color = Color.blue; }"
         ownRenderer.material.color = value ? Color.cyan : Color.blue;
     }
 
 }

The rest of the functionality simply doesn't belong into UnitSphere, because it is user input. What is the rest of the functionality? Creating the units, being able to select and unselect them, add a waypoint, and set a new waypoint. Here it goes:

 using UnityEngine;
 
 public class UnitInput : MonoBehaviour {
 
     [SerializeField] private int numUnits = 10;
 
     [SerializeField] UnitSphere unitSpherePrefab = null;
 
     private UnitSphere selectedUnit;
 
     private void Start () {
         for (int i = 0; i < numUnits; ++i) {
             // you can directly assign a position when instantiating
             Vector3 position = new Vector3(Random.Range(5f, 45f), .5f, Random.Range(5f, 45f));
             // you can directly create a game object and get a reference to a script on it
             UnitSphere unitSphereInstance = Instantiate(unitSpherePrefab, position, Quaternion.identity);
             // every script has a game object, and every game object has a name
             unitSphereInstance.name = i.ToString();
             // unitSphereInstance.SetSelected(false); // we could call this here, but this initialization doesn't really belong here
         }
     }
 
     private void Update () {
         // on right click...
         if (Input.GetMouseButtonDown(1)) {
             RaycastHit hit;
             // this is an easier way of creating a ray from mouse click
             if (Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out hit)) {
                 // instead of checking tag, get the script directly
                 UnitSphere unitClicked = hit.collider.GetComponent<UnitSphere>();
                 if (unitClicked != null) {
                     // change selection, wrapped into a function
                     SelectUnit(unitClicked);
                 }
                 // clicked on something else; you might want to check if it is terrain
                 else {
                     // if there is a unit selected...
                     if (selectedUnit != null) {
                         if (Input.GetKey(KeyCode.LeftShift)) {
                             selectedUnit.AddWaypoint(hit.point);
                         }
                         else {
                             selectedUnit.SetWaypoint(hit.point);
                             // unselect as you do in your example; 
                             // however, it would be better to have selection/unselection on a different button!
                             SelectUnit(null);
                         }
                     }
                 }
             }
         }
     }
 
     private void SelectUnit (UnitSphere newUnitSphere) {
         if (selectedUnit != null) { selectedUnit.SetSelected(false); }
         selectedUnit = newUnitSphere;
         if (selectedUnit != null) { selectedUnit.SetSelected(true); }
     }
 
 }

You might also notice that I wrapped things that belong together into separate functions, for example in case of SelectUnit(). Note how it handles all the possibilities, first unselecting the currently selected unit, no matter what, and then selecting the new one, but only if it wasn't null.
Any question you might have, feel free to ask!

Comment
Add comment · Show 8 · 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 Topthink · May 15, 2018 at 03:57 PM 0
Share

I will look at this immediately. I really appreciate your help.

avatar image Topthink · May 15, 2018 at 05:18 PM 0
Share

When I run the program I get a million little spheres and a crash...a couple questions.

I'm a bit confused on one part having to do with the Serializable Field...I'm not that familiar with them. Do I need to add "[System.Serializable]" over where is says "public class UnitInput..." and/or "public class UnitSphere..."

Also, I created the two scripts "UnitSphere" and "UnitInput" and now do I attach both of those to my primitive sphere in the Hierarchy and then drag the sphere into the Project Window and then delete the sphere from the hierarchy? And what do I need to drag to the Inspector?

Thanks.

I know how (and what order) to do this in my original program but I'm a teenie bit confused as to the exact procedure and sequence to use in this situation.

avatar image Topthink · May 15, 2018 at 06:41 PM 0
Share

...of course, it could be that I forgot to add the Nav$$anonymous$$esh to the terrain and the Nav$$anonymous$$eshAgent to the sphere. LoL. I'll do that and run the program again. $$anonymous$$aybe it would work if I actually did all the things I need to do.

avatar image Topthink · May 15, 2018 at 06:42 PM 0
Share

...I'm working on this off and on today. I really do appreciate the time you are taking to help me. Thanks again.

avatar image Topthink · May 16, 2018 at 03:48 PM 0
Share

I'm going down your suggested code line by line and where I don't fully understand it I'm doing a bit of research to help me get there. I still don't have everything working properly but I'm learning a tremendous amount from your examples.

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

504 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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

Tetris Unity game structure C# 3 Answers

Classes, MonoBehaviours C# 2 Answers

Distribute terrain in zones 3 Answers

Multiple Cars not working 1 Answer

Issue Instantiating prefab in C# 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