Project/AR Project

Claw machine game

Red_Horse 2022. 2. 18. 00:46

AR Project ('22.02.19 ~ '22.02.21.)

 

Claw machine app 개발

 

제작 순서

  - 뽑기 발판 기능 제작

  - 뽑기 밀판 기능 제작

  - 인형 추가

  - 기능 오브젝트 → 프로젝트 오브젝트 변경

  - 뽑기 애니메이션 연결

  - 인형뽑기 이벤트 추가 

 

  뽑기 발판 기능 제작

인형뽑기 발판
public class Plane_rotate_auto : MonoBehaviour
{
    float speed = 40f;

    private void Start()
    {
        gameObject.SetActive(true);
    }

    private void Update()
    {
        gameObject.transform.Rotate(0, -this.speed * Time.deltaTime, 0);
    }
}

발판이 되는 게임 오브젝트에 스크립트를 넣어 놓고 게임 실행시에 자동으로 회전을 하게 한다.

-this.Speed * Time.deltaTime

   - Y축 회전 및 시계방향으로 회전시키기 위해 현재 오브젝트의 - 속도로 회전

 

하위 오브젝트 Transform 영향 문제

플레이중 바닥오브젝트의 하위로 인형을 올려놓았을 경우 이상없이 회전을 실행하지만 플레이 전에 넣어서 실행할 경우

인형 오브젝트 크기 속성이 부모 오브젝트로부터 영향을 받는 문제점이 식별되었다. 식별된 문제로는 인형이 찹쌀떡처럼 쭉 늘어지는 현상... 또 영상에서는 표현이 되지 않았지만 파란색 오브젝트 위로 떨어뜨렸을때에는 치즈가 늘어나듯이 스케일 값이 변화되는 모습이 식별되었다.

 

private void OnTriggerEnter(Collider other)
    {
        other.transform.parent = gameObject.transform;
    }

이전 문제를 해결하기 위해 mesh를 가지고 있지 않은 빈오브젝트를 생성하고 그 하위에 인형과 발판이 위치하여 돌아가는 방식으로 해결하였다. 또 빈오브젝트에 Collider을 생성하여 해당 위치에 떨어지는 오브젝트는 하위 오브젝트로 들어가는 코드를 기존 회전 코드에 추가해주었다. (하위 오브젝트로 들어가있어야 인형이 발판과 함께 회전)

 

  뽑기 밀판 기능 제작

public class Push_bar : MonoBehaviour
{
    Vector3 origin_position;
    bool push;
    bool push_back;
    float speed = 4f;

void Start()
    {
        origin_position = gameObject.transform.position;
        push = false;
        push_back = false;
    }

    void Update()
    {
        if (Input.GetMouseButtonDown(0))
            push = true;

        if(push)
        {
            if(gameObject.transform.position.x < 11f)
                gameObject.transform.position += new Vector3(speed * Time.deltaTime, 0, 0);
            else
            {
                push_back = true;
                push = false;
            }
        }
        if(push_back)
        {
            if (gameObject.transform.position.x > 0f)
                gameObject.transform.position -= new Vector3(speed * Time.deltaTime, 0, 0);
            else
            {
                gameObject.transform.position = origin_position;
                push_back = false;
            }
        }
            
    }
}

발판으로부터 올라온 인형들이 뽑히기 위해 파란색 오브젝트에 위치하고 보라색 오브젝트가 인형들을 앞으로 밀어주어 뽑을 수 있게 구현하였다. 현재는 테스트를 위해 마우스 클릭시 실행으로 조건을 주었고 이후 Invoke로 변경하여 일정 시간간격으로 실행되게 변경할 예정이다.

 * 축과 최대 길이가 정해져 있다보니 전체 오브젝트의 방향이 바뀌었을시 밀대가 기대하지 않았던 방향으로 움직이는 문제점이 식별되었다. 고정이 된다하면 지금처럼 고정수치로 두고 사용을 하면 되지만 이후 수정시에 일일이 밀대가 움직이는 수치를 확인하고 변경해주어야하는 문제점이 있다. 이를 해결하기 위해서는 빈오브젝트로 위치를 고장하여 묶고 위치값만을 가지고 있는 오브젝트를 생성해 해당 위치로 움직이는 방식으로 수정을 할 필요성이 있다.

 

  ☆ 문제 현상

