using System; using System.Collections.Generic; using System.Linq; using System.Security.Cryptography; using JetBrains.Annotations; using Pools; using Routes; using UnityEngine; namespace Roads { [Serializable] public struct CrossingData { public Transform west; public Transform north; public Transform east; public Transform south; } public enum RoadDirection { West, North, East, South, None } public enum TurnDirection { Right, Left, Straight } static class TurnDirectionMapper { private static readonly Dictionary fromSouth = new Dictionary { {RoadDirection.East, TurnDirection.Right}, {RoadDirection.West, TurnDirection.Left} }; private static readonly Dictionary fromNorth = new Dictionary { {RoadDirection.East, TurnDirection.Left}, {RoadDirection.West, TurnDirection.Right} }; private static readonly Dictionary fromWest = new Dictionary { {RoadDirection.North, TurnDirection.Left}, {RoadDirection.South, TurnDirection.Right} }; private static readonly Dictionary fromEast = new Dictionary { {RoadDirection.North, TurnDirection.Right}, {RoadDirection.South, TurnDirection.Left} }; public static TurnDirection GetTurnDirection(RoadDirection from, RoadDirection to) { TurnDirection direction; switch (from) { case RoadDirection.West: return fromWest.TryGetValue(to, out direction) ? direction : TurnDirection.Straight; case RoadDirection.North: return fromNorth.TryGetValue(to, out direction) ? direction : TurnDirection.Straight; case RoadDirection.East: return fromEast.TryGetValue(to, out direction) ? direction : TurnDirection.Straight; case RoadDirection.South: return fromSouth.TryGetValue(to, out direction) ? direction : TurnDirection.Straight; default: return TurnDirection.Straight; } } } public class CrossingExtras : Turn { public CrossingData crossingData; [CanBeNull] private Pool arrowPool; private bool arrowPoolAvailable; private TurnDirection turnDirection; private void Awake() { arrowPool = FindObjectsOfType().FirstOrDefault(o => o.CompareTag("ArrowPool")); arrowPoolAvailable = arrowPool != null; if (!arrowPoolAvailable) Debug.LogWarning("Arrow Pool not found"); } private void Start() { if (comingFrom == RoadDirection.None || goingTo == RoadDirection.None) return; turnDirection = TurnDirectionMapper.GetTurnDirection(comingFrom, goingTo); var items = new[] {RoadDirection.West, RoadDirection.North, RoadDirection.East, RoadDirection.South}; foreach (var position in items.Where(i => i != comingFrom && i != goingTo)) { AddArrows(position); } } private void AddArrows(RoadDirection position) { if (!arrowPoolAvailable) return; Transform t; switch (position) { case RoadDirection.North: t = crossingData.north; break; case RoadDirection.West: t = crossingData.west; break; case RoadDirection.East: t = crossingData.east; break; case RoadDirection.South: t = crossingData.south; break; case RoadDirection.None: throw new ArgumentException("RoadDirection.None not allowed for adding arrows"); default: throw new ArgumentOutOfRangeException(nameof(position), position, "Wrong Argument for AddArrows"); } System.Diagnostics.Debug.Assert(arrowPool != null, nameof(arrowPool) + " != null"); var arrows = arrowPool.GetItem(); SetRotation(arrows, position); arrows.transform.position = t.position; } private void SetRotation(GameObject arrows, RoadDirection position) { //by default, the arrow shows to north switch (position) { case RoadDirection.West: { if (turnDirection == TurnDirection.Left || turnDirection == TurnDirection.Straight && goingTo == RoadDirection.South) { arrows.transform.Rotate(Vector3.up, 90); } else if (turnDirection == TurnDirection.Right || turnDirection == TurnDirection.Straight && goingTo == RoadDirection.North) { arrows.transform.Rotate(Vector3.up, 90); } break; } case RoadDirection.North: if (turnDirection == TurnDirection.Left || turnDirection == TurnDirection.Straight && goingTo == RoadDirection.East) { arrows.transform.Rotate(Vector3.up, 180); } break; case RoadDirection.East: if (turnDirection == TurnDirection.Right || turnDirection == TurnDirection.Straight && goingTo == RoadDirection.South) { arrows.transform.Rotate(Vector3.up, 90); } else if (turnDirection == TurnDirection.Left || turnDirection == TurnDirection.Straight && goingTo == RoadDirection.North) { arrows.transform.Rotate(Vector3.up, -90); } break; case RoadDirection.South: if (turnDirection == TurnDirection.Right || turnDirection == TurnDirection.Straight && goingTo == RoadDirection.West) { arrows.transform.Rotate(Vector3.up, 180); } break; case RoadDirection.None: throw new ArgumentException("RoadDirection.None not allowed for adding arrows"); default: throw new ArgumentOutOfRangeException(nameof(position), position, null); } } } }