this is a bit complex, but bear with me:
Instigator is setup in ‘WeaponConfig.cs’, when the enemy/player fires a weapon, through a function called ‘LaunchProjectile’ (which, similar to my dodging state, is split into two parts. One is for freelook, where you fire a straight arrow, and the other is for targeting, firing an aimed-straight arrow), as follows:
// Launching Projectile on a target in the targeting state:
public void LaunchProjectile(Transform rightHand, Transform leftHand, Health target, GameObject instigator, float calculatedDamage) {
// This function instantiates our Projectile (for our ranged weapons),
// sets its position (either from right or left hand),
// and Rotation (using Quaternion.Identity)
// NOTE: GetMainHand() is out of course content. Original content function is 'GetTransform()' below:
// Projectile projectileInstance = Instantiate(projectile, GetMainHand(rightHand, leftHand).position, Quaternion.identity);
Projectile projectileInstance = Instantiate(projectile, GetTransform(rightHand, leftHand).position, Quaternion.identity);
// Finally, we also want to set the target for our projectile to follow (our player/enemy),
// set the one who started the battle as the instigator,
// and give it damage to deal whoever this projectile is aiming at
projectileInstance.SetTarget(target, instigator, calculatedDamage, GetSkill());
}
// for cases of firing a projectile when we don't have a target (freelook state):
public void LaunchProjectile(Transform rightHandTransform, Transform leftHandTransform, GameObject instigator, float damage)
{
Transform correctTransform = GetTransform(rightHandTransform, leftHandTransform);
Projectile projectileInstance = Instantiate(projectile, correctTransform.position, Quaternion.identity);
projectileInstance.transform.forward = instigator.transform.forward;
projectileInstance.SetupNoTarget(instigator, damage);
}
and then it’s setup in ‘Projectile.cs’:
public void SetTarget(Health target, GameObject instigator, float damage, Skill skill) {
// This function calls 'SetTarget' below, so we can aim at our enemies using our abilities
SetTarget(instigator, damage, target, Vector3.zero, skill);
}
public void SetTarget(Vector3 targetPoint, GameObject instigator, float damage, Skill skill) {
SetTarget(instigator, damage, null, targetPoint, skill);
}
/// <summary>
/// This function sets the target of our projectile. 1. It sets the target the projectile is aiming at, 2. it keeps track of him,
/// 3. It sets the damage destined to the projectile target, 4. It keeps track of who is responsible for firing that projectile, and 5.
/// it sets the skill that will get the XP for firing that hit
/// </summary>
/// <param name="instigator"></param>
/// <param name="damage"></param>
/// <param name="target"></param>
/// <param name="targetPoint"></param>
/// <param name="skill"></param>
public void SetTarget(GameObject instigator, float damage, Health target = null, Vector3 targetPoint = default, Skill skill = Skill.Ranged) {
this.target = target;
// our Target is now the GameObject holding this script
this.targetPoint = targetPoint;
// keep track of the target we are firing our Projectile abilities at
this.damage = damage;
// The damage dealt by our Projectile = damage from SetTarget ('float damage' argument)
this.instigator = instigator;
// The instigator is set to be an instance of whoever holds this script
this.skill = skill;
// The skill to train when a projectile is fired
Destroy(gameObject, maxLifeTime); // destroys our Projectile after its maximum lifetime (so it doesn't take a toll on our computer)
}
If needed, here’s also my ‘Projectile.OnTriggerEnter()’:
// New Code, for Third Person projectiles:
private void OnTriggerEnter(Collider other)
{
if (other.CompareTag("IncomingRangedDamageDetector"))
{
Debug.Log($"Incoming Ranged Attack detected");
var stateMachine = other.GetComponentInParent<EnemyStateMachine>();
if (stateMachine != null)
{
Debug.Log($"{stateMachine.gameObject.name} has been detected");
}
return;
}
// This function tells the projectile holding this script what to do
// when it hits something, depending on whether it's a target, or just
// something in the way
// if he's dead, just keep going. Don't try to damage him again...:
// if (other.GetComponent<Health>().IsDead()) return;
if (other.gameObject == instigator) return; // don't hit yourself
// if (other.TryGetComponent(out Health health)) health.TakeDamage(instigator, damage, instigator.GetComponent<Fighter>().GetCurrentWeaponConfig().GetSkill());
// TEST (if failed, uncomment the line above)
if (other.TryGetComponent(out Health health) && !alreadyHit.Contains(health))
{
if (other.GetComponent<Health>().IsDead()) return;
alreadyHit.Add(health);
health.TakeDamage(instigator, damage, instigator.GetComponent<Fighter>().GetCurrentWeaponConfig().GetSkill());
}
if (other.TryGetComponent(out ForceReceiver forceReceiver)) forceReceiver.AddForce(transform.forward * damage * 0.5f, true); // multiplied by 0.5f so as to neutralize the knockback impact
speed = 0;
onHit.Invoke();
if (hitEffect != null) Instantiate(hitEffect, transform.position, transform.rotation);
foreach (GameObject toDestroy in destroyOnHit) Destroy(toDestroy);
Destroy(gameObject, lifeAfterImpact);
Debug.Log($"Instigator = {instigator.name}");
Debug.Log($"Collider = {other.name}");
Debug.Log($"Damage Dealt = {damage}");
}
I’ll be gone for a bit now (apologies for this), and will be back in an hour or two, but I think I have an idea for this. My idea would be to check if the instigator is the parent of the detected detector, then we can cancel it out. I’ll tag you when I return (again, I’m sorry for this)