[멋쟁이사자처럼 부트캠프 TIL] 멋쟁이사자처럼 유니티게임스쿨 4일차

굥지·2024년 10월 4일
0

EndPoint로 골인지점과 애니메이션, 콜라이더 추가

  • Collider - isTrigger
  • Animation 추가
  • 스크립트 추가
public class EndPoint : MonoBehaviour
{

    private void OnTriggerEnter2D(Collider2D collision)
    {
        if (collision.gameObject.tag == "Player")
        {
            Debug.Log("End");
        }
    }
}

Item(Melon)과 애니메이션, 콜라이더 추가

  • Collider - isTrigger
  • Animation 추가 (+Eaten)
  • 스크립트 추가

먹으면 먹는 애니메이션(Eaten)과 함께 과일이 사라지도록함

public class Fruits : MonoBehaviour
{
    private void OnTriggerEnter2D(Collider2D collision)
    {
        if (collision.gameObject.tag == "Player")
        {
            GetComponent<Animator>().SetTrigger("Eaten");
        }
    }
}

Gamemanger 생성

public class GameManager : MonoBehaviour
{
    private static GameManager instance;
    public static GameManager Instance
    {
        get { return instance; }
    }
    public TMP_Text timeLimitLabel;

    public float TimeLimit = 30;

    private void Awake()
    {
        instance = this;
    }
   
    void Update()
    {
        TimeLimit -= Time.deltaTime;
        timeLimitLabel.text = "Time Left" + ((int)TimeLimit);
    }
}
  • 남은시간 표시

  • 캔버스 추가
  • 남은 시간 텍스트 추가

아이템 먹고 사라지게 하기

public class Fruits : MonoBehaviour
{
    private void OnTriggerEnter2D(Collider2D collision)
    {
        if (collision.gameObject.tag == "Player")
        {
            GetComponent<Animator>().SetTrigger("Eaten");
            GetComponent<Collider2D>().enabled = false;
            Invoke("DestroyThis", 0.6f);
        }
    }
    void DestroyThis()
    {
        Destroy(gameObject);
    }
}
  • Invoke("DestroyThis", 0.6f); 없이도 원하는 시기에 함수 호출 가능

Add event로 이벤트 추가 후


원하는 함수 입력 가능

시간 늘리기

public class GameManager : MonoBehaviour
{
    private static GameManager instance;
    public static GameManager Instance
    {
        get { return instance; }
    }
    public TMP_Text TimeLimitLabel;

    public float TimeLimit = 30;

    private void Awake()
    {
        instance = this;
    }

    void Start()
    {
        
    }

   
    void Update()
    {
        TimeLimit -= Time.deltaTime;
        TimeLimitLabel.text = "Time Left " + ((int)TimeLimit);
    }
    public void AddTime(float time)
    {
        TimeLimit += time;
    }
}

AddTime 함수를 통해 아이템을 먹으면 시간이 늘어나도록 설정

public class Fruits : MonoBehaviour
{
    public float TimeAdd = 5;
    private void OnTriggerEnter2D(Collider2D collision)
    {
        if (collision.gameObject.tag == "Player")
        {
            GameManager.Instance.AddTime(TimeAdd);
            GetComponent<Animator>().SetTrigger("Eaten");
            GetComponent<Collider2D>().enabled = false;
        }
    }
    void DestroyThis()
    {
        Destroy(gameObject);
    }
}

GameManager.Instance.AddTime(TimeAdd); Fruits 스크립트에서 함수 호출

  • 아이템을 먹으면 5초씩 늘어남

프리팹 설정

Revert All : 리셋(프리팹대로 돌리겠다)
Apply All : 적용(이 설정대로 프리팹을 수정하겠다)

죽었을때

public class DeadZone : MonoBehaviour
{
    private void OnTriggerEnter2D(Collider2D collision)
    {
        if(collision.gameObject.tag == "Player")
        {
            GameManager.Instance.Die();
            Debug.Log("Dead");
        }
    }
}

죽었는데도 플레이어를 움직이면 카메라가 움직이는 것 방지하기

public class GameManager : MonoBehaviour
{
    public GameObject CinemaCamera;

    private static GameManager instance;
    public static GameManager Instance
    {
        get { return instance; }
    }
    public TMP_Text TimeLimitLabel;

