Anyone can help me to get script moving like in Seafight web game ?
This is my actually script
using UnityEngine;
public class TileMoveShipWithStaticDiagonals : MonoBehaviour
{
public float moveSpeed = 5f; // Prędkość poruszania się statku
public float animationSpeed = 0.3f; // Jak szybko zmieniają się sprite’y (częstotliwość animacji)
public float tileSize = 1f; // Rozmiar jednego kafelka w Unity units
// Sprite'y statku dla każdego głównego kierunku
public Sprite up1, up2; // Sprite'y dla ruchu w górę
public Sprite down1, down2; // Sprite'y dla ruchu w dół
public Sprite left1, left2; // Sprite'y dla ruchu w lewo
public Sprite right1, right2;// Sprite'y dla ruchu w prawo
// Stałe sprite'y statku dla każdego przekątnego kierunku (bez animacji)
public Sprite upRight; // Sprite dla ruchu w prawo-górę
public Sprite upLeft; // Sprite dla ruchu w lewo-górę
public Sprite downRight; // Sprite dla ruchu w prawo-dół
public Sprite downLeft; // Sprite dla ruchu w lewo-dół
private Vector2 targetPosition;
private bool isMoving = false;
private SpriteRenderer spriteRenderer;
private float animationTimer;
private bool useFirstSprite = true;
private enum Direction { Up, Down, Left, Right, UpRight, UpLeft, DownRight, DownLeft }
private Direction currentDirection;
void Start()
{
spriteRenderer = GetComponent<SpriteRenderer>(); // Pobranie komponentu SpriteRenderer
animationTimer = animationSpeed; // Ustawienie początkowej wartości timera animacji
}
void Update()
{
if (Input.GetMouseButtonDown(0)) // Lewy przycisk myszy
{
Vector3 mousePosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
mousePosition.z = 0; // Ustaw z na 0, jeśli używasz 2D
// Konwersja z pozycji świata na siatkę
Vector2Int gridPosition = WorldToGrid(mousePosition);
targetPosition = GridToWorld(gridPosition); // Konwersja z siatki na pozycję świata
// Ustaw, że statek ma się poruszać
isMoving = true;
}
if (isMoving)
{
MoveShip();
}
// Animujemy statek tylko w głównych kierunkach (góra, dół, lewo, prawo)
if (isMoving && (currentDirection == Direction.Up || currentDirection == Direction.Down || currentDirection == Direction.Left || currentDirection == Direction.Right))
{
AnimateShip();
}
}
// Poruszanie statkiem
void MoveShip()
{
// Oblicz kierunek, w którym statek powinien się poruszać
Vector3 direction = (targetPosition - (Vector2)transform.position).normalized;
// Wybierz kierunek ruchu (główne kierunki + przekątne)
if (Mathf.Abs(direction.x) > 0.1f && Mathf.Abs(direction.y) > 0.1f) // Ruch po przekątnej
{
if (direction.x > 0 && direction.y > 0)
{
currentDirection = Direction.UpRight; // Ruch w prawo-górę
spriteRenderer.sprite = upRight; // Ustaw stały sprite
}
else if (direction.x < 0 && direction.y > 0)
{
currentDirection = Direction.UpLeft; // Ruch w lewo-górę
spriteRenderer.sprite = upLeft; // Ustaw stały sprite
}
else if (direction.x > 0 && direction.y < 0)
{
currentDirection = Direction.DownRight; // Ruch w prawo-dół
spriteRenderer.sprite = downRight; // Ustaw stały sprite
}
else if (direction.x < 0 && direction.y < 0)
{
currentDirection = Direction.DownLeft; // Ruch w lewo-dół
spriteRenderer.sprite = downLeft; // Ustaw stały sprite
}
}
else if (Mathf.Abs(direction.x) > Mathf.Abs(direction.y)) // Ruch poziomy
{
if (direction.x > 0)
{
currentDirection = Direction.Right; // Ruch w prawo
}
else
{
currentDirection = Direction.Left; // Ruch w lewo
}
}
else // Ruch pionowy
{
if (direction.y > 0)
{
currentDirection = Direction.Up; // Ruch w górę
}
else
{
currentDirection = Direction.Down; // Ruch w dół
}
}
// Ruch statku w stronę celu
float step = moveSpeed * Time.deltaTime;
transform.position = Vector2.MoveTowards(transform.position, targetPosition, step);
// Sprawdź, czy statek osiągnął cel
if (Vector2.Distance(transform.position, targetPosition) < 0.01f)
{
isMoving = false; // Zatrzymaj poruszanie się
transform.position = targetPosition; // Upewnij się, że statek jest dokładnie na kafelku
}
}
// Funkcja animująca statek (tylko dla ruchu w głównych kierunkach)
void AnimateShip()
{
// Zmień sprite'y co określony czas
animationTimer -= Time.deltaTime;
if (animationTimer <= 0)
{
// Przełącz na drugi sprite
useFirstSprite = !useFirstSprite;
switch (currentDirection)
{
case Direction.Up:
spriteRenderer.sprite = useFirstSprite ? up1 : up2;
break;
case Direction.Down:
spriteRenderer.sprite = useFirstSprite ? down1 : down2;
break;
case Direction.Left:
spriteRenderer.sprite = useFirstSprite ? left1 : left2;
break;
case Direction.Right:
spriteRenderer.sprite = useFirstSprite ? right1 : right2;
break;
}
// Zresetuj timer animacji
animationTimer = animationSpeed;
}
}
// Konwersja z pozycji świata na siatkę
Vector2Int WorldToGrid(Vector3 worldPosition)
{
return new Vector2Int(
Mathf.RoundToInt(worldPosition.x / tileSize),
Mathf.RoundToInt(worldPosition.y / tileSize)
);
}
// Konwersja z siatki na pozycję świata
Vector3 GridToWorld(Vector2Int gridPosition)
{
return new Vector3(
gridPosition.x * tileSize,
gridPosition.y * tileSize,
0
);
}
}
Not sure what the “seafight” game is if it is something tile-based, look up tutorials for how to do tile based movement. It will be much more than simply code. There will be scene and prefab setup always.
Here’s some notes on tile-based movement:
Tile-based / grid-based 2D games: match3, tetris, chips challenge, rogue, etc:
For any tile-based game such as Match3 or Tetris or a grid-based Roguelike, do all the logical comparisons in your own data storage mechanism for the tiles, such as a 2D array of tiles.
Otherwise you needlessly bind your game logic into Unity objects and the Unity API, making it about 10x more complicated than it needs to be.
If you have no idea how to work with 2D arrays, hurry to some basic C# tutorials for the language portions of it, then look at any good tutorial that uses a 2D array
Here is my Match3 demo using this technique of storing data in a grid. Full source linked in game comments.
It stores all of its data in a 2D array:
PieceController[,] Board;
This allows for easy simple checking in code, not relying on anything like physics.
You should strive to use that pattern for all logic, then only use Unity to present what is happening in the game logic.
Two steps to tutorials and / or example code:
- do them perfectly, to the letter (zero typos, including punctuation and capitalization)
- stop and understand each step to understand what is going on.
If you go past anything that you don’t understand, then you’re just mimicking what you saw without actually learning, essentially wasting your own time. It’s only two steps. Don’t skip either step.
Like this guy: Imphenzia: How Did I Learn To Make Games: