Search Unity

Tactical Shooter AI - Asset Store Pack

Discussion in 'Works In Progress - Archive' started by squared55, Mar 2, 2015.

  1. pierre92nicot

    pierre92nicot

    Joined:
    Aug 21, 2018
    Posts:
    57
    Hi,
    My agents have their legs "shaking" when they are aiming, did you know why ?
    Have you some custom behaviour script to share ?
    I can not get the Adjust Priority script working. If I add an Adjust Priority script to all team 1 members, and set the team number to look for to 2, all the team 2 members will stop seing team1 members and will stay at idle.
    Thanks.
     
  2. squared55

    squared55

    Joined:
    Aug 28, 2012
    Posts:
    1,818
    Hello,

    The leg shaking behavior is something that got introduced in one of the more recent versions of Unity, I don't know which. In any case, lowering the Obstacle Avoidance "Quality" in the navmesh agent should solve the issue.

    OA.png

    Unless I'm missing something about your set up, you can just change the priority of an agent in their Target Script. The Adjust priority script is for dynamically increasing the priority of a target script when a specific team is nearby. Otherwise, it gets reduced (potentially to 0). For instance, you may want the agents to only target an explosive barrel when an enemy is standing near it.

    On a side note, the "team numbers to look for" is an array, not a single value. That means the first number is the number of teams to look for, and then the subsequent entries contain the actual team numbers.
     
    Last edited: Nov 4, 2018
  3. pierre92nicot

    pierre92nicot

    Joined:
    Aug 21, 2018
    Posts:
    57
    Hi, I want team 1 to target team 2 members who are the closest.
    Team 1 members seems to pick up their target randomly, even if there is team 2 members close, they will target far away target.
     
  4. squared55

    squared55

    Joined:
    Aug 28, 2012
    Posts:
    1,818
    Each agent is given a score based on it's distance, which is then divided by it's priority. Agents will first choose a target which they have a clear line of sight to, and if they have line of sight to more than one target, then the target with the lowest score (usually the closest) will be targeted. A different target

    There's probably a collider blocking the agent's vision (this could even be a part of the target's body that's on a physics layer that the agent can't see through, as specified in the AI Controller's layermask). Or maybe the more distant agents have a higher priority.

    Furthermore, agents will only switch targets once every few seconds (determined by a variable in the target script).

    If you want the agent to choose the closest target regardless of whether or not it has Line of Sight, you will have to go to line 355 of the TargetScript (this if statement)

    Code (CSharp):
    1. if (enemyScoreCheckingNow < currentEnemyScore || currentEnemyScore == 0 || !foundTargetWithLoS)
    and replace the above line of code with:

    Code (CSharp):
    1.  
    2. if (enemyScoreCheckingNow < currentEnemyScore || currentEnemyScore < 0)
    And do the same with the if statement on line 366.
     
    Last edited: Nov 5, 2018
  5. pierre92nicot

    pierre92nicot

    Joined:
    Aug 21, 2018
    Posts:
    57
    Thanks you, I will take a look at it.
     
  6. nipu212

    nipu212

    Joined:
    Jul 9, 2017
    Posts:
    2
    Hi,
    My ai agents aren't throwing grenade properly. Grenades immediately drop when thrown or go to right side of the agents but never reach to the target. Can you tell me why?
    Thanks.
     
  7. desertGhost_

    desertGhost_

    Joined:
    Apr 12, 2018
    Posts:
    260
    Hi,

    If I spawn cover nodes at run-time will the Controller Script add them to the static cover map? If not, how would I go about adding them to the static cover map at run-time? Dynamic cover is simply too resource intensive for use in our game.

    Thank you.
     
    Last edited: Nov 17, 2018
  8. nipu212

    nipu212

    Joined:
    Jul 9, 2017
    Posts:
    2
    Somehow i edited the GrenadeScript without even realizing it. It's all working fine now. Thanks
     
  9. squared55

    squared55

    Joined:
    Aug 28, 2012
    Posts:
    1,818
    Glad to hear things are working.

    The cover nodes positions are added to the Controller Script via the Controller Script's Awake function. There's no built-in way to neatly add new nodes after the controller is created by default, so you'd need to add a method to the Controller Script which can update the list at runtime.

    Here's a quick recompile method. Place it in the Controller Script and call it at runtime. Let me know if it works and then we can look at a higher performance option (assuming you don't get to it first!).

    Code (CSharp):
    1.         public void GetNewCoverList()
    2.         {
    3.             GameObject[] tempCoverNodeObjects = GameObject.FindGameObjectsWithTag("Cover");
    4.             List<TacticalAI.CoverNodeScript> tempScripsList = new List<TacticalAI.CoverNodeScript>();
    5.             for (int i = 0; i < tempCoverNodeObjects.Length; i++)
    6.             {
    7.                 tempScripsList.Add(tempCoverNodeObjects[i].GetComponent<TacticalAI.CoverNodeScript>());
    8.             }
    9.             coverNodeScripts = tempScripsList.ToArray();
    10.         }
     
  10. desertGhost_

    desertGhost_

    Joined:
    Apr 12, 2018
    Posts:
    260
    Thank you for the suggestion. For performance reasons I ended up doing the following:
    • I changed coverNodeScripts array in the ControllerScript to being a List and fixed any compilation errors that resulted.
    • I commented out the initialization code for the coverNodeScripts in the Awake function of the ControllerScript.
    • I added a RegisterCover function and an UnregisterCover function to the ControllerScript.
    • In the CoverNodeScript, I added OnEnable function that registers the CoverNode with the ControllerScript instance.
    • In the CoverNodeScript, I added OnDisable function that de-registers the CoverNode with the ControllerScript.
    This allows cover nodes to add/remove themselves at run-time as they are spawned / despawned.

    Here is the new code I wrote for reference:
    Code (CSharp):
    1. //added  to controller script
    2. public void RegisterCover(CoverNodeScript cover)
    3. {
    4.     coverNodeScripts.Add(cover);
    5. }
    6.  
    7. public void UnregisterCover(CoverNodeScript cover)
    8. {
    9.     coverNodeScripts.Remove(cover);
    10. }
    11.  
    12. //added to cover node
    13. void OnEnable()
    14. {
    15.     if (ControllerScript.currentController != null)
    16.     {
    17.         ControllerScript.currentController.RegisterCover(this);
    18.     }
    19. }
    20.  
    21. private void OnDisable()
    22. {
    23.     if (ControllerScript.currentController != null)
    24.     {
    25.         ControllerScript.currentController.UnregisterCover(this);
    26.     }
    27. }
    The only thing this code requires to work is that the ControllerScript instance is created before any cover nodes.
     
  11. unity_4WJJK75q1-ocTg

    unity_4WJJK75q1-ocTg

    Joined:
    Oct 6, 2018
    Posts:
    10
    Hi, i recently tried the package on an empty map with a plane as the ground as 4 cubes reshaped like rectangles at acts as walls on 4 sides, and another cube on the center that acts as the test target. i followed a youtube tutorial on a Quick Setup method but i wasn't successful in doing so. The reason is that i placed the generated Ragdoll Agent on a corner but it spawn on the farther side outside the plane's dimension. i have not changed any other parameters and just followed whatever was on the tutorial. i didn't also add any additional eye and bullet spawn objects as its already in the prefab found on the current package version. another thing worth nothing, is i can't make the forward vector (blue arrow) rotate on where the ragdoll/model is facing.

    below is a screenshot on how things is happening:

    On #1 is where the original model/ragdoll was placed and even where the Agent generated the model. #2 is where the agent spawns when launching the game.



    These are the (default) script parameters for the Agent Model of which are all untouched.



    And this is what my basic map looks like, literally basic.


    I know i have not provided sufficient information as i currently lack knowledge in using the package. i did read the documentation provided but i would rather straight forward tutorials like videos which i can't find on youtube or google other that that from Squared55's channel.
     
  12. squared55

    squared55

    Joined:
    Aug 28, 2012
    Posts:
    1,818

    Hello,

    Some questions:

    1) Have you baked a navmesh for this map? If so, is it on the map?

    2) When you placed the agent, did you move the entire agent (ie: the object with all the scripts on it) or just the ragdoll that is parented to this object? If they don't start in the same place, the ragdoll can swing around the base object like something on the end of a stick.

    3) Do the demo agents work in this scene?

    Also, I recommend placing a cover node in the scene, as scenes without any can sometimes produce unintended behavior.

    Hopefully this helps.
     
  13. unity_4WJJK75q1-ocTg

    unity_4WJJK75q1-ocTg

    Joined:
    Oct 6, 2018
    Posts:
    10

    1. Yes i have baked a navmesh, the plane and all other elements (except the cube target and the ragdoll) are ticked as static.

    2. I just dragged and dropped the agent prefab from the \Tactical Shooter AI\Tactical AI\Tactical AI Prefabs\Agents folder, placed it in the map and have not moved it prior to that.

    3. No i haven't tried the demo agents yet. where can they be found?

    Also, what do you mean by cover node? sorry as i'm new to Unity Development but have long experience in C# Development.

    I think one of my main question is that what causes the agent to spawn farther than its supposed spawn point? as seen on my first screenshot. This is what confuses me. Also, can i add a collider to the prefab\ragdoll before creating an AI Agent out of it? will the agent adapt the collider? the reason is that the model passes through walls.

    Thank you for your assistance.
     
    Last edited: Nov 22, 2018
  14. squared55

    squared55

    Joined:
    Aug 28, 2012
    Posts:
    1,818
    It sounds like you made an agent out of one of the demo agents instead of a raw model. This resulted in a single agent having two separate sets of scripts controlling it, resulting in what you're seeing.

    The demo agents in the "Tactical Shooter AI\Tactical AI\Tactical AI Prefabs\Agents" folder should be fully set up, and require no further modification (barring behavior changes and layermasks). Try just dropping all six types into your scene and see what happens. If that doesn't work at all, then try just running the demo scenes.

    A cover node is a prefab included with TSAI. They are the green spheres you can see in the demo scenes and mark static locations where the agents can take cover. Not having one in the scene can result in undesired behavior when the agent tries to look for spots but doesn't find any possible locations to check.

    It is likely that the agent's model is offset from the Base Object, which controls movement. Then, when the base rotates, the model swings around the center, clipping through walls or anything else in its path in an attempt to maintain it's relative offset. Imagine something on the end of a spinning stick, except the stick can pass through walls.

    All colliders and rigidbodies should be set up prior to creating an agent. Otherwise the agent could end up bugging out when alive or fail to ragdoll properly when dead.
     
    Last edited: Nov 24, 2018
  15. unity_4WJJK75q1-ocTg

    unity_4WJJK75q1-ocTg

    Joined:
    Oct 6, 2018
    Posts:
    10

    Hi, i think that part where you informed me that the agents in the \Agents folder are fully set up fixed the case for bugged spawns. However, i'm trying to integrate it with UFPS (not v2) and Modern Ruins Package, and i encounter another set of error of which i hope is not compatibility issues, which are:

    1. When using a Player Prefab from UFPS and an Agent from TSAI that are both dropped on an empty scene with an Empty Object with ControllerScript.cs attached, and TargetScript.cs to the UFPS model. The TSAI Agent seems to damage a humongous amount of health (probably about 100+ points per damage while the player health is only at 100).


    2̶.̶ ̶W̶h̶e̶n̶ ̶u̶s̶i̶n̶g̶ ̶U̶F̶P̶S̶'̶ ̶P̶l̶a̶y̶e̶r̶ ̶P̶r̶e̶f̶a̶b̶ ̶a̶n̶d̶ ̶T̶S̶A̶I̶'̶s̶ ̶A̶g̶e̶n̶t̶ ̶o̶n̶ ̶M̶o̶d̶e̶r̶n̶ ̶R̶u̶i̶n̶'̶s̶ ̶D̶e̶m̶o̶ ̶S̶c̶e̶n̶e̶,̶ ̶t̶h̶e̶ ̶A̶g̶e̶n̶t̶ ̶o̶n̶l̶y̶ ̶f̶o̶l̶l̶o̶w̶s̶ ̶P̶l̶a̶y̶e̶r̶ ̶b̶u̶t̶ ̶d̶o̶e̶s̶ ̶n̶o̶t̶ ̶t̶r̶y̶ ̶t̶o̶ ̶s̶h̶o̶o̶t̶ ̶o̶r̶ ̶a̶n̶y̶t̶h̶i̶n̶g̶.̶
    i fixed this one after i saw that Team IDs 1 & 2 are registered as default AI Teams.

    3. I can't seem to kill the Agent or anything. Or do i have to code its death event for when it looses HP? although i do see a Health Script on the Agent. Also, i don't know why he does this. its creeping me out hehe. But he doesn't shoot me or anything while he's doing that. Or if he does, he's not hitting me. Also after that, he looked down, reloaded, then resumed shooting and hitting me.
     
    Last edited: Nov 24, 2018
  16. AngelBeatsZzz

    AngelBeatsZzz

    Joined:
    Nov 24, 2017
    Posts:
    239
    Hello, I have some questions.

    20181124171323.png

    1.Character's eye direction is correct when attacking, but his body is twisted by 180 degrees.

    I tried to rotate "Spine_02" by 180 degrees in Avatar Configure, but it didn't help.

    20181124171952.png

    2.I added Target Script.cs to barrel, but the character does not attack it but walks to it.

    If I delete all colliders on barrel, the character will attack it.But without the collider there is no damage.

    3.I created a CoverNodeScript object and set up the Layer Mask. I placed the CoverNode next to the Cube, but the characters didn't hide at the CoverNode during the battle.
     
    Last edited: Nov 25, 2018
  17. squared55

    squared55

    Joined:
    Aug 28, 2012
    Posts:
    1,818
    1) You can adjust the damage done in the bullet prefab's BulletScript.

    3) You are probably just doing so little damage relative to the agent's health that you don't notice. Try lowering the agent's health to 1 or increasing the damage your UFPS weapons do to something ridiculously high like 10000000 damage. Once you've established that that the damage works, then you can balance the gameplay.

    As for the agent deforming... do you have any more details on how to recreate the issue?

    1) Make sure your bulletspawn is facing towards the end of the barrel and not towards the agent's body. Try spinning it around 180 degrees. Do the same with the eye so it is facing out the front of the agent's head.

    2) Put the barrel on a physics layer that is not visible by the AI (specified in the AI Controller Script). That layermask controls what the agent cannot see through, rather than what the agent can see. The agent's real target is at the center of the barrel, but the agent thinks that the barrel's model is a wall it cannot see though. So, putting it on a different physics layer that the bullets can hit but the agent cannot see though should fix it.

    3) Make sure that the sight node has a clear line of sight to the target- agents will only choose cover locations that they move out and see their target from. Also make sure the object has the tag "Cover". Do the agents take cover in the demo scenes? Are you using the included cover nodes, or did you make your own?
     
    Last edited: Nov 24, 2018
  18. AngelBeatsZzz

    AngelBeatsZzz

    Joined:
    Nov 24, 2017
    Posts:
    239
    1.The direction of eye and bulletspawn are correct (z/blue axis is facing forward). I found this because of Spine's wrong direction, and now the problem is solved.

    2.I get it.

    3.I get it, I forgot to set the tag.

    Thanks for reply.

    New questions:

    1.I didn't understand how Command Center works. I have three AIs already set up, one Commander (Captain Script), and two Member (Formation Follower). I set the Command Center's Attacking Starting Pos/Defending Starting Pos to itself, then placed it near Commander. After running the game, Commander and Member did not go to the Pos but walked around.

    2.How can I let AI run to the target instead of walking to the target?

    3.The damage value of the UCC character does not look the same as the damage value of the AI. Where can I modify them?

    4.I want AI to sit in the car and shoot the enemy. Do you think this is possible?

    20181124203634.png

    5.When the two AIs stand, there is always an AI that cannot be properly aimed, causing the bullets to not hit the enemy.

    I assigned Neck to AI's "Target Object Tranform" and made Neck's Sphere Collider very big, but it didn't help much. When two AI stood or covered, there is always one that cannot be properly aimed. Eye and BulletSpawn are in the right direction. Is there any other way to optimize?
     
    Last edited: Nov 26, 2018
  19. unity_4WJJK75q1-ocTg

    unity_4WJJK75q1-ocTg

    Joined:
    Oct 6, 2018
    Posts:
    10
    Hi, thank you for assisting.

    1. I have fixed this by your instructions. I have reduced the damage to 0.0125 ~ 0.25 for the most optimal damage points for my project.

    3. I tried reducing the AI's health to 0.0001 and also tried increasing UFPS' Bullet damage to 10000 but still, the AI doesn't die. I have not added any additional scripts nor modified others parts so i don't understand why this is happening.

    Also, how can i tap on the AI Model's event handlers? like when the AI is taking damage, or the AI died. I'm planning to integrate another instance of the AI upon death with increased parameter values so i need to be able to inject additional codes

    Also, i have recorded a sample video showing the AI's Health at its lowest value, and the AI also performing that deformed position on his hip. see here: https://www.videosprout.com/video?id=e726be9d-0527-42a7-9416-12a2d7a9a221

    Thank you as always.

    Edit: I inserted a print(); method in the HealthScript just to check if the Damage() method gets called upon bullet hit from the Player to the AI, for some reason, it doesn't print at all.


    Also, i noticed that he died when he threw a grenade when i moved near him, causing him to also die from the explosion radius
     
    Last edited: Nov 26, 2018
  20. squared55

    squared55

    Joined:
    Aug 28, 2012
    Posts:
    1,818
    Short on time, so I'll make these answers quick.


    1. I'll get back to you later on this

    2. There's an option to enable sprinting in the base script.

    3. In the various bullet/explosion prefabs.

    4. This is not possible as the package stands now.

    5. Enable high quality aiming and try pulling the bullet spawn object back towards the agent (or, make a duplicate that is pulled back and set as the RotateToAimGun script's reference)
    3. Is the bullet even hitting the agents? Try checking your physics layers.

    The agents just use SendMessage, so any script on the hitbox objects that has the same method signature should be called when the agent takes damage.

    Make sure that all the rigidbodies object on the agents are set to be Kinematic on awake.
     
  21. AngelBeatsZzz

    AngelBeatsZzz

    Joined:
    Nov 24, 2017
    Posts:
    239
    2. Do you mean the Can Sprint option? I have tried to open it, but it didn't help, the character still walked to the target point(Key Transform).
     
  22. unity_4WJJK75q1-ocTg

    unity_4WJJK75q1-ocTg

    Joined:
    Oct 6, 2018
    Posts:
    10
    Hi, i don't see any Rigid Body component attached to the agent prior to drag and drop operation.


    Also do i need to change anything here on the Physics Manager based on what you're telling me?


    i'm pretty sure i'm hitting the Agent directly and point blank. unless there are events that i need to wire up in either UFPS or TSAI. either of which, i don't is necessary as its already out of the box.

    also, the agent seems to shoot down, even when i'm directly in front.
     
    Last edited: Nov 28, 2018
  23. squared55

    squared55

    Joined:
    Aug 28, 2012
    Posts:
    1,818
    Still not a lot of time to answer, sorry. Will try and give fuller responses tomorrow :)

    If you set an agent's combat behaviour to berserker, do they sprint when engaging a target?

    I was referring to the ragdoll. In any case, I think it would be quicker to start from scratch, to unto any changes you may have inadvertently made.

    Import UFPS into a new project, then import TSAI. Follow the integration instructions, drop a player controller into one of the demo scenes and see if everything works.

    Again, will try and give more expansive responses tomorrow.
     
  24. AngelBeatsZzz

    AngelBeatsZzz

    Joined:
    Nov 24, 2017
    Posts:
    239
    No, they are still walking to the target point. I did the test with the demo scene.
     
  25. unity_4WJJK75q1-ocTg

    unity_4WJJK75q1-ocTg

    Joined:
    Oct 6, 2018
    Posts:
    10
    Hi, i tried it on a new project. did as you told me to: import UFPS then TSAI after. Dropped UFPS Player to the demo scene (parkour), but still the AI wont die. do i need to attach any UFPS script to the agent? (vp_Damage Handler)

    I think its best to inform you, i'm using UFPS 1, not the second version. and TSAI v1.8.1 - these are what my client's unity project includes as provided to me.
     
    Last edited: Nov 28, 2018
  26. squared55

    squared55

    Joined:
    Aug 28, 2012
    Posts:
    1,818
    You also need to set up things like the Damage Mode in the UFPS bullet prefabs as specified in the integration instructions. Have you done so?

    Alternatively, just use TSAI bullet prefabs in the UFPS weapons.

    Does the animation controller you're using have a sprint animation? Also, agents will not sprint when idle- only when they are actively engaged in combat and only when they are further from their target position than the "Min Dist From Target To Sprint" variable.

    As for the AI Command Center, did you set the Target/Command Team array variables as appropriate to your game? You also need to set the flanking routes/suppressing positions in the Command Center script itself. There's an example scene which should just work out of the box, for reference.
     
    Last edited: Nov 28, 2018
  27. AngelBeatsZzz

    AngelBeatsZzz

    Joined:
    Nov 24, 2017
    Posts:
    239
    Understand, thanks.

    I tried to set both "My Field Of View" and "Max Dist To Notice Target" to 5, but Team 1 and Team 2 did not fight when approaching. Why is that?

    I want them to move to the same target point, only to find each other within 5 meters and then fight.
     
  28. tcmeric

    tcmeric

    Joined:
    Dec 21, 2016
    Posts:
    190
    Hi, recently purchased your asset, so far so good. However, I am finding 2 issues.

    1. If I shoot an AI, they dont necessary look towards or become aware of the person shooting them. Is this by design? If so, I can adjust the code, but just want to make sure before I do that.

    2. I found that some agents don't react/shoot as they should. Ive put together a short video.

    You can see that the third AI, does not react to being shot (other than my hit-reaction, which I set up separately). All three AI agents are set up the same. Any tips to debug this?

    He takes damage, and the IK weapon aims at me when I am in view. But he doesnt fire at all or move.

    [PS, the whistle audio is when the AI shots, so I can debug that easier]

     
  29. tcmeric

    tcmeric

    Joined:
    Dec 21, 2016
    Posts:
    190
    Hi, so I think I solved #2. The line of sight distance (field of view) was too short.
     
  30. unity_4WJJK75q1-ocTg

    unity_4WJJK75q1-ocTg

    Joined:
    Oct 6, 2018
    Posts:
    10
    Hi, Thank you. i think my issues have been fixed. Thank you for your overall support.

    Now my final question is, how can i tap into the Agent/AI's Death and Spawn Events? I'd like to add some codes.

    I've tried to add a custom script that i've made to the "Team 2_Rifle" agent demo which has a Coroutine object that sinks the dead body in about 10 seconds and is being called on the KillAI() method of the HealthScript. However, the coroutine doesn't seem to work, it cancels succeeding code right after yield return

    below codes are for testing purposes only and will be changed as the development goes:



     
    Last edited: Nov 30, 2018
  31. squared55

    squared55

    Joined:
    Aug 28, 2012
    Posts:
    1,818
    5 units with the default models is probably a lot closer than it seems, it's nearly melee range. Keep in mind it needs to cover the vertical distance between the agent's origin and the target as well.

    But, assuming that is what you want, the field of view is likely far too low to work. At 5 degrees, the agents will only be able to see a target whose origin is directly in front of the eye transform. At a range of 5 units, this will almost certainly be outside vertically, and unless your animation has the head pointing straight forwards (the demo agents don't; they look significantly off to the side) there will be a difference >5 degrees horizontally as well.

    Solution: Increase both until you get the desired behavior, starting with the FoV.

    1. You can create a TSAI "sound" which will attract idle agents on the opposite team to the source. There should be a create sound script included that you can use or look at for reference.

    Try OnAIDeath() on a script attached to the base object. However, the Base is destroyed instantly, so that might cause problems with regards to delayed code execution. I'd recommend using the script on the base as an intermarry, and then attaching the code that actually does the work to the ragdoll.
     
  32. unity_4WJJK75q1-ocTg

    unity_4WJJK75q1-ocTg

    Joined:
    Oct 6, 2018
    Posts:
    10
    Hi, and sorry as i have a batch of new questions:

    1. is it safe to clone the current AI Agent on the map on runtime (programmatically)? I'm trying it via Instantiate(GameObject.Find ("Team 2_Rifle")); because i'm returned with an error Object reference not set to an instance of an object TacticalAI.NavmeshInterface.Update () or how do i instantiate a new AI Agent programmatically (any kind of them: Rifle, SMG, etc)?

    2. how do i modify the bullet prefab's damage programmatically? i tried GameObject.Find ("Bullet Rifle").GetComponent<BulletScript> ().damage += 0.0125f; and it doesn't work.
     
    Last edited: Nov 30, 2018
  33. 935077388

    935077388

    Joined:
    Nov 27, 2018
    Posts:
    1
    Hello, this asset is very useful, but I have a question to ask.
    How to generate new enemies? I tried Instantiate () an AI while the program was running, but it didn't work. What's going on here?
     
  34. squared55

    squared55

    Joined:
    Aug 28, 2012
    Posts:
    1,818
    Instantiate should work, you can find an example in the sample spawning script. You'll want to use the (prefab, position, rotation) signature. Just make sure you are instantiating from a prefab and not an agent already in the scene.

    Code (CSharp):
    1. GameObject.Instantiate(agentPrefab, spawnPosition, spawnRotation);
    1. The bases detach from the ragdoll at runtime and destroy themselves when the agent dies, so no, cloning an agent that is already in the scene will not work without code modification. I recommend just instantiating from a prefab.

    2. Using the name will miss "Bullet Rifle(Clone)" or "Bullet Rifle(Clone)23" or whatever modified name it gets spawned as. You can use your own bullet script or access the bullet object as it is spawned in the GunScript.
     
  35. tcmeric

    tcmeric

    Joined:
    Dec 21, 2016
    Posts:
    190
    Hi, I am modifying your patrol with wait script. I want it to look at a specific direction at the patrol point. It all works fine, except I cannot manually set a destination via the navmesh agent. I tried setting it directly through the navmesh agent component, as well as the navmesh agent interface. I can only assume something else is overriding it?

    See the "LookWithoutMoving" method.

    Anything I set this variable to be, it never moves: _navMeshAgent.SetDestination(nextLookDirection);
    Even if I disable the navmesh interface component.

    Any tips here?

    Code (CSharp):
    1. using System.Collections;
    2. using Sirenix.OdinInspector;
    3. using UnityEngine;
    4. using UnityEngine.AI;
    5.  
    6. namespace TacticalAI
    7. {
    8.     public class PatrolWithTimer : TacticalAI.CustomAIBehaviour
    9.     {
    10.         [Tooltip("Time to wait should be longer than delay before look variable, as well as give enough time to finish the rotation before moving to the next point")]
    11.         public float timeToWaitAtEachPoint = 5.0f;
    12.  
    13.         [Tooltip("True if AI should look at the patrol points forward transform after a delay")]
    14.         public bool lookAtDirection = true;
    15.  
    16.         [Tooltip("Delay time before looking at the patrol point transform.")]
    17.         public float delayBeforeLook = 0.5f;
    18.  
    19.         private bool haveAPatrolTarget = false;
    20.         private int currentPatrolIndex = 0;
    21.         private float patrolNodeDistSquared;
    22.         private float timeUntilNextPoint = 5.0f;
    23.         private bool canRotate = true;
    24.         private NavMeshAgent _navMeshAgent;
    25.         private NavmeshInterface _navmeshInterface;
    26.  
    27.         [ShowInInspector]
    28.         private Vector3 nextLookDirection;
    29.  
    30.         public void Awake()
    31.         {
    32.             base.Initiate();
    33.             targetVector = transform.position;
    34.             timeUntilNextPoint = timeToWaitAtEachPoint;
    35.            
    36.            
    37.             _navMeshAgent = GetComponent<NavMeshAgent>();
    38.             if (_navMeshAgent == null)
    39.             {
    40.                 Debug.LogError("No nav mesh agent found on this gameobject " + gameObject);
    41.             }
    42.  
    43.             _navmeshInterface = GetComponent<NavmeshInterface>();
    44.             if (_navmeshInterface == null)
    45.             {
    46.                 Debug.LogError("No nav mesh interface was found on this gameobject " + gameObject);
    47.             }
    48.         }
    49.  
    50.         public override void AICycle()
    51.         {
    52.             if (baseScript.patrolNodes.Length < 0)
    53.             {
    54.                 Debug.LogError("No patrol nodes set!  Please set the array in the inspector, via script, or change the AI's non-engaging behavior");
    55.             }
    56.  
    57.             else
    58.             {
    59.                 //if we don't have a current goal, find one.
    60.                 if (!haveAPatrolTarget)
    61.                 {
    62.                     GetNextPatrolTarget();
    63.                 }
    64.  
    65.                 //if we have one, check if we're to close.  If so, cancel the current goal.
    66.                 else if (Vector3.SqrMagnitude(targetVector - myTransform.position) < patrolNodeDistSquared)
    67.                 {
    68.                     timeUntilNextPoint -= baseScript.cycleTime;
    69.  
    70.                     if (timeUntilNextPoint <= 0)
    71.                     {
    72.                         haveAPatrolTarget = false;
    73.                     }
    74.                 }
    75.  
    76.                 if (Vector3.SqrMagnitude(targetVector - myTransform.position) > patrolNodeDistSquared)
    77.                 {
    78.                     timeUntilNextPoint = timeToWaitAtEachPoint;
    79.                 }
    80.  
    81.                 // arrived at destination
    82.                 else
    83.                 {
    84.                     if (!lookAtDirection) return;
    85.  
    86.                     // if AI can rotate, then start rotation coroutine
    87.                     if (canRotate)
    88.                     {
    89.                         StartCoroutine("RotatePlayer");
    90.                     }
    91.                 }
    92.             }
    93.         }
    94.  
    95.         private void GetNextPatrolTarget()
    96.         {
    97.             // restore control only if rotation has been started, otherwise ignore.
    98.             if (!canRotate)
    99.             {
    100.                 ReturnControl();
    101.             }
    102.  
    103.             SetPatrolNodeDistSquared();
    104.             targetVector = baseScript.patrolNodes[currentPatrolIndex].position;
    105.             nextLookDirection = baseScript.patrolNodes[currentPatrolIndex].rotation.eulerAngles;
    106.             haveAPatrolTarget = true;
    107.  
    108.             //Move the current patrol node index up and loop it around to the beginning if necessary
    109.             currentPatrolIndex++;
    110.             if (currentPatrolIndex >= baseScript.patrolNodes.Length)
    111.             {
    112.                 currentPatrolIndex = 0;
    113.             }
    114.  
    115.             Debug.Log("Set can look again.");
    116.             canRotate = true;
    117.         }
    118.  
    119.         void SetPatrolNodeDistSquared()
    120.         {
    121.             patrolNodeDistSquared = baseScript.closeEnoughToPatrolNodeDist * baseScript.closeEnoughToPatrolNodeDist;
    122.         }
    123.  
    124.         /// <summary>
    125.         /// Rotate the AI player towards a direction using a delay
    126.         /// </summary>
    127.         /// <returns></returns>
    128.         IEnumerator RotatePlayer()
    129.         {
    130.             canRotate = false;
    131.             Debug.Log("Arrived at way point");
    132.             yield return new WaitForSeconds(delayBeforeLook);
    133.             LookWithoutMoving();
    134.         }
    135.  
    136.         /// <summary>
    137.         /// Look at direction without moving navmesh agent
    138.         /// </summary>
    139.         private void LookWithoutMoving()
    140.         {
    141.             if (_navMeshAgent != null)
    142.             {
    143.                 Debug.Log("Looking without moving");
    144.  
    145.                 _navmeshInterface.enabled = false;
    146.                 _navMeshAgent.updatePosition = false;
    147.                 _navMeshAgent.updateRotation = true;
    148.                 _navMeshAgent.SetDestination(nextLookDirection);
    149.             }
    150.         }
    151.  
    152.         /// <summary>
    153.         /// Return control of navmesh agent
    154.         /// </summary>
    155.         private void ReturnControl()
    156.         {
    157.             if (_navMeshAgent != null)
    158.             {
    159.                 Debug.Log("Control restored");
    160.  
    161.                 _navMeshAgent.Warp(transform.position);
    162.                 _navMeshAgent.updatePosition = true;
    163.                 _navMeshAgent.updateRotation = true;
    164.                 _navmeshInterface.enabled = true;
    165.             }
    166.         }
    167.     }
    168. }
     
  36. AngelBeatsZzz

    AngelBeatsZzz

    Joined:
    Nov 24, 2017
    Posts:
    239
    I added Target Script to the building. my AI is a monster, It uses melee attacks. How do I connect the damage value to the building's HP?
     
    Last edited: Dec 1, 2018
  37. Mario167100

    Mario167100

    Joined:
    Jul 25, 2016
    Posts:
    49
    Hello.
    I'm having a little trouble when integrating this asset pack with RFPS. I can have the TSA NPCs shoot at the FPS MAIN prefab and i can shoot and kill them, but i can't take any damage from the AI itself. Does anyone know how i can have the FPS MAIN prefab take damage from the NPCs?

    (Tiny question, can the scripts that are used in this asset pack be added to the NPCs in RFPS asset pack?)
     
  38. squared55

    squared55

    Joined:
    Aug 28, 2012
    Posts:
    1,818
    IIRC, the Animation Script controls the agent's rotation. When in combat, it faces towards the target, when idle, it faces in the direction of movement. You may want to try changing things in there.

    On the building's TargetScript, at the very bottom there should be a variable for "Health Script Holder." Set this to the object which has the building's health script, and as long as the health script has the right damage method signature, it should take damage.

    Assuming you have uncommented the lines of code in the TSAI scripts, make sure the TSAI bullet prefabs's LayerMask variable includes the layer that the player is on. Try setting it to everything to start, and then you can start removing layers you don't need.

    I do not think the scripts in this asset pack can be added onto the RFPS NPC's. It's one or the other.
     
    Last edited: Dec 3, 2018
  39. tcmeric

    tcmeric

    Joined:
    Dec 21, 2016
    Posts:
    190
    Sure, I will have a look. Maybe I can find the combat part that changes direction, and use the same way of changing rotation.
     
  40. Mario167100

    Mario167100

    Joined:
    Jul 25, 2016
    Posts:
    49
    Does the greentext mean that it's uncommented?
     

    Attached Files:

    • boi.PNG
      boi.PNG
      File size:
      30 KB
      Views:
      722
  41. tcmeric

    tcmeric

    Joined:
    Dec 21, 2016
    Posts:
    190
    Yes, anything green in there is commented. You want to uncomment the the part that is between

    You want to delete the /* and */ , so that section returns to normal color.
     
  42. pierre92nicot

    pierre92nicot

    Joined:
    Aug 21, 2018
    Posts:
    57
    Hi,
    What is the purpose of "stop for cover" in the rotate to aim gun script ?
    Is there a way to make the agents shooting only when they are not moving ?
    It is possible to make the agents to aim the target only when firing but not when moving or in cover for exemple ?

    Thanks you
     
  43. tcmeric

    tcmeric

    Joined:
    Dec 21, 2016
    Posts:
    190
    For anyone who wants a patrol with wait at each point, as well, turn to face the direction of that point gameobject.

    Use this custom script:

    Code (CSharp):
    1. using System.Collections;
    2. using UnityEngine;
    3.  
    4. namespace TacticalAI
    5. {
    6.     public class PatrolWithTimer : TacticalAI.CustomAIBehaviour
    7.     {
    8.      
    9.         [Tooltip("True if AI should look at the patrol points forward transform after a delay")]
    10.         public bool lookAtDirection = true;
    11.         public float rotationSpeed;
    12.         [Tooltip("Time to wait should be longer than delay before look variable, as well as give enough time to finish the rotation before moving to the next point")]
    13.         public float timeToWaitAtEachPoint = 5.0f;
    14.         [Tooltip("Delay time before looking at the patrol point transform.")]
    15.         public float delayBeforeLook = 0.5f;
    16.  
    17.         private bool haveAPatrolTarget = false;
    18.         private int currentPatrolIndex = 0;
    19.         private float patrolNodeDistSquared;
    20.         private float timeUntilNextPoint = 5.0f;
    21.         private bool canRotate = true;
    22.         private Vector3 lastWayPoint;
    23.         private AnimationScript _animationScript;
    24.         private Vector3 nextLookDirection;
    25.  
    26.         public void Awake()
    27.         {
    28.             base.Initiate();
    29.             targetVector = transform.position;
    30.             timeUntilNextPoint = timeToWaitAtEachPoint;
    31.  
    32.             _animationScript = GetComponent<AnimationScript>();
    33.             if (_animationScript == null)
    34.             {
    35.                 Debug.LogError("No animation script found on this gameobject " + gameObject);
    36.             }
    37.         }
    38.  
    39.         public override void AICycle()
    40.         {
    41.             if (baseScript.patrolNodes.Length < 0)
    42.             {
    43.                 Debug.LogError("No patrol nodes set!  Please set the array in the inspector, via script, or change the AI's non-engaging behavior");
    44.             }
    45.  
    46.             else
    47.             {
    48.                 //if we don't have a current goal, find one.
    49.                 if (!haveAPatrolTarget)
    50.                 {
    51.                     GetNextPatrolTarget();
    52.                 }
    53.  
    54.                 //if we have one, check if we're to close.  If so, cancel the current goal.
    55.                 else if (Vector3.SqrMagnitude(targetVector - myTransform.position) < patrolNodeDistSquared)
    56.                 {
    57.                     timeUntilNextPoint -= baseScript.cycleTime;
    58.  
    59.                     if (timeUntilNextPoint <= 0)
    60.                     {
    61.                         haveAPatrolTarget = false;
    62.                     }
    63.                 }
    64.  
    65.                 if (Vector3.SqrMagnitude(targetVector - myTransform.position) > patrolNodeDistSquared)
    66.                 {
    67.                     timeUntilNextPoint = timeToWaitAtEachPoint;
    68.                 }
    69.  
    70.                 // arrived at destination
    71.                 else
    72.                 {
    73.                     if (!lookAtDirection) return;
    74.  
    75.                     // if AI can rotate, then start rotation coroutine
    76.                     if (canRotate)
    77.                     {
    78.                         StartCoroutine("RotatePlayer");
    79.                     }
    80.                 }
    81.             }
    82.         }
    83.  
    84.         private void GetNextPatrolTarget()
    85.         {
    86.  
    87.             SetPatrolNodeDistSquared();
    88.             targetVector = baseScript.patrolNodes[currentPatrolIndex].position;
    89.             nextLookDirection = baseScript.patrolNodes[currentPatrolIndex].rotation.eulerAngles;
    90.             haveAPatrolTarget = true;
    91.  
    92.             //Move the current patrol node index up and loop it around to the beginning if necessary
    93.             currentPatrolIndex++;
    94.             if (currentPatrolIndex >= baseScript.patrolNodes.Length)
    95.             {
    96.                 currentPatrolIndex = 0;
    97.             }
    98.  
    99.             if (!canRotate)
    100.             {
    101.                   ReturnControl();
    102.             }
    103.  
    104.             canRotate = true;
    105.         }
    106.  
    107.         void SetPatrolNodeDistSquared()
    108.         {
    109.             patrolNodeDistSquared = baseScript.closeEnoughToPatrolNodeDist * baseScript.closeEnoughToPatrolNodeDist;
    110.         }
    111.  
    112.         /// <summary>
    113.         /// Rotate the AI player towards a direction using a delay
    114.         /// </summary>
    115.         /// <returns></returns>
    116.         IEnumerator RotatePlayer()
    117.         {
    118.             canRotate = false;
    119.           //  Debug.Log("Arrived at way point");
    120.             yield return new WaitForSeconds(delayBeforeLook);
    121.             LookWithoutMoving();
    122.  
    123.         }
    124.  
    125.         /// <summary>
    126.         /// Look at direction using the animation script.
    127.         /// </summary>
    128.         private void LookWithoutMoving()
    129.         {
    130.           //  Debug.Log("Looking without moving started");
    131.             _animationScript.StartCoroutine(_animationScript.FaceDirection(nextLookDirection, rotationSpeed));
    132.         }
    133.  
    134.         /// <summary>
    135.         /// All the AI to return to its normal looking direction.
    136.         /// </summary>
    137.         private void ReturnControl()
    138.         {
    139.            // Debug.Log("Control restored");
    140.             _animationScript.useCustomRotation = false;
    141.  
    142.         }
    143.     }
    144. }
    Second, add this method to your AnimationScript

    Code (CSharp):
    1.         public IEnumerator FaceDirection(Vector3 _directionToFace, float _rotationSpeed)
    2.         {
    3.             var defaultTurnSpeed = turnSpeed;
    4.             turnSpeed = _rotationSpeed;
    5.  
    6.             directionToFace = _directionToFace;
    7.             useCustomRotation = true;
    8.          
    9.             /* Uncomment below to set a custom animation for turning */
    10.            // animator.SetBool("Turn", true);
    11.  
    12.             yield return new WaitUntil(()=> Vector3.Angle(directionToFace, myAIBodyTransform.forward) > maxAngleDeviation);
    13.  
    14.             /* Uncomment below to set a custom animation to stop the turning animation */
    15.            // animator.SetBool("Turn", false);
    16.          
    17.             turnSpeed = defaultTurnSpeed;
    18.             yield return null;
    19.         }
    Has optional lines to add your own custom turning animation, otherwise your AI will just turn without a specific animation.
     
    hopeful and pierre92nicot like this.
  44. squared55

    squared55

    Joined:
    Aug 28, 2012
    Posts:
    1,818
    It should stop the agent from rotating their torso to aim at a target when crouching behind cover. You'll want to use it when your crouching animation doesn't play well with aiming.

    Try enabling sprinting and then setting the distance to stop sprinting to something low.
     
  45. unity_4WJJK75q1-ocTg

    unity_4WJJK75q1-ocTg

    Joined:
    Oct 6, 2018
    Posts:
    10

    Hi Thank you again, i managed to do as you have told me.

    However, i have a few more questions:

    1. My Player doesn't seem to receive Grenade Damages. i have set it to 100 but i still dont have my HP decreased. Or better yet, how do i disable the AI from throwing grenades?
    2. If i place a static crate on my map and put a short node there, will the AI dock and hide behind the box?
    3. If i may also ask, have you used State Machines as the base of the Algorithm for your AI Package?
     
    Last edited: Dec 17, 2018
  46. squared55

    squared55

    Joined:
    Aug 28, 2012
    Posts:
    1,818
    Hello,

    It's late where I am and I'm pretty tired, but I'll try and give you some quick answers anyways. :)

    On the explosion's layermask variable, exclude whatever physics layer the player is on.

    The AI will take cover at any node location so long as the cover node satisfies all the conditions for cover. The actual environment only matters with regards to what lines of sight are uncovered and blocked.
     
    Last edited: Dec 18, 2018
  47. AngelBeatsZzz

    AngelBeatsZzz

    Joined:
    Nov 24, 2017
    Posts:
    239
    Hi squared, I am using UCC and TSAI, I have two questions. How do I get the enemy's death information such as headshot when the UCC character kills the enemy? How to judge whether an enemy is killed by a UCC character instead of another AI?
     
  48. squared55

    squared55

    Joined:
    Aug 28, 2012
    Posts:
    1,818
    That would mostly have to be done with new code, but TSAI does have some things that could help. Each hitbox script stores whether it has been hit last frame with a variable called damageTakenThisFrame. You can also run some code when the AI dies by placing a method called OnAIDeath() inside any script on the base object.

    So...

    Code (CSharp):
    1. public TacticalAI.HitBox headHitBox;
    2. public void OnAIDeath()
    3. {
    4.      if (headHitBox.damageTakenThisFrame > 0)
    5.             {
    6.                         //Do headshot stuff
    7.             }
    8.      else
    9.             {
    10.                        //Do non-headshot stuff
    11.             }
    12. }
     
  49. AngelBeatsZzz

    AngelBeatsZzz

    Joined:
    Nov 24, 2017
    Posts:
    239
    I get it, thank you. How to judge whether an enemy is killed by a UCC character instead of another AI? Do you have an idea?
     
  50. squared55

    squared55

    Joined:
    Aug 28, 2012
    Posts:
    1,818
    This is mostly going to have to be independently of TSAI's systems, but I can give you some general advice on a simple implementation.

    You'll need:

    1) To modify the bullets so that they alert the struck object what hit them last. You could try "GetComponent," "SendMessage" or or Unity Events (although Unity Events are a bit harder to implement than the others). This is pretty much the same thing as regular damage transfer, so you can look at that code in the BulletScript for reference.

    Code (CSharp):
    1. hit.collider.SendMessage("HitByAI", true, SendMessageOptions.DontRequireReceiver);
    2) A central storage script which stores what it was hit with last and actually does something with this data (say, with OnAIDeath()).

    3) A way for the data to the storage script. There's a lot of different ways you could do this. The simplest would probably be to modify the HitBox script to take this data from the bullet in 1) and transfer it to the storage script. Again, this is pretty much the same thing as regular damage transfer, so you can look at the pre-existing code in the HitBox script for reference.

    Code (CSharp):
    1. public StorageScript storageScript;
    2.  
    3. public void HitByAI(bool didAIHit)
    4.         {
    5.             if (storageScript)
    6.             {
    7.                     storageScript.WasHitByAI(didAIHit);
    8.             }
    9.         }
     
    Last edited: Dec 19, 2018
    AngelBeatsZzz likes this.