    public float TimeLimit = 30;

    private void Awake()
    {
        instance = this;
    }
   
    void Update()
    {
        TimeLimit -= Time.deltaTime;
        TimeLimitLabel.text = "Time Left " + ((int)TimeLimit);
    }
    public void AddTime(float time)
    {
        TimeLimit += time;
    }

    public void Die()
    {
        CinemaCamera.SetActive(false);
    }
}

CinemaCamera.SetActive(false); 로 시네마 카메라를 비활성화 해준다.

콜라이더의 차이

public Collider2D BottomCollider;
public CompositeCollider2D TerrainCollder;

▲ 위에서 아래로 찾기 때문에 그냥 Collider2D 라고하면 Tilemap 콜라이더를 가져온다.

목숨 UI

  • horizontal layout group으로 가로로 정렬해준다
public class LifeDisplayer : MonoBehaviour
{
    public List<GameObject> lifeImage;

    public void SetLives(int life)
    {
        for(int i = 0; i<lifeImage.Count; i++)
        {
            if(i<life)
            {
                lifeImage[i].SetActive(true);
            }
            else
            {
                lifeImage[i].SetActive(false);
            }
        }
    }
}

🚨 오류가 생겼던 부분

이 코드에서 false ↔ true를 바꿔버림


public class GameManager : MonoBehaviour
{
    public GameObject CinemaCamera;

    private static GameManager instance;
    public static GameManager Instance
    {
        get { return instance; }
    }
    public TMP_Text TimeLimitLabel;

    public float TimeLimit = 30;

    private void Awake()
    {
        instance = this;
    }

    void Start()
    {
        life = 3;
    }

   
    void Update()
    {
        TimeLimit -= Time.deltaTime;
        TimeLimitLabel.text = "Time Left " + ((int)TimeLimit);
    }
    public void AddTime(float time)
    {
        TimeLimit += time;
    }

    public LifeDisplayer LifeDisplayerInstance;
    int life = 3;

    public void Die()
    {
        CinemaCamera.SetActive(false);
        life--;
        LifeDisplayerInstance.SetLives(life);
    }
}

이제 떨어지면 dead존(아래 떨어지면 Collider)에 맞고 life가 하나 깎인다

죽었을때 위치 초기화

public class PlayerController : MonoBehaviour
{
    public float Speed = 5;
    public float JumpSpeed = 5;
    public Collider2D BottomCollider;
    public CompositeCollider2D TerrainCollder;

    float prevVx = 0;
    float vx = 0;
    bool isGround;

    Vector2 originalPosition;

    public void Restart()
    {
        transform.position = originalPosition;
        GetComponent<Rigidbody2D>().linearVelocity = Vector2.zero;//떨어지고 있을때의 속도 초기화
    }
...생략

}

GetComponent<Rigidbody2D>().linearVelocity = Vector2.zero

떨어지는 속도를 초기화해준다.

public class GameManager : MonoBehaviour
{
    public GameObject CinemaCamera;
    public PlayerController Player;

    private static GameManager instance;
    public static GameManager Instance
    {
        get { return instance; }
    }
    public TMP_Text TimeLimitLabel;

    public float TimeLimit = 30;

    ..생략
    
    public LifeDisplayer LifeDisplayerInstance;
    int life = 3;

    public void Die()
    {
        CinemaCamera.SetActive(false);
        life--;
        LifeDisplayerInstance.SetLives(life);

        Invoke("Restart", 2);
    }

    void Restart()
    {
        if(life > 0)
        {
            CinemaCamera.SetActive(true);
            Player.Restart();
        }
        else
        {
            GameOver();
        }
    }

    void GameOver()
    {
        Debug.Log("Game OVer");
    }
}

Die, Restart, GameOver 함수를 추가해준다.

적 만들기


  • sorting layer는 player로
  • Collider 추가
  • Animation 추가
  • 스크립트 추가
public class EnemyConteroller : MonoBehaviour
{
    public float Speed;
    Vector2 vx;

    void Start()
    {
        vx = Vector2.right * Speed;
    }

    private void FixedUpdate()
    {
       // GetComponent<Rigidbody2D>().MovePosition
        transform.Translate(vx*Time.fixedDeltaTime);
    }
}

