Баг в тетрисе(Решено)

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

Баг в тетрисе(Решено)

Сообщение Grin 12 сен 2010, 10:41

Сам баг такой: создается фигура, но вместо того чтобы падать зависает, соотв следующие фигуры зависают в ней.
Фигур пока всего 1, это "Линия" 3 стандартных юнити-куба в ряд + GameObject "Center", который юзается как pivot при поворотах и установлен по центру фигуры(т.к. обычный пивот оказался вообще не там и я не знаю как его переставить).
Код скрипта отвечающего за создание фигур:
Синтаксис:
Используется csharp
using UnityEngine;
using System.Collections;

public class FigureSpawn : MonoBehaviour {
       
        public GameObject[] figures;
        private GameObject curFigure;
       
        // Use this for initialization
        void Start () {
                Spawn();
       
        }
       
        // Update is called once per frame
        void Update () {
               
                Spawn();
       
        }
               
                private void Spawn()
                {
                        if(curFigure == null)
                        {
                               
                                int val = Random.Range(0,figures.Length);
                               
                                //curFigure.position = new Vector3(2.25f, 11.5f, 0);
                                //curFigure = new GameObject(figures[0].name).GetComponent<Transform>();
                                Vector3 rotate = Vector3.zero;
                                int ranRotate = Random.Range(0,4);
                               
                       
                                if(ranRotate == 0 )
                                {
                                        rotate = new Vector3(0,0,0);
                                }
                                else if(ranRotate == 1)
                                {
                                        rotate = new Vector3(0,0,90);
                                }
                                else if(ranRotate == 2)
                                {
                                        rotate = new Vector3(0,0,180);
                                }
                                else if(ranRotate == 3)
                                {
                                        rotate = new Vector3(0,0,270);
                                }
                                curFigure = Instantiate(figures[val], new Vector3(2.5f, 11.5f,0), Quaternion.Euler(rotate)) as GameObject;
                       
                        }
                       
                }
               
       
        }


 

figures - массив с префабами фигур(пока 1 линия).

Код отвечающий за саму фигуру(не весь, в целях удобства).
Синтаксис:
Используется csharp
using UnityEngine;
using System.Collections;

public class LineRayControl : MonoBehaviour {
       
        public Transform center;
       
        private float moveDelay;
        private float rotateDelay;
        private float fallDelay;

        // Use this for initialization
        void Start () {
                moveDelay = Time.time;
                rotateDelay = Time.time;
                fallDelay = Time.time;
        }
       
        // Update is called once per frame
        void Update () {
               
                MoveAndRotate();
               
                if(!CanVerticalMove())
                {
                        Landing();
                }
                else
                {
                        FallDown();
                }              
               
               
               
        }
        #region Update function
       
        private bool CanVerticalMove()
        {
               
                if(transform.eulerAngles.z == 0 || transform.eulerAngles.z == 180)
                {
                        if(Physics.Raycast(center.position + new Vector3(0,-1.4f,0), new Vector3(0,-1,0), 0.2f))
                        {
                               
                                return false;
                        }
                }
                else
                {
                        if(Physics.Raycast(center.position + new Vector3(-1,-0.4f,0), new Vector3(0,-1,0), 0.2f) ||
                                Physics.Raycast(center.position + new Vector3(0,-0.4f,0), new Vector3(0,-1,0), 0.2f) ||
                                Physics.Raycast(center.position + new Vector3(1,-0.4f,0), new Vector3(0,-1,0), 0.2f)
                        )
                        {
                               
                                return false;
                        }
                }
                return true;
        }
       
        private void Landing()
        {
                Transform[] trfs;
                //gravity = Vector3.zero;
                trfs = GetComponentsInChildren<Transform>();
                foreach(Transform trf in trfs)
                {
                        if(trf.name == "Center")
                        {
                                Destroy(trf);
                        }
                        else
                        {
                                trf.parent = GameObject.Find("CubeBox").GetComponent<Transform>();
                        }
                }
                transform.DetachChildren();
                Destroy(gameObject);
        } private void FallDown()
        {
                if(Time.time - fallDelay >= 1)
                {
                        fallDelay = Time.time;
                        transform.position -= new Vector3(0,1,0);
                }
        }      
       
       
        #endregion
       


}

 

MoveAndRotate() - Проверяет, двигает и вращает фигуру если можно, в зависимости от ввода.
Собсно баг наверняка связан с этими методами:

CanVerticalMove() - проверяет есть ли снизу препятстие.При баге возвращает false(должно true).Соотвественно выполняется
Landing() - производит некоторые действия.

FallDown() - двигает фигуру вниз.

Если баг не проявляется, то все нормально, фигуры ставятся одна на другую.
Последний раз редактировалось Grin 13 сен 2010, 13:53, всего редактировалось 1 раз.
Grin
UNец
 
Сообщения: 34
Зарегистрирован: 12 июл 2010, 04:45
Откуда: Россия, г. Челябинск
  • ICQ

Re: Баг в тетрисе

Сообщение Ert Donuell 12 сен 2010, 11:32

