suriyun-production / mmorpg-kit-docs

This is document for MMORPG KIT project (https://www.assetstore.unity3d.com/#!/content/110188?aid=1100lGeN)
https://suriyun-production.github.io/mmorpg-kit-docs
49 stars 11 forks source link

Question about the possibility of impactable but non-depawnable projectiles #2328

Closed Niinra closed 8 months ago

Niinra commented 9 months ago

Hello, I have a question about the way the hit of the projectiles works. I am trying to make projectiles that apply damage when touching the hitbox but the projectile is not destroyed or deactivated and continues to apply damage to all the hitboxes in front of it. That is, it disappears until its distance is complete, so I was reviewing the MissileDamageEntity script in this method: image

I understand that when finding a hitbox that is not dead or that cannot take damage or its value is null it will return false and the path of the projectile will continue, but if not it returns true and applies the damage and that is where it disappears, but I still don't understand exactly What to do with this method so that it continues on its path, finding the hitbox and dealing its damage, until the projectile dies at a distance.

If my question is very tedious or annoying, archive it or leave me a small idea where to start. If you clearly have time, thank you very much in advance

pd:If it is something in general that I can do but you have to touch the core, I would like to help to be able to implement projectiles that dare and apply damage. It is very good mechanics.

darkkriteus commented 9 months ago

Hi, make these modifications if you want the projectile to go through the targets

`// remove this function FindAndApplyDamage // if (!_alreadyHitObjects.Contains(target.GetObjectId()))

// it remove this line ExplodeApplyDamage // FindAndApplyDamage(collider.gameObject, false, _alreadyHitObjects); `

Modify the HitDetect method to iterate over all hit objects and apply damage to each one. for (int i = 0; i < hitCount; ++i) { if (CurrentGameInstance.DimensionType == DimensionType.Dimension2D && _hits2D[i].transform != null) TriggerEnter(_hits2D[i].transform.gameObject); if (CurrentGameInstance.DimensionType == DimensionType.Dimension3D && _hits3D[i].transform != null) TriggerEnter(_hits3D[i].transform.gameObject); }

Modify the TriggerEnter function to remove the _destroying check and allow the projectile to apply damage to each target.
`protected virtual void TriggerEnter(GameObject other)

{ // remove this line // if (_destroying) // return;

if (!other.GetComponent<IUnHittable>().IsNull())
    return;

if (FindTargetHitBox(other, true, out DamageableHitBox target))
{
    // remove
    // if (explodeDistance <= 0f)
    // {
    //     if (!_alreadyHitObjects.Contains(target.GetObjectId()))
    //     {
    //         _alreadyHitObjects.Add(target.GetObjectId());
    //         ApplyDamageTo(target);
    //     }
    // }

    // aplly damage
    ApplyDamageTo(target);

    // Remova este bloco de código
    // PushBack(destroyDelay);
    // _destroying = true;

    return;
}

// remove
// if (explodeDistance > 0f)
// {
//     Explode();
// }
// PushBack(destroyDelay);
// _destroying = true;

}`

I haven't tested it, but I hope it helps

darkkriteus commented 9 months ago

If you want, send me your email, and I'll send you the modified script when I can, it was difficult to organize here

insthync commented 9 months ago

@Niinra I recommend you create a new component which inherited from missile damage entity, so you won't have to modify CORE's codes and then override just a few functions to do it like this

public class CustomMissileDamageEntity : MissileDamageEntity {
        protected override void TriggerEnter(GameObject other)
        {
            if (Destroying)
                return;

            if (!other.GetComponent<IUnHittable>().IsNull())
                return;

            if (FindTargetHitBox(other, true, out DamageableHitBox target))
            {
                // Hit a locking target
                if (explodeDistance <= 0f)
                {
                    // Don't store and check already hit hitboxes
                    ApplyDamageTo(target);
                }
                else
                {
                    // Explode immediately when hit something
                    Explode();
                }
                // Don't mark it as destroyed, continues its ability to applies damage
                return;
            }

            // Must hit walls or grounds to explode
            // So if it hit item drop, character, building, harvestable and other ignore raycasting objects, it won't explode
            if (!CurrentGameInstance.IsDamageableLayer(other.layer) &&
                !CurrentGameInstance.IgnoreRaycastLayersValues.Contains(other.layer))
            {
                if (explodeDistance > 0f)
                {
                    // Explode immediately when hit something
                    Explode();
                }
                // Don't mark it as destroyed, continues its ability to applies damage
                return;
            }
        }

        protected override bool FindAndApplyDamage(GameObject other, bool checkLockingTarget, HashSet<uint> alreadyHitObjects)
        {
            // Don't store and check already hit hitboxes
            if (FindTargetHitBox(other, checkLockingTarget, out DamageableHitBox target))
            {
                ApplyDamageTo(target);
                return true;
            }
            return false;
        }
}
Niinra commented 8 months ago

@darkkriteus Thank you very much, I will send you my email, although I already understood how the script works, also thank you very much @insthync <3