インディー・ゲームの開発に携わって僕が感じた10の事柄について
http://ch.nicovideo.jp/ayasawa_s/blomaga/ar747373
このアーティクルはなかなかに当を得ていて良いものだったので、僕たちは類似した記事を書くことにしました。そして、同人ゲーム制作について一般に誤解されていることを明らかにしました。
(以上パクリ)
インディー・ゲームの開発に携わって僕が感じた10の事柄について
http://ch.nicovideo.jp/ayasawa_s/blomaga/ar747373
このアーティクルはなかなかに当を得ていて良いものだったので、僕たちは類似した記事を書くことにしました。そして、同人ゲーム制作について一般に誤解されていることを明らかにしました。
(以上パクリ)
色々状況も実装も変わったので1は消去しました。
Effective Unity とか欲しい。
プレハブとは、ヒエラルキー上にあるオブジェクトをまるで切り取ったかのように状態保存し、使い回せる形にする Unity の要の機能である。使いこなせばとても便利だが、その一方で少々クセがあり、修羅場時にハマる原因となることも確か。正しく知り、正しく使うことがマスターアップ直前に焦らないための第一歩だと思う。
実際にぼくがゲームを作る上で心がけている運用は以下の通りである。
ベヨネッタ2クリアしました。
やってみたら思いのほか簡単だった。
むしろ最初からポリゴン数表示くらいしてほしいものだが。
using UnityEngine; using System.Collections; using UnityEditor; [CustomEditor(typeof(MeshFilter))] public class PolygonCounter : Editor { public override void OnInspectorGUI() { base.OnInspectorGUI(); MeshFilter filter = target as MeshFilter; string polygons = "Polygons: " + filter.sharedMesh.triangles.Length/3; EditorGUILayout.LabelField( polygons ); } }
上のスクリプトを適当な名前.csとつけてEditorフォルダにぶちこみましょう。
コースのようなペラっとしたオブジェクトを選択してメニューを選ぶと、その部分の地形がそのオブジェクトに吸い付くように整地される。勿論、それまでの地形はキープ。
以下をEditor/フォルダにぶち込み。
//-------------------------------------------------------------------------------- // - ObjectToTerrain - //-------------------------------------------------------------------------------- // // オブジェクトをTerrainに転写 // 元のTerrainはキープ // //-------------------------------------------------------------------------------- using UnityEngine; using UnityEditor; //-------------------------------------------------------------------------------- public class Object2Terrain : EditorWindow { //---------------------------------------------------------------------------- [MenuItem ("Edit/Export/Object to Terrain")] static void DoObject2Terrain() { BeginTransfer(); } //---------------------------------------------------------------------------- static void BeginTransfer () { if ( !Selection.activeGameObject ) { Debug.Log( "[Object2Terrain] No object is selected. " ); return; } TerrainData terrain_data = Terrain.activeTerrain.terrainData; Undo.RecordObject( Terrain.activeTerrain, "Object to Terrain" ); GameObject target = Selection.activeGameObject; MeshCollider target_col = target.GetComponent<MeshCollider>(); if ( !target_col ) { Debug.Log( "[Object2Terrain] No collider is detected in selection." ); return; } Bounds targetbounds = target_col.bounds; Bounds bounds = Terrain.activeTerrain.collider.bounds; // Do raycasting samples over the object to see what terrain heights should be float cTerrainY = Terrain.activeTerrain.GetPosition().y; int cHMWidth = terrain_data.heightmapWidth; int cHMHeight = terrain_data.heightmapHeight; float cTerrainHeight = terrain_data.size.y; float[,] heightmap = new float[ cHMWidth, cHMHeight ]; float[,] originmap = terrain_data.GetHeights( 0, 0, cHMWidth, cHMHeight ); Vector3 ray_origin = new Vector3( bounds.min.x, targetbounds.max.y * 2, bounds.min.z ); Ray ray = new Ray( ray_origin, Vector3.down ); RaycastHit hit = new RaycastHit(); float cRayDistance = targetbounds.size.y * 4; Vector2 cNextDiv = new Vector2( bounds.size.x / cHMHeight , bounds.size.z / cHMWidth ); for (int i = 0; i < cHMWidth; i++) { for (int j = 0; j < cHMHeight; j++) { bool result = target_col.Raycast( ray, out hit, cRayDistance ); if ( result ) { heightmap[i, j] = ( hit.point.y - cTerrainY ) / cTerrainHeight; } else { heightmap[i, j] = originmap[i, j]; } ray_origin.x += cNextDiv.x; ray.origin = ray_origin; } ray_origin.z += cNextDiv.y; ray_origin.x = bounds.min.x; ray.origin = ray_origin; } terrain_data.SetHeights( 0, 0, heightmap ); } }
メッシュコライダをオブジェクトとTerrainにつけるのをお忘れなく。