Notice
Recent Posts
Archives
Today
Total
«   2024/06   »
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30
Recent Comments
관리 메뉴

우당탕탕 개발일지

[Unity]UGUI Particle Mask 본문

Unity

[Unity]UGUI Particle Mask

devchop 2023. 9. 11. 13:03

UIParticleAdditiveClip.shader
0.00MB

UI에서 리스트뷰를 사용하고, 그 안에서 파티클을 올렸을때 마스킹이 안되는 현상이 있다. 이를 위해서는 

 

1. 아래 스트립트를 원하는 이펙트오브젝트 최상위에 올려준다(particleMask.cs)  보통 여러개의 파티클이 모여있기 때문에, 각 파티클에 particleMask를 올리는게 아니라 최상위 하나에 올리는걸로 변경하였다. 

2. 각 파티클 머티리얼의 셰이더는 위에 첨부 되어있는 UIParticleAdditiveClip.shader로 변경한다. 

3. 나는 이펙트 오브젝트를 동적으로 생성하는 일이 많아서, ParticleMask.cs 에 있는 mask를 미리 세팅해줄수가없다. 따라서 동적으로 생성하고 난 뒤 SetMaskAndInit() 함수를 통해 Rectmask2D를 전달하고 초기화하게끔 했다.

4. RectMask2D 는 스크롤뷰 오브젝트에 붙어있어야한다. (ScrollRect 를 GetComponent 하기때문, 안그럼 에러남)

 

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

public class ParticleMask : MonoBehaviour
{
    public RectMask2D mask;

    List<Material> materials = new List<Material>();
    [SerializeField] List<ParticleSystem> particles = null;
    private RectTransform rect = null;

    bool isInit = false;
    private void Awake()
    {
        Init();
    }
    public void SetMaskAndInit(RectMask2D mask)
    {
        if (this.mask == mask) return;
        this.mask = mask;
        Init();
    }

    public void Init()
    {
        if (mask == null) return;
        if (isInit) return;

        rect = mask.GetComponent<RectTransform>();
        int length = particles.Count;
        for (int i = 0; i < length; i++)
        {
            if (particles[i] != null) materials.Add(particles[i].GetComponent<Renderer>().material);
        }
        mask.GetComponent<ScrollRect>().onValueChanged.AddListener((e) => { setClip(); });

        isInit = true;
    }

    void setClip()
    {
        Vector3[] wc = new Vector3[4];
        rect.GetWorldCorners(wc); // Calculate the point coordinates in world space
        var clipRect = new Vector4(wc[0].x, wc[0].y, wc[2].x, wc[2].y);// Select the lower left and upper right corners

        int length = materials.Count;
        for (int i = 0; i < length; i++)
        {
            materials[i].SetVector("_ClipRect", clipRect);
            materials[i].SetFloat("_UseClipRect", 1.0f);
        }
    }

}

 

rewardEff 아래에 4개의 파티클로 이루어진 effect object.
rewardEff 오브젝트엔 4개의 파티클을 미리 넣어놓고, mask는 비워놓는다. 나중에 동적생성한 뒤 세팅을 해주면된다 ( setMaskAndInit )

 

아래 사이트를 참고하여 내가 필요한 부분으로 변형하였다. 

https://www.programmersought.com/article/7682124522/

 

ScrollRect crops ParticleSystem particles (UGUI) (1) - Programmer Sought

UGUI's ScrollRect can correctly trim UGUI's own components including Image, Text, etc., but can't correctly crop ParticleSystem particles, which causes great trouble for the client and artists. Today we solve the cropping problem by modifying the shader. E

www.programmersought.com