ARTICLE AD BOX
Note: Someone in the first iteration of this question said that CheckForMagicPoint() is being called every frame, but it is not, as checkingForMagicPoints is only set to true when someone is using the magic pen, and even if it was being called every frame, that would now be problematic as it only adds an item to the list if the raycast hits a magic detection point, and the same magic detection point cannot be added twice because of the following line of code:
if (hit.transform.gameObject != glyphs[glyphObjects[glyphObjects.Count - 1]][glyphs[glyphObjects[glyphObjects.Count - 1]].Count - 1]) { ... }I am trying to make a magic system for my VR game using dots in a hexagonal grid, but before I make the magic system actually work, I need to visualize the glyphs drawn, but the rendering won't work. I don't have any errors, so I don't know what I did wrong.
The following is simply an explanation of what all of the variables are for, if you don't need them, skip ahead:
glyphs; A dictionary containing every list of magic points, with the corresponding glyph renderer as the key
castPoint; The transform where the pen raycasts from
checkingForMagicPoints; A bool variable that is set to true when the player is using the magic pen, and vice versa. Used for the if check each frame.
lineRenderer; A line renderer defined in the editor that is used for the initial raycast visualization from the pen
rayPoints; The points of the raycast visualizer from the pen.
glyphObjects; A list of all of the instantiated glyph prefabs
glyphPrefab; A prefab defined in the editor. Simply an empty gameobject, except for a line renderer component used for rendering the glyphs.
This is my current code:
using System.Collections.Generic; using System.Linq; using Unity.VisualScripting; using UnityEngine; using UnityEngine.Events; using UnityEngine.XR.Interaction.Toolkit; using UnityEngine.XR.Interaction.Toolkit.Interactors; public class magicPen : MonoBehaviour { private Dictionary<GameObject, List<GameObject>> glyphs = new Dictionary<GameObject, List<GameObject>>(); public Transform castPoint; private bool checkingForMagicPoints = false; public LineRenderer lineRenderer; private Vector3[] rayPoints; private List<GameObject> glyphObjects = new List<GameObject>(); public GameObject glyphPrefab; //create an action to be referenced in the editor public void setCheckingState(bool state) { //set the checkingForMagicPoints variable to the declared bool checkingForMagicPoints = state; //check the new state of checkingForMagicPoints if (checkingForMagicPoints) { //instantiate a new visual glyph when you start pressing the magic pen GameObject newGlyph = Instantiate(glyphPrefab); //add that new glyph visualizer into the glyphobjects list glyphObjects.Add(newGlyph); //Add the new glyph renderer into the glyphs list as the key, with the corresponding list of points as the stored data glyphs.Add(newGlyph, new List<GameObject>()); } } public void CheckForMagicPoint() { //use this type to gain info from raycasts RaycastHit hit; //define the layer that we want the raycast to hit int layer = 3; //change it into a form that the raycast can read int layerMask = 1 << layer; //send the raycast if (Physics.Raycast(castPoint.position, castPoint.TransformDirection(Vector3.forward), out hit, 30, layerMask)) { lineRenderer.enabled = true; //Debug.Log("Checking For Magic Point"); rayPoints = new Vector3[] { castPoint.position, hit.point }; // Configure basic appearance lineRenderer.startWidth = 0.01f; lineRenderer.endWidth = 0.01f; lineRenderer.material = new Material(Shader.Find("Sprites/Default")); lineRenderer.positionCount = rayPoints.Length; //Set main ray positions lineRenderer.SetPositions(rayPoints); //Check if there are any glyphs that have been drawn if (glyphs[glyphObjects[glyphObjects.Count -1]].Count != 0) { //Check if the current magic point is the newest point, stopping it from repeatedly adding the same point to the list if (hit.transform.gameObject != glyphs[glyphObjects[glyphObjects.Count - 1]][glyphs[glyphObjects[glyphObjects.Count - 1]].Count - 1]) { //Record the current magic point on the last list on the glyphs dictionary, aka add a new point to the current glyph glyphs[glyphObjects[glyphObjects.Count - 1]].Add(hit.transform.gameObject); } } else { //Record the current magic point on the last list on the glyphs list, aka add a new point to the current glyph glyphs[glyphObjects[glyphObjects.Count - 1]].Add(hit.transform.gameObject); } } else { lineRenderer.enabled = false; } } // Start is called once before the first execution of Update after the MonoBehaviour is created void Start() { } // Update is called once per frame void Update() { if (checkingForMagicPoints) { CheckForMagicPoint(); } else { lineRenderer.enabled = false; } //Check if any glyphs have been made and that glyphObjects is exists if(glyphObjects.Count != 0 && glyphObjects != null) { //Get each glyph visualizer, set its neccecary stuff, then grab the coresponding list of magic points, get their transforms, and set the line renderer points to those. foreach (GameObject visualGlyph in glyphObjects) { visualGlyph.GetComponent<LineRenderer>().startWidth = 0.05f; visualGlyph.GetComponent<LineRenderer>().endWidth = 0.05f; visualGlyph.GetComponent<LineRenderer>().material = new Material(Shader.Find("Sprites/Default")); visualGlyph.GetComponent<LineRenderer>().positionCount = glyphs[visualGlyph].Count; visualGlyph.GetComponent<LineRenderer>().SetPositions(glyphs[visualGlyph].Where(go => go != null).Select(go => go.transform.position).ToArray()); } } } }When I look at the instantiated glyph renderers, they all show the same position, only once each.
If I remove the if statement stopping it from repeating the same point multiple times, they all repeat the same position, but in different amounts, and I don't know why.
