Массив объектов. Проблемка у чайника по Unity ))

Форум для самых маленьких, а так же тех, кому недосуг читать справку самостоятельно.

Массив объектов. Проблемка у чайника по Unity ))

Сообщение xazratbek 16 фев 2013, 21:16

У меня есть квадрат 8х8, т.е. 64 ячейки. Нужно сделать так, что если я нажму на какой-нибудь квадратик, и если он пуст, то прога должна поставить туда шарик случайного цвета, а если квадратик не пуст, то прога должна удалить с поля все шарики, цвет которого одинаков с данным. Я создал GameObject - Plane, накинул туда как Asset эту самую шахматную доску. Потом начал писать скрипт... Я всего лишь 6 дней в Unity и почти не знаю C#, разве что базовые конструкции и выражения. Посмотрите мой код. Верно ли я иду? И как мне поступить далее?
Синтаксис:
Используется csharp
using UnityEngine;
using System.Collections;

public class NewBehaviourScript : MonoBehaviour {
        public GameObject[] sphere;
        Vector3 SpherePosition;
        string s;
        // Use this for initialization
        void Start () {
       
        }
       
        // Update is called once per frame
        void Update () {
        if(Input.GetMouseButton(0))
                {
                RaycastHit hit;//создаем новую точку соприкосновения луча (назовем это так, хотя возможно правильно это обозвать подругому)
                Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);                 //и сам луч, который будет направлен от курсора мыши вглубь экрана
        if(Physics.Raycast(ray, out hit, Mathf.Infinity))                //если созданный луч соприкоснулся с объектом                
        {
                                s=renderer.material.GetColor (); // правильно ли я написал это?
                        for (int i=0;i<64;i++){
                                                if (renderer.material.color==s){   //тут должно быть, что если цвет этого объекта, т.е. сферы, совпадает с цветом тапнутого шарика, то он должен удалиться
                                                Destroy (GameObject[i]);}}
        }
                       
                else {//В противном случае в тапнутой клетке надо создать шарик случайного цвета
                        }      

}
        }
        }
}

Помогите разобраться, плиз
xazratbek
UNец
 
Сообщения: 13
Зарегистрирован: 16 фев 2013, 21:05

Re: Массив объектов. Проблемка у чайника по Unity ))

Сообщение lawson 16 фев 2013, 21:17

пожалуйста учитесь писать так чтобы ваш код был читаем - на будущее.
lawson
UNIверсал
 
Сообщения: 481
Зарегистрирован: 14 сен 2012, 21:20

Re: Массив объектов. Проблемка у чайника по Unity ))

Сообщение igoryan 17 фев 2013, 00:45

Делаешь 2 префаба (надеюсь знаешь как), первый - ГО клетки(незабудь накинуть Rigidbody, и тег), второй - ГО сферы.
В цикле Instantiate' ом устанавливаешь 64 обьекта типа клетка(используя первый префаб).
Далее, по Ray' ю ищешь клетку, проверяешь наличие у нее дочернего ГО типа сфера.
Если ГО сферы нет, значить Instantiate + Parent тебе в помощь(+ материал колор рандом), если есть, то в цикле пробегаешь по всем ГО клеткам, с проверкой наличия дочерних ГО сфер с таким же материалом и при обнаружении таковых, соответствующие действия с ними.
Самая популярная игра жанра квест называется "Где второй носок"
Аватара пользователя
igoryan
UNITрон
 
Сообщения: 174
Зарегистрирован: 16 сен 2012, 19:35
Откуда: Азов

Re: Массив объектов. Проблемка у чайника по Unity ))

Сообщение xazratbek 17 фев 2013, 11:09

igoryan писал(а):Делаешь 2 префаба (надеюсь знаешь как), первый - ГО клетки(незабудь накинуть Rigidbody, и тег), второй - ГО сферы.
В цикле Instantiate' ом устанавливаешь 64 обьекта типа клетка(используя первый префаб).
Далее, по Ray' ю ищешь клетку, проверяешь наличие у нее дочернего ГО типа сфера.
Если ГО сферы нет, значить Instantiate + Parent тебе в помощь(+ материал колор рандом), если есть, то в цикле пробегаешь по всем ГО клеткам, с проверкой наличия дочерних ГО сфер с таким же материалом и при обнаружении таковых, соответствующие действия с ними.

Я нашел, как создать префаб, но как сделать ГО клетки, ГО сферы не знаю... Цикл Instantiate тоже не знаю (( Искать по Ray'ю тоже не умею... Если не трудно, опишите все с самого начала, пожалуйста! Я полный новичок тут...
xazratbek
UNец
 
Сообщения: 13
Зарегистрирован: 16 фев 2013, 21:05

Re: Массив объектов. Проблемка у чайника по Unity ))

Сообщение igoryan 19 фев 2013, 20:56

1.Вопрос: Как сделать GameObject клетки?
Ответ: В Unity > GameObject > CreateOther > Cube
(в окне Inspector параметр Scale X=1, Y=0.01, Z=1)

2.Вопрос: Как сделать GO сферы?
Ответ: В Unity > GameObject > CreateOther > Sphere
(в окне Inspector параметр Scale X,Y,Z по вкусу)

