Search Unity

  1. Unity 2018.3 is now released.
    Dismiss Notice
  2. The Unity Pro & Visual Studio Professional Bundle gives you the tools you need to develop faster & collaborate more efficiently. Learn more.
    Dismiss Notice
  3. Want more efficiency in your development work? Sign up to receive weekly tech and creative know-how from Unity experts.
    Dismiss Notice
  4. Build games and experiences that can load instantly and without install. Explore the Project Tiny Preview today!
    Dismiss Notice
  5. Want to provide direct feedback to the Unity team? Join the Unity Advisory Panel.
    Dismiss Notice
  6. Improve your Unity skills with a certified instructor in a private, interactive classroom. Watch the overview now.
    Dismiss Notice

Tactical Shooter AI - Asset Store Pack

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

  1. Felinsky

    Felinsky

    Joined:
    Jan 22, 2018
    Posts:
    7
    Im using waypoints transform for patroling points, which AI is following. Is it possible to stay some time at every point, before starting move to another ? Like patrol with staying on every waypoint some time. Thanks
     
  2. squared55

    squared55

    Joined:
    Aug 28, 2012
    Posts:
    1,803
    That would require a bit of modification to the Patrol behavior's code. Next time I get a chance I'll see if I can make a modified version for you.

    Also, I just uploaded a version which should support UFPS 2, with no code changes required on your end. Let me know if there's any problems with the integration. :)


    EDIT:

    OK, try this for the patrolling:

    ---See fixed/improved version below---

    Put that in a new C# script called "PatrolWithTimer", put it on your agent and set the "BehaveLevel" variable to Idle. Then set the timeToWaitAtEachPoint to your desired time value. Let me know if it works! :)
     
    Last edited: Nov 1, 2018
    Felinsky likes this.
  3. Felinsky

    Felinsky

    Joined:
    Jan 22, 2018
    Posts:
    7
    Hey, thanks for answer and script. I crečated script with your code, put on AI, set patrol behavior, set 3 transforms as points. When i run, game always crashes after i did that. Im using 2018.3.05 unity.
     
  4. squared55

    squared55

    Joined:
    Aug 28, 2012
    Posts:
    1,803
    OK, try this instead. This works on my computer.

    Code (CSharp):
    1.  
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5.  
    6. namespace TacticalAI
    7. {
    8.     public class PatrolWithTimer : TacticalAI.CustomAIBehaviour
    9.     {
    10.  
    11.         bool haveAPatrolTarget = false;
    12.         int currentPatrolIndex = 0;
    13.         float patrolNodeDistSquared;
    14.  
    15.         public void Awake()
    16.         {
    17.             base.Initiate();
    18.             targetVector = transform.position;
    19.             timeUntilNextPoint = timeToWaitAtEachPoint;
    20.         }
    21.  
    22.         public float timeToWaitAtEachPoint = 5.0f;
    23.         float timeUntilNextPoint = 5.0f;
    24.  
    25.         public override void AICycle()
    26.         {
    27.             if (baseScript.patrolNodes.Length >= 0)
    28.             {
    29.                 //if we don't have a current goal, find one.
    30.                 if (!haveAPatrolTarget)
    31.                 {
    32.                     SetPatrolNodeDistSquared();
    33.                     targetVector = baseScript.patrolNodes[currentPatrolIndex].position;
    34.                     haveAPatrolTarget = true;
    35.  
    36.                     //Move the current patrol node index up and loop it around to the beginning if necessary
    37.                     currentPatrolIndex++;
    38.                     if (currentPatrolIndex >= baseScript.patrolNodes.Length)
    39.                     {
    40.                         currentPatrolIndex = 0;
    41.                     }
    42.                 }
    43.                 //if we have one, check if we're to close.  If so, cancel the current goal.
    44.                 else if (Vector3.SqrMagnitude(targetVector - myTransform.position) < patrolNodeDistSquared)
    45.                 {
    46.                     timeUntilNextPoint -= baseScript.cycleTime;
    47.                     if (timeUntilNextPoint <= 0)
    48.                     {
    49.                         haveAPatrolTarget = false;
    50.                     }
    51.                 }
    52.  
    53.                 if(Vector3.SqrMagnitude(targetVector - myTransform.position) > patrolNodeDistSquared)
    54.                 {
    55.                     timeUntilNextPoint = timeToWaitAtEachPoint;
    56.                 }
    57.             }
    58.             else
    59.             {
    60.                 Debug.LogError("No patrol nodes set!  Please set the array in the inspector, via script, or change the AI's non-engaging behavior");
    61.             }
    62.         }
    63.  
    64.         void SetPatrolNodeDistSquared()
    65.         {
    66.             patrolNodeDistSquared = baseScript.closeEnoughToPatrolNodeDist * baseScript.closeEnoughToPatrolNodeDist;
    67.         }
    68.  
    69.     }
    70. }
    71.  
    Make sure every entry in the patrol array has a gameobject in it too. Empty/null slots can cause problems.
     
    Last edited: Nov 3, 2018
    tcmeric likes this.
  5. pierre92nicot

    pierre92nicot

    Joined:
    Aug 21, 2018
    Posts:
    14
    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.
     
  6. squared55

    squared55

    Joined:
    Aug 28, 2012
    Posts:
    1,803
    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
  7. pierre92nicot

    pierre92nicot

    Joined:
    Aug 21, 2018
    Posts:
    14
    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.
     
  8. squared55

    squared55

    Joined:
    Aug 28, 2012
    Posts:
    1,803
    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
  9. pierre92nicot

    pierre92nicot

    Joined:
    Aug 21, 2018
    Posts:
    14
    Thanks you, I will take a look at it.
     
  10. 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.
     
  11. desertGhost_

    desertGhost_

    Joined:
    Apr 12, 2018
    Posts:
    17
    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
  12. nipu212

    nipu212

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

    squared55

    Joined:
    Aug 28, 2012
    Posts:
    1,803
    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.         }
     
  14. desertGhost_

    desertGhost_

    Joined:
    Apr 12, 2018
    Posts:
    17
    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.
     
  15. unity_4WJJK75q1-ocTg

    unity_4WJJK75q1-ocTg

    Joined:
    Oct 6, 2018
    Posts:
    9
    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.
     
  16. squared55

    squared55

    Joined:
    Aug 28, 2012
    Posts:
    1,803

    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.
     
  17. unity_4WJJK75q1-ocTg

    unity_4WJJK75q1-ocTg

    Joined:
    Oct 6, 2018
    Posts:
    9

    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
  18. squared55

    squared55

    Joined:
    Aug 28, 2012
    Posts:
    1,803
    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
  19. unity_4WJJK75q1-ocTg

    unity_4WJJK75q1-ocTg

    Joined:
    Oct 6, 2018
    Posts:
    9

    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
  20. AngelBeatsZzz

    AngelBeatsZzz

    Joined:
    Nov 24, 2017
    Posts:
    107
    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
  21. squared55

    squared55

    Joined:
    Aug 28, 2012
    Posts:
    1,803
    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
  22. AngelBeatsZzz

    AngelBeatsZzz

    Joined:
    Nov 24, 2017
    Posts:
    107
    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
  23. unity_4WJJK75q1-ocTg

    unity_4WJJK75q1-ocTg

    Joined:
    Oct 6, 2018
    Posts:
    9
    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
  24. squared55

    squared55

    Joined:
    Aug 28, 2012
    Posts:
    1,803
    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.
     
  25. AngelBeatsZzz

    AngelBeatsZzz

    Joined:
    Nov 24, 2017
    Posts:
    107
    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).
     
  26. unity_4WJJK75q1-ocTg

    unity_4WJJK75q1-ocTg

    Joined:
    Oct 6, 2018
    Posts:
    9
    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
  27. squared55

    squared55

    Joined:
    Aug 28, 2012
    Posts:
    1,803
    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.
     
  28. AngelBeatsZzz

    AngelBeatsZzz

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

    unity_4WJJK75q1-ocTg

    Joined:
    Oct 6, 2018
    Posts:
    9
    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
  30. squared55

    squared55

    Joined:
    Aug 28, 2012
    Posts:
    1,803
    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
  31. AngelBeatsZzz

    AngelBeatsZzz

    Joined:
    Nov 24, 2017
    Posts:
    107
    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.
     
  32. tcmeric

    tcmeric

    Joined:
    Dec 21, 2016
    Posts:
    94
    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]

     
  33. tcmeric

    tcmeric

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

    unity_4WJJK75q1-ocTg

    Joined:
    Oct 6, 2018
    Posts:
    9
    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
  35. squared55

    squared55

    Joined:
    Aug 28, 2012
    Posts:
    1,803
    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.
     
  36. unity_4WJJK75q1-ocTg

    unity_4WJJK75q1-ocTg

    Joined:
    Oct 6, 2018
    Posts:
    9
    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
  37. 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?
     
  38. squared55

    squared55

    Joined:
    Aug 28, 2012
    Posts:
    1,803
    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.
     
  39. tcmeric

    tcmeric

    Joined:
    Dec 21, 2016
    Posts:
    94
    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. }
     
  40. AngelBeatsZzz

    AngelBeatsZzz

    Joined:
    Nov 24, 2017
    Posts:
    107
    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
  41. Mario167100

    Mario167100

    Joined:
    Jul 25, 2016
    Posts:
    20
    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?)
     
  42. squared55

    squared55

    Joined:
    Aug 28, 2012
    Posts:
    1,803
    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
  43. tcmeric

    tcmeric

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

    Mario167100

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

    Attached Files:

    • boi.PNG
      boi.PNG
      File size:
      30 KB
      Views:
      10
  45. tcmeric

    tcmeric

    Joined:
    Dec 21, 2016
    Posts:
    94
    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.
     
  46. pierre92nicot

    pierre92nicot

    Joined:
    Aug 21, 2018
    Posts:
    14
    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
     
  47. tcmeric

    tcmeric

    Joined:
    Dec 21, 2016
    Posts:
    94
    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.
  48. squared55

    squared55

    Joined:
    Aug 28, 2012
    Posts:
    1,803
    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.