実現したいこと
- スクリプトのエラーの解消
- Unityで作成したプログラムを動かしたい
困っていること
Unityで『Object2Terrain』のスクリプトを書いていたのですが、下記のようなメッセージが出た上、メニューアイテムにこのプログラムが追加されないので困っています…。プログラムはVisual studio 2019で書きました。
発生しているエラーメッセージ
No MonoBehaviour scripts in the file, or their names do not match fale name.
試したこと
- クラス名の修正
- 大文字、小文字のミスがないか確認
- **using System.Collection;**の追加
using UnityEngine;
using UnityEditor;
using System.Collection;
コード比較(修正前、修正後)
修正前のコード
using UnityEngine;
using UnityEditor;
public class Object2Terrain : EditorWindow
{
[MenuItem("Terrain/Object to Terrain", false, 2000)]
static void OpenWindow()
{
EditorWindow.GetWindow<Object2Terrain>(true);
}
private int resolution = 512;
private Vector3 addTerrain;
int bottomTopRadioSelected = 0;
static string[] bottomTopRadio = new string[] { "Bottom Up", "Top Down" };
private float shiftHeight = 0f;
void OnGUI()
{
resolution = EditorGUILayout.IntField("Resolution", resolution);
addTerrain = EditorGUILayout.Vector3Field("Add terrain", addTerrain);
shiftHeight = EditorGUILayout.Slider("Shift height", shiftHeight, -1f, 1f);
bottomTopRadioSelected = GUILayout.SelectionGrid(bottomTopRadioSelected, bottomTopRadio, bottomTopRadio.Length, EditorStyles.radioButton);
if (GUILayout.Button("Create Terrain"))
{
if (Selection.activeGameObject == null)
{
EditorUtility.DisplayDialog("No object selected", "Please select an object.", "Ok");
return;
}
else
{
CreateTerrain();
}
}
}
delegate void CleanUp();
void CreateTerrain()
{
//fire up the progress bar
ShowProgressBar(1, 100);
TerrainData terrain = new TerrainData();
terrain.heightmapResolution = resolution;
terrain.SetDetailResolution(resolution, 100);
GameObject terrainObject = Terrain.CreateTerrainGameObject(terrain);
Undo.RegisterCreatedObjectUndo(terrainObject, "Object to Terrain");
MeshCollider collider = Selection.activeGameObject.GetComponent<MeshCollider>();
CleanUp cleanUp = null;
//Add a collider to our source object if it does not exist.
//Otherwise raycasting doesn't work.
if (!collider)
{
collider = Selection.activeGameObject.AddComponent<MeshCollider>();
cleanUp = () => DestroyImmediate(collider);
}
Bounds bounds = collider.bounds;
float sizeFactor = collider.bounds.size.y / (collider.bounds.size.y + addTerrain.y);
terrain.size = collider.bounds.size + addTerrain;
bounds.size = new Vector3(terrain.size.x, collider.bounds.size.y, terrain.size.z);
// Do raycasting samples over the object to see what terrain heights should be
float[,] heights = new float[terrain.heightmapWidth, terrain.heightmapHeight];
Ray ray = new Ray(new Vector3(bounds.min.x, bounds.max.y + bounds.size.y, bounds.min.z), -Vector3.up);
RaycastHit hit = new RaycastHit();
float meshHeightInverse = 1 / bounds.size.y;
Vector3 rayOrigin = ray.origin;
int maxHeight = heights.GetLength(0);
int maxLength = heights.GetLength(1);
Vector2 stepXZ = new Vector2(bounds.size.x / maxLength, bounds.size.z / maxHeight);
for (int zCount = 0; zCount < maxHeight; zCount++)
{
ShowProgressBar(zCount, maxHeight);
for (int xCount = 0; xCount < maxLength; xCount++)
{
float height = 0.0f;
if (collider.Raycast(ray, out hit, bounds.size.y * 3))
{
height = (hit.point.y - bounds.min.y) * meshHeightInverse;
height += shiftHeight;
//bottom up
if (bottomTopRadioSelected == 0)
{
height *= sizeFactor;
}
//clamp
if (height < 0)
{
height = 0;
}
}
heights[zCount, xCount] = height;
rayOrigin.x += stepXZ[0];
ray.origin = rayOrigin;
}
rayOrigin.z += stepXZ[1];
rayOrigin.x = bounds.min.x;
ray.origin = rayOrigin;
}
terrain.SetHeights(0, 0, heights);
EditorUtility.ClearProgressBar();
if (cleanUp != null)
{
cleanUp();
}
}
void ShowProgressBar(float progress, float maxProgress)
{
float p = progress / maxProgress;
EditorUtility.DisplayProgressBar("Creating Terrain...", Mathf.RoundToInt(p * 100f) + " %", p);
}
}
修正後のコード
using UnityEngine;
using UnityEditor;
using System.Collections;
public class Object2Terrain : EditorWindow {
[MenuItem("Terrain/Object to Terrain", false, 2000)]
static void OpenWindow() => EditorWindow.GetWindow(typeof(Object2Terrain))(true);
private int resolution = 512;
private Vector3 addTerrain;
int bottomTopRadioSelected = 0;
static string[] bottomTopRadio = new string[] { "Bottom Up", "Top Down"};
private float shiftHeight = 0f;
void OnGUI () {
resolution = EditorGUILayout.IntField("Resolution", resolution);
addTerrain = EditorGUILayout.Vector3Field("Add terrain", addTerrain);
shiftHeight = EditorGUILayout.Slider("Shift height", shiftHeight, -1f, 1f);
bottomTopRadioSelected = GUILayout.SelectionGrid(bottomTopRadioSelected, bottomTopRadio, bottomTopRadio.Length, EditorStyles.radioButton);
if(GUILayout.Button("Create Terrain")){
if(Selection.activeGameObject == null){
EditorUtility.DisplayDialog("No object selected", "Please select an object.", "Ok");
return;
}
else{
CreateTerrain();
}
}
}
delegate void CleanUp();
void CreateTerrain(){
//fire up the progress bar
ShowProgressBar(1, 100);
TerrainData terrain = new TerrainData();
terrain.heightmapResolution = resolution;
GameObject terrainObject = Terrain.CreateTerrainGameObject(terrain);
Undo.RegisterCreatedObjectUndo(terrainObject, "Object to Terrain");
MeshCollider collider = Selection.activeGameObject.GetComponent<MeshCollider>();
CleanUp cleanUp = null;
//Add a collider to our source object if it does not exist.
//Otherwise raycasting doesn't work.
if(!collider){
collider = Selection.activeGameObject.AddComponent<MeshCollider>();
cleanUp = () => DestroyImmediate(collider);
}
Bounds bounds = collider.bounds;
float sizeFactor = collider.bounds.size.y / (collider.bounds.size.y + addTerrain.y);
terrain.size = collider.bounds.size + addTerrain;
bounds.size = new Vector3(terrain.size.x, collider.bounds.size.y, terrain.size.z);
// Do raycasting samples over the object to see what terrain heights should be
float[,] heights = new float[terrain.heightmapWidth, terrain.heightmapHeight];
Ray ray = new Ray(new Vector3(bounds.min.x, bounds.max.y + bounds.size.y, bounds.min.z), -Vector3.up);
RaycastHit hit = new RaycastHit();
float meshHeightInverse = 1 / bounds.size.y;
Vector3 rayOrigin = ray.origin;
int maxHeight = heights.GetLength(0);
int maxLength = heights.GetLength(1);
Vector2 stepXZ = new Vector2(bounds.size.x / maxLength, bounds.size.z / maxHeight);
for(int zCount = 0; zCount < maxHeight; zCount++){
ShowProgressBar(zCount, maxHeight);
for(int xCount = 0; xCount < maxLength; xCount++){
float height = 0.0f;
if(collider.Raycast(ray, out hit, bounds.size.y * 3)){
height = (hit.point.y - bounds.min.y) * meshHeightInverse;
height += shiftHeight;
//bottom up
if(bottomTopRadioSelected == 0){
height *= sizeFactor;
}
//clamp
if(height < 0){
height = 0;
}
}
heights[zCount, xCount] = height;
rayOrigin.x += stepXZ[0];
ray.origin = rayOrigin;
}
rayOrigin.z += stepXZ[1];
rayOrigin.x = bounds.min.x;
ray.origin = rayOrigin;
}
terrain.SetHeights(0, 0, heights);
EditorUtility.ClearProgressBar();
if(cleanUp != null){
cleanUp();
}
}
void ShowProgressBar(float progress, float maxProgress){
float p = progress / maxProgress;
EditorUtility.DisplayProgressBar("Creating Terrain...", Mathf.RoundToInt(p * 100f)+ " %", p);
}
}
修正したのは良いが
修正しましたが、そしたらまたエラーメッセージが…。
Assets\Editor\object2terrain.cs(1,1):error CS1056: Unexpected character"
そんなメッセージが出たので再度修正作業を行いました。
2回目の修正後のコード
using UnityEngine;
using UnityEditor;
using System.Collections;
public class Object2Terrain : EditorWindow {
[MenuItem("Terrain/Object2Terrain", false, 2000)]
static void OpenWindow() => EditorWindow.GetWindow(typeof(Object2Terrain))(true);
private int resolution = 512;
private Vector3 addTerrain;
int bottomTopRadioSelected = 0;
static string[] bottomTopRadio = new string[] ("Bottom Up", "Top Down");
private float shiftHeight = 0f;
void OnGUI () {
resolution = EditorGUILayout.IntField("Resolution", resolution);
addTerrain = EditorGUILayout.Vector3Field("Add terrain", addTerrain);
shiftHeight = EditorGUILayout.Slider("Shift height", shiftHeight, -1f, 1f);
bottomTopRadioSelected = GUILayout.SelectionGrid(bottomTopRadioSelected, bottomTopRadio, bottomTopRadio.Length, EditorStyles.radioButton);
if(GUILayout.Button("Create Terrain")){
if(Selection.activeGameObject == null){
EditorUtility.DisplayDialog("No object selected", "Please select an object.", "Ok");
return;
}
else{
CreateTerrain();
}
}
}
delegate void CleanUp();
void CreateTerrain(){
//Fire up the progress bar
ShowProgressBar(1, 100);
TerrainData terrain = new TerrainData();
terrain.heightmapResolution = resolution;
GameObject terrainObject = Terrain.CreateTerrainGameObject(terrain);
Undo.RegisterCreatedObjectUndo(terrainObject, "Object2Terrain");
MeshCollider collider = Selection.activeGameObject.GetComponent<MeshCollider>();
CleanUp cleanUp = null;
//Add a collider to our source object if it does not exist.
//Otherwise raycasting doesn't work.
if(!collider){
collider = Selection.activeGameObject.AddComponent<MeshCollider>();
cleanUp = () => DestroyImmediate(collider);
}
Bounds bounds = collider.bounds;
float sizeFactor = collider.bounds.size.y / (collider.bounds.size.y + addTerrain.y);
terrain.size = collider.bounds.size + addTerrain;
bounds.size = new Vector3(terrain.size.x, collider.bounds.size.y, terrain.size.z);
// Do raycasting samples over the object to see what terrain heights should be
float[,] heights = new float[terrain.heightmapWidth, terrain.heightmapHeight];
Ray ray = new Ray(new Vector3(bounds.min.x, bounds.max.y + bounds.size.y, bounds.min.z), -Vector3.up);
RaycastHit hit = new RaycastHit();
float meshHeightInverse = 1 / bounds.size.y;
Vector3 rayOrigin = ray.origin;
int maxHeight = heights.GetLength(0);
int maxLength = heights.GetLength(1);
Vector2 stepXZ = new Vector2(bounds.size.x / maxLength, bounds.size.z / maxHeight);
for(int zCount = 0; zCount < maxHeight; zCount++){
ShowProgressBar(zCount, maxHeight);
for(int xCount = 0; xCount < maxLength; xCount++){
float height = 0.0f;
if(collider.Raycast(ray, out hit, bounds.size.y * 3)){
height = (hit.point.y - bounds.min.y) * meshHeightInverse;
height += shiftHeight;
//bottom up
if(bottomTopRadioSelected == 0){
height *= sizeFactor;
}
//clamp
if(height < 0){
height = 0;
}
}
heights[zCount, xCount] = height;
rayOrigin.x += stepXZ[0];
ray.origin = rayOrigin;
}
rayOrigin.z += stepXZ[1];
rayOrigin.x = bounds.min.x;
ray.origin = rayOrigin;
}
terrain.SetHeights(0, 0, heights);
EditorUtility.ClearProgressBar();
if(cleanUp != null){
cleanUp();
}
}
void ShowProgressBar(float progress, float maxProgress){
float p = progress / maxProgress;
EditorUtility.DisplayProgressBar("Creating Terrain...", Mathf.RoundToInt(p * 100f)+ " %", p);
}
しかし!
Assets\Editor\object2terrain.cs(1,1):error CS1056: Unexpected character"
このメッセージが消えず…。なにか対処法はありますか!?
自分にはミスがわからないので救世主が欲しいです…。