Кубик Рубика

Программирование на Юнити.

Кубик Рубика

Сообщение mikita 07 апр 2012, 17:42

Всем здравствуйте.
С некоторых пор решил опять взяться за изучение Unity. Для пробы решил сделать простую (как мне тогда ошибочно казалось) программку - Кубик Рубика.
Уж сколько я с ним намучался - это отдельная история. На данном этапе реализовано так:
1. Есть набор кубиков, составляющих, собственно, цельный куб.\
2. В центре есть главный кубик, который временно становится родителем для определенных кубиков. Поворачивается сам и поворачивает чилдренов.
3. Над каждой стороной куба размещено 6 плоскостей (каждая из которых состоит из 9 отдельных малых плоскостей), у которых отключен рендер (на рисунке отображено, как это выглядит в редакторе).
.PNG

Теперь главное. Я перепробовал массу вариантов реализации поворотов, и все время упирался в какую-то нерешимую проблему. В данный момент это реализовано так:
4. Для поворота нужно кликнуть на один из кубиков и протащить курсор на другой (на самом деле клик попадает в плоскость). Исходя из этого действия, определяется, в какую сторону будет крутиться центральный кубик, а так же то, каких кубиков он станет парентом на время поворота. Поворот реализован на 6 анимациях, которых были подготовлены прямо в редакторе.
5. После поворота центральных кубик сбрасывает своих чилдренов и координаты.

И все бы ничего, но вот кубики начинают неверно поворачиваться после 1-2 поворотов. Какие то вообще не двигаются, какие-то двигаются не так. Чтобы понять, достаточно попробовать покрутить. В прилагаемом примере активна только одна плоскость (для наглядности), та, которая обращена к камере.

В общем, полный мрак x_x Подозреваю, что проблема в координатах дочерне-родительских объектов, но по причине неопытности не могу сообразить, как исправить положение. Помогите, люди добрые!

Для поворота кубика надо кликнуть левой КМ по одному кубику и перевести курсор на другой, в желаемую сторону поворота.
Вращения всего кубика-рубика осуществляется при нажатой ПКМ.

HTML код для вашего блога :
Код: Выделить всё
<script language='javascript' type="text/javascript"> document.write("<iframe marginheight='0' src='http://unity3d.ru/distribution/player.php?url=http://fs.yourdocs.biz/d/f/a0c208d0-832f-4d08-9cf2-d57b16b99251/WebPlayer.unity3d&w=400&h=400&t=false&preview=1' height='"+(400+30)+"' width='400' frameborder='0' scrolling='no'></iframe>"); </script>


Скрипты, отвечающие за повороты:
На центральном кубике:
Синтаксис:
Используется csharp
using UnityEngine;
using System.Collections;

public class Cube_X : MonoBehaviour {

void  Update (){
        if(Input.GetMouseButtonUp(0))
                {
                        if(Globals.rotX == 1) animation.Play("animYplus");
                        if(Globals.rotX == -1) animation.Play("animYminus");
                        if(Globals.rotY == -1) animation.Play("animXplus");
                        if(Globals.rotY == 1) animation.Play("animXminus");
                        if(Globals.rotZ == -1) animation.Play("animZplus");
                        if(Globals.rotZ == 1) animation.Play("animZminus");

                        Globals.rotX = 0;
                        Globals.rotY = 0;
                        Globals.rotZ = 0;
                }
}
}
 


На плэйнах, висящих со внешней стороны кубиков:
Синтаксис:
Используется csharp
using UnityEngine;
using System.Collections;

public class Rotate_1 : MonoBehaviour {
       
        void OnMouseDown()
        {
                GameObject.Find("Cube_X").transform.DetachChildren();
                GameObject.Find("Cube_X").transform.rotation = Quaternion.identity;

                Globals.x1 = transform.position.x;
                Globals.y1 = transform.position.y;
                Globals.z1 = transform.position.z;
                Globals.Click = true;
        }

