Как вернуть блок на прежнее место спустя время?

273
16 мая 2017, 01:24

Есть блок, который я отключаю с помощью SetActive. Затем проверяю, активен ли объект с помощью ActiveSelf. Но по моей задумке блок не появляется спустя некое время.

Код:

using UnityEngine;
using System.Collections;
public class IceBlockDestroy : MonoBehaviour {
    bool onBlock;
    Animator anim;
    public float waitAfterStepped;
    public float waitAfterDestroy;
    public IceBlockDestroy block;
    // Use this for initialization
    void Start () {
        block = gameObject.GetComponent<IceBlockDestroy>();
        anim = gameObject.GetComponent<Animator> ();
    }
    // Update is called once per frame
    void Update () {
        if(!block.gameObject.activeSelf){
            waitAfterDestroy-=Time.deltaTime;
            if(waitAfterDestroy < 0){
                block.gameObject.SetActive(true);
                anim.SetBool ("isStepped", false);
            }
        }
    }
    void OnCollisionStay2D(Collision2D other)
    {
        if (onBlock) {
            anim.SetBool ("isStepped", true);
            waitAfterStepped-=Time.deltaTime;
            if(waitAfterStepped < 0){
                block.gameObject.SetActive(false);
            }
        }
    }
    void OnTriggerEnter2D()
    {
        onBlock = true;
    }
    void OnTriggerExit2D(){
        onBlock = false;
    }
}

Вопрос: как вернуть блок? Уместен ли тут SetActive и ActiveSelf?

Answer 1

Если я правильно понял, то ты сделал кое-что смешное: ты повесил скрипт на каждый блок. При этом в переменную block ты помещаешь ссылку на компонент этого же блока. Как следствие в строке:

block.gameObject.SetActive(false);

ты делаешь неактивным тот самый блок, на котором исполняется скрипт. Логично, что когда он делается неактивным — он отключается. В результате чего метод Update и другие методы уже не работают (зачем движку вхолостую их гонять?).

Вот если бы у тебя в переменной block лежала ссылка на объект (положил бы через редактор), то ты бы работал с block.gameObject уже того другого объекта. А так: сам себе яму выкопал.

В общем решений как минимум два:

  1. Делаешь какой-то общий менеджер по работе с блоками, в котором будет массив/список, в общем коллекция этих блоков. Этот менеджер, как раз управляет этими блоками, в том числе их появлением и исчезанием (например блок при прыжке на него рассылает сообщение "На меня прыгнули!", а менеджер получает сообщение и реагирует).

  2. Вместо того, чтобы делать SetActive, можешь изменять два параметра:

    • Прозрачнось (альфа канал) у материала
    • Отключать/включать BoxCollider2D (или какой у тебя там коллайдер висит)

    В этом случае скрипт продолжит работать в штатном режиме, но объект будет и появляться и исчезать как и задумано.

Также напомню, что переменным waitAfterStepped и waitAfterDestroy ты не возвращаешь первоначальные значения после операций. В итоге они после первого же исчезания/появления останутся в отрицательном значении.

Еще я бы порекомендовал иногда (всегда) разрабатывать в IDE VisualStudio или MonoDevelop, в которых иногда (всегда) в непонятных ситуациях заниматься отладкой: поставить breakpoint на том месте, где кажется должна происходить задуманная логика и посмотреть что происходит, какие данные получаются в переменных и что не так.

READ ALSO
Как задать таймаут для GET-запроса

Как задать таймаут для GET-запроса

Использую библиотеку xnetdll

355
Метод соприкосновения pictureBoxe`s

Метод соприкосновения pictureBoxe`s

Подскажите пожалуйста есть ли какой нибудь метод соприкосновения 2х пикчерБоксов в c#?

308
Защита rdp сервера

Защита rdp сервера

Вопрос глуп возможно, однако уже не знаю что делать

510