[압량(Amnyang)] #11. 2D 공포 분위기 조성용 이벤트 만들기

2022. 2. 15. 01:42Projects/Amnyang

 

 

 

프로젝트 개발 진행 초기에 디자이너 님께서 구현해보고 싶다는 내용이 있었다. "집 창문에서 사람이 떨어지는 연출을 넣고 싶다."고 하셨었다. 그래서 오늘 그 부분을 이뤄드리려고 구현에 들어갔는데, 아쉽게도 디자이너 님께서 포토샵 작업하실 때 레이어를 덜 나누셨다. 그래서, 사람이 떨어지는 걸 구현할 수가 없었다.

 

그래도, 좀 그럴싸하게 어떻게 공포스런 느낌을 줄 수 없을까 내 자신 나름대로 고민을 해봤다. 빨간 조명이 뜨면서 어떤 남자가 창문에서 서 있는 모습도 괜찮지 않을까란 생각이 들었다. 그래서 우선 구현에 들어가봤다.

 

 

 

1. 색감 탁하게 만들기

 

전역 조명의 세기를 낮춰도, 기본적으로 약간 밝은 톤으로 만들어진 이미지들이었기에 어두운 느낌을 내질 못했다.

그래서, 스프라이트의 Color 프로퍼티를 통해 색감을 탁하게 먼저 만들어줬다.

/*   캡쳐할려니 안 보여서, 전역 조명의 세기를 높인 다음에 캡쳐했습니다.   */

 

색감 변경 전

 

색감 변경 후

 

 

2. 빨간 조명 설치하기

 

창문의 모양에 조명 모양을 설정해주기 위해, Universal RP의 2D LightFreeform 타입을 사용했다.

 

 

빨간 조명이 좀 더 인상에 강하게 남아야 하므로, 전체적인 밝기를 조금 세게 줬다. Light Order후순위로 둠으로써, 캐릭터의 휴대폰 조명에 영향을 덜 받도록 설정해줬다. 그것 외에도 이것저것 옵션을 적용해보면서 그럴듯한 연출을 낼 수 있도록 했다.

 

 

 

 

3. 이벤트용 애니메이션 만들기

 

우선, 오브젝트들을 다음과 같이 배치해줬다.

 

 

그리고, 애니메이터를 만들고 이벤트를 세 가지 정도 만들었다.

 

첫 번째 이벤트

 

두 번째 이벤트

 

세 번째 이벤트

 

그리고 애니메이터 Integer 매개변수("EventNumber")를 두고, 스크립트에서 랜덤으로 배정해줄 계획이다. 각 애니메이션의 Loop Time은 꺼줬고, 트랜지션 조건은 순서대로 매개변수가 1, 2, 3일 때로 줬다.

다시 Idle로 돌아오는 트랜지션 조건은 없다. (애니메이션이 끝나면 돌아오도록 했다.)

 

/*   Idle 애니메이션은 라이트랑 이벤트용 오브젝트들을 비활성화 해 둔 기본 상태다. 이건 Loop Time을 켜줘야 한다.   */

 

 

 

 

4. 스크립트 작성하기

 

주인공 캐릭터 수지의 집이므로, SujiHouse라는 이름으로 스크립트를 하나 생성해줬다. 그리고, 예전 눈 깜빡임 애니메이션에서 다뤘던 Invoke 재귀함수 방식을 다시 사용해줬다.

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

public class SujiHouse : MonoBehaviour
{
    private Animator animator;
    private int eventNumber;
    private const float MIN_DELAYTIME = 5f;
    private const float MAX_DELAYTIME = 10f;


    void Start()
    {
        animator = GetComponent<Animator>();
        animator.SetInteger("EventNumber", 0);
        Invoke("OnEvent", Random.Range(MIN_DELAYTIME, MAX_DELAYTIME));
    }

    private void OnEvent()
    {
        eventNumber = Random.Range(1, 4);
        animator.SetInteger("EventNumber", eventNumber);

        float delayTime = Random.Range(MIN_DELAYTIME, MAX_DELAYTIME);
        Invoke("OnEvent", delayTime);
    }
}

 

이러면, 5초 ~ 10초 주기로 3개 중 하나가 임의로 선택되어 애니메이션이 재생될 것이다. 하지만, 이대로 두면 매개변수를 다시 0으로 셋팅하는 코드가 없기 때문에 다시 해당 매개변수에 해당하는 애니메이션으로 트랜지션이 일어난다. 

 

매개변수를 0으로 셋팅하는 순간은 언제일까? 바로 애니메이션이 끝났을 때다.애니메이터에서 각 애니메이션에 Add Behaviour를 클릭해서 StateMachineBehaviour 스크립트를 부착해줬다.

 

 

 

 

스크립트 내용은 별 거 없다. OnStateExit() 함수에서 매개변수를 0으로 셋팅해주는 로직을 짜면 된다.

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

public class HouseEventReset : StateMachineBehaviour
{
    // OnStateEnter is called when a transition starts and the state machine starts to evaluate this state
    //override public void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    //{
    //    
    //}

    // OnStateUpdate is called on each Update frame between OnStateEnter and OnStateExit callbacks
    //override public void OnStateUpdate(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    //{
    //    
    //}

    // OnStateExit is called when a transition ends and the state machine finishes evaluating this state
    override public void OnStateExit(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    {
        /// 애니메이션 재생이 끝났을 경우

        animator.SetInteger("EventNumber", 0);
    }

    // OnStateMove is called right after Animator.OnAnimatorMove()
    //override public void OnStateMove(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    //{
    //    // Implement code that processes and affects root motion
    //}

    // OnStateIK is called right after Animator.OnAnimatorIK()
    //override public void OnStateIK(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    //{
    //    // Implement code that sets up animation IK (inverse kinematics)
    //}
}

 

이렇게 하면, 전체적인 로직은 완성되었다.

마지막으로 밝게 해놨던 전역 조명을 다시 어둡게 하면 완성이다!

 

 

완성

 

 

 

 

728x90
반응형