筆記23 Unity項目:超級瑪麗

拖放地圖,裁剪精靈,形成跑步動畫,精靈渲染器

在這裏插入圖片描述

攝像機跟隨+代碼CameraControl

在這裏插入圖片描述

    //跟隨的物體
    public Transform target;

    //最小邊界(能到的最左邊)
    public float minX;
    //最大邊界(能到的最右邊)
    public float maxX;

	void Update () {
        //獲取當前位置
        Vector3 pos = transform.position;
        //將它的x改成目標的x
        pos.x = target.position.x;
        //邊界判斷。需要傳入兩個邊界
        if(pos.x > maxX)
        {
            pos.x = maxX;
        }
        if(pos.x < minX)
        {
            pos.x = minX;
        }
        //再賦值回去
        transform.position = pos;
	}

瑪里奧動畫

在這裏插入圖片描述

給馬里奧、地面等添加碰撞器、剛體(注意是2D的!)

在這裏插入圖片描述

添加音樂播放器+代碼AudioManager

在這裏插入圖片描述

   //音頻播放器有了,首先寫成單例類。
    public static AudioManager Instance;

    //寫出兩個播放器(背景音、音效)。然後到unity裏關聯(背景音,循環打鉤)。
    public AudioSource bgmPlayer;
    public AudioSource sePlayer;

    void Awake()
    {
        //單例類一定要在Awake裏面賦值。因爲這個方法調用的時機比Start靠前。
        //這樣可以保證在第一時間把這個單例做成。
        Instance = this;
    }

    // 下面給三個方法
    //一個播放bgm。傳進來一個name,就是你播放的文件名稱
    public void PlayMusic(string name)
    {
        //如果當前沒有播放,再去播放
        if (bgmPlayer.isPlaying == false)
        {
            /*加載音頻資源。類型AudioClip。
            從哪個位置加載?直接把name(外界傳進來的)放那就可以了。*/
            AudioClip clip = Resources.Load<AudioClip>(name);
            //更換當前播放的聲音片段
            bgmPlayer.clip = clip;
            //播放Play
            bgmPlayer.Play();
        }
    }
    //停止播放
    public void StopMusic()
    {
        bgmPlayer.Stop();
    }
    //播放音效
    public void PlaySound(string name)
    {
        /*加載音頻資源。類型AudioClip。
        從哪個位置加載?直接把name(外界傳進來的)放那就可以了。*/
        AudioClip clip = Resources.Load<AudioClip>(name);
        //播放音效
        sePlayer.PlayOneShot(clip);
    }

檢測是否與地面碰撞(有兩種方法)

法一:利用射線檢測是否碰到地面(適用此遊戲)

       //利用射線檢測是否碰到地面(法一)
        //畫出射線。從中心點出發,向下*0.1米。
        Debug.DrawRay(transform.position, Vector2.down * 0.1f);
        /*創建2d射線。特點:可以直接返回。3d返回的是布爾值,hit在上面,利用out給hit值。
        而且在括號裏可以直接填寫射線的起點,方向,距離,檢測的層(此處是第8層)。*/
        RaycastHit2D hit = Physics2D.Raycast(transform.position, Vector2.down ,0.1f,1<<8);
        if(hit.collider != null)
        {
            //說明碰到地面了
            isGround = true;
            //把跳躍的動畫關閉
            ani.SetBool("Jump", false);
        }
        else
        {
            //沒碰到地面(在空中)
            isGround = false;
            ani.SetBool("Jump", true);
        }

在這裏插入圖片描述

法二:不通過射線(不適用此遊戲)

   //判斷是否碰撞到地面(法二)。此處不適用,比如碰到左邊碰撞體,可以二段跳。
    private void OnCollisionEnter2D(Collision2D collision)
    {
        if (collision.collider.tag == "Ground")
        {
            isGround = true;
        }
    }
    private void OnCollisionExit2D(Collision2D collision)
    {
        if (collision.collider.tag == "Ground")
        {
            isGround = false;
        }
    }

敵人蘑菇+代碼EnemyControl

