Unity: игра работает в редакторе, но не работает. Код редактора отличается от сборки? - PullRequest
0 голосов
/ 08 ноября 2018

У меня проблема с моей простой игрой, которую я создаю с использованием движка Unity.В этой игре игрок может подбирать предметы и взаимодействовать с ними.Что я делаю, так это то, что когда игрок смотрит на объект и находится в пределах досягаемости, объект меняет цвет.Это прекрасно работает в редакторе и не выдает никаких ошибок.

Однако, когда игра построена, все работает, пока я не смотрю на объект и не пытаюсь с ним взаимодействовать.Цвет меняется на розовый, как если бы не было материала / текстуры.И когда я смотрю в сторону, он остается розовым, когда он должен превратиться в исходный цвет. Также нет ошибок при отладке.

В редакторе:

Перед просмотромобъект

После просмотра объекта

В встроенной игре:

Перед просмотром объекта

После просмотра объекта

  • output_log.txt не содержит ошибок.
  • Унитар обновлен (5.6.1f1)
  • Нетошибки в редакторе отладки, а также встроенной отладке игры.
  • Я где-то читал, что Assembly-UnityScript.dll должен присутствовать в папке с игрой, но ее нет в моей.Но этот ответ был несколько лет назад.И другие сценарии, кажется, работают (ходьба, триггеры, звуки и т. Д.).

Код:

Взаимодействие, которое вызывает изменение цвета:

    if (Physics.Raycast(transform.position, transform.TransformDirection(Vector3.forward), out hit, raycastDistance, layerMask))
    {


        if (hit.collider.tag=="Computer") {
            hit.collider.GetComponentInChildren<Image> ().color = Color.cyan;

            return;
        }

        Debug.DrawRay(transform.position, transform.TransformDirection(Vector3.forward) * hit.distance, Color.yellow);

        if (lastHit != null) {

            if (lastHit != GameObject.Find (hit.collider.name)) {
                lastHit.GetComponent<ManipulateColor> ().setDefaultColor ();
            }
        }

        lastHit = GameObject.Find (hit.collider.name);
        lastHit.GetComponent<ManipulateColor> ().setColor ();

        interactionText.text = lastHit.GetComponent<Interactable> ().interactionText;
        interactionText.enabled = true;

        canInteract = true;

    }
    else
    {
        Debug.DrawRay(transform.position, transform.TransformDirection(Vector3.forward) * raycastDistance, Color.white);

        if (lastHit != null) {
            lastHit.GetComponent<ManipulateColor> ().setDefaultColor ();
        }

        interactionText.enabled = false;
        canInteract = false;
    }

// Класс изменения цвета:

public Color colorToSet = Color.green;

private Color defaultColor;

private List<Color> childrenColors = new List<Color>();
private List<Color> colorListToUse = new List<Color> ();

private Renderer rend;

private bool hasChildren = false;
private bool parentHasRender = false;

// Use this for initialization
void Start () {


    if (gameObject.transform.childCount > 0) {
        hasChildren = true;
        if (gameObject.GetComponent<Renderer> ()!=null) {
            rend = gameObject.GetComponent<Renderer> ();
            childrenColors.Add (rend.materials [0].color);
            parentHasRender = true;
        } 

        foreach (Transform child in gameObject.transform) {


            if (child.gameObject.GetComponent<Renderer> ()!=null) {

                rend = child.gameObject.GetComponent<Renderer> ();
                childrenColors.Add (rend.materials [0].color);
            }

        }

    } else {
        rend = gameObject.GetComponent<Renderer> ();
        defaultColor = rend.materials[0].color;
    }


    colorListToUse = childrenColors;

}

public void setColor(){




    if (hasChildren) {
        if (parentHasRender) {
            rend = gameObject.GetComponent<Renderer> ();
            rend.materials[0].shader = Shader.Find ("_Color");
            rend.materials[0].SetColor ("_Color", colorToSet);


            rend.materials[0].shader = Shader.Find ("Specular");
            rend.materials[0].SetColor ("_SpecColor", colorToSet);
        }


        foreach (Transform child in gameObject.transform) {
            if (child.gameObject.GetComponent<Renderer> ()!=null) {
                rend = child.gameObject.GetComponent<Renderer> ();
                rend.materials[0].shader = Shader.Find ("_Color");
                rend.materials[0].SetColor ("_Color", colorToSet);



                rend.materials[0].shader = Shader.Find ("Specular");
                rend.materials[0].SetColor ("_SpecColor", colorToSet);
            }



        }

    } else {
        rend.materials[0].shader = Shader.Find("_Color");
        rend.materials[0].SetColor ("_Color", colorToSet);


        rend.materials[0].shader = Shader.Find("Specular");
        rend.materials[0].SetColor ("_SpecColor", colorToSet);
    }

}