        void OnMouseEnter()
        {
                int i = 0;
                if (Globals.Click)
                {
                        /// Поворот по X плюс
                        if(transform.position.x < Globals.x1)
                        {
                                Globals.rotX = 1;
                                ////
                        GameObject[] gos;
                        gos = GameObject.FindGameObjectsWithTag("Cube");
                foreach (GameObject go in gos) {
                                        if(go.transform.position.y == Globals.y1){
                                        go.transform.parent = GameObject.Find("Cube_X").transform;
                                        }
                        }
                                ////
                        }
                       
                        /// Поворот по X минус
                        if(transform.position.x > Globals.x1){
                                Globals.rotX = -1;
                                ////
                        GameObject[] gos;
                        gos = GameObject.FindGameObjectsWithTag("Cube");
                foreach (GameObject go in gos) {
                                        if(go.transform.position.y == Globals.y1){
                                        go.transform.parent = GameObject.Find("Cube_X").transform;
                                        }
                        }
                                ////
                        }
                        /// Поворот по Y плюс
                        if(transform.position.y < Globals.y1){
                                Globals.rotY = 1;
                                ////
                        GameObject[] gos;
                        gos = GameObject.FindGameObjectsWithTag("Cube");
                foreach (GameObject go in gos) {
                                        if(go.transform.position.x == Globals.x1){
                                        go.transform.parent = GameObject.Find("Cube_X").transform;
                                        }
                        }
                                ////
                        }
                        /// Поворот по Y минус
                        if(transform.position.y > Globals.y1){
                                Globals.rotY = -1;
                                ////
                        GameObject[] gos;
                        gos = GameObject.FindGameObjectsWithTag("Cube");
                foreach (GameObject go in gos) {
                                        if(go.transform.position.x == Globals.x1){
                                        go.transform.parent = GameObject.Find("Cube_X").transform;
                                        }
                        }
                                ////

                        }
                        /// end
                        Globals.Click = false;
                }      
        }
}
 


Не судите строго, в C# совсем новичок и понимаю, что скрипты могут выглядеть и более корректно и оптимизировано написаны. В данный момент меня больше волнует проблема с непослушными кубиками. Не знаю, как же решить ~x(
У вас нет доступа для просмотра вложений в этом сообщении.
mikita
UNец
 
Сообщения: 3
Зарегистрирован: 24 июл 2010, 17:26

Re: Кубик Рубика

Сообщение Левш@ 07 апр 2012, 18:42

Глубоко лезть в код не стал, но удивило отсутствие в коде transform.parent = null; :-? Может в этом проблемы ?
И еще анимация тут не лучший метод, я бы просто вращал родитель с интерполяцией.
_X.cor.R (Prologue)
Аватара пользователя
Левш@
Адепт
 
Сообщения: 4073
Зарегистрирован: 14 окт 2009, 16:34
Откуда: IBERIA
Skype: bars_levsha
  • Сайт

Re: Кубик Рубика

Сообщение mikita 07 апр 2012, 21:15

Левш@ писал(а):Глубоко лезть в код не стал, но удивило отсутствие в коде transform.parent = null; :-? Может в этом проблемы ?

Но для родителя есть: GameObject.Find("Cube_X").transform.DetachChildren(); - вроде результат один и тот же? Или нет?
mikita
UNец
 
Сообщения: 3
Зарегистрирован: 24 июл 2010, 17:26

Re: Кубик Рубика

Сообщение Левш@ 07 апр 2012, 21:44

вроде результат один и тот же?

Вроде да по идее, просто я этим методом не пользовался.
Можно проследить в иерархии сцены проекта, в реалтайме при тесте.
_X.cor.R (Prologue)
Аватара пользователя
Левш@
Адепт
 
Сообщения: 4073
Зарегистрирован: 14 окт 2009, 16:34
Откуда: IBERIA
Skype: bars_levsha
  • Сайт

Re: Кубик Рубика

Сообщение pod4444 07 апр 2012, 22:03

а можно .unitypackage? я завтра когда буду за нормальным компом посмотрю.
а то липить сцену с нуля неохото, чтобы просто посмотреть как это работает
Аватара пользователя
pod4444
Старожил
 
Сообщения: 721
Зарегистрирован: 20 янв 2012, 22:02
Откуда: Воронеж
Skype: pod4444
  • Сайт

Re: Кубик Рубика

Сообщение jetyb 08 апр 2012, 14:16

Я бы сперва сделал функцию, которая изображает поворот тела вокруг оси(меняются позиция и вращение).
Сам объект кубик-рубик расположил бы в центре координат, мелкие кубики сделал бы детьми. Для каждого поворота автоматически выделяется своя группа движущихся кубиков(к примеру , кого координата y>0), и к ним поодиночке применяется этот метод.
jetyb
Адепт
 
Сообщения: 1486
Зарегистрирован: 31 окт 2011, 17:21


Вернуться в Скрипты

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

Сейчас этот форум просматривают: Yandex [Bot] и гости: 6