Search Unity

Unity RTS Engine

Discussion in 'Assets and Asset Store' started by OussamaB, Feb 7, 2017.

  1. OussamaB

    OussamaB

    Joined:
    Feb 8, 2013
    Posts:
    1,470
    There's an error, please let me know from where it is occurring.
    But I strongly think that this error is happening because you have "Placed By Default" enabled in the building you are trying to place.
     
    Phesant33 likes this.
  2. OussamaB

    OussamaB

    Joined:
    Feb 8, 2013
    Posts:
    1,470
    Mostly NPC Behavior improvements. It will be submitted in 2-3 days.
     
  3. A_Akkad

    A_Akkad

    Joined:
    Aug 28, 2017
    Posts:
    45
    I tried to mess around with the nav mesh agent offset to no avail :\
     
  4. A_Akkad

    A_Akkad

    Joined:
    Aug 28, 2017
    Posts:
    45
    1. I created a class that creates a Hunger value and ties that to the Health value of the unit. After a couple days it all worked beautifully. However, when selected, the value of the units health would not update in the UI until you deselect the unit and reselect. So I dug around in your UI code for a long time and found the nice UpdateUnitHealthUI(Unit) function. Using that in my script the game started automatically updating the units health (100, 99, 98 etc) without reselecting the unit. Today however, I realized that my code started changing the health of EVERY unit on the map from whatever their value was to match the health of the unit who had my custom script as a component!
    As far as I know, that means that my code applies changes to all the units' UIManagers, but it should not because the parameter I am passing is myUnit, (myUIManager.UpdateUnitHealthUI(myUnit); ) which should only affect the unit who has the component, right?

    Here is a condensed version of my code:
    Code (CSharp):
    1. public class HerdBehavior : MonoBehaviour { //Allows herd members to move erratically, have hunger, find, move to and consume food. Must be placed on herd member.
    2.  
    3.     [HideInInspector]
    4.     GameManager GameMgr;
    5.  
    6.     int randomInt;
    7.     int randomX;
    8.     int randomZ;
    9.  
    10.     float hunger;
    11.  
    12.     Vector3 randomPos = Vector3.zero;
    13.     Vector3 currentPos = Vector3.zero;
    14.     GameObject TargetObj;
    15.     Unit myUnit;
    16.     UIManager myUIManager;
    17.  
    18.     public float howOftenHerdMovesErratically = 10f; //in seconds, see line 27 InvokeRepeating ("ErraticMovement", 1f, 10f * frequencyOfErraticMovement);
    19.     public float howFastHerdGetsHungry = 1f;
    20.  
    21.     // Use this for initialization
    22.     void Start () {
    23.  
    24.         GameMgr = GameManager.Instance;
    25.         myUIManager = GameMgr.UIMgr;
    26.         //myUIManager = GameMgr.GetComponent<UIManager> ();
    27.         Debug.Log ("the UIManager is " + myUIManager);
    28.  
    29.         myUnit = gameObject.GetComponent<Unit> ();
    30. }
    31.  
    32. void HungerSystem () { //Ties herd health to hunger, controls hunger and calls other functions that feed and heal herd
    33.  
    34.         //IF HEALTH = HUNGER
    35.         hunger = myUnit.Health;
    36.  
    37.         hunger -= 1f * howFastHerdGetsHungry;
    38.         myUnit.Health = hunger;
    39.  
    40.         //Unit tester = GameObject.Find ("Sheep").GetComponent<Unit> ();
    41.         myUIManager.UpdateUnitHealthUI(myUnit);
    42.         //myUIManager.UpdateUnitHealthUI;
    43.  
    44.     }
    45.  
    Either the function is not the function I should call or my code logic is off. Can you please help?

    2.
    I messed around with those values (Unit -> Unit Height and Unit Radius) and with the Nav Mesh Agent -> Base Offset before posting and just now after reading your post, to still no avail! Haha, maybe I just don't understand what you mean exactly?

    What I just tried was to copy and paste the Nav Mesh Agent -> Base Offset, Unit -> Unit Height and Unit Radius values from the default non-floating prefab to my custom unit. For me, these values move the actual Agent's green cylinder, but when I start the game my units still float. What am I doing wrong? Basically, the default functional prefab has these same 3 values as my floating units.


    3. Also, I just remembered to rate and review your RTS Engine Asset! It's amazing and your support is great and you deserve more customers :)
     
  5. Phesant33

    Phesant33

    Joined:
    Nov 13, 2015
    Posts:
    34
    Thanks heaps I will give that a try
     
  6. OussamaB

    OussamaB

    Joined:
    Feb 8, 2013
    Posts:
    1,470
    Assuming that you call HungerSystem () when you want to remove health from the unit because of loosing hunger points, this is the way it should be done.

    Code (csharp):
    1.  
    2. void HungerSystem () { //Ties herd health to hunger, controls hunger and calls other functions that feed and heal herd
    3.         myUnit.AddHealth(-howFastHerdGetsHungry);
    4.     }
    5.  
    Always use the method above to update a unit's health (this will also make sure it is updated when it is an offline or online game and will also update the UI automatically when the unit is selected).

    Okay I am going to explain another way, try changing the "Unit Height" field in the Unit.cs inspector without touching the Navigation Agent component and you will see how your unit changes its y position when the game starts.
    For example I had to set the Unit Height to 0 in the prefab you sent me in order for it to not be floating.

    I just checked that review, thanks a lot! I really appreciate it. Hopefully this asset will help bring back the golden age of RTS games like you mentioned!
     
    Asledziu likes this.
  7. CPTEliteWarfare

    CPTEliteWarfare

    Joined:
    Apr 9, 2014
    Posts:
    68

    Just want show off what we been making with the RTS Engine Asset! :) ( Models are ours they dont come with RTS Engine Asset! ) Soon to be on Steam also :D. This asset/framework is the best Framework for our project and im really thankful for this asset without this asset/framework my idea for this RTS game wouldnt have came true.
     
    OussamaB likes this.
  8. OussamaB

    OussamaB

    Joined:
    Feb 8, 2013
    Posts:
    1,470
    WOW! This looks so good. Please let us know when this is going to hit Steam!
     
    CPTEliteWarfare likes this.
  9. CPTEliteWarfare

    CPTEliteWarfare

    Joined:
    Apr 9, 2014
    Posts:
    68
    Will do!
     
  10. A_Akkad

    A_Akkad

    Joined:
    Aug 28, 2017
    Posts:
    45
    Yes! I had to re-write the script logic, but at least now it works with the function (myUnit.AddHealth) you provided. I initially had hunger = myUnit.Health; and myUnit.Health = hunger;. Also, I need the health to drop every second of the game, so I used an "InvokeRepeating ("HungerSystem", 1f, 1f);" function in the Start().
    I am astounded at how I missed that initially. I played around with all the values several times. I guess I only used small values and did not notice the difference? Either way, it worked perfectly! Thank you.
    Thank you. With this RTS Engine maybe we can revive the RTS golden age :)


    I still have some issues, but I want to spend more time working on them myself before asking for help. It is such a nice feeling to code something then watch it work!
     
    OussamaB likes this.
  11. A_Akkad

    A_Akkad

    Joined:
    Aug 28, 2017
    Posts:
    45
    That screenshot looks amazing! You have a link for the game page?
    The center building reminds me of the Citadel from City 17.
     
  12. A_Akkad

    A_Akkad

    Joined:
    Aug 28, 2017
    Posts:
    45
    For my game, the food resource regenerates over time. I placed that simple code in Resources.cs, where, using InvokedRepeated, it regenerates a set amount every 10s. However, I'm running into the same problem as I did when regenerating health for my units (which you helped me fix with a specific function). I cannot view the current amount of resource (resource().amount) until I deselect and reselect the particular food resource object.

    I have been trying to solve this myself, but the function calling gets pretty intricate and goes through several different scripts and I don't want to run into the same issue as last time where I used the wrong function.
    What should I do to have the food's current amount be continuously refreshed/updated without having to reselect it?

    Thank you.
     
  13. OussamaB

    OussamaB

    Joined:
    Feb 8, 2013
    Posts:
    1,470
    Whenever you update the resource's amount, you can do this:

    Code (csharp):
    1.  
    2.  
    3. //assuming "MyResource" is the "Resource.cs" component for the resource you want to update.
    4.  
    5. MyResource.Amount += 10; //Here you update the resource's amount.
    6.  
    7. //right here you check whether the resource is selected or not:
    8. if(GameManager.Instance.SelectionMgr.SelectedResource == MyResource)
    9. {
    10.     GameManager.Instance.UIMgr.UpdateResourceUI(MyResource);
    11. }
    12.  
    13.  
    Let me know how this works for you.
     
  14. A_Akkad

    A_Akkad

    Joined:
    Aug 28, 2017
    Posts:
    45
    Worked great. However, the syntax of my code is different. I just want to make sure I am doing it correctly:

    I placed the following code WITHIN resources.cs as a function that gets InvokeRepeated. Your code makes it seem like it was in a different script?
    Code (CSharp):
    1. void RegenerateFood () {
    2.         if (Amount <= initialAmount - 10)
    3.         Amount += 10;
    4.  
    5.         if(GameManager.Instance.SelectionMgr.SelectedResource == this.gameObject.GetComponent<Resource>())
    6.         {
    7.             GameManager.Instance.UIMgr.UpdateResourceUI(this.gameObject.GetComponent<Resource>());
    8.  
    9.             Debug.Log ("CODE RUNNING");
    10.         }
    11.     }
     
  15. BritishGuy

    BritishGuy

    Joined:
    Oct 2, 2013
    Posts:
    5
    I enjoyed the Demo, One question, when the resources are limited, once depleted will the players civilian AI move onto the next closest resource to start gathering or is it micro managed?
     
    Last edited: Sep 28, 2017
  16. OussamaB

    OussamaB

    Joined:
    Feb 8, 2013
    Posts:
    1,470
    Currently they just stop gathering resources and wait for the player's commands.
    NPC civilians do that on their own tho so it shouldn't be a problem adding that behavior for local player units as well.
     
  17. OussamaB

    OussamaB

    Joined:
    Feb 8, 2013
    Posts:
    1,470
    Yeah this should work as well. But instead of having "this.gameObject.GetComponent<Resource>()", you can simply replace that with "this" only (assuming the function is inside the "Resource.cs" script because this refers to the component). Also it's better to refresh the resource UI only when the amount has actually changed. The code below does the same job but it is better organised.

    Code (CSharp):
    1.  
    2. void RegenerateFood () {
    3.         if (Amount <= initialAmount - 10)
    4.         {
    5.             Amount += 10;
    6.  
    7.             if(SelectionMgr.SelectedResource == this) //since the SelectionManager.cs can be called using "SelectionMgr" inside the Resource script.
    8.             {
    9.                 GameManager.Instance.UIMgr.UpdateResourceUI(this);
    10.  
    11.                 Debug.Log ("CODE RUNNING");
    12.             }
    13.         }
    14.     }
    15.  
     
  18. A_Akkad

    A_Akkad

    Joined:
    Aug 28, 2017
    Posts:
    45
    Thank you. It's small details like these that show how good of a coder you are and the details whihc I am trying to learn myself!

    1. I'm not sure if it is because I changed some code or it's an asset bug; according to my debug.log, the if statement on line 41 in Builder.cs never seems to run?

    2. When you tell the builder units build something, the "buildings to build" icons in the lower left disappear, and you have to reselect the builders to see them again.

    EDIT: I solved number 3. somehow by simply altering the Building Description. That is ALL I did!! Of course, after thinking on it a while, I think it is because I also hit Apply on the Prefab option in the inspector. I will leave issue 3. written in this post incase other's have a similar issue.
    3. This has been driving me nuts for days. I am trying to build a building that is actually a resource. However, using the current code, buildings vary greatly from resources. So my logic is to destroy the building once it is complete (has max health) and instantiate the resource I wanted the builder to build. It sounds simple, but it simply doesn't work no matter what I do! I first tried to write the code in my builder in the if statement of line 41 (see issue 1.), but that if statement isn't running at all. I tried placing that code in BuildingPlacement.cs, but it wouldnt figure out when the max health is reached so it would just place my resource without waiting for it to be built.
    Eventually, I had what I thought was a eureka moment and decided to place it in Building.cs. Of course, Building.cs has a custom editor. Took me a while to figure that out. After a long time, I learned how the custom inspector works and I wrote code in both Building.cs and BuildingEditor.cs and thought I solved everything. However, the prefab I am attaching to Building.cs is not seen by Builder.cs no matter what I try. I get the error:
    "ArgumentException: The Object you want to instantiate is null.
    UnityEngine.Object.CheckNullArgument (System.Object arg, System.String message) (at C:/buildslave/unity/build/Runtime/Export/UnityEngineObject.cs:238)
    UnityEngine.Object.Instantiate (UnityEngine.Object original, Vector3 position, Quaternion rotation) (at C:/buildslave/unity/build/Runtime/Export/UnityEngineObject.cs:150)
    UnityEngine.Object.Instantiate[Resource] (.Resource original, Vector3 position, Quaternion rotation) (at C:/buildslave/unity/build/Runtime/Export/UnityEngineObject.cs:205)
    Building.UpdateBuildingState () (at Assets/RTS Engine/Buildings/Scripts/Building.cs:1660)
    Building.CheckBuildingState () (at Assets/RTS Engine/Buildings/Scripts/Building.cs:1600)
    Building.AddHealthLocal (Single Value, UnityEngine.GameObject Source) (at Assets/RTS Engine/Buildings/Scripts/Building.cs:1123)
    Building.AddHealth (Single Value, UnityEngine.GameObject Source) (at Assets/RTS Engine/Buildings/Scripts/Building.cs:1159)
    Builder.Update () (at Assets/RTS Engine/Units/Scripts/Builder.cs:109)"
     
    Last edited: Sep 30, 2017
  19. OussamaB

    OussamaB

    Joined:
    Feb 8, 2013
    Posts:
    1,470
    In my Builder.cs script, the line number 41 is not an if statement, could you specify which is it exactly?

    Thanks for reporting the bug, will be fixed!

    Awesome that you got this solved by yourself. I see you are getting to the asset.
     
  20. A_Akkad

    A_Akkad

    Joined:
    Aug 28, 2017
    Posts:
    45
    Starting line 37 to 44:
    Code (CSharp):
    1. void Update () {
    2.  
    3.         //If the player has a target building, then send him there:
    4.         if (TargetBuilding != null) {
    5.             if (TargetBuilding.Health >= TargetBuilding.MaxHealth) { //If the target building reached the maximum health:
    6.                 //stop building //ANY DEBUG.LOG DOES NOT RUN IN THIS IF STATEMENT
    7.                 UnitMvt.StopMvt ();
    8.                 UnitMvt.CancelBuilding ();
    Of course. Is there a quick work around in the meantime? I'm avoiding updates until my code gets more solid, because as you told me earlier, the updates don't discriminate!

    Thanks! I usually solve my bugs before writing a question on them, but this one almost drove me up the wall and I didn't want to delete the question so maybe someone else can benefit.

    I created 4 new units with their own automated behavior. My next miniproject is adding spells/actions on my units.
     
  21. CPTEliteWarfare

    CPTEliteWarfare

    Joined:
    Apr 9, 2014
    Posts:
    68
    dont know if it is my issue on my end of the spectrum but at spot of my maps my units just get stuck and dont do anything their animations stop playing and everything , only thing that i can do while they are like that is just select them and give them a order but they just still dont move or anything. Ill post a video soon on the issue. We haven't changed anything much in the Unit.cs beside audios and some other Team Based info
     
  22. OussamaB

    OussamaB

    Joined:
    Feb 8, 2013
    Posts:
    1,470
    This if statement has been there since I started creating the RTS Engine. Its function before was the following:
    the builder unit can add 4 health points each second to the building while constructing. Imagine the building's health while being constructed is 48/50 and in the next second, the builder will add 4 health points. So its health will become 52, this if statement makes the builder stop building.

    But right now, the function that adds health to the building checks automatically if the health goes above maximum allowed value and corrects it so this if statement has become kinda useless but I forgot to remove it.

    Thanks for clearing this!

    Since you probably have made changes to a lot of scripts then you can send me these 3 scripts: UIManager.cs, SelectionManager.cs, BuildingPlacement.cs in an e-mail and I will apply the modification to fix that bug and send back to you.

    Let me know how this works out, I would love to see the custom units in action.
    Have you been using the custom events?
     
  23. OussamaB

    OussamaB

    Joined:
    Feb 8, 2013
    Posts:
    1,470
    That is pretty weird. Can't really think of a possible reason for the issue without taking a better look at it. I'll be waiting for the video.
     
  24. A_Akkad

    A_Akkad

    Joined:
    Aug 28, 2017
    Posts:
    45
    Thank you for clarifying! I will see if I can remove this part of the code without screwing up the script.
    I tried to place most of my new code in a custom script to allow me to update safely if I ever choose to, in the future! I do have some minor code in SelectionManager.cs and BuildingPlacement.cs but haven't edited UIManager.cs yet. Thankfully, I also have a .doc detailing where I made changes in the RTS Engine code, although its not accurate because line numbers change as you add/change code! But it still helps.
    Would it be possible for you to tell me how to update it myself (so I can learn), or would it be easier for you if I email them to you?
    Oh you flatter me! They are simple units (animal placeholders, I lack any animation knowledge so I need to either save enough money to hire one or learn to do it myself) who I coded to reproduce, eat, move around automatically, and get slaughtered. Hence why I started trying to implement a "spell" system today for my worker to "slaughter" the animals. I realized today it is a pretty behemoth task for me!
    Maybe you can help see if my logic for going about this is good?
    What I did was study how you implemented your Tasks system, correct me if I am wrong: All the code I need (aside from AI code) would be made/edited within Building.cs. To make the RTS Engine respond to my new "spell" tasks, I would add a BuildingTasksList.TaskType.Spell/Action to the enums, then I would follow what you did to the BuildingTasks.CreateUnit code, and do the same for the BuildingTasks.Spell code. Right?
    What is the difference between TasksQueue and BuildingTasksList? What does the Custom Panel do exactly? On line 205ish, what does this variable stand for: public bool Upgrade = false;? Speaking of AI, is there any AI code within Building.cs. I ask, because some of the code I do not understand, and my guess is it is code only for the NPCManager?

    Regarding your question on Custom events, I am still pretty new to this. I know there is an Events feature for unity/C#, but I still need to study it. Thank you for reminding me! I went over your CustomEvents.cs, which is pretty cool. I can imagine how it can be very useful, but is there a specific use for it I can implement to make my life easier? From my perspective as a newb developer, it would be really useful as a counter, for example to count how many units there are on the map?
     
  25. JOJOMCGEE

    JOJOMCGEE

    Joined:
    Aug 25, 2017
    Posts:
    4
    I'm trying to go through the documentation, but I'm getting a bit confused trying to make things from scratch. Would it be easier to just re purpose the units and buildings that already exist and am I able to change the name and code of the units and buildings without destroying everything?

    Even better is there a way to start from scratch so I don't have the demo map?
     
    Last edited: Oct 2, 2017
  26. OussamaB

    OussamaB

    Joined:
    Feb 8, 2013
    Posts:
    1,470
    Well to fix the bug, I had to modify some small things here and there but yeah I am gonna explain each one for you. However I updated the fix and it turns out that it can be easily fixed by doing a simple change:

    In the SelectionManager.cs script, here in line 118, you normally have:

    Code (csharp):
    1.  
    2. if(Input.GetMouseButtonDown(0)) //If the player preses the left mouse button
    3.  
    Now I changed that to:

    Code (csharp):
    1.  
    2. if(Input.GetMouseButtonUp(0))
    3.  
    The reason is that allows me to avoid making the player select the newly placed building as it is built (because the selection mouse button is the same one of the button you press to place the building on the map).

    If it something that is linked to the asset's workflow then I am more than happy to help. But for specific custom requests, that depends on how much time I have.

    You also need to deal with the TaskManager.cs which handles tasks for buildings and the UIManager.cs (both to draw the task and to handle what happens when the player presses).

    Now this gave an idea for a new feature, I am thinking about having the ability to have custom tasks which you can assign to buildings/units and each time the task is completed, a custom event will be called from where you can put your own code.

    Tasks Queue holds the pending tasks for the building and Building Tasks List holds the definitions of the tasks that the building can launch. For example, you can have 3 elements in the Tasks Queue and the three have the same job: to create a civilian. However you only have one task defined in the Building Tasks List that defines how you can create a civilian.

    The custom panel was requested by one of the RTS Engine users. It allows to launch tasks from any building without having to select the building but rather using a panel that can activated and hidden using a button. It also makes use of the RTS Engine custom events and shows how you can work with them.

    That differentiates a normal task from a task that upgrades an already existing task. (Example, the Soldier 1 in the Barrack can be upgraded to a Robot). When you launch a task that creates the Soldier 1, that bool will be false but when you launch the upgrade of the Soldier 1 to a Robot then you'd have Upgrade set to true.

    Some NPC code exists in normal scripts as well.

    Each time a major action happens (building has been placed, unit has been created, unit has been selected) a custom event will be called. Search how you can use delegate events, you'll find tutorials in the Unity Documentation (example: https://unity3d.com/de/learn/tutorials/topics/scripting/events). So yeah using the event that is called when a unit is created and the one that is called when the unit is dead, you can have a counter for units in the map.

    Please note each event is called with a handful of parameters from where you can access attributes of the object related to that event. (For example, when a unit is created, the whole Unit.cs component is passed in the params so you can access the unit's name, code, faction from that parameter).

    Hopefully I answered all your questions.
     
  27. OussamaB

    OussamaB

    Joined:
    Feb 8, 2013
    Posts:
    1,470
    Yes, you can start creating units, buildings and resources starting from the ones that are available in the demo. I honestly think it's the easier way to go and most RTS Engine users do this as well (you can use the docs in this case to check when you don't what a field on the inspector exactly does).

    If you read the documentation from the beginning, you'll see that it's all about creating a scene from scratch. You start with placing the game managers and then start creating an instance of each object (unit, building and resource), at the end it handles dealing with menus.
     
    Paul-Swanson likes this.
  28. Paul-Swanson

    Paul-Swanson

    Joined:
    Jan 22, 2014
    Posts:
    319
    Btw if anyones interested...
    I wrote a quick tutorial on how to make Command and Conquer like Unit/Building/Abilities Icons, Much like my Avatar on this forum.
    Its just a 3 step process, Iv posted the how-to on my Wordpress...
    https://paulswansonblog.wordpress.com/2017/08/13/3-todays-task-icons/

    I'll also be posting on there sometime soon. My method for making classic type maps using web colors combined with height maps for plateaus all in photoshop.
     
    Last edited: Oct 2, 2017
    OussamaB likes this.
  29. A_Akkad

    A_Akkad

    Joined:
    Aug 28, 2017
    Posts:
    45
    Perfect!
    On line 118 in the SelectionManager.cs, I have this code
    Code (CSharp):
    1. SentBuilder = true;
    2.                                                                 } else {
    3.                                                                     MaxBuildersReached = true;
    4.                                                                     //if the max builders amount has been reached.
    5.                                                                     //Show this message:
    6.                                                                     UIMgr.ShowPlayerMessage ("Max building amount for building has been reached!", UIManager.MessageTypes.Error);
    7.  
    8.                                                                 }
    The nearest code similar to the code you asked me to change is "if (Input.GetMouseButtonDown (1) || Input.GetMouseButtonDown (0)) {" on line 85. Am I looking at a different script?

    My question "if you were willing to help" was referring to the following questions in that text about the engine, haha. I was not asking you to write the code for me :) Thank you for the offer though! In addition to developing my RTS game, my goal is to learn how to become a Unity Developer, and to do so I have chosen the RTS Engine to help. But eventually I want to learn how to develop games autonomously, and I want to code myself wherever possible. I can concede that there are a lot of mechanics which are not in my ability to code, like most of your RTS Engine asset. It is pretty intricate.
    The current great support you provide on your asset should suffice for the time being. Like I mentioned earlier though, I think I will have to talk to artists/animators to actually polish my game.

    Yes. I am having a very hard time wrapping my head around the tasks system in this engine. It appears that most of the task code actually lies in the UIManager.cs, correct? So to add a 'spell' to my civilian/worker/builder unit I would start from the UIManager and do a code similar to this one on line 432:
    Code (CSharp):
    1. if (SelectedBuilding.gameObject.GetComponent<APC> ()) {
    2.                     int TaskCount = 0;
    3.                     if (SelectedBuilding.gameObject.GetComponent<APC> ().CurrentUnits.Count > 0) {
    4.                         TaskCount++;
    5.                         if (......
    6.  
    Instead of if (SelectedBuilding.gameObject.GetComponent<APC> ()) { it would be ]if (SelectedBuilding.gameObject.GetComponent<Civilian> ()) { and I would write my own behavior? Then from there I would follow up the code in the TaskManager.cs too. What I mentioned earlier about the Buildings "
    gravitytr1 said:
    What I did was study how you implemented your Tasks system, correct me if I am wrong: All the code I need (aside from AI code) would be made/edited within Building.cs. To make the RTS Engine respond to my new "spell" tasks, I would add a BuildingTasksList.TaskType.Spell/Action to the enums, then I would follow what you did to the BuildingTasks.CreateUnit code, and do the same for the BuildingTasks.Spell code. Right?" Would only apply if I wanted to make spells for the buildings themselves? For now I think I should start small and just make my units able to do spells, but I am having trouble knowing where to start.
    To reiterate, I would start by 1. making a spell option in UIManager.cs for my civilians, under LaunchTask() and using an if(TaskType == TaskManager.TaskTypes.Spell)). 2. Add a TaskTypes to the enum line 11 in TaskManager.cs and 3. ??? (I'm still working on this theory)
    This logic works so far, right?

    That's the cool things about forums! Discussions can be very beneficial to every participator :D
    That idea sounds great. I took some time today to go back to learning about the events system (FYI, the link you posted was localized to Germany). I feel like I understand how it works, but not where/why I can benefit from it. Looking at your code in CustomEvents.cs, you do not seem to be using events for the engine, right? You simply have the events infrastructure set up? The reason I ask is because I wanted to see an example of it being used within the confines of your asset. I just realized you already told me that you used the events system in CustomPanel.cs. I am using it to learn more about the cool custom events. FYI, documentation is pretty much non-existent in CustomPanel.cs :(
    Also, what does this do: "= delegate {};" I tried googling it but no one really talks about it and both the delegate and events tutorials on Unity do not mention it. You use it several times in your code.
    Personally, it might be prudent to implement a spell system for units since a lot of RTS's utilize one (another customer of yours suggested it too earlier in this thread) or to write documentation facilitating it. If I successfully develop a spell system, I can share it here too and you can simply use it in your asset, if you want. However, my code might not be up to standards :p

    I cannot stress enough how helpful your answers are!
    There is no similar list for units as the BuildingTasksList, right?
    The custompanel is actually a very good example for me to mimic, so thanks for implementing that and thanks for whomever suggested it.

    Last question for today: In the UIManger documentation, scroll down to "
    • Create a new UI Button object and make it a child of the “Task Buttons Parent” object and drag and drop it to the “Base Task Button” field then apply the below settings to it:
    1. Add the “UnitTaskUI.cs” script to it.
    2. In the “On Click” event of the “Button” component, drag and drop the base task button as the event source and set the event to “UnitTaskUI” -> “LaunchTask”.
    3. Add an “Event Trigger” component to the base task button object. Add a “Pointer Enter” event type, have the base task button as the source and set the event to “UnitTaskButton” -> “ShowTaskInfo”. Add a “Pointer Exit” event type, have the base task button as the source and set the event to “UnitTaskButton” -> “HideTaskInfo”."
    Is this the process for changing the white square placeholder task button? If so, why would I want do that?

    Can you please notify me when you write the Custom Event Documentation?
    Regarding my spell system and custom events, I could not figure a way, logically, to use events to facilitate spells. I think I will stick to implementing a spell system using your tasks. Eventually, after I complete the spells, I plan on making a custom inventory system for units which is when the custom panel should come in handy and a keyboard shortcut system (maybe using events!) similar to WC3.
     
    Last edited: Oct 2, 2017
  30. A_Akkad

    A_Akkad

    Joined:
    Aug 28, 2017
    Posts:
    45
    Thanks! It is still too soon for me to need that, but when I do I will check it out!
     
  31. jobo22

    jobo22

    Joined:
    Dec 1, 2016
    Posts:
    83
    Hi guys, I don't have this asset yet but am planning on buying it pretty soon. I have a question about the faction colors, and how you guys did it. I see in the documentation it says to drag a mesh into the "Faction color objs". Doing it this way instead of just a material slot makes it so you can't make your units out of just one mesh. Just curious on how you guys made your units, especially units like infantry and civilians.
     
  32. Paul-Swanson

    Paul-Swanson

    Joined:
    Jan 22, 2014
    Posts:
    319
    So here's how I did mine.
    When I'm in 3ds program I make my objects MultiSub. I assign my textures based on PolyGon IDs.
    Then when I'm happy with how its sectioned off, I detach those polys that will indicate the team color.
    I make a mental note that when i switch over to my texture program those need to be assigned white for maximum color coverage. And the rest I do normal.
    The reason I separated was so that with my faction Color OBJs would be a separate mesh and I can just drag that in there. Its a really convenient way to do it once you get used to detaching polygons. It doesnt hurt anything and you can still texture everything together on the same UV space.

    For infantry just make them a backpack or helmet and use that as the Color Object. Something that you can see from far enough away and is a significant object that helps identify what it actually is. The silhouette is key.
     
    Asledziu and OussamaB like this.
  33. OussamaB

    OussamaB

    Joined:
    Feb 8, 2013
    Posts:
    1,470
    Would be awesome to share this as well. Thank you!
     
  34. OussamaB

    OussamaB

    Joined:
    Feb 8, 2013
    Posts:
    1,470
    Oh I am really sorry, I meant the "BuildingPlacement.cs" script instead.

    So if your units are going to cast the spells, why do you need to define the task in the building? (Maybe I missunderstood something, please correct me).

    Here's some useful tutorial about delegates and how they are used as events and callbacks:

    http://unitydojo.blogspot.de/2015/03/how-to-use-delegates-in-unity-like-boss.html


    I actually have a complete spell system asset called S-Spell on the asset store (shameless promotion haha).
    But yeah I've considered merging both assets and bringing the spell system to the RTS Engine. But it does not sit at the top of my to-do list right now. So can't really promise anything right now.

    Not sure what you mean here.

    This allows you to set up the UI Manager from scratch (simply adding a UIManager.cs script to an object and start filling the fields in the inspector) and explains how everything works UI-wise. So no it's not a way to replace the placeholder task button.

    Sure, I am supposed to just write a small tutorial on how you can use the events but keep forgetting to do that. Sorry for the inconvenience. I will make sure to contact you when I do so.

    It would be awesome to share things you made to other users when you feel like it.

    Keep up, you are really getting used to the RTS Engine and making of the most out of it.
     
    Last edited: Oct 3, 2017
  35. jobo22

    jobo22

    Joined:
    Dec 1, 2016
    Posts:
    83
    That seems like a great way to do it! Thanks tons! I also read your website on how to make the icons and it seems easy as well. :)
     
  36. A_Akkad

    A_Akkad

    Joined:
    Aug 28, 2017
    Posts:
    45
    No problem at all, it wasn't a time sensitive bug. 1. However, your code did not work for me. To double check, in BuildingPlacement.cs I edit line 125 (for me) from
    Code (CSharp):
    1. else if(CurrentBuilding.CanPlace == true) //If the player can place the building at its current position:
    2.             {
    3.                 if(Input.GetMouseButtonDown(0)) //If the player presses the left mouse button
    4.                 {
    5.                     if(CheckBuildingResources(CurrentBuilding) == true) //Does the player's team have all the required resources to build this building
    To

    Code (CSharp):
    1. else if(CurrentBuilding.CanPlace == true) //If the player can place the building at its current position:
    2.             {
    3.                 if(Input.GetMouseButtonUp(0)) //If the player presses the left mouse button
    4.                 {
    5.                     if(CheckBuildingResources(CurrentBuilding) == true) //Does the player's team have all the required resources to build this building
    My builder still needs to be reselected.

    Thanks! I already checked out his explanation of events! It is a good post to support what I learned from the Unity tuts. But I never reached far enough to see the = delegates {} portion of his post until you posted it. He mentions that " instead of the null check (and the potential bugs from forgetting it) you can initialize it like this: "event SimpleDelegate OnTestEvent = delegate {};"", however, you still do null checks "if (GameMgr.Events != null)"in addition to the = delegate{};. 2. Why is that?

    3.
    What does this do? (in the APC.cs)
    Code (CSharp):
    1. void Start ()
    2.     {
    3.         GameMgr = GameManager.Instance;
    4.         if (gameObject.GetComponent<Unit> ()) {
    5.             FactionMgr = GameMgr.Factions[gameObject.GetComponent<Unit> ().FactionID].FactionMgr;
    6.         }
    7.         else if (gameObject.GetComponent<Building> ()) {
    8.             FactionMgr = GameMgr.Factions[gameObject.GetComponent<Building> ().FactionID].FactionMgr;
    9.         }
    10.     }
    the gameObject here refers to the APC, right? Why would it have a building component?


    That's pretty cool! Since you already have and own the code the RTS asset should definitely include it! For me, it is definitely a lot of features I do not need at the moment. I just need a simple system to add spells to my units. After these couple of days worth of work, I think I am finally getting the hang of writing a spell for my units. Even have a little guide I am working on incase I want to add more spells in the future. It is not a complete system, just adding tasks to my units. Its very non-intuitive because most of the work is in the UIManager.

    Yes, haha, I understand what you mean. At first, I thought I had to port the buildingtaskslist concept for units. During this process I discovered APCs, whom basically have spells (to manipulate other units). Thus, I don't need a buildingstasks for my units, since you already have a system implemented to help with unit tasks. Does that make sense? That is why I shifted over to focusing only on units instead of buildings and units.

    Okay, that makes sense.

    It would be my honor! If there is something in particular a user wants they can feel free to ask. I won't share anything that can hint at what my RTS game is about, but I can share things like the inventory system (if I ever build it) etc. I can also share my guide if someone wants it.

    I reached the stage now where I have to code my spell in the LaunchTask when my spell is actually clicked on. I will start on that tomorrow, I want to be able to click on the unit I want the spell to be used on after clicking on the spell task in the task panel. Do you have any similar code in the RTS Engine?
    Any plans for a Fog of War update?
     
    Last edited: Oct 3, 2017
  37. CPTEliteWarfare

    CPTEliteWarfare

    Joined:
    Apr 9, 2014
    Posts:
    68
    There a asset that can be used with this RTS asset. :)
     
    OussamaB likes this.
  38. CPTEliteWarfare

    CPTEliteWarfare

    Joined:
    Apr 9, 2014
    Posts:
    68
    sorry for long reply been busy with IRL things , but ill post a video soon on it once i redo the map just incase its a map problem :)
     
  39. OussamaB

    OussamaB

    Joined:
    Feb 8, 2013
    Posts:
    1,470
    That is weird, I've done a lot of changes to multiple scripts related to the building placement so I am not really sure which lines you need to change to keep your modified code. I will double check once I have my computer.

    Checking if (GameMgr.Events != null) has no relation at all with defining the delegate event. In fact I don't even have them in the same script.
    Before I call a custom event (from the CustomEvents component to which I refer to as GameMgr.Events) I simply check if the CustomEvent.cs component exists in the scene by doing that of statement to avoid any kind of error if one of the users decides not to use that script.

    The APC can be either a unit or a building.

    Yup. You only need to focus on units fo this matter, not buildings.

    Yes, but not really sure exactly when as it's not a priority now.
     
  40. A_Akkad

    A_Akkad

    Joined:
    Aug 28, 2017
    Posts:
    45
    Thank you.

    Ah, that makes sense. Thank you.

    As in, you can have buildings that can contain units (such as bunkers) be APCs too, without having to rewrite the APC code for buildings. That's a great idea.

    One question regarding the Task Categories you have set up. Using your system, I should be able to place my task (in this case, the spell) in whichever category I like. How exactly do you do that? I reviewed your documentation and code, and thought I understood it, but it just isn't working out for me.
    In this case, I want to put it in the opposite corner of my task panel which would be the bottom right corner, since the buildings start populating in the task panel from the top left. This is the code I am using on line 813 of UIManager.cs:
    Code (CSharp):
    1. SetTaskButtonParent (LastTaskID, 1); //fix so that its on the 3rd line
    2.                     Debug.Log ("LastTaskID is " + LastTaskID);
    3.                     //SetTaskButtonParent (0, 1); //fix so that its on the 3rd line
    4.                     TaskButtons [LastTaskID].gameObject.SetActive (true);
    5.                     etc.................
    Eventually, after I gave up, I tried experimenting with random numbers in the "SetTaskButtonParent (LastTaskID, 0);" but all that does is place my task inside another task. Currently, with the above code, I managed to place the task/spell right after the last building task icon.
    I already created a "Category3" in the scene under Canvas->TaskPanel. But I cannot find where you define "public Transform[] TaskParentCategories;", only its declaration.

    EDIT: I don't know if it helps, but the LastTaskID debug prints out 8. (because there are by default 8 buildings in the asset)
     
    Last edited: Oct 5, 2017
  41. OussamaB

    OussamaB

    Joined:
    Feb 8, 2013
    Posts:
    1,470
    At this point it would be much better to send me the UIManager.cs, SelectionManager.cs and BuildingPlacement scripts that you have and I'll modify them and let you know what exactly changed. I've a few changes here and there and need to check what changes are actually related to the bug so we don't waste more time on this.

    Exactly!

    Well to start, LastTaskID and Task Categories are two completely different things. If you want to create a new Task Category Parent, then create a UI object as a child object of the Selection Panel, add the Group Grid Layout component to it and then drag and drop it in the TaskParentCategories field in the UI Manager inspector then the order of that category in the list (starting from 0) is its ID. So when you're asked to set the task parent category, you use that ID.

    (is it not explained like this in the docs? if it's unclear then no problem, just please let know so I can expalin it another way)

    P.S: using an ID of -1 will place the task under the default task parent (which is usually the whole task panel)
     
  42. A_Akkad

    A_Akkad

    Joined:
    Aug 28, 2017
    Posts:
    45
    Will do.

    You do a great job explaining, for me that is not the problem. My only issue is sometimes I do not know what you are explaining, haha. For example, I read the same document yesterday but did not realize that "Task Parent Categories:" in the UIManager documentation refers to the same thing I needed documentation on, so I only read until "Task Buttons:". When reading it today again, after reading your answer, then it makes sense. Also, "Create a new UI Button object and make it a child of the “Task Buttons Parent”" I only understood what that meant after messing around with the asset AND reading your answer. I recall being confused yesterday as to what it meant. Now I realize it means "make it a child of the gameobject in the Task Buttons Parent field."

    1. However, I still do not understand how to move the task to the right. I managed to actually use the 3rd category. So it is in the third line, but on the left.

    In Unit.cs, line 127+:
    Code (CSharp):
    1. BuilderMgr = GetComponent <Builder> ();
    2.         HealMgr = GetComponent<Healer> ();
    3.         ConvertMgr = GetComponent<Converter> ();
    4.         APCMgr = GetComponent<APC> ();
    5.         ResourceMgr = GetComponent<GatherResource> ();
    6.         AttackMgr = GetComponent<Attack> ();
    7.         HerdMgr = GetComponent<HerdBehavior> ();
    2. How do we not get errors when the game looks for an APC component, for example, when there are no such components attached? (I did a debug and there was no APC component defined, maybe I am just ignorant of how Unity deals with such things.)
    3. Out of curiosity, why did you choose to retrieve the scripts off of "GameMgr = GameManager.Instance;" rather than creating fields (which you did, but hid with the [HideInInspector]) and dragging the gameObjects to the fields in the inspector?
    The reason I ask is because I had to create a new script to solve a problem that I've been working on for a while, and I had to drag the UIManager into the Inspector field. Copying and pasting the
    Code (CSharp):
    1. //Scripts:
    2.     public UIManager UIMgr;
    3.     [HideInInspector]
    4.     public GameManager GameMgr;
    and
    Code (CSharp):
    1. GameMgr = GameManager.Instance;
    2.  UIMgr = GameMgr.UIMgr; //why is this null?
    gave me a nullreference error, even though it is literally the same as the code that came with the asset!
     
    Last edited: Oct 5, 2017
  43. OussamaB

    OussamaB

    Joined:
    Feb 8, 2013
    Posts:
    1,470
    Select task buttons parent object and in the inspector: Grid Layout Group component -> Start Corner -> Upper/Lower Right.

    You won't get an error if a unit does not have a APC component. Before accessing the APC component of a unity, I check whether the "APCMgr" is null or not. This helps me to avoid using GetComponent each time I need the APC component and when you have multiple scripts using multiple GetComponent many times then it's going to be bad for the performance. (It does not make a big difference with the CPUs we have nowadays but even if it does contribute slightly to improve the performance then I prefer to use it).

    For two reasons actually:
    1) this allows me to make the Game Manager component a singleton (Because I only need one instance of that component per map and having multiple Game Manager components by mistake could cause Chaos).
    2) This also allows me to avoid using the FindObjectByType (which is pretty bad for performance) to link the Game Manager with other scripts (so I use GameManager.Instance instead) and it allows me to get all the other scripts from the Game Manager by doing so (as all main scripts are connected to the Game Manager and they are then connected with each other by the intermediate of the Game Manager).

    If you placed that in the Awake () void of a new script then it will most likely to cause an error because the Game Manager needs to finish his Awake () before the other scripts start their (as I explained above, the Game Manager is the middle man that all scripts use to communicate with each other).
    Therefore, go to Edit -> Project Settings -> Script Executions Order and add your new script in the list (make sure it is after Game Manager).

    ------

    At one point I'm going to use all your questions and maybe add new documentation dedicated for code modification. So keep them coming!
     
  44. OussamaB

    OussamaB

    Joined:
    Feb 8, 2013
    Posts:
    1,470
    Documentation has been added for custom events: http://soumidelrio.com/docs/unity-rts-engine/custom-events/

    -----

    Update 1.1.6 has been submitted. Here is the update list:

    - Fixed portal buildings selection.
    - Healer and Converter new behavior: healers and converters can now search for units on their own within a certain range and heal/convert them.
    - Added a new custom event for the Converter component.
    - NPC armies can now take healers and converters with them to attack buildings.
    - Added a new NPC component: NPC Unit Spawner. It allows to spawn custom units like healers, converters and APC units depending on certain settings in the inspector.
    - You can now require to have buildings placed in order to launch another building upgrade: useful for age upgrade.
     
  45. A_Akkad

    A_Akkad

    Joined:
    Aug 28, 2017
    Posts:
    45
    I will send you the files soon. Can you please keep any information related to the nature of my game (other than what I have shared freely on this forum) confidential? On a personal level, this is very important to me. I already reviewed the code and it shouldn't contain much information, as I have made a large effort to have all new code encapsulated in new separate scripts. (mainly so I can update the game with your updates in the future, should the need arise)

    Thanks, that worked, but I also had to change Child Alignment.


    Okay, that makes sense. I just do not understand why Unity does not freak out when it calls "BuilderMgr = GetComponent <Builder> ();" when there is no Builder component.
    And from experience, optimization is very important. So I am glad you do your best to minimize high overhead commands! It is a good practice I am trying to employ in my code too, regardless of how powerful modern CPUs are.


    I had to look up some things on google to understand better, but that makes complete sense! Thank you. It is interconnected with this:
    Which also helps a lot. I revised my code to make sure there is only one instance of the UIManager. Speaking of which, since I just learned about this from you, is there a method to see (at game launch) how many instances of an object or script there are? Just to make sure its optimized well.

    I am still trying to wrap this around my head. How exactly do you have the Game Manager act as a central hub or intermediate?
    And what does this code "if (ResourceMgr != null)
    ResourceMgr.GameMgr = this;" do on line 132 of the Game Manager? I already understand what this does:
    Code (CSharp):
    1. //set the instance:
    2.         if (Instance == null) {
    3.             Instance = this;
    4.         } else if(Instance != this) {
    5.             Destroy (gameObject);
    6.         }
    Is that related to line 132?

    That makes me really happy! Documentation on code modification would help A LOT. I might not benefit from it by the time it is out, but others definitely will. And from how things are going, I think I will have a lot more questions as time goes by and as I modify the engine even more.
    Speaking of which, I am planning on adding a "simple" State Machine to my game next, as it should help me when I add more functionality to the game and further modify the engine. It should also help me remove some more code I have placed in the original engine assets and allow me to place them in separate scripts. Assuming this is not too big a task for me!

    Perfect.
     
  46. OussamaB

    OussamaB

    Joined:
    Feb 8, 2013
    Posts:
    1,470
    Don't worry, I won't be sharing your code with anyone.

    It does not freak out the GetComponent can return either the component that has been called or null if the component is not found. And BuilderMgr (type of Builder.cs) can have "null" as its value. But when it's null and you try to access it, there you have a couple of issues. That's why it's always recommendes to check if the component exists before trying to access its attributes or call something inside that component.

    You can use FindObjectsOfType which will return an array that has all the instances of that component inside the scene. The length of that array is the amount of the instances of that component.

    I simply avoided having to call FindObjectOfType in each component (because most classes need access to multiple other classes and multiple FindObjectOfType calls is pretty for performance) and made sure that Game Manager is connected to all major components. So when a class wants to access another class, it does that by the intermediate of the Game Manager. The Game Manager also holds important information about the local player and all factions present in the map.

    Just checks if there's a resource manager and then directly assign the game manager to it because the resource manager initializes very early (directly after the game manager) and needs the game manager to start as it needs access to the faction list.
     
  47. A_Akkad

    A_Akkad

    Joined:
    Aug 28, 2017
    Posts:
    45
    Haha, thanks. You flatter me :D, but I said the nature of the game, not the code. The code I produce won't be of much use to anyone at this stage, and like I noted, most of my functional code are in separate scripts anyways. 1. By nature of the game, I mean what the game is about, and what it involves. I do not plan on releasing those details to anyone.

    2. What is the function of MvtTargetObj?
    3. Currently, if there are uncontructed buildings around the civilian (for example, after using shift to place multiple compies) the builder ignores them until told otherwise. Is there an autobuild function that allows the civs to automatically finish buildings after creating multiple copies?
    4. I have coded drag and place grided walls, but after realizing just how complicated it would be to integrate that into the engine, I want to use two types of walls (horizontal, and vertical) to manually just build small walls. However, it is difficult to use the shift function to create multiple copies of these walls because the "undercontruction" model that appears as a placeholder is too LARGE. So I edited them under the prefab, and resized them. But when I launch the game they revert to their original size! How can I solve this issue? Below are pictures that might help clarify my goal to you.
    upload_2017-10-9_12-50-26.png
    upload_2017-10-9_12-51-27.png
    FYI: The game did not allow me to build buildings with different rotations (such as the vertical wall). I had to change the BuildingPlacement.cs StartPlacingBuilding function code to:
    Code (CSharp):
    1. //make sure we have enough resources
    2.         if (CheckBuildingResources(AllBuildings [BuildingID].GetComponent<Building>()) == true) {
    3.             GameObject BuildingClone;
    4.             Debug.Log ("THIS BUILDING IS " + (AllBuildings [BuildingID].GetComponent<Building>().name));
    5.             //Spawn the building for the player to place on the map:
    6.             //custom code PARTIALLY
    7.             if (AllBuildings [BuildingID].GetComponent<Building>().name != "Fence Barn Vertical") {
    8.                 BuildingClone = (GameObject)Instantiate (AllBuildings [BuildingID], new Vector3 (0, 0, 0), Quaternion.identity);
    9.                 LastBuildingID = BuildingID;
    10.                 BuildingClone.gameObject.GetComponent<Building> ().FactionID = GameManager.PlayerFactionID;
    11.             } else { //if the building is called "Fence Barn Vertical" THEN BUILD IT WITH DIFFERENT ROTATION
    12.                 BuildingClone = (GameObject)Instantiate (AllBuildings [BuildingID], new Vector3 (0, 0, 0), Quaternion.AngleAxis(90, Vector3.down));
    13.                 LastBuildingID = BuildingID;
    14.                 BuildingClone.gameObject.GetComponent<Building> ().FactionID = GameManager.PlayerFactionID;
    15.             }
     
  48. A_Akkad

    A_Akkad

    Joined:
    Aug 28, 2017
    Posts:
    45
    It took a while to wrap my head around this, but I understand it now. Thank you!

    Okay, I will start doing that from now on. Makes a lot of sense.
     
  49. OussamaB

    OussamaB

    Joined:
    Feb 8, 2013
    Posts:
    1,470
    When you command unit(s) to move to a certain destination, a little green square appears and starts blinking for a few seconds at the destination. That is the MvtTargetObj (name sounds confusing yes).

    That behavior for builders is currently not available, planning to add it though. Thanks for the suggestion.

    I can't think of anything that might be causing this issue. Just resized a under construction in one if the buildings and it worked. Can you tedt this on another building and see if you get the same issue?

    ---

    For that problem about updating the task panel for builders after placing a building, just go to the "PlaceBuilding ()" funciton in the "BuildingPlacement.cs" script and add the line below at the end of the function.

    Code (csharp):
    1. IsBuilding = false;[CODE]
     
  50. OussamaB

    OussamaB

    Joined:
    Feb 8, 2013
    Posts:
    1,470
    Just wanted to let you all know that the new update is live on the asset store!