В скрипте, отвечающем за создание фигур Вы вызываете функцию Spawn(); в Start () и Update(). Зачем? Не проще так:
Синтаксис:
Используется csharp
using UnityEngine;
using System.Collections;

public class FigureSpawn : MonoBehaviour {
       
        public GameObject[] figures;
        private GameObject curFigure;
       
        // Update is called once per frame
        void Update () {
                if (curFigure == null) {
                        int val = Random.Range(0,figures.Length);
                       
                        //curFigure.position = new Vector3(2.25f, 11.5f, 0);
                        //curFigure = new GameObject(figures[0].name).GetComponent<Transform>();
                        Vector3 rotate = Vector3.zero;
                        int ranRotate = Random.Range(0,4);
               
                        if (ranRotate == 0 ) {
                                rotate = new Vector3(0,0,0);
                        }
                        else if (ranRotate == 1) {
                                rotate = new Vector3(0,0,90);
                        }
                        else if (ranRotate == 2) {
                                rotate = new Vector3(0,0,180);
                        }
                        else if (ranRotate == 3) {
                                rotate = new Vector3(0,0,270);
                        }
                        curFigure = Instantiate(figures[val], new Vector3(2.5f, 11.5f,0), Quaternion.Euler(rotate)) as GameObject;
                }
        }
}
 
Последний раз редактировалось Ert Donuell 12 сен 2010, 11:51, всего редактировалось 2 раз(а).
Добавить dmitrii.baranov.yumasoft в Skype
Аватара пользователя
Ert Donuell
Старожил
 
Сообщения: 781
Зарегистрирован: 05 июл 2010, 09:50
Откуда: Санкт-Петербург
  • ICQ

Re: Баг в тетрисе

Сообщение Grin 12 сен 2010, 11:39

Кстати, да. Спасибо.
Баг остался.
Grin
UNец
 
Сообщения: 34
Зарегистрирован: 12 июл 2010, 04:45
Откуда: Россия, г. Челябинск
  • ICQ

Re: Баг в тетрисе

Сообщение Ert Donuell 12 сен 2010, 17:29

Мда, это было замечание по оптимизации кода)

Как они должны падать? Гравитационно? =)
Добавить dmitrii.baranov.yumasoft в Skype
Аватара пользователя
Ert Donuell
Старожил
 
Сообщения: 781
Зарегистрирован: 05 июл 2010, 09:50
Откуда: Санкт-Петербург
  • ICQ

Re: Баг в тетрисе

Сообщение Ert Donuell 12 сен 2010, 18:03

У Вас там случайно Rigidbody нет? :) Если есть, то поставьте галочку IsKinematic)

Был аналогичный баг, несколько месяцев боролся
Последний раз редактировалось Ert Donuell 14 сен 2010, 07:39, всего редактировалось 1 раз.
Добавить dmitrii.baranov.yumasoft в Skype
Аватара пользователя
Ert Donuell
Старожил
 
Сообщения: 781
Зарегистрирован: 05 июл 2010, 09:50
Откуда: Санкт-Петербург
  • ICQ

Re: Баг в тетрисе

Сообщение Grin 13 сен 2010, 05:40

Падают они с помощью FallDown(), ригидбоди нету. Может что-то не так с Physics.Raycast(), у меня их там много еще в MoveAndRotate() для проверки возможности поворота и горизонтального движения?
Grin
UNец
 
Сообщения: 34
Зарегистрирован: 12 июл 2010, 04:45
Откуда: Россия, г. Челябинск
  • ICQ

Re: Баг в тетрисе(Решено)

Сообщение Ert Donuell 13 сен 2010, 13:58

Так как решено? :)
Добавить dmitrii.baranov.yumasoft в Skype
Аватара пользователя
Ert Donuell
Старожил
 
Сообщения: 781
Зарегистрирован: 05 июл 2010, 09:50
Откуда: Санкт-Петербург
  • ICQ

Re: Баг в тетрисе(Решено)

Сообщение Grin 13 сен 2010, 14:16

Если интересно, баг остался, но те кубы в которых все начинает застревать после бага просто уничтожаются при помощи ClearPlace().
Синтаксис:
Используется csharp
using UnityEngine;
using System.Collections;

public class FigureSpawn : MonoBehaviour {
       
        public GameObject[] figures;
        private GameObject curFigure;
       
        // Use this for initialization
        void Start () {
               
       
        }
       
        // Update is called once per frame
        void Update () {
               
                Spawn();
       
        }
               
                private void Spawn()
                {
                        if(curFigure == null)
                        {
                               
                                int val = Random.Range(0,figures.Length);
                               
                                //curFigure.position = new Vector3(2.25f, 11.5f, 0);
                                //curFigure = new GameObject(figures[0].name).GetComponent<Transform>();
                                Vector3 rotate = Vector3.zero;
                                int ranRotate = Random.Range(0,4);
                               
                       
                                if(ranRotate == 0 )
                                {
                                        rotate = new Vector3(0,0,0);
                                }
                                else if(ranRotate == 1)
                                {
                                        rotate = new Vector3(0,0,90);
                                }
                                else if(ranRotate == 2)
                                {
                                        rotate = new Vector3(0,0,180);
                                }
                                else if(ranRotate == 3)
                                {
                                        rotate = new Vector3(0,0,270);
                                }
                                curFigure = Instantiate(figures[val], new Vector3(5.5f, 12.5f,0), Quaternion.Euler(rotate)) as GameObject;
                               
                                ClearPlace();
                        }
                       
                }
               
