とあるプログラマの備忘録

都内某所に住むプログラマが自分用に備忘録を残すという趣旨のブログです。はてなダイアリーから移動しました!

Unity2D入門 スクロールアクションゲームを作る ~鬼門!?ジャンプ処理~

実はこの記事を書いている3日前、、
敵のジャンプモーションを作った私はプレイヤーのジャンプの実装も使用と思ったのですが。。

で き ま せ ん で し た orz

たった3日前ですが、理解があさかったんですね。
前回の反省を踏まえアプローチ方法を変えて再度トライです!

一重にジャンプ処理といっても自分がやりたいジャンプはもちろんマリオのような山型に力が加わる処理です。
前回はRigidbodyの重力操作でなんとかしよとおもいましたが、理想のジャンプに至らなかったのです。
なので今回は

  1. player.Rigidbody2Dの重力を切る
  2. ジャンプモーションを作る
  3. player.gameObject.taransform制御処理を自前で書く

ようは重力制御でなんとかしようと思ったのが間違いだったんやっ!
(すいません本当にこれでいいかはさっぱり不明です)

では早速

player.Rigidbody2Dの重力を切る

f:id:raharu0425:20140116170038p:plain

これを切るともちろん今まで敵にぶつかった際に飛んでいたのが地面に落ちてきません。
とりあえずこの状態にしておきます。

ジャンプモーションを作る

前にスライスしておいたSptiteを使用してジャンプのモーションを作ります。
Unity2D入門 スクロールアクションゲームを作る キャラクター作成 - とあるプログラマの備忘録

f:id:raharu0425:20140116170504p:plain

ジャンプを判断するフラグを作ります

f:id:raharu0425:20140116170655p:plain

モーションができたらAnimatorでモーションの紐付けを行ないます。

f:id:raharu0425:20140116170808p:plain

紐付けはこんな感じで
player@walk > player@jump : isJump = true
player@jump > player@walk : isJump = false
player@jump > player@attack : isAttack = true

player.gameObject.taransform制御処理を自前で書く

playermove.cs

using UnityEngine;
using System.Collections;

public class playermove : MonoBehaviour {
    
    public GameObject firePrefab;

    private bool isRight = true;
    private bool isAttack = false;
+   private bool isJump = false;

+   // JumpParams
+   private float jumpPowor;
+   public float jumpPoworConst = 0.8f;
+   public float jumpGrvity = 0.05f;
    

    // Update is called once per frame
    void Update () 
    {
        GetComponent<Animator>().SetBool("isAttack",isAttack);
+       GetComponent<Animator>().SetBool("isJump",isJump);


+       // Jumpingtime
+       if(isJump){
+           jumpPowor = jumpPowor - jumpGrvity;
+           transform.Translate(Vector3.up * jumpPowor);
+
+           if(jumpPowor < 0 && transform.position.y <= 1){
+               isJump = false;
+           }
+       }else{
+           if(transform.position.y > 1.0f){
+               transform.Translate(Vector3.down * 0.1f);
+           }
+       }

    }

    void FixedUpdate ()
    {
        //  Attack
        if(!isAttack && Input.GetKeyDown("return")){
            isAttack = true;
            StartCoroutine("WaitForAttack");

            // fire Generate
            GameObject fire = Instantiate(firePrefab, new Vector3(transform.position.x, transform.position.y - 0.5f, 1), Quaternion.identity) as GameObject;
            fire.gameObject.SendMessage("setDirection", isRight);
        }

+       //  Jump
+       if(!isAttack && !isJump && Input.GetKeyDown("space")){
+           jumpPowor = jumpPoworConst;
+           isJump = true;
+       }

        //左右キーの入力
        if(!isAttack){
            float h = Input.GetAxis("Horizontal");
            rigidbody2D.AddForce(Vector2.right * h * 300f);

            //右を向いていて、左の入力があったとき、もしくは左を向いていて、右の入力があったとき
            if((h > 0 && !isRight) || (h < 0 && isRight))
            {
                //右を向いているかどうかを、入力方向をみて決める
                isRight = (h > 0);
                //localScale.xを、右を向いているかどうかで更新する
                transform.localScale = new Vector3((isRight ? 2 : -2), 2, 2);
            }
        }
    }

    IEnumerator WaitForAttack()
    {
        yield return new WaitForSeconds(0.5f);
        isAttack = false;
    }
}

+が追加行です
1. ジャンプをしたらisJumpフラグを立てて、初速を初期化します
2. ジャンプフラグをアニメーションに差し込んで
3. 初速に対して係数をフレーム毎にマイナスしていきます
4. 地面に着いたらisJumpフラグをfalseにします。
5. ジャンプ中じゃないのに宙に浮いている場合は下に力を加えます

こんなかんじですかね?
さぁエミュレートしてみましょう!

f:id:raharu0425:20140116172859p:plain

いいです!スバラッ!!

ジャンプを制御するのは、transformを自前で制御してあげるのが楽そうです
他にいい感じのジャンプの実装方法が有れば是非教えてくださいm( )m

今回はこれまで、次回はなにしようかな。。
会社のHさんがイラスト書いてくれる!といっていたのでもしできたらタイトル画面でも作りたいです