拖放,添加碰撞器、剛體,添加動畫,編寫代碼,形成預設體。
在這裏插入圖片描述

    //血量
    public int Hp = 1;
    //剛體
    private Rigidbody2D rBody;
    //動畫
    private Animator ani;

    //保存方向。方向分爲1(正方向)和-1(負方向)。
    private int dir = 1;

	void Start () {
        //在這裏得到
        rBody = GetComponent<Rigidbody2D>();
        ani = GetComponent<Animator>();		
	}
	
	void Update () {
		if(Hp <= 0)
        {
            return;
        }
        /*移動(方向*速度)。
        爲了使敵人碰到物體後向相反方向移動,此處乘以方向(上面設置了默認是正方向)。*/
        //老師寫的是Vector3.left
        transform.Translate(Vector2.left * 0.2f * dir * Time.deltaTime);
	}
    //不管碰到什麼物體,都向反方向移動
    private void OnCollisionEnter2D(Collision2D collision)
    {
        dir = -dir;
        //判斷玩家碰到自己。注意給玩家標籤。
        if(collision.collider.tag == "Player")
        {
            //contacts[0]碰撞的點,point代表拿到這一點的位置。
            //contacts[0].normal它還有一個法線,就是和碰撞點垂直的單位向量。
            //比如玩家從上面踩了蘑菇,會產生從碰撞點向下的法線。
            if (collision.contacts[0].normal == Vector2.down)
            {
                //也就是說玩家從上方踩到,敵人死亡
                //拿到玩家身上的剛體組件,給它添加一個向上的力。
                collision.collider.GetComponent<Rigidbody2D>().AddForce(Vector2.up * 100f);
                //死亡方法寫在外面,此處調用。
                Die();
            }
            else
            {
                //玩家從其他方向碰到敵人,玩家死亡
                //拿到玩家的代碼,調用裏面的Die方法。
                collision.collider.GetComponent<PlayControl>().Die();
            }
        }
    }
    //死亡
    void Die()
    {
        Hp--;
        if(Hp <= 0)
        {
            //死亡
            //一秒之後銷燬
            Destroy(gameObject, 1f);
            //動畫
            ani.SetBool("Die", true);
            //聲音
            AudioManager.Instance.PlaySound("踩敵人");
            /*碰撞器失效(因爲死亡了,玩家踩到的時候不能再觸發事件。
            而之所以能產生事件,是因爲碰撞器的存在)*/
            GetComponent<Collider2D>().enabled = false;
            //刪除剛體(碰撞器也可以用此方法。如果刪除了碰撞器,而沒有刪除剛體,那麼蘑菇會掉下去。)
            Destroy(GetComponent<Rigidbody2D>());
        }
    }

代碼:馬里奧PlayControl

    //人物的血量
    public int Hp = 1;
    //是否在地面
    private bool isGround = false;
    //剛體
    private Rigidbody2D rBody;
    //動畫
    private Animator ani;
    //獲取精靈圖片(爲了後面翻轉圖片)
    private SpriteRenderer sr;


	void Start () {
        //在此處拿到這兩個組件
        rBody = GetComponent<Rigidbody2D>();
        ani = GetComponent<Animator>();
        sr = GetComponent<SpriteRenderer>();
	}
	
	void Update () {
		if (Hp <= 0)
        {
            return;
        }
        //因爲人物只是左右跑,所以拿水平軸
        float horizontal = Input.GetAxis("Horizontal");
        //如果水平軸不爲0
        if (horizontal != 0)
        {
            //前進
            transform.Translate(transform.right * Time.deltaTime * 1 * horizontal);
            //翻轉圖片(模擬轉頭)
            if (horizontal > 0)
            {
                //說明是往右邊走所以不翻轉
                sr.flipX = false;
            }
            if (horizontal < 0)
            {
                sr.flipX = true;
            }
            //移動動畫
            ani.SetBool("Run", true);
        }
        else
        {
            ani.SetBool("Run", false);
        }
        //跳躍。按了I鍵,並且人物是站在地上的。
        if (Input.GetKeyDown(KeyCode.I) && isGround == true)
        {
            //跳躍力(向上,作用在剛體上)
            rBody.AddForce(Vector2.up * 200);
            //播放跳的聲音
            AudioManager.Instance.PlaySound("跳");
        }
       
        //利用射線檢測是否碰到地面(法一)
        //畫出射線。從中心點出發,向下*0.1米。
        Debug.DrawRay(transform.position, Vector2.down * 0.1f);
        /*創建2d射線。特點:可以直接返回。3d返回的是布爾值,hit在上面,利用out給hit值。
        而且在括號裏可以直接填寫射線的起點,方向,距離,檢測的層(此處是第8層)。*/
        
       RaycastHit2D hit = Physics2D.Raycast(transform.position, Vector2.down, 0.1f, 1<<8);
       if(hit.collider != null)
       {
           //說明碰到地面了
           isGround = true;
           //把跳躍的動畫關閉
           ani.SetBool("Jump", false);
       }
       else
       {
           //沒碰到地面(在空中)
           isGround = false;
           ani.SetBool("Jump", true);
       }     
    }

    //玩家的死亡方法,因爲在敵人的代碼裏調用,所以此處是public
    public void Die()
    {
        Hp--;
        if (Hp <= 0)
        {
            //死亡
            ani.SetTrigger("Die");
            //刪除碰撞器。(因爲玩家死亡時,是從場景中掉落的,所以只要刪除碰撞器,不刪剛體)。
            Destroy(GetComponent<Collider2D>());
            //停止播放背景音樂
            AudioManager.Instance.StopMusic();
            //播放死亡音樂
            AudioManager.Instance.PlaySound("死亡");
            //讓玩家靜止
            rBody.velocity = Vector2.zero;
            //讓玩家靜止,即將它的速度設爲0。爲了避免玩家在不同情況下死亡後,向上跳的高度不同)
            rBody.velocity = Vector2.zero;
            //跳躍。給一個向上的力
            rBody.AddForce(Vector2.up * 150f);
            //延時。1秒之後播放
            Invoke("Die2", 1f);
        }
    }
    void Die2()
    {
        AudioManager.Instance.PlaySound("死亡2");
    } 