Push Bar 문제 현상

 문제점 수정

 

Push Bar 문제현상 수정
 IEnumerator Push_bool()
    {
        yield return new WaitForSeconds(2.5f);
        push_back = true;
        push = false;
    }

    IEnumerator Back_push_bool()
    {
        yield return new WaitForSeconds(2.5f);
        push = true;
        push_back = false;
    }
    void Update()
    {
        if (push)
        {
            gameObject.transform.position += move_position.transform.forward * Time.deltaTime * this.speed;
            StartCoroutine(Push_bool());
        }

        else if (push_back)
        {
            gameObject.transform.position -= move_position.transform.forward * Time.deltaTime * this.speed;
            StartCoroutine(Back_push_bool());
        }
    }

 ※ 일정 시간동안 지정된 위치에 있는 오브젝트가 바라보는 방향으로 이동을 하는 코드로 변경함으로서 이전 문제 현상을 해결하였다.

 

이후 인형을 잡아서 올렸을 때 인형 오브젝트의 부모 오브젝트가 계속 회전을 하고 있어서 다른 곳에 충돌을 하고 있지만 기존 회전이 멈추지 않고 계속 진행되어 뽑기발판에서 벗어나 다시 떨어지는 문제점이 식별되었다.

 

public class Release_Parent : MonoBehaviour
{
    private void OnTriggerEnter(Collider other)
    {
        other.transform.parent = null;
    }
}

이전 문제를 해결하기 위해 뽑기 발판에 닿은 물체의 부모오브젝트를 해제하는 스크립트를 추가하는 것으로 해결하였다.

 

  뽑기 애니메이션 연결

public class play_animation : MonoBehaviour
{
    public Animator claw;
    bool duplicate;
    float speed = 4f;

    void Start()
    {
        claw.Play("Base Layer.Armature|Stay", 0, 0.25f);
        duplicate = true;
    }

    void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            if (duplicate)
                StartCoroutine(Duplicate_timer());
        }
    }

    IEnumerator Duplicate_timer()
    {
        duplicate = false;
        claw.Play("Base Layer.Armature|action", 0, 0.25f);
        yield return new WaitForSeconds(5.0f);
        duplicate = true;
    }
}

마우스 클릭시(디바이스 터치인식시) 애니메이션이 실행되며 일정 시간동안 애니메이션이 다시 실행되는 것을 방지하기 위해서 코루틴을 활용하여 뽑기 애니메이션 중복실행을 방지한다.

 

또한 집게발에는 충돌한 오브젝트의 현 부모오브젝트에서 해제되는 스크립트가 추가되었다.

(발판 회전에서 벗어나기 위함)

 

  인형뽑기 이벤트 추가 

Event Coillder

public class doll_trigger_count : MonoBehaviour
{
    public GameObject Robot;
    public GameObject Rosie;
    private int count = 0;
    private void OnTriggerEnter(Collider other)
    {
        if (other.gameObject.name == "ROBOT_03" || other.gameObject.name == "Rosie_fixfix")
        {
            Robot.SetActive(true);
            Rosie.SetActive(true);
            StartCoroutine(off_setting());
        }
    }

    IEnumerator off_setting()
    {
        yield return new WaitForSeconds(5.0f);
        Robot.SetActive(false);
        Rosie.SetActive(false);
    }
}

Event coillder에 특정 오브젝트가 충돌을 하였을 경우 미리 세팅을 해놓은 오브젝트들이 활성화 된다.

(일정시간 이후 오브젝트 비활성화)

 

public class Newt_animation : MonoBehaviour
{
    public Animator newt;
    
    private void OnEnable()
    {
        gameObject.SetActive(true);
        newt.Play("Base Layer.Newt_hug", 0, 0.25f);
    }
}

 

해당 오브젝트들은 Animator를 가지고 있으며 오브젝트 활성화시 지정된 애니메이션이 실행된다.

 

프로젝트 결과물

프로젝트 결과 모델