오늘의 학습 키워드

Async와 Coroutine

 

공부한 내용

Async와 Coroutine

프로젝트를 진행하면서

캐릭터가 오브젝트에 부딪혔을 때

1. 캐릭터의 조작을 멈추고

2. 일정 시간이 지나고 난 후 풀어주는 로직을 짜기로 했다.

3. 이 때 캐릭터에 다시 충돌이 들어오면 경과 시간을 초기화해주는 조건이 필요했다.

4. 이를 기다리는데 다른 로직이 방해받지 않고 기다렸으면 좋겠다고 생각하고 정보들을 찾아보기로 했다.

 

찾아보니 Unite Copenhagen에서 진행한 자료가 있어서 참고해봤다.

대충 이런 차이점이 있는데 내 경우에서는 MonoBehaviour를 상속받지 않으므로 Async를 사용하기로 했다.

 

다음은 Async를 적용하여 MonoBehaviour를 상속받는 Obstacle 클래스에서 OnCollisionEnter 이벤트가 호출되면 조건을 체크하여 ObstacleCollision의 ApplyCollision을 호출하고 물리적 힘을 준 뒤 캐릭터가 이미 충돌 상태인지 확인하고 처리해주는 것을 구현한 로직이다.

public class Obstacle : MonoBehaviour, IPoolingObject<Obstacle>
{
    private void OnCollisionEnter(Collision collision)
    {
        if (collision.collider.TryGetComponent(out CharacterController controller))
        {
            _obstacleCollision.ApplyCollision(controller, collision.rigidbody, -collision.GetContact(0).normal, mass, waitMilliseconds);
        }
    }
}
public class ObstacleCollision
{
    public async void ApplyCollision(CharacterController controller, Rigidbody oppositeRigid, Vector3 towardTargetVec, float mass, int waitMilliseconds)
    {
        oppositeRigid.AddForce(towardTargetVec * mass, ForceMode.Impulse);

        controller.SetImmovable();

        await Task.Delay(waitMilliseconds);

        controller.SetMovable();
    }
}
public class CharacterController : MonoBehaviour
{
    public void SetMovable()
    {
        if (_collisionStack > 0)
        {
            _collisionStack--;

            if (_collisionStack == 0)
                _canMove = true;
        }
    }

    public void SetImmovable()
    {
        _collisionStack++;

        if (_collisionStack == 1)
            _canMove = false;
    }
}

 

 

오늘의 회고

 오늘은 코루틴과 비동기의 차이점에 대해서 배웠다. 코루틴은 유니티에서 MonoBehaviour를 상속 받을 때 싱글 쓰레드로 동작하는 것이고 Async는 멀티 쓰레드로 웹에 요청을 보내거나 파일 입출력을 할 때 많이 쓰인다는 것을 배우게 되었다.

 내일은 게임의 결과를 보여주는 창과 SFX 관리를 할 생각이다. 내일도 열심히 하자 파이팅!

 

 

참고 : 

https://www.youtube.com/watch?v=7eKi6NKri6I

 

+ Recent posts