unity代码修改地形

挖土功能,非webgl平台的话,简单的方法是:挖土后地形和挖掉的地形叠加,挖土事件触发后,挖掉的地形.setActive(false)即可

但是发布webgl平台,需要尽量减少unity堆大小,多个地形导致文件太大,用代码修改会大大提高加载速度。

新建Resources文件夹,地形数据,贴图数据放在其下,1、2 为地形数据,3、4为地形贴图数据

在这里插入图片描述


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO;
using System.Text;
public class TerrianDig : MonoBehaviour {
   public  Terrain terrains;
   public Terrain terraind;

    StreamWriter writer;
    StreamReader reader;
    void OnGUI()
    {
        //if (GUI.Button(new Rect(150, 100, 120, 20), "设置地形_1"))
        //{
        //    setTeData1();
        //
        //}
        //if (GUI.Button(new Rect(250, 100, 120, 20), "设置地形_2"))
        //{
        //    setTeData2();
        //
        //}
        //if (GUI.Button(new Rect(150, 200, 120, 20), "设置材质_1"))
        //{
        //    setTeMat1();
        //
        //}
        //if (GUI.Button(new Rect(250, 200, 120, 20), "设置材质_2"))
        //{
        //    setTeMat2();
        //
        //        	 	
    }
    // Use this for initialization
    void Start () {        
    }
    //把所有的数据写入文本中
    public void WriteIntoTxt(string message,string path)
    {
        FileInfo file = new FileInfo(Application.dataPath + "/Resources/"+ path);
        if (!file.Exists)
        {
            writer = file.CreateText();
        }
        else
        {
            writer = file.AppendText();
        }
        writer.WriteLine(message);
        writer.Flush();
        writer.Dispose();
        writer.Close();
    } 
    public void setTeData1(){
        TextAsset textFile = Resources.Load("1") as TextAsset;
        string tdata = textFile.text;
        string[] tar_data = tdata.Split(','); 
        float[,] heightMapBackup = new float[200, 200];//
        //int alength = heightMapBackup.GetLength(0);
        for (int i = 0; i < 200; i++)
        {
            for (int j = 0; j < 200; j++)
            {
                heightMapBackup[i, j] = float.Parse(tar_data[(j+i*200)]);
            }
        }
        //terrains.heightmapPixelError = 5;
        //terrains.basemapDistance = 2000; //解决地形使用prfab会变黑的情况
        terraind.terrainData.SetHeights(520, 1440, heightMapBackup);
    }
    public void setTeData2()
    {
        TextAsset textFile = Resources.Load("2") as TextAsset;
        string tdata = textFile.text;
        string[] tar_data = tdata.Split(',');
        float[,] heightMapBackup = new float[200, 200];//
        //int alength = heightMapBackup.GetLength(0);
        for (int i = 0; i < 200; i++)
        {
            for (int j = 0; j < 200; j++)
            {
                heightMapBackup[i, j] = float.Parse(tar_data[(j + i * 200)]);
            }
        }
        //terrains.heightmapPixelError = 5;
        //terrains.basemapDistance = 2000; //解决地形使用prfab会变黑的情况
        terraind.terrainData.SetHeights(520, 1440, heightMapBackup);
    }
    public void getTedata1() {
        float[,] testdata = terrains.terrainData.GetHeights(520, 1440, 200, 200);
        int length = testdata.GetLength(0);
        string str = "";
        for (int i = 0; i < 200; i++)
        {
            for (int j = 0; j < 200; j++)
            {
                str += testdata.GetValue(i, j) + ",";
            }
        }
        WriteIntoTxt(str,"1.txt"); 
    }
    public void getTedata2()
    {
        float[,] testdata = terraind.terrainData.GetHeights(520, 1440, 200, 200);
        int length = testdata.GetLength(0);
        string str = "";
        for (int i = 0; i < 200; i++)
        {
            for (int j = 0; j < 200; j++)
            {
                str += testdata.GetValue(i, j) + ",";
            }
        }
        WriteIntoTxt(str, "2.txt");
    }
    public void getTeMat1()
    {
        int awidth = 100; //terraind.terrainData.alphamapWidth;
        int aheight = 100;//terraind.terrainData.alphamapHeight;
        float[,,] testdata = terraind.terrainData.GetAlphamaps(520 / 2, 1440 / 2, awidth, aheight);
        string str = "";
       // print(testdata.GetValue(1023,1023,3));
        for (int i = 0; i < awidth; i++)
        {
            for (int j = 0; j < aheight; j++)
            {
                for (int k = 0; k < 4; k++)
                {
                   // print(i + "," + j + "," + k);
                    str += testdata.GetValue(new int[] { i, j, k }).ToString() + ",";
                }
            }
        }
        WriteIntoTxt(str, "3.txt");
    }
    public void getTeMat2()
    {
        int awidth = 100; //terraind.terrainData.alphamapWidth;
        int aheight = 100;//terraind.terrainData.alphamapHeight;
        float[,,] testdata = terrains.terrainData.GetAlphamaps(520 / 2, 1440 / 2, awidth, aheight);
        string str = "";
        // print(testdata.GetValue(1023,1023,3));
        for (int i = 0; i < awidth; i++)
        {
            for (int j = 0; j < aheight; j++)
            {
                for (int k = 0; k < 4; k++)
                {
                    // print(i + "," + j + "," + k);
                    str += testdata.GetValue(new int[] { i, j, k }).ToString() + ",";
                }
            }
        }
        WriteIntoTxt(str, "4.txt");
    }
    public void setTeMat1()
    {
        TextAsset textFile = Resources.Load("3") as TextAsset;
        string tdata = textFile.text;
        string[] tar_data = tdata.Split(',');
        float[,,] heightMapBackup = new float[100, 100,4];//
        //int alength = heightMapBackup.GetLength(0);
        for (int i = 0; i < 100; i++)
        {
            for (int j = 0; j < 100; j++)
            {
                for (int k=0;k<4;k++) { 
					heightMapBackup[i, j,k] = float.Parse(tar_data[i*400+j*4+k]);
                }
            }
        }
        terraind.terrainData.SetAlphamaps(520 / 2, 1440 / 2, heightMapBackup);
    }
    public void setTeMat2()
    {
		TextAsset textFile = Resources.Load("4") as TextAsset;
		string tdata = textFile.text;
		string[] tar_data = tdata.Split(',');
		float[,,] heightMapBackup = new float[100, 100,4];//
		//int alength = heightMapBackup.GetLength(0);
		for (int i = 0; i < 100; i++)
		{
			for (int j = 0; j < 100; j++)
			{
				for (int k=0;k<4;k++) { 
					heightMapBackup[i, j,k] = float.Parse(tar_data[i*400+j*4+k]);
				}
			}
		}
		terraind.terrainData.SetAlphamaps(520 / 2, 1440 / 2, heightMapBackup);
    }
}

