0

I'm trying to create the board game Hex. Player One at the bottom being yellow and Player Two at the top being blue. When Player One clicks a hex it should become yellow and when Player two clicks a hex it should become blue.

I've created this Hex Map using a prefab and now I want to be able to change the color of each tile when I click on it (The yellow hexes you see will be transparent but the sprite I imported is yellow which is why the color on the Sprite Renderer is white even though the hexes look yellow).

Btw, as of right now changing the color in the Sprite Renderer changes the color of all the hexes.

I followed quill18creates's tutorial to make the Hex Map except I did it in 2D instead of 3D.

https://www.youtube.com/watch?v=j-rCuN7uMR8

enter image description here

As of write now my Color Change script isn't working at all. I was trying to have it so when it receives one click it changes to yellow. Then the next click to blue, the next to yellow, and so on. Since each player only get's one click.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ColorChange : MonoBehaviour {

    public Color[]colors; // allows input of material colors in a set sized array
    public SpriteRenderer rend;  // what are we rendering? the hex

    private int index = 1; //initialize at 1, otherwise you have to press the ball twice to change color


    // Use this for initialization
    void Start () {
        rend = GetComponent<SpriteRenderer> (); // gives functionality for the renderer
    }

    // Update is called once per frame
    void onMouseDown () {
        // if there are no colors present nothing happens
        if (colors.Length == 0){
            return;
        }

       if (Input.GetMouseButtonDown(0)){
           index += 1; // when mouse is pressed down we increment up to the next index location

           // when it reaches the end of the colors it stars over
           if (index == colors.Length +1){
               index = 1;
           }

        print (index); // used for debugging
        rend.color = colors [index - 1]; // this sets the material color values inside the index
       }
   } //onMouseDown
}

How should I go about implementing this? Any help would be much appreciated!

Jon
  • 43
  • 1
  • 6
  • [OnMouseDown()](https://docs.unity3d.com/ScriptReference/MonoBehaviour.OnMouseDown.html) has to be properly capitalized to work. You also don't need to check `Input.GetMouseButtonDown` since it's in `OnMouseDown`. Also, `OnMouseDown` requires a GUIElement or Collider; your object seems to have neither – Foggzie Mar 18 '19 at 22:57
  • Possible duplicate of [How to detect click/touch events on UI and GameObjects](https://stackoverflow.com/questions/41391708/how-to-detect-click-touch-events-on-ui-and-gameobjects) – Hellium Mar 18 '19 at 22:59
  • @Foggzie I saw a video on youtube of someone just clicking a 3d gameobject and changing it's material. That's essentially what I want to do with a 2d sprite and its color. I think my issue is that I generated a hex map instead and need to change individual hexes within it but I'm not sure. Here's the video I mentioned: https://www.youtube.com/watch?v=6zNHaLdVk80&t=206s – Jon Mar 19 '19 at 03:17
  • Hexprefab is what kind of object ? is that any button? or any UI Elements that can able to take clickes ? – Jasil Mar 19 '19 at 04:58
  • Foggzie already gave you the answer. Add a 2D collider for starters. – Reasurria Mar 19 '19 at 05:15
  • @Jon Yes, the example in that video works because they have a collider on the object being clicked; they also properly capitalized `OnMouseDown()`. – Foggzie Mar 19 '19 at 17:07

2 Answers2

1

First things first, you need to properly capitalize OnMouseDown() for it to get called.

After that, since you're using a SpriteRenderer, you'll need to add a collider to detect mouse click events. As mentioned in the OnMouseDown() documentation:

This event is sent to all scripts of the Collider or GUIElement.

Since you have neither, on your prefab, click Add Component > Polygon Collider 2D and it'll automatically create the proper geometry for your sprite (assuming that everything outside the hex is transparent).

Finally, remove your check against Input.GetMouseButtonDown(0). OnMouseDown is already capturing the fact that the mouse was clicked and the specific instance running OnMouseDown() was the instance that was clicked.

Foggzie
  • 9,691
  • 1
  • 31
  • 48
  • 1
    Awesome! Adding the collider worked! However, do you know how I can alternate each color? Right now every hex tile I click, it changes to blue, then if I click the same tile again it changes yellow (which is what I should have expected). But how would I change it so if I click a tile, it changes to blue, and when I click the next tile, it changes to yellow? – Jon Mar 19 '19 at 20:38
  • @Jon To be clear, you want to implement something like a "selection" mechanic? Where only 0 or 1 tiles are blue at any given point (the "selected" tile)? You mention multiple players in your question at the top; is there a "yellow" player and "blue" player? – Foggzie Mar 19 '19 at 20:44
  • 1
    Yeah, there is a yellow player and a blue player, so when the blue player goes I want the tile to change to blue and when the yellow player goes the tile should change to yellow. The aim of the game is to create a line to reach from one side to the other. – Jon Mar 19 '19 at 20:51
  • @Jon Then you'll need some way `ColorChange` can detect who is clicking on it. You can give it a `public static Color CurrentPlayerColor` property that's set from an external source. Or you can have an object somewhere in a parent that has a publicly exposed field regarding the current player's information and use `GetComponentInParent<>` to reference that component and access its data. – Foggzie Mar 19 '19 at 22:38
  • Either way, if you'd like a thorough answer on that, you'll probably need to make a new question. Issues should be isolated in their own question so historical data is better preserved; this question could serve as a good resource for anyone with `OnMouseDown` issues. Managing a "current player" is it's own separate problem space. – Foggzie Mar 19 '19 at 22:40
  • 1
    Ok, great I'll do that. Thanks so much for your help! – Jon Mar 24 '19 at 21:41
0

add collider and rigid body to your prefab then capital O in OnMouseDown and delete "if (Input.GetMouseButtonDown(0)){" Input.GetMouseButtonDown(0) return true when player click anywhere which is not what you want

public Color[] colors; // allows input of material colors in a set sized array
    public SpriteRenderer rend;  // what are we rendering? the hex

    private int index = 1; //initialize at 1, otherwise you have to press the ball twice to change color


    // Use this for initialization
    void Start()
    {
        rend = GetComponent<SpriteRenderer>(); // gives functionality for the renderer
    }

    // Update is called once per frame
    void OnMouseDown()
    {
        // if there are no colors present nothing happens
        if (colors.Length == 0)
        {
            return;
        }


            index += 1; // when mouse is pressed down we increment up to the next index location

            // when it reaches the end of the colors it stars over
            if (index == colors.Length + 1)
            {
                index = 1;
            }

            print(index); // used for debugging
            rend.color = colors[index - 1]; // this sets the material color values inside the index

    } //onMouseDown