Search Unity

TurnBased-Toolkit (TBTK)

Discussion in 'Assets and Asset Store' started by Song_Tan, Aug 11, 2013.

  1. Song_Tan

    Song_Tan

    Joined:
    Apr 9, 2011
    Posts:
    2,993
    I don't understand what exactly are you trying to do.

    The problem is reloading the scene. The unit in the unitList are actual unit in the scene. If you load a new scene, or reload, they would have been destroyed. Leaving you with a list with empty references.
     
    Stexe likes this.
  2. guihaoh

    guihaoh

    Joined:
    Oct 4, 2021
    Posts:
    18
    First of all, I want to make a TRPG game using this system. Before entering combat, there will be a screen where players can choose to add deployable units. After this, players will enter the deployment phase where they can place the units they are currently able to deploy. What I want to do is, before officially entering combat, to have the functionality to edit, add, reduce, or change the units that players can deploy. For example,player can bring a maximum of 6 characters into battle for deployment, but they have a total of 10 characters. They must choose 6 of these before entering the deployment phase.

     
  3. Song_Tan

    Song_Tan

    Joined:
    Apr 9, 2011
    Posts:
    2,993
    I suggest you take a look at the documentation, page-22 (integrating TBTK to your game). As well as the example scenes - Demo_Persistent_Game and Demo_Persistent_PreGame. You can use the existing caching system to save the player starting unit for the next scene.
     
    Stexe likes this.
  4. guihaoh

    guihaoh

    Joined:
    Oct 4, 2021
    Posts:
    18
    Finally, I figured out how it works. BTW, If I want to generate something at the end of a turn, where should I insert this generation function? This function needs to use getGameObject. However, all the turn-ending functions I've found so far are static.
     
  5. Song_Tan

    Song_Tan

    Joined:
    Apr 9, 2011
    Posts:
    2,993
    Hard to say, it depends what you want to generate. While the functions are static, The key component like GameControl, TurnControl, UnitManager are singleton. That means you can use the variable instance in each of the corresponding script to get access to the instance. See EndTurn() in TurnControl.cs for example. You access the non static function _EndTurn() by using instance._EndTurn();.
     
  6. guihaoh

    guihaoh

    Joined:
    Oct 4, 2021
    Posts:
    18
    But my thought is to insert my Generation() in EndTurn(), or are there other ways?
     
  7. Song_Tan

    Song_Tan

    Joined:
    Apr 9, 2011
    Posts:
    2,993
    I'm not sure I understand your question. You can do just that. If you have a local reference, just put it in _EndTurn(). It's the same thing.
     
  8. guihaoh

    guihaoh

    Joined:
    Oct 4, 2021
    Posts:
    18
    May I ask how did you implement AI using skills, I am figuring out it.
     
  9. guihaoh

    guihaoh

    Joined:
    Oct 4, 2021
    Posts:
    18
    Could you please tell me where I should add new features if I want to modify the criteria for a unit attacking an enemy?
    I need to call the enemy's transform when a unit attacks an enemy unit. Then, compare the Y-axis positions of the enemy and my unit to ensure that the unit positioned higher inflicts more damage on the unit positioned lower.
     
  10. Song_Tan

    Song_Tan

    Joined:
    Apr 9, 2011
    Posts:
    2,993
    The code for AI is all in AI.cs. Specifically, the function AnalyseAction() where the method determine what action the unit should perform. It's a score based system that determine which would be the best action based on the score given to each action. What you need to do is modify the existing section for calculating the attack score, by taking the target y-axis position into consideration.
     
  11. guihaoh

    guihaoh

    Joined:
    Oct 4, 2021
    Posts:
    18
    Hello, I want to create a skill that allows teleportation back to a specified unit's position from the previous turn. My idea is to generate a unique GameObject under each unit's feet at every turn to record their traveled positions. Then, when using the skill, clicking on these GameObjects to teleport. However, my problem is that although the unit's GameObject is teleported to the specified position, the unit's position on the board does not change. How can I solve this?
     
  12. Song_Tan

    Song_Tan

    Joined:
    Apr 9, 2011
    Posts:
    2,993
    You can't just move the gameobject. The position change has be register to the grid. There's an existing ability 'Teleport' that do its namesake. You can refer to the code to add to your own code. It's in Ability.cs (line 209) and it goes like this:
    Code (csharp):
    1.  
    2. teleportingUnit.node.unit=null;  //clear the origin node of the unit
    3. teleportingUnit.node=newNode;  //assign the unit to the new node
    4. teleportingUnit.node.unit=teleportingUnit;  //assign the new node with the unit
    5. teleportingUnit.GetT().position=newNode.GetPos();  //change the transform position of the unit
    6.  
     
    Stexe likes this.
  13. guihaoh

    guihaoh

    Joined:
    Oct 4, 2021
    Posts:
    18
    May I ask if I want to spawn enemies after a specific number of turns, and enemies only start to act when player units enter a certain range, how should I do it?
     
  14. Song_Tan

    Song_Tan

    Joined:
    Apr 9, 2011
    Posts:
    2,993
    There should be a setting in the 'AI' component on the GameControl object in the scene that allow you to do that. You can set the 'AI Behaviour' to Aggressive and check the 'Require Trigger' option. The enemies should stay dormant until player units get in range.
     
  15. guihaoh

    guihaoh

    Joined:
    Oct 4, 2021
    Posts:
    18
    May I ask why does my unit's attack deplete all AP and movement consumes AP, even though I've disabled 'Consume AP when Move/Attack' in the game controls, but I still have this issue?
     
  16. Song_Tan

    Song_Tan

    Joined:
    Apr 9, 2011
    Posts:
    2,993
    I've just checked. Apparently there's a bug with the code. What you can do is enable both consume AP when move and attack, then set both cost to 0. Sorry for the trouble.
     
  17. guihaoh

    guihaoh

    Joined:
    Oct 4, 2021
    Posts:
    18
    It doesn't work, even I enable consume AP ehen move and attack and setting it whatever 0,1, still will cost 1 ap per move and cost full ap when attack
     
  18. guihaoh

    guihaoh

    Joined:
    Oct 4, 2021
    Posts:
    18
    By the way I want to know how to modify the UI of the level's win or lose, I found that whatever faction 1 win or lose will only display the same UI, but I want to have a continue button if faction 1 win, and only a restart and return to the main menu button if faction 2 lose.
     
  19. Song_Tan

    Song_Tan

    Joined:
    Apr 9, 2011
    Posts:
    2,993
    I'm not sure what happen with the move ap cost. Mine's work correctly. Have you modify the code in anyway? As for attack, do you have the 'End Move After Attack' option turned on. If yes, the ap cost will reduced to 0 after an attack. This is to prevent the unit from performing other action. If you want to disable that, you can modify EndAllAction() in Unit.cs and take out the line ap=0;.

    For the gameover UI. You can modify UIGameOver.cs. In the function _Show(), you can do something like this:

    if(GameControl.winningFacIdx()==0){ //faction 1 wins
    buttonContinue.button.interactable=true;
    buttonRestart.button.interactable=false;
    buttonMainMenu.button.interactable=false;
    }
    else if(GameControl.winningFacIdx()==1){ //faction 2 wins
    buttonContinue.button.interactable=false;
    buttonRestart.button.interactable=true;
    buttonMainMenu.button.interactable=true;
    }
     
  20. guihaoh

    guihaoh

    Joined:
    Oct 4, 2021
    Posts:
    18
    Yeah, I found it works if I turn off 'End Move After Attack' option but moving still cost ap whatever I turn on or off 'Consume ap when move'
     
  21. Song_Tan

    Song_Tan

    Joined:
    Apr 9, 2011
    Posts:
    2,993
    I found another thing. Check your grid, each individual nodes has a move ap cost assigned to them. Make sure yours is 0. You can do this by using GridEditor, select 'Ap Cost' and you will see the cost of each individual node in SceneView.
     
  22. guihaoh

    guihaoh

    Joined:
    Oct 4, 2021
    Posts:
    18
    Thank you. By the way, I have new a question, What does this error mean? When I use the pause menu to restart, and after deployment is completed to officially start the game, this error occurs. Although I can ignore this error and forcefully continue the game, every time I click on a unit, the error occurs again and the game is forcefully paused.

    Here is the error:

    MissingReferenceException: The object of type 'GameObject' has been destroyed but you are still trying to access it.
    Your script should either check if it is null or you should not destroy the object.
    TBTK.UIObject.SetActive (System.Boolean flag) (at Assets/TBTK/Scripts/UI/_UI_ObjectDefinition.cs:52)
    TBTK.UIUnitControl.OnSelectUnit (TBTK.Unit unit) (at Assets/Scripts/UIUnitControl.cs:93)
    TBTK.TBTK.OnSelectUnit (TBTK.Unit unit) (at Assets/TBTK/Scripts/_TBTK.cs:64)
    TBTK.UnitManager._SelectUnit (TBTK.Unit unit) (at Assets/TBTK/Scripts/UnitManager.cs:380)
    TBTK.UnitManager.TBSelectUnit (TBTK.Unit unit) (at Assets/TBTK/Scripts/UnitManager.cs:352)
    TBTK.UnitManager.EndTurn_FactionPerTurn (System.Int32 turnIdx) (at Assets/TBTK/Scripts/UnitManager.cs:293)
    TBTK.TurnControl+<_EndTurn>d__27.MoveNext () (at Assets/TBTK/Scripts/TurnControl.cs:94)
    UnityEngine.SetupCoroutine.InvokeMoveNext (System.Collections.IEnumerator enumerator, System.IntPtr returnValueAddress) (at <3b24cc7fa9794ed8ab04312c53e6dedd>:0)
     
  23. Song_Tan

    Song_Tan

    Joined:
    Apr 9, 2011
    Posts:
    2,993
    Sorry for the slow response. I've been away for most of last week.

    What version of TBTK are you using? Have you done any modification to the code? I don't have the script UIUnitControl.cs in my project. I vaguely remember that is something from older version of TBTK. Anyway it sounds like you there's a static variable in the script that get referenced to something in the scene and didn't get refreshed when a new scene is loaded.
     
  24. Mythica_Spunky

    Mythica_Spunky

    Joined:
    Sep 17, 2013
    Posts:
    3
    Hi, your asset is great. I have some errors & questions though.

    How do you spawn units during runtime? I took a look at the SpawnUnit ability code.

    I created a PlayMaker custom action (through chatGPT). The action kinda works, it spawns the unit prefab onto the field at the gameobject node I set it to, adds it to the UnitManager and UnitList and sets its faction ID properly. I also manually assigned the Node idx & idy (through other PM actions) but the unit still won't get a turn. The game just acts like the unit isn't there at all.

    Here is the PM action code:


    Code (CSharp):
    1. using UnityEngine;
    2. using TBTK;
    3. using HutongGames.PlayMaker;
    4. using System.Collections.Generic;
    5.  
    6. namespace HutongGames.PlayMaker.Actions
    7. {
    8.     [ActionCategory("TBTK")]
    9.     [Tooltip("Spawn a unit from the UnitDB based on its index ID at a specified position and assign it to the specified faction.")]
    10.  
    11.     public class SpawnUnit : FsmStateAction
    12.     {
    13.         public FsmInt unitIndex; // Index of the unit in the UnitDB
    14.         public FsmInt factionID; // ID of the faction to which the unit belongs
    15.         public FsmGameObject targetNode; // The node at which the unit will be spawned
    16.         public GameObject unitManager; // Reference to the UnitManager GameObject in the scene
    17.         [UIHint(UIHint.Variable)]
    18.         public FsmGameObject spawnedUnit; // Variable to store the spawned unit
    19.  
    20.         public override void OnEnter()
    21.         {
    22.             if (unitManager == null)
    23.             {
    24.                 Debug.LogError("UnitManager GameObject is not assigned. Please assign the UnitManager GameObject in the Inspector.");
    25.                 Finish();
    26.                 return;
    27.             }
    28.  
    29.             SpawnUnitByIndex();
    30.             Finish();
    31.         }
    32.  
    33.         private void SpawnUnitByIndex()
    34.         {
    35.             if (unitIndex != null && factionID != null && targetNode != null && targetNode.Value != null)
    36.             {
    37.                 // Retrieve the unit prefab from UnitDB based on the index
    38.                 Unit unitPrefab = UnitDB.GetItem(unitIndex.Value);
    39.  
    40.                 if (unitPrefab != null)
    41.                 {
    42.                     // Instantiate the unit prefab at the target node's position
    43.                     GameObject unitInstance = UnityEngine.Object.Instantiate(unitPrefab.gameObject, targetNode.Value.transform.position, Quaternion.identity);
    44.                     Unit unitComponent = unitInstance.GetComponent<Unit>();
    45.  
    46.                     if (unitComponent != null)
    47.                     {
    48.                         // Assign the unit to the specified faction
    49.                         UnitManager.AddUnit(unitComponent, factionID.Value);
    50.  
    51.                         // Set the UnitManager as the parent of the spawned unit
    52.                         unitInstance.transform.SetParent(unitManager.transform);
    53.  
    54.                         // Store the spawned unit in the FsmGameObject variable
    55.                         spawnedUnit.Value = unitInstance;
    56.  
    57.                         Debug.Log("Unit spawned successfully!");
    58.                     }
    59.                     else
    60.                     {
    61.                         Debug.LogError("Failed to spawn unit. Unit component not found.");
    62.                     }
    63.                 }
    64.                 else
    65.                 {
    66.                     Debug.LogError("No unit found in the UnitDB at index: " + unitIndex.Value);
    67.                 }
    68.             }
    69.             else
    70.             {
    71.                 Debug.LogError("Unit index, faction ID, or target node is not assigned.");
    72.             }
    73.         }
    74.     }
    75. }
    76.  
    Am I missing something?

    Also, for some weird reason, my units deployed have 10 AP (not their full AP at the start of the game), even when in the Unit Editor I put their AP at higher values, like 12 and 14.
     
  25. Song_Tan

    Song_Tan

    Joined:
    Apr 9, 2011
    Posts:
    2,993
    Your code is clearly missing a few steps. Since you are referring to SpawnUnit in Ability.cs, you can see which line are missing.

    First you need to assign a node to the unit otherwise it's not registered to the grid. That's:

    unitComponent.node=targetNode; targetNode.unit=unitComponent;

    Then you need to add the unit to UnitManager otherwise it won't be considered by the game logic. That's:

    UnitManager.AddUnit(unitComponent, 0); //second parameter is the factionID (the one on UnitManagerEditor)
     
    Stexe likes this.
  26. Mythica_Spunky

    Mythica_Spunky

    Joined:
    Sep 17, 2013
    Posts:
    3
    I'm not a great coder, hence the use of chatGPT.

    I can't figure it out. I tried copy-pasting your line:

    unitComponent.node=targetNode; targetNode.unit=unitComponent;

    Couldn't get it to work. How do we ACTUALLY assign the node to the unit? Is the node component inside the Unit.cs script?

    The Ability.cs for SpawnUnit section says:


    {
    if (spawnUnitPrefab != null)
    {
    GameObject obj = (GameObject)MonoBehaviour.Instantiate(spawnUnitPrefab.gameObject, node.GetPos(), Quaternion.identity);
    Unit unit = obj.GetComponent<Unit>();
    unit.node = node; node.unit = unit;
    unit.hp = unit.GetFullHP();
    UnitManager.AddUnit(unit, srcUnit != null ? srcUnit.GetFacID() : facID);
    GridManager.SetupFogOfWar();
    }
    else Debug.Log("No unit prefab has been assigned!!");

    How is it getting the node? I'm sorry that I don't understand. My coding is not great, I am an artist/designer background. I can't find how to assign the node and I've been looking through many of the scripts trying to find where it is actually assigning the node upon instantiating.
     
  27. Song_Tan

    Song_Tan

    Joined:
    Apr 9, 2011
    Posts:
    2,993
    Right. What I was saying is your generated code is missing the line I mention. So you need to add the code to the generated code. It's a copy and paste job but where you paste it matters. So you will need to add them just after the line unitInstance.transform.SetParent(unitManager.transform); in your code.

    Just these copy and paste these 2 will do. I miss read your code the other day so the other one is not required.

    unitComponent.node=targetNode;
    targetNode.unit=unitComponent;
     
    Stexe likes this.