效果如下:(恢复至初始:setTeData2() + setTeMat1())在这里插入图片描述
经过挖土动画后:(setTeData1() + setTeMat2())
在这里插入图片描述
地形:
在这里插入图片描述

### 回答1: 我可以提供一个示例代码,可以帮助你实现挖土的效果:void DigGround(){ Vector3 pos = transform.position; for (int x = -1; x <= 1; x++) { for (int z = -1; z <= 1; z++) { pos.x += x; pos.z += z; RaycastHit hit; if (Physics.Raycast (pos, Vector3.down, out hit)) { hit.transform.GetComponent<MeshRenderer>().enabled = false; } } } } ### 回答2: 在Unity实现挖土效果的代码可以通过以下步骤来完成: 1. 创建一个新的场景,添加一个地形对象(Terrain)用作挖土的目标。 2. 编写脚本来控制挖土效果。创建一个新的C#脚本并将其附加到地形对象上。这个脚本将负责处理挖土的逻辑。 3. 在脚本中声明变量来保存挖土操作所需的信息,例如挖土的半径、深度等。 4. 在Update函数中检测玩家输入(例如鼠标点击)来确定需要挖土的区域。 5. 根据玩家输入的位置,使用Unity提供的TerrainData类来修改地形的高度。可以使用SetHeights函数来设置特定区域的高度,也可以使用GetHeights函数来获取当前地形的高度数据。 6. 根据挖土的半径和深度,使用循环来计算每个要修改高度的点的坐标,并逐一修改它们的高度。 7. 修改高度后,调用ApplyDelayedHeightmapModification函数来应用修改,并实时更新地形。 8. 可以添加音效、粒子特效或其他视觉元素来增强挖土效果的真实感。 请注意,挖土效果的实现还取决于具体的需求和目标。上述步骤提供了一个简单的实现思路,但具体的代码实现可能需要根据场景和需求进行调整和修改。 ### 回答3: 在Unity中实现挖土效果的代码可以如下: 1. 首先,创建一个空的游戏对象,并将其设置为地形的父物体。 2. 在地形父物体上添加一个MeshFilter组件和一个MeshRenderer组件。 3. 创建一个C#脚本,将其挂载到地形父物体上,并将其命名为"TerrainGenerator"。 4. 在TerrainGenerator脚本中定义以下变量: - 一个公共整数变量gridSize,用于设置地形网格的大小。 - 一个公共浮点数变量depth,用于设置挖土的深度。 - 一个私有MeshFilter变量terrainMeshFilter,用于存储地形网格的MeshFilter组件。 - 一个私有网格变量terrainMesh,用于存储地形网格的网格数据。 5. 在Start函数中,获取并存储terrainMeshFilter组件的引用。 6. 实现一个公共方法GenerateTerrain,用于生成地形。 - 在方法内部,首先创建一个网格数据,网格大小为gridSize。 - 然后根据挖土的深度,将网格的顶点沿Y轴向下移动。 - 设置terrainMeshFilter的网格数据为新创建的网格数据。 7. 在Update函数中,检测玩家输入。 - 如果玩家按下鼠标左键,则调用GenerateTerrain方法生成挖土效果。 - 如果玩家按下鼠标右键,则重置地形为原始状态。 8. 在Unity编辑器中,设置地形父物体的gridSize和depth的值。 9. 调整摄像机和光照以观察地形的变化。 10. 运行游戏,点击鼠标左键即可看到挖土效果。 以上是一个简单的Unity实现挖土效果的代码,你可以根据具体需求进行优化和调整。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值