TIL(Today I Learn)

[모각코][Unity/유니티]0814 TIL_애니메이션 구현, 맵 탐색 기능 추가

어둠의 그림자 2021. 8. 16. 03:09

이번회차에는 1) 애니메이션2)맵에 있는 스프라이트들(울타리, 나무, 등등)을 조사할수 있는 기능 3) 대화창에 맵 조사기능 출력하기 를 구현해보았다.

 

+직접 디자인하거나 혹은 마음에드는 스프라이트로 구현하려고 애니메이션 설정을 미뤄두고있었는데, 추후 기능추가에 있어서 애로사항이 생길것같아 미리 설정해두려고 한다.

 

+ 이전시간에 플레이어 이동스크립트를 수정하다가, physics 2d 기능을 추가했는데 중력도 고려가 되서 계속 아래로 천천히 떨어졌다..플랫포머 게임과 시점이 다르다보니까 이런부분에서 오류가 생겼었는데 gravity scale 값을 0으로 바꿔주면된다!

기본값이 1로 저장이 되있는데 이러면 아래로 천천히 떨어진다..

++box collider가 갑자기 안먹혀서 계속 수정을 하다가 원인을 찾았는데

isTrigger 속성에 체크가 되어있으면 collider기능을 하지못한다!

isTrigger는 보통 코드상 플레이어가 액션을 취했을때 물체를 통과하고싶다!할때 if문으로 설정해주는 편인데, 실수로 체크해놔서 collider 기능이 먹히지않았었다..

1)애니메이션 설정_Player

horizontal, vertical 키를 이용해  4가지 방향과 걷기 기능을 구현해야하므로 총 8개의 애니메이션을 만들었다

애니메이터

그다음 animation간의 transition을 만들어주었다. 이 과정에서 시간이 꽤 많이 걸렸는데 다시 한번 살펴보니 애니메이션을 잘못넣거나, parameter값을 잘못설정해주어서 생긴 문제들이였다.

parameter로는 vAxisRaw와 hAxisRaw 값으로 키 input값을 이용해주기 위해 int값으로 설정하였고

isChange는 transition을 여러번 사용하면 애니메이션이 실행되지않으므로 bool값으로 설정해주었다.

이런식으로 애니메이션창과 game창을 동시에 띄워놓고, 1) 애니메이션 작동안하는부분 세부적으로 체크 2) transition parameter 설정 체크 3)애니메이션 수정 과정으로 수정하였다.

+디자인은 골드메탈 에셋을 사용했는데 추후에 변경할예정이다

//player.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Player : MonoBehaviour
{
    public float Speed;
    float h;
    float v;
    Rigidbody2D rigid;
    Animator anim;
    bool isHorizonMove;
    // Start is called before the first frame update
    void Start()
    {
        rigid = GetComponent<Rigidbody2D>();
        anim = GetComponent<Animator>();
    }

    // Update is called once per frame
    void Update()
    {
        h = Input.GetAxisRaw("Horizontal");
        v = Input.GetAxisRaw("Vertical");
        
        bool hDown = Input.GetButtonDown("Horizontal");
        bool vDown = Input.GetButtonDown("Vertical");
        bool hUp = Input.GetButtonUp("Horizontal");
        bool vUp = Input.GetButtonUp("Vertical");

        if(hDown)//
            isHorizonMove = true;
        else if(vDown)
            isHorizonMove = false;
        else if(hUp || vUp )
            isHorizonMove = h != 0;
        //Animation
        if (anim.GetInteger("hAxisRaw") != h){
            anim.SetInteger("hAxisRaw",(int)h);
            anim.SetBool("isChange",true);
        }
        else if (anim.GetInteger("vAxisRaw") != v){
            anim.SetInteger("vAxisRaw",(int)v);
            anim.SetBool("isChange",true);
        }
        else{
            anim.SetBool("isChange",false);
        }
    
    }
    void FixedUpdate(){
        Vector2 moveVec = isHorizonMove ? new Vector2(h,0): new Vector2(0,v);
        rigid.velocity =moveVec*Speed;
    }
}

2. 맵 탐색 기능

스페이스바를 누르면, 맵안에 있는 스프라이트들의 이름을 출력하는 기능을 구현해보았다

