Search Unity

  1. Unity 2019.4 has been released.
    Dismiss Notice
  2. Good news ✨ We have more Unite Now videos available for you to watch on-demand! Come check them out and ask our experts any questions!
    Dismiss Notice
  3. Ever participated in one our Game Jams? Want pointers on your project? Our Evangelists will be available on Friday to give feedback. Come share your games with us!
    Dismiss Notice

Turn Based Strategy Framework

Discussion in 'Assets and Asset Store' started by michal-zetkowski, Jul 2, 2019.

  1. michal-zetkowski

    michal-zetkowski

    Joined:
    Mar 11, 2015
    Posts:
    53
    Regarding Spells, adding new GridState is the first thing that comes to my mind. I see that you have a pretty good understanding of the framework already :)

    I agree that CellGrid could be divided into two or more classes. As for GridState, I don't like it for a few reasons. First of all, the name CellGridState doesn't make much sense. Basically what it does, is disabling and enabling user interaction with the game. I think that spliting CellGrid and extracting this state somewhere else might help. This is a minor issue though, the worst thing is that with this system, AI and Human interaction with the game is completly separated. Take your case for example - if you want to make a "speed" based system, you need to code it separately for AI and Human players (well, I guess that GridState is only a part of the problem here). It would be great if I could come up with a unified system.

    Recently I was asked to code a very basic tic-tac-toe project that would include both AI and Human players. I tried hard to come up with a different approach, but ended up going with similar design. I had separate classes for storing game state and game controller though. There was also a GameState system with just two subclasses - BoardInteractionEnabled and BoardInteractionDisabled. In the end I was quite happy with it, but I guess that it can be done better. I guess I worked with this design for so long that I can't see some obvious flaws in my resoning. I would be great if someone could show me how to approach it in a better way, because I'm sure there is a better way :)
     
  2. michal-zetkowski

    michal-zetkowski

    Joined:
    Mar 11, 2015
    Posts:
    53
    I see that you are using MyUnit script. It was made for the purpose of example scenes and if you want to use them with your models then you will need to make some changes. The lines that you commented out is a part of it.

    Regarding units dropping below grid - take a look at "offset" field in MyUnit. If you set it to 0 then it should be fine.
     
  3. Banksy

    Banksy

    Joined:
    Mar 31, 2013
    Posts:
    357

    --------------------------------------------- ----------------------------------

    Q. How to have a
    unit face in the direction of travel ??

    Note:
    My character's walk animation is triggered each time I click on a destination hex cell & then the animation stops when the unit arrives.. awesome. (I'm sure there' a more efficient method than using tags.. yes ?

    Code (CSharp):
    1. // TRAVEL - Walk Animation is here
    2.         public override void Move(Cell destinationCell, List<Cell> path)
    3.         {
    4.             if (tag == "alien")
    5.             {
    6.                 AlienAnim = this.GetComponentInChildren<Animator>();
    7.                 AlienAnim.SetBool("walk", true);
    8.                 Debug.Log("here");
    9.             }
    10.  
    11.             if (tag == "enemy")
    12.             {
    13.                 AlienAnim = this.GetComponentInChildren<Animator>();
    14.                 AlienAnim.SetBool("handsup", true);
    15.                 Debug.Log("here");
    16.             }
    17.             else
    18.                 Highlighter.gameObject.SetActive(false);
    19.                 base.Move(destinationCell, path);
    20.         }

    Here's my progress so far.
     
    Last edited: Jun 28, 2020 at 11:46 AM
  4. Jon_Brant

    Jon_Brant

    Joined:
    Mar 22, 2018
    Posts:
    46
    Hum, yeah I didn't really think the CellGridState name seemed off until you pointed it out. It makes sense with it currently coupled, I'd say.

    As far as the AI, I can't comment too much as I've never done an AI, but I think it makes perfect sense that I'd have to completely rework it. I am completely changing the flow of the game. I'm just thankful that there IS an AI. Honestly it's one of the main reasons I bought the kit.

    But yeah, I DEFINITELY get being stuck in a mode of thought and using the same design patterns repeatedly. I'd say that's pretty normal. Don't take my feedback as criticism. Every asset can always be better. You did an extremely good job. It can just always be better
     
  5. Bellatorpoeta

    Bellatorpoeta

    Joined:
    Feb 25, 2020
    Posts:
    1
    Hi! Really love your product. It has saved me dozens of hours. Right now, I'm trying to implement a cover system and I have code set up for line of sight and cover like so.


    Code (CSharp):
    1. public virtual bool IsUnitAttackable(Unit other, Cell sourceCell)
    2.     {
    3.         //supercover line code for LOS
    4.         var p0 = other.Cell.OffsetCoord; var p1 = sourceCell.OffsetCoord;
    5.         var dx = p1.x - p0.x; var dy = p1.y - p0.y;
    6.         var nx = Math.Abs(dx); var ny = Math.Abs(dy);
    7.         var sign_x = dx > 0 ? 1 : -1; var sign_y = dy > 0 ? 1 : -1;
    8.  
    9.         var p = new Vector2(p0.x, p0.y);
    10.         var points = new List<Vector2>();
    11.         for (int ix = 0, iy = 0; ix < nx || iy < ny;)
    12.         {
    13.             if ((0.5+ix) /nx == (0.5 + iy) / ny)
    14.             {
    15.                 //next step is diagonal
    16.                 p.x += sign_x;
    17.                 p.y += sign_y;
    18.                 ix++;
    19.                 iy++;
    20.                 if (Cell.IsCover == true)
    21.                 {
    22.                     return false;
    23.                 }
    24.             }
    25.             else if ((0.5+ix) / nx < (0.5+iy)/ny)
    26.             {
    27.                 //next step is horizontal
    28.                 p.x += sign_x;
    29.                 ix++;
    30.                 if (Cell.IsCover == true)
    31.                 {
    32.                     return false;
    33.                 }
    34.             }
    35.             else
    36.             {
    37.                 //next step is vertical
    38.                 p.y += sign_y;
    39.                 iy++;
    40.                 if (Cell.IsCover == true)
    41.                 {
    42.                     return false;
    43.                 }
    44.             }
    45.             points.Add(new Vector2(p.x, p.y));
    46.         }      
    47.  
    48.         if (sourceCell.GetDistance(other.Cell) <= AttackRange)
    49.             return true;
    50.  
    51.         MarkAsReachableEnemy();
    52.         return false;
    53.     }
    I added a bit of code in Cell to make obstacles be identified as cover, in the same place where it shows a cell is taken.

    The problem is that it doesn't seem to work. Units can still target each other if cover is in the way. Right now I'm just trying to make it so cover stops all targeting but I hope to adjust it to make it so cover just decreases chance to hit. One step at a time though. Any comments you can give me on why it doesn't work?
     
  6. Banksy

    Banksy

    Joined:
    Mar 31, 2013
    Posts:
    357
    Attempting to apply ROTATION so unit looks towards the destination_pos. ( from unit.cs )

    Model.transform.LookAt(destination_pos);

    note: "Model" is a public GameObject (my Unit piece )

    When I hit play and move the unit leans back approx. 15 degrees and walks but does not
    face the destination.

    I'm also wondering how to face to attack towards an enemy piece... hhmm ?
     
    Last edited: Jun 29, 2020 at 3:26 PM
  7. michal-zetkowski

    michal-zetkowski

    Joined:
    Mar 11, 2015
    Posts:
    53
    I didn't take it as criticism, and event if it was I wouldn't mind :)
     
  8. michal-zetkowski

    michal-zetkowski

    Joined:
    Mar 11, 2015
    Posts:
    53
    You definatelly have the right idea, this code belongs to IsUnitAttackable. It would be easiest for me if you could export your project and send it to me. It's hard to debug just by looking at the code.
     
  9. michal-zetkowski

    michal-zetkowski

    Joined:
    Mar 11, 2015
    Posts:
    53
    The following code used to work in TBSFv1.2.1. In the current version I'm getting some really strange rotations. I've spent about an hour so far and couldn't fix it. Please experiment with this, I'm sure that this is the way to go but there is a small issue that I fail to see (please let me know if you figure this out)

    Code (CSharp):
    1. protected virtual IEnumerator MovementAnimation(List<Cell> path)
    2.     {
    3.         isMoving = true;
    4.         path.Reverse();
    5.         foreach (var cell in path)
    6.         {
    7.             Vector3 destination_pos = new Vector3(cell.transform.localPosition.x, transform.localPosition.y, cell.transform.localPosition.z);
    8.             while (transform.localPosition != destination_pos)
    9.             {
    10.                 transform.localPosition = Vector3.MoveTowards(transform.localPosition, destination_pos, Time.deltaTime * MovementAnimationSpeed );
    11.                 Vector3 newDir = Vector3.RotateTowards(transform.forward, destination_pos - transform.position, Time.deltaTime * MovementAnimationSpeed, 0.0f);
    12.                 transform.rotation = Quaternion.LookRotation(newDir);
    13.                 Debug.DrawRay(transform.position, newDir, Color.red);
    14.                 yield return 0;
    15.             }
    16.         }
    17.         isMoving = false;
    18.     }
    Regarding turning the unit towards enemy, I would put the code in Unit.AttackHandler. Unfortunately in the current version this method is not virtual, so you will need to modify it in base class.
     
  10. michal-zetkowski

    michal-zetkowski

    Joined:
    Mar 11, 2015
    Posts:
    53
    Nice video :). Instead of tags I would make subclasses for 'Alien' and 'Enemy' and put this code there, or use Strategy design pattern (encapsulate the code in AlienAnimationHandler and EnemyAnimationHandler, both classes would implement AnimationHandler, add AnimationHandler field to Unit and assign appropriate implementation - but I guess that this is an overkill, the first option seems simpler)
     
  11. Banksy

    Banksy

    Joined:
    Mar 31, 2013
    Posts:
    357
    OK I can see the flipping issue. This is the same problem I faced earlier.

    worth noting: I've added your script recommendation and then I changed from - transform.position, to transform.localPosition & it now faces in the correct direction of travel.. but still flips horizontally.. which I feel might be due to the original positioning of prefab Units being in a horizontal position. Why are all prefabs positioned like this ? This creates a headache for anyone wanting to animate each prefab
     
    Last edited: Jun 30, 2020 at 3:53 AM
  12. michal-zetkowski

    michal-zetkowski

    Joined:
    Mar 11, 2015
    Posts:
    53
    Sorry about that, it seems to be some unintended consequence. I'll try figuring this out, but can't say when because I'll be traveling in the following days.
     
  13. Banksy

    Banksy

    Joined:
    Mar 31, 2013
    Posts:
    357
    Hi ya Michael
    Here's an update on my test scene to date... showcasing the issue with the units rotating incorrectly. Look forward to your thoughts. I can send you the project if you wish.. a slimmed down version. Safe & Happy Travels.

     
  14. Banksy

    Banksy

    Joined:
    Mar 31, 2013
    Posts:
    357
    Perhaps locking a rotation axis of the unit - using Mathf.Clamp(current_value, min, max)

    or simply
    newDir.y = 0;
    newDir.z = 0;

    For some strange reason when I lock all axis and all translations the unit moves towards world zero.

    note: Is it not better to rotate only the Alien... not the hexagonal tile as well.
    so in "Example 1" simply rotate the cube (archer) or capsule unit (paladin) this way developers can simply parent their character to it.
     
    Last edited: Jul 3, 2020 at 3:44 AM
  15. ZanesTheArgent

    ZanesTheArgent

    Joined:
    Jul 6, 2019
    Posts:
    2
    Hey, i'm interested in also doing a multi-tile units thing, but i'm a bit weak on the coding game as of now. Mind in sharing what you scribbled so far?
     
  16. Banksy

    Banksy

    Joined:
    Mar 31, 2013
    Posts:
    357
    Hi ya Zanes… Let me know if you manage to work out movement in terms of have a unit turn towards the enemy unit for attack and defence.

    fingers crossed we might see this implemented into the base project.
     
    Last edited: Jul 2, 2020 at 7:28 AM
  17. Banksy

    Banksy

    Joined:
    Mar 31, 2013
    Posts:
    357
    Can anyone recommend a site that has tutorials focusing on turn based tile game play.. or even a few links to YouTube videos would be greatly appreciated
     
  18. Jon_Brant

    Jon_Brant

    Joined:
    Mar 22, 2018
    Posts:
    46
  19. Banksy

    Banksy

    Joined:
    Mar 31, 2013
    Posts:
    357
    wow... thanks so much for the link Jon_Brant. hopeful this will help ease the pain of so much trial and error.. taking a look now.

    I am wondering if TBSF uses A* Path Finding ?
     
  20. Banksy

    Banksy

    Joined:
    Mar 31, 2013
    Posts:
    357
    Take 3.. still not sure about movement The angle is off and not facing correct direction but unit does turn at start of move.

     
unityunity