구현한 것들

원의 방정식을 사용한 카드 세팅 연출

작은 원을 기준으로 현재 위치에서 원과 만나는 y좌표를 찾아 직선으로 움직이는 것이 아닌 원을 따라 곡선으로 움직이게 만들어준다.

IEnumerator CoMoveOffsetPosition(Transform cardTrans, Vector3 destination)
    {
        Vector3 offsetPos = cardTrans.position;
        Vector3 targetPos = Vector3.zero;
        float ratio = 0f;
        while (ratio < cardSettingTime)
        {
            ratio += Time.deltaTime;
            targetPos = Vector3.Lerp(offsetPos, destination, ratio / cardSettingTime);

            // 원의 방정식 (x-a)^2 + (y-b)^2 = r^2
            float halfRadius = radius * 0.5f;
            // 반지름의 제곱
            float powRadius = Mathf.Pow(halfRadius, 2);
            // 현재 x위치가 목표의 왼쪽인지 오른쪽인지
            bool isDestinationXLow = targetPos.x > destination.x;
            // 오른쪽이라면 반지름 빼주기 왼쪽이라면 반지름 더해주기 (원의 센터 x좌표가 반지름만큼 차이나니까)
            float powXPos = isDestinationXLow ? Mathf.Pow(targetPos.x - destination.x - halfRadius, 2) 
                : Mathf.Pow(targetPos.x - destination.x + halfRadius, 2);
            // y좌표
            float yPos = Mathf.Sqrt(Mathf.Abs(powRadius - powXPos));

            // 현재 위치에서 목표지점까지의 선분(원의 지름) 위의 점 + 원 중심으로부터 y좌표
            targetPos.y += yPos;
            cardTrans.position = targetPos;

            yield return null;
        }
    }

카드 뒤집기 연출

카드가 뒤집어지는 연출을 구현하였다.

앞면과 뒷면을 나누어 y축을 0~90도까지 회전 90~0도까지 회전하는 방식을 사용하였다.

IEnumerator CoFlip()
    {
        // 애니메이션 꺼주기 -> rotate 애니메이션 끄기
        anim.SetBool("isOpen", true);

        // 뒷면의 y축 회전을 0 ~ 90까지 증가
        float ratio = 0f;
        Vector3 backRotation = backTransform.rotation.eulerAngles;
        while (ratio < flipRotation)
        {
            ratio += Time.deltaTime * flipSpeed;
            backRotation.y = ratio;
            backTransform.rotation = Quaternion.Euler(backRotation);
            yield return null;
        }

        // 뒷면 -> 앞면 스위치
        frontTransform.gameObject.SetActive(true);
        backTransform.gameObject.SetActive(false);

        // 앞면의 y축 회전을 90 ~ 0까지 감소
        Vector3 frontRotation = frontTransform.rotation.eulerAngles;
        while (ratio > 0)
        {
            ratio -= Time.deltaTime * flipSpeed;
            frontRotation.y = ratio;
            frontTransform.rotation = Quaternion.Euler(frontRotation);
            yield return null;
        }

    }
IEnumerator CoReverseFlip()
    {
        float ratio = 0f;

        // 앞면의 y축 회전을 0 ~ 90까지 증가
        Vector3 frontRotation = frontTransform.rotation.eulerAngles;
        while (ratio < flipRotation)
        {
            ratio += Time.deltaTime * flipSpeed;
            frontRotation.y = ratio;
            frontTransform.rotation = Quaternion.Euler(frontRotation);
            yield return null;
        }

        // 앞면 -> 뒷면 스위치
        frontTransform.gameObject.SetActive(false);
        backTransform.gameObject.SetActive(true);

        // 뒷면의 y축 회전을 90 ~ 0까지 감소
        Vector3 backRotation = backTransform.rotation.eulerAngles;
        while (ratio > 0)
        {
            ratio -= Time.deltaTime * flipSpeed;
            backRotation.y = ratio;
            backTransform.rotation = Quaternion.Euler(backRotation);
            yield return null;
        }

        // 애니메이션 켜주기 -> rotate 애니메이션 키기
        anim.SetBool("isOpen", false);
    }

터치 이펙트 구현

간단한 파티클과 풀링으로 터치 이펙트를 구현하였다.

입력 감지

void Update()
    {
#if UNITY_ANDROID
        if (Input.touchCount > 0)
        {
            touch = Input.GetTouch(0);
            if (touch.phase == TouchPhase.Began)
            {
                GameObject particle = touchPool.GetObject();
                particle.transform.position = mainCam.ScreenToWorldPoint(touch.position);
            }
        }
#endif
#if UNITY_STANDALONE
        if (Input.GetMouseButtonDown(0))
        {
            ParticleSystem particle = touchPool.GetObject();
            Vector3 mousePos = mainCam.ScreenToWorldPoint(Input.mousePosition);
            mousePos.z = 0;
            particle.transform.position = mousePos;
        }
#endif

    }

스택으로 간단한 풀링 구현

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

public class TouchPool
{
    ParticleSystem touchParticle;
    Stack<ParticleSystem> particlePool = new Stack<ParticleSystem>();

    Transform parentTrans;

    public TouchPool(ParticleSystem particle, Transform trans)
    {
        touchParticle = particle;
        parentTrans = trans;
    }

    public ParticleSystem GetObject()
    {
        ParticleSystem particle = null;

        if (particlePool.Count > 0)
        {
            particle = particlePool.Pop();
            particle.gameObject.SetActive(true);
        }
        else
        {
            particle = CreateNewObject();
            particlePool.Push(particle);
        }

        return particle;
    }

    void ReturnObject(ParticleSystem particle)
    {
        particle.gameObject.SetActive(false);
        particlePool.Push(particle);
    }

    ParticleSystem CreateNewObject()
    {
        ParticleSystem particle = Object.Instantiate(touchParticle, parentTrans);
        particle.GetComponent<TouchParticle>().SetReturnCallback(ReturnObject);
        return particle;
    }
}

 

중간 점검

오늘 개발한 것들을 포함한 플레이 영상이다.

 

 

참고 :

https://youtu.be/Xo7EEegTUfE

 

'스파르타 Unity 1기' 카테고리의 다른 글

스파르타 Unity 8기 4일차 TIL  (0) 2023.08.10
스파르타 Unity 8기 3일차 TIL  (0) 2023.08.09
스파르타 Unity 8기 1일차 TIL  (1) 2023.08.07
사전캠프 4일차  (0) 2023.08.04
사전캠프 3일차  (0) 2023.08.03

+ Recent posts