補充

使用字符串(即動畫名字)播放動畫

    //
            //移動動畫
            ani.SetBool("Run", true);

將名稱(字符串)轉成ID後使用

每個動畫都有一個ID。
因爲系統開闢字符串比開闢整形更加費性能,如果一個動作需要多次使用,優化方法:
在最開始的時候(Start裏),把動作都轉成int類型,用的時候,只要用int類型就好。

    //移動動畫
    int run = Animator.StringToHash("Run");
    //Debug.Log(run);打印ID
    ani.SetBool(run,true);
    
    //獲取數值
    bool res = ani.GetBool(run);

靜態金幣+代碼CoinStatic

在這裏插入圖片描述

    //觸發
    private void OnTriggerEnter2D(Collider2D collision)
    {
         if(collision.tag == "Player")
         {
            //播放聲音
            AudioManager.Instance.PlaySound("金幣");
            //銷燬自己
            Destroy(gameObject);
         }
     }

磚塊+代碼RockControl

在這裏插入圖片描述

    //大磚塊
    public GameObject Rock;
    //小磚塊
    public GameObject[] Rocks;
    //寫完上面的代碼,需要到unity裏面關聯一下。

	// Use this for initialization
	void Start () {
		
	}
	

    private void OnCollisionEnter2D(Collision2D collision)
    {
        //如果玩家碰了我,並且碰撞點的法線向上(說明玩家是從線面碰到的)
        if (collision.collider.tag == "Player" && collision.contacts[0].normal == Vector2.up)
        {
            //播放音樂
            AudioManager.Instance.PlaySound("頂破磚");
            //小磚塊會四散開來。首先遍歷一下
            foreach(GameObject rock in Rocks)
            {
                //把父物體(大磚塊)設置爲空,小磚塊就沒有父物體了,會顯示在前面
                rock.transform.parent = null;
                //3D有爆炸力,2D沒有。首先,添加剛體。rock是4個小磚塊
                Rigidbody2D rbody = rock.AddComponent<Rigidbody2D>();
                //得到從整體的中心點到各個小磚塊中心點的向量。
                Vector2 dir = rock.transform.position - transform.position;
                //給力。dir沿着這個向量的方向*100的力
                rbody.AddForce(dir * 900f);
                //1秒之後銷燬
                Destroy(rock, 1f);
            }
            //銷燬大磚塊
            Destroy(gameObject);
        }
    } 

箱子、頂出動態金幣+二者代碼

在這裏插入圖片描述

代碼:箱子BoxControl

    //血量。(頂幾次)
    public int Hp = 5;
    //頂出來的物體
    public GameObject goPre;
    //音效名稱(傳進來)
    public string sound; 

	void Start () {
		
	}
	
	private void OnCollisionEnter2D(Collision2D collision)
    {
        //如果玩家從下面頂撞
        if (collision.collider.tag == "Player" && collision.contacts[0].normal == Vector2.up)
        {
            if(Hp > 0)
            {
                Hp--;
                //頂出物品
                //聲音
                AudioManager.Instance.PlaySound(sound);
                //實例化物品
                Instantiate(goPre, transform.position, Quaternion.identity);
                if(Hp <= 0)
                {
                    //變成磚塊(就是下面的“沒了”)
                    //獲得動畫
                    GetComponent<Animator>().SetTrigger("Die");
                }
            }else
            {
                //箱子已經沒了。
                //播放沒了的聲音
                AudioManager.Instance.PlaySound("頂磚石塊");
            }
        }
    }

代碼:動態金幣CoinControl

   void Start () {
        //獲得剛體
        GetComponent<Rigidbody2D>().AddForce(Vector2.up * 150f);
        //銷燬金幣
        Destroy(gameObject, 1f);
    }

頂箱子,頂出其他東西

在這裏插入圖片描述

老師說要進行拓展練習(暫空)

小記:《馬里奧、〈白夜行〉、我》

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章