[골드메탈 BE4] 따라하기 2

배근철·2022년 7월 25일
0

GoldMetal BE4

목록 보기
2/11

✍ 프리펩으로 발사체 만들기

Prefabs

  • 재활용을 위해 에셋으로 저장된 게임오브젝트
  • Scene 오브젝트를 에셋 안으로 드래그하여 생성한다.
  • 총알을 프리펩으로 생성하고 충돌이벤트를 위해 Collider와 Rigidbody를 넣어준다.
    • Rigidbody는 AddForce로 총알의 발사를 구현할 것이기 때문에 Dynamic 타입에 Gravity Scale은 0으로 설정

      프리펩은 위와 같이 파란색으로 표시됨.

✍ 오브젝트 삭제

  • 게임에 이미 지나간 총알이 계속쌓이면 메모리낭비가 일어나므로, 경계를 만들어 총알이 경계를 지나면 삭제하도록 한다.
  • 따라하기 1에서 한 플레이어경계를 복사해 크기를 설정하고 태그를 BorderBullet으로 설정 한 후 , Bullet.cs를 만들고 OnTriggerEnter2D 함수를 이용해 제거한다.
  • 게임오브젝트의 제거는 Destroy()를 사용한다.
private void OnTriggerEnter2D(Collider2D collision)
    {
        if(collision.gameObject.tag == "BorderBullet")
        {
            Destroy(gameObject);
        }
    }

✍ 발사체 생성

  • Input.GetButton을 이용해 발사체를 생성한다.
  • Instantiate()를 사용해 생성 -> Instantiate() : 매개변수 오브젝트를 생성하는 함수
  • Instantiate로 생성하고 AddForce로 발사를 구현
 GameObject Bullet = Instantiate(BulletA, transform.position, transform.rotation); // 프리펩이름, 위치, 회전
 Rigidbody2D rigid = Bullet.GetComponent<Rigidbody2D>();
 rigid.AddForce(Vector2.up * 10, ForceMode2D.Impulse);

✍ 발사체 다듬기

  • 총알의 충돌을 막기 위해 isTrigger를 켜준다.
  • 마우스 좌클릭을 누를 때 무한대로 총알이 발사하기 때문에 딜레이를 설정할 변수를 만들어준다.
  • curShotDelay에 Time.deltTime을 더해주면서 maxShotDelay보다 작을 경우 총알이 나가지 않게함.
    curShotDelay += Time.deltaTime;
  • 마우스 좌클릭을 누르지 않거나, 딜레이 시간이 안지났으면 return
    if (!Input.GetButton("Fire1")) // Fire1은 마우스좌클릭
               return;
     if (curShotDelay < maxShotDelay)
               return;

✍ 발사체 파워

  • 발사체의 파워에 따라 총알이 다르게 나가도록 설정
  • switch문으로 로직을 만들어주고, power의 단계에 따라 2개가 나가던지, 3개가 나가던지 설정
 switch(power)
        {
            case 1:
                // Power 1
                GameObject Bullet = Instantiate(BulletA, transform.position, transform.rotation);
                Rigidbody2D rigid = Bullet.GetComponent<Rigidbody2D>();
                rigid.AddForce(Vector2.up * 10, ForceMode2D.Impulse);
                break;
            case 2:
                // Power 2
                GameObject BulletR = Instantiate(BulletA, transform.position + Vector3.right*0.1f, transform.rotation);
                GameObject BulletL = Instantiate(BulletA, transform.position + Vector3.left*0.1f, transform.rotation);
                Rigidbody2D rigidR = BulletR.GetComponent<Rigidbody2D>();
                Rigidbody2D rigidL = BulletL.GetComponent<Rigidbody2D>();
                rigidR.AddForce(Vector2.up * 10, ForceMode2D.Impulse);
                rigidL.AddForce(Vector2.up * 10, ForceMode2D.Impulse);
                break;
            case 3:
                // Power 3
                GameObject BulletRR = Instantiate(BulletA, transform.position + Vector3.right*0.35f, transform.rotation);
                GameObject BulletCC = Instantiate(BulletB, transform.position, transform.rotation);
                GameObject BulletLL = Instantiate(BulletA, transform.position + Vector3.left*0.35f, transform.rotation);
                Rigidbody2D rigidRR = BulletRR.GetComponent<Rigidbody2D>();
                Rigidbody2D rigidCC = BulletCC.GetComponent<Rigidbody2D>();
                Rigidbody2D rigidLL = BulletLL.GetComponent<Rigidbody2D>();
                rigidRR.AddForce(Vector2.up * 10, ForceMode2D.Impulse);
                rigidCC.AddForce(Vector2.up * 10, ForceMode2D.Impulse);
                rigidLL.AddForce(Vector2.up * 10, ForceMode2D.Impulse);
                break;
        }

