# Unity 2D 小粉人 ## unity簡介 * Unity 是一款由Unity Technologies開發的跨平台遊戲引擎,可用於開發2D和3D遊戲。 * 支援多種個人電腦、行動裝置、遊戲主機、網頁平台、擴增實境和虛擬實境,被認為容易上手,並在獨立遊戲開發中廣受歡迎。 * 許多遊戲,如:傳說對決、碧藍航線、原神,皆用unity製做。 * 遊戲透過製作場景、放置物件、撰寫C#腳本而成。 ## 遊戲介紹 #### 2D跑酷遊戲: 一種類型的電子遊戲,通常由玩家控制角色在橫向捲動的場景中不斷奔跑,躲避障礙物並收集物品。這種遊戲注重玩家的反應速度和操作技巧。 #### 遊戲操作: * 透過左右鍵控制角色左右移動 * 空白鍵進行跳躍 ## 遊戲場景 * #### 開始場景![image](https://hackmd.io/_uploads/BJ79s3TIA.png) * #### 遊戲關卡一![image](https://hackmd.io/_uploads/Sy3Uh3aIA.png) * #### 遊戲關卡二![image](https://hackmd.io/_uploads/BkFla3T8A.png) * #### 結束畫面![image](https://hackmd.io/_uploads/rkb7pnpIR.png) ## 物件 * ### 小粉人![image](https://hackmd.io/_uploads/B1Vb23RU0.png) * #### 移動 * 左右移動+跑動動畫 * 跳躍+音效+跳躍動畫 * ```csharp= private SpriteRenderer sprite; private Animator anim; private Rigidbody2D rb; private BoxCollider2D coll; [SerializeField] private AudioSource jumpSoundEffect; [SerializeField] private LayerMask jumpableGround; private float dirX=0f; [SerializeField] private float moveSpeed = 7f; [SerializeField] private float jumpForce = 7f; private enum MovementState { idle,running,jumping,falling} void Start() { rb=GetComponent<Rigidbody2D>(); coll = GetComponent<BoxCollider2D>(); sprite = GetComponent<SpriteRenderer>(); anim = GetComponent<Animator>(); } // 移動 void Update() { dirX=Input.GetAxisRaw("Horizontal"); rb.velocity = new Vector2(dirX*moveSpeed,rb.velocity.y); if (Input.GetButtonDown("Jump")) { jumpSoundEffect.Play(); rb.velocity= new Vector2(rb.velocity.x,jumpForce); } UpdateAnimationState(); } //動畫 private void UpdateAnimationState() { MovementState state; if(dirX > 0f) { state = MovementState.running; sprite.flipX = false; } else if(dirX < 0f) { state = MovementState.running; sprite.flipX = true; } else { state = MovementState.idle; } if(rb.velocity.y > .1f) { state = MovementState.jumping; } else if(rb.velocity.y < -.1f) { state = MovementState.falling; } anim.SetInteger("state", (int)state); } ``` * #### 收集物品 * 播放音效 * 更新計分 * 刪除櫻桃 * ```csharp= int cherries = GameManger.Instance.score; [SerializeField] private Text cherriesText; [SerializeField] private AudioSource collectSoundEffect; private void OnTriggerEnter2D(Collider2D collision) { if (collision.gameObject.CompareTag("cherry")) { collectSoundEffect.Play(); Destroy(collision.gameObject); cherries++; cherriesText.text = "cherries:" + cherries; GameManger.Instance.score = cherries; } } ``` * #### 死亡 * 播放音效 * 死亡動畫 * 回到此場景開頭 * ```csharp= private Rigidbody2D rb; private Animator anim; [SerializeField] private AudioSource deathSoundEffect; // Start is called before the first frame update private void Start() { rb=GetComponent<Rigidbody2D>(); anim=GetComponent<Animator>(); } private void OnCollisionEnter2D(Collision2D collision) { if (collision.gameObject.CompareTag("trap")) { deathSoundEffect.Play(); Die(); } } private void Die() { rb.bodyType = RigidbodyType2D.Static; anim.SetTrigger("death"); } private void RestartLevel() { SceneManager.LoadScene(SceneManager.GetActiveScene().name); } ``` * ### 櫻桃 ![image](https://hackmd.io/_uploads/S1d5b6R80.png) * 跳動循環動畫 * 被觸碰後加分且消失 * ### 陷阱一:地刺![image](https://hackmd.io/_uploads/B1b3Mp0UC.png) * 碰到使角色死亡 * ### 陷阱二:旋轉齒輪![image](https://hackmd.io/_uploads/BJLdmaR80.png) * 碰到使角色死亡 * 在固定的兩點間移動且旋轉 * ```csharp= [SerializeField] private float speed = 2f; //設定齒輪旋轉速度 private void Update() { transform.Rotate(0,0,360*speed*Time.deltaTime); } ``` * ### 移動地板![image](https://hackmd.io/_uploads/HJgpVpRIR.png) * 角色可站在上面移動 * 在固定的兩點間移動 * ```csharp= [SerializeField] private GameObject[] waypoints; private int currentWaypointIndex = 0; [SerializeField] private float speed = 2f;//設定移動速度 private void Update() {//在兩點間移動 if (Vector2.Distance(waypoints[currentWaypointIndex].transform.position , transform.position) < .1f) { currentWaypointIndex++; if(currentWaypointIndex >= waypoints.Length) { currentWaypointIndex = 0; } } transform.position = Vector2.MoveTowards(transform.position, waypoints[currentWaypointIndex].transform.position, Time.deltaTime * speed); } ``` * ### 最終旗子![image](https://hackmd.io/_uploads/HJZ-E6RUR.png) * 角色碰到進入下一個場景且撥放音效 * ```csharp= private AudioSource finishSound; private bool levelCompleted = false; private void Start() {//設定音效 finishSound = GetComponent<AudioSource>(); } private void OnTriggerEnter2D(Collider2D collision) {//判斷觸碰 if(collision.gameObject.name == "player" && !levelCompleted) { finishSound.Play(); levelCompleted = true; Invoke("CompleteLevel", 2f); } } private void CompleteLevel() {//改變場景 SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex +1); } ```