유니티 2d 아이템 드랍 효과 만들어보기 Item drop effect

2023. 3. 23. 23:30유니티실습

반응형
728x170

키입력을 받아 코인을 생성하여 랜덤 한 방향으로 뿌리는 간단한 예제입니다.

 ※ 유니티 버전은 2021.3.19f1 에서 진행하였습니다.

결과화면

Coin 프리팹 구조

 

코인 오브젝트 구조는 부모 오브젝트인 [Coin]

자식 오브젝트인 [Sprite], [Shadow]로 이루어져있습니다.

[Coin] 오브젝트에는 Coin 아래의 coin스크립트를 할당하고

[Sprite] , [Shadow] 오브젝트에는 Sprite Render와 Animaotr 컴포넌트를 할당합니다.

※ Shadow 오브젝트는 Color를 검게 변경해주시고 Layer를 -1변경합니다.

※ Animator는 굳이 포함하지 않으셔도 관계없습니다.

할당을 마친 후에는 코인 오브젝트를 프로젝트에 드래그하여 프리팹화 시켜주고

이후에 Spawn 스크립트에 프리팹을 등록해 줍니다.

 

Spawn 스크립트 예제

public class Spawn : MonoBehaviour
{
    public int spawnCont;
    public GameObject coin;
    
    void Update() {
        if(Input.GetKeyDown(KeyCode.Space)) {
            for (int i = 0; i < spawnCont; i++) {
                Instantiate(coin);
            }
        }
    }
}

 

Spawn 예제는 Space입력을 받을 시 등록 되어있는 프리팹을 Count 만큼 생성합니다.

 

Coin 스크립트 예제

public class Coin : MonoBehaviour {

    public int maxBounce;	// 팅기는 횟수

    public float xForce;	// x축 힘 (더 멀리)
    public float yForce;	// Y축 힘 (더 높이)
    public float gravity;	// 중력 (떨어지는 속도 제어)

    private Vector2 direction;
    private int currentBounce = 0;
    private bool isGrounded = true;

    private float maxHeight;
    private float currentheight;

    public Transform sprite;
    public Transform shadow;

    void Start() {
        currentheight = Random.Range(yForce - 1, yForce);
        maxHeight = currentheight;
        Initialize(new Vector2(Random.Range(-xForce, xForce), Random.Range(-xForce, xForce)));
    }

    void Update() {

        if (!isGrounded) {

            currentheight += -gravity * Time.deltaTime;
            sprite.position += new Vector3(0, currentheight, 0) * Time.deltaTime;
            transform.position += (Vector3)direction * Time.deltaTime;

            float totalVelocity = Mathf.Abs(currentheight) + Mathf.Abs(maxHeight);
            float scaleXY = Mathf.Abs(currentheight) / totalVelocity;
            shadow.localScale = Vector2.one * Mathf.Clamp(scaleXY, 0.5f, 1.0f);

            CheckGroundHit();
        }
    }

    void Initialize(Vector2 _direction) {
        isGrounded = false;
        maxHeight /= 1.5f;
        direction = _direction;
        currentheight = maxHeight;
        currentBounce++;
    }

    void CheckGroundHit() {
        if (sprite.position.y < shadow.position.y) {
            sprite.position = shadow.position;
            shadow.localScale = Vector2.one;

            if (currentBounce < maxBounce) {
                Initialize(direction / 1.5f);
            } else {
                isGrounded = true;
            }
        }
    }
}

 

(1) 오브젝트가 특정한 방향으로 포물선을 그린다.

[Coin] 부모 오브젝트를 Random.Range 만큼 X축으로 이동

transform.position += (Vector3) direction * Time.deltaTime;

[Sprite] 자식 오브젝트에서 Y축을 상승시키고 Grvity 만큼 감소시키면

sprite.position += new Vector3(0, currentheight, 0) * Time.deltaTime;

currentheight += -gravity * Time.deltaTime;

코인이 랜덤한 방향으로 포물선을 그리는 모습을 확인할 수 있습니다.

 

※ 한 오브젝트에서 XY축을 움직이는것이 아니라 부모 오브젝트 X축을 제어, 자식 오브젝트의 Y축을 제어하는게 포인트

(2) 추락을 멈추고 다시 포물선을 (이전 보다 낮게 상승한다) 그린다.

[Sprite] 자식 오브젝트가 점차 추락하여 기존에 멈추어있던

[Shadow] 자식 오브젝트의 위치보다 낮아질 경우 

if (sprite.position.y < shadow.position.y)

current Bounce를 증가시키고 xForce, yForce축의 수치를 1.5 나눈만큼 감소시킨채

(1) 작업을 (포물선 그리기) 반복합니다.

Initialize(direction / 1.5f);

maxHeight /= 1.5f;

 

※ Shadow 오브젝트를 땅이라 생각하고 Sprite 오브젝트와 위치 비교를 트리거로 건 부분이 포인트

(3) Bounce 초과 시 정지

currentBounce의 수치가 maxBounce 를 넘어서게 되면 오브젝트는 바운스를 멈추고 정지합니다.

if (currentBounce < maxBounce) {
                Initialize(direction / 1.5f);
            } else {
                isGrounded = true;
            }

 

 

}

 

부족한 예제와 설명이였지만 많은 도움이 되셨으면 좋겠습니다.

감사합니다.

반응형
그리드형