Files
Continentis/Assets/OtherPlugins/Kamgam/UGUIParticles/Scripts/ParticleSystemForImage.Attractor.cs
SoulliesOfficial d09b58fd80 架构大更
2026-03-20 11:56:50 -04:00

139 lines
5.2 KiB
C#

using System;
using UnityEngine;
namespace Kamgam.UGUIParticles
{
public partial class ParticleSystemForImage // .Attractor
{
private RectTransform _attractorRect;
[NonSerialized] protected ParticleSystemForceField _particleSystemForceField;
public ParticleSystemForceField ParticleSystemForceField
{
get
{
if (ParticleSystem == null)
return null;
if (_particleSystemForceField == null)
_particleSystemForceField =
ParticleSystem.gameObject.GetComponentInChildren<ParticleSystemForceField>(true);
return _particleSystemForceField;
}
}
public void OnUseAttractorChanged(bool value)
{
if (value)
EnableAttractor();
else
DisableAttractor();
ParticleImage?.MarkDirtyRepaint();
}
public void EnableAttractor()
{
if (ParticleSystem == null)
return;
// Find or create force field
var forceField = ParticleSystem.gameObject.GetComponentInChildren<ParticleSystemForceField>(true);
var forces = ParticleSystem.externalForces;
forces.enabled = true;
forces.influenceFilter = ParticleSystemGameObjectFilter.List;
if (forces.influenceCount == 0 || forces.GetInfluence(0) == null)
{
if (forceField == null)
{
var go = new GameObject("Particle Attractor ForceField");
go.SetActive(false);
go.transform.parent = ParticleSystem.gameObject.transform;
go.transform.localRotation = Quaternion.identity;
go.transform.localPosition = new Vector3(0f, 0f, 0f);
go.transform.localScale = Vector3.one;
forceField = go.AddComponent<ParticleSystemForceField>();
forceField.gravity = 1f;
forceField.drag = 0.1f;
forceField.endRange = 1000f;
forceField.multiplyDragByParticleSize = false;
go.SetActive(true);
}
if (forces.influenceCount > 0)
forces.SetInfluence(0, forceField);
else
forces.AddInfluence(forceField);
}
if (forceField != null)
forceField.gameObject.SetActive(true);
}
public void DisableAttractor()
{
if (ParticleSystem == null)
return;
var forces = ParticleSystem.externalForces;
forces.enabled = false;
var forceField = ParticleSystem.gameObject.GetComponentInChildren<ParticleSystemForceField>(true);
if (forceField != null) forceField.gameObject.SetActive(false);
}
/// <summary>
/// </summary>
/// <param name="originRelativeToBottomLeft">
/// The origin of the particles relative to the bottom left of the ParticleImage
/// rect.
/// </param>
/// <param name="width"></param>
/// <param name="height"></param>
public void UpdateAttractorPosition(Vector3 originRelativeToBottomLeft, float width, float height)
{
if (UseAttractor && Attractor == null)
{
DisableAttractor();
return;
}
if (UseAttractor && Attractor && !ParticleSystemForceField.gameObject.activeSelf) EnableAttractor();
if (!UseAttractor || ParticleImage == null || ParticleSystem == null || ParticleSystemForceField == null ||
Attractor == null)
return;
if (_attractorRect != Attractor)
{
if (Attractor != null)
_attractorRect = Attractor as RectTransform;
else
_attractorRect = null;
}
Vector3 attractorDeltaToBottomLeft;
if (_attractorRect != null)
attractorDeltaToBottomLeft = ParticleImage.WorldSpaceToUISpace(
_attractorRect.TransformPoint(_attractorRect.rect.center), true, ParticleImage.RectTransform,
ParticleImage.GetRenderMode());
else
attractorDeltaToBottomLeft = ParticleImage.WorldSpaceToUISpace(Attractor, ParticleImage.RectTransform,
ParticleImage.GetRenderMode());
var pixelsPerUnitScaled = new Vector3(
PixelsPerUnit * ParticleImage.transform.lossyScale.x,
PixelsPerUnit * ParticleImage.transform.lossyScale.y,
PixelsPerUnit * ParticleImage.transform.lossyScale.z
);
var deltaInWorldSpace = attractorDeltaToBottomLeft - originRelativeToBottomLeft;
deltaInWorldSpace.x /= pixelsPerUnitScaled.x;
deltaInWorldSpace.y /= pixelsPerUnitScaled.y;
deltaInWorldSpace.z /= pixelsPerUnitScaled.z;
ParticleSystemForceField.gameObject.transform.localPosition = deltaInWorldSpace;
}
}
}