WinCNT

Sandevistan 이펙트를 만들어 보자! 본문

Unity/Graphics 관련

Sandevistan 이펙트를 만들어 보자!

WinCNT_SSS 2025. 6. 16. 09:00

서론

글 쓸 거리가 점점 쌓이고는 있지만, 그건 두고 우선적으로 해보고 싶은 게 생겼다!

그건 바로 사이버 펑크 애니메이션에 나오는 Sandevistan 이펙트!!

(사이버 펑크 애니 보진 않았지만…)


우선은 작업 결과부터…

나름 잘 나온 것 같다!


핵심은 바로 BakeMesh!

우선은 소스 코드부터!

public void CreateEcho(float echoDuration)
{
    if (!skinnedMeshRenderer) return;
    if (!echoPrefab) return;

    // 현재 포즈를 복사
    Mesh bakedMesh = new Mesh();
    skinnedMeshRenderer.BakeMesh(bakedMesh);

    // 오브젝트 생성
    var echo = Instantiate(echoPrefab);
    echo.transform.position = skinnedMeshRenderer.transform.position;
    echo.transform.rotation = skinnedMeshRenderer.transform.rotation;
    echo.transform.localScale = skinnedMeshRenderer.transform.lossyScale;

    // 메시와 머티리얼 세팅
    var mf = echo.GetComponent<MeshFilter>();
    var mr = echo.GetComponent<MeshRenderer>();

    mf.sharedMesh = bakedMesh;

    int subMeshCount = bakedMesh.subMeshCount;
    // 모든 SubMesh에 동일한 머티리얼 적용
    var materials = Enumerable.Repeat(echoMaterial, subMeshCount).ToArray();
    mr.sharedMaterials = materials;
    
    // 머티리얼 프로퍼티 블럭 설정
    var mpb = new MaterialPropertyBlock();
    mpb.SetColor(BaseColor, echoColor);
    for (int i = 0; i < subMeshCount; ++i)
        mr.SetPropertyBlock(mpb, i); // 서브메시 단위로 설정

    Destroy(echo, echoDuration);
}

결과적으로 로직은 생각보다 어렵지 않았다

MeshRenderer의 현재 포즈를 베이크하는 BakeMesh라는 API가 있었다

그걸 Instantiate하면 잔상 캐릭터가 생긴다!


잔상은 Coroutine으로 제어!

잔상의 생성과 제어는 Coroutine를 사용하기로 했다(UniTask가 더 낫겠지만ㅎㅎ)

public void StartEcho()
{
    echoRoutine ??= StartCoroutine(EchoLoop());
    echoGenerator.ApplyEchoColor(true);
}

public void StopEchoLoop()
{
    if (echoRoutine != null)
    {
        StopCoroutine(echoRoutine);
        echoRoutine = null;
        echoGenerator.ApplyEchoColor(false);
    }
}

private IEnumerator EchoLoop()
{
    while (true)
    {
        echoGenerator.CreateEcho(echoDuration);
        yield return new WaitForSeconds(interval);
    }
}

색상은 Animation Clip으로 제어!

색상은 좀 고민하다가 Animation Clip에 색상 변경을 설정해두고 켰다 끄는 걸로 구현했다


마무리

애니메이션을 안 봤다 보니 사실 산데비스탄이 어떤 능력인지 정확히는 모르겠다…

약간 시간 정지의 느낌이 있나?

즉 좀 더 완벽하게 산데비스탄을 구현하려면, 추가로 시간 정지 연출과 발동 중 전체 화면 색상을 조정하는 기능이 필요할 것으로 보인다

문제는 전체 화면 색상 조정이 생각보다 복잡해질 거 같군…

타임라인 + 볼륨으로 전체 화면 색상을 조정하고, 특정 스크립트로 발동 캐릭터는 색이 안 바뀌게 해야 하나?

나중에 하게 되면 생각해야지


참고 사이트

Robbie Howe

 

Robbie Howe

Technical/VFX Artist

robbiehowe.xyz