ゲーム制作勉強中!あこがれだったプログラマーに今からなろう!

昔あこがれだったプログラマー。今からでもUnityを勉強してみようと思い立ち、チャレンジ開始! Unity勉強メモや、悪戦苦闘な日々の記録です。

飛行型の敵キャラの作り方:3Dアクションゲームを作ろう(13)

3Dアクションゲームの最後のザコ敵。
Objectだけは追加して、そのまま放置していたので、そろそろ作り込んでいこう。
飛んでいるようなキャラなので、Rigidbodyの「重力の使用」を解除しておけばいいかと簡単に考えて、さっくりと実装。

ところが、実際に試してみると、、、

youtu.be

プレイヤーに弾き飛ばされ、天高く飛んでいくフライングアイ😭

重力制御がないので、プレイヤーに弾き飛ばされて、上方向にVelocityが入ると、それが補正されないわけだから
考えてみれば当然の結果だったようだ😕

かといって、Rigidbodyの重力を効かせると、当然、今度は地面に落ちてしまうし、
「キネマティックにする」にチェックを入れると、敵同士の重なったりと、別の不具合がでてしまう。

ならば、Updateの最後に、強制的に高度を補正する様にしてみた。

transform.position=new Vector3(transform.position.x,153.5f,transform.position.z);

youtu.be

うまくいってる様に見えるけど、地面の高さとは関係なく同じ高度を維持してしまうため、戦闘時に支障が出そう。

ならば、敵の位置の地面の高さをRayCastで調べて、その高さを利用して高度を調整すれば良いと考えた。

Vector3 StartPos = new Vector3(transform.position.x,transform.position.y+1,transform.position.z);

if(Physics.SphereCast(StartPos, 0.15f,Vector3.down,out hit,1.5f, LayerMask.GetMask("Ground")))
{
     Groundhigh=hit.transform.position.y;
}

これでいけると思ったんだけど、Groundhighが0になってしまう。
意味がわからなくて、いろいろとサイトや記事を読み漁っていたら、Terrainの高さを調べるには、
GetInterpolatedHeightが必要だという事がわかったので、早速試してみる。

taiboman.com

[SerializeField] float altitude;//地面からの高さ

Terrain terrain=Terrain.activeTerrain;

float TerrainHigh = terrain.terrainData.GetInterpolatedHeight(transform.position.x / terrain.terrainData.size.x, transform.position.z / terrain.terrainData.size.z);

flaot Y_movement=transform.position.y-(TerrainHigh+altitude);

speed.y=-Y_movement;
transform.Translate(speed);

結果はこんな感じ。

youtu.be

イメージ通りの高度維持の仕組みはできたので、明日からはこいつに攻撃能力を持たせていこう😁