                private void ClearPlace()
                {
                        Transform[] cubes = GameObject.Find("CubeBox").GetComponentsInChildren<Transform>();
                        for(int i = 0; i <cubes.Length; i++)
                        {
                                if(cubes[i].position.y >= 10.5 && cubes[i].parent == GameObject.Find("CubeBox").GetComponent<Transform>())
                                {
                                        Destroy(cubes[i].gameObject);
                                }
                        }
                }
               
               
       
        }

 
Grin
UNец
 
Сообщения: 34
Зарегистрирован: 12 июл 2010, 04:45
Откуда: Россия, г. Челябинск
  • ICQ

Re: Баг в тетрисе(Решено)

Сообщение Ert Donuell 13 сен 2010, 14:25

По-прежнему недоумеваю зачем Spawn() и ClearPlace() выносить в отдельные функции))
Добавить dmitrii.baranov.yumasoft в Skype
Аватара пользователя
Ert Donuell
Старожил
 
Сообщения: 781
Зарегистрирован: 05 июл 2010, 09:50
Откуда: Санкт-Петербург
  • ICQ

Re: Баг в тетрисе(Решено)

Сообщение Grin 13 сен 2010, 14:35

Для развития полезной привычки=)
Grin
UNец
 
Сообщения: 34
Зарегистрирован: 12 июл 2010, 04:45
Откуда: Россия, г. Челябинск
  • ICQ

Re: Баг в тетрисе(Решено)

Сообщение Ert Donuell 13 сен 2010, 14:51

Мм.. Я, конечно, могу ошибаться, но создание лишних функций не есть хорошая привычка) Особенно в погоне за скоростью ;)
Добавить dmitrii.baranov.yumasoft в Skype
Аватара пользователя
Ert Donuell
Старожил
 
Сообщения: 781
Зарегистрирован: 05 июл 2010, 09:50
Откуда: Санкт-Петербург
  • ICQ

Re: Баг в тетрисе(Решено)

Сообщение Grin 13 сен 2010, 15:04

А вы предлагаете все в Update?
Я после изучения car.js стандартного гоночного туториала взял на вооружение метод в Update пихать только функции по возможности, как там сделано.
Так как то удобнее.=)
Grin
UNец
 
Сообщения: 34
Зарегистрирован: 12 июл 2010, 04:45
Откуда: Россия, г. Челябинск
  • ICQ

Re: Баг в тетрисе(Решено)

Сообщение Fox Rex 13 сен 2010, 15:04

Объясните мне зачем в тетресе физикой пользоваться, когда достаточно простого двумерного массива, тем более что без него будет проблематично определить заполненные линии. Делается это так вся анимация отражается в массиве, один элемент массива один кубик, можно создать массив типа bool, true - есть кубик в позиции, false - нет. Прежде чем передвинуть кубик в позицию проверяется в массиве занята ли она. Для трехмерного тетриса 3 мерный массив.
Never more!
Аватара пользователя
Fox Rex
UNITрон
 
Сообщения: 218
Зарегистрирован: 04 сен 2010, 11:24

Re: Баг в тетрисе(Решено)

Сообщение Ert Donuell 13 сен 2010, 15:16

Grin писал(а):А вы предлагаете все в Update?

Да, именно так. Для удобства можно юзать комментарии. А функции имеют смысл там где код часто повторяется. Где запарно будет много фрагментов изменять. А тут функция просто бессмысленна :)
Добавить dmitrii.baranov.yumasoft в Skype
Аватара пользователя
Ert Donuell
Старожил
 
Сообщения: 781
Зарегистрирован: 05 июл 2010, 09:50
Откуда: Санкт-Петербург
  • ICQ

Re: Баг в тетрисе(Решено)

Сообщение Serge 13 сен 2010, 15:18

Я ради развлечения, в свободное время, тоже делаю тетрис с физикой :) . Просто интересно, что из этого получится :) . А проверить заполнение линии можно через RaycastAll, она же вернет массив кубиков для удаления.
Насчет выноса кода в отдельные функции, согласен с автором и читабельно и легче отлаживать и модернизировать. Главное что все было в меру :) .
О, сколько нам открытий чудных Готовят просвещенья дух И опыт, сын ошибок трудных, И гений, парадоксов друг, И случай, бог изобретатель.
Аватара пользователя
Serge
UNIверсал
 
Сообщения: 476
Зарегистрирован: 20 мар 2009, 15:53
Откуда: Сибирь г. Омск
  • Сайт
  • ICQ

След.

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

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

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