//Method used to add a new line renderer vertex and a new vertex sphere. public GameObject addVertex(Vector3 pos, int vertexID, GameObject selectedVertex) { pos = rotateVertex(pos, -getLocalRotation()); //Get the vertex spheres that are children of this object List <GameObject> children = getChildrenVertices(); //Add the selected vertex to that list (as it won't be a child of the object if it's selected), and sort the list. if (selectedVertex) { children.Add(selectedVertex); } children.Sort(sortByVertexID); //for loop to go through each vertex and update it's vertexID if it's PAST the selected vertex foreach (GameObject child in children) { VertexManager childsVM = child.GetComponent <VertexManager>(); if (childsVM.getVertexID() >= vertexID) { childsVM.setVertexID(childsVM.getVertexID() + 1); } } //create a new vertex sphere GameObject newVert = drawVert(pos, vertexID, false); VertexManager newVertsVM = newVert.GetComponent <VertexManager>(); //make the new vertex's size and "length" field equal to the one currently selected if (selectedVertex) { newVert.transform.localScale = selectedVertex.transform.lossyScale; newVertsVM.setVertexLength(selectedVertex.GetComponent <VertexManager>().getVertexLength()); } //add this new vertex to the dictionary of vertexmanagers with its current timing timingDict[newVertsVM.getVertexTiming()].Add(newVertsVM); //add this new vertex to the list of children, and sort the list again. children.Add(newVert); children.Sort(sortByVertexID); //create a Vector3[] to hold the positions that the line renderer will be set to. Vector3[] finalPositions = new Vector3[children.Count]; //translate the position of every child and add it to finalPositions. for (int i = 0; i < children.Count; i++) { Vector3 tempPos = children[i].transform.position; tempPos = rotateVertex(tempPos, -getLocalRotation()); //tempPos = vertexRotationTwo(tempPos, localRotation+270, i); finalPositions[i] = tempPos; } //create a new vertex on the line renderer and set it's positions to finalPositions. attachedLR.positionCount += 1; attachedLR.SetPositions(finalPositions); boxColliderManager.addBoxCollider(vertexID); return(newVert); }
//method called when user creates a new vertex while holding another public GameObject addNewVertex() { //if statement to check whether a vertex is currently held if (!currentRigidBody) { //if no held vertex, try to create a new one on a line renderer. GameObject closestBoxCollider = getClosestBoxCollider(); if (closestBoxCollider) { int index = closestBoxCollider.GetComponent <Trigger>().getEndID(); closestBoxCollider.transform.parent.GetComponent <LineManager>().addVertex(gameObject.transform.position, index, null); resetVariables(); } return(null); } else { float clampedY; float clampedTiming; yClamper(out clampedY, out clampedTiming); Vector3 posToSnap = new Vector3(currentGameObject.transform.position.x, clampedY, currentGameObject.transform.position.z); Vector3 snappedY = snap(); return(currentVertexManager.getParentsLineManager().addVertex(snappedY, currentVertexManager.getVertexID(), currentGameObject)); } }
//the main method for this script, used to go through all vertices (spheres) in the environment and update their positions private void getVertexStats() { //get all vertices (spheres) allVertices = GameObject.FindGameObjectsWithTag("Vertex"); foreach (GameObject vertex in allVertices) { //get each vertexManager attached to current vertex (sphere) vertexManager = vertex.GetComponent <VertexManager>(); //Set the vector variables according to the vertice (sphere) position. To do maths on later. xVector.Set(vertex.transform.position.x, 0f, 0f); yVector.Set(0f, vertex.transform.position.y, 0f); zVector.Set(0f, 0f, vertex.transform.position.z); //calculate the distance between the vertices (sphere) x, y, and z cords from the center. xDist = Vector3.Distance(gameObject.transform.position, xVector); yDist = Vector3.Distance(gameObject.transform.position, yVector); zDist = Vector3.Distance(gameObject.transform.position, zVector); if (vertexManager != null && vertexManager.getVertexID() != 0 && vertexManager.getVertexID() != vertexManager.getParentsLineManager().getNumberOfVertices() - 1) { //setting vertex volume by passing x^2 + z^2 to convert volume vertexManager.setVertexVolume(convertVolume((xDist * xDist) + (zDist * zDist))); //setting vertex timing by passing y distance. vertexManager.setVertexTiming(convertTiming(vertex.transform.position.y)); //calling calculateAngle with the vertices (sphere) x and z cordinates, and then setting the vertices note accordingly. float vertexAngle = calculateAngle(vertexManager.transform.position.x, vertexManager.transform.position.z); vertexManager.setVertexAngle(vertexAngle); vertexManager.setVertexNote(convertAngle(vertexAngle)); } } }
//Method used to remove a vertex from a line and return it back to the pool public void removeVertex(Vector3 pos, int vertexID, GameObject selectedVertex) { boxColliderManager.removeBoxCollider(vertexID); //if statement to detect whether the vertex being removed is the last in the line. if (vertexID == attachedLR.positionCount - 1) { //Lower the position count by 1 and return the object to the pool. attachedLR.positionCount -= 1; timingDict[selectedVertex.GetComponent <VertexManager>().getVertexTiming()].Remove(selectedVertex.GetComponent <VertexManager>()); objectPooler.returnToPool("Vertex", selectedVertex); } else { //removing a vertex from the middle of a list //get the children of the lineBase and sort them List <GameObject> children = getChildrenVertices(); children.Sort(sortByVertexID); //go through each vertex sphere that is a child of lineBase and lower it's vertexID by 1 if it is past the vertex being removed. foreach (GameObject child in children) { VertexManager childsVM = child.GetComponent <VertexManager>(); if (childsVM.getVertexID() >= vertexID) { childsVM.setVertexID(childsVM.getVertexID() - 1); } } //Translate the vector3 pos to take into account the position of the baseline object. pos = rotateVertex(pos, -getLocalRotation()); //create a list of final positions that the line renderer vertices will be set too Vector3[] finalPositions = new Vector3[children.Count]; for (int i = 0; i < children.Count; i++) { Vector3 tempPos = children[i].transform.position; tempPos = rotateVertex(tempPos, -getLocalRotation()); finalPositions[i] = tempPos; } //lower the number of vertices in the line renderer by 1, and set the remaining vertices to finalPositions attachedLR.positionCount -= 1; timingDict[selectedVertex.GetComponent <VertexManager>().getVertexTiming()].Remove(selectedVertex.GetComponent <VertexManager>()); attachedLR.SetPositions(finalPositions); //return the removed vertex sphere back to the pool objectPooler.returnToPool("Vertex", selectedVertex); } }
//method to see whether a vertex is currently close enough to the controller to be considered "hovering over" public GameObject hoverOverVertex() { if (GetNearestRigidBody()) { GameObject nearestVertex = GetNearestRigidBody().gameObject; Vector3 nearestVertexVector = nearestVertex.transform.position; if (Vector3.Distance(transform.position, nearestVertexVector) < 0.1f) { //is within range VertexManager nearestVertexManager = nearestVertex.GetComponent <VertexManager>(); if (isEditable(nearestVertexManager.getVertexID(), nearestVertexManager.getBaseLineParent().gameObject)) { //is "editable" return(nearestVertex); } } } return(null); }
//method that is called when the controller should pick up the nearest rigid body public void pickUp() { currentRigidBody = GetNearestRigidBody(); if (!currentRigidBody) { return; } else { //if statement checking the id of the vertex: if (currentRigidBody.GetComponent <VertexManager>().getBaseLineParent().GetComponent <LineManager>().getNumberOfVertices() - 1 == currentRigidBody.GetComponent <VertexManager>().getVertexID()) { //if the id is the last in the line, cycle the voice of the line currentRigidBody.GetComponent <VertexManager>().getParentsLineManager().cycleVoices(); resetVariables(); } else { //set current-XYZ variables currentGameObject = currentRigidBody.gameObject; currentVertexManager = currentRigidBody.GetComponent <VertexManager>(); currentVertexManager.setIsSelected(true); Vector3 oldPos = currentGameObject.transform.position; //set the rigidBody parent and position to the controller holding it. currentRigidBody.transform.parent = gameObject.transform; currentRigidBody.transform.position = transform.position; fixedJoint.connectedBody = currentRigidBody; currentVertexManager.onPickUp(); //if statement to check whether the id of the vertex is editable, if it isn't, act as if a new vertex should be made: if (!isEditable(currentVertexManager.getVertexID(), currentVertexManager.getBaseLineParent().gameObject)) { VertexManager newlyCreatedVertexManager = addNewVertex().GetComponent <VertexManager>(); newlyCreatedVertexManager.moveTo(oldPos); } } } }
//method called by pulse manager to calculate a pulse should be on this line renderer. (and for creating new lead on pulses) public Vector3 interpole(float height, bool playVertex) { float lowerBoundTiming = float.MinValue; float upperBoundTiming = float.MaxValue; int lowerBoundIndex = 0; int upperBoundIndex = 0; int flooredHeight = Mathf.FloorToInt(height); //get all of the children, even ones attached to controllers. List <GameObject> childrenVertices = getAllChildrenVerticesForInterpole(); childrenVertices.Sort(sortByVertexID); //first 1/3 of method used for deducing which 2 vertices the pulse should be between based on a given height. foreach (GameObject Vertex in childrenVertices) { VertexManager currentVertexManager = Vertex.GetComponent <VertexManager>(); if (currentVertexManager.getVertexTiming() >= lowerBoundTiming && currentVertexManager.getVertexTiming() <= height) { lowerBoundTiming = currentVertexManager.getVertexTiming(); lowerBoundIndex = currentVertexManager.getVertexID(); } if (currentVertexManager.getVertexTiming() < upperBoundTiming && currentVertexManager.getVertexTiming() > height && currentVertexManager.getVertexTiming() != upperBoundTiming) { upperBoundTiming = currentVertexManager.getVertexTiming(); upperBoundIndex = currentVertexManager.getVertexID(); } } if (lastHeight > flooredHeight && flooredHeight == 0) { if (playVertex) { foreach (VertexManager vm in timingDict[0]) { vm.playVertex(); } } } else if (lastHeight < flooredHeight) { float diffOfHeights = flooredHeight - lastHeight; if (playVertex && flooredHeight < GridManager.getYSegments() - 1) { foreach (VertexManager vm in timingDict[flooredHeight]) { vm.playVertex(); } } } if (flooredHeight != -1) { lastHeight = flooredHeight; } float difference = upperBoundTiming - lowerBoundTiming; float segment = 1 / difference; float leftover = height - lowerBoundTiming; int numberOfDivs = Mathf.FloorToInt(leftover); float t = (numberOfDivs * segment) + ((leftover % 1) / difference); if (flooredHeight == -1) { //lead on pulse: return(Vector3.Lerp(PulseTranslation(attachedLR.GetPosition(0)), PulseTranslation(attachedLR.GetPosition(1)), 1 - (height * -1))); } else { return(Vector3.Lerp(PulseTranslation(attachedLR.GetPosition(lowerBoundIndex)), PulseTranslation(attachedLR.GetPosition(upperBoundIndex)), t)); } }
//method called when user wants to remove the vertex currently being held from the game. public void removeVertex() { //if statement to check whether a vertex is currently being held: if (!currentRigidBody) { //if no held vertex, try to remove one that may be being hovered over. GameObject nearestVertex = hoverOverVertex(); if (nearestVertex) { nearestVertex.transform.parent = gameObject.transform; VertexManager nearestVertexManager = nearestVertex.GetComponent <VertexManager>(); nearestVertexManager.getParentsLineManager().removeVertex(nearestVertex.transform.position, nearestVertexManager.getVertexID(), nearestVertex); resetVariables(); } } else if (isEditable(currentVertexManager.getVertexID(), currentVertexManager.getBaseLineParent().gameObject)) { //if statement won't be entered if the id of the vertex being held is 1 (because that vertex is needed) currentVertexManager.getParentsLineManager().removeVertex(transform.position, currentVertexManager.getVertexID(), currentGameObject); resetVariables(); } else { return; } }