【Unity2d】引っ張ると押す処理の再実装:前編
こんにちは。なおキーヌです。
ブログ毎日更新は340日目になります。
新たな管理方法にしてから掴む処理を実装することが出来たので、今度は引っ張る処理を再実装していきましょう。
とりあえず一旦は引っ張る処理を元に戻すところから始めます。
グリッド移動は一旦後回しにしましょう。
1回で終わらなかったので前編後編に分けます。
動かせる対象をつかめているかどうかの確認
まずはGを押してLinecastを飛ばしてちゃんと動かせるオブジェクト……つまりLayerが「Wall」で、
なおかつ「GrabOK」のタグがついていたら方向キーとは逆を押したら動かせるようにしたいです。
その前にGを押したら向きを固定してしまう仕組みを作らなければ、
今のところGを押しても方向が変更されちゃう仕組みなので少し弄ります。
Gを押している時はステートが5の状態になっているのでそれを利用しましょう。
向きを変更しているのはState_Managerですし、向き保持もState_Managerがしてるため参照楽ですね。
// 向き変数変更
protected void setDirection(List<KeyCode> arrowDirect) {
// 指定のステートの場合は何もしない
if (_actState == 5) {
return;
}
// 押されているキーが2つ以上あるか調べる
bool flag = arrowDirect.Count > 1;
//~~~以下コード省略~~~
}
これでGを押している最中はステートが5の状態なので向きの変更が出来なくしました。
オブジェクトを認知して引っ張る
復習になりますがLinecastを出しているのであとはオブジェクトにそのラインが当たっていれば、
衝突判定検出となってオブジェクト情報を取得することが出来ます。
スクリプト設計前ではその状態で後ろを押すと引っ張ることが出来ました。
とりあえずその状態に戻してみましょう。
やることは
- 掴む
- 動かせるオブジェクトをつかんでいる状態
- 向いてる方向の後ろキーを押す
- プレイヤーとオブジェクトを一緒に動かす
でしたね。
掴みがステート5なので引っ張りは6にします。
ついでに押すは7にしましょう。
早速やってみましょう。
先ほどの_actStateが5のときにreturnしてたところに追記します。
// 向き変数変更
protected void setDirection(List<KeyCode> arrowDirect) {
// 指定のステートの場合は何もしない
if (_actState >= 5 && _actState <= 7) {
// 何も押されてなければステートは5にする
if (arrowDirect.Count == 0) { _actState = 5; }
switch (_direction ) {
case 0:
if (arrowDirect[0] == KeyCode.UpArrow) { _actState = 6; }
if (arrowDirect[0] == KeyCode.DownArrow) { _actState = 7; }
break;
case 1:
if (arrowDirect[0] == KeyCode.DownArrow) { _actState = 6; }
if (arrowDirect[0] == KeyCode.UpArrow) { _actState = 7; }
break;
case 2:
if (arrowDirect[0] == KeyCode.RightArrow) { _actState = 6; }
if (arrowDirect[0] == KeyCode.LeftArrow) { _actState = 7; }
break;
case 3:
if (arrowDirect[0] == KeyCode.LeftArrow) { _actState = 6; }
if (arrowDirect[0] == KeyCode.RightArrow) { _actState = 7; }
break;
}
return;
}
// 押されているキーが2つ以上あるか調べる
bool flag = arrowDirect.Count > 1;
//~~~以下コード省略~~~
}
ステートが5・6・7の時はコチラに分岐しておいて、
まずはステート5になったら何も十字キーが押されていないと5のままにしておきます。
その後に方向によって前後のキーだけを有効にしてそれぞれでステートを変更します。
これで押すか引くかの状態変化を作ることが出来ました。
ステートマネージャーとしてちゃんとステート変更だけを行っていますね。
良い感じです。
しかしこのままではオブジェクトが掴んでいるかどうかがわからないので、
アクションの掴み関数をステート5~7で動くようにしましょう。
押すも引っ張るも掴んでる事には変わりないですからね!
次にこれによってステートが変わるので、Action側もステートに合わせて処理を変えましょう。
// 掴み処理
protected virtual void Grab() {
if (_State.ActState >= 5 && _acTState <= 7 ) {
// 衝突判定をしたオブジェクトのcolliderがnullでなければ
if (getLineCast2Object(_State.Direction, _Player, _layerMaskGrab, true).collider != null ) {
switch (_State.ActState) {
case 6:
Pull();
break;
case 7:
Push();
break;
default:
break;
}
}
}
}
// 引っ張り処理
protected virtual void Pull() {
Debug.Log("引っ張り");
}
// 押す処理
protected virtual void Push() {
Debug.Log("押し");
}
とりあえず移動処理は次回に回すとして、オブジェクトをつかんでいる状態であれば
ステートが変わったら引っ張ると押すの関数を呼び出せるようにしてみました。
ここで問題が発生!
よく考えたらディレクション決めてる側でステートをきめようとしているので、
Gキーを押した後に5にしている「setState」関数が後に呼ばれてしまっているため
ループの終わりでステートが5に書き換わっているため不具合が起こります。
なのでGを押している時にキー入力でステート変更に切り替えにしなければいけません。
ちょっとしっかりと見直さないといけないので次回に回します。
それでは!