3.Вопрос: Как из GO сделать Prefab?
Ответ: В окне Project ПК мышки Create > Prefab. Далее, из окна Hierarchy перетаскиваешь GO в префаб, и ... он готов!

4.Вопрос: Как создать цикл?
Ответ: Конструкция типа -
For(i=0; i<8; i++){
For(j=0; j<8; j++){
....................
}
}
(Вложенный цикл для получения 8 строк из 8 ячеек каждая)

5.Вопрос: Как создать объект в сцене из префаба?
Ответ: Unity3D > Help > Scripting Reference > находим Object.Instantiate > читаем, смотрим примеры, Promt use при необходимости.
6.Вопрос: Как найти объект на сцене с помощью Ray?
Ответ: похож на ответ в 5 вопросе, только ищешь Physics.Raycast.
Ну а дальше все просто, по алгоритму, описанному в моем посте выше!
(ну конечно не забывая Гугл, this.forum, Scripting Reference и т.д.)

ps К сожалению, все это прийдется пройти самому, ибо писать тебе скрипты если и будут, то за бабосики! :-B

pps Сам из новичков, С#, да и вообще ООП изучаю недавно, все как-то по Basic' у да по Pascal' ю носило.
ppps Начинал с просмотра видеоуроков от OGASODA, за что ему ОХРОМЕННЫЙ РЕСПЕКТ!
Самая популярная игра жанра квест называется "Где второй носок"
Аватара пользователя
igoryan
UNITрон
 
Сообщения: 174
Зарегистрирован: 16 сен 2012, 19:35
Откуда: Азов

Re: Массив объектов. Проблемка у чайника по Unity ))

Сообщение extravert 21 фев 2013, 09:57

Вот три скрипта. Не самые короткие по коду и не самые быстрые, но и не для себя делаю.

Создаешь объект клетка (меню GameObject -> Cube) у которой scale(размер) - x = 1, y = 1, z = 0.01
Добавляешь ей компонент rigidbody
Кидаешь на него этот скрипт:
Синтаксис:
Используется csharp
public class Cell : MonoBehaviour //Этот скрипт вешается на префаб квадрата. Можно конечно просто выставить у ГО клетки тег и тогда проверку изменить на тег
{
    public Sphere Sphere;
}
 

Сохраняешь в префаб. Где нибудь в папке. Со сцены удалить можно после этого.

Создаешь объект сфера(меню GameObject -> Sphere) у которой scale(размер) - x = 1, y = 1, z = 0.01
Добавляешь ей любой материал.
Кидаешь на нее этот скрипт:
Синтаксис:
Используется csharp
public class Sphere : MonoBehaviour
{
    private const int CountColor = 3;
    public Color? Color;
    //Свойства твоей сферы

    public void Awake()
    {
        Color = RandomColor();
        renderer.material.SetColor("_Color", Color ?? new Color(0,0,0));
    }

    private static Color RandomColor()
    {
        var random = new System.Random().Next(CountColor);
        switch (random)
        {
            case 0: return new Color(0,0,0);
            case 1: return new Color(255,255,255);
            case 2: return new Color(0,255,0);
            default: return new Color(0,0,0);
        }
    }
}

Сохраняешь в префаб. Где нибудь в папке. Со сцены удалить можно после этого.

На объект камеры кидаешь этот скрипт:
Синтаксис:
Используется csharp
public class YourCore : MonoBehaviour
{
    public Cell CellPrototype;      //В самом редакторе сюда нужно будет вставить "клетку-квадрат"
    public Sphere SpherePrototype;  //А сюда твою сферу.

    private const int XCount = 8;
    private const int YCount = 8;
    private readonly Cell[,] cells = new Cell[XCount,YCount];

    private void Start()
    {
        /*Создает все твои клетки по осям (х, у).
         * Если у тебя объекты ориентируются на другую плоскость -
         * переставь ноль на одну из двух других позиций */

        for (var x = 0; x < XCount; x++)
            for (var y = 0; y < YCount; y++)
            {
                var obj = (Transform)Instantiate(CellPrototype, new Vector3(x, y, 0), Quaternion.identity);
                cells[x, y] = obj.GetComponent<Cell>();
            }
    }

