Example Board Game Movement System
Very rough example of how I would approach the task.user_8400650
csharp
2 years ago
5.2 kB
51
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...