Created
December 21, 2015 04:49
-
-
Save n-yoda/eb006687b124a5201592 to your computer and use it in GitHub Desktop.
UnityのTerrainの平行移動とか
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
using UnityEditor; | |
using System; | |
using System.Reflection; | |
using System.Linq; | |
using System.Collections.Generic; | |
public class TerrainEditor : EditorWindow | |
{ | |
int moveX = 10; | |
int moveY = 10; | |
int width, height; | |
public TerrainData target; | |
[MenuItem("Window/Terrain Editor")] | |
static void OpenTerrainEditor() | |
{ | |
var window = EditorWindow.GetWindow<TerrainEditor>("Terrain Editor"); | |
window.target = Selection.activeObject as TerrainData; | |
} | |
void OnGUI() | |
{ | |
target = EditorGUILayout.ObjectField(target, typeof(TerrainData), false) as TerrainData; | |
if (target != null) | |
{ | |
EditorGUILayout.LabelField("Size", "(" + target.heightmapWidth + ", " + target.heightmapHeight + ")"); | |
moveX = EditorGUILayout.IntField("Move X", moveX); | |
moveY = EditorGUILayout.IntField("Move Y", moveY); | |
if (GUILayout.Button("Move")) | |
{ | |
MoveTerrain(target, moveX, moveY); | |
} | |
} | |
} | |
public static void MoveTerrain(TerrainData terrain, int x, int y) | |
{ | |
var so = new SerializedObject(terrain); | |
var editeds = new List<UnityEngine.Object>(); | |
// Undo | |
var textures = so.FindProperty("m_SplatDatabase.m_AlphaTextures"); | |
for (int i = 0; i < textures.arraySize; i++) | |
{ | |
editeds.Add(textures.GetArrayElementAtIndex(i).objectReferenceValue); | |
} | |
editeds.Add(terrain); | |
Undo.RecordObjects(editeds.ToArray(), "Move Terrain"); | |
// Move Hightmap | |
var w = terrain.heightmapWidth; | |
var h = terrain.heightmapHeight; | |
var heights = terrain.GetHeights(0, 0, w, h); | |
terrain.SetHeights(0, 0, MoveHeights(heights, w, h, x, y)); | |
// Move Trees | |
var moveU = (float)x / w; | |
var moveV = (float)y / h; | |
var trees = terrain.treeInstances; | |
for (int i = 0; i < trees.Length; i++) | |
{ | |
trees[i].position += new Vector3(moveU, 0f, moveV); | |
} | |
terrain.treeInstances = trees.Where(tree => | |
0f <= tree.position.x && tree.position.x <= 1f | |
&& 0f <= tree.position.z && tree.position.z <= 1f).ToArray(); | |
// Move Details | |
// Move Splat | |
for (int i = 0; i < textures.arraySize; i++) | |
{ | |
var tex = textures.GetArrayElementAtIndex(i).objectReferenceValue as Texture2D; | |
editeds.Add(tex); | |
MoveTexture(tex, moveU, moveV); | |
} | |
} | |
static float[,] MoveHeights(float[,] map, | |
int width, int height, int moveX, int moveY) | |
{ | |
var result = new float[width, height]; | |
for (int y = 0; y < height; y++) | |
{ | |
for (int x = 0; x < width; x++) | |
{ | |
var srcX = x - moveX; | |
var srcY = y - moveY; | |
if (0 <= srcX && srcX < width && 0 <= srcY && srcY < height) | |
result[y, x] = map[srcY, srcX]; | |
else | |
result[y, x] = 0; | |
} | |
} | |
return result; | |
} | |
static void MoveTexture(Texture2D texture, float u, float v) | |
{ | |
Color[] colors = new Color[texture.width * texture.height]; | |
var uUnit = 1f / texture.width; | |
var vUnit = 1f / texture.height; | |
for (int y = 0; y < texture.width; y++) | |
{ | |
for (int x = 0; x < texture.height; x++) | |
{ | |
var dst = y * texture.width + x; | |
var srcU = (x + 0.5f) * uUnit - u; | |
var srcV = (y + 0.5f) * vUnit - v; | |
colors[dst] = texture.GetPixelBilinear(srcU, srcV); | |
} | |
} | |
texture.SetPixels(colors); | |
texture.Apply(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment