Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Change Sphere Material When Clicking a Game Object

Discussion in 'Scripting' started by amoeboar, Jun 7, 2017.

  1. amoeboar

    amoeboar

    Joined:
    Nov 30, 2015
    Posts:
    23
    Hi all,

    I've got a large sphere with inverted normals that my player is standing inside to simulate a pseudo skybox. I'm trying to click an object in scene (a cube) to change the material on this sphere to create the next "step" in the sequence. I've got it working with a starting texture, and then clicking my cube loads the second texture. But I have potentially dozens of textures, and each time the user clicks a cube to advance, both the cube will move and the camera will need to rotate to prepare for the next step. What's a good way for me to continue and scale this? I'm looking for advice.

    I'm hoping this is helpful to other people too because a lot of the solutions I'm seeing online are deprecated.

    I'm new to Unity but not to programming, and because I'm not yet familiar enough with Unity's capabilities I want to write efficient code. The way it's working now, I have a serialized field where I can drop my single Texture into. I'm trying to accomplish three things:

    1) Can I make an array of these textures and just toggle the array element I need depending on which cube is clicked?
    2) Can I have an array of cubes too, each at their own positions, and hide and show them as needed? Or do I keep one cube but move it around and select which texture it corresponds with?
    3) How can I orient the default rotation of the camera when each new texture loads, or else how can I orient the location of the texture relative to the cameras POV?

    I want to be smart about how I architect this and I'm welcoming all advice from the community. Here's what I've got attached to my ClickHotspot cube:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class ClickHotspot : MonoBehaviour {
    6.  
    7.   [SerializeField] private Color colorChange;
    8.   [SerializeField] private Texture texture;
    9.   [SerializeField] private GameObject sphere;
    10.  
    11.   void Start() {
    12.     sphere = GameObject.Find("Sphere");
    13.   }
    14.  
    15.     void OnMouseEnter() {
    16.       // Debug.Log("Mouse Entered");
    17.       gameObject.GetComponent<MeshRenderer>().material.color = colorChange;
    18.     }
    19.  
    20.     void OnMouseExit() {
    21.       // Debug.Log("Mouse Exited");
    22.       gameObject.GetComponent<MeshRenderer>().material.color = Color.white;
    23.     }
    24.  
    25.   void OnMouseDown() {
    26.       // Debug.Log("You clicked");
    27.     gameObject.GetComponent<MeshRenderer>().material.color = Color.green;
    28.     sphere.GetComponent<Renderer>().material.mainTexture = texture;
    29.   }
    30. }
    EDIT: Please see Game_View_Before and Game_View_After to get a sense of what I'm seeing.
     

    Attached Files:

    Last edited: Jun 7, 2017
  2. amoeboar

    amoeboar

    Joined:
    Nov 30, 2015
    Posts:
    23
    My code is starting to look like this, and this is what I was worried about:

    Code (CSharp):
    1. void OnMouseDown() {
    2.     clickCounter();
    3.   }
    4.  
    5.   void clickCounter() {
    6.  
    7.     if (counter == 0) {
    8.       counter++;
    9.     }
    10.  
    11.     switch (counter) {
    12.       case 1:
    13.         sphere.GetComponent<Renderer>().material.mainTexture = textures[0];
    14.         counter++;
    15.         break;
    16.       case 2:
    17.         sphere.GetComponent<Renderer>().material.mainTexture = textures[1];
    18.         counter++;
    19.         break;
    20.       case 3:
    21.         sphere.GetComponent<Renderer>().material.mainTexture = textures[2];
    22.         counter++;
    23.         break;
    24.       case 4:
    25.         sphere.GetComponent<Renderer>().material.mainTexture = textures[3];
    26.         counter++;
    27.         break;
    28.       case 5:
    29.         sphere.GetComponent<Renderer>().material.mainTexture = textures[4];
    30.         counter++;
    31.         break;
    32.       default:
    33.         break;
    34.     }
    35. }
    I'd love to hear what suggestions people have.
     
  3. Laperen

    Laperen

    Joined:
    Feb 1, 2016
    Posts:
    1,065
    Cache the renderer of the sphere in a variable.
    Use the counter integer as the index for the textures array/list. Will need to add or subtract a little to avoid errors and make the number match up.
     
    amoeboar likes this.
  4. amoeboar

    amoeboar

    Joined:
    Nov 30, 2015
    Posts:
    23
    Thanks for the response, Laperen. Are you able to go into a little more detail about what you mean? Perhaps with a code or pseudocode example? I'm not sure which methods I need, and I'm not sure how to achieve the functionality you're talking about within Unity.
     
  5. LiterallyJeff

    LiterallyJeff

    Joined:
    Jan 21, 2015
    Posts:
    2,807
    pretty sure this is what he's saying, assuming "counter" is an integer. If not, then cast it to an int when doing the array lookup.
    Code (CSharp):
    1. public List<Texture> textures;
    2.  
    3. private Renderer sphereRenderer;
    4. private int counter;
    5.  
    6. private void Start()
    7. {
    8.     sphereRenderer = sphere.GetComponent<Renderer>();
    9. }
    10.  
    11. private void OnMouseDown()
    12. {
    13.     clickCounter();
    14. }
    15.  
    16. private void clickCounter()
    17. {
    18.     if(counter < textures.Count)
    19.     {
    20.         sphereRenderer.material.mainTexture = textures[counter];
    21.         counter++;
    22.     }
    23. }
     
    amoeboar likes this.
  6. amoeboar

    amoeboar

    Joined:
    Nov 30, 2015
    Posts:
    23
    OK I see, thanks for showing me that. Is your reason for using
    Code (CSharp):
    1. private Renderer sphereRenderer;
    and then fetching it with a
    Code (CSharp):
    1.  sphereRenderer = sphere.GetComponent<Renderer>();
    less expensive than Find? I'd like to know if this is true because there's outdated info out there on the internet.

    One issue I see with the counter++ approach is that I can only advance forward. Let's say the player wishes to turn around, and click a cube behind them to return to the previous texture.. I'm not sure what to do then.

    Also, a big question for me is still how to write a statement that sets the camera and/or texture rotation whenever the texture advances. This is to make sure the horizon stays in place and the path is always in front of the character.

    Additionally, what is a statement I could write to move the cube to its new position "on the path", or is it better to make many cubes and just hide/show them? Any tips? Wondering what you would all do if you were solving this problem.
     
    Last edited: Jun 7, 2017
  7. amoeboar

    amoeboar

    Joined:
    Nov 30, 2015
    Posts:
    23
    Also, still getting used to textures.Count and not textures.Length

    o_O
     
  8. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Caching the renderer is much better than looking it up every time. It's also much better to use GetComponent than Find, for sure. In general, you should do your best to avoid Find whenever possible ;) Use sparingly until you get comfortable & familiar with the options you'll learn (such as in this thread).

    As for what if they want to go backwards.. well, you'd have to subtract? :) and check that the index >= 0.
     
    amoeboar likes this.
  9. amoeboar

    amoeboar

    Joined:
    Nov 30, 2015
    Posts:
    23
    OK, thank you! This is all very helpful! I will spend some time adopting this strategy.

    I notice when I try to implement:

    Code (CSharp):
    1. Camera.main.transform.rotation = Quaternion.Euler(180,180,180);
    in my switch statement (I did not refactor it yet as per the above suggestions!) the line above has no effect. I also notice that at runtime I can't change the camera's rotation in the inspector.

    Am I not allowed to change camera rotation via script while the game is running? Or is there some logic in the default asset "FirstPersonCharacter" that prevents me from overriding it with my own camera rotation?
     
    Last edited: Jun 8, 2017
  10. amoeboar

    amoeboar

    Joined:
    Nov 30, 2015
    Posts:
    23
    For anyone who's interested, I found that the above method is deprecated. The correct statement is:

    Code (CSharp):
    1.  sphere.transform.eulerAngles = new Vector3 (x, y, z);
    There's a lot of outdated content on the internet about Unity, unfortunately. So maybe this will help someone in the future who's in my shoes.
     
  11. LiterallyJeff

    LiterallyJeff

    Joined:
    Jan 21, 2015
    Posts:
    2,807
    This part is a little confusing to me:
    You said the player can turn around and click a previous cube, doesn't that imply you have many cubes? Where does the clicked cube move to?

    If that is the case then this is not a material swap based on number of times clicked, so this logic isn't right for your needs.

    I think what you're saying is that you have one cube per material essentially, the cubes just act as buttons. So instead of keeping an array of materials in one script, you can give each cube the material reference for that step, and when you click that cube, that material is shown.

    So each cube would get the same component with this code in it:
    Code (CSharp):
    1. public Texture texture; // the texture that should show when this cube is clicked
    2.  
    3. // assign this in the inspector
    4. // or give the sphere a unique component and use
    5. // FindObjectOfType<UniqueComponent>() on start to assign it
    6. public Renderer sphereRenderer;
    7.  
    8. private void OnMouseDown()
    9. {
    10.     sphereRenderer.material.mainTexture = texture;
    11. }
     
    amoeboar likes this.
  12. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Were you referring to : transform.rotation = Quaternion.Euler() is deprecated?
    If you were, that's just not true..
     
    amoeboar likes this.
  13. amoeboar

    amoeboar

    Joined:
    Nov 30, 2015
    Posts:
    23
    OK, it didn't work for me so I assumed the method was outdated (because I believe a lot of the info available online predates Unity 5 and I assume to be outdated). I realize it's possible that the above method works fine, just not the way I used it. When I swapped it out for the second method it just worked so I went with it.
     
  14. amoeboar

    amoeboar

    Joined:
    Nov 30, 2015
    Posts:
    23
    So, let me clarify: as I've been building this out, Ive got 4 cubes (click triggers). I've labeled them cardinally: NCube, WCube, ECube, SCube (or using a WASD convention). Each of these cubes sits roughly at cardinal positions relative to the player: in front of them, behind them, to their left and right.

    Surrounding the player is a single large sphere with a Material on it. When a cube is clicked, the texture on the material changes to the next one. I took photos every 10 steps so that I could simulate "walking forward" when a person advances to the next texture. What I'm trying to do now, is that when a person clicks forward, the texture on the sphere changes to a specific index in the array (based on the corresponding image in the sequence), if they click the West cube they would trigger the texture that corresponds with that direction, etc. At every step (texture rendered), they might not be able to move forward, backward, left and right, so I hide the cubes as needed to prevent them from moving that way.

    Here's my code so far (again, I'm still sticking with the switch case so I can handle 10 textures and get my directions working, and then I'll introduce more later. I'm still using Find because it works.. I'll refactor later).

    This script is attached to all 4 of my trigger cubes: WCube, ACube, SCube, DCube:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class ClickHotspot : MonoBehaviour {
    6.  
    7.   [SerializeField] private Color colorChange;
    8.   [SerializeField] private List<Texture> textures = new List<Texture>();
    9.   // [SerializeField] private Texture texture;
    10.   [SerializeField] private GameObject sphere;
    11.   private GameObject WCube, ACube, SCube, DCube;
    12.  
    13.   int counter = 0;
    14.  
    15.   void Start() {
    16.     sphere = GameObject.Find("Sphere");
    17.     WCube = GameObject.Find("WCube");
    18.     ACube = GameObject.Find("ACube");
    19.     SCube = GameObject.Find("SCube");
    20.     DCube = GameObject.Find("DCube");
    21.     showCubes(true, false, false, false);
    22.     sphere.transform.eulerAngles = new Vector3 (2.37f, 3.81f, -4.29f);
    23.     counter++;
    24.     Debug.Log(counter-1);
    25.   }
    26.  
    27.      void OnMouseEnter() {
    28.       gameObject.GetComponent<MeshRenderer>().material.color = colorChange;
    29.      }
    30.  
    31.     void OnMouseExit() {
    32.       gameObject.GetComponent<MeshRenderer>().material.color = Color.white;
    33.      }
    34.  
    35.   void OnMouseDown() {
    36.     clickCounter();
    37.   }
    38.  
    39.   void showCubes(bool w, bool a, bool s, bool d) {
    40.     if (!w) WCube.GetComponent<Renderer>().enabled = false;
    41.     if (!a) ACube.GetComponent<Renderer>().enabled = false;
    42.     if (!s) SCube.GetComponent<Renderer>().enabled = false;
    43.     if (!d) DCube.GetComponent<Renderer>().enabled = false;
    44.     if (w) WCube.GetComponent<Renderer>().enabled = true;
    45.     if (a) ACube.GetComponent<Renderer>().enabled = true;
    46.     if (s) SCube.GetComponent<Renderer>().enabled = true;
    47.     if (d) DCube.GetComponent<Renderer>().enabled = true;
    48.   }
    49.  
    50.   // The walkForward function rotates the sphere so that the texture's horizon
    51.   // and rotation stays consistent from frame to frame
    52.   void walkForward(float x, float y, float z) {
    53.     sphere.transform.eulerAngles = new Vector3 (x, y, z);
    54.   }
    55.  
    56.   void clickCounter() {
    57.  
    58.     switch (counter) {
    59.       case 1:
    60.         sphere.GetComponent<Renderer>().material.mainTexture = textures[0];
    61.         walkForward(2.13f, -0.07f, -2.14f);
    62.         showCubes(true, false, true, false);
    63.         DCube.transform.position = new Vector3 (-2.24f, -0.7f, -9.53f);
    64.         SCube.transform.position = new Vector3 (-10.34f, -0.56f, 0.95f);
    65.         counter++;
    66.         break;
    67.       case 2:
    68.         sphere.GetComponent<Renderer>().material.mainTexture = textures[1];
    69.         walkForward(2.13f, -2.63f, -3.39f);
    70.         counter++;
    71.         break;
    72.       case 3:
    73.         sphere.GetComponent<Renderer>().material.mainTexture = textures[2];
    74.         walkForward(-1.12f, -4.91f, -3.34f);
    75.         counter++;
    76.         break;
    77.       case 4:
    78.         sphere.GetComponent<Renderer>().material.mainTexture = textures[3];
    79.         walkForward(1.4f, -9.51f, -5.62f);
    80.         showCubes(true, false, true, false);
    81.         // It breaks when you do this:
    82.         // showCubes(false, false, true, false);
    83.         DCube.transform.position = new Vector3 (-2.24f, -0.7f, -9.53f);
    84.         counter++;
    85.         break;
    86.       case 5:
    87.         sphere.GetComponent<Renderer>().material.mainTexture = textures[4];
    88.         walkForward(7.07f, 77.5f, -4.42f);
    89.         counter++;
    90.         break;
    91.       case 6:
    92.         sphere.GetComponent<Renderer>().material.mainTexture = textures[5];
    93.         walkForward(-5.13f, 50.64f, -2.37f);
    94.         counter++;
    95.         break;
    96.       case 7:
    97.         sphere.GetComponent<Renderer>().material.mainTexture = textures[6];
    98.         walkForward(9.98f, 112.5f, -9.8f);
    99.         counter++;
    100.         break;
    101.       case 8:
    102.         sphere.GetComponent<Renderer>().material.mainTexture = textures[7];
    103.         walkForward(8.47f, 101.17f, 0.69f);
    104.         counter++;
    105.         break;
    106.       case 9:
    107.         sphere.GetComponent<Renderer>().material.mainTexture = textures[8];
    108.         walkForward(3.98f, 112.5f, -4.54f);
    109.         counter++;
    110.         break;
    111.       default:
    112.         break;
    113.     }
    114.     Debug.Log(counter-1);
    115.   }
    116. }
    Two problems with the above:

    1) Introducing multiple cubes, all with a counter++ incrementer, makes it so that any cube advances the count. I don't just want to move forward, I want to be able to trigger the material that simulates movement right or left (see the attached photos, they are in sequence Step 1, 2, and 3). I.E. if I am rendering texture[5] and I click the "Back" cube, I should go to texture[4]. If I am rendering texture[5] and I click the "Left" cube, perhaps the corresponding texture in the array is texture[11] and we jump to that index. Also, because this same script is attached to all 4 cubes I think it's getting confused and I'm not sure how to distinguish between them.
    2) Around line 81 it breaks. When I try to hide/show cubes, it loops me back to the first texture in the array and I start at the beginning of my sequence. No idea why.

    This is an interesting problem, and I'm having fun solving it. Tips and suggestions are still very much appreciated :D
     

    Attached Files:

    Last edited: Jun 8, 2017
  15. LiterallyJeff

    LiterallyJeff

    Joined:
    Jan 21, 2015
    Posts:
    2,807
    Okay, I have a much better idea of what you're trying to do, but let me ask you another question.

    You said that if you keep clicking forward, you might wind up at texture index 5. Then if you click Left, it might take you to texture index 11. If you didn't click Left, and kept clicking forward, would you end up at texture 11?

    Right now you're approaching this as a linear list of textures, but it sounds like you want more of a 2D list of textures that you can navigate through with an X index and a Y index, is that accurate?
     
    amoeboar likes this.
  16. amoeboar

    amoeboar

    Joined:
    Nov 30, 2015
    Posts:
    23
    Let me clarify: I start the demo, there's a cube in front of me (and none behind me, because there is no image for a player to navigate to as we are in the first texture. I click the cube in front of me once, and I'm in texture 2. Now a cube appears behind me because a person CAN go back to the previous. I continue forward to 3, 4 and 5. Now, because in real life I did not take a photo any further forward than this, the user cannot go further in this direction. So the cube in front of me disappears, and new cubes appear to my left and right. In real life, I turn left and take 5 photos in that direction. So at the end of this path we are at photo 10. Now, because the player could have also gone right at that crossroads I mentioned, in real life, I return to this spot, take that right, and take my photo (which is 11). So, from that juncture point (photo 5), to a player's left is photo 6 but to their right is photo 11. Does that make sense?

    That's probably right. A matrix might serve well here, but I'm nowhere near that point in my Unity journey to know how to do that. Basically, I want to build a system (eventually) where I can import all my textures, place the appropriate cubes or trigger points, and allow someone to take a 360 degree tour of the environment.
     
  17. LiterallyJeff

    LiterallyJeff

    Joined:
    Jan 21, 2015
    Posts:
    2,807
    Well I had some free time over my lunch break so I decided to try and whip up something that might work for you.

    Basically I made a class that allows you to set up your steps in terms of 2D positions, which then get converted to an internal 2D array. Each step consists of a Vector2 location (integers only for index), and a Texture. You should be able to expand on this if you want more functionality when changing steps.

    I added some public functions like "MoveBy" and "MoveTo" and "IsValidLocation" that you can hook your cubes up to.

    If it all works the way I'm imagining, your North cube will always call "MoveBy(0,1)", the East cube will call "MoveBy(1,0)", and so on. For cubes that lead nowhere and should be hidden, you can use "IsValidLocation" to see if there's anything in the next step. If not, hide the cube. If there is, show the cube.

    I admit I got a little carried away with it, but it was fun. Try it out and let me know if it makes sense to you.
    Code (CSharp):
    1. using System;
    2. using System.Collections.Generic;
    3. using System.Linq;
    4. using UnityEngine;
    5.  
    6. public class NavigationMap : MonoBehaviour
    7. {
    8.     // data container for each step
    9.     [Serializable] public class Step
    10.     {
    11.         [HideInInspector] public string inspectorName;
    12.         public bool startingLocation;
    13.         public Vector2 location;
    14.         public Texture skyTexture;
    15.     }
    16.  
    17.     #region Inspector
    18.  
    19.     // reference to SkySphere mesh, drag in or find on Awake
    20.     [SerializeField] private MeshRenderer skySphere;
    21.  
    22.     // setup the map in the inspector
    23.     [SerializeField] private List<Step> map;
    24.  
    25.     #endregion Inspector
    26.  
    27.     // Steps get converted to 2D array for easier use internally
    28.     public Step[,] Map { get; private set; }
    29.     public Step CurrentStep { get; private set; }
    30.     public int CurrentX { get; private set; }
    31.     public int CurrentY { get; private set; }
    32.  
    33.     private void Awake()
    34.     {
    35.         if(Map == null)
    36.         {
    37.             SetupMap();
    38.         }
    39.  
    40.         // start at the starting location, or 0,0
    41.         Step startStep = map.Find(step => step.startingLocation);
    42.         if(startStep == null) {
    43.             startStep = Map[0, 0];
    44.         }
    45.         SetStep(startStep);
    46.     }
    47.  
    48.     // moves by offset if valid location
    49.     public bool MoveBy(int x, int y)
    50.     {
    51.         int newX = (int)CurrentStep.location.x + x;
    52.         int newY = (int)CurrentStep.location.y + y;
    53.  
    54.         return MoveTo(newX, newY);
    55.     }
    56.  
    57.     // moves directly to new position if valid location
    58.     public bool MoveTo(int x, int y)
    59.     {
    60.         if(IsValidLocation(x, x))
    61.         {
    62.             SetStep(Map[x, x]);
    63.             return true;
    64.         }
    65.         return false;
    66.     }
    67.  
    68.     // check if a location is within the map dimensions
    69.     public bool IsValidLocation(int x, int y) {
    70.         bool validX = x > 0 && x < Map.GetLength(0);
    71.         bool validY = y > 0 && y < Map.GetLength(1);
    72.  
    73.         return validX && validY && Map[x, y] != null;
    74.     }
    75.  
    76.     // function to do whatever needs to be done on step change
    77.     private void SetStep(Step newStep)
    78.     {
    79.         CurrentStep = newStep;
    80.         CurrentX = Mathf.RoundToInt(newStep.location.x);
    81.         CurrentY = Mathf.RoundToInt(newStep.location.y);
    82.  
    83.         if(skySphere != null && CurrentStep.skyTexture != null) {
    84.             skySphere.material.mainTexture = CurrentStep.skyTexture;
    85.         }
    86.     }
    87.  
    88.     // build the map from the inspector values
    89.     private void SetupMap()
    90.     {
    91.         // get map dimensions by finding the maximum X and Y locations
    92.         int rows = Mathf.RoundToInt(map.Max(step => step.location.x)) + 1;
    93.         int columns = Mathf.RoundToInt(map.Max(step => step.location.y)) + 1;
    94.  
    95.         if(map.Count == 0)
    96.         {
    97.             return;
    98.         }
    99.  
    100.         // create Map 2D array of Steps
    101.         Map = new Step[rows, columns];
    102.  
    103.         // loop through each entry in the inspector
    104.         foreach(Step step in map)
    105.         {
    106.             // keep locations positive and round to ints
    107.             int x = Mathf.Max(0, Mathf.RoundToInt(step.location.x));
    108.             int y = Mathf.Max(0, Mathf.RoundToInt(step.location.y));
    109.  
    110.             step.location.x = x;
    111.             step.location.y = y;
    112.  
    113.             // check if the location already exists
    114.             Step stepAtLocation = Map[x, y];
    115.  
    116.             if(stepAtLocation == null)
    117.             {
    118.                 Map[x, y] = step;
    119.             }
    120.             else
    121.             {
    122.                 step.inspectorName = "[DUPLICATE] " + step.inspectorName;
    123.                 Debug.LogFormat("Duplicate Entry at ({0},{1}).", x, y);
    124.             }
    125.         }
    126.     }
    127.  
    128.     // called automatically any time the inspector changes
    129.     private void OnValidate()
    130.     {
    131.         int startingIndex = -1;
    132.  
    133.         // assign names to the inspector entries
    134.         for(int i = 0; i < map.Count; i++)
    135.         {
    136.             Step step = map[i];
    137.  
    138.             // if no start step has been encountered yet
    139.             // set this one as the start
    140.             if(step.startingLocation)
    141.             {
    142.                 if(startingIndex == -1)
    143.                 {
    144.                     startingIndex = i;
    145.                 }
    146.                 else
    147.                 {
    148.                     step.startingLocation = false;
    149.                 }
    150.             }
    151.  
    152.             string prefix = step.startingLocation ? "[START] " : string.Empty;
    153.             step.inspectorName = prefix + step.location.ToString();
    154.         }
    155.  
    156.         // build the
    157.         SetupMap();
    158.     }
    159. }
     
    Last edited: Jun 9, 2017
    amoeboar likes this.
  18. amoeboar

    amoeboar

    Joined:
    Nov 30, 2015
    Posts:
    23
    This is fantastic. I will comb over this thoroughly and give it a try!

    What should this script be attached to?

    THANK YOU!!
     
  19. LiterallyJeff

    LiterallyJeff

    Joined:
    Jan 21, 2015
    Posts:
    2,807
    If you add that script to an empty gameobject, it should just work. Think of it as a big data container and grid manager of sorts. You can do a FindObjectOfType<NavigationMap>() to get a reference to it in other scripts on Awake.

    Hopefully there are no bugs, and feel free to ask questions if anything doesn't make sense to you.
     
    amoeboar likes this.
  20. shrutisingh25

    shrutisingh25

    Joined:
    Sep 15, 2017
    Posts:
    2
    Hey
    Can you share your code.