한참 미루다가 이제야 다시 글을 써봅니다. 지금 vfx를 공부중인데, 현재 진행중인 프로젝트의 초기화면에 사용하려고 제작해봤습니다.
셰이더는 총 3개가 들어갔습니다. 워프통로 & 빠르게 앞으로 쏟아지는 별빛 & 로켓불꽃 입니다.
적용을 위해서는 새 프로젝트로 3D URP로 생성 후에
상단의 window - package manager - 탭의 상단에 unity registry로 바꾸고
검색창에 shader graph와 visual effect graph를 다운받아주셔야 합니다.
버전은 제가 유니티 설치방법글에 쓴 버전입니다.
아래는 별빛의 vfx graph입니다.
아래는 불꽃 vfx 그래프입니다.
아래는 워프 통로 shader graph입니다.
불꽃 이펙트는 포토샵을 이용해서 그린 후에 PNG로 가져왔습니다. (흰색이라 검은배경으로 가져왔어요.)
아래의 스크립트를 이용해서 화면이 흔들리는 효과와, 시작 후에 스페이스바를 이용해서 워프통로와 별빛이 서서히 나타나고 사라지고를 구현했습니다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.VFX;
public class CombinedScript : MonoBehaviour
{
// Camera shake variables
public float shakeAmount = 0.003f;
public float shakeTime = 100.0f;
// Warp speed and shader variables
public MeshRenderer cylinder;
public VisualEffect warpSpeedVFX;
public float rate = 0.02f;
private bool warpActive;
public float delay = 2.5f;
private Vector3 originalCameraPosition;
private void Start()
{
// Initialize VFX and shader
warpSpeedVFX.Stop();
warpSpeedVFX.SetFloat("WarpAmount", 0);
cylinder.material.SetFloat("Active_", 0);
// Store the original camera position
originalCameraPosition = Camera.main.transform.position;
// Start the camera shake coroutine
StartCoroutine(Shake(shakeAmount, shakeTime));
}
private void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
warpActive = !warpActive;
StartCoroutine(ActivateParticles());
StartCoroutine(ActivateShader());
}
}
IEnumerator Shake(float ShakeAmount, float ShakeTime)
{
float timer = 0;
while (timer <= ShakeTime)
{
Vector3 shakePosition = originalCameraPosition + (Vector3)UnityEngine.Random.insideUnitCircle * shakeAmount;
Camera.main.transform.position = shakePosition;
timer += Time.deltaTime;
yield return null;
}
Camera.main.transform.position = originalCameraPosition;
}
IEnumerator ActivateParticles()
{
if (warpActive)
{
yield return new WaitForSeconds(delay);
warpSpeedVFX.Play();
float amount = warpSpeedVFX.GetFloat("WarpAmount");
while (amount < 1 && warpActive)
{
amount += rate;
warpSpeedVFX.SetFloat("WarpAmount", amount);
yield return new WaitForSeconds(0.1f);
}
}
else
{
float amount = warpSpeedVFX.GetFloat("WarpAmount");
while (amount > 0 && !warpActive)
{
amount -= rate;
warpSpeedVFX.SetFloat("WarpAmount", amount);
yield return new WaitForSeconds(0.1f);
if (amount <= 0 + rate)
{
amount = 0;
warpSpeedVFX.SetFloat("WarpAmount", amount);
warpSpeedVFX.Stop();
}
}
}
}
IEnumerator ActivateShader()
{
if (warpActive)
{
float amount = cylinder.material.GetFloat("Active_");
while (amount < 1 && warpActive)
{
amount += rate;
cylinder.material.SetFloat("Active_", amount);
yield return new WaitForSeconds(0.1f);
}
}
else
{
float amount = cylinder.material.GetFloat("Active_");
while (amount > 0 && !warpActive)
{
amount -= rate;
cylinder.material.SetFloat("Active_", amount);
yield return new WaitForSeconds(0.1f);
if (amount <= 0 + rate)
{
amount = 0;
cylinder.material.SetFloat("Active_", amount);
}
}
}
}
}
간단하게 여기까지 하고 궁금한점은 댓글 남겨주세요~