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 /
  • Help Room /
avatar image
1
Question by huxley443 · Sep 29, 2015 at 05:35 PM · gridselectionhow-tobestpracticeshexagon

Multiple Hex placement grid

Hello, Noob here. I have a 2d project where I want to create a hex grid for unit placement. Currently I have a script that creates a hex mesh and then uses that mesh to create a hex grid.

I also implemented a mouse over color change. Which worked great. Then I switched it from reacting to the mouse pointer to reacting to a single hex I moved with the mouse. Again, worked great.

But what I really want is for it to react to multiple hexes, as the units will have varying sizes. Smallest unit may be 1 hex but a larger unit might take 3 or 7 hexes of space. At my current level of Unity noobness I can't figure out how to do this, nor the best way to go about it.

Currently I am applying a script to each individual grid hex that checks for a raycast and changes the color. This was based on an example I found to do the mouse over.

My idea was to create a group of 'selection hexes' that matched the size of the unit and as I move it around it would highlight a legitimate location to place it (i.e. unit size 7 finds 7 empty hexes). No idea if this is the way to go about it and currently what I have doesn't work anyway. I just took my working single example and put it in a loop. But, again, it doesn't work, it just highlights 1 hex at a time.

Any advice on how to best implement this? Best practices?

Code attached to hexes in the grid:

 using UnityEngine;
 
 [RequireComponent(typeof(Collider))]
 public class GridHex : MonoBehaviour {
     Color normalColor;
     GameObject[] selectors;
     //public Transform selectionObject;
 
     void Awake() {
         selectors = GameObject.FindGameObjectsWithTag("selectortile");
         //selectionObject = GameObject.Find("HexagonSelectorTile").transform;
     }
 
     void Start() {
         normalColor = GetComponent<Renderer>().material.color;
     }
 
     void Update () {
         foreach (GameObject selector in selectors) {
             //Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
             //Ray ray = new Ray(selectionObject.position, Vector3.forward);
             Ray ray = new Ray(selector.transform.position, Vector3.forward);
             RaycastHit hitInfo;
     
             Debug.DrawRay(ray.origin, ray.direction, Color.green);
             if (GetComponent<Collider>().Raycast(ray, out hitInfo, Mathf.Infinity)) {
                 GetComponent<Renderer>().material.color = UnityEngine.Color.red;
             } else {
                 GetComponent<Renderer>().material.color = normalColor;
             }            
         }
     }
 }


What it looks like: hexselect

hex.png (39.8 kB)
Comment
Add comment · Show 1
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 Zypherr7 · Oct 02, 2015 at 08:52 PM 0
Share

Alright. Good luck!

2 Replies

· Add your reply
  • Sort: 
avatar image
0

Answer by Zypherr7 · Sep 30, 2015 at 01:01 AM

I see what you are trying to do and I may be able to help. There is a formula you can use that, when the width and length of the tile is entered, can calculate a world coordinate, into a hex based coordinate, and back again if you wished. I have actually built a method to do so, but it is slightly confusing just to enter into here. I am going to suggest you use the initial coordinate to find the hexs around it. The offset you need would be on the y, .75*height, and for the x, it would be width\2 every other tile.

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 huxley443 · Sep 30, 2015 at 12:55 PM 0
Share

Thanks, this has given me something to think about.

avatar image Zypherr7 · Oct 02, 2015 at 10:39 AM 0
Share

Ok, so I had a little more time to work on this, so, if you wanted to find the six tiles around the original one, you would be looking at tiles relative to it either (-1,0), (1,0), (0,1), (1,1), (0,-1), (1,-1); or you would be looking for (-1,0), (1,0), (0,1), (-1,1), (0,-1), (-1,-1). It would just depend on the offset of the initial tile. If it was on a row with tiles further left, it would be the first one. If it was on a row with the tiles further to the right, it would be the second group. Based off of that, you would then have to find the position of the origin tile to find the ones around it. The code would be something like this.

 vector2 tile1;
 vector2 tile2;
 vector2 tile3;
 vector2 tile4;
 vector2 tile5;
 vector2 tile6;
 
 //tile width and length
 double tileWidth;
 double tileHeight;
 
 public void findSurroundingTiles(vector2 origin){
        //to find tile left
        tile1.x = orgin.x + (-1 * coordinateTransferX(tileWidth, tileHeight).x);
        tile1.y = orgin.y + (0 * coordinateTransferX(tileWidth, tileHeight).y);
        //to find tile above
        tile2.x = orgin.x + (0 * coordinateTransferY(tileWidth, tileHeight).x);
        tile2.y = orgin.y + (1 * coordinateTransferY(tileWidth, tileHeight).y);
 }
 
 //finds coordinate of tile on same offset compared to origin
 public vector2 coordinateTransferX(double width, double height){
       vector2 temp.x = width;
       temp.y = height;
       return temp;
 }
 
 //finds coordinate of tile on offset compared to origin
 public vector2 coordinateTransferY(double width, double height){
        vector2 temp.x = width * .75;
        temp.y = height / 2;
        return temp;
 }