public void setDefaultColor(){



    if (hasChildren) {
        if (parentHasRender) {

            rend.materials[0].shader = Shader.Find("_Color");
            rend.materials[0].SetColor ("_Color", colorListToUse[0]);


            rend.materials[0].shader = Shader.Find("Specular");
            rend.materials[0].SetColor ("_SpecColor", colorListToUse[0]);
            colorListToUse.RemoveAt (0);
        }


        foreach (Transform child in gameObject.transform) {
            if (child.gameObject.GetComponent<Renderer> ()!=null) {
                rend = child.gameObject.GetComponent<Renderer> ();
                rend.materials[0].shader = Shader.Find ("_Color");
                rend.materials[0].SetColor ("_Color", colorListToUse[0]);



                rend.materials[0].shader = Shader.Find ("Specular");
                rend.materials[0].SetColor ("_SpecColor", colorListToUse[0]);
            }
        }


    } else {
        rend = gameObject.GetComponent<Renderer> ();
        rend.materials[0].shader = Shader.Find("_Color");
        rend.materials[0].SetColor ("_Color", defaultColor);


        rend.materials[0].shader = Shader.Find("Specular");
        rend.materials[0].SetColor ("_SpecColor", defaultColor);

    }


    colorListToUse = childrenColors;
}

Решено:

Удаление всех Shader.Find и SetColor, и вместо этого просто использование rend.materials [0] .color = colorToSet решило проблему;

Ответы [ 2 ]

0 голосов
/ 08 ноября 2018

Прежде всего

rend.materials[0].shader = Shader.Find("_Color");
rend.materials[0].SetColor ("_Color", colorToSet);


rend.materials[0].shader = Shader.Find("Specular");
rend.materials[0].SetColor ("_SpecColor", colorToSet);

было бы совершенно бесполезным, поскольку вы перезаписали materials[0].shader в строке 3, а затем изменили только SpecColor этого нового шейдера. Это делает строки 1 + 2 избыточными / безрезультатными.


Чем ваш вопрос: Да, сборка ведет себя немного иначе, чем редактор. В сборке проект удаляется из большинства активов / скриптов и т. Д., Если на них никогда не ссылаются (=> очевидно, никогда не используется).

С Shader.Find

Обратите внимание, что шейдер может не быть включен в билд плеера, если на него ничего не ссылается! В этом случае Shader.Find будет работать только в редакторе, и в сборке плеера появятся розовые «недостающие шейдерные» материалы. В связи с этим рекомендуется использовать ссылки на шейдеры, а не искать их по имени. Чтобы убедиться, что шейдер включен в сборку игры, выполните одно из следующих действий:

1) ссылаться на него из некоторых материалов, использованных в вашей сцене,

2) добавьте его в список «Всегда включенные шейдеры» в ProjectSettings / Graphics или

3) положить шейдер или что-то, что ссылается на него (например, материал), в папку «Ресурсы».


Но на самом деле мне кажется, что вы действительно не хотите изменять Shader материала во время выполнения, а скорее цвет (а).

Так что вместо

rend.materials[0].shader = Shader.Find("_Color");
rend.materials[0].SetColor ("_Color", colorListToUse[0]);

Вы должны просто использовать

rend.materials[0].color = colorToSet;

для изменения цвета материала. см. также Material.color

Если вам назначен только один материал, вы также можете просто использовать

rend.material.color = colorToSet;

Если вам по-прежнему необходимо установить SpecColor, вы должны уже в редакторе установить соответствующие материалы на Specular, а затем вы все еще можете использовать

rend.materials[0].SetColor ("_SpecColor", colorToSet);
0 голосов
/ 08 ноября 2018

Удалить все Shader.Find («...») , поскольку он пытается загрузить шейдер с таким именем, которого не существует, и вызывает единство, чтобы показать любимый розовый запасной шейдер.

...