使用了RectMask2D的列表使其子项加入的粒子物体受父物体的遮罩影响

使用了RectMask2D的列表使其子项加入的粒子物体受父物体的遮罩影响

核心:使用 Sprite Mask 组件 为特效层做遮罩处理
Sprite Mask设置

为列表Go新建子物体添加Sprite Mask组件

设置Sprite Mask 的Sprite

并取列表RectMask2D的 rectTransform

将新建物体设置为相应大小且位置同步

写了一个同步脚本来设置 可以在创建时加入Sprite Mask后挂载使用

根据mask的四个Corner坐标 来计算位置宽高以及scale 之后作为子物体移动到列表下

using UnityEngine;
using UnityEngine.UI;

[RequireComponent(typeof(SpriteMask))]
public class SetMaskScale : MonoBehaviour
{
    public RectTransform mask;
    private SpriteMask spriteMask;

    private void Start()
    {
        if (mask == null)
        {
            var mask2D = transform.GetComponentInParent<RectMask2D>();
            if (mask2D)
            {
                mask = mask2D.rectTransform;
            }
        }
        spriteMask = GetComponent<SpriteMask>();
        if (mask)
        {
            var corners = new Vector3[4];
            mask.GetWorldCorners(corners);

            var size = spriteMask.bounds.size;
            var width = (corners[3].x - corners[0].x);
            var height = (corners[1].y - corners[0].y);

            var scaleX = width / size.x;
            var scaleY = height / size.y;

            var localScale = transform.localScale;
            localScale.x *= scaleX;
            localScale.y *= scaleY;
            transform.localScale = localScale;
            transform.position = (corners[0] + corners[2]) / 2;
        }
    }
}

在同步好mask区域后 设置Sprite Mask的自定义范围设置

将Sprite Mask的isCustomRangeActive设置为true

具有自定义范围设置的Sprite Mask 可以确保mask仅仅影响指定 front 到 back 图层范围内的Sprite

之后分别设置相应的层级ID和SortingOrder即可

frontSortingLayerID / frontSortingOrder / backSortingLayerID / backSortingOrder


粒子设置

Sprite Mask之后 取粒子Go子物体中的 ParticleSystemRenderer

设置其 **maskInteraction **属性 (Enum SpriteMaskInteraction) 为 SpriteMaskInteraction.VisibleInsideMask(sprite将会在蒙版区域内可见)

其指定了粒子如何与Sprite Mask交互

namespace UnityEngine
{
    //
    // 摘要:
    //     This enum controls the mode under which the sprite will interact with the masking
    //     system.
    public enum SpriteMaskInteraction
    {
        //
        // 摘要:
        //     The sprite will not interact with the masking system.
        None = 0,
        //
        // 摘要:
        //     The sprite will be visible only in areas where a mask is present.
        VisibleInsideMask = 1,
        //
        // 摘要:
        //     The sprite will be visible only in areas where no mask is present.
        VisibleOutsideMask = 2
    }
}

完成

React TypeScript (tsx) 中实现一个无限轮播效果通常涉及以下几个步骤: 1. **状态管理**: 创建一个状态来表示当前显示的子索引。这可以是一个名为 `currentSlide` 的变量,并使用 React Hooks 如 `useState` 来初始化和更新它。 ```typescript import { useState } from 'react'; const [currentSlide, setCurrentSlide] = useState(0); ``` 2. **数据结构**: 假设你有一个数组 `items` 包含所有列表。你可以使用 TypeScript 的泛型来创建一个通用的组件,接受任何类型的子组件作为内容。 ```typescript interface ListItem<T> { id: number; content: T; } type CarouselProps<T> = { items: ListItem<T>[]; }; ``` 3. **轮播组件**: 使用 `map` 函数遍历 `items`,并根据索引动态渲染每个子。同时添加一个 `key` 属性以帮助 React 识别哪些部分发生了更改。 ```tsx function Carousel<T>(props: CarouselProps<T>) { const { items } = props; return ( <div className="carousel"> {items.map((item, index) => ( <div key={index} className={`slide ${index === currentSlide ? 'active' : ''}`}> <div>{item.content}</div> </div> ))} </div> ); } ``` 4. **处理滚动**: 当用户滚动到列表底部时,增加 `currentSlide` 并更新状态。如果已经到了最后一,可以将其设置回第一开始新的一轮循环。 ```tsx function handleScroll() { if (currentSlide + 1 >= items.length) { setCurrentSlide(0); } else { setCurrentSlide(currentSlide + 1); } } // 使用 React Hooks useEffect 进行监听 useEffect(() => { window.addEventListener('scroll', handleScroll); return () => window.removeEventListener('scroll', handleScroll); }, [handleScroll]); ``` 5. **样式和布局**: 别忘了添加 CSS 样式来实现滚动效果,比如使用 CSS Scroll Snap Points 或其他动画库来实现平滑过渡。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值