This question was
closed Mar 21, 2017 at 09:55 PM by
hexagonius for the following reason:
Question by
gguttilla · Mar 21, 2017 at 06:01 AM ·
shadernullreferenceexceptionmaterialsarraysforeach
Null Reference Exception when changing material shader
I am trying to create a script that makes all the materials of all objects obstructing the view of the player become transparent, and become opaque when they are no longer obstructing the view. It seems to work fine in the editor now, but whenever I go from having >= 1 object blocking the view to having no objects blocking the view I am flooded with null reference exception errors that point specifically to mats = rends.materials; near the bottom. Through debugging i've found that the error seems to stem from specifically referencing the materials of gameobjects in the if (hits.length == 0) { statement. Any thoughts?
using UnityEngine; using System.Collections;
public class ObstructionFade : MonoBehaviour {
public Camera cam;
public Renderer[] rend;
public Renderer[] lastRend;
public RaycastHit[] hits;
public Material[] mats;
public int i;
LayerMask mask;
void Start () {
mask = LayerMask.GetMask ("Default");
}
// Update is called once per frame
void LateUpdate () {
i = 0;
Ray camRay = cam.ScreenPointToRay (cam.WorldToScreenPoint (transform.position + new Vector3 (0, 2, 0)));
Debug.DrawLine (cam.transform.position, transform.position);
//gets all things the raycast hits
hits = Physics.RaycastAll (camRay, Vector3.Distance (Camera.main.transform.position, transform.position) - 3, mask);
//for every thing the raycast hits
foreach (RaycastHit hit in hits){
//set last renderer hit to the current renderer
lastRend[i] = rend[i];
//get the current renderer hit and make it transparent
rend[i] = hit.collider.gameObject.GetComponent<MeshRenderer> ();
mats = rend [i].materials;
foreach (Material mat in mats) {
mat.color = new Color (mat.color.r, mat.color.g, mat.color.b, 0.3f);
mat.shader = Shader.Find ("Legacy Shaders/Transparent/Diffuse");
}
//if the last and current renderer dont match make the last renderer opaque
if (lastRend[i] != rend[i]){
mats = lastRend [i].materials;
foreach (Material mat in mats) {
mat.color = new Color (mat.color.r, mat.color.g, mat.color.b, 1.0f);
mat.shader = Shader.Find ("Standard");
}
}
//increment i
i++;
}
//if the raycast hits nothing make all previously hit objects opaque
if (hits.Length == 0) {
foreach (Renderer rends in rend) {
mats = rends.materials;
foreach (Material mat in mats) {
mat.color = new Color (mat.color.r, mat.color.g, mat.color.b, 1.0f);
mat.shader = Shader.Find ("Standard");
}
}
}
}
}
Comment