Raycast 기능과 layer를 활용했고, scanObject라는 변수를 만들어 rayHit에 닿은 물체들을 저장해주었다.

Scene에 나오는것처럼 초록색 막대기가 raycast다 DrawRay를 해주어서 보인다(Game화면에서는 안보인다)

<추가코드>

if(vDown && v ==1)
            dirVec = Vector3.up;
        else if(vDown && v == -1)
            dirVec = Vector3.down;
        else if(hDown && h == -1)
            dirVec = Vector3.left;
        else if(hDown && h == 1)
            dirVec = Vector3.right;
        //Scan
        if (Input.GetButtonDown("Jump")&& scanObject != null)
            Debug.Log("this is :"+ scanObject.name);
. . .
//FixedUpdate
	//Ray
        Debug.DrawRay(rigid.position, dirVec*0.7f ,new Color(0,1,0));
        RaycastHit2D rayHit = Physics2D.Raycast(rigid.position,dirVec,0.7f,LayerMask.GetMask("Object"));
        if(rayHit.collider){
            scanObject = rayHit.collider.gameObject;
        }
        else
            scanObject = null;

3. 대화창에 출력_조사기능

저번시간에 구현해본 대화창기능과 이번시간에 구현한 조사기능을 엮어서 대화창에 조사한 내용을 출력해보겠다

(2번에서는 콘솔에 출력한것을 대화창에 출력하는것이다)

GameManager를 사용해서 public으로 Text를 넣을수있게 해주었다. 그리고 Action이라는 함수의 매개변수로 scanObj를 넣어주었는데 이는 player 스크립트에서 설정해주었다

public GameManager manager으로 GameManager를 넣을수있게해주었고,

manager.Action(scanObject)로 player 스크립트에서 불러와주었다.

+) 

public으로 써주었다면 꼭 이렇게 넣어주어야한다!안그러면 오류 뜬다

또한 조사를 해서 문구가 나올때만 대화창을 표시하기 위해서 talkPanel의(Image까지 포함해서)활성화를 껐다 낄수있게 해주었다 + 플레이어의 움직임도 막아두었다.

+)

이렇게 활성화를 꺼두어야 처음화면에도 안뜬다

<gameManager 스크립트>

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

public class GameManager : MonoBehaviour
{
    public GameObject talkPanel;
    public Text talkText;
    public GameObject scanObject;
    public bool isAction;

    public void Action(GameObject scanObj)
    {
        if(isAction){//Exit Action
            isAction = false;
            
        }
        else{//EnterAction
            isAction = true;
           
            scanObject = scanObj;
            talkText.text = "이건 " + scanObject.name + "입니다";

        }
        talkPanel.SetActive(isAction);
        
    }
}

 

<결과화면>

 

<정리및 회고>

1)애니메이션 구현

전에 했던 플랫포머게임보다 방향이 두가지 더 많기도하고(그때는 flipX로만 관리함) 관리해야할 애니메이션이 많았다. 플랫포머 게임에서는 모든 애니메이션끼리 transition을 다 생성해서 번거로움이 있었는데, 이번에는 any state를 적극 활용해서 transition을 보다 간략하게 관리할수있는 부분이 효율적이였다.

그리고 애니메이션 적용이 안되는걸 고치는데에 시간투자를 많이했는데, 위에 기재한바와 같이

1) 애니메이션 작동안하는부분 세부적으로 체크

2) transition parameter 설정 체크

3)애니메이션 수정

으로 진행하는 습관을 들여야겠다.

 

2,3)조사기능 추가및 텍스트박스 연동

저번 플랫포머게임에서 다른 스크립트끼리 연동하는데에 오류가 적잖아 많이 떠서, 구글링에 시간을 많이 투자했었는데,  public을 통해서 유니티 설정창에서 간편하게 드래그앤 드랍하는 방식을 이용하면 굉장히 간편함을 느꼈다.

 

참고영상)

https://www.youtube.com/watch?v=bZVa6C6vRBQ&list=PLO-mt5Iu5TeYfyXsi6kzHK8kfjPvadC5u&index=2 

 

<다음회차 목표>

- 대화창 애니메이션 구현

- 게임진행 시나리오 구체적설정및 적용