Your error is caused by one of the many reference variables in your code that could be null. The script is trying to access a nonexistent object, so it throws an error. To fix this, simply check that it is not null before accessing it. For example
if (GlyphText != null)
GlyphText.text = "Example";
But I simply cannot stand idly by looking at your mess of code. I hope you don’t mind, but I have made many modifications to your script to improve readability and usability. The script has been reworked in a way that I presume you would want to use it.
I have renamed Raycast_DHD to DHDRaycast, and dhd_INT to DHDGlyph.
I have added a bool to DHDGlyph, isOn, to represent whether the Glyph button is on or not.
A single array now holds all 38 Glyph GameObjects, and it can be resized in the Inspector. This means we don’t have to copy/paste code for each GameObject. We can just loop through each object in the array.
I have added two functions, UpdateGlyph and SetTexture, which changes the texture of the Glyph based on whether it is on or off.
There is now also a Dial function to find the address from all Glyphs that are On, and then do something with that address. The Address string is created fully in the Dial function, and is not changed or added to during the UpdateGlyph function.
DHDRaycast.cs
using UnityEngine;
using UnityEngine.UI;
public class DHDRaycast : MonoBehaviour
{
public DHDGlyph[] Glyphs = new DHDGlyph[0]; // set all 38 Glyphs in the inspector
public Texture2D ButtonOnTex;
public Texture2D ButtonOffTex;
// runtime variables
public string Address = "";
private Text GlyphText;
void Awake()
{
// find GlyphText object
GameObject CanvasText = GameObject.Find("GlyphText");
if (CanvasText != null)
{
GlyphText = CanvasText.GetComponent<Text>();
}
else
Debug.LogWarning("There is no GameObject with the tag GlyphText.");
// initialize GlyphText text
if (GlyphText != null)
GlyphText.text = "";
else
Debug.LogWarning("There is no GlyphText.");
// initialize Glyph textures
foreach (DHDGlyph Glyph in Glyphs)
{
if (Glyph != null)
{
UpdateGlyph(Glyph);
}
}
}
void Update()
{
// make sure Glyphs array is not null
if (Glyphs == null)
Glyphs = new DHDGlyph[0];
RaycastHit hit;
Ray ray = Camera.main.ViewportPointToRay(new Vector3(0.5f, 0.5f, 0f));
if (Physics.Raycast(ray, out hit, 200f))
{
// check if the collider is a Glyph
DHDGlyph Glyph = hit.collider.GetComponent<DHDGlyph>();
if (Glyph != null) // note it no longer needs to check hit.collider.tag, it just checks to see that it has a DHDGlyph component
{
bool foundGlyph = false;
for (int i = 0; i < Glyphs.Length; ++i) // loop through all of the Glyphs until it finds the right one
{
if (Glyphs *== Glyph)*
{
foundGlyph = true;
if (GlyphText != null)
GlyphText.text = "Glyph " + i;
if (Input.GetKeyDown(KeyCode.E))
{
Glyph.isOn = !Glyph.isOn; // toggle button on/off state
UpdateGlyph(Glyph); // calls the function
}
break; // do not loop through the rest of the Glyph objects
}
}
if (!foundGlyph) // if the Glyph was not in the array, reset the GlyphText
{
if (GlyphText != null)
GlyphText.text = “”;
}
}
}
else // if no object was hit, reset the GlyphText
{
if (GlyphText != null)
GlyphText.text = “”;
}
// if you want to dial the gate address
if (Input.GetKeyDown(KeyCode.Q)) // for example
{
Dial();
}
}
private void UpdateGlyph(DHDGlyph Glyph)
{
if (Glyph.isOn) // if button is now on
{
SetTexture(Glyph, ButtonOnTex);
}
else // if button is now off
{
SetTexture(Glyph, ButtonOffTex);
}
}
private void SetTexture(DHDGlyph Glyph, Texture tex)
{
MeshRenderer renderer = Glyph.GetComponentInChildren();
if (renderer != null && renderer.material != null)
{
renderer.material.mainTexture = tex; // use material instead of sharedMaterial. Setting sharedMaterial will make all the Glyph textures change.
}
else
Debug.LogError(“Glyph " + Glyph.name + " either does not have a renderer, or its renderer has no material.”);
}
// once finished setting all the Glyphs On or Off, dial the address
public void Dial()
{
Address = “”;
// loop through each Glyph
foreach (DHDGlyph Glyph in Glyphs)
{
if (Glyph != null)
{
if (Glyph.isOn) // if the button is on, add its glyph to the address
{
Address += Glyph.glyph;
}
}
}
// do something with Address
Debug.Log("Dialled Address " + Address);
}
}
DHDGlyph.cs
using UnityEngine;
public class DHDGlyph : MonoBehaviour
{
public int glyph;
public bool isOn = false;
}