Как изменить цвет игрового объекта при нажатии в Unity?

Пытаюсь создать настольную игру Hex. Первый игрок внизу желтого цвета, а второй игрок вверху - синего цвета. Когда Игрок 1 щелкает гексагон, он должен стать желтым, а когда Игрок 2 щелкает гексагон, он должен стать синим.

Я создал эту шестнадцатеричную карту, используя префаб, и теперь я хочу иметь возможность изменять цвет каждой плитки, когда я нажимаю на нее (желтые шестиугольники, которые вы видите, будут прозрачными, но спрайт, который я импортировал, желтый, поэтому цвет на Sprite Renderer белый, хотя гексы выглядят желтыми).

Кстати, на данный момент изменение цвета в Sprite Renderer меняет цвет всех гексов.

Я следовал руководству quill18creates, чтобы создать шестнадцатеричную карту, за исключением того, что сделал это в 2D, а не в 3D.

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

введите описание изображения здесь

На момент написания мой скрипт смены цвета вообще не работает. Я пытался сделать так, чтобы при одном щелчке он становился желтым. Затем следующий щелчок будет синим, следующий - желтым и так далее. Поскольку каждый игрок получает только один щелчок.

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
}

Как мне это реализовать? Любая помощь приветствуется!


person Jon    schedule 18.03.2019    source источник
comment
Для работы OnMouseDown () необходимо правильно использовать заглавные буквы. Вам также не нужно проверять Input.GetMouseButtonDown, так как он находится в OnMouseDown. Также OnMouseDown требует GUIElement или Collider; у вашего объекта нет ни того, ни другого   -  person Foggzie    schedule 19.03.2019
comment
@Foggzie Я видел на YouTube видео, где кто-то просто щелкает трехмерный игровой объект и меняет его материал. По сути, это то, что я хочу сделать с двухмерным спрайтом и его цветом. Я думаю, что моя проблема в том, что вместо этого я создал шестнадцатеричную карту и мне нужно изменить в ней отдельные шестиугольники, но я не уверен. Вот упомянутое мной видео: youtube.com/watch?v=6zNHaLdVk80&t=206s   -  person Jon    schedule 19.03.2019
comment
Hexprefab - это что за объект? это какая-нибудь кнопка? или любые элементы пользовательского интерфейса, которые могут выполнять щелчки мышью?   -  person Jasil    schedule 19.03.2019
comment
Фоггзи уже дал вам ответ. Для начала добавьте 2D-коллайдер.   -  person Reasurria    schedule 19.03.2019
comment
@Jon Да, пример в том видео работает, потому что у них есть коллайдер на объекте, по которому щелкают; они также правильно написали OnMouseDown() с заглавной буквы.   -  person Foggzie    schedule 19.03.2019


Ответы (2)


Прежде всего, вам необходимо правильно использовать OnMouseDown() для вызова с заглавной буквы.

После этого, поскольку вы используете SpriteRenderer, вам нужно добавить коллайдер для обнаружения событий щелчка мыши. Как упоминалось в OnMouseDown() документации:

Это событие отправляется во все скрипты Коллайдера или GUIElement.

Поскольку у вас их нет, в вашем префабе нажмите Добавить компонент> Polygon Collider 2D, и он автоматически создаст правильную геометрию для вашего спрайта (при условии, что все за пределами шестиугольника прозрачно).

Наконец, снимите чек с Input.GetMouseButtonDown(0). OnMouseDown уже фиксирует тот факт, что щелкнули мышью, и конкретный запущенный экземпляр OnMouseDown() был экземпляром, который был нажат.

person Foggzie    schedule 19.03.2019
comment
Потрясающий! Добавление коллайдера сработало! Однако знаете ли вы, как я могу чередовать каждый цвет? Прямо сейчас каждая шестиугольная плитка, которую я щелкаю, становится синей, а затем, если я снова нажимаю ту же плитку, она меняет цвет на желтый (чего я и ожидал). Но как мне изменить его, чтобы если я щелкнул плитку, он стал синим, а когда я щелкнул следующую плитку, он стал желтым? - person Jon; 19.03.2019
comment
@Jon Для ясности, вы хотите реализовать что-то вроде механики выбора? Где только 0 или 1 плитка синего цвета в любой заданной точке (выбранной плитке)? Вы упоминаете нескольких игроков в своем вопросе вверху; есть желтый игрок и синий игрок? - person Foggzie; 19.03.2019
comment
Да, есть желтый игрок и синий игрок, поэтому, когда синий игрок уходит, я хочу, чтобы плитка изменилась на синий, а когда желтый игрок уйдет, плитка должна измениться на желтый. Цель игры состоит в том, чтобы создать линию, чтобы пройти от одной стороны до другой. - person Jon; 19.03.2019
comment
@Jon Тогда вам понадобится способ ColorChange определить, кто нажимает на него. Вы можете присвоить ему свойство public static Color CurrentPlayerColor, которое устанавливается из внешнего источника. Или вы можете иметь объект где-нибудь в родительском элементе, который имеет публично открытое поле, касающееся информации о текущем проигрывателе, и использовать GetComponentInParent<> для ссылки на этот компонент и доступа к его данным. - person Foggzie; 20.03.2019
comment
В любом случае, если вы хотите получить исчерпывающий ответ на этот вопрос, вам, вероятно, придется задать новый вопрос. Проблемы должны быть выделены в отдельный вопрос, чтобы лучше сохранить исторические данные; этот вопрос может послужить хорошим источником для всех, у кого OnMouseDown проблемы. Управление текущим игроком - это отдельная отдельная проблемная область. - person Foggzie; 20.03.2019
comment
Хорошо, я сделаю это. Большое спасибо за Вашу помощь! - person Jon; 25.03.2019

добавьте коллайдер и твердое тело в свой префаб, затем заглавную O в OnMouseDown и удалите "if (Input.GetMouseButtonDown (0)) {" Input.GetMouseButtonDown (0) вернет true, когда игрок щелкнет в любом месте, что не то, что вы хотите

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
person Peyman Ansary    schedule 19.03.2019
comment
Вам не нужен RigidBody, он здесь ничего не сделает. - person Foggzie; 19.03.2019