/// <summary> /// Initializes a new gravity frame from maze frame fitted splines. /// </summary> /// <param name="mazeFrame">Maze frame.</param> /// <param name="mazeFrameSplines">Maze frame fitted splines.</param> /// <param name="closebyDistFac"> Units of max(mazeFrame.Scale) at which nodes are considered close by.</param> /// <param name="junctionDistFac"> Units of max(mazeFrame.Scale) at which nodes are considered close to junction.</param> public GravityFrameController(MazeFrame mazeFrame, MazeFrameSplines mazeFrameSplines, float junctionDistFac, float planeSize) { //float currCloseByDist = mazeFrame.Scale.ComponentMax() * closebyDistFac; float currJunctionDist = mazeFrame.Scale.ComponentMax() * junctionDistFac; GenerateGravityFrameFromSplines(mazeFrame, mazeFrameSplines, currJunctionDist, planeSize); }
private void DestroyCurrentLevel() { if (!LevelIsPresent) { return; } mazeFrame = null; mazeFrameSplines = null; gravityFrameController = null; Destroy(mazeObjects); if (player != null) { player.SetActive(false); } if (cameraRig != null) { cameraRig.SetActive(false); } if (endPortal != null) { endPortal.SetActive(false); } if (cubeOfDeath != null) { Destroy(cubeOfDeath); } if (mindWarpTriggers != null) { Destroy(mindWarpTriggers); } //Destroy(player); //Destroy(cameraRig); //Destroy(cubeOfDeath); //Destroy(endPortal); }
public void PopulateWithSplineFittedShape(MazeFrame mazeFrame, ref MazeFrameSplines mazeFrameSplines, ref GameObject mazeObjects, Vector3 resize, string baseShape) { int objPerCurveSegment = 2; // First, fit splines to maze path segments mazeFrameSplines = new MazeFrameSplines(mazeFrame); // Set color list to use for paths List <Color> colorList = new List <Color>(); GetColorBasedOnPathIndex(new List <int>(1), ref colorList); // Create parent object to hold maze objects mazeObjects = new GameObject("mazeObjects"); mazeObjects.layer = 10; mazeObjects.transform.position = Vector3.zero; mazeObjects.transform.rotation = Quaternion.identity; // Load and resize prefab //string prefabObjName = baseShape + "/" + baseShape + "-20-" + objN; string prefabObjName = baseShape + "/" + baseShape + "-20-1"; GameObject prefabInst = Instantiate(Resources.Load("Prefabs/" + prefabObjName) as GameObject); Vector3 mazeObjectPrefabSize = prefabInst.GetComponent <MeshRenderer>().bounds.size; if (!resize.ComponentsAreApproxEqualTo(mazeObjectPrefabSize)) { Utilities.MeshResize(prefabInst, Vector3.Scale(resize, prefabInst.GetComponent <MeshRenderer>().bounds.size.ComponentInverse())); mazeObjectPrefabSize = prefabInst.GetComponent <MeshRenderer>().bounds.size; } // Create objects and add meshes to fit StartCoroutine(CreateSplineFittedMeshesCoroutine(mazeObjects, mazeFrameSplines, prefabInst, objPerCurveSegment, colorList)); //CreateSplineFittedMeshesCoroutine(mazeObjects, mazeFrameSplines, prefabInst, objPerCurveSegment, colorList); //// Add lights to the sides //GameObject mazeLightObjects = new GameObject("mazeLightObjects"); //mazeLightObjects.transform.position = Vector3.zero; //mazeLightObjects.transform.rotation = Quaternion.identity; //// Load prefab //string prefabLightName = "PathObjectLightBar"; //GameObject prefabLightInst = Instantiate(Resources.Load("Prefabs/" + prefabLightName) as GameObject); //float spacing = 1f; //// Add lights //AddPathObjectLights(mazeLightObjects, mazeFrameSplines, prefabLightInst, spacing, mazeObjectPrefabSize, colorList); }
/// <summary> /// Generate gravity frame from splines fitted to maze frame. /// </summary> /// <param name="mazeFrameSplines">Splines fitted to maze frames.</param> ///// <param name="closebyDist"> Distance at which nodes are considered close by.</param> /// <param name="junctionDist"> Distance at which nodes are considered close to junction.</param> private void GenerateGravityFrameFromSplines(MazeFrame mazeFrame, MazeFrameSplines mazeFrameSplines, float junctionDist, float planeWidth) { // Generate gravity frame based on maze frame fitted splines int nodeCount = 0; foreach (MazeFrameSplines.SplineSegment splineSeg in mazeFrameSplines.SplineSegments) { nodeCount += splineSeg.spline.NSamplesToUse; } gravityFrame = new List <GravityNode>(nodeCount); // Generate sub frame to use later List <List <GravityNode> > segmentSubFrame = new List <List <GravityNode> >(mazeFrameSplines.SplineSegments.Count); // Create nodes for each splines for (int iSpline = 0; iSpline < mazeFrameSplines.SplineSegments.Count; iSpline++) { segmentSubFrame.Add(new List <GravityNode>(mazeFrameSplines.SplineSegments[iSpline].spline.NSamplesToUse)); GravityNode prevNode = null; for (int i = 0; i < mazeFrameSplines.SplineSegments[iSpline].spline.NSamplesToUse; i++) { Vector3 currPos = mazeFrameSplines.SplineSegments[iSpline].spline.GetPointOnSpline(mazeFrameSplines.SplineSegments[iSpline].spline.SampleIndToT(i)); Vector3 currTang = mazeFrameSplines.SplineSegments[iSpline].spline.GetTangentToPointOnSpline(mazeFrameSplines.SplineSegments[iSpline].spline.SampleIndToT(i)).normalized; Vector3 currNorm = mazeFrameSplines.SplineSegments[iSpline].spline.DefaultGetNormalAtT(mazeFrameSplines.SplineSegments[iSpline].spline.SampleIndToT(i)).normalized; Vector3 cross = Vector3.Cross(currTang, currNorm); Vector3[] planePoints = new Vector3[2] { currPos + (cross * (planeWidth / 2f)), currPos - (cross * (planeWidth / 2f)) }; GravityNode node = new GravityNode(currPos, iSpline + "-" + currPos.ToString(), planePoints); if (prevNode != null) { node.neighbors.Add(prevNode); prevNode.neighbors.Add(node); } // Determine if near junction if (mazeFrameSplines.SplineSegments[iSpline].startNeighbors.Count > 0) { if (Vector3.Distance(currPos, mazeFrameSplines.SplineSegments[iSpline].spline.GetPointOnSpline(0)) < junctionDist) { node.nearJunction = true; } } if (mazeFrameSplines.SplineSegments[iSpline].endNeighbors.Count > 0) { if (Vector3.Distance(currPos, mazeFrameSplines.SplineSegments[iSpline].spline.GetPointOnSpline(1)) < junctionDist) { node.nearJunction = true; } } // Add to frame gravityFrame.Add(node); prevNode = node; // Add spline segment sub-frame as well segmentSubFrame[iSpline].Add(node); } } // Create closeby list from, and connect, neighboring splines for (int iSeg = 0; iSeg < mazeFrameSplines.SplineSegments.Count; iSeg++) { // Add frame to its own closeby List <GravityNode> currSubFrame = segmentSubFrame[iSeg]; foreach (GravityNode node in currSubFrame) { node.closeby.AddRange(currSubFrame); } // Start/end of spline List <List <MazeFrameSplines.SplineSegment> > segList = new List <List <MazeFrameSplines.SplineSegment> >(2) { mazeFrameSplines.SplineSegments[iSeg].startNeighbors, mazeFrameSplines.SplineSegments[iSeg].endNeighbors }; for (int iStartEnd = 0; iStartEnd <= 1; iStartEnd++) { foreach (MazeFrameSplines.SplineSegment neighSeg in segList[iStartEnd]) { // Get sub frame index List <GravityNode> neighSegSF = segmentSubFrame[mazeFrameSplines.SplineSegments.IndexOf(neighSeg)]; // Add to closeby list foreach (GravityNode node in currSubFrame) { node.closeby.AddRange(neighSegSF); } // Connect start/end switch (iStartEnd) { case 0: { if (Vector3.Distance(currSubFrame[0].position, neighSegSF[0].position) < Vector3.Distance(currSubFrame[0].position, neighSegSF[neighSegSF.Count - 1].position)) { currSubFrame[0].neighbors.Add(neighSegSF[0]); } else { currSubFrame[0].neighbors.Add(neighSegSF[neighSegSF.Count - 1]); } break; } case 1: { if (Vector3.Distance(currSubFrame[currSubFrame.Count - 1].position, neighSegSF[0].position) < Vector3.Distance(currSubFrame[currSubFrame.Count - 1].position, neighSegSF[neighSegSF.Count - 1].position)) { currSubFrame[currSubFrame.Count - 1].neighbors.Add(neighSegSF[0]); } else { currSubFrame[currSubFrame.Count - 1].neighbors.Add(neighSegSF[neighSegSF.Count - 1]); } break; } } } } } }
private IEnumerator CreateSplineFittedMeshesCoroutine(GameObject mazeObjects, MazeFrameSplines mazeFrameSplines, GameObject prefabInst, int objPerCurveSegment, List <Color> colorList) { MazeObjectsPlaced = 0; // First, setup the shared materials that will be modified. Dictionary <int, Material> materials = new Dictionary <int, Material>(); foreach (MazeFrameSplines.SplineSegment seg in mazeFrameSplines.SplineSegments) { if (seg.shortestPathInd.Count == 1) { if (materials.ContainsKey(seg.shortestPathInd[0])) { continue; } Material mat = Object.Instantiate(prefabInst.GetComponent <MeshRenderer>().material); mat.SetColor("_EmissionColor", GetColorBasedOnPathIndex(seg.shortestPathInd, ref colorList)); materials.Add(seg.shortestPathInd[0], mat); } } Material materialBlack = Object.Instantiate(prefabInst.GetComponent <MeshRenderer>().material); materialBlack.SetColor("_EmissionColor", Color.black); //List<Color> colorList = new List<Color>(); //Dictionary<List<int>, Material> materials = new Dictionary<List<int>, Material>(); //foreach (MazeFrameSplines.SplineSegment seg in mazeFrameSplines.SplineSegments) //{ // if (materials.ContainsListKeyWithContents(seg.shortestPathInd)) { continue; } // Material mat = Object.Instantiate(prefabInst.GetComponent<MeshRenderer>().material); // mat.SetColor("_EmissionColor", GetColorBasedOnPathIndex(seg.shortestPathInd, ref colorList)); // materials.Add(seg.shortestPathInd, mat); //} // Per spline, create gameobject holding the mesh //Dictionary<string, GameObject> processedPrefabInstances = new Dictionary<string, GameObject>(); int count = 0; foreach (MazeFrameSplines.SplineSegment segment in mazeFrameSplines.SplineSegments) { GameObject obj = Object.Instantiate(prefabInst, mazeObjects.transform) as GameObject; string junctionAffix = ""; if (segment.isJunction) { junctionAffix = "junction_" + segment.JunctionID + "_"; } obj.name = junctionAffix + "spline_" + segment.spline.startPoint.ToString() + "_" + segment.spline.endPoint.ToString(); obj.layer = 10; // Attached SplineFittedMesh script and initilaze with prefab obj.AddComponent(typeof(SplineFittedMesh)); SplineFittedMesh splineMesh = obj.GetComponent <SplineFittedMesh>(); splineMesh.SetSplineAxis(Vector3.forward); splineMesh.SetSpline(segment.spline); splineMesh.SetNMeshesPerSegment(objPerCurveSegment); Mesh[] meshes; if (mazeFrameSplines.ShortestPathInd.Count > 1) { meshes = new Mesh[] { Instantiate(obj.GetComponent <MeshFilter>().mesh), Instantiate(obj.GetComponent <MeshFilter>().mesh) }; } else { meshes = new Mesh[] { Instantiate(obj.GetComponent <MeshFilter>().mesh) }; } splineMesh.SetMeshBase(meshes); // Set segment color to first color if only one path, or determine multiple colors below if (mazeFrameSplines.ShortestPathInd.Count == 1) { obj.GetComponent <MeshRenderer>().sharedMaterial = materials[0]; } else { // Determine segment color based on start/end neighbors if segment color itself is ambigious Material[] mats = new Material[2]; if (segment.shortestPathInd.Count == 1) { mats[0] = materials[segment.shortestPathInd[0]]; mats[1] = materials[segment.shortestPathInd[0]]; } else { // Start if (segment.shortestPathIndAtStart.Count == 1) { mats[0] = materials[segment.shortestPathIndAtStart[0]]; } else { if (segment.shortestPathIndAtEnd.Count == 1) { mats[0] = materials[segment.shortestPathIndAtEnd[0]]; } else { mats[0] = materialBlack; } } // End if (segment.shortestPathIndAtEnd.Count == 1) { mats[1] = materials[segment.shortestPathIndAtEnd[0]]; } else { if (segment.shortestPathIndAtStart.Count == 1) { mats[1] = materials[segment.shortestPathIndAtStart[0]]; } else { mats[1] = materialBlack; } } } if (mats[0] == materialBlack && mats[1] == materialBlack && segment.shortestPathIndAtStart.EqualContents(segment.shortestPathIndAtEnd) && segment.shortestPathIndAtStart.Count == 2 && segment.shortestPathIndAtEnd.Count == 2) { mats[0] = materials[segment.shortestPathInd[0]]; mats[1] = materials[segment.shortestPathInd[1]]; } // Assign to object obj.GetComponent <MeshRenderer>().sharedMaterials = mats; } // Increment global counter MazeObjectsPlaced++; // Yield count++; if ((count % 200) == 0) { yield return(null); } } // Destroy processed prefab instances Object.Destroy(prefabInst); }
public void PlaceCubeOfDeath(ref GameObject cubeParent, Vector3 position, Vector3 scale, Vector3 mazeFrameScale, MazeFrameSplines mazeFrameSplines) { if (cubeParent != null) { Object.Destroy(cubeParent); cubeParent = null; } cubeParent = new GameObject("CubesOfDeath"); GameObject cube = Object.Instantiate(Resources.Load("Prefabs/" + "CubeOfDeath"), cubeParent.transform) as GameObject; cube.transform.position = position; cube.transform.localScale = Vector3.zero; cube.name = "CubeOfDeath"; CubeOfDeathController cubeOfDeathController = cube.GetComponent <CubeOfDeathController>(); CubeOfDeathController.MazeScale = mazeFrameScale; CubeOfDeathController.MazeFrameSplines = mazeFrameSplines; CubeOfDeathController.cubeScale = scale; cubeOfDeathController.Activate(); //cube.SetActive(true); }
private void AddPathObjectLights(GameObject mazeLightObjects, MazeFrameSplines mazeFrameSplines, GameObject prefabInst, float spacing, Vector3 mazeObjectPrefabSize, List <Color> colorList) { // First, setup the shared materials that will be modified. Dictionary <int, Material> materials = new Dictionary <int, Material>(); foreach (MazeFrameSplines.SplineSegment seg in mazeFrameSplines.SplineSegments) { if (seg.shortestPathInd.Count == 1) { if (materials.ContainsKey(seg.shortestPathInd[0])) { continue; } Material mat = Object.Instantiate(prefabInst.GetComponent <MeshRenderer>().material); mat.SetColor("_EmissionColor", GetColorBasedOnPathIndex(seg.shortestPathInd, ref colorList)); materials.Add(seg.shortestPathInd[0], mat); } } Material materialBlack = Object.Instantiate(Resources.Load("Materials/" + "PathObjectLight")) as Material; materialBlack.SetColor("_EmissionColor", Color.black); // Per spline, create lights Vector3 lightSize = prefabInst.GetComponent <MeshRenderer>().bounds.size; int count = 0; foreach (MazeFrameSplines.SplineSegment segment in mazeFrameSplines.SplineSegments) { // Create parent object GameObject parent = new GameObject("segment" + count); parent.transform.parent = mazeLightObjects.transform; parent.transform.position = Vector3.zero; parent.transform.rotation = Quaternion.identity; parent.AddComponent <MeshFilter>(); parent.AddComponent <MeshRenderer>(); // Set color based on shortest path ind. if (segment.shortestPathInd.Count == 1) { parent.GetComponent <MeshRenderer>().sharedMaterial = materials[segment.shortestPathInd[0]]; } else { parent.GetComponent <MeshRenderer>().sharedMaterial = materialBlack; } // Determine total number of lights to place, and place them equally spaced int nLights = Mathf.RoundToInt(segment.spline.SplineTotalDistance / (lightSize.z + spacing)); float currSpacing = (segment.spline.SplineTotalDistance - (lightSize.z * nLights)) / nLights; // Place lights for (int iLight = 0; iLight < nLights; iLight++) { // Get current spline vectors and set base position/rotation of light float currDist = ((lightSize.z + currSpacing) / 2f) + iLight * (lightSize.z + currSpacing); float currT = segment.spline.GetTAtDistance(currDist); Vector3 currTangent = segment.spline.GetTangentToPointOnSpline(currT); Vector3 currNormal = segment.spline.DefaultGetNormalAtT(currT); Vector3 currReference = Vector3.Cross(currNormal, currTangent).normalized; Quaternion baseRotation = Quaternion.LookRotation(currTangent); Vector3 basePosition = segment.spline.GetPointOnSpline(currT); Vector3 offset = ((mazeObjectPrefabSize.x / 2f) + (lightSize.x / 2f)) * currReference; // Place light object left/right foreach (Vector3 currOffset in new Vector3[] { -offset, offset }) { GameObject obj = Object.Instantiate(prefabInst, basePosition + currOffset, baseRotation, parent.transform) as GameObject; // Set color based on shortest path ind. if (segment.shortestPathInd.Count == 1) { obj.GetComponent <MeshRenderer>().sharedMaterial = materials[segment.shortestPathInd[0]]; } else { obj.GetComponent <MeshRenderer>().sharedMaterial = materialBlack; } // Increment global counter MazeObjectsPlaced++; } } // Merge into one object Utilities.MergeChildrenOfParent(parent, true, true, true); count++; } // Destroy processed prefab instances Object.Destroy(prefabInst); }
public void PopulateWithSplineFittedBars(MazeFrame mazeFrame, ref MazeFrameSplines mazeFrameSplines, ref GameObject mazeObjects, Vector3 resize) { PopulateWithSplineFittedShape(mazeFrame, ref mazeFrameSplines, ref mazeObjects, resize, "MazeBar"); }