唉一开始做太唐了居然想着多复制几分雨不然怕区域不够因为如果让雨跟着角色走那太诡异了,而且很明显能看出来,然后写了些许代码让雨合理些
当然毕竟借鉴了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
);
}
}
}
风那块可以拉高点,唉面条下多了怎么吃啊,虽然很好吃

1万+

被折叠的 条评论
为什么被折叠?



