how to make an enemy only attack the player when the player is in a state that can be attacked? - 2d

how to make an enemy only attack the player when the player is in a state that can be attacked in unity C#

Related

How to trigger enemy's area entered function while disabling player's hurtbox collision

I am making 2d platformer zombie game. When player entered enemy's hitbox area, enemy will enter Grab Attack State from Chase State. Once player entered enemy's hitbox area and enemy entered Grab Attack State, I would like to disable player's hurtbox collision. So I can avoid another enemy to be in Grab Attack State while player and enemy are in Grab Attack State. I tried to achieve this by simply disabling Player's hurtbox collision by $CollisionShape2D.set_defferted("disabled", true). However, this will make enemy return to Idle state instantly, as Grab Attack State and Chase State will only happen when Player's hurtbox entered. I would appreciate if you could teach me how to keep enemy's Grab Attack State sequence while disabling player's hurtbox collision.
For a good melee enemy solution, you want:
Idle (a.k.a stand by): you already know this one.
Windup (a.k.a anticipation): when the attack is being telegraphed to the player.
Strike: When the attack can connect.
Recovery (a.k.a follow through): If the attack failed to connect.
There are multiple ways to handle this. For example, you could have a state machine that triggers each animation (perhaps with some blending), or you could have an AnimationTree do it. Or you could use the animation_finished signal… Or it could be just one animation, and have a method call track that tells the script in what part of it is (you might be interested in "frame data" and how fighting games use it). However you handle it…
When the player enters the trigger area of the enemy, you will go into windup, and the appropriate animation must begin to play. If the attack is cancelable, then the behavior you have makes sense: leaving the trigger area returns the enemy to idle.
Addendum: You might have a cancelable windup following by another state where it isn't cancelable but it can't contact yet. That state would be "commitment".
When the windup animation is finished, you go into strike, which is when you check hit and hurt boxes. So the attack might connect or or not. If it does not connect you continue into recovery.
For a regular attack, you would do whatever damage mechanic you have.
But being this a grab, you need and extra grab state. For when the enemy is actually grabbing the player, not just attempting to grab the player.
So the enemy will enter this grab state when the attack actually connected. And then it does whatever it has to do to the player (e.g. throw it, hit it, whatever), and then release it (perhaps the player has to do some inputs, I don't know).
I'm going to suggest a "movement disabled" state for the player where it does not take input and some other code is responsible for moving it, it is useful for cut scenes, and you can reuse it here. If the enemy is setting this state on the player, the enemy is also responsible from clearing it.
And in sync with that you need to prevent prevent other enemies to attack※, ar at least prevent their attacks from connecting. How? There are a few options:
Since at this point you already checked hit and hurt boxes, you can actually disable the collision (as you were trying to do). And remember that then the enemy must enable it when it releases the player.
Another options is to have a "grabbing" node group, then the enemy can add itself there only if it is empty, if it wasn't consider it didn't connect and go into recovery. When the enemy releases the player it must exit the group.
Similarly, you could store in metadata of the player (or in some other conveniente location) who is grabbing it. The enemies would set themselves on said metadata only if it was not set previously. The enemy that set itself will also be responsible from clearing the metadata when it releases the player.
※: Using a node group where the enemies that are attacking must join, but only if it is below a certain size, will allow you to limit how many enemies attack at the same time. Which is one more variable that affects difficulty, if you need it.

How to synchronize the ball in a network pong game?

I’m developing a multiplayer network pong game, my first game ever. The current state is, I’ve running the physic engine with the same configurations on the server and the clients. The own paddle movement is predicted and get just confirmed by the authoritative server. Is a difference detected between them, I correct the position at the client by interpolation. The opponent paddle is also interpolated 200ms to 100ms in the past, because the server is broadcasting snapshots every 100ms to each client.
So far it works very well, but now I have to simulate the ball and have a problem to understanding the procedure.
I’ve read Valve’s (and many other) articles about fast-paced multiplayer several times and understood their approach. Maybe I can compare my ball with their bullets, but their advantage is, the bullets are not visible. When I have to display the ball, and see my paddle in the present, the opponent in the past and the server is somewhere between it, how can I synchronize the ball over all instances and ensure, that the it got ever hit by the paddle even if the paddle is fast moving? Currently my ball’s position is simply set by a server update, so it can happen, that the ball bounces back, even if the paddle is some pixel away (because of a delayed server position).
Until now I’ve got no synced clock over all instances. I’m sending a client step index with each update to the server. If the server did his job, he sends the snapshot with the last step index of each client back to the clients. Now I’m looking for the stored position at the returned step index and compare them. Do I need a common clock to sync the ball?
EDIT:
I've tried to sync a common clock for the server and all clients with a timestamp. But I think it's better to use an own stepping instead of a timestamp (so I don't need to calculate with the ping and so on - and the timestamp will never be exact). The physics are running 60 times per second and now I use this for keeping them synchronized. Is that a good way?
When the ball gets calculated by each client, the angle after bouncing can differ because of the different position of the paddles (the opponent is 200ms in the past). When the server is sending his ball position, velocity and angle (because he knows the position of each paddle and is authoritative), the ball could be in a very different position because of the different angles after bouncing (because the clients receive the server data after 100ms). How is it possible to interpolate such a huge difference?
As you are developing your first game, I think you should try the simplest but brute-force method first. Then you will experience the first exciting result, then you will get courage and try the better methods.
Like Source Engine method, process the game play in one side and send every object state to the other for each 1/30 second. This is a brute method but it works in LAN environment.
Now you will find problems that occur WAN environment where latency is more than 1/30 second.
I am not sure it works actually, but I think that:
Assume that the movement of ball does not change by only player's hit.
Send ball position P, velocity and player A position only when player hits the ball to B.
At B, receive it but process it as if time L is already passed (L=latency between A and B * 2) However, rendered ball should be keep its previous movement until it reaches the ball position P.
Values which never are affected can be masqueraded, even if it is time value. :)

Unity Multiplayer player synchronization

I am working on a unity mobile game. Which is like a multiplayer version of temple run. Because this game is meant for mobile there is a fluctuating latency generally in the range of 200ms - 500ms.
Since the path is predetermined and actions the user can perform are limited (jump,slide, use powerup etc) , the remote player keep running on the path until it receives the updated state from its local player.
This strategy generally works pretty well since I only need to send limited amount of data over the network but there is a specific case in which I am having issues.
In the game, players die on the specific positions (obstacles).
I want remote players to die on the same obstacle/position as local player but due to latency in sending message, the remote player crosses the obstacle by the time it receives the death message.
Is there a way to sync the players on the deaths.
One of the things I tried was moving the remote player back to the local players death position but not only does it look awkward visually but can also raise other syncing issues.
Is there some other better way to do this ?
One way I may recommend is to make one player acts like server (not real server). The server-player will do all the computation like moving, jumping, creating scenes, etc. Then the server-player will send all the data to sync with the client-player. The client-player get the data and process game state. The client-player can also send his action (left-right-jump-slide) to the server-player. This way both player will have the same state of the game like position, die. You also need to deal with latency by adding some prediction.
So the solution I implemented was I spawned all the remote player behind enough so they can have some time to receive the information that local player was died on specific obstacle. And in the end there is a straight path where I just sync players again. So that result is displayed correctly.

Network Traffic, MMO Tower Defense

I am programming a MMO Tower Defense game (Client Server architecture). Because of cheating protection, the server needs to have the logic. But I have real design problem. When lets say 10 People fight deathmatch against each other, every tower shoot needs to be calcuted and send over to the players. When many towers are build. (Like 10 Players * 10 Tower = 100 Tower ) the traffic is very high. (One player causes many messages per second) How can I solve this problem?
Server is written in Java ( Smartfox 2x)
Client is written in C# ( Unity 3d)
Thanks in advance.
Use strong simplified Units and combat rules on the server. Just program your damage algorithm by affecting continuous damage over time if someone is stepping into the "Damage area" around the tower.
U can use tow dimensional battlefields on the server where all units and towers and damage areas are just circles or oints and circles. U can also use several rings of damage with damage per second is lower in the outter circles and higher at the inner circles around the defense tower.
U can use queues for managing single target damage / multi target damage and area damage. Just the first in the queue is affecting by the damage area if single shot, just the first, second and third is affected by multi shot etc.
If a tower shoot a bullet every 5 seconds and does 40 damage per bullet u just calculate on the server by affecting a damage of 8 per second for every target standing in the "Damage area" or "damage circle".
On the client u can all the things like flying bullets and hitting and splish and splash and fireworks and so on.
But on the server do all the stuff by entering damage areas and then get damage per second. (sorry for bad english)
Because of cheating protection, the server needs to have the logic.
This is a false assumption. The server needs to have sufficient logic to run game logic and make sure that all players' actions make sense, but it does not need to send back the results. The clients can all run that same logic in parallel and figure out the results on their own.

Computing Checkmate Correctly

When computing checkmate for a king in chess, do you determine the other players possible moves against your king? Or do you consider merely their unit's reach? If you say it's the former, then there is a contradiction like "this statement is false" Consider this image with two kings a square apart and their knights protecting from above rooks. If we assume that the definition of possible moves must prevent check based on enemy possible moves, then the logic recursively alternates.
First, we say that our king is in check from the enemy knight so we are limited from moving our own knight because we must escape.
Then we realize that the knight does not have an available move into our king's square because he will be placing his king in check with our rook. He does not have our king in check after all.
Then we realize, free from check, that we are now able to move our own knight to the enemy king forcing him to move from check and preventing further his choices.
However, we notice that we cannot do this because it will place us in check with the enemy rook.
We realize that since we cannot actually move our knight, the enemy king is not actually in check, therefore he is freely able to use his knight to attack our king.
Go to step 2 (no matter how many times you have already).
Okay, so maybe we assume that reach always counts regardless of the enemy's check status. If our king is in reach of the enemy knight's usual attack range, we consider it a check and must resolve it. Is this how the actual game is ruled though? It seems an easy solution to the problem faced when programming the game logic, but I'm not sure if it is correct or not.
I did some thinking and came up with this analysis:
I think you have proven that the scenario of both kings being in check (not necessarily the scenario of the board I showed) cannot exist by contradiction.
Only one player can make a move at a time.
Therefore, one player makes the initial move which transitions from the state of no kings being in check to some king(s) being in check.
According to the rules, this move is not allowed if that player's king results is in a check. (I will point out the significance of 'results' soon)
This means that no matter how check is defined, he cannot make any move if his king meets that condition.
Therefore, the only transition to checks from no checks is to the enemy being in check.
The enemy must escape check, still following the rule of not entering check in one move.
The remaining state would be game over or that king escaping check.
So I understand that both kings being in check is not possible.
Now the board I showed is either reachable or not reachable.
Let's assume the board is reachable and see if there is a contradiction.
Let's ambiguously assume it's white's turn since the scenario is symmetric.
This means black just moved.
Therefore, black's king is not in check.
The black king is only reachable by the white knight.
Therefore, the white knight must be restricted by some rule to not attack the black king.
The only two possible rules that can enforce that conclusion are:
The white knight is currently protecting his king from check.
The white king is in check already and that move will not solve the check.
First, assume 2 is true regardless of 1.
The white king is in check and the only piece in attack range is black knight.
The black knight cannot attack the square containing king, however, because it would place his own king in check.
Therefore 1 must be true and the white king is not in check.
So both kings are not in check.
We reverse the game board to see if this is reachable.
Assume the scenario with the following alterations:
White has a bishop 2 up and 1 right from the black rook.
The black king is one square to the left.
The white king is one square to the right.
No kings are in range of any other pieces, so it may be reasonable to assume this initial state is reachable.
The black knight is protecting his king from the bishop, so it cannot move to under the white knight.
The white king moves left.
Now the white knight is protecting the white king and cannot move to under the black knight.
The black king moves right one square.
Thus, the scenario is reachable.
The only questioned assumption standing is that when any moves are considered, it is safe to assume that the check rules are computed. Thus, a king may come in range of a unit which may not attack it due to prevention of his own king being in check. If this assumption is not made, then the pieces simply could follow the rules of not allowing kings to enter the unrestricted attack range of an enemy unit.
Now, it is interesting to see if this scenario is computable without infinite loops.
For dependencies, I will use arrows.
For the initial white king moving left,
white king -> black knight stopped -> white bishop attack black king
Those are single step computations, no loops in dependencies so far.
For the black king to move right,
black king -> white knight stopped -> black rook attack white king
Still no dependencies.
What about when we now try to check white knight's available moves including attacking the black king?
white knight stopped -> black rook attack white king
What about if the white rook attacks the black rook?
white rook stopped -> black knight attack white king
White's remaining options are to move the king to the right or down.
Our conclusion,
Moving to this board state is possible without breaking the 'don't move into check' rule.
This board state obviously assumes that computing check depends on possible enemy moves, not their simple native attack ranges.
When this state is reached, both kings are not in check.
It is at least possible that this is not a stalemate. (Unknown if always)
So I finally found rules on wikipedia about placing another king in check even if it compromises one's own king. So, we cannot make our assumption in part 2, thus the board state is not reachable.
"A piece unable to move because it would place its own king in check (it is pinned against its own king) may still deliver check to the opposing player."
Thus our final conclusion for the apparent actual rules of chess, the board state is not reachable as it follows the check rules.
I am going to choose icedtrees answer because of the valuable logic which follows the game rules:
if for every move for player X (ignoring rules about king threats),
player Y can capture player X's king next turn,
then player X is in checkmate.
However, I would fix them to be the following:
{X is checkmate}
if and only if {
For all legal moves:(move according to rule definition) X {
There exists a generic move:(legal move A ignoring rules of protecting king A) Y such that {
X king is captured
}
}
}
I may be misunderstanding, but I think your problem is easily fixed by noting that it is only possible to be in check if it is your own turn. Check in chess is associated strongly with a compulsion to defend the check, and you cannot do that if it is not your turn.
For any chess position, it is VERY IMPORTANT to define whose turn it is, because that lies behind so many mechanics in the game. In your board position, if it is black's turn, then black is in check, and if it is white's turn, then white is in check.
Even if the position is impossible, you can still define some good rules about positions that are good for chess computations.
Some notes on checkmate in chess:
Checkmate is actually not very intuitive, and when you play the game you start to notice funny checkmate situations that do not make much sense.
Here is a good way of thinking about checkmate, in my opinion:
In a legal chess game, when checkmate occurs, the checkmated player is unable to prevent his king being captured the successive turn by the opposing player. That is, checkmate in chess is nothing but "ending the game one turn early", so to speak. If you ignore all rules in chess about threats to the king, but preserve the movement patterns of the pieces, a computer could calculate checkmate by looking forward.
The logic would be as follows:
if for every move for player X (ignoring rules about king threats), player Y can capture player X's king next turn, then player X is in checkmate.
Here is a more complete version of "check and escaping check":
Given it is player X's turn:
if player X's king is in movement range of player Y's piece, it is in check. If the piece cannot escape check, it is checkmate.
There are three ways of escaping check:
Moving your king to a non-attacked square
Blocking the piece(s) delivering check
Capturing the checking piece.
Maybe you're over-thinking this :-)
Here's the algorithm from a working chess program that's relatively strong in human terms:
Generate the list of pseudo-legal moves for the side to move. By pseudo-legal, I mean don't bother to verify whether the generated move leaves that side's King in check. Omitting this verification can save time validating moves that are never searched.
For each move that is searched, validate that it doesn't leave the side to move in check.
If every move leaves the King in check, then the side to move has either been mated or it's stalemate.
If the side to move is currently in check, then it's mate. Otherwise it's stalemate.
My naïve approach would probably go like this.
player.startTurn();
if (player.isInCheck()
if(player.king.hasNoLegalMoves() && player.cannotProtectKing())
game.checkMate(player);
function isInCheck() {
boolean isInCheck = false;
for (Piece p : player.Opponent)
if (p.canAttack(player.king) {
isInCheck = true;
return;
}
I may be missing something here, but I don't understand why it wouldn't be this simple.
For one thing, this board position isn’t even REMOTELY possible.
1) How did you get the rooks and kings off the first and eighth ranks without moving any pawns?
2) Check is defined as the state where your king is under attack by an opposing piece. CheckMATE is the situation where you are in check and cannot legally get out of check.
3) If it’s your turn and one of your pieces is capable of capturing the opponent’s king, it doesn’t matter if you would put yourself in check to do so: it’s whose king would die first?
4) Notwithstanding that, if it’s your turn and your opponent is in check, it either means neither player noticed that your opponent was in check (in which case you go back and make sure they can—and do—get out of check before you do anything else) or that nobody noticed that it was checkmate.
So, when it’s your turn you can’t finish in check, but when determining a threat to the king, the opposing king’s safety is irrelevant.

Resources