private PuzzleData GeneratePuzzle(int i_puzzleIndex, IPuzzleGenerator i_puzzleGeneratorIF, Vector3 i_startingPosition) { PuzzleData puzzleData = i_puzzleGeneratorIF.GeneratePuzzle(m_width, m_emulatedState.m_difficulty, m_forwardCellsPerSideways); Vector2Int gridSize = new Vector2Int(puzzleData.Width, puzzleData.Height); GameObject[,] spawnedObjects = new GameObject[gridSize.x, gridSize.y]; m_spawnedObjects.Add(i_puzzleIndex, spawnedObjects); for (int x = 0; x < puzzleData.Width; ++x) { for (int y = 0; y < puzzleData.Height; ++y) { PuzzleCell cell = puzzleData.GetCell(x, y); if (cell.m_prefabToSpawn != null) { spawnedObjects[x, y] = Instantiate(cell.m_prefabToSpawn, i_startingPosition + new Vector3(x * m_cellSize, 0, y * m_cellSize), Quaternion.identity, transform); } } } // Link for (int x = 0; x < puzzleData.Width; ++x) { for (int y = 0; y < puzzleData.Height; ++y) { PuzzleCell cell = puzzleData.GetCell(x, y); if (cell.m_cellsToLinkTo != null) { foreach (Vector2Int cellCoords in cell.m_cellsToLinkTo) { GameObject objectToLinkFrom = spawnedObjects[x, y]; GameObject objectToLinkTo = spawnedObjects[cellCoords.x, cellCoords.y]; foreach (IActivator activator in objectToLinkFrom.GetComponents <IActivator>()) { foreach (IActivatee activatee in objectToLinkTo.GetComponents <IActivatee>()) { activator.AssignActivee(activatee); } } } } } } return(puzzleData); }
public GameBoardVMFactory(IPuzzleGenerator puzzleGenerator) { _puzzleGenerator = puzzleGenerator; }
private IEnumerator GeneratePuzzle(IPuzzleGenerator i_puzzleGeneratorIF, float i_difficulty, float i_startingSplineT, float i_startingSplineTClamped) { PuzzleData puzzleData = i_puzzleGeneratorIF.GeneratePuzzle(m_trackWidthInCells, i_difficulty, m_forwardCellsPerSideways); AddRandomStuff(puzzleData, i_difficulty); SplineTransformData puzzleStartTransformData = m_spline.CalculateAproxSplineTransformData(i_startingSplineTClamped); Vector2Int gridSize = new Vector2Int(puzzleData.Width, puzzleData.Height); SpawnedPuzzle spawnedPuzzleData = new SpawnedPuzzle(); spawnedPuzzleData.m_spawnedObjects = new GameObject[gridSize.x, gridSize.y]; spawnedPuzzleData.m_startPuzzleHeight = m_runningDistancePS; spawnedPuzzleData.m_endPuzzleHeight = m_runningDistancePS + puzzleData.Height; spawnedPuzzleData.m_puzzleData = puzzleData; spawnedPuzzleData.m_startTransformData = puzzleStartTransformData; m_spawnedPuzzles.Enqueue(spawnedPuzzleData); float GetT(int i_y) { return((i_startingSplineTClamped + i_y * m_trackTPerCell) % 1f); } // Work out if we need to offset the starting spline T float trackLength = m_spline.Length; float puzzleTLength = (puzzleData.Height * m_cellSize) / trackLength; float totalAddedT = 0f; while (!m_spline.DoesTRangeSupportPuzzles(i_startingSplineT, i_startingSplineT + puzzleTLength, out float nextValidT)) { totalAddedT += (nextValidT - i_startingSplineT); i_startingSplineT = nextValidT; i_startingSplineTClamped = i_startingSplineT % 1f; yield return(0); } m_runningDistancePS += Mathf.CeilToInt(totalAddedT * trackLength / m_cellSize); // Lets figure out wtf we need to spawn this crap for (int y = 0; y < puzzleData.Height; ++y) { // Every time we go up one we need to find our new transform info float splineT = GetT(y); SplineTransformData splineTransformData = m_spline.CalculateAproxSplineTransformData(splineT); int timesAroundTrack = Mathf.FloorToInt(i_startingSplineT); if (timesAroundTrack % 2 == 1) // If odd, flip { splineTransformData.m_worldUp = -splineTransformData.m_worldUp; } m_splineTransformsCalulated.Add(splineTransformData); Vector3 puzzleLeftPos = splineTransformData.m_worldPos - (Vector3.Cross(splineTransformData.m_worldUp.normalized, splineTransformData.m_worldFwd.normalized) * m_cellSize * (m_trackWidthInCells - 1) / 2f); Quaternion objectRotation = Quaternion.LookRotation(splineTransformData.m_worldFwd.normalized, splineTransformData.m_worldUp.normalized); for (int x = 0; x < puzzleData.Width; ++x) { PuzzleCell cell = puzzleData.GetCell(x, y); if (cell.m_prefabToSpawn != null) { Vector3 positionToSpawn = puzzleLeftPos + (objectRotation * new Vector3(x * m_cellSize, 0, 0)); Quaternion rotationToSpawn = objectRotation; // Adjust because the track isn't actually flat all the way along // Lift above the track Vector3 raycastFrom = positionToSpawn + splineTransformData.m_worldUp * m_upwardProjectionLengthBeforeDownwardRaycast; if (Physics.Raycast(new Ray(raycastFrom, -splineTransformData.m_worldUp), out RaycastHit hit, m_downwardRaycastLength, m_trackLayer)) { // Adjust positionToSpawn = hit.point; rotationToSpawn = Quaternion.LookRotation(splineTransformData.m_worldFwd.normalized, hit.normal.normalized); } spawnedPuzzleData.m_spawnedObjects[x, y] = Instantiate(cell.m_prefabToSpawn, positionToSpawn, cell.m_prefabRotation * rotationToSpawn, transform); spawnedPuzzleData.m_spawnedObjects[x, y].transform.localScale *= m_modelScaler; } } yield return(0); } // Link for (int x = 0; x < puzzleData.Width; ++x) { for (int y = 0; y < puzzleData.Height; ++y) { PuzzleCell cell = puzzleData.GetCell(x, y); if (cell.m_cellsToLinkTo != null) { foreach (Vector2Int cellCoords in cell.m_cellsToLinkTo) { GameObject objectToLinkFrom = spawnedPuzzleData.m_spawnedObjects[x, y]; GameObject objectToLinkTo = spawnedPuzzleData.m_spawnedObjects[cellCoords.x, cellCoords.y]; foreach (IActivator activator in objectToLinkFrom.GetComponents <IActivator>()) { foreach (IActivatee activatee in objectToLinkTo.GetComponents <IActivatee>()) { activator.AssignActivee(activatee); } } } } } } }