Unity根据当前位置获取地形贴图
这比最初看起来要稍微棘手一些--部分原因是地形上的任何给定位置都可能是两种或两种以上地形的混合体,部分原因是用于存储这些信息的数据相对复杂。
简而言之,您需要使用 GetAlphaMaps() 函数从Terrain 类中读取 Alpha Map 数据。Alpha Map 数据是遍布地形区域的网格值,网格中的每个条目都包含用于 "混合 "每种不同地形纹理的值,因此更具体地说,您需要计算玩家所在的网格单元,然后读取该网格单元的混合值。
开始吧。将下面的大型脚本作为一个新的 C# 脚本添加到你的项目中。将文件命名为 "TerrainSurface"。
然后,您就可以使用这些辅助函数来读取纹理的混合值,或者只获取给定世界位置上最主要的纹理索引。例如:
function Update() {
var surfaceIndex = TerrainSurface.GetMainTexture(transform.position);
}
现在,您的 "surfaceIndex
"将包含一个整数,表示该位置上最主要纹理的零基索引。如果您在地形中添加了 4 种纹理,该值将是 0、1、2 或 3 中的一种。
或者,您也可以像这样读取实际的纹理组合:
function Update() {
var surfaceMix = TerrainSurface.GetTextureMix(transform.position);
}
您的 "surfaceMix "将包含一个浮点数值数组,表示该位置上每种材质的相对混合程度。例如,如果您有 4 个纹理,而第 4 个纹理是 "泥",那么您可以用它来确定当前位置的泥泞程度,如下所示:_(请记住,索引是以 0 为基础的,因此第 4 个纹理的索引为 3)_
function Update() {
var surfaceMix = TerrainSurface.GetTextureMix(transform.position);
var muddiness = surfaceMix[3];
}
下面是主辅助脚本。将其作为一个新的 C# 脚本添加到你的项目中。将文件命名为 "TerrainSurface.cs"。
您可以直接使用 C# 脚本中的函数。如果要使用其他 Javascript 脚本中的这些函数(如上面的示例),则需要将脚本放在一个文件夹中,使其获得更早的编译通过。为此,请在项目中创建一个名为 "Plugins "的文件夹,并将 TerrainSurface.cs 脚本放入其中。
// -- TerrainSurface.cs --
using UnityEngine;
using System.Collections;
public class TerrainSurface {
public static float[] GetTextureMix(Vector3 worldPos) {
// returns an array containing the relative mix of textures
// on the main terrain at this world position.
// The number of values in the array will equal the number
// of textures added to the terrain.
Terrain terrain = Terrain.activeTerrain;
TerrainData terrainData = terrain.terrainData;
Vector3 terrainPos = terrain.transform.position;
// calculate which splat map cell the worldPos falls within (ignoring y)
int mapX = (int)(((worldPos.x - terrainPos.x) / terrainData.size.x) * terrainData.alphamapWidth);
int mapZ = (int)(((worldPos.z - terrainPos.z) / terrainData.size.z) * terrainData.alphamapHeight);
// get the splat data for this cell as a 1x1xN 3d array (where N = number of textures)
float[,,] splatmapData = terrainData.GetAlphamaps(mapX,mapZ,1,1);
// extract the 3D array data to a 1D array:
float[] cellMix = new float[splatmapData.GetUpperBound(2)+1];
for (int n=0; n<cellMix.Length; ++n)
{
cellMix[n] = splatmapData[0,0,n];
}
return cellMix;
}
public static int GetMainTexture(Vector3 worldPos) {
// returns the zero-based index of the most dominant texture
// on the main terrain at this world position.
float[] mix = GetTextureMix(worldPos);
float maxMix = 0;
int maxIndex = 0;
// loop through each mix value and find the maximum
for (int n=0; n<mix.Length; ++n)
{
if (mix[n] > maxMix)
{
maxIndex = n;
maxMix = mix[n];
}
}
return maxIndex;
}
}