Unity:游戏可以在编辑器中运行,但不能在构建时使用。编辑器代码与构建是否有所不同?

时间:2018-11-08 15:45:46

标签: c# unity3d colors renderer

我使用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 :(得分:1)

首先

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);

将毫无用处,因为您覆盖了第3行中的materials[0].shader,而不仅仅是更改了此新着色器的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,则应该已经在编辑器中将相应的材质设置为“高光”,并且仍然可以使用

rend.materials[0].SetColor ("_SpecColor", colorToSet);

答案 1 :(得分:-1)

删除所有Shader.Find(“...”)调用,因为它确实尝试加载具有该名称的着色器,该名称不存在,并导致统一显示心爱的粉红色后备着色器。