❤❤Fungus新課程即將發布,快寫問卷拿優惠❤❤

2016年12月28日 星期三

Unity 小遊戲 教學 UFO 2D





註解裡的所有中文命名只是為了理解程式的邏輯而編寫 並非標準的中文通用翻譯

using UnityEngine;

public class Rotator : MonoBehaviour
//public class 旋轉器 : MonoBehaviour
    {
    void Update ( )
    //void 更新() 每秒執行約60次
        {
        transform.Rotate ( new Vector3 ( 0 , 0 , 45 ) * Time.deltaTime );
        //變形.旋轉(新 3維向量(0, 0, 45 )) * 時間.時間變化)
        //總之可以理解為每秒以Z軸為中心轉45度

        //面對一個人的時候 :
        //對方點頭 就是頭部沿著X軸在旋轉
        //對方搖頭 就是頭部沿著Y軸在旋轉
        //對方擺頭頂著肩膀 就是頭部沿著Z軸在旋轉
        }
    }



using System.Collections;
using System.Collections.Generic;
using UnityEngine;

//攝影機控制器
public class CameraController : MonoBehaviour {

    [Header("玩家物件")]
    public GameObject player;

    [Header ( "相對位移" )]
    public Vector3 offset;//宣告成public可以即時修改數值


    void Start () {

        offset = transform.position - player.transform.position;
        //相對位移 = 攝影機的座標 - 玩家的座標
 }
 
 // Update is called once per frame
 void LateUpdate () {
        transform.position = player.transform.position + offset;
        //攝影機的座標 = 玩家的座標 + 相對位移
 }
}



using UnityEngine;

public class TriggerAndCollider : MonoBehaviour
//public class 觸發器與碰撞器 : MonoBehaviour
    {
    void OnCollisionEnter2D ( Collision2D collision )
    //void 碰撞器進入2D (碰撞器2D 碰撞) 觸碰到東西的時候才執行
        {
        Debug.Log ( "OnCollisionEnter2D " + name + "碰到了" + collision.gameObject.name );
        //除錯.紀錄("碰撞器進入2D "+ 名稱 +"碰到了"+ 碰撞器.所屬遊戲物件.名稱 );
        }

    void OnTriggerEnter2D ( Collider2D collision )
    //void 觸發器進入2D (碰撞器2D 碰撞) 觸碰到東西的時候才執行
        {
        Debug.Log ( "OnTriggerEnter2D " + name + "觸發了" + collision.gameObject.name );
        ////除錯.紀錄("觸發器進入2D "+ 名稱 +"觸發了" + 碰撞器.所屬遊戲物件.名稱 );
        }
    }
可以這樣想:
trigger也是扣板機的意思 手指扣下trigger板機
觸發手槍發射出子彈
所以跟子彈碰撞的不是手指 而是子彈跟標靶
手指跟板機之間會有個onTrigger相關的設定
子彈跟標靶之間會有個onCollider相關的設定



using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

//玩家控制器
public class PlayerController : MonoBehaviour {

    [Header("水平方向")]
    public float moveX;

    [Header ( "垂直方向" )]
    public float moveY;

    [Header("推力")]
    public float push;

    Rigidbody2D rb2D;//剛體 以便可以被施力

    [Header ( "分數文字UI" )]
    public Text countText;//這不是string字串喔

    [Header ( "過關文字UI" )]
    public Text winText;//這不是string字串喔

    int score;//分數

    void Start () {
        rb2D = GetComponent<rigidbody2d> ( );
        //rb2D = 取得組件<剛體2D> (); 

        winText.text = "";//清空過關文字的內容
        setScoreText ( );//顯示 目前分數:0
 }

    
    void FixedUpdate ( )
        {
        moveX = Input.GetAxis ( "Horizontal");
        //水平移動 = 輸入.取得軸向("水平");

        moveY = Input.GetAxis ( "Vertical" );
        //垂直移動 = 輸入.取得軸向("垂直");

        Vector2 movement = new Vector2 ( moveX , moveY );
        //2維向量 移動方向 = 新 2維向量 (水平移動, 垂直移動);

        rb2D.AddForce ( push * movement );
        //rb2D.施加力量 ( 推力 * 移動方向 );
        }

    void OnTriggerEnter2D ( Collider2D other )
        {
        Debug.Log ( name+"觸發了"+other.name );

        if ( other.CompareTag("PickUp") )
        //其他.比較標籤("PickUp")
            {
            other.gameObject.SetActive ( false );
            //其他.遊戲物件.設定活躍狀態(否);

            score = score + 1;
            setScoreText ( );
            }
        }

