unity更合理的雨

唉一开始做太唐了居然想着多复制几分雨不然怕区域不够因为如果让雨跟着角色走那太诡异了,而且很明显能看出来,然后写了些许代码让雨合理些

当然毕竟借鉴了ultrakill,粒子数量是50000,速度30,起始大小0.05,伸展billboard速度比例0.0075

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

public class RainController : MonoBehaviour
{
    [Header("玩家设置")]
    public Transform player;
    public float minFollowSpeed = 1f;
    public float maxFollowSpeed = 10f;
    public float followSmoothness = 0.5f;

    [Header("基础粒子参数")]
    public float baseParticleSpeed = 30f;
    public float speedMultiplier = 1.5f;
    public float baseSize = 0.05f;
    public float stretchScale = 0.0075f;
    public int baseEmissionRate = 50000;

    [Header("性能优化")]
    public float lodDistance1 = 30f;
    public float lodDistance2 = 50f;
    public float frameRateThreshold = 10f;
    public float performanceDowngradeFactor = 0.9f;

    [Header("风向效果")]
    public float windIntensity = 1f;
    public float windSpeed = 0.5f;

    [Header("固定风力设置")]
    public float fixedWindX = 12.5f; // 在Inspector中可调节
    public float fixedWindZ = 0f;  // 如果需要固定Z轴
    public bool useRandomWind = false; // 是否保留随机变化

    private ParticleSystem rainParticles;
    private ParticleSystem.MainModule mainModule;
    private ParticleSystem.VelocityOverLifetimeModule velocityModule;
    private ParticleSystem.EmissionModule emissionModule;
    private ParticleSystemRenderer particleRenderer;
    private Vector3 lastPosition;
    private float currentSpeed;
    private Vector3 smoothPosition;
    private float initialEmissionRate;

    void Start()
    {
        rainParticles = GetComponent<ParticleSystem>();
        mainModule = rainParticles.main;
        velocityModule = rainParticles.velocityOverLifetime;
        emissionModule = rainParticles.emission;
        particleRenderer = GetComponent<ParticleSystemRenderer>();

        lastPosition = player.position;
        smoothPosition = transform.position;
        initialEmissionRate = baseEmissionRate;

        InitializeParticles();
    }

    void InitializeParticles()
    {
        mainModule.startSpeed = baseParticleSpeed;
        mainModule.startSize = baseSize;
        mainModule.simulationSpace = ParticleSystemSimulationSpace.World;
        mainModule.maxParticles = Mathf.FloorToInt(baseEmissionRate * 1.2f);

        particleRenderer.renderMode = ParticleSystemRenderMode.Stretch;
        particleRenderer.velocityScale = stretchScale;
        particleRenderer.lengthScale = 2f;

        emissionModule.rateOverTime = baseEmissionRate;

        velocityModule.enabled = true;
    }

    void Update()
    {
        CalculatePlayerSpeed();
        UpdateParticleParameters();
        SmoothFollowPlayer();
        ApplyWindEffect();
        HandleLOD();
        MonitorPerformance();
    }

    void CalculatePlayerSpeed()
    {
        Vector3 horizontalMove = new Vector3(
            player.position.x - lastPosition.x,
            0,
            player.position.z - lastPosition.z
        );
        currentSpeed = horizontalMove.magnitude / Time.deltaTime;
        lastPosition = player.position;
    }

    void UpdateParticleParameters()
    {
        float speedRatio = Mathf.Clamp01(
            (currentSpeed - minFollowSpeed) /
            (maxFollowSpeed - minFollowSpeed)
        );

        // 动态调整参数
        mainModule.startSpeed = baseParticleSpeed * (1 + speedRatio * speedMultiplier);
        particleRenderer.velocityScale = stretchScale * (1 + speedRatio * 2f);
        mainModule.startSize = baseSize * (1 - speedRatio * 0.3f);
        emissionModule.rateOverTime = initialEmissionRate * (1 + speedRatio * 0.5f);
    }

    void SmoothFollowPlayer()
    {
        Vector3 targetPosition = new Vector3(
            player.position.x,
            transform.position.y,
            player.position.z
        );

        smoothPosition = Vector3.Lerp(
            smoothPosition,
            targetPosition,
            followSmoothness * Time.deltaTime * 10f
        );

        transform.position = smoothPosition;
    }

   

void ApplyWindEffect()
{
    // 固定风力
    velocityModule.x = 12.5f;

    if (useRandomWind)
    {
        // 保留随机变化部分
        float windOffset = Time.time * windSpeed;
        float windZ = Mathf.PerlinNoise(0, windOffset) * 2f - 1f;
        velocityModule.z = fixedWindZ + (windZ * windIntensity * 0.5f);
    }
    else
    {
        velocityModule.z = fixedWindZ;
    }
}

    void HandleLOD()
    {
        if (Camera.main == null) return;

        float distance = Vector3.Distance(transform.position, Camera.main.transform.position);

        if (distance > lodDistance2)
        {
            emissionModule.rateOverTime = initialEmissionRate * 0.4f;
            mainModule.startSize = baseSize * 0.8f;
        }
        else if (distance > lodDistance1)
        {
            emissionModule.rateOverTime = initialEmissionRate * 0.7f;
            mainModule.startSize = baseSize * 0.9f;
        }
        else
        {
            emissionModule.rateOverTime = initialEmissionRate;
            mainModule.startSize = baseSize;
        }
    }

    void MonitorPerformance()
    {
        // 计算当前帧率(如果targetFrameRate未设置则使用默认60)
        int targetFPS = Application.targetFrameRate > 0 ? Application.targetFrameRate : 60;
        float currentFPS = 1f / Time.unscaledDeltaTime;

        if (targetFPS - currentFPS > frameRateThreshold)
        {
            initialEmissionRate = Mathf.Max(
                initialEmissionRate * performanceDowngradeFactor,
                baseEmissionRate * 0.5f
            );
        }
        else if (initialEmissionRate < baseEmissionRate * 0.95f)
        {
            initialEmissionRate = Mathf.Min(
                initialEmissionRate / performanceDowngradeFactor,
                baseEmissionRate
            );
        }
    }
}

风那块可以拉高点,唉面条下多了怎么吃啊,虽然很好吃

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值