Problem: Whenver I start my level and draw a line, first time I draw I get the error mentioned below. When I draw again the script works fine without giving any error. Kindly if someone can look into this and help out it'll be great! I've been stuck on this problem for a few days no... This one when my mouse is pressed:
ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: index System.ThrowHelper.ThrowArgumentOutOfRangeException (System.ExceptionArgument argument, System.ExceptionResource resource) (at <695d1cc93cca45069c528c15c9fdd749>:0) System.ThrowHelper.ThrowArgumentOutOfRangeException () (at <695d1cc93cca45069c528c15c9fdd749>:0) System.Collections.Generic.List`1[T].get_Item (System.Int32 index) (at <695d1cc93cca45069c528c15c9fdd749>:0) DrawingManager.DrawVisibleLine () (at Assets/2DPhysicsDraw/Scripts/DrawingManager.cs:401) DrawingManager.Update () (at Assets/2DPhysicsDraw/Scripts/DrawingManager.cs:219)
This one when my I release the mouse,
NullReferenceException: Object reference not set to an instance of an object DrawingManager.Update () (at Assets/2DPhysicsDraw/Scripts/DrawingManager.cs:274)
Awake Method:
private void Awake() { startMoving = false; drawCount = 0; if (_instance != null && _instance != this) { //Destroy(this.gameObject); } else { _instance = this; } }
Start Method:
void Start() { DestroyLastPath(); startMoving = false; canDraw = true; // Physics2D.IgnoreLayerCollision( 8, 3 ,true); Physics2D.IgnoreLayerCollision(LayerMask.NameToLayer("OnDraw"), LayerMask.NameToLayer("OnDraw")); mousePointer = GameObject.Find("MousePointer"); cloneNumber = 0; //colorStart = Color.black; // colorEnd = Color.black; // widthStart = 0.2f; // widthEnd = 0.2f; verticesDistance = 0.1f; // lifeTime = 2f; colliderType = ColliderTypeChoices.Polygon_Collider; // isPermanent = true; // fixedPosition = false; showMassCenter = false; massCenterPrecision = 100; dynamicMass = true; massScale = 1f; gravityScale = 1f; // overlapHandling = overlapHandlingChoices.Follow_The_Edge; freezeWhileDrawing = true; tagsCantdraw = tagCantDraw.Split(','); //tagCantDraw pathLineRenderer = path.GetComponent<LineRenderer>(); //pathRigidbody = path.GetComponent<Rigidbody2D>(); pathLineRenderer.useWorldSpace = false; // Setting up material of the line, it can be modified or placed as public so it can be changed in inspector // *Obs: changing the material will be facilitated in the next release of the asset // pathLineRenderer.material = new Material(Shader.Find("Particles/Alpha Blended Premultiply")); pathLineRenderer.SetColors(colorStart, colorEnd); pathLineRenderer.SetWidth(widthStart, widthEnd); posCount = 0; }
FixedUpdate Method:
void FixedUpdate() { mousePointer.GetComponent<TargetJoint2D>().target = (Vector2)Camera.main.ScreenToWorldPoint(Input.mousePosition); } public void StartVehicle() { StartCar.SetActive(true); }
Update Method:
void Update() { canDraw = true; // hit detection by mouse position for the on drawing collision handling if (overlapHandling == overlapHandlingChoices.Cut_After_Collision) hit = Physics2D.Raycast(mousePointer.transform.position, Vector2.zero, Mathf.Infinity, layerMask); // mouseRay detects if the mouse is over some object mouseRay = Physics2D.Raycast((Vector2)Camera.main.ScreenToWorldPoint(Input.mousePosition), Vector2.zero, Mathf.Infinity, layerMask); if (Input.GetMouseButtonDown(0)) { // PathMaterial.color = Pathcolor[GameManager.EnvirenmentNo - 1]; FreezeMoving.freeze = true; // disables the drawing when click on objects with the tag "Wall" foreach (string tag in tagsCantdraw) { if (mouseRay.collider != null && mouseRay.collider.tag == tag) canDraw = false; } if (GraphicRaycasterRaycasterExample.Instance.candraw == false) { canDraw = false; } if (canDraw == true) { mousePointer.transform.position = Camera.main.ScreenToWorldPoint(Input.mousePosition); if (overlapHandling == overlapHandlingChoices.Follow_The_Edge) Physics2D.IgnoreLayerCollision( 9, 8 ,true); mousePointer.GetComponent<CircleCollider2D>().isTrigger = false; mousePointer.transform.localScale = new Vector3(widthEnd, widthEnd, widthEnd); canDraw = true; StarPrefab(); centerOfMassCount = 0; centerOfMass = Vector2.zero; } } if (Input.GetMouseButton(0)) { if (canDraw == true) { Particle.SetActive(true); // if collides, sets collision handing flag if (hit.collider != null) { mouseHit = true; } canDraw = true; DrawVisibleLine(); } } if (Input.GetMouseButtonUp(0)) { FreezeMoving.freeze = false; Particle.SetActive(false); if (canDraw == true) { mousePointer.GetComponent<CircleCollider2D>().isTrigger = true; mouseHit = false; if (colliderType == ColliderTypeChoices.Edge_Collider) { newVerticies.Add(mousePointer.transform.position - clone.transform.position); Debug.Log("currently in if"); } else { Debug.Log("Currently in esleeee"); newVerticies2.Clear(); newVerticies.Add(mousePointer.transform.position); for (int i = 0; i < newVerticies.Count - 1; i++) { if (i < newVerticies.Count - 2) { // calculates the angle of each edge in the line colliderAngle = Mathf.Atan2(newVerticies[i].y - newVerticies[i + 1].y, newVerticies[i].x - newVerticies[i + 1].x); colliderAngle = colliderAngle + (Mathf.Deg2Rad * 90f); } else { // Since we have two points to have an edge and the last point is not in this for, the angle calculation is not // done for the last edge and the same angel from befor is preserved } float cos = Mathf.Cos(colliderAngle); // calc cos float sin = Mathf.Sin(colliderAngle); // calc sin // Get the width of the line for each point of it float tempWidth = Mathf.Lerp(widthStart, widthEnd, (float)i / (newVerticies.Count - 2)); // To make the Polygon Collider 2D go around the line, it means each side of the line, // adds one point to the beginning and one to the end of the List newVerticies2.Add(new Vector2( (newVerticies[i].x) + ((tempWidth / 2) * cos), (newVerticies[i].y) + ((tempWidth / 2) * sin))); newVerticies2.Insert(0, new Vector2( (newVerticies[i].x) - ((tempWidth / 2) * cos), (newVerticies[i].y) - ((tempWidth / 2) * sin))); } pathPolygonCollider.points = newVerticies2.ToArray(); pathPolygonCollider.sharedMaterial = material; } CalculatesPrevCenterOfMassAndMass(newVerticies.Count - 1); clone.layer = LayerMask.NameToLayer("Drawing"); pathLineRenderer.SetVertexCount(newVerticies.Count - 1); for (int i = 0; i < newVerticies.Count - 1; i++) { pathLineRenderer.SetPosition(i, newVerticies[i]); } if (dynamicMass == true) pathRigidbody.mass *= massScale; else pathRigidbody.mass = massScale; centerOfMass /= centerOfMassCount; if (newVerticies.Count > 2 && (widthStart != 0 || widthEnd != 0)) pathRigidbody.centerOfMass = centerOfMass; // Check if you want to show the center of mass during the gameplay and instantiate the prefab in the proper position // *Obs: the MassCenter prefab can be personalized with an image or anything you want to show the center of mass if (showMassCenter) { massCenterClone = (GameObject)Instantiate(massCenter, this.transform.position, Quaternion.identity); massCenterClone.transform.parent = pathRigidbody.transform; massCenterClone.transform.position = centerOfMass; } pathRigidbody.bodyType = RigidbodyType2D.Dynamic; posCount = 0; // Check if the drawn line is too small or if it doesn't have visual volume and destroy the prefab if it true /*if (newVerticies.Count <= 2 || (widthStart == 0 && widthEnd == 0)) { cloneNumber--; Destroy(clone); }*/ } canDraw = true; drawCount++; Debug.Log(drawCount); FreezeMoving.freeze = false; // if set to freeze the drawn objects while drawing a new one and is not set to be fixed position, // it adds the script FreezeMoving to the new drawings so it freezes when FreezeMoving.freeze variable is true if (fixedPosition == false && clone) { clone.gameObject.AddComponent<FreezeMoving>(); } else { if (pathRigidbody != null) { pathRigidbody.bodyType = RigidbodyType2D.Static; } } Invoke(nameof(StartVehicle),1.5f); } }
DestroyLastPathMethod:
public void DestroyLastPath() { if (paths.Count > 0) { Destroy(paths[paths.Count - 1]); paths.RemoveAt(paths.Count - 1); } }
StarPrefab Method:
/// <summary> /// Instantiate prefab and initialize necessary variables for the drawing construction /// </summary> void StarPrefab() { canDraw = true; clone = (GameObject)Instantiate(path, mousePointer.transform.position, Quaternion.identity); // instantiate prefab clone.name = "Drawing" + cloneNumber; paths.Add(clone); // Rename instantiated object so it can be easyli tracked cloneNumber++; // Add 1 in the variable for renaming the drawings pathLineRenderer = clone.GetComponent<LineRenderer>(); pathRigidbody = clone.GetComponent<Rigidbody2D>(); pathRigidbody.bodyType = RigidbodyType2D.Kinematic; // Set rigidbody kinematic so it wont move during the drawing process pathRigidbody.gravityScale = gravityScale; // Adjust gravity for the drawing clone.transform.position = Vector3.zero; // Camera.main.transform.position - new Vector3(0,0,Camera.main.transform.position.z); clone.transform.rotation = Quaternion.identity; pathRigidbody.centerOfMass = Vector2.zero; // Initialize center of mass before calculating the real position pathLineRenderer.SetColors(colorStart, colorEnd); // Set colors pathLineRenderer.SetWidth(widthStart, widthEnd); // width newVerticies.Clear(); // Clear Lists before adding new points for the new drawing newVerticies_.Clear(); newVerticies2.Clear(); // This is the List used to create the Polygon Collider 2D pathLineRenderer.SetVertexCount(1); // Add one position spot so it can add the first point of the Drawing pathLineRenderer.SetPosition(0, mousePointer.transform.position - new Vector3(0,0,Camera.main.transform.position.z)); // Add first point in the Line Renderer newVerticies.Add(mousePointer.transform.position - clone.transform.position); // Add first point to the array used to create the Colliders newVerticies_.Add(mousePointer.transform.position - clone.transform.position); // Check if the chosen collider is Edge or Polygon and destroy the one is not going to be used if (colliderType == ColliderTypeChoices.Edge_Collider) { Destroy(clone.GetComponent<PolygonCollider2D>()); pathEdgeCollider = clone.GetComponent<EdgeCollider2D>(); } else { Destroy(clone.GetComponent<EdgeCollider2D>()); pathPolygonCollider = clone.GetComponent<PolygonCollider2D>(); pathPolygonCollider.points = newVerticies2.ToArray(); // Bugfix: when creating a new drawing, collider was created in the center of the scene and hit some objects } }
Drawline Method:
/// <summary> /// Draw the line using mouse position and adding the points to the Line Renderer /// </summary> void DrawVisibleLine() { canDraw = true; Debug.Log("drawinggggggggggggggg"); // Check if the minimun distance (verticesDistance) from the previous vertice is reached and add the next point if (Vector2.Distance(mousePointer.transform.position, newVerticies_[posCount]) >= verticesDistance || Vector2.Distance(mousePointer.transform.position, newVerticies_[posCount]) <= verticesDistance ) { posCount++; pathLineRenderer.SetVertexCount(posCount + 1); pathLineRenderer.SetPosition(posCount, mousePointer.transform.position - new Vector3(0, 0, Camera.main.transform.position.z)); Particle.transform.position = mousePointer.transform.position - new Vector3(0, 0, Camera.main.transform.position.z); newVerticies_.Add(mousePointer.transform.position - clone.transform.position); if (mouseHit == false) { newVerticies.Add(mousePointer.transform.position - clone.transform.position); // Check the chosen collider if (colliderType == ColliderTypeChoices.Edge_Collider) { //for (int i = 0; i < newVerticies.Count - 1; i++) //{ // // Get the width of the line for each point of it // float tempWidth = Mathf.Lerp(widthStart, widthEnd, (float)i / (newVerticies.Count - 2)); // //} if (newVerticies.Count > 2) pathEdgeCollider.points = newVerticies.ToArray(); pathEdgeCollider.sharedMaterial = material; } else { newVerticies2.Clear(); newVerticies.Add(mousePointer.transform.position - clone.transform.position); for (int i = 0; i < newVerticies.Count - 1; i++) { // calculates the angle of each edge in the line colliderAngle = Mathf.Atan2(newVerticies[i].y - newVerticies[i + 1].y, newVerticies[i].x - newVerticies[i + 1].x); colliderAngle = colliderAngle + (Mathf.Deg2Rad * 90f); float cos = Mathf.Cos(colliderAngle); // calc cos float sin = Mathf.Sin(colliderAngle); // calc sin // Get the width of the line for each point of it float tempWidth = Mathf.Lerp(widthStart, widthEnd, (float)i / (newVerticies.Count - 2)); // To make the Polygon Collider 2D go around the line, it means each side of the line, // adds one point to the beginning and one to the end of the List newVerticies2.Add(new Vector2( (newVerticies[i].x) + ((tempWidth / 2) * cos), (newVerticies[i].y) + ((tempWidth / 2) * sin))); newVerticies2.Insert(0, new Vector2( (newVerticies[i].x) - ((tempWidth / 2) * cos), (newVerticies[i].y) - ((tempWidth / 2) * sin))); } newVerticies.RemoveAt(newVerticies.Count - 1); pathPolygonCollider.points = newVerticies2.ToArray(); pathPolygonCollider.sharedMaterial = material; } } } }
Thanks in Advance!