Now, this code should work for what you are trying to do, if you can find objects based on their location. Also, you have to take into fact that an offset may be left or right. I cannot think of anything that could fix that off the top of my head. Also, on a side note, this may not compile properly if copied and pasted directly into scripts because I wrote this directly into the comment, and may have messed up some syntax.
If you need any help you can email me at zypherr7@gmail.com, I will be glad to help with any questions.

avatar image huxley443 · Oct 02, 2015 at 03:41 PM 0
Share

Thanks @Zypherr7. Your previous comment had me thinking that ins$$anonymous$$d of the multiple raycast method I should just find the hex my mouse was over and then find the adjacent hexes. Yesterday I ran through this $$anonymous$$inesweeper tutorial to see how they did it. I not sure I'm a big fan of how they did their Grid data class, but it did make me realize I need a data class of some kind. Barring any other examples though I'll try to semi-clone what they did in that tut and modify it for hex and just basic detection.

Combined with your code example I'm sure I can hack something together, though I doubt the data class will follow any kind best practice. I'll report back on my progress...

avatar image
0

Answer by huxley443 · Oct 05, 2015 at 11:38 PM

Well I got this working, but I think it's pretty ugly. I'm not sure I'm passing data back & forth in a good way. And I'm not happy using OnMouseOver & OnMouseExit. I tried some OnCollision events but couldn't make them work.

Anyway, there's a lot going on, but it boils down to this. In a Grid class I have:

     public List<GridTile> GetAdjacentTiles(Vector2 pPosition) {
         int x = (int)pPosition.x;
         int y = (int)pPosition.y;
         int w = gridWidthInHexes - 1;
         int h = gridHeightInHexes - 1;
 
        List<GridTile> Adjacents = new List<GridTile>();
        
        if (x > 0) {
             Adjacents.Add(hexes[x-1,y].GetComponent<GridTile>());
         }
         if (x < w) {
             Adjacents.Add(hexes[x+1,y].GetComponent<GridTile>());
         }
         if (y > 0) {  //the two above
             if (y % 2 == 0) { //even row
                 Adjacents.Add(hexes[x, y - 1].GetComponent<GridTile>());
                 if (x != 0) Adjacents.Add(hexes[x - 1,y - 1].GetComponent<GridTile>());
             } else { //odd rows
                 Adjacents.Add(hexes[x,y - 1].GetComponent<GridTile>());
                 if (x < w) Adjacents.Add(hexes[x + 1,y - 1].GetComponent<GridTile>());
             }
         }
         if (y < h) {  //the two below
             if (y % 2 == 0) { //even row
                 Adjacents.Add(hexes[x, y + 1].GetComponent<GridTile>());
                 if (x != 0) Adjacents.Add(hexes[x - 1,y + 1].GetComponent<GridTile>());
             } else { //odd rows
                 Adjacents.Add(hexes[x,y + 1].GetComponent<GridTile>());
                 if (x < w) Adjacents.Add(hexes[x + 1,y + 1].GetComponent<GridTile>());
             }            
         }          
         return Adjacents;
     }

And In a Tile class I have:

     void OnMouseOver() {
         this.IsSelected = true;
         
         List<GridTile> adjecentTiles = gridMap.GetAdjacentTiles(myGridPosition);
         
         foreach (GridTile gt in adjecentTiles) {
             gt.IsSelected = true;
             gt.SetVisual();
         }
     }
     void OnMouseExit() {
         this.IsSelected = false;
         
         List<GridTile> adjecentTiles = gridMap.GetAdjacentTiles(myGridPosition);
         
         foreach (GridTile gt in adjecentTiles) {
             gt.IsSelected = false;
             gt.SetVisual();
         }        
     }

Which results in this as I move my mouse around: alt text


hexgrid.png (127.5 kB)
Comment
Add comment · 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

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

30 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

Related Questions

Instantiate GameObjects in a Sphere shape 2 Answers

Hexagon grid check for specific tile 0 Answers

Hexagonal geodesic map 0 Answers

Keeping track of dynamic positions of items in a grid using List/Array? 0 Answers

Difference between Mesh, nested arrays and terrain 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