본문 바로가기

유니티

[유니티] 진행이 불가능 할 때 방향을 스스로 바꾸는 오브젝트 만들기

먼저 한 방향으로 움직이는 오브젝트를 만들어준다.

게임이 시작하자마자 오른쪽으로 간다.

    Vector3 MoveV;
    int vec;  //이동 방향을 저장한 변수
    int speed;
    private void Awake()
    {
        speed = 1;
        vec = 1;            
    }
    void Update()
    {
        MoveV = new Vector3(vec, 0, 0);
        transform.position += MoveV * Time.deltaTime  * speed;
        Vector2 front = new Vector2(transform.position.x + vec*0.5f, transform.position.y);
    }

여기서 토끼의 진행방향에 Laycast를 생성해준 후, 그 Laycast가 border태그를 가진 오브젝트를 만나면 진행방향을 바꿔준다.

DrawLay기능을 이용해서 laycast가 생성되는 위치를 씬에서 확인할 수 있다.

씬뷰에서 확인한 lay가 그려지는 모습

 Vector2 front = new Vector2(transform.position.x + vec*0.5f, transform.position.y);
        Debug.DrawRay(front, Vector3.down, new Color(0, 1, 0));

Update문에 이와같이 내가 레이를 생성하고 싶은 위치를 넣고, 확인후 적당한 위치를 정한다.

 

   private void Awake()
    {
        speed = 1;
        vec = 1;  
    }
    void Update()
    {
        MoveV = new Vector3(vec, 0, 0);
        transform.position += MoveV * Time.deltaTime  * speed;
        Vector2 front = new Vector2(transform.position.x + vec*0.5f, transform.position.y);
        Debug.DrawRay(front, Vector3.down, new Color(0, 1, 0));    
        RaycastHit2D rayHitborder = Physics2D.Raycast(front, Vector3.down, 1,
        LayerMask.GetMask("border"));//태그가 border인 오브젝트와 hit한다면 null이외를 반환하므로
        if (rayHitborder.collider != null)
        {
            turn(); //방향을 바꿔주는 함수를 호출
        }
    }
     void turn()
    {
        vec *= -1;//방향을 바꿔준다.
        transform.localScale = new Vector2(transform.localScale.x * -1, transform.localScale.y);
        //진행 방향에 맞게 오브젝트도 좌우 반전
    }

*결과를 보기 위해 speed 의 값을 10으로 했다.

위와 같이 토끼는 벽에 닫지 않았지만, raycast가 border를 반환하는 점에서 토끼의 방향이 바뀌는 모습을 볼 수 있다.

raycast를 활용하면 위와같이 진행방향에 벽이 있는 상황 뿐 아니라 , 바닥이 비어있는 부분에서도 방향을 바꾸게 할 수 있다.

   Vector3 MoveV;
    int vec;  
    int speed;
    private void Awake()
    {
        speed = 5;
        vec = 1;
    }
    void Update()
    {
        MoveV = new Vector3(vec, 0, 0);
        transform.position += MoveV * Time.deltaTime  * speed;
        Vector2 front = new Vector2(transform.position.x + vec*0.5f, transform.position.y);
        Debug.DrawRay(front, Vector3.down, new Color(0, 1, 0));
        
        RaycastHit2D rayHitblock = Physics2D.Raycast(front, Vector3.down, 1, LayerMask.GetMask("block"));
        //블럭이 잇는지 확인
        RaycastHit2D rayHitborder = Physics2D.Raycast(front, Vector3.down, 1, LayerMask.GetMask("border"));
        
        if (rayHitborder.collider != null)
        {
            turn();
        }
        else //앞에 벽은 없지만, 바닥도 없을 경우에도 turn함수를 호출함
        if (rayHitblock.collider == null)
        {
            turn();
        }
    }
        void turn()
    {
        vec *= -1;
        transform.localScale = new Vector2(transform.localScale.x * -1, transform.localScale.y);
    }

위와 같이 가고싶은 길에 바닥이 없거나, 벽이 있으면 스스로 방향을 바꾸는 코드였다.