✍ 전체코드

Bullet.cs

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

public class Bullet : MonoBehaviour
{
    private void OnTriggerEnter2D(Collider2D collision)
    {
        if(collision.gameObject.tag == "BorderBullet")
        {
            Destroy(gameObject);
        }
    }
}

Player.cs

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

public class Player : MonoBehaviour
{
    public bool isTouchTop;
    public bool isTouchBottom;
    public bool isTouchLeft;
    public bool isTouchRight;

    public float speed;
    public float power;
    public float curShotDelay;
    public float maxShotDelay;
    
    public GameObject BulletA;
    public GameObject BulletB;

    Animator anim;

    private void Awake()
    {
        anim = GetComponent<Animator>();
    }

    // Update is called once per frame
    void Update()
    {
        Move();
        Fire();
        Reload();
    }

    void Reload()
    {
        curShotDelay += Time.deltaTime;
    }

    void Fire()
    {
        if (!Input.GetButton("Fire1")) // Fire1은 마우스좌클릭
            return;

        if (curShotDelay < maxShotDelay)
            return;


        switch(power)
        {
            case 1:
                // Power 1
                GameObject Bullet = Instantiate(BulletA, transform.position, transform.rotation);
                Rigidbody2D rigid = Bullet.GetComponent<Rigidbody2D>();
                rigid.AddForce(Vector2.up * 10, ForceMode2D.Impulse);
                break;
            case 2:
                // Power 2
                GameObject BulletR = Instantiate(BulletA, transform.position + Vector3.right*0.1f, transform.rotation);
                GameObject BulletL = Instantiate(BulletA, transform.position + Vector3.left*0.1f, transform.rotation);
                Rigidbody2D rigidR = BulletR.GetComponent<Rigidbody2D>();
                Rigidbody2D rigidL = BulletL.GetComponent<Rigidbody2D>();
                rigidR.AddForce(Vector2.up * 10, ForceMode2D.Impulse);
                rigidL.AddForce(Vector2.up * 10, ForceMode2D.Impulse);
                break;
            case 3:
                // Power 3
                GameObject BulletRR = Instantiate(BulletA, transform.position + Vector3.right*0.35f, transform.rotation);
                GameObject BulletCC = Instantiate(BulletB, transform.position, transform.rotation);
                GameObject BulletLL = Instantiate(BulletA, transform.position + Vector3.left*0.35f, transform.rotation);
                Rigidbody2D rigidRR = BulletRR.GetComponent<Rigidbody2D>();
                Rigidbody2D rigidCC = BulletCC.GetComponent<Rigidbody2D>();
                Rigidbody2D rigidLL = BulletLL.GetComponent<Rigidbody2D>();
                rigidRR.AddForce(Vector2.up * 10, ForceMode2D.Impulse);
                rigidCC.AddForce(Vector2.up * 10, ForceMode2D.Impulse);
                rigidLL.AddForce(Vector2.up * 10, ForceMode2D.Impulse);
                break;

        }
        

        curShotDelay = 0;
    }

    void Move()
    {
        float h = Input.GetAxisRaw("Horizontal");
        if ((isTouchRight && h == 1) || (isTouchLeft && h == -1))
            h = 0;
        float v = Input.GetAxisRaw("Vertical");

        if ((isTouchTop && v == 1) || (isTouchBottom && v == -1))
            v = 0;

        Vector3 curPos = transform.position;
        Vector3 nextPos = new Vector3(h, v, 0) * speed * Time.deltaTime;

        transform.position = curPos + nextPos;

        // Animation

        if (Input.GetButtonUp("Horizontal") || Input.GetButtonDown("Horizontal"))
        {
            anim.SetInteger("Input", (int)h);

        }
    }

    public void OnTriggerEnter2D(Collider2D collision)
    {
        if(collision.gameObject.tag == "Border")
        {
            switch(collision.gameObject.name)
            {
                case "Top":
                    isTouchTop = true;
                    break;
                case "Bottom":
                    isTouchBottom = true;
                    break;
                case "Left":
                    isTouchLeft = true;
                    break;
                case "Right":
                    isTouchRight = true;
                    break;
                   
            }
        }
    }

    private void OnTriggerExit2D(Collider2D collision)
    {
        if (collision.gameObject.tag == "Border")
        {
            switch (collision.gameObject.name)
            {
                case "Top":
                    isTouchTop = false;
                    break;
                case "Bottom":
                    isTouchBottom = false;
                    break;
                case "Left":
                    isTouchLeft = false;
                    break;
                case "Right":
                    isTouchRight = false;
                    break;

            }
        }
    }
}

출처 - https://www.youtube.com/c/GoldMetal

0개의 댓글