Invector Integration Tutorial - Black-Horizon-Studios/Emerald-AI GitHub Wiki

Invector Integration Tutorial

This tutorial will get Emerald AI working with Invector Third Person Controller. This will allow users to use Invector TPC to damage Emerald AI agents with melee damage, ranged damage, and explosive damage. It also allows Emerald AI agents to damage the Invector TPC player with block support. Note: This tutorial requires adding a few lines to a couple Invector TPC scripts and some basic understanding of minor editing of scripts.

In order for Emerald AI to work correctly, your scenes must be baked with Unity’s NavMesh. For a quick guide on how to do so, see Unity’s guide here: Baking your Scene with Unity's NavMesh. Your AI’s attack animations will also need to have Attack Animation Events for ranged/melee attacks. See the tutorial on doing this here: Attack Animation Event Tutorial

Setting up the AI Layer and Tags

Select any AI that you would like to be compatible with Invector. Set its Unity Tag and Unity Layer to Enemy.

Next, within the Emerald AI Editor, go to Detection & Tags>Tag & Factions>Tag Options and set your settings to the Emerald Unity Tag to Enemy. Set the Detection Layers to Enemy and Player.

Setting up the Shooter Manager (Important)

The Invector Shooter Manager needs to have the proper layer set in order for it to properly damage Emerald AI agents. With this tutorial, we are using the Enemy layer. This can be found on your Invector player. The options can become visible by pressing the Open Properties button.

Press the Damage Layers button and add the Enemy layer to the Layer Mask.

vMeleeManager Code Snippet

Find the vMeleeManager script within your projects and open it. This code should be added right below the line onDamageHit.Invoke(hitInfo);

//Emerald AI Damage
if (hitInfo.targetCollider.gameObject.GetComponent<EmeraldAI.EmeraldAISystem>())
{                 
   hitInfo.targetCollider.gameObject.GetComponent<EmeraldAI.EmeraldAISystem>().Damage((int)hitInfo.attackObject.damage.damageValue, EmeraldAI.EmeraldAISystem.TargetType.Player, transform, 400);
}

vProjectileControl Code Snippet

Find the vProjectileControl script within your projects and open it. This code should be added right below the first instance of onCastCollider.Invoke(hitInfo); and damage.damageValue = maxDamage;

//Emerald AI Damage
if (hitInfo.collider.gameObject.GetComponent<EmeraldAI.EmeraldAISystem>() != null)
{                       
   hitInfo.collider.gameObject.GetComponent<EmeraldAI.EmeraldAISystem>().Damage((int)damage.damageValue, EmeraldAI.EmeraldAISystem.TargetType.Player);
}

vExplosive Code Snippet

Find the vExplosive script within your projects and open it. This code should be added right below the line colliders[i].gameObject.ApplyDamage(_damage, null);

//Emerald AI Damage
if (colliders[i].gameObject.GetComponent<EmeraldAI.EmeraldAISystem>() != null)
{                      
   colliders[i].gameObject.GetComponent<EmeraldAI.EmeraldAISystem>().Damage((int)damage.damageValue, EmeraldAI.EmeraldAISystem.TargetType.Player);
}

EmeraldAIPlayerDamage Code Snippet

Find the EmeraldAIPlayerDamage script within your projects and open it. This code should replace the current DamageInvectorPlayer function code as it has been updated to allow blocking.

void DamageInvectorPlayer (int DamageAmount, Transform Target)
        {
            if (GetComponent<Invector.vCharacterController.vCharacter>())
            {
                //Applies damage to Invector and allows its melee weapons to block incoming Emerald AI damage.
                if (GetComponent<Invector.vCharacterController.vMeleeCombatInput>().meleeManager != null)
                {
                    var PlayerInput = GetComponent<Invector.vCharacterController.vMeleeCombatInput>();
                    var MeleeManager = GetComponent<Invector.vCharacterController.vMeleeCombatInput>().meleeManager;

                    if (PlayerInput.isBlocking)
                    {
                        var _Damage = new Invector.vDamage(DamageAmount);
                        var DamageReduction = MeleeManager != null ? MeleeManager.GetDefenseRate() : 0;
                        if (DamageReduction > 0)
                            _Damage.ReduceDamage(DamageReduction);
                        MeleeManager.OnDefense();
                        _Damage.reaction_id = MeleeManager.GetDefenseRecoilID();
                        _Damage.sender = Target;
                        _Damage.hitPosition = Target.position;
                        GetComponent<Invector.vCharacterController.vCharacter>().TakeDamage(_Damage);
                    }
                    else
                    {
                        var _Damage = new Invector.vDamage(DamageAmount);
                        _Damage.sender = Target;
                        _Damage.hitPosition = Target.position;
                        GetComponent<Invector.vCharacterController.vCharacter>().TakeDamage(_Damage);
                    }
                }
                //If no Melee Manager is found, cause unreduced damage.
                else
                {
                    var _Damage = new Invector.vDamage(DamageAmount);
                    _Damage.sender = Target;
                    _Damage.hitPosition = Target.position;
                    GetComponent<Invector.vCharacterController.vCharacter>().TakeDamage(_Damage);
                }

            }
        }

Lastly, ensure that the DamageInvectorPlayer(int DamageAmount, Transform Target) function we just created is being called within the SendPlayerDamage function of EmeraldAIPlayerDamage script. Without this, the player cannot be damaged as the DamageInvectorPlayer function is never called.

This concludes the Invector TPC integration tutorial, if something isn’t working correctly, go through the tutorial again to ensure nothing was missed. If you’re having issues with implementing Invector TPC, and you’ve gone through the tutorial video, support can be provided at: [email protected]