    void setScoreText ( ) {
        countText.text = "目前分數:" + score.ToString ( );
        //計分文字UI.文字 = "目前分數:" + 分數.轉字串 ( );

        if ( score>=12 ) //如果分數大於12
            {
            winText.text = "你贏了";
            //過關文字UI.文字 = "你贏了";
            }
        }
    }




17 則留言:

  1. 不好意思,我想問一下,為什麼攝影機的offset能夠用Vector3?不是只有x,y嗎?
    還有,若是我把程式改成transform.position = player.transform.position;
    這樣會導致攝影機拍不出東西?

    回覆刪除
    回覆
    1. 雖然是2D遊戲,但還是有Z軸前後景的區分喔,所以當你使用這行程式碼的時候:
      transform.position = player.transform.position;
      意思是指把玩家的座標套用到攝影機裡面
      等於攝影機跟玩家"零距離"
      你可以理解為類似玩家在攝影機後面一點點的地方
      所以當然拍不到東西

      刪除
    2. 不好意思~那如果是用offset把相對的位移加回去,z軸的值應該也是一樣被加回去了,這樣不是一樣和玩家物件依然在同一個平面上?(還是會改變?

      刪除
  2. 你好請問 如果要將 金塊動起來 且 撞牆不會飛出去 又可以讓球吃掉他 該怎麼設計呢 onTrigger onCollider 還是有點糊塗 謝謝老師

    回覆刪除
    回覆
    1. 作者已經移除這則留言。

      刪除
    2. 我目前是卡在 球可以吃掉金塊 金塊可以亂移動 但是金塊會跑出去外框

      刪除
    3. Scene內點擊某個金塊,掛上RigidBody2D以後,Gravity重力改成0,然後點擊Inspector視窗右上角的Apply,套用到每一個金塊裡。
      然後PlayerController的OnTriggerEnter2D方法可以改成這樣:
      void OnCollisionEnter2D(Collision2D other )
      {
      Debug.Log(name + "碰到了" + other.collider.name );

      if ( other.collider.CompareTag("PickUp") )
      //其他.比較標籤("PickUp")
      {
      other.gameObject.SetActive ( false );
      //其他.遊戲物件.設定活躍狀態(否);

      score = score + 1;
      setScoreText ( );
      }
      }

      你應該有另外設定金塊自動移動吧?不然如果金塊一樣只是原地轉動,位置不動的話,這樣修改的意義不大,因為碰到的瞬間就會讓金塊消失了,如果金塊本身會隨時移動位置的話就比較有意義

      刪除
    4. 我將 rotator 加上一行
      transform.Translate(new Vector2(Random.Range(-20, 20), Random.Range(-20, 20)) * Time.deltaTime);
      讓他亂數移動 然後我把PlayerController的OnTriggerEnter2D方法改了 結果金塊還是 跑出去牆壁外了 是還有哪裡要注意的嗎

      刪除
    5. 還是這種移動方式 會把他擠出牆壁 因為我看金塊移動有點像是在跳躍的感覺

      刪除
    6. 對了 照老師的方式改 變成球碰到金塊 沒有把它吃掉了

      刪除
    7. 啊 抱歉 ,金塊Collider的IsTrigger 要取消打勾 應該就不會跑出牆壁外了
      跟金塊的移動方式比較沒關係,除非你牆壁做得很薄,才有可能被擠出去

      刪除
    8. 有了有了 我剛剛把他is Trigger 取消 就吃掉了 謝謝 我在想辦法解決 移動的問題

      刪除
  3. 老師請問一下,在UFO吃金塊的時候我按照您的設定都一樣。可是執行的時候寫說金塊沒有定義,可以觸發不過吃不了金塊,我是哪裡出了問題呢??

    回覆刪除
  4. 金塊有上Tag標籤嗎? PickUP標籤 大小寫有別喔
    或是找一下 文字比對 的軟體
    看看你寫的程式碼是不是跟我的完全一模一樣

    回覆刪除
  5. 我幽浮吃掉金塊的那邊的程式一直出錯= =
    明明都已經照著打甚至複製還是一樣

    回覆刪除
    回覆
    1. 有沒有什麼錯誤訊息?
      金塊有上tag嗎? 金塊的IsTrigger有沒有打勾?
      還是沒辦法的話,請加我line傳截圖或專案檔幫你看

      https://www.youtube.com/channel/UCXWxqnjzo4q6NhQiLhQFk7g/about

      刪除

留言給作者加油打氣