我使用Unity引擎创建的简单游戏存在问题。在此游戏中,玩家可以捡起物品并与之互动。我正在做的是,当玩家看着一个物体并且在范围之内时,物体会改变颜色。这在编辑器中可以正常工作,并且不会引发任何错误。
但是,当构建游戏时,一切似乎都能正常工作,直到我看着该对象并尝试与之交互。颜色变为粉红色,好像没有任何材质/纹理。当我把目光移开时,它保持粉红色,应该变成原始颜色。调试时也不会抛出任何错误。
在编辑器中:
看物体之前
看完物体后
在内置游戏中:
看物体之前
看完物体后
代码:
需要改变颜色的互动方式:
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解决了该问题;
答案 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将仅在编辑器中起作用,并且会在播放器版本中产生粉红色的“缺少着色器”材料。因此,建议使用着色器引用而不是按名称查找它们。要确保游戏构建中包含着色器,请执行以下任一操作:
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(“...”)调用,因为它确实尝试加载具有该名称的着色器,该名称不存在,并导致统一显示心爱的粉红色后备着色器。