Источник: http://www.smokymonkeys.com/kyrill/index.asp?direct=22
Синтаксис:
Используется javascript
var sizeX:int = 2;
var sizeY:int = 2;
var terrain:Terrain;
private var myRenderer:Renderer;
private var mf:MeshFilter;
function Start() {
makePoly(false);
myRenderer = renderer;
if (!myRenderer) {
myRenderer = gameObject.AddComponent(MeshRenderer);
myRenderer.hideFlags = HideFlags.HideAndDontSave;
}
mf = GetComponent(MeshFilter);
}
function OnDrawGizmosSelected() {
makePoly(true);
}
private var verts:Array = new Array();
private var uvs:Array = new Array();
private var inds:Array = new Array();
private var nmls:Array = new Array();
private function makePoly(isEdit_:boolean) {
if (!terrain) {return;}
var w:int = terrain.terrainData.heightmapWidth;
var h:int = terrain.terrainData.heightmapHeight;
var meshScale:Vector3 = terrain.terrainData.size;
var tData = terrain.terrainData.GetHeights(0, 0, w, h);
meshScale = Vector3(meshScale.x/(w-1), meshScale.y, meshScale.z/(h-1));
var stX:int = Mathf.Floor(transform.position.z /meshScale.z);
var stY:int = Mathf.Floor(transform.position.x /meshScale.x);
var vCountW:int = sizeX +1;
var vCountH:int = sizeY +1;
var ii:int = 0;
var xi:int = 0;
var yi:int = 0;
verts.Clear();
uvs.Clear();
inds.Clear();
nmls.Clear();
for (var y:int = stY; y < stY +vCountH; y++) {
for (var x:int = stX; x < stX +vCountW; x++) {
verts.Add(Vector3.Scale(meshScale, Vector3(y, tData[x,y], x)) -transform.position);
uvs.Add(Vector2(1.0 /(vCountW -1) *xi, 1.0 /(vCountH -1) *yi));
nmls.Add(terrain.terrainData.GetInterpolatedNormal(x/(w -0.0), y/(h -0.0)));
if ((x < stX +vCountW -1) && (y < stY +vCountH -1)) {
inds.Add(ii);
inds.Add(ii +1);
inds.Add(ii +1 +vCountW);
inds.Add(ii);
inds.Add(ii +1 +vCountW);
inds.Add(ii +vCountW);
}
ii++;
xi++;
}
yi++;
xi = 0;
}
if (!isEdit_) {
if (!mf) {
mf = gameObject.AddComponent(MeshFilter);
mf.hideFlags = HideFlags.HideAndDontSave;
}
mf.mesh.Clear();
mf.mesh.vertices = verts.ToBuiltin(Vector3);
mf.mesh.uv = uvs.ToBuiltin(Vector2);
mf.mesh.normals = nmls.ToBuiltin(Vector3);
mf.mesh.triangles = inds.ToBuiltin(int);
} else {
for (var i:int = 0; i < inds.length; i += 3) {
Gizmos.color = Color(1.0, 0.7, 0.0, 0.5);
Gizmos.DrawLine(verts[inds[i]] +transform.position, verts[inds[i+1]] +transform.position);
Gizmos.DrawLine(verts[inds[i+1]] +transform.position, verts[inds[i+2]] +transform.position);
Gizmos.DrawLine(verts[inds[i+2]] +transform.position, verts[inds[i]] +transform.position);
}
}
}
var sizeY:int = 2;
var terrain:Terrain;
private var myRenderer:Renderer;
private var mf:MeshFilter;
function Start() {
makePoly(false);
myRenderer = renderer;
if (!myRenderer) {
myRenderer = gameObject.AddComponent(MeshRenderer);
myRenderer.hideFlags = HideFlags.HideAndDontSave;
}
mf = GetComponent(MeshFilter);
}
function OnDrawGizmosSelected() {
makePoly(true);
}
private var verts:Array = new Array();
private var uvs:Array = new Array();
private var inds:Array = new Array();
private var nmls:Array = new Array();
private function makePoly(isEdit_:boolean) {
if (!terrain) {return;}
var w:int = terrain.terrainData.heightmapWidth;
var h:int = terrain.terrainData.heightmapHeight;
var meshScale:Vector3 = terrain.terrainData.size;
var tData = terrain.terrainData.GetHeights(0, 0, w, h);
meshScale = Vector3(meshScale.x/(w-1), meshScale.y, meshScale.z/(h-1));
var stX:int = Mathf.Floor(transform.position.z /meshScale.z);
var stY:int = Mathf.Floor(transform.position.x /meshScale.x);
var vCountW:int = sizeX +1;
var vCountH:int = sizeY +1;
var ii:int = 0;
var xi:int = 0;
var yi:int = 0;
verts.Clear();
uvs.Clear();
inds.Clear();
nmls.Clear();
for (var y:int = stY; y < stY +vCountH; y++) {
for (var x:int = stX; x < stX +vCountW; x++) {
verts.Add(Vector3.Scale(meshScale, Vector3(y, tData[x,y], x)) -transform.position);
uvs.Add(Vector2(1.0 /(vCountW -1) *xi, 1.0 /(vCountH -1) *yi));
nmls.Add(terrain.terrainData.GetInterpolatedNormal(x/(w -0.0), y/(h -0.0)));
if ((x < stX +vCountW -1) && (y < stY +vCountH -1)) {
inds.Add(ii);
inds.Add(ii +1);
inds.Add(ii +1 +vCountW);
inds.Add(ii);
inds.Add(ii +1 +vCountW);
inds.Add(ii +vCountW);
}
ii++;
xi++;
}
yi++;
xi = 0;
}
if (!isEdit_) {
if (!mf) {
mf = gameObject.AddComponent(MeshFilter);
mf.hideFlags = HideFlags.HideAndDontSave;
}
mf.mesh.Clear();
mf.mesh.vertices = verts.ToBuiltin(Vector3);
mf.mesh.uv = uvs.ToBuiltin(Vector2);
mf.mesh.normals = nmls.ToBuiltin(Vector3);
mf.mesh.triangles = inds.ToBuiltin(int);
} else {
for (var i:int = 0; i < inds.length; i += 3) {
Gizmos.color = Color(1.0, 0.7, 0.0, 0.5);
Gizmos.DrawLine(verts[inds[i]] +transform.position, verts[inds[i+1]] +transform.position);
Gizmos.DrawLine(verts[inds[i+1]] +transform.position, verts[inds[i+2]] +transform.position);
Gizmos.DrawLine(verts[inds[i+2]] +transform.position, verts[inds[i]] +transform.position);
}
}
}
По каким-то причинам массив tData постоянно вываливается в out of range. Обращение к массиву tData заменил на terrain.terrainData.GetHeight(x,y), скрипт заработал, но значение по Y в 2000 раз превысило фактическое. Добавил в рассчет Scale деление для Y на 2000, над терейном появилась сеточка маски, но она зависла на высоте 1450,955 и не меняет ее независимо от рельефа ландшафта. Такое ощущение что функции TerrainData.GetHeights и TerrainData.GetHeight не "чуствуют" террейн.
Я вполне допускаю что я что-то проглядел, но после 2х суток втыкания в скрипт так ни к чему и не пришел. Может кто подсказать, в чем тут проблема?