transform.Translate(vx*Time.fixedDeltaTime);
이 방법은 추천하진 않지만 이런 방법이 있다.

❓ 이유는

  • 순간이동하는 방식이라 속도가 빠르고 콜라이더가 얇으면 뚫을수도 있음
  • rigd로 사용하면 천천히 이동

벽과 절벽등을 감지하는 collider를 만들어줌

Front : 앞에 벽이 있는지

Front Bottom : 땅을 밟고 있는지

void Update()
{
	    if(FrontCollider.IsTouching(TerrainCollider) || !FrontBottomCollider.IsTouching(TerrainCollider)) //벽이 있거나 || (절벽이 있는 경우) 바닥이 없는 경우
    {
        vx = -vx; //좌우반전
       transform.localScale = new Vector2(-transform.localScale.x, 1);

    }
}

좌우반전

        transform.localScale = new Vector2(-transform.localScale.x, 1);

적과 부딪히면 죽도록

    private void OnCollisionEnter2D(Collision2D collision)
    {
        if(collision.gameObject.tag == "Enemy")
        {
            Die();
        }
    }

    void Die()
    {
        GameManager.Instance.Die();
    }
using UnityEngine;

public class PlayerController : MonoBehaviour
{
    enum State{
        Playing,
        Dead
    }

//생략
  
    Vector2 originalPosition;
    State state;

    void Start()
    {
        originalPosition = transform.position;
        State state = State.Playing;
    }

    public void Restart()
    {
        //원상복구
        GetComponent<Rigidbody2D>().constraints = RigidbodyConstraints2D.FreezeRotation; 
        GetComponent<Rigidbody2D>().angularVelocity = 0; 
        GetComponent<BoxCollider2D>().enabled = true;

        transform.position = originalPosition;
        GetComponent<Rigidbody2D>().linearVelocity = Vector2.zero;//떨어지고 있을때의 속도 초기화
        state = State.Playing;
    }

   //생략
   
    private void OnCollisionEnter2D(Collision2D collision)
    {
        if(collision.gameObject.tag == "Enemy")
        {
            Die();
        }
    }

    void Die()
    {
        state = State.Dead;
        GetComponent<Rigidbody2D>().constraints = RigidbodyConstraints2D.None; //Freeze OFF
        GetComponent<Rigidbody2D>().angularDamping = 720; //빙글빙글
        GetComponent<Rigidbody2D>().AddForce(new Vector2(0, 10), ForceMode2D.Impulse);//한번에 힘을 주기
        GetComponent<BoxCollider2D>().enabled = false;

        GameManager.Instance.Die();
    }
}

Rigidbody2D컴포넌트에서 여러 설정을 수정해서


▲ 이런식으로 죽게 만들기

enum State{
    Playing,
    Dead
}

현재 상태를 나타내는 State를 만들어주고,

State state;

void Start()
{
    originalPosition = transform.position;
    State state = State.Playing;
}

처음에는 Playing으로 초기화,

    void Die()
    {
        state = State.Dead;
        GetComponent<Rigidbody2D>().constraints = RigidbodyConstraints2D.None; //Freeze OFF
        GetComponent<Rigidbody2D>().angularDamping = 720; //빙글빙글
        GetComponent<Rigidbody2D>().AddForce(new Vector2(0, 10), ForceMode2D.Impulse);//한번에 힘을 주기
        GetComponent<BoxCollider2D>().enabled = false;

        GameManager.Instance.Die();
    }

죽었을때는 Dead로 설정해주고, 캐릭터가 움직이지 못하고 떨어지는 효과를 주기 위해

Rigdbody의 여러 상태들을 바꿔준다.

    public void Restart()
    {
        //원상복구
        GetComponent<Rigidbody2D>().constraints = RigidbodyConstraints2D.FreezeRotation; 
        GetComponent<Rigidbody2D>().angularVelocity = 0; 
        GetComponent<BoxCollider2D>().enabled = true;

        transform.position = originalPosition;
        GetComponent<Rigidbody2D>().linearVelocity = Vector2.zero;//떨어지고 있을때의 속도 초기화
        state = State.Playing;
    }

Restart(재시작)이 될 경우에는 원상복구를 해준다.

게임 오버 팝업창을 만들어준다.

Sliced는 안 깨지고 크기가 늘어나게

0개의 댓글

관련 채용 정보