ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Unity 2D Ghost Trail Effect 제작
    쾌락없는 책임 (공부)/Unity 2021. 5. 2. 15:02
    반응형

    서론

     게임을 제작하면서 '대쉬를 했을 때 흔적이 남는 효과를 넣고 싶다' 라고 생각했는데 막상에 구글에 검색을 해보려고 하니 어떤 단어로 검색해야 할지 몰라 한동안 놓고 있던 기능이었다. 찾아보니 영어로 Chost Trail Effect, Trail Renderer정도로 검색하니 관련 자료들이 잘 나왔고 한글로는 유니티 잔상 이라고 치니 자료들이 좀 나왔다.

    소스코드

    using UnityEngine;
    using DG.Tweening;
    
    public class GhostTrailEffect : MonoBehaviour{
        PlayerMovement playerMovement;
        SpriteRenderer sprite;
        PlayerAnimation anim;
        public Transform ghostsParent;
        public Color trailColor;
        public Color fadeColor;
        public float trailInterval;
        public float fadeTime;
        void Start(){
            sprite = GetComponent<SpriteRenderer>();
            playerMovement = FindObjectOfType<PlayerMovement>();
            anim = FindObjectOfType<PlayerAnimation>();
        }
    
        public void ShowGhost() {
            Sequence s = DOTween.Sequence();
            /*  DOTween
                Append : 애미메이션 바로 실행
                AppendCallback : 기다린 후 콜백호출
                AppendInterval : 시간 기다림
            */
            for (int i = 0; i < ghostsParent.childCount; i++){
                Transform currentGhost = ghostsParent.GetChild(i);
                s.AppendCallback(()=> currentGhost.position = playerMovement.transform.position);
                s.AppendCallback(() => currentGhost.GetComponent<SpriteRenderer>().flipX = anim.spriteRenderer.flipX);
                s.AppendCallback(()=>currentGhost.GetComponent<SpriteRenderer>().sprite = anim.spriteRenderer.sprite);
                s.Append(currentGhost.GetComponent<SpriteRenderer>().material.DOColor(trailColor, 0));
                s.AppendCallback(() => FadeSprite(currentGhost));
                s.AppendInterval(trailInterval);
            }
        }
        // 효과 페이드 아웃
        public void FadeSprite(Transform current){
            current.GetComponent<SpriteRenderer>().material.DOKill();
            current.GetComponent<SpriteRenderer>().material.DOColor(fadeColor, fadeTime);
        }
    
        
    }
    

     이번 새로 산 DOTween을 이용해서 쓸 수 는 없을까 고민을 했고 다행히 외국 자료에서 찾을 수 있었다. 필드에 빈 오브젝트인 Ghost를 두고 자식을 총 3개를 둬 자식 수만큼 잔상이 나오게끔 했다. ShowGhost의 경우 public으로 둬서 대쉬할 때마다 호출하는 형식으로 했다.

     

     잔상 효과를 보여주는 로직은

     1. 함수가 불리면 첫 자식부터 마지막 자식까지 돌아가면서 for문

     2. 현재 잔상의 위치를 플레이어 위치로 동기화, 잔상의 spriterenderer의 flip여부도 플레이어의 flip과 동일하게

     3. 고스트의 스프라이트는 현재 없으며 플레이어는 애니메이션으로 스프라이트 제어 중이니

        '함수가 불리는 시점의 플레이어 스프라이트 = 고스트의 스프라이트'를 줘서 잔상이 플레이어의 스프라이트를 따르게 합니다.

      4. 잔상은 Fade를 통해 없어지게 하며 이후 다음 자식을 불러 잔상 추가 (시간 간격은 trailInterval)

     

    개선점

    처음 Find를 통해서 playermovement, playeranimaion 스크립트를 2개 불러오는데 이게 상당히 비효율적이라고 생각을 했다. 또한 ShowGhost를 호출할 때도 Find를 사용하고 있기 때문에 이점은 개선의 여지가 있다!


    참고자료

     

    mixandjam/Celeste-Movement

    Recreating the movement and feel from Celeste. Contribute to mixandjam/Celeste-Movement development by creating an account on GitHub.

    github.com

     

    반응형

    댓글

Designed by Tistory.