I would like to find out why it returns null and more importantly how I get to the collider of the object I hit.
My setup:
(Attached to the shooting particle system)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Gamekit3D;
using System;
using System.Linq;
[RequireComponent(typeof(ParticleSystem))]
public class DamagingParticleTriggerListener : MonoBehaviour
{
[SerializeProperty("DamageAmount")] float damageAmount;
public float DamageAmount { get; internal set; } = 1;
public Damageable owner;
private ParticleSystem myParticleSystem;
private List<ParticleCollisionEvent> collisionEvents;
protected VList<Damageable> hittables;
void Start()
{
myParticleSystem = GetComponent<ParticleSystem>();
collisionEvents = new List<ParticleCollisionEvent>();
hittables = FindObjectsOfType<Damageable>().ToVList();
hittables -= hittables.Where((damageable) =>
{
if (damageable == null) Debug.LogWarning(String.Format("'{0}' found an object in the {4} Script with a {1} owned by '{2}' that is null. Que???", name, nameof(Damageable), damageable.name, typeof(DamagingParticleTriggerListener)));
else
{
if (owner == null) Debug.LogWarning(String.Format("'{0}' found in the {1} Script that {2} is null. Que???", name, nameof(DamagingParticleTriggerListener), nameof(owner)));
else return damageable.team == owner.team;
}
return false;
});
ParticleSystem.TriggerModule particleSysTrigger = myParticleSystem.trigger;
foreach (Component component in hittables) particleSysTrigger.AddCollider(component);
}
void OnParticleTrigger()
{
// Get all of the systems particles entering one of the given triggers this frame
List<ParticleSystem.Particle> particlesTriggeredEntered = new List<ParticleSystem.Particle>();
int numEntered = myParticleSystem.GetTriggerParticles(ParticleSystemTriggerEventType.Enter, particlesTriggeredEntered, out ParticleSystem.ColliderData insideData);
// Iterate over these particles, send a damage message to all hit triggers and destroy the particle by setting its remaining lifetime to 0
for (int particleIndex = 0; particleIndex < numEntered; particleIndex++)
{
for (int colliderIndex = 0; colliderIndex < insideData.GetColliderCount(particleIndex); colliderIndex++)
{
Component collider = insideData.GetCollider(particleIndex, colliderIndex);
if (collider != null) SendDamageMessage(collider.gameObject);
else Debug.LogWarning(string.Format("'{0}' hit something that doesn't exist.", name));
ParticleSystem.Particle particle = particlesTriggeredEntered[particleIndex];
particle.remainingLifetime = 0;
}
}
// Push the remainingLifetime = 0 particles into the system, replacing the old particles.
myParticleSystem.SetTriggerParticles(ParticleSystemTriggerEventType.Enter, particlesTriggeredEntered);
}
void SendDamageMessage(GameObject other)
{
if (!other.TryGetComponent(out Damageable theHurtOne))
{
return;
}
Damageable.HealthInteractionMessage message = new Damageable.HealthInteractionMessage()
{
difference = -DamageAmount,
damager = this,
direction = Vector3.up,
stopCamera = false,
AppliesToTeamsX = (Damageable.Teams)(!(owner is null) ? owner.team != 0 ? 4/*~(owner.team)*/ : 0 : 0)
};
theHurtOne.ApplyHealthInteraction(message);
}
}
Note: VList is a custom defined List wrapper, inheriting from List and overloading all bitwise operators, “-=” in this case amounts to
public static VList<T> operator -(VList<T> a, IEnumerable<T> b)
{
return new VList<T>(a.Where((x) => !b.Contains(x)));
}
Results while Debugging:
When I shoot someone of my team, the particle passes through the target. Yay!
When I slow down the particles and walk through them, nothing happens. Yay!
When I shoot someone of the opposing team it triggers the “hit something that doesn’t exist.”-warning, I set for when ParticleSystem.ColliderData.GetCollider(int particleIndesx, int colliderIndex) returns null.
The particle moves through the opposing player.
Nay…
No other Logs are in the Debug Log.
Thanks to everyone helping!