c# / unity programming

本文关键字:programming unity | 更新日期: 2023-09-27 18:34:48

编程

新手,一月份才开始上课。 所以如果有人能帮我制作 2 段代码 1,我将不胜感激。 我想做的是在统一中制作无限的地形,然后地形应该程序化地生成。 这两段代码都已经完成,但我不知道如何让它们协同工作......请帮忙。

我想使地形无限并且已经有了代码,但是在程序生成中,我只能使它像这样在指定的数字上工作(2(。 见下文

//Terrain settings
    public int m_tilesX = 2; //Number of terrain tiles on the x axis
    public int m_tilesZ = 2; //Number of terrain tiles on the z axis
    public float m_pixelMapError = 6.0f; //A lower pixel error will draw terrain at a higher Level of detail but will be slower
    public float m_baseMapDist = 1000.0f; //The distance at which the low res base map will be drawn. Decrease to increase performance

无限地形-

using UnityEngine;
using System.Collections;
public class InfiniteTerrain : MonoBehaviour
{
    public GameObject PlayerObject;
    private Terrain[,] _terrainGrid = new Terrain[3,3];
    void Start ()
    {
        Terrain linkedTerrain = gameObject.GetComponent<Terrain>();
        _terrainGrid[0,0] = Terrain.CreateTerrainGameObject(linkedTerrain.terrainData).GetComponent<Terrain>();
        _terrainGrid[0,1] = Terrain.CreateTerrainGameObject(linkedTerrain.terrainData).GetComponent<Terrain>();
        _terrainGrid[0,2] = Terrain.CreateTerrainGameObject(linkedTerrain.terrainData).GetComponent<Terrain>();
        _terrainGrid[1,0] = Terrain.CreateTerrainGameObject(linkedTerrain.terrainData).GetComponent<Terrain>();
        _terrainGrid[1,1] = linkedTerrain;
        _terrainGrid[1,2] = Terrain.CreateTerrainGameObject(linkedTerrain.terrainData).GetComponent<Terrain>();
        _terrainGrid[2,0] = Terrain.CreateTerrainGameObject(linkedTerrain.terrainData).GetComponent<Terrain>();
        _terrainGrid[2,1] = Terrain.CreateTerrainGameObject(linkedTerrain.terrainData).GetComponent<Terrain>();
        _terrainGrid[2,2] = Terrain.CreateTerrainGameObject(linkedTerrain.terrainData).GetComponent<Terrain>();
        UpdateTerrainPositionsAndNeighbors();
    }
    private void UpdateTerrainPositionsAndNeighbors()
    {
        _terrainGrid[0,0].transform.position = new Vector3(
            _terrainGrid[1,1].transform.position.x - _terrainGrid[1,1].terrainData.size.x,
            _terrainGrid[1,1].transform.position.y,
            _terrainGrid[1,1].transform.position.z + _terrainGrid[1,1].terrainData.size.z);
        _terrainGrid[0,1].transform.position = new Vector3(
            _terrainGrid[1,1].transform.position.x - _terrainGrid[1,1].terrainData.size.x,
            _terrainGrid[1,1].transform.position.y,
            _terrainGrid[1,1].transform.position.z);
        _terrainGrid[0,2].transform.position = new Vector3(
            _terrainGrid[1,1].transform.position.x - _terrainGrid[1,1].terrainData.size.x,
            _terrainGrid[1,1].transform.position.y,
            _terrainGrid[1,1].transform.position.z - _terrainGrid[1,1].terrainData.size.z);
        _terrainGrid[1,0].transform.position = new Vector3(
            _terrainGrid[1,1].transform.position.x,
            _terrainGrid[1,1].transform.position.y,
            _terrainGrid[1,1].transform.position.z + _terrainGrid[1,1].terrainData.size.z);
        _terrainGrid[1,2].transform.position = new Vector3(
            _terrainGrid[1,1].transform.position.x,
            _terrainGrid[1,1].transform.position.y,
            _terrainGrid[1,1].transform.position.z - _terrainGrid[1,1].terrainData.size.z);
        _terrainGrid[2,0].transform.position = new Vector3(
            _terrainGrid[1,1].transform.position.x + _terrainGrid[1,1].terrainData.size.x,
            _terrainGrid[1,1].transform.position.y,
            _terrainGrid[1,1].transform.position.z + _terrainGrid[1,1].terrainData.size.z);
        _terrainGrid[2,1].transform.position = new Vector3(
            _terrainGrid[1,1].transform.position.x + _terrainGrid[1,1].terrainData.size.x,
            _terrainGrid[1,1].transform.position.y,
            _terrainGrid[1,1].transform.position.z);
        _terrainGrid[2,2].transform.position = new Vector3(
            _terrainGrid[1,1].transform.position.x + _terrainGrid[1,1].terrainData.size.x,
            _terrainGrid[1,1].transform.position.y,
            _terrainGrid[1,1].transform.position.z - _terrainGrid[1,1].terrainData.size.z);
        _terrainGrid[0,0].SetNeighbors(             null,              null, _terrainGrid[1,0], _terrainGrid[0,1]);
        _terrainGrid[0,1].SetNeighbors(             null, _terrainGrid[0,0], _terrainGrid[1,1], _terrainGrid[0,2]);
        _terrainGrid[0,2].SetNeighbors(             null, _terrainGrid[0,1], _terrainGrid[1,2],              null);
        _terrainGrid[1,0].SetNeighbors(_terrainGrid[0,0],              null, _terrainGrid[2,0], _terrainGrid[1,1]);
        _terrainGrid[1,1].SetNeighbors(_terrainGrid[0,1], _terrainGrid[1,0], _terrainGrid[2,1], _terrainGrid[1,2]);
        _terrainGrid[1,2].SetNeighbors(_terrainGrid[0,2], _terrainGrid[1,1], _terrainGrid[2,2],              null);
        _terrainGrid[2,0].SetNeighbors(_terrainGrid[1,0],              null,              null, _terrainGrid[2,1]);
        _terrainGrid[2,1].SetNeighbors(_terrainGrid[1,1], _terrainGrid[2,0],              null, _terrainGrid[2,2]);
        _terrainGrid[2,2].SetNeighbors(_terrainGrid[1,2], _terrainGrid[2,1],              null,              null);
    }
    void Update ()
    {
        Vector3 playerPosition = new Vector3(PlayerObject.transform.position.x, PlayerObject.transform.position.y, PlayerObject.transform.position.z);
        Terrain playerTerrain = null;
        int xOffset = 0;
        int yOffset = 0;
        for (int x = 0; x < 3; x++)
        {
            for (int y = 0; y < 3; y++)
            {
                if ((playerPosition.x >= _terrainGrid[x,y].transform.position.x) &&
                    (playerPosition.x <= (_terrainGrid[x,y].transform.position.x + _terrainGrid[x,y].terrainData.size.x)) &&
                    (playerPosition.z >= _terrainGrid[x,y].transform.position.z) &&
                    (playerPosition.z <= (_terrainGrid[x,y].transform.position.z + _terrainGrid[x,y].terrainData.size.z)))
                {
                    playerTerrain = _terrainGrid[x,y];
                    xOffset = 1 - x;
                    yOffset = 1 - y;
                    break;
                }
            }
            if (playerTerrain != null)
                break;
        }
        if (playerTerrain != _terrainGrid[1,1])
        {
            Terrain[,] newTerrainGrid = new Terrain[3,3];
            for (int x = 0; x < 3; x++)
                for (int y = 0; y < 3; y++)
                {
                    int newX = x + xOffset;
                    if (newX < 0)
                        newX = 2;
                    else if (newX > 2)
                        newX = 0;
                    int newY = y + yOffset;
                    if (newY < 0)
                        newY = 2;
                    else if (newY > 2)
                        newY = 0;
                    newTerrainGrid[newX, newY] = _terrainGrid[x,y];
                }
            _terrainGrid = newTerrainGrid;
            UpdateTerrainPositionsAndNeighbors();
        }
    }
}

程序生成-

public class TerrainGenerator : MonoBehaviour
{
    //Prototypes
    public Texture2D m_splat0, m_splat1;
    public float m_splatTileSize0 = 10.0f;
    public float m_splatTileSize1 = 2.0f;
    public Texture2D m_detail0, m_detail1, m_detail2;
    public GameObject m_tree0, m_tree1, m_tree2;
    //Noise settings. A higher frq will create larger scale details. Each seed value will create a unique look
    public int m_groundSeed = 0;
    public float m_groundFrq = 800.0f;
    public int m_mountainSeed = 1;
    public float m_mountainFrq = 1200.0f;
    public int m_treeSeed = 2;
    public float m_treeFrq = 400.0f;
    public int m_detailSeed = 3;
    public float m_detailFrq = 100.0f;
    //Terrain settings
    public int m_tilesX = 2; //Number of terrain tiles on the x axis
    public int m_tilesZ = 2; //Number of terrain tiles on the z axis
    public float m_pixelMapError = 6.0f; //A lower pixel error will draw terrain at a higher Level of detail but will be slower
    public float m_baseMapDist = 1000.0f; //The distance at which the low res base map will be drawn. Decrease to increase performance
    //Terrain data settings
    public int m_heightMapSize = 513; //Higher number will create more detailed height maps
    public int m_alphaMapSize = 1024; //This is the control map that controls how the splat textures will be blended
    public int m_terrainSize = 2048;
    public int m_terrainHeight = 512;
    public int m_detailMapSize = 512; //Resolutions of detail (Grass) layers
    //Tree settings
    public int m_treeSpacing = 32; //spacing between trees
    public float m_treeDistance = 2000.0f; //The distance at which trees will no longer be drawn
    public float m_treeBillboardDistance = 400.0f; //The distance at which trees meshes will turn into tree billboards
    public float m_treeCrossFadeLength = 20.0f; //As trees turn to billboards there transform is rotated to match the meshes, a higher number will make this transition smoother
    public int m_treeMaximumFullLODCount = 400; //The maximum number of trees that will be drawn in a certain area. 
    //Detail settings
    public DetailRenderMode detailMode;
    public int m_detailObjectDistance = 400; //The distance at which details will no longer be drawn
    public float m_detailObjectDensity = 4.0f; //Creates more dense details within patch
    public int m_detailResolutionPerPatch = 32; //The size of detail patch. A higher number may reduce draw calls as details will be batch in larger patches
    public float m_wavingGrassStrength = 0.4f;
    public float m_wavingGrassAmount = 0.2f;
    public float m_wavingGrassSpeed = 0.4f;
    public Color m_wavingGrassTint = Color.white;
    public Color m_grassHealthyColor = Color.white;
    public Color m_grassDryColor = Color.white;
    //Private
    PerlinNoise m_groundNoise, m_mountainNoise, m_treeNoise, m_detailNoise;
    Terrain[,] m_terrain;
    SplatPrototype[] m_splatPrototypes;
    TreePrototype[] m_treeProtoTypes;
    DetailPrototype[] m_detailProtoTypes;
    Vector2 m_offset;
    void Start()
    {
        m_groundNoise = new PerlinNoise(m_groundSeed);
        m_mountainNoise = new PerlinNoise(m_mountainSeed);
        m_treeNoise = new PerlinNoise(m_treeSeed);
        m_detailNoise = new PerlinNoise(m_detailSeed);
        if (!Mathf.IsPowerOfTwo(m_heightMapSize - 1))
        {
            Debug.Log("TerrianGenerator::Start - height map size must be pow2+1 number");
            m_heightMapSize = Mathf.ClosestPowerOfTwo(m_heightMapSize) + 1;
        }
        if (!Mathf.IsPowerOfTwo(m_alphaMapSize))
        {
            Debug.Log("TerrianGenerator::Start - Alpha map size must be pow2 number");
            m_alphaMapSize = Mathf.ClosestPowerOfTwo(m_alphaMapSize);
        }
        if (!Mathf.IsPowerOfTwo(m_detailMapSize))
        {
            Debug.Log("TerrianGenerator::Start - Detail map size must be pow2 number");
            m_detailMapSize = Mathf.ClosestPowerOfTwo(m_detailMapSize);
        }
        if (m_detailResolutionPerPatch < 8)
        {
            Debug.Log("TerrianGenerator::Start - Detail resolution per patch must be >= 8, changing to 8");
            m_detailResolutionPerPatch = 8;
        }
        float[,] htmap = new float[m_heightMapSize, m_heightMapSize];
        m_terrain = new Terrain[m_tilesX, m_tilesZ];
        //this will center terrain at origin
        m_offset = new Vector2(-m_terrainSize * m_tilesX * 0.5f, -m_terrainSize * m_tilesZ * 0.5f);
        CreateProtoTypes();
        for (int x = 0; x < m_tilesX; x++)
        {
            for (int z = 0; z < m_tilesZ; z++)
            {
                FillHeights(htmap, x, z);
                TerrainData terrainData = new TerrainData();
                terrainData.heightmapResolution = m_heightMapSize;
                terrainData.SetHeights(0, 0, htmap);
                terrainData.size = new Vector3(m_terrainSize, m_terrainHeight, m_terrainSize);
                terrainData.splatPrototypes = m_splatPrototypes;
                terrainData.treePrototypes = m_treeProtoTypes;
                terrainData.detailPrototypes = m_detailProtoTypes;
                FillAlphaMap(terrainData);
                m_terrain[x, z] = Terrain.CreateTerrainGameObject(terrainData).GetComponent<Terrain>();
                m_terrain[x, z].transform.position = new Vector3(m_terrainSize * x + m_offset.x, 0, m_terrainSize * z + m_offset.y);
                m_terrain[x, z].heightmapPixelError = m_pixelMapError;
                m_terrain[x, z].basemapDistance = m_baseMapDist;
                //disable this for better frame rate
                m_terrain[x, z].castShadows = false;
                FillTreeInstances(m_terrain[x, z], x, z);
                FillDetailMap(m_terrain[x, z], x, z);
            }
        }
        //Set the neighbours of terrain to remove seams.
        for (int x = 0; x < m_tilesX; x++)
        {
            for (int z = 0; z < m_tilesZ; z++)
            {
                Terrain right = null;
                Terrain left = null;
                Terrain bottom = null;
                Terrain top = null;
                if (x > 0) left = m_terrain[(x - 1), z];
                if (x < m_tilesX - 1) right = m_terrain[(x + 1), z];
                if (z > 0) bottom = m_terrain[x, (z - 1)];
                if (z < m_tilesZ - 1) top = m_terrain[x, (z + 1)];
                m_terrain[x, z].SetNeighbors(left, top, right, bottom);
            }
        }
    }
    void CreateProtoTypes()
    {
        //Ive hard coded 2 splat prototypes, 3 tree prototypes and 3 detail prototypes.
        //This is a little inflexible way to do it but it made the code simpler and can easly be modified 
        m_splatPrototypes = new SplatPrototype[2];
        m_splatPrototypes[0] = new SplatPrototype();
        m_splatPrototypes[0].texture = m_splat0;
        m_splatPrototypes[0].tileSize = new Vector2(m_splatTileSize0, m_splatTileSize0);
        m_splatPrototypes[1] = new SplatPrototype();
        m_splatPrototypes[1].texture = m_splat1;
        m_splatPrototypes[1].tileSize = new Vector2(m_splatTileSize1, m_splatTileSize1);
        m_treeProtoTypes = new TreePrototype[3];
        m_treeProtoTypes[0] = new TreePrototype();
        m_treeProtoTypes[0].prefab = m_tree0;
        m_treeProtoTypes[1] = new TreePrototype();
        m_treeProtoTypes[1].prefab = m_tree1;
        m_treeProtoTypes[2] = new TreePrototype();
        m_treeProtoTypes[2].prefab = m_tree2;
        m_detailProtoTypes = new DetailPrototype[3];
        m_detailProtoTypes[0] = new DetailPrototype();
        m_detailProtoTypes[0].prototypeTexture = m_detail0;
        m_detailProtoTypes[0].renderMode = detailMode;
        m_detailProtoTypes[0].healthyColor = m_grassHealthyColor;
        m_detailProtoTypes[0].dryColor = m_grassDryColor;
        m_detailProtoTypes[1] = new DetailPrototype();
        m_detailProtoTypes[1].prototypeTexture = m_detail1;
        m_detailProtoTypes[1].renderMode = detailMode;
        m_detailProtoTypes[1].healthyColor = m_grassHealthyColor;
        m_detailProtoTypes[1].dryColor = m_grassDryColor;
        m_detailProtoTypes[2] = new DetailPrototype();
        m_detailProtoTypes[2].prototypeTexture = m_detail2;
        m_detailProtoTypes[2].renderMode = detailMode;
        m_detailProtoTypes[2].healthyColor = m_grassHealthyColor;
        m_detailProtoTypes[2].dryColor = m_grassDryColor;

    }
    void FillHeights(float[,] htmap, int tileX, int tileZ)
    {
        float ratio = (float)m_terrainSize / (float)m_heightMapSize;
        for (int x = 0; x < m_heightMapSize; x++)
        {
            for (int z = 0; z < m_heightMapSize; z++)
            {
                float worldPosX = (x + tileX * (m_heightMapSize - 1)) * ratio;
                float worldPosZ = (z + tileZ * (m_heightMapSize - 1)) * ratio;
                float mountains = Mathf.Max(0.0f, m_mountainNoise.FractalNoise2D(worldPosX, worldPosZ, 6, m_mountainFrq, 0.8f));
                float plain = m_groundNoise.FractalNoise2D(worldPosX, worldPosZ, 4, m_groundFrq, 0.1f) + 0.1f;
                htmap[z, x] = plain + mountains;
            }
        }
    }
    void FillAlphaMap(TerrainData terrainData)
    {
        float[, ,] map = new float[m_alphaMapSize, m_alphaMapSize, 2];
        Random.seed = 0;
        for (int x = 0; x < m_alphaMapSize; x++)
        {
            for (int z = 0; z < m_alphaMapSize; z++)
            {
                // Get the normalized terrain coordinate that
                // corresponds to the the point.
                float normX = x * 1.0f / (m_alphaMapSize - 1);
                float normZ = z * 1.0f / (m_alphaMapSize - 1);
                // Get the steepness value at the normalized coordinate.
                float angle = terrainData.GetSteepness(normX, normZ);
                // Steepness is given as an angle, 0..90 degrees. Divide
                // by 90 to get an alpha blending value in the range 0..1.
                float frac = angle / 90.0f;
                map[z, x, 0] = frac;
                map[z, x, 1] = 1.0f - frac;
            }
        }
        terrainData.alphamapResolution = m_alphaMapSize;
        terrainData.SetAlphamaps(0, 0, map);
    }
    void FillTreeInstances(Terrain terrain, int tileX, int tileZ)
    {
        Random.seed = 0;
        for (int x = 0; x < m_terrainSize; x += m_treeSpacing)
        {
            for (int z = 0; z < m_terrainSize; z += m_treeSpacing)
            {
                float unit = 1.0f / (m_terrainSize - 1);
                float offsetX = Random.value * unit * m_treeSpacing;
                float offsetZ = Random.value * unit * m_treeSpacing;
                float normX = x * unit + offsetX;
                float normZ = z * unit + offsetZ;
                // Get the steepness value at the normalized coordinate.
                float angle = terrain.terrainData.GetSteepness(normX, normZ);
                // Steepness is given as an angle, 0..90 degrees. Divide
                // by 90 to get an alpha blending value in the range 0..1.
                float frac = angle / 90.0f;
                if (frac < 0.5f) //make sure tree are not on steep slopes
                {
                    float worldPosX = x + tileX * (m_terrainSize - 1);
                    float worldPosZ = z + tileZ * (m_terrainSize - 1);
                    float noise = m_treeNoise.FractalNoise2D(worldPosX, worldPosZ, 3, m_treeFrq, 1.0f);
                    float ht = terrain.terrainData.GetInterpolatedHeight(normX, normZ);
                    if (noise > 0.0f && ht < m_terrainHeight * 0.4f)
                    {
                        TreeInstance temp = new TreeInstance();
                        temp.position = new Vector3(normX, ht, normZ);
                        temp.prototypeIndex = Random.Range(0, 3);
                        temp.widthScale = 1;
                        temp.heightScale = 1;
                        temp.color = Color.white;
                        temp.lightmapColor = Color.white;
                        terrain.AddTreeInstance(temp);
                    }
                }
            }
        }
        terrain.treeDistance = m_treeDistance;
        terrain.treeBillboardDistance = m_treeBillboardDistance;
        terrain.treeCrossFadeLength = m_treeCrossFadeLength;
        terrain.treeMaximumFullLODCount = m_treeMaximumFullLODCount;
    }
    void FillDetailMap(Terrain terrain, int tileX, int tileZ)
    {
        //each layer is drawn separately so if you have a lot of layers your draw calls will increase 
        int[,] detailMap0 = new int[m_detailMapSize, m_detailMapSize];
        int[,] detailMap1 = new int[m_detailMapSize, m_detailMapSize];
        int[,] detailMap2 = new int[m_detailMapSize, m_detailMapSize];
        float ratio = (float)m_terrainSize / (float)m_detailMapSize;
        Random.seed = 0;
        for (int x = 0; x < m_detailMapSize; x++)
        {
            for (int z = 0; z < m_detailMapSize; z++)
            {
                detailMap0[z, x] = 0;
                detailMap1[z, x] = 0;
                detailMap2[z, x] = 0;
                float unit = 1.0f / (m_detailMapSize - 1);
                float normX = x * unit;
                float normZ = z * unit;
                // Get the steepness value at the normalized coordinate.
                float angle = terrain.terrainData.GetSteepness(normX, normZ);
                // Steepness is given as an angle, 0..90 degrees. Divide
                // by 90 to get an alpha blending value in the range 0..1.
                float frac = angle / 90.0f;
                if (frac < 0.5f)
                {
                    float worldPosX = (x + tileX * (m_detailMapSize - 1)) * ratio;
                    float worldPosZ = (z + tileZ * (m_detailMapSize - 1)) * ratio;
                    float noise = m_detailNoise.FractalNoise2D(worldPosX, worldPosZ, 3, m_detailFrq, 1.0f);
                    if (noise > 0.0f)
                    {
                        float rnd = Random.value;
                        //Randomly select what layer to use
                        if (rnd < 0.33f)
                            detailMap0[z, x] = 1;
                        else if (rnd < 0.66f)
                            detailMap1[z, x] = 1;
                        else
                            detailMap2[z, x] = 1;
                    }
                }
            }
        }
        terrain.terrainData.wavingGrassStrength = m_wavingGrassStrength;
        terrain.terrainData.wavingGrassAmount = m_wavingGrassAmount;
        terrain.terrainData.wavingGrassSpeed = m_wavingGrassSpeed;
        terrain.terrainData.wavingGrassTint = m_wavingGrassTint;
        terrain.detailObjectDensity = m_detailObjectDensity;
        terrain.detailObjectDistance = m_detailObjectDistance;
        terrain.terrainData.SetDetailResolution(m_detailMapSize, m_detailResolutionPerPatch);
        terrain.terrainData.SetDetailLayer(0, 0, 0, detailMap0);
        terrain.terrainData.SetDetailLayer(0, 0, 1, detailMap1);
        terrain.terrainData.SetDetailLayer(0, 0, 2, detailMap2);
    }

}

所以基本上,我希望使用无限地形而不是 (2( 生成程序生成,请帮助某人。

c# / unity programming

哈哈,我已经使用过那个地形生成器,如果你是 Unity 的新手,但独自一人是编程新手,我会 100% 建议你不要使用它。地形生成器使用柏林噪声在地形(丘陵和山谷(上产生噪声,与制作无限地形无关。它的性能非常繁重,除非您知道自己在做什么,否则我不会使用它。更不用说那个地形生成器(我以前用过它(在编程方面远远超出了你的头脑。不是你可以在不了解OOP,数据结构,算法等基本编程概念的情况下插入游戏并理解的东西。等

PS您的标题具有误导性 "存储过程"是一个数据库术语,与Unity3D无关。

更新根据要求,我找到了一个适用于无限地形的良好入门项目,您可以下载它并使用它,我建议对其进行重新设计并真正了解正在发生的事情,以便您以后可以制作更复杂的东西:)

http://forum.unity3d.com/threads/infinite-terrain-free-project-source.68807/