示例#1
0
    private IEnumerator Generate(int seed, bool gameStart)
    {
        Debug.Log("GENERATING WITH SEED = " + seed);
        IsGenerating = true;


        //Debug.Log("random value : " + Random.Range(0,999));

        //instancedObjects = Instantiate(new GameObject("InstancedObjects"), this.transform).transform;

        GameObject player = GameObject.FindWithTag("Player");

        if (Application.isPlaying)
        {
            //Debug.Log("Triggering camera effect...");
            player.GetComponentInChildren <CameraResolutionManager>().TriggerEvolution(gameStart);
            if (!gameStart)
            {
                yield return(new WaitForSeconds(player.GetComponentInChildren <CameraResolutionManager>().cycleDuration / 2f));
            }
        }

        CleanUp();

        Random.InitState(seed);

        audioRegular.StopAll();
        //audioRegular.StopAll();


        List <int> musicIndexes = new List <int>()
        {
            0, 1, 2, 3, 4, 5, 6
        };
        int musicAmount = Random.Range(minMusicAmount, maxMusicAmount + 1);
        int pitchIndex  = Random.Range(0, audioRegular.maxPitchIndex);

        for (int i = 0; i < musicAmount; i++)
        {
            int musicIndex = musicIndexes[Random.Range(0, musicIndexes.Count)];
            musicIndexes.Remove(musicIndex);

            audioRegular.SetupMusic(musicIndex, pitchIndex);
            audioAlternate.SetupMusic(musicIndex, pitchIndex);
        }


        float hueshift    = hueshiftValues[Random.Range(0, hueshiftValues.Length)];
        float saturation  = saturationValues[Random.Range(0, saturationValues.Length)];
        float temperature = temperatureValues[Random.Range(0, temperatureValues.Length)];
        float tint        = tintValues[Random.Range(0, tintValues.Length)];

        ColorGradingModel.Settings colorGradingWater = waterPP.colorGrading.settings;
        ColorGradingModel.Settings colorGradingMain  = mainPP.colorGrading.settings;

        colorGradingWater.basic.hueShift    = hueshift;
        colorGradingWater.basic.saturation  = saturation;
        colorGradingWater.basic.temperature = temperature;
        colorGradingWater.basic.tint        = tint;

        colorGradingMain.basic.hueShift    = hueshift;
        colorGradingMain.basic.saturation  = saturation;
        colorGradingMain.basic.temperature = temperature;
        colorGradingMain.basic.tint        = tint;

        waterPP.colorGrading.settings = colorGradingWater;
        mainPP.colorGrading.settings  = colorGradingMain;


        float azimuth   = Random.Range(0f, 360f);
        float ascension = lightAngleOrigin + lightAngleAmplitude * Random.Range(-1f, 1f);

        sunLight.transform.rotation = Quaternion.Euler(ascension, azimuth, 0f);
        float timeOfDayFactor = (ascension - (lightAngleOrigin - lightAngleAmplitude)) / (2 * lightAngleAmplitude);

        sunLight.GetComponent <Light>().intensity = Mathf.Lerp(lightIntensityMin, lightIntensityMax, timeOfDayFactor);

        float skyValue     = Mathf.Lerp(skyValueMin, skyValueMax, timeOfDayFactor);
        float horizonValue = Mathf.Lerp(horizonValueMin, horizonValueMax, timeOfDayFactor);
        //Debug.Log("timeOfDayFactor = " + timeOfDayFactor);


        // sky ============================
        float hue1      = Random.Range(0f, 1f);
        float hueDelta  = Mathf.Lerp(hueDiffMin, hueDiffMax, Random.value);
        float hue2      = (hue1 + hueDelta) % 1f;
        Color skyColor1 = Color.HSVToRGB(hue1, skySaturation, skyValue);
        Color skyColor2 = Color.HSVToRGB(hue2, horizonSaturation, horizonValue);

        sunLight.GetComponent <Light>().color = skyColor1;
        //float atmosphereThickness = skyThicknessOrigin + skyThicknessAmplitude * Random.Range(-1f, 1f);

        sky.SetColor("_Color1", skyColor1);
        sky.SetColor("_Color2", skyColor2);
        //RenderSettings.fog = false;
        RenderSettings.fogColor = skyColor2;
        currentFogColor         = skyColor2;
        //RenderSettings.fog = true;

        Debug.Log("horizon color : " + skyColor2 + " // fog color : " + RenderSettings.fogColor);
        //sky.SetFloat("_AtmosphereThickness", atmosphereThickness);

        float cloudIntensity = cloudIntensityOrigin + cloudIntensityAmplitude * Random.Range(-1f, 1f);

        clouds.LS_CloudIntensity = cloudIntensity;

        float cloudThickness = cloudThicknessOrigin + cloudThicknessAmplitude * Random.Range(-1f, 1f);

        clouds.LS_CloudThickness = cloudThickness;


        hmPerlinSeed   = new Vector2Int(Random.Range(0, 999), Random.Range(0, 999));
        hmPerlinSeed2  = new Vector2Int(Random.Range(0, 999), Random.Range(0, 999));
        detPerlinSeed  = new Vector2Int(Random.Range(0, 999), Random.Range(0, 999));
        detPerlinSeed2 = new Vector2Int(Random.Range(0, 999), Random.Range(0, 999));

        int heightCurveIndex = Random.Range(0, radialHeightFactor.Length);

        // water

        Color waterColor = Random.ColorHSV(0f, 1f, waterSaturation, waterSaturation, waterValue, waterValue);

        waterColor.a = waterAlpha;

        waterMat.SetColor("_BaseColor", waterColor);
        //waterMat.SetColor("_BaseColor", waterColor);


        // Debug.Log("Generating heightmap...");

        int heightMapWidth = terrain.terrainData.heightmapWidth;

        terrainSizeOverride      = new Vector3(terrainSizeXZ, baseAltitude, terrainSizeXZ);
        terrainSizeOverride.y   += Random.Range(-1f, 1f) * altitudeAmplitude;
        terrain.terrainData.size = terrainSizeOverride;
        Vector3 terrainCenterWorldPos = terrain.transform.position + new Vector3(0.5f * terrainSizeOverride.x, 0f, 0.5f * terrainSizeOverride.z);

        Vector2Int heightMapCenter = new Vector2Int(heightMapWidth / 2, heightMapWidth / 2);

        float[,] heightMap = new float[heightMapWidth, heightMapWidth];

        float hmPerlinScale  = hmPerlinScaleOrigin + Random.Range(-1f, 1f) * hmPerlinScaleAmplitude;
        float hmPerlinScale2 = hmPerlinScaleOrigin2 + Random.Range(-1f, 1f) * hmPerlinScaleAmplitude2;

        for (int x = 0; x < heightMapWidth; x++)
        {
            for (int y = 0; y < heightMapWidth; y++)
            {
                float distanceToCenter = Vector2Int.Distance(heightMapCenter, new Vector2Int(x, y)) / (heightMapWidth / 2);
                float normalizedHeight = (1 - hmHarmonicFactor) * Mathf.PerlinNoise((hmPerlinSeed.x + x) * hmPerlinScale, (hmPerlinSeed.y + y) * hmPerlinScale);
                normalizedHeight += (hmHarmonicFactor) * Mathf.PerlinNoise((hmPerlinSeed2.x + x) * hmPerlinScale2, (hmPerlinSeed2.y + y) * hmPerlinScale2);
                heightMap[x, y]   = normalizedHeight * radialHeightFactor[heightCurveIndex].Evaluate(distanceToCenter);
            }
        }

        terrain.terrainData.SetHeights(0, 0, heightMap);

        //Debug.Log("Generating alpha map...");

        int alphaMapWidth     = terrain.terrainData.alphamapWidth;
        int alphaTextureCount = 4;

        float[,,] alphaMap = new float[alphaMapWidth, alphaMapWidth, alphaTextureCount];
        float waterTexHeight    = waterHeightNormalized * terrainSizeOverride.y + waterTextHeightOffset;
        float baseTextureHeight = waterTexHeight + smoothingHeight;
        bool  rockyWorld        = Random.value < rockyWorldProbability;
        int   waterIndex        = rockyWorld ? 3 : 1;
        int   groundIndex       = rockyWorld ? 2 : 0;
        int   unused1           = rockyWorld ? 0 : 2;
        int   unused2           = rockyWorld ? 1 : 3;

        for (int x = 0; x < alphaMapWidth; x++)
        {
            for (int y = 0; y < alphaMapWidth; y++)
            {
                float height = heightMap[x, y] * terrainSizeOverride.y;

                alphaMap[x, y, unused1] = 0;
                alphaMap[x, y, unused2] = 0;

                if (height < waterTexHeight)
                {
                    alphaMap[x, y, groundIndex] = 0;
                    alphaMap[x, y, waterIndex]  = 1;
                }
                else if (height > baseTextureHeight)
                {
                    alphaMap[x, y, groundIndex] = 1;
                    alphaMap[x, y, waterIndex]  = 0;
                }
                else
                {
                    alphaMap[x, y, groundIndex] = (height - waterTexHeight) / smoothingHeight;
                    alphaMap[x, y, waterIndex]  = 1f - (height - waterTexHeight) / smoothingHeight;
                }
            }
        }

        terrain.terrainData.SetAlphamaps(0, 0, alphaMap);

        // Debug.Log("Generating detail map...");

        int detailMapWidth = terrain.terrainData.detailWidth;

        int[,] detailMap0 = new int[detailMapWidth, detailMapWidth];
        int[,] detailMap1 = new int[detailMapWidth, detailMapWidth];

        for (int x = 0; x < detailMapWidth; x++)
        {
            for (int y = 0; y < detailMapWidth; y++)
            {
                float detail = (1 - detHarmonicFactor) * Mathf.PerlinNoise((detPerlinSeed.x + x) * detPerlinScale, (detPerlinSeed.y + y) * detPerlinScale);
                detail += (detHarmonicFactor) * Mathf.PerlinNoise((detPerlinSeed2.x + x) * detPerlinScale2, (detPerlinSeed2.y + y) * detPerlinScale2);
                if (detail < detPerlinThreshold || heightMap[x, y] < minAltitudeNormalized || heightMap[x, y] > maxAltitudeNormalized)
                {
                    detail = 0f;
                }
                else
                {
                    detail = 1f;
                }
                if (heightMap[x, y] > waterHeightNormalized)
                {
                    detailMap0[x, y] = (int)(grassDensity * detail);
                }
                else
                {
                    detailMap1[x, y] = (int)(alguaeDensity * detail);
                }
            }
        }

        terrain.terrainData.SetDetailLayer(0, 0, 0, detailMap0);
        terrain.terrainData.SetDetailLayer(0, 0, 1, detailMap1);


        //Debug.Log("Placing temple...");

        float   templeHeight = 0f + terrain.terrainData.GetHeight(heightMapWidth / 2, heightMapWidth / 2);
        Vector3 position     = terrainCenterWorldPos + Vector3.up * templeHeight;

        temple.transform.position = position;

        //Debug.Log("Placing player...");

        player.transform.position = playerSpawn.position;

        //Debug.Log("Placing water...");

        float waterHeight = waterHeightNormalized * terrainSizeOverride.y;

        position = terrainCenterWorldPos + Vector3.up * waterHeight;
        water.transform.position = position;


        int snowDensityIndex = Random.Range(0, snowDensities.Length);

        snow.maxParticles = snowDensities[snowDensityIndex];

        // ruins ============================

        //Debug.Log("Placing ruins...");

        int ruinAmount = ruinAmounts[Random.Range(0, ruinAmounts.Length)];

        GameObject ruinPrebab = ruinsPrefabs[Random.Range(0, ruinsPrefabs.Length)];

        for (int i = 0; i < ruinAmount; i++)
        {
            azimuth = Random.Range(0f, 360f) * Mathf.Deg2Rad;
            float distance = Mathf.Lerp(minDistanceNormalized, maxDistanceNormalized, (float)i / (ruinAmount - 1));
            position = new Vector3(distance * Mathf.Cos(azimuth), 0f, distance * Mathf.Sin(azimuth));
            //position.y = terrain.terrainData.GetHeight((int)position.x, (int)position.z);
            position.x = position.x * terrainSizeOverride.x * 0.5f + terrainCenterWorldPos.x;
            position.z = position.z * terrainSizeOverride.z * 0.5f + terrainCenterWorldPos.z;
            position.y = GetWorldYAtWorldXZ(position.x, position.z);
            Quaternion rotation = Quaternion.Euler(0f, Random.Range(0, 360), 0f);
            GameObject ruin     = Instantiate(ruinPrebab, position, rotation, instancedObjects);
        }

        for (int i = 0; i < NPCs.Length; i++)
        {
            NPCs[i].gameObject.SetActive(true);
            NPCs[i].useNavmesh = useNavmesh;

            azimuth = Random.Range(0f, 360f) * Mathf.Deg2Rad;
            float distance = Mathf.Lerp(minDistanceNormalized, maxDistanceNormalized, (float)i / (NPCs.Length - 1));
            position = new Vector3(distance * Mathf.Cos(azimuth), 0f, distance * Mathf.Sin(azimuth));
            //position.y = terrain.terrainData.GetHeight((int)position.x, (int)position.z);
            position.x = position.x * terrainSizeOverride.x * 0.5f + terrainCenterWorldPos.x;
            position.z = position.z * terrainSizeOverride.z * 0.5f + terrainCenterWorldPos.z;
            position.y = GetWorldYAtWorldXZ(position.x, position.z);
            //Quaternion rotation = Quaternion.Euler(0f, Random.Range(0, 360), 0f);
            //GameObject ruin = Instantiate(ruinPrebab, position, rotation, instancedObjects);
            NPCs[i].transform.position = position;
            if (!useNavmesh)
            {
                NPCs[i].AdjustPosition();
            }
        }

        if (useNavmesh)
        {
            StartCoroutine(BuildNavmesh(terrain.GetComponent <NavMeshSurface>()));
        }


        IsGenerating = false;
    }