前回はとりあえず、波を再現しましたが、どうも動くメカニズムがちょっと。。。ということで普通に物理的に妥当な式でやり直し。。合わせて南の島を再現してそこに打ち寄せる姿♪
出来ました!
やったこと
(1)物理的に波は?
(2)波を動かす
(3)山を作る
(4)OculusGoで見る
(1)物理的に進行波は?
適当な参考サイトがない。。。ということで以下
【参考】
・正弦波@高校物理の備忘録
以下のような波は時間とともに動くということです。
y(x,t)=A\sin2\pi(\frac{t}{T}-\frac{x}{\lambda})
ここで時間的な周期T,波長λ、振幅Aです。
ちなみに波速つまり波の速さ(波長λ分進むのに要する時間T)は
v=\frac{\lambda}{T}
(2)波を動かす
ということで前回のCalculateを以下のように変更しました。
float Calculate(double X, double Y)
{
float s= (float)Math.Sin((X+Y-0.1*t)*0.8);
float s1 = 1 + (float)0.05 *UnityEngine.Random.value + (float)0.1 *(float)s;
//float s1 = UnityEngine.Random.value;
return s1;
}
新しいのはsinの中に-0.1tを入れたところ。。この係数0.1が波速ということになります。
また、進行方向は(X,Y)の係数(1,1)の方向になります。
(3)山を作る
山は前々回と同じですが、山に草色と石色をペイントしてよりそれらしく装飾してみました。
ちなみに山のアッセットは以下のものを使いました。
Free Island Collection
今回はついにTerrainのTextureをEdit Textureで貼り付けることができました。
これを使って山をぬりぬりしました。
そして懸案の海の色。。。これいいのないけどとりあえず青っぽい色で塗りました。
【参考】
・テレインテクスチャ@Unityマニュアル
(4)OculusGoで見る
これ位がどうやらOculusGoの限界ではないか。。転送にすごく時間がかかるようになった。動作は一応できているけど。。。
ということでこんな感じになりました。
【Unity】波がうち寄せる南の島。。。出来た♬
※画像をクリックするとYouTube動画につながります
まとめ
・島と海を作成して南の島に打ち寄せる波を作成した
・進行波を物理的に動かした
・島をぬりぬりした
・人を配置して冒険したい
・適当なトリガーで雨を降らせたい、風を吹かせたい
・森や木々を作りたい
おまけ
全体のコード
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
public class RandCircle : MonoBehaviour
{
[SerializeField]
double baseX = 20.0;
[SerializeField]
double baseY = 20.0;
[SerializeField]
double renderArea = 50;
TerrainData terrainData;
float t = 0;
// Use this for initialization
void Start()
{
terrainData = GetComponent<Terrain>().terrainData;
StartCoroutine(UpdateTerrainCoroutine());
}
// Update is called once per frame
void Update()
{
terrainData = GetComponent<Terrain>().terrainData;
StartCoroutine(UpdateTerrainCoroutine());
//Debug.Log(terrainData.heightmapHeight);
renderArea = 50;
t += 1;
}
float Calculate(double X, double Y)
{
float s= (float)Math.Sin((X+Y-0.1*t)*0.8);
float s1 = 1 + (float)0.05 *UnityEngine.Random.value + (float)0.1 *(float)s;
//float s1 = UnityEngine.Random.value;
return s1;
}
IEnumerator UpdateTerrainCoroutine()
{
var heights = new float[terrainData.heightmapWidth, terrainData.heightmapHeight];
//renderArea *= 0.98;
var startX = baseX - renderArea / 2.0;
var startY = baseY - renderArea / 2.0;
var renderAreaPerWidth = renderArea / terrainData.heightmapWidth;
var renderAreaPerHeight = renderArea / terrainData.heightmapHeight;
for (int x = 0; x < terrainData.heightmapWidth; x++)
{
for (int y = 0; y < terrainData.heightmapHeight; y++)
{
heights[x, y] = Calculate(
startX + x * renderAreaPerWidth,
startY + y * renderAreaPerHeight);
heights[x, y] = heights[x, y]/ 2;
}
}
terrainData.SetHeights(0, 0, heights);
yield return null;
}
}