Example Board Game Movement System
Very rough example of how I would approach the task.user_8400650
csharp
3 years ago
5.2 kB
57
Indexable
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using UnityEngine;
using Random = UnityEngine.Random;
namespace _Scripts.Examples
{
public struct PlayerInfo
{
public int id;
}
public class PlayerInputHandler
{
public Action<MoveDirection> OnDirectionInput;
// allows for creating input handlers for both input systems
// I'd likely make this an interface or abstract class -- would have to test a bit
}
public class PlayerTurnManager
{
public Action<PlayerInfo> OnNewTurn;
static PlayerTurnManager() { }
private PlayerTurnManager(){ }
public static PlayerTurnManager instance { get; } = new PlayerTurnManager();
private Dictionary<int, PlayerInfo> _players = new Dictionary<int, PlayerInfo>();
private int _currPlayerIndex;
public void RegisterPlayer(PlayerInfo playerInfo)
{
_players.TryAdd(playerInfo.id, playerInfo);
}
public void OnTurnFinished()
{
// do stuff like check for end of game with game manager, etc
// if game is still valid:
NotifyNextTurn();
}
private void NotifyNextTurn()
{
OnNewTurn?.Invoke(NextPlayer());
}
private PlayerInfo NextPlayer()
{
_currPlayerIndex = _currPlayerIndex >= _players.Count - 1 ? 0 : _currPlayerIndex + 1;
return _players[_currPlayerIndex];
}
}
public static class DataGenerator
{
public static int GetDiceRoll(int low = 1, int high = 6)
{
return Random.Range(low, high);
}
}
public enum MoveDirection
{
Up,
Right,
Down,
Left
}
public struct BoardPosition
{
public int id;
public List<BoardPosition> nextBoardPositions;
}
public class PlayerMoveHandler
{
public Action<BoardPosition> OnMoveComplete;
public bool InitMovement(MoveDirection moveDirection)
{
// check for valid move
// if valid
MovePlayer(moveDirection);
// return true
// else
return false;
}
private void MovePlayer(MoveDirection moveDirection)
{
// ... do movement stuff
// ... get ending position node and send in action (instead of new placeholder)
OnMoveComplete?.Invoke(new BoardPosition());
}
}
public class PlayerControllerExample : MonoBehaviour
{
private PlayerInfo _playerInfo;
private PlayerInputHandler _playerInputHandler;
private PlayerMoveHandler _playerMoveHandler;
[SerializeField]
private GameObject inputPrompt;
private int _movesRemaining;
private bool _isMoving;
public PlayerInfo playerInfo
{
get => _playerInfo;
set => _playerInfo = value;
}
private void Awake()
{
PlayerTurnManager.instance.RegisterPlayer(_playerInfo);
}
private void OnEnable()
{
PlayerTurnManager.instance.OnNewTurn += OnNewTurn;
_playerInputHandler.OnDirectionInput += OnDirectionInput;
_playerMoveHandler.OnMoveComplete += OnMoveComplete;
}
private void OnDisable()
{
PlayerTurnManager.instance.OnNewTurn -= OnNewTurn;
_playerInputHandler.OnDirectionInput -= OnDirectionInput;
_playerMoveHandler.OnMoveComplete -= OnMoveComplete;
}
private void OnMoveComplete(BoardPosition obj)
{
// perhaps notify game manager or UI of relevant info
_isMoving = false;
}
private void OnDirectionInput(MoveDirection obj)
{
_isMoving = _playerMoveHandler.InitMovement(obj);
}
private void OnNewTurn(PlayerInfo turnPlayerInfo)
{
if (turnPlayerInfo.id != _playerInfo.id) return;
SetRemainingMoves();
InitMoveProcess();
}
private void InitMoveProcess()
{
Move();
}
private async Task Move()
{
while (_movesRemaining > 0)
{
if (!_isMoving)
{
// probably would do this a bit more elegantly
// but this gets the point across
inputPrompt.SetActive(true);
}
await Task.Yield();
}
// perhaps notify game manager or UI of relevant info
PlayerTurnManager.instance.OnTurnFinished();
}
private void SetRemainingMoves()
{
_movesRemaining = DataGenerator.GetDiceRoll();
}
}
}Editor is loading...