    private void Update()
    {
        if (Input.GetMouseButton(0))
        {
            RaycastHit hit;
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            if (Physics.Raycast(ray, out hit, Mathf.Infinity) && hit.transform != null)
            {
                //Цикл по всем ячейкам
                foreach (var cell in cells)
                {
                    //Если это ячейка на которую нажали
                    if (cell.gameObject == hit.transform.gameObject)
                    {
                        //Если сферы нет, создаем новую
                        if (cell.Sphere == null)
                        {
                            var obj = (Transform)Instantiate(SpherePrototype, cell.transform.position, Quaternion.identity);
                            cell.Sphere = obj.GetComponent<Sphere>();
                        }
                        //Иначе удаляем все сферы этого цвета
                        else
                        {
                            foreach (var c in cells)
                            {
                                if (c.Sphere.Color == cell.Sphere.Color)
                                {
                                    c.Sphere.Color = null;
                                    Destroy(c.gameObject);
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

Нажимаешь на камеру. Там будет два поля. Соответственно кидаешь префаб клетки из папки куда сохранял в поле CellPrototype. А префаб сферы в SpherePrototype.
Запускаешь.
Исправляешь мелкие баги, если возникли.
Игра готова к продаже.
Аватара пользователя
extravert
UNIверсал
 
Сообщения: 465
Зарегистрирован: 24 дек 2012, 11:54

Re: Массив объектов. Проблемка у чайника по Unity ))

Сообщение xazratbek 24 фев 2013, 20:58

extravert писал(а):Вот три скрипта. Не самые короткие по коду и не самые быстрые, но и не для себя делаю.

Создаешь объект клетка (меню GameObject -> Cube) у которой scale(размер) - x = 1, y = 1, z = 0.01
Добавляешь ей компонент rigidbody
Кидаешь на него этот скрипт:
Синтаксис:
Используется csharp
public class Cell : MonoBehaviour //Этот скрипт вешается на префаб квадрата. Можно конечно просто выставить у ГО клетки тег и тогда проверку изменить на тег
{
    public Sphere Sphere;
}
 

Сохраняешь в префаб. Где нибудь в папке. Со сцены удалить можно после этого.

Создаешь объект сфера(меню GameObject -> Sphere) у которой scale(размер) - x = 1, y = 1, z = 0.01
Добавляешь ей любой материал.
Кидаешь на нее этот скрипт:
Синтаксис:
Используется csharp
public class Sphere : MonoBehaviour
{
    private const int CountColor = 3;
    public Color? Color;
    //Свойства твоей сферы

    public void Awake()
    {
        Color = RandomColor();
        renderer.material.SetColor("_Color", Color ?? new Color(0,0,0));
    }

    private static Color RandomColor()
    {
        var random = new System.Random().Next(CountColor);
        switch (random)
        {
            case 0: return new Color(0,0,0);
            case 1: return new Color(255,255,255);
            case 2: return new Color(0,255,0);
            default: return new Color(0,0,0);
        }
    }
}

Сохраняешь в префаб. Где нибудь в папке. Со сцены удалить можно после этого.

На объект камеры кидаешь этот скрипт:
Синтаксис:
Используется csharp
public class YourCore : MonoBehaviour
{
    public Cell CellPrototype;      //В самом редакторе сюда нужно будет вставить "клетку-квадрат"
    public Sphere SpherePrototype;  //А сюда твою сферу.

    private const int XCount = 8;
    private const int YCount = 8;
    private readonly Cell[,] cells = new Cell[XCount,YCount];

    private void Start()
    {
        /*Создает все твои клетки по осям (х, у).
         * Если у тебя объекты ориентируются на другую плоскость -
         * переставь ноль на одну из двух других позиций */

        for (var x = 0; x < XCount; x++)
            for (var y = 0; y < YCount; y++)
            {
                var obj = (Transform)Instantiate(CellPrototype, new Vector3(x, y, 0), Quaternion.identity);
                cells[x, y] = obj.GetComponent<Cell>();
            }
    }

    private void Update()
    {
        if (Input.GetMouseButton(0))
        {
            RaycastHit hit;
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            if (Physics.Raycast(ray, out hit, Mathf.Infinity) && hit.transform != null)
            {
                //Цикл по всем ячейкам
                foreach (var cell in cells)
                {
                    //Если это ячейка на которую нажали
                    if (cell.gameObject == hit.transform.gameObject)
                    {
                        //Если сферы нет, создаем новую
                        if (cell.Sphere == null)
                        {
                            var obj = (Transform)Instantiate(SpherePrototype, cell.transform.position, Quaternion.identity);
                            cell.Sphere = obj.GetComponent<Sphere>();
                        }
                        //Иначе удаляем все сферы этого цвета
                        else
                        {
                            foreach (var c in cells)
                            {
                                if (c.Sphere.Color == cell.Sphere.Color)
                                {
                                    c.Sphere.Color = null;
                                    Destroy(c.gameObject);
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

Нажимаешь на камеру. Там будет два поля. Соответственно кидаешь префаб клетки из папки куда сохранял в поле CellPrototype. А префаб сферы в SpherePrototype.
Запускаешь.
Исправляешь мелкие баги, если возникли.
Игра готова к продаже.


Огромное спасибо Вам! Все написано очень доступно и просто :) Возникло несколько ошибок, я многие, вроде бы, исправил, только одну не смог... Посмотрите, пожалуйста, в чем может быть ошибка. Я сделал все так, как вы и говорили.
if (cell.Sphere == null)
{
var obj = (Transform)Instantiate (SpherePrototype,cell.transform.position,Quaternion.identity);
cell.Sphere=obj.GetComponent<Sphere>();
}
Выходит ошибка "Cannot implicitly convert type 'Sphere' to 'UnityEngine.Rigidbody'". Помогите, пожалуйста, в чем может быть ошибка?
xazratbek
UNец
 
Сообщения: 13
Зарегистрирован: 16 фев 2013, 21:05


Вернуться в Почемучка

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 28