Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

[RELEASED] Emerald AI 3.2 (New Sound Detection) - The Ultimate Universal AAA Quality AI Solution

Discussion in 'Assets and Asset Store' started by BHS, Jun 26, 2015.

  1. Mojo-Game-Studio

    Mojo-Game-Studio

    Joined:
    Sep 18, 2015
    Posts:
    111
    Is there a way I can change at runtime the faction relationship on the AI? So if it's default setting were say 'npc_faction' = enemy, can I just get the Emerald_AI component and set this value to 'Friendly'? if so which member?
     
  2. llJIMBOBll

    llJIMBOBll

    Joined:
    Aug 23, 2014
    Posts:
    578
    I’m not at my pc now so can’t be sure if exact but it’s something like emeraldai.behavourtype = behavourtype.Sometypehere ... It should show a list when u stat typing the code. And switch emeraldai to your param
     
  3. SickaGames1

    SickaGames1

    Joined:
    Jan 15, 2018
    Posts:
    1,269
    @BHS how are you looking on the 2.2 release?
     
  4. RonnyDance

    RonnyDance

    Joined:
    Aug 17, 2015
    Posts:
    557
    Not with the current version. This feature will come with the 2.3 release.
     
  5. BHS

    BHS

    Joined:
    Dec 21, 2009
    Posts:
    4,760
    Very strange, I'm not sure why I have been unable to recreate it. I know there was another user who experienced this issue on Windows so I'm not sure what's causing it. I tried both 2018.2.12 and 2018.2.13 and still could not recreate the issue.

    If you're willing to try something, this may offer a solution, but I cannot say for sure. I know it has to do with the title portion of each part of the Emerald AI editors.

    In the EmeraldAISetupManager try replacing this:
    Code (CSharp):
    1. EditorGUILayout.LabelField(new GUIContent(SettingsIcon), style, GUILayout.ExpandWidth(true), GUILayout.Height(32));
    2.         EditorGUILayout.LabelField("Emerald AI Setup Manager - v1.0", style, GUILayout.ExpandWidth(true));
    With this:
    Code (CSharp):
    1. EditorGUILayout.LabelField(new GUIContent(SettingsIcon), style, GUILayout.Height(32));
    2.         EditorGUILayout.LabelField("Emerald AI Setup Manager - v1.0", style);


    I can look into adding an event for the alert state. I agree, I will look into dynamic events for the 2.3 update.




    In your custom code that damage the building, you will need to check when the build's health reaches 0. When this happens you need to call ResetAI() to set the AI back to its default state or SearchForTarget() to look for the next target.


    I don't believe this is possible. If you need more complex shapes, use multiple Nav Mesh Obstacles to match the shape of your instantiated objects.


    This isn't currently possible, but I will see if I have time to add it to the 2.2 update.


    About 3 weeks.
     
    lawsochi and Mojo-Game-Studio like this.
  6. zKici

    zKici

    Joined:
    Feb 12, 2014
    Posts:
    438
    damn another 3 weeks i wait
     
  7. AngelBeatsZzz

    AngelBeatsZzz

    Joined:
    Nov 24, 2017
    Posts:
    239
    I use "EmeraldObjectPool.Spawn()" and "EmeraldObjectPool.Despawn()" to generate AI, but the AI that is generated after the AI dies will remain dead. How to reset the state of AI when Spawn?
     
  8. PlainStudios

    PlainStudios

    Joined:
    Sep 9, 2013
    Posts:
    18
    I have a problem with the way my AI are moving and attacking . When my AI sees me it runs away so it can make a turn and begins to chase me . When the AI reaches me it plays the attack animation but half of the times the hits don't do any damage .
     
  9. Mojo-Game-Studio

    Mojo-Game-Studio

    Joined:
    Sep 18, 2015
    Posts:
    111
    Having etup some Navmesh obstacles, I have a problem with the AI moving around them/ Instead of turning to avoid an obstacle they 'slide' sideways until the object isn't in front of them anymore then continue walking past it, Is there some kind of setting that causes this?
     
  10. Rahd

    Rahd

    Joined:
    May 30, 2014
    Posts:
    324
    Emerald AI integration to covershooter
    1- play with tags and layer for best results example : player should be tagged to player or add the enemy AI of cover shooter with the same tag or other like this ....
    2- find the Emerald_AI script and change the public void DamagePlayer() to this ...
    public void DamagePlayer(){




    if ( CurrentTarget.gameObject == this.gameObject)
    return;

    var shield = BulletShield.Get(CurrentTarget.gameObject);

    if (shield != null)

    return;

    var part = CurrentTarget.GetComponent<BodyPartHealth>();
    var obj = (part == null || part.Target == null) ? CurrentTarget.gameObject : part.Target.gameObject;



    var normal = (CurrentTarget.position - obj.transform.position).normalized;

    HitType type;



    var hit = new Hit(transform.position, normal, CurrentDamageAmount, this.gameObject, CurrentTarget.gameObject, HitType.Machete, DamageResponseWaitTime);
    CurrentTarget.SendMessage("OnHit", hit, SendMessageOptions.DontRequireReceiver);


    }

    done thats it ...
    covershooter is the most easy asset to work with in along time and i highly recommend Emerald AI for mobile if you gonna have some monsters or animals ... it's really simple like stupid simple and i really like it since it's fast for mobile.
    i will update the player side on the covershooter forum later..
    a big thanks for all the devs that worked on Emerald AI
     
    Last edited: Oct 30, 2018
  11. Rahd

    Rahd

    Joined:
    May 30, 2014
    Posts:
    324
    it should be working now with covershooter plugin

    dear dev of emerald-ai please message EduardasFunka.
    so i can share the code with both of you . since i can't just share the code online for non paying users .
    cheers
    PS : covershooter devs are out for the holidays ... i will remind him
     
  12. BHS

    BHS

    Joined:
    Dec 21, 2009
    Posts:
    4,760
    Before an AI is respawned, you need to call YourEmeraldAIReference.ResetAI(); so the AI's settings are reset back to their default values.


    If you are referring to the AI running away from the player before running towards its target, this will be fixed with version 2.2. As for the attack, Emerald AI uses multiple attack values to cause damage. Ensure that each attack you are using has a damage value.


    Strange, the AI should avoid the Navmesh Obstacles. Is Carve check on the Navmesh Obstacles?


    Awesome, thanks for sharing and it's great to hear you're enjoying Emerald AI.

    I will reach out to the developers to get proper supported added for Emerald AI when I get the chance.
     
    Rahd likes this.
  13. p_hergott

    p_hergott

    Joined:
    May 7, 2018
    Posts:
    414
    For next version is there going to be critical hit boxes? Like headshots?
     
  14. p_hergott

    p_hergott

    Joined:
    May 7, 2018
    Posts:
    414
    In the script, for player weapon. Its wanting the mouse button down for input, would it be easy to change that to any other input name? (Im using a controller)
     
  15. llJIMBOBll

    llJIMBOBll

    Joined:
    Aug 23, 2014
    Posts:
    578
    I'm using Emerald and ''Dismember'' together, this is so can have ragdoll and per limb damage, i've edited both scripts to work together. I would recommend something like this for new version, if you have ragdolls have a script on each limb to send the damage to Emerald main script and remove damage, with this you can have multiplier for per limb, like 2x headshots damage.

    Looking forward to new update, awesome work man
     
    Rahd likes this.
  16. paulojsam

    paulojsam

    Joined:
    Jul 2, 2012
    Posts:
    573
    im trying to use rfps and emerald, but i cant get it to animate even if it hunts and harms the player. ive tried a bunch of stuff any ideias please?
     
  17. paulojsam

    paulojsam

    Joined:
    Jul 2, 2012
    Posts:
    573
  18. magique

    magique

    Joined:
    May 2, 2014
    Posts:
    4,030
    Your problem is a bit vague. RFPS itself has nothing to do with whether or not an Emerald AI will animate so I wonder if you think the integration is somehow wrong and causing your issue. Did you follow the integration instructions here at the following link?

    https://docs.google.com/document/d/1QGSEdc2-6bks22KIelYlBw_601uHce2BVLM3QTq5axg/edit#!

    In any case, try to be more specific of what your problem is because it's not really clear to me.
     
    Last edited: Oct 31, 2018
  19. Vampyr_Engel

    Vampyr_Engel

    Joined:
    Dec 17, 2014
    Posts:
    449
    I gather that your package integrates with UFPS and Opsive UFPS 2 So my question is can this enable A.I to walk/run and Drive On A Sphere and can it make a.i with vehicles and also let the player control his A.I via the keyboard as well as make the A.I control Air and Spacecraft as I have bought UFPS and UFPS2 and I am thinking of buying a decent A.I system
     
    Last edited: Oct 31, 2018
  20. AngelBeatsZzz

    AngelBeatsZzz

    Joined:
    Nov 24, 2017
    Posts:
    239
    I use "emerald_AI.SetFollowerPet()" to get the pet to a place, then I want it to return to Wander state.

    I have set Wander Type to Dynamic and successfully get the pet to the target point, then I try use "emerald_AI.SetFollowerPet(null)" to let the pet back to wander state, but the pet does not move. How can I get it to start wander?
     
  21. joeyether40

    joeyether40

    Joined:
    Jan 26, 2018
    Posts:
    20
    hey I am using Zerk's Animal Ragdoll tool from the unity store. Will I be able to use that in conjunction with 2.2 when it comes. I want a ragdoll death on my animals so I can carry them and have them look dead. I would perefr just to enable the ragdoll on death instead of instantiating a ragdoll prefab. when I try to build a animal with a ragdoll on it with emerald ai , the animations are very shaky (otherwise it still works . Do you have any suggestions as to why tis happens ?
     
  22. PlainStudios

    PlainStudios

    Joined:
    Sep 9, 2013
    Posts:
    18
    Has anybody had the problem with UFPS where the character can just run over AI . I've had this problem for a while now and I can't find any info as to why this happens . I tried contacting the UFPS team and using forums but found no fix .
     
  23. pushingpandas

    pushingpandas

    Joined:
    Jan 12, 2013
    Posts:
    1,419
    Hello, anybody know to to make it working with VR WeaponInteractor?
    Its so frustrating :(

    Iam getting following error when I shot at the Skeleton from demo.

    Failed to call function Damage of class Emerald_AI
    Calling function Damage with 1 parameter but the function requires 2.
    UnityEngine.Component:SendMessageUpwards(String, Object, SendMessageOptions)
    VRWeaponInteractor.<ApplyDamage>c__Iterator0:MoveNext() (at Assets/VRWeaponInteractor/Scripts/Weapons/VRPhysicalBullet.cs:124)
    UnityEngine.MonoBehaviour:StartCoroutine(IEnumerator)
    VRWeaponInteractor.VRPhysicalBullet:Update() (at Assets/VRWeaponInteractor/Scripts/Weapons/VRPhysicalBullet.cs:113)




    Here the VRPhysicalBullet.cs


    //========= Copyright 2018, Sam Tague, All rights reserved. ===================
    //
    // Moves an object until it hits a target, at which time it calls the Damage(float) method on all scripts on the hit object
    // Can also home in on targets and "detonate" when in close proximity.
    //
    //=============================================================================
    #if VRInteraction
    using UnityEngine;
    using System.Collections;
    using VRInteraction;

    namespace VRWeaponInteractor
    {
    public class VRPhysicalBullet : MonoBehaviour
    {
    public Transform bulletRoot;
    public float speed = 100f;
    public float maxLifeTime = 3;
    public float timeToResetAfterHit = 1f;

    private bool _active;
    private Coroutine _maxLifeCo;
    private float _currentSpeed = -1f;

    private string _damageMethodName = "Damage";
    private LayerMask _layerMask;
    private int _damage = 16;
    private float _bulletForce = 100;
    private GameObject _bulletDecalPrefab;
    private TrailRenderer _trail;
    private LineRenderer _line;
    private Renderer[] _childRenderers;

    public string damageMethodName
    {
    set { _damageMethodName = value; }
    }
    public LayerMask layerMask
    {
    set { _layerMask = value; }
    }
    public int damage
    {
    get { return _damage; }
    set { _damage = value; }
    }
    public float bulletForce
    {
    set { _bulletForce = value; }
    }
    public GameObject bulletDecalPrefab
    {
    set { _bulletDecalPrefab = value; }
    }
    public LineRenderer getLine
    {
    get
    {
    if (_line == null) _line = bulletRoot.GetComponentInChildren<LineRenderer>();
    return _line;
    }
    }
    public TrailRenderer getTrail
    {
    get
    {
    if (_trail == null) _trail = bulletRoot.GetComponentInChildren<TrailRenderer>();
    return _trail;
    }
    }
    public Renderer[] getChildRenderers
    {
    get
    {
    if (_childRenderers == null)
    _childRenderers = bulletRoot.GetComponentsInChildren<Renderer>();
    return _childRenderers;
    }
    }

    void OnEnable()
    {
    if (bulletRoot == null) bulletRoot = transform;
    StopAllCoroutines();
    _active = true;
    _currentSpeed = speed;
    ToggleRenderers(true);
    if (getLine != null)
    {
    getLine.SetPositions(new Vector3[0]);
    getLine.enabled = true;
    }
    if (getTrail != null)
    {
    getTrail.Clear();
    getTrail.enabled = true;
    }
    _maxLifeCo = StartCoroutine(MaxLife());
    }

    void Update()
    {
    if (!_active) return;

    RaycastHit hit;
    bool hitSomething = false;
    hitSomething = Physics.Raycast(bulletRoot.position, bulletRoot.forward, out hit, _currentSpeed * Time.deltaTime, _layerMask.value);

    if (hitSomething)
    {
    if (getLine != null) getLine.SetPositions(new Vector3[] {bulletRoot.position, hit.point});
    bulletRoot.position = hit.point;
    StartCoroutine(ApplyDamage(hit));
    } else
    {
    Vector3 oldPosition = bulletRoot.position;
    bulletRoot.Translate(Vector3.forward * Time.deltaTime * _currentSpeed);
    if (getLine != null) getLine.SetPositions(new Vector3[] {oldPosition, bulletRoot.position});
    }
    }

    IEnumerator ApplyDamage(RaycastHit hit)
    {
    hit.collider.SendMessageUpwards(_damageMethodName, _damage, SendMessageOptions.DontRequireReceiver);

    VREvent.Send("ApplyDamage", new object[] {this, hit});

    VRGunHandler.ApplyDecal(_bulletDecalPrefab, hit);

    ToggleRenderers(false);
    if (getLine != null) getLine.enabled = false;

    _active = false;

    if (_bulletForce > 0.001f)
    {
    yield return null;
    if (hit.rigidbody != null) hit.rigidbody.AddForceAtPosition(bulletRoot.forward * _bulletForce, hit.point, ForceMode.Impulse);
    }

    PoolingManager.instance.DestroyPoolObject(bulletRoot.gameObject, timeToResetAfterHit);

    if (_maxLifeCo != null) StopCoroutine(_maxLifeCo);

    yield return null;
    }

    IEnumerator MaxLife()
    {
    yield return new WaitForSeconds(maxLifeTime);
    PoolingManager.instance.DestroyPoolObject(bulletRoot.gameObject);
    }

    void ToggleRenderers(bool show)
    {
    foreach(Renderer renderer in getChildRenderers)
    {
    if (renderer.GetComponent<DontHide>() != null) continue;
    renderer.enabled = show;
    }
    }
    }
    }
    #endif
     
  24. BHS

    BHS

    Joined:
    Dec 21, 2009
    Posts:
    4,760
    I'm looking into a way to easily implement this for version 2.2 as long as it doesn't interfere with my deadline for it.


    Thanks! Cool to hear that you were able to implement dismember and Emerald AI together. I am looking into a way to add support for limb damage. However, I don't want it to cause any delay to my deadline. So, depending on how difficult it ends up being, it may have to wait until the 2.3 update.


    UFPS integration is currently possible with this tutorial: https://docs.google.com/document/d/...uHce2BVLM3QTq5axg/edit#heading=h.g90cyocltt35

    UCC support is coming soon. I haven't quite had the time to do an integration tutorial.

    As for your other questions, Emerald AI agents cannot move on spheres or drive vehicles.The integration support covers damaging and interacting with the player. Emerald AI agents use Unity NavMesh to navigate a scene. This requires a scene to be baked with Unity's NavMesh.


    You may need to adjust the AI's StartingPosition variable, however, this variable is private in Emerald AI. So, you will have to make it public. When setting your AI back to its wander state, set the AI's StartingPosition to its current position. The StartingPosition is what is used to generate dynamic waypoints.


    Hey there,

    Yes you will. Emerald AI automatically disables the ragdoll components on start and activates them when an AI dies. There is no limit to how many components can be used. The process is also seamless with the AI's current animation. Ragdoll isn't supported with the current version of Emerald AI, which is most likely when you're having issues with it.


    Have you tried to increase your AI's stopping distance? This usually happens because the AI tries to go to close to the player's actual position rather than stopping before it.


    Where it says IEnumerator ApplyDamage(RaycastHit hit)

    Change:
    Code (CSharp):
    1. hit.collider.SendMessageUpwards(_damageMethodName, _damage, SendMessageOptions.DontRequireReceiver);
    To:
    Code (CSharp):
    1. if (hit.collider.GetComponent<Emerald_AI>() != null)
    2. {
    3.    hit.collider.GetComponent<Emerald_AI>().Damage((int)_damage, Emerald_AI.TargetType.Player)
    4. }
    However, this is just a guess as I'm not familiar with your code or what it's dependent on. Send Message upwards doesn't work because Emerald AI's Damage function requires 2 parameters and Send Message can only handle one. If your hit.collider is referencing the currently hit target, then it should work correctly.
     
  25. Vampyr_Engel

    Vampyr_Engel

    Joined:
    Dec 17, 2014
    Posts:
    449

    OK thank you
     
  26. jeromeWork

    jeromeWork

    Joined:
    Sep 1, 2015
    Posts:
    427
    Is it possible to decouple (turn off) various parts of the system?

    I'm trying to integrate Emerald AI with another asset that already takes care of health/damage, so I just want EmeraldAI to move the NPCs around and play attack animations when in combat range.

    Is it an all or nothing solution, or is there a chance of being able to turn parts of it off?
     
  27. pushingpandas

    pushingpandas

    Joined:
    Jan 12, 2013
    Posts:
    1,419
    [QUOTE="BHS]


    Where it says IEnumerator ApplyDamage(RaycastHit hit)

    Change:
    Code (CSharp):
    1. hit.collider.SendMessageUpwards(_damageMethodName, _damage, SendMessageOptions.DontRequireReceiver);
    To:
    Code (CSharp):
    1. if (hit.collider.GetComponent<Emerald_AI>() != null)
    2. {
    3.    hit.collider.GetComponent<Emerald_AI>().Damage((int)_damage, Emerald_AI.TargetType.Player)
    4. }
    However, this is just a guess as I'm not familiar with your code or what it's dependent on. Send Message upwards doesn't work because Emerald AI's Damage function requires 2 parameters and Send Message can only handle one. If your hit.collider is referencing the currently hit target, then it should work correctly.[/QUOTE]

    Thank you. Sadly it does not work :( now I getting other reds

    Failed to call function Damage of class Emerald_AI
    Calling function Damage with 1 parameter but the function requires 2.
    UnityEngine.Component:SendMessageUpwards(String, Object, SendMessageOptions)
    VRWeaponInteractor.VRGunHandler:FireRaycast() (at Assets/VRWeaponInteractor/Scripts/Weapons/VRGunHandler.cs:794)
    VRWeaponInteractor.VRGunHandler:Shoot() (at Assets/VRWeaponInteractor/Scripts/Weapons/VRGunHandler.cs:505)
    VRWeaponInteractor.VRGunHandler:Step() (at Assets/VRWeaponInteractor/Scripts/Weapons/VRGunHandler.cs:334)
    VRInteraction.VRInteractableItem:FixedUpdate() (at Assets/VRInteraction/Scripts/VRInteractableItem.cs:153)
     
  28. AndyNeoman

    AndyNeoman

    Joined:
    Sep 28, 2014
    Posts:
    938
    Hi @BHS, Im struggling setting up the African cartoon gorilla from the asset store to use emerald. It seems the animations are all as one track not individual fbx files. Any advice on how to set this up with Emerald?
     
  29. joeyether40

    joeyether40

    Joined:
    Jan 26, 2018
    Posts:
    20
     
  30. BHS

    BHS

    Joined:
    Dec 21, 2009
    Posts:
    4,760
    You cannot turn off any portion of Emerald AI. However, you can change how damage is called by customizing the function that's called for player damage within the DamagePlayer function and AI damage within the Damage function. This would of course require some modifications to the system on your end to change how the damage is handled.


     
  31. AndyNeoman

    AndyNeoman

    Joined:
    Sep 28, 2014
    Posts:
    938
    Hi @BHS could you advise on using emerald with animals with Animations all on one take as above with the gorilla? Also my animals are running through each other as emerald changes the rigid bodies to knematic is there a solution to this?

    Thanks,

    Andy
     
  32. cheesee09

    cheesee09

    Joined:
    Mar 30, 2018
    Posts:
    35
    Can you help me in this one when my invector player blocks emerald ai don't do damage or reduce my player stamina when blocking. I even lowered the defense rate and range and still it doesn't do damage or reduce my stamina
     
  33. Deckard_89

    Deckard_89

    Joined:
    Feb 4, 2016
    Posts:
    315
    The only solution I can think of for this is to import the gorilla with animations into your animation software, find which frames each animation is at, then export these frames as separate animations (in separate fbx files).
    There may be a quicker way, but this is what I would do.
     
    AndyNeoman likes this.
  34. AndyNeoman

    AndyNeoman

    Joined:
    Sep 28, 2014
    Posts:
    938
    I've reverted to ICE for that animal currently as I use both systems in my game but at least if I know they cant be used in emerald I can bear that in mind with future characters. The Gorilla has about 60 animations and it is not really my skillset. I will mention it to the creator to see if they can release animations seperately.
     
  35. RealAspireGames

    RealAspireGames

    Joined:
    Dec 24, 2013
    Posts:
    265
    How would I make the A.I chase the player on start?
     
  36. llJIMBOBll

    llJIMBOBll

    Joined:
    Aug 23, 2014
    Posts:
    578
    Code (CSharp):
    1. public Emerald_AI AI;
    2. public Transform Target;
    3.  
    4. void Start()
    5. {
    6. //Clear any Targets
    7. AI.CurrentTarget = null;
    8. AI.ClearTargets ();
    9.  
    10. // Search For Target or Set Target
    11. AI.SearchForTarget ();
    12. AI.CurrentTarget = Target;
    13. }
     
    hessex, Mark_01 and RealAspireGames like this.
  37. RealAspireGames

    RealAspireGames

    Joined:
    Dec 24, 2013
    Posts:
    265
    Thank you so much! :D
     
  38. tredpro

    tredpro

    Joined:
    Nov 18, 2013
    Posts:
    515
    Do you plan to add ecs to this and the other assets also?
     
  39. AndyNeoman

    AndyNeoman

    Joined:
    Sep 28, 2014
    Posts:
    938
    Morning all. Does anyway have a solution to stop the AI running through each other? I was hoping putting colliders on the lods/root object would do it but they still seem effected by the kinematic setting on the top object. (where Emerald script is)
     
  40. C_p_H

    C_p_H

    Joined:
    Nov 24, 2014
    Posts:
    153
    A while ago @BHS said: "AI can avoid each other by setting the quality of an AI's Avoidance Quality. The higher the quality, the more they will avoid each other. The next version will have AI avoid each other better using raycasts. Also, using NavMesh Obstacles on NavMesh Agents is something Unity said may cause undesirable affects."
    Hope this was helpful.
     
    AndyNeoman likes this.
  41. SickaGames1

    SickaGames1

    Joined:
    Jan 15, 2018
    Posts:
    1,269
    @BHS we are two weeks out from the update?
     
  42. BHS

    BHS

    Joined:
    Dec 21, 2009
    Posts:
    4,760
    Most animated assets should have their animations split up into individual animation clips. I feel if an asset isn't doing this then it's a limitation to the animated asset. The animation clips are needed so they can be individually applied to the Animator Controller. Is it not possible to create a new animation clip for each individual animation within the one take animation?

    AI avoidance is coming with version 2.2. This allows an AI to avoid AI as well as the player and objects. What is avoidable is controlled with a layer mask within the Emerald AI editor.


    I don't think I fully implemented blocking with Invector. When I get the chance, I will see if I can update the tutorial to include proper blocking for Invector.


    Yes, after version 2.3, I will look into this further.


    Yes, proper AI avoidance is coming with version 2.2. The NavMesh avoidance doesn't avoid other AI very well which is why I'm implementing a custom solution. The custom solution will allow AI as well as the player to be properly avoided.


    Probably more like 3 weeks from now.
     
    AndyNeoman likes this.
  43. jeromeWork

    jeromeWork

    Joined:
    Sep 1, 2015
    Posts:
    427
    I'm getting a massive 280ms spike on NPC death caused by Font.CacheFontForText when using AutoCreateHealthbar:



    If I switch on Customize Health Bar, the problem goes away.

    Thought you might want to know

    (Unity 2017.4.8)
     
  44. llJIMBOBll

    llJIMBOBll

    Joined:
    Aug 23, 2014
    Posts:
    578
    Here I made a simple version of my death script to use ragdoll death.

    First you will need to add ragdoll to your ai, and then set and resize the box collider to the ai's eyes


    then add this script to the same object as the emerald ai script.

    Code (CSharp):
    1. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    2. // MAKE SURE YOUR AI HAS BEEN SETUP AS A RAGDOLL, AND ALL RIGIDBODYS ARE SET TO 'ISKINEMATIC = TRUE AND USEGRAVITY = FALSE'
    3. ///
    4. // RESIZE EMERALD'S BOX COLLIDER TO 0.1,0.1,0.1 AND SET THE BOX COLLIDER TO THE AI EYES POSITION
    5. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    6.  
    7. using UnityEngine;
    8. using System.Collections;
    9. using UnityEngine.Events;
    10.  
    11.  
    12. public class EmeraldAI_RagdollDeath : MonoBehaviour
    13. {
    14.     [Header ("Componments")]
    15.     protected Emerald_AI m_EmeraldAI = null;
    16.     public Emerald_AI EmeraldAI {
    17.         get {
    18.             if (m_EmeraldAI == null)
    19.                 m_EmeraldAI = gameObject.GetComponent<Emerald_AI> ();
    20.             return m_EmeraldAI;
    21.         }
    22.     }
    23.     protected Animator m_animator = null;
    24.     public Animator animator {
    25.         get {
    26.             if (m_animator == null)
    27.                 m_animator = gameObject.GetComponent<Animator> ();
    28.             return m_animator;
    29.         }
    30.     }
    31.     protected AudioSource m_aSource = null;
    32.     public AudioSource aSource {
    33.         get {
    34.             if (m_aSource == null)
    35.                 m_aSource = gameObject.GetComponent<AudioSource> ();
    36.             return m_aSource;
    37.         }
    38.     }
    39.     protected BoxCollider m_boxCollider = null;
    40.     public BoxCollider boxCollider {
    41.         get {
    42.             if (m_boxCollider == null)
    43.                 m_boxCollider = gameObject.GetComponent<BoxCollider> ();
    44.             return m_boxCollider;
    45.         }
    46.     }
    47.     protected UnityEngine.AI.NavMeshAgent m_navMesh = null;
    48.     public UnityEngine.AI.NavMeshAgent navMesh {
    49.         get {
    50.             if (m_navMesh == null)
    51.                 m_navMesh = gameObject.GetComponent<UnityEngine.AI.NavMeshAgent> ();
    52.             return m_navMesh;
    53.         }
    54.     }
    55.  
    56.  
    57.     [Header ("Spawning")]
    58.     public bool UseSpawnEffect = false;
    59.     [Space (5f)]
    60.     public int SpawnEmoteID = -1;
    61.     public AudioClip SpawnSoundFX;
    62.     public GameObject SpawnEffectObject;
    63.  
    64.     [Header ("OnDeath")]
    65.     public Rigidbody[] myRBs;
    66.     public bool UseForceOnDeath = false;
    67.     public float RemoveBodyAfterTime = 30f;
    68.  
    69.     [Header ("Events")]
    70.     public UnityEvent OnDie = new UnityEvent ();
    71.  
    72.  
    73.     public void Awake ()
    74.     {
    75.         RegisterSpawnFX ();
    76.     }
    77.  
    78.     public void Start ()
    79.     {    
    80.         RegisterDeath ();
    81.  
    82.         // FIND RIGIDBODYS, ONLY NEED TO DO THIS ONCE, EVEN WITH POOLING.
    83.         myRBs = gameObject.GetComponentsInChildren<Rigidbody> ();
    84.     }
    85.  
    86.  
    87.     //////////////////////////////////////
    88.  
    89.     /// <summary>
    90.     /// Register Spawn Events with Emerald.
    91.     /// </summary>
    92.     public void RegisterSpawnFX ()
    93.     {
    94.         if (!UseSpawnEffect)
    95.             return;
    96.  
    97.         // PLAY ANIMATION
    98.         if (SpawnEmoteID != -1)
    99.             EmeraldAI.OnStartEvent.AddListener (EmoteSpawnFX);
    100.         // PLAY SOUNDS FX
    101.         if (SpawnSoundFX != null)
    102.             EmeraldAI.OnStartEvent.AddListener (SFXSpawnFX);
    103.         // CREATE SPAWN FX
    104.         if (SpawnEffectObject != null)
    105.             EmeraldAI.OnStartEvent.AddListener (EffectSpawnFX);        
    106.     }
    107.     public void EmoteSpawnFX ()
    108.     {
    109.         EmeraldAI.PlayEmoteAnimation (SpawnEmoteID);
    110.     }
    111.     public void SFXSpawnFX ()
    112.     {
    113.         EmeraldAI.PlaySound (SpawnSoundFX);
    114.     }
    115.     public void EffectSpawnFX ()
    116.     {
    117.         EmeraldAI.CreateEffect (SpawnEffectObject);
    118.     }
    119.  
    120.     //////////////////////////////////////
    121.  
    122.     /// <summary>
    123.     /// Registers the death.
    124.     /// </summary>
    125.     public void RegisterDeath ()
    126.     {
    127.         if (EmeraldAI != null)
    128.             EmeraldAI.DeathEvent.AddListener (OnDead);
    129.     }
    130.  
    131.     //////////////////////////////////////
    132.  
    133.     /// <summary>
    134.     /// Here you can add custom code to handle your AI's death.
    135.     /// </summary>
    136.     public void OnDead ()
    137.     {    
    138.         // DISABLE COMPONMENTS
    139.         this.gameObject.tag = "Flesh";
    140.         navMesh.enabled = false;
    141.         animator.enabled = false;
    142.         boxCollider.enabled = true; // WITH THIS DISABLED THE AI WILL FALL THRU THE FLOOR
    143.         EmeraldAI.enabled = false;
    144.  
    145.         // CONVERT TO RAGDOLL
    146.         if (myRBs.Length > 0) {
    147.             foreach (var item in myRBs) {
    148.                 item.isKinematic = false;
    149.                 item.useGravity = true;
    150.             }
    151.         }
    152.  
    153.  
    154.         // ADD FORCE EXAMPLE
    155.         if(UseForceOnDeath) {
    156.  
    157.             for (int i = 0; i < myRBs.Length; i++) {
    158.  
    159.                 int k = i;
    160.                 if(myRBs[k].gameObject.name == "Chest" || myRBs[k].gameObject.name == "chest" ||
    161.                     myRBs[k].gameObject.name == "Spine" || myRBs[k].gameObject.name == "spine" ||
    162.                     myRBs[k].gameObject.name == "Root" || myRBs[k].gameObject.name == "root" ||
    163.                     myRBs[k].gameObject.name == "Pelvis" || myRBs[k].gameObject.name == "pelvis") {
    164.  
    165.                     myRBs[k].AddForce (-transform.forward * 1000f);
    166.  
    167.                 } else {
    168.  
    169.                     // cant find any bones with names above. use a random body part to apply force
    170.                     int Random = UnityEngine.Random.Range (0, myRBs.Length);
    171.                     myRBs[Random].AddForce (-transform.forward * 1000f);
    172.  
    173.                 }
    174.             }            
    175.         }
    176.  
    177.  
    178.  
    179.         // YOUR CODE HERE //
    180.  
    181.  
    182.  
    183.         //....(EXAMPLE REMOVE BODY)
    184.         StopCoroutine (RemoveBody ());
    185.         StartCoroutine (RemoveBody ());
    186.  
    187.         // PLAY ANY EVENTS!
    188.         if (OnDie != null)
    189.             OnDie.Invoke ();
    190.     }
    191.  
    192.     // REMOVE THIS GAMEOBJECT
    193.     IEnumerator RemoveBody ()
    194.     {
    195.         yield return new WaitForSeconds (RemoveBodyAfterTime);
    196.  
    197.         Destroy (gameObject);
    198.     }
    199. }
     
    Mark_01 and jeromeWork like this.
  45. jeromeWork

    jeromeWork

    Joined:
    Sep 1, 2015
    Posts:
    427
    Very cool @llJIMBOBll Thanks for sharing.

    I'm new to EmeraldAi, can you explain the function of that small EmeraldAi box collider? I noticed it being added to agents, but couldn't see it mentioned in the docs. It's so small and doesn't made sense to use it instead of a capsule collider.
     
  46. llJIMBOBll

    llJIMBOBll

    Joined:
    Aug 23, 2014
    Posts:
    578
    Hi NP :D I'm not 100% sure but I think Emerald uses it to detect Targets. I've been using this setup for a while and haven't seen any strange behaviours as of yet. Just a suggestion of what worked for me :D You could probably even set it as your Ai's hips/root bone of the ragdoll, not testing this but don't see why not.
     
    jeromeWork likes this.
  47. jeromeWork

    jeromeWork

    Joined:
    Sep 1, 2015
    Posts:
    427
    @BHS Spoke too soon, spike suddenly reappeared, even with the custom UI.
    I've not turned on any of the text options so not sure why Font.CacheFontForText is being a problem


    I've removed all other canvases in the scene, the only thing that makes it go away is disabling the EmeraldAI health bar.

    Any ideas?

    edit: happens only on the AI's death (I assume as the UI bar is being faded out)
     
  48. cheesee09

    cheesee09

    Joined:
    Mar 30, 2018
    Posts:
    35
    @BHS how can emerald ai damage my Invector player when it is blocking? Emerald ai does not pass damage or even reduce my stamina
     
  49. AndyNeoman

    AndyNeoman

    Joined:
    Sep 28, 2014
    Posts:
    938
    I understand I just thought I would check if you had a solution. I will contact the the modeller. Thanks.

    If you have a preveiw of 2.2 i'd love to take a look my game is releasing this week, if not no problems i will just have to patch in when ready.
     
  50. AndyNeoman

    AndyNeoman

    Joined:
    Sep 28, 2014
    Posts:
    938
    Hi @BHS

    Im trying to setup the non AI for my other creatures and have successfully got them damaging emerald AI but cant seem to get the reverse. Should be quite simple, using a variation on the method I use to attack my player that has iceplayer component. My other animals have ICE on them but emerald is not attacking them. Does emarald not attempt to attack non AI tagged objects?

    public void DamageICE()
    {
    //Should find ICE component and inflict damage.

    if (CurrentTarget != null && CurrentTarget.GetComponent<ICECreatureControl>() != null)
    {
    CurrentTarget.GetComponent<ICECreatureControl>().ApplyDamage((float)CurrentDamageAmount);
    }
    }


    this is called from :- EmeraldAI()

    else if (TargetTypeRef == TargetType.NonAITarget)
    {
    Debug.Log("Ice could damage");
    //Custom code can be added here.
    if (TargetInView)
    {
    Debug.Log("ICE DAMAGE");
    DamageICE();
    }
    }
     
    Last edited: Nov 6, 2018