|
Post by karrion on May 11, 2018 19:06:54 GMT
I've almost completed the tutorial and have to say that I liked it a lot, as it made me able to base my project on yours (and if I pass my end of degree project, I'll dedicate it to you somewhere ) and base it on my favorite genre of games, but there are four things that I need to be able to work on the meat of the project (the AI), two of them I may be able to figure on my own (location-based victory conditions and not randomized spawn points), as I already asked how I may be able to implement the victory condition and can begin there, and the other is simply tinkering with the SpawnTestUnits method, but the two things that are in the title I'm not sure where to begin even. 1- Mininmum attacking distance: To make archers not absolutely overpowered I wanted to give them a minimum distance of attack so that they cannot attack at point-blank, let's say a 3-5 range. In the tutorial you basicaly brute-force every single possible tile from the unit to the distance passed on the ability in question, but I'm now sure how to begin the search on a minimum distance or how to "discard" tiles that are within the range of 1-minimum. One possibility that came to mind was doing two searches, one from, let's say, 1-2, and the other from 1-5 and discard the tiles that are the same on both searches, but I feel like there must be an easier way. 2- Taunt status effect: This may be a bit trickier. A taunt status effect may be easier to implement on the AI as you simply make the taunting unit the best possible target, but I'm not really sure how on the player's part you could implement it. Maybe having a taunter Unit variable that checks if the target of the attack is the taunter and make the status itself add or remove the taunter in question. Any suggestions on this? Thanks in advance, and really, good job on the tutorial
|
|
|
Post by Admin on May 11, 2018 22:24:24 GMT
Hey, good luck on your project Been awhile since I looked in-depth at my code, but here's what I remember. I added an "AbilityRange" component that will determine the candidate tiles of an ability. You would need to create a concrete subclass of this that has the ability to create the min to max tile area. Check out the code in the "ConstantAbilityRange" . I could imagine a quick solution to your problem using the same code in that class as a starting point, but then doing a second search in the 'minimum' range. The tiles in the minimum search would be removed from the collection of tiles in the max range, and then you return the final result. I believe that if you complete this component that the A.I. will already work as is. The taunt system is trickier, you're right about that. Essentially you would want a way to validate that a unit within reach was a valid target. You could allow units with a taunt ability to observe the notification and then invalidate the target if there are taunt units in play, but the targeted unit is not a taunter. Hope that helps!
|
|
|
Post by karrion on May 15, 2018 17:01:43 GMT
Number 1 done Was easier than expected. Main problem I expected to find was doing the difference between two lists, but stackoverflow came to the rescue. In case you want to use the code in the tutorial or tinker with it, here it is. using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
public class MinimumConstantAbilityRange : AbilityRange
{
public int minimum = 1;
public override List<Tile> GetTilesInRange(Board board)
{
List<Tile> outer = board.Search(unit.tile, ExpandSearch);
List<Tile> inner = board.Search(unit.tile, InnerSearch);
return difference(outer, inner);
}
bool ExpandSearch(Tile from, Tile to)
{
return (from.distance + 1) <= horizontal && Mathf.Abs(to.height - unit.tile.height) <= vertical;
}
bool InnerSearch(Tile from, Tile to)
{
return (from.distance + 1) <= minimum && Mathf.Abs(to.height - unit.tile.height) <= vertical;
}
List<Tile> difference(List<Tile> minuend, List<Tile> substrahend)
{
return minuend.Except(substrahend).ToList();
}
} It can most likely be simplified but I like the readability of this code. And here's the result: Result
|
|
|
Post by Admin on May 15, 2018 17:06:19 GMT
Looks great, glad you got it working
|
|
|
Post by karrion on Jun 6, 2018 16:21:36 GMT
Hey again. I've been breaking my head to figure how to implement the Taunt effect and the "best" way would be to listen to a notification when the unit is taunting and post it when the taunted unit is going to select a target. The problem is, I'm worried about race conditions. If the tauntee goes to select a target before the taunter has had the opportunity to respond to the notification, the effect does nothing, and if the tauntee has a condition by which it has to wait until every single unit has checked if it is taunting another unit, it kind of defeats the point of the notification center :/
Any suggestions?
|
|
|
Post by Admin on Jun 6, 2018 22:34:45 GMT
The notification center is executed synchronously - as long as you post the notification as part of the selection validation process, then you wont have anything to worry about. For example, "tauntee" could post a notification saying "I think these are valid targets", then the "Taunters" could modify said list, and then on the next line the edited result (assuming you passed the list and it was edited by observers) can be used as needed.
|
|
|
Post by SuzieGurl on Dec 18, 2018 3:36:03 GMT
I was using this to make a ranged attack skill, but when I am in the target enemy state for the skill if I go back a square towards the using unit he flips to a back animation. This means that I can attack backwards basically. I think I need to add a new get direction function or something but I am not really sure. Any ideas?
|
|
|
Post by Admin on Dec 20, 2018 15:28:17 GMT
SuzieGurl, I'm not sure I understand your scenario. Maybe a video or something would make it more clear. If you're asking about turning to face a target before applying an attack ability, you could handle that sort of thing inside the "PerformAbilityState". The end result might feel similar to the way we use the "MoveSequenceState" coupled with the "Movement" sub class scripts to "Traverse" our path while making sure we face the correct direction and jump up tiles as needed etc.
|
|