敵ロックオン機能をUnityで実装する <ゼルダの伝説シリーズ>
かずまです。
今回も引き続き、ゼル伝シリーズをやっていきます。
そういえば今回のゼルダの伝説は一応ストーリー全クリしました。
ただマップの開放とかいっぱいやることはありますね。
ネタバレっぽくなっちゃいますが、感動した!これだけ言っておきます!笑
テーマ
今回は画面内に入った敵を注目してLボタンでロックオンするところです。
ロックオンして、タイミングよくバク転か、サイドステップをするとラッシュ攻撃ができます。
これです。
ちなみに一定の範囲内に入った時に注目できるよって示すマークを出します。
考察
ロックオン(注目)で重要な点は
- 注目できる敵の上になにか表示
- 注目したらなにか表示(上とは違うものを)
- 注目しているときは敵を見続ける
- 画面外になったときは解除される
これぐらいです。
下準備
まずは重要な点でも言ったなにか表示の部分の準備です。
注目している場合の画像は、今回いいのがあったのでフリーを使います。
yajidesign.com
この末広がりのやじるしです。
[指し示すだけの三角]
白紙ですが、この上に有ります。
これをSpriteRendererで違和感のないサイズに変更し、名前を"Point"に変更し、Prefab化します。
サイズ的にはこんな感じ。
そのPrefabに次のスクリプトをアタッチします。
これでPrefabにくっつけます。
この時、InspectorからSpriteをセットし忘れないように...。
EnemyManagerを作る
今回Enemyが画面に入ったらリストに追加、削除していきます。
そこから最短のEnemyを取り出したりすることができます。
これを作りました。
MonoBehaviourは継承しません。継承しちゃうとインスタンス生成できなくなりますかね。
次にEnemyManagerをPlayer.cs内でインスタンス生成します。
前回のPlayer.csを使い、変数とStart関数、新規メソッドを追加します。
ついでにXbox One ControllerのLBをLTriggerとしてUnityにセットしておきます。
// 変数 public EnemyManager EnemyMGR; // Start関数でインスタンス生成、コンストラクタとしてPlayerが必要なので自分をいれる private void Start () { EnemyMGR = new EnemyManager (this); CharactorCTL = GetComponent<CharacterControl> (); CameraCTL = GameObject.Find ("Main Camera").GetComponent<CameraControl> (); } // 新規メソッド追加 public void Locked () { if (Input.GetAxis ("LTrigger") > 0.9f) { Enemy enemy = EnemyMGR.getNearEnemy (); if (enemy != null) { // あとでEnemyにAttentionメソッドを記載します enemy.Attention (); } } }
Enemyスクリプトに追記
次にEnemyは画面に入った、出た場合のタスクとして、そのEnemyManagerに自身を突っ込んでもらいます。
画面外は自分をリストから削除します。
画面に入った入ってないは
このQiitaで完結に解説されています。
// 画面外にでた private void OnBecameInvisible () { player.EnemyMGR.DeleteEnemy (this); } // 画面内に入った private void OnBecameVisible () { player.EnemyMGR.AddEnemy (this); } private void OnWillRenderObject() { // あとで記載 }
EnemyはPlayerを常に見ている状態なのでPlayerのEnemyManagerにもアクセスできることになります。
これで画面に入ったりでたりというのが確認できます。
注目しているかしていないか、Player側に持っておくのではなくEnemy側で管理します。
Enemy.csに変数とメソッドをもう少し付け加えます。
private readonly float AttentionDistance = 4f; public bool isDrawingAttention = false; public void Attention () { player.transform.LookAt (transform.position); isDrawingAttention = true; } public void UnAttention () { isDrawingAttention = false; } private void OnWillRenderObject() { // あとで記載と書いていた場所 if (getDistance () < AttentionDistance) { transform.FindChild ("Point").GetComponent<SpriteRenderer> ().enabled = true; } else { transform.FindChild ("Point").GetComponent<SpriteRenderer> ().enabled = false; } }
あとはこれでEnemyの子どもとしてPointのPrefabをセットします。
isDrawAttentionがtrueのときは注目している画像になればOKです!
結果
もっと派手なエフェクトほしいけどまた今度!
なんか雑になってきたやばい...。
追記
- クラス図とか書こうと思う
- オブジェクト指向プログラミング意識しよう
- ちゃんと寝よう
敵の目線の動きをUnityで実装する <ゼルダの伝説シリーズ>
かずまです。
前回まではPlayerの動きを実装していました。
ちなみにSwitchのゼルダの伝説の動きが気になる方はこちら。
テーマ
今回のテーマは"敵の動き"です。
敵がいないと始まらないですからね。
考察
敵の動きを見てみます。
気づかれると注目して見られる
音に気づく
目線があうと気づかれる
隠れると見失う
ココらへんが結構重要だと思います。
この章では歩くことはあとで実装します。
Enemyを追加
EnemyをPlayerと同じものを作ります。
前回作ったCharactorControlをつけます。
今度はEnemy.csを作ります。
気づいたときのアクション
EnemyにつけるNoticeObjectを作ります。
気づいたときのびっくりマークとはてなマークをPhotoShopとかIllustratorで作ります。
[びっくり]
[はてな]
両方背景透明なので白く見えますがあります。
Notice.csを作成
先程用意した画像をSpriteにして、SpriteRendererで表示します。
その時につけるスクリプトです。
以下のように設定します。
WarningはHatenaのSpriteを入れて、
DiscoveryはBikkuriのSpriteを入れます。
これをPrefab化して、その後、NoticeObjectに入れます。
ここからは重要な部分だけを取り上げて解説していきたいと思います。
Playerとの距離
Unity C#では
Vector3.Distance (Vector3 a, Vector3 b)
で距離を求めますが、今回は簡単なので実装してみます。
PowはC++でもライブラリがあるみたいなので、ちょっと意識して...
// Enemy.cs Vector3 dv = player.transform.position - transform.position; return Mathf.Pow ((dv.x * dv.x + dv.y * dv.y + dv.z * dv.z), 0.5f);
unitylab.wiki.fc2.com
いや、ここのサイトのように正規化したほうが良さそう。
EnemyはPlayerを探す
EnemyにはSearchメソッドがあって、そこの中でPlayerを探しています。
検索方法としては、
目線
Enemy.cs内でenum設定している
- Warning
これは気づくか気づかないかを表します。
はてなマークのアイコンを使います。
- Discovery
これは気づいたときを表します。
ビックリマークのアイコンを使います。
距離
これは先程、使ったメソッドを使って距離を測っています。
次の足音が小さければ距離が近くても気づかれないです。
入力の力に合わせて足音を実装する
今回はXbox Controllerのスティックを使っているためGetAxisを使うことができます。
float dx = Input.GetAxis ("Horizontal"); float dy = Input.GetAxis ("Vertical"); WalkVolume = (Vector3.right * dx + Vector3.up * dy).magnitude; getWalkVolumeStatus ();
Player.cs内のこの部分でmagnitudeで入力の加減を取っています。
これを足音としています。
スティックを強く押し込むと足音が大きく、軽く押し込むと小さくなります。
VolumeのStatusでどの動きか、を取ることができます。
- Quiet
- Small
- Loud
こんな感じ。
これに音をつければそれっぽくなります。
後半へばってしまいましたが、今回はこんな感じです。
デザインとかも実装したいですがうーん笑
コードのデザインもうまくいかないのでそこまで手が回らなそう。
もっとこうしたらいいよ、みたいなのがありましたら言ってください...!
カメラワークとプレイヤーの動きをUnityで実装する Part2 <ゼルダの伝説シリーズ>
かずまです。
前回の記事はこちら。
そう、ゼルダの伝説です。
考察
リンクの動きはカメラの方向が正面になります。
なので、動いている時にカメラを回転させたらその方向に移動する感じですね。
Playerを実装
まずはPlayerを動かします。
今回は拡張性を踏まえてCharactorControllerを使わないで自分で実装します。
上記スクリプトを書きます。
CharactorControllerではisGroundがあったので、それも実装してしまいます。
- Raycastで距離を測る
- Colliderでのあたり判定
この2つによって実装されます。
Colliderだけだと天井などに当たったときに反応してしまうのでRaycastも使います。
つけるコンポーネントは以下の通りです。
RigidbodyをつけてFreeze Rotationをすべてチェックいれます。
これをしないと物に当たった時に制御できなくなります。
次にPlayer.csを実装します。
これをPlayerのオブジェクトにくっつけます。
前回のブログでもちょこっとかきましたが、それにすこし付け足します。
UnityでXboxOneコントローラを使う…前に | 蒼玉亭
ここを参考にして、Playerの動きはXbox Controllerの左スティック、カメラの動きは右スティックを使って制御します。
Edit -> Project Settings -> Input
からMouse XとMouse Yがあるとおもうので、以下のように変更してあげます。
これでInput.GetAxis("Mouse X")でOKになります。
カメラワークをUnityで実装する Part1 <ゼルダの伝説シリーズ>
かずまです。
Switchが発売され、スプラトゥーンの試射会も行われ、
ようやく落ち着いた感じがします。
あいかわらずSwitchは台数が少ないみたいで、品薄みたいですね。
ちなみに沖縄のゲオは数台ありました。
今日日曜日も入荷するとか...
さて、今日からシリーズで書いていきたいと思います。
テーマ
今回のシリーズは今流行りの「ゼルダの伝説」を取り上げていきます。
もちろん、開発の方です。
僕はゲームの中で一番と言っていいほどゼルダが大好きなのですが、
何と言ってもゲーム性と操作性、全てに置いて素晴らしいですね。
僕もゼルダの開発に携わりたい、というのが一生の夢ですが、もしかするとゲーム開発が手軽になった今、自分でも近いものが実装できるのでは?
と思ったわけです。(無謀)
今回のお題
"プレイヤーを写すカメラの動き"です。
これはゲームに置いて結構重要なのではないでしょうか。
考察
まずは実際に見てみます。
もちろん僕は実際にプレーもしました。
きれいなカメラワークですね。
プレイヤーが中心でその周りをカメラが移動していますね。
常にプレイヤーに向いている感じ。
あとは上下の限界を決めてますね。
実装部分
今回実装する部分の詳細は以下になります。
スティックを倒した時にカメラの回転と高さの変更
天井が低い場所に行った場合のカメラの位置を下げる
カメラワークのリセット
3つになります。
ほんとは移動の常に倒した方向に移動するところとかまで行きたかったけど仕方なく、次回です。
プログラミング & ゲーミング
やりつつ、コード書きつつと言った形でやってみました。
こんな感じです。
実装
はじめ、カメラを子オブジェクトにして、それを回転させればできそう!と思って作ってたのですが、高さを変更する時とかバグったため、それは諦めました。
ただし、構造は同じです。
カメラに空の親オブジェクトをくっつけて、その親は常にPlayerの座標に位置するというものです。
上のスクリプトをMain Cameraにアタッチします。
そのあとPlayer.csを作成します。
これはPlayerのゲームオブジェクトにくっつけます。
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Player : MonoBehaviour { public float HeightToRoof = 0f; // Use this for initialization void Start () { } // Update is called once per frame void Update () { HeightToRoof = getHeadHeight (); } public float getHeadHeight () { RaycastHit hit; if (Physics.Raycast (transform.position, Vector3.up, out hit)) { print ("Found an object - distance: " + hit.distance); return transform.position.y + hit.distance; } return 100f; }
これでInspectorのところでターゲットとなるPlayerと、親を入れてあげればOK!
解説
CameraではLookAtを使ってPlayerの方向を向かせています。
これはまぁこれでいいかと思います。
回転部分
回転部分は三角関数を使って計算しています。
入力はGetAxisを使ってますが、場合に合わせて変更してください。
参考はこちら
r-dimension.xsrv.jp
とある角度a(float)に対してのSinはy座標、Cosはx座標となるので半径をrとするととある座標pは
これで座標pのx,yが求まりますね。
Cameraは子オブジェクトなのでこの座標をローカル座標に入れて上げることで円形を書いて回転します。
上下の位置を変更する場合は、Verticalの値をそのまま高さにかけてあげます。
自動カメラ下げ
Player.csではRaycastを書いたと思います。
体から上方向にRayを飛ばして、天井との高さを返しています。
あとはカメラのグローバル座標をその高さにするだけです。
リセット
スペースを押せばリセットされるようになっています。
ここの値は強制...してますです。
まとめ
さて、今回はUnityでカメラワークを実装してきました。
本家の方はどうなってるんでしょうね、気になりますが、それなりに上手く行ったと思います。
たぶん、これだとターゲットの部分を変更すると自動的にターゲット変更できるかも...
あと
dtweenとかと組み合わせるといいですね。
次回はプレイヤーの移動に関しての記事を書こうとおもいます。
品テク meetup Vol.05に参加してきました。
かずまです。
一昨日からついに東京に引っ越ししました。
地元徳島、大阪2年、沖縄2年と渡り歩いて、次は東京です。
今回は何年いるかは不明です。笑
品テクとは?
品川駅港南口でテクノロジーと未来をテーマに、お酒を飲んで食事をしながら、気になる話題を聞いたり話したり体験もできる交流会です。品テクマルシェ2016において開催された「品テクFUNFAN meetup!」のスピンオフ企画
お仕事帰りにぴったりの時間ですので、美味しい食事とともにお酒を飲みながら、テクノロジートークを楽しみましょう。
と言うもので、技術、技術というよりも生活をより良くするために技術を使って良くしてみました!というお話ですね。
なのでエンジニアじゃない人達も気軽に参加できるイベントです!と言うよりエンジニアよりも住んでる人が重要だったり...笑
参加したイベントページはこちらになります。
内容
今回はざっくりしか覚えてないですが、
保育所を探せるサービスを作った!
品川でもハロウィンイベントをやったよ!
PETSを海外に持っていったよ!
オープンデータを使うとこんなにおもしろい!
地方の行政とお仕事をするには!
みたいな、このタイトルは僕が主観でつけたものです。
どうしてもエンジニアが集まると、技術のお話でサービスが置き去りになってしまったりしちゃうのでほんとに必要なのは何か、みたいなのがいいですね。
その中で幾つか気になったのを紹介します。
保育所の情報は意外と見つからないらしい
インターネットが普及して探せるんじゃないかなーと思っていたのですが、ほんとに見つからないらしいです。
あとほしい情報が乗ってなかったり、地区ごとに書かれててサイトを多数開く必要があったりとか、来たばっかの地域で近所からの情報もないし...みたいな。
ハロウィンイベントの話もこれにつながってます。近所の間のコミュニケーションを作ることができるのでローカルな情報をゲットできるとか。
オープンデータ
行政が様々なデータを公開しているそうです。
例えば1年間で事故が起こった場所のデータであれば、起こった場所の分布図みたいなのを作って、可視化できるようにすると、ここらへんは事故が多いから小学生とかの登下校時に大人を配置しよう!みたいなのが今までは「あそこ、事故多いらしいよ」と言った曖昧なことでしたが、データを見ることによって確信に変わるわけですね。
PETSの海外進出
PETSって?
プログラミング脳を養うためのロボットですね。
ここで本PETSのサイトから引用します。
PETS」(ペッツ)は、いろいろな方向のブロックを背中に挿し込んで、命令された通りに動くプログラミング学習用のロボットです。マス目の書かれたシートの上を、スタートからゴールまで、時には障害物をよけながら目指します。
いままでは日本各地でワークショップを開催していましたが、この度海外に進出されたそうです!
僕も実際やってみました。
わかりやすい
差し込んで、ボタンを押すだけで動き出すのですぐにフィードバックが返ってくるのでトライ・アンド・エラーが身につく。
意外と難しい
力技のトライ・アンド・エラーで繰り返して行けばそのうちゴールにたどり着くかもしれないけどそれでは莫大な時間がかかってしまうため、事前に頭の中で考える力が身につく。
プログラムを書くよりも楽しいので子どもも飽きないというのがいいですね。
キックスターターに出しています!
まとめ
今回はこんな感じでした。
雰囲気の写真とかは撮り損なったのでまた次回行った時にとりたいかなーと思ってます。
けど結構laughな感じです笑