Hello, I’ve run into a strange bug with projectiles if their weapon ranges are around 15 or higher. Just after spawning the projectile, the cursor and Raycast stop detecting the enemy for 30-40 frames. I’ve worked out what’s causing it, but I’m at a loss for how to fix it, since we’re using RaycastAll and the colliders on the enemies aren’t being modified.
In the InteractWithComponent() method, everything works as normal until the character starts to attack. I have a print(hits.length) statement that returns 2 when hovering on an enemy. Starting on the call of the projectile spawning, the statement goes down to 1 and no longer returns any IRaycastable (even if I’m hovering over another enemy).
It only affects the CombatTargets, since if I place a pickup behind an enemy, it’ll change to the pickup cursor rather than Movement.
If I comment out the instantiate below, everything works as normal.
public void LaunchProjectile(Transform rightHand, Transform leftHand, Health target, GameObject instigator, float calculatedDamage)
{
Projectile projectileInstance = Instantiate(Projectile, GetTransform(rightHand, leftHand).position, Quaternion.identity);
projectileInstance.SetTarget(target, instigator, calculatedDamage);
}
I tried swapping projectiles to see if it was a framerate thing, but that doesn’t seem to be the case. I also checked the gizmos and scene to make sure that the enemy colliders weren’t teleporting off into the distance or something, but everything stayed in place.
Here’s a video of the bug, the first 6 seconds are normal speed, then slowed down by 20x in gametime. It seems to be a set number of frames, which is even weirder to me.
InteractWithComponent() code
Summary
private bool InteractWithComponent()
{
RaycastHit[] hits = RaycastAllSorted();
foreach (RaycastHit hit in hits)
{
print("Raycast hits: " + hits.Length);
IRaycastable[] raycastables = hit.transform.GetComponents<IRaycastable>();
foreach (IRaycastable raycastable in raycastables)
{
if(raycastable.HandleRaycast(this))
{
SetCursor(raycastable.GetCursorType());
return true;
}
}
}
return false;
}
CombatTarget.cs
Summary
namespace RPG.Combat
{
[RequireComponent(typeof(Health))]
public class CombatTarget : MonoBehaviour, IRaycastable
{
public CursorType GetCursorType()
{
return CursorType.Combat;
}
public bool HandleRaycast(PlayerController callingController)
{
Fighter fight = callingController.GetComponent<Fighter>();
if(!fight.CanAttack(gameObject))
{
return false;
}
if (Input.GetMouseButtonDown(0))
{
fight.Attack(gameObject);
}
return true;
}
}
}
IRaycastable.cs
Summary
namespace RPG.Control
{
public interface IRaycastable
{
bool HandleRaycast(PlayerController callingController);
CursorType GetCursorType();
}
}
Fighter Shoot event code
Summary
// Animation Event
void Hit()
{
if (target == null) { return; }
float damage = GetComponent<BaseStats>().GetStat(Stat.Damage);
// Actions to take when animation hits
if(currentWeapon.value.HasProjectile())
{
currentWeapon.value.LaunchProjectile(rightHandTransform, leftHandTransform, target, gameObject, damage);
}
else
{
target.TakeDamage(gameObject, damage);
}
}
void Shoot()
{
Hit();
}
When googling, I was only able to find instances where people weren’t able to raycast against their instantiated objects, but no cases where an instantiation call stopped raycast hits on existing colliders. Any help towards a solution is much appreciated!
Edit: I’m still very confused after some more debugging. As soon as the projectile is spawned, any Raycast seems to completely ignore any distant enemy’s Capsule Collider for several frames. Setting up a debug ray, you can see that the raycast is passing straight through the Capsule, but returns that it’s only intersecting the Terrain and that it’s not IRaycastable.
Picture showing the change after projectile spawning.
Once spawned, disabling the projectile Box Collider fixes the issue, even thought it’s nowhere near the raycast and doesn’t fire the OnTriggerEnter or anything else…