dynamic loading of gate prefabs

This commit is contained in:
klemek
2020-12-19 20:02:15 +01:00
parent 205a663e07
commit 972a689d9c
61 changed files with 5685 additions and 7662 deletions
+16 -2
View File
@@ -1,6 +1,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
using Unity.VectorGraphics;
using UnityEngine;
using UntitledLogicGame.Workspace;
@@ -26,6 +27,9 @@ namespace UntitledLogicGame
[Header("Prefabs")]
public Cable CablePrefab;
public Gate GatePrefab;
public Anchor AnchorPrefab;
public Anchor BigAnchorPrefab;
[Header("Groups")]
public Transform GatesGroup;
@@ -36,12 +40,14 @@ namespace UntitledLogicGame
public Color ActivatedColor;
[Header("Gates")]
public List<Gate> GatePrefabs;
public TextAsset GateBook;
public List<Sprite> GateSprites;
#endregion
#region Public Properties
public List<Gate> GatePrefabs { get; set; }
public Anchor CurrentAnchor { get; set; }
public Gate CurrentGate { get; set; }
public PointerManager PointerManager
@@ -64,6 +70,13 @@ namespace UntitledLogicGame
#region Unity Methods
private void Start()
{
var factory = gameObject.AddComponent<GatePrefabFactory>();
factory.Init(GatePrefab, AnchorPrefab, BigAnchorPrefab, GateSprites);
GatePrefabs = factory.GeneratePrefabs(GateBook);
}
#endregion
#region Public Methods
@@ -71,6 +84,7 @@ namespace UntitledLogicGame
public void CreateGate(Gate gatePrefab)
{
var gate = Instantiate(gatePrefab, GatesGroup);
gate.gameObject.SetActive(true);
gate.transform.position = PointerManager.MousePos - gate.Box.transform.position;
PointerManager.DragGate(gate, true);
}
+3 -2
View File
@@ -47,7 +47,7 @@ namespace UntitledLogicGame.UI
private IEnumerator Start()
{
yield return new WaitUntil(() => GameManager.Instance != null);
yield return new WaitUntil(() => GameManager.Instance != null && GameManager.Instance.GatePrefabs == null);
CreateGateBar();
UpdateUI();
}
@@ -126,7 +126,8 @@ namespace UntitledLogicGame.UI
var uiGate = Instantiate(UIGatePrefab, parent.transform);
uiGate.GatePrefab = gatePrefab;
uiGate.Rect.anchoredPosition = new Vector2(currentPos, 0);
uiGate.OnClick = () => {
uiGate.OnClick = () =>
{
GameManager.Instance.CreateGate(gatePrefab);
};
currentPos += 100f;
+6 -2
View File
@@ -84,10 +84,14 @@ namespace UntitledLogicGame.Workspace
private void OnDestroy()
{
foreach(var cable in Cables)
if(Cables != null)
{
Destroy(cable.gameObject);
foreach(var cable in Cables)
{
Destroy(cable.gameObject);
}
}
}
#endregion
+172
View File
@@ -0,0 +1,172 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using UnityEngine;
using UntitledLogicGame.Workspace;
using UntitledLogicGame.Workspace.Gates;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.NamingConventions;
namespace UntitledLogicGame.Workspace
{
public class GatePrefabFactory : MonoBehaviour
{
#region Public Properties
#endregion
#region Private Properties
private Gate _gatePrefab;
private Anchor _anchorPrefab;
private Anchor _bigAnchorPrefab;
private List<Sprite> _gateSprites;
#endregion
#region Public Methods
public void Init(Gate gatePrefab, Anchor anchorPrefab, Anchor bigAnchorPrefab, List<Sprite> gateSprites)
{
_gatePrefab = gatePrefab;
_anchorPrefab = anchorPrefab;
_bigAnchorPrefab = bigAnchorPrefab;
_gateSprites = gateSprites;
}
public List<Gate> GeneratePrefabs(TextAsset gateBook)
{
Debug.Log("Loading gates");
var deserializer = new DeserializerBuilder()
.WithNamingConvention(UnderscoredNamingConvention.Instance)
.Build();
var book = deserializer.Deserialize<GateBook>(gateBook.ToString());
return book.List.Select(kp => NewPrefab(kp.Key, kp.Value)).ToList();
}
private Gate NewPrefab(int key, GateBookItem item)
{
var gate = Instantiate(_gatePrefab);
var prefab = gate.gameObject;
prefab.SetActive(false);
prefab.name = $"prefab_{key}";
prefab.hideFlags = HideFlags.HideInHierarchy;
if (!string.IsNullOrEmpty(item.Class))
{
var newClass = System.Type.GetType($"{typeof(GatePrefabFactory).Namespace}.{item.Class}", true);
Destroy(gate);
gate = (Gate)prefab.AddComponent(newClass);
}
gate.GateType = (GateType)key;
var sprite = _gateSprites.First(s => s.name == $"{item.Skin}Sprite");
gate.Sprite.Renderer.sprite = sprite;
gate.Sprite.ResetCollider();
if(item.Input != null && item.Input.Count > 0)
{
foreach(var inputAnchor in item.InputAnchors)
{
var anchor = Instantiate(inputAnchor.Big ? _bigAnchorPrefab : _anchorPrefab);
anchor.transform.parent = prefab.transform;
inputAnchor.ConfigAnchor(anchor);
anchor.IsInput = true;
}
}
if(item.Output != null && item.Output.Count > 0)
{
foreach(var outputAnchor in item.OutputAnchors)
{
var anchor = Instantiate(outputAnchor.Big ? _bigAnchorPrefab : _anchorPrefab);
anchor.transform.parent = prefab.transform;
outputAnchor.ConfigAnchor(anchor);
}
}
gate.Box.transform.position = new Vector3(
item.Width / 2f,
-item.Height / 2f,
gate.Box.transform.position.z
);
gate.Box.transform.localScale = new Vector3(
item.Width - 0.5f,
item.Height - 0.5f,
1f
);
Debug.Log($"Loaded gate {gate.Definition.Name}");
return gate;
}
#endregion
#region Private Methods
#endregion
#region Classes
public class GateBook
{
public Dictionary<int, GateBookItem> List { get; set; }
}
public class GateBookItem
{
public string Skin { get; set; }
public int Width { get; set; }
public int Height { get; set; }
public string Class { get; set; }
public List<string> Input { get; set; }
public List<string> Output { get; set; }
public List<GateBookItemAnchor> InputAnchors => Input.Select(i => i.Split(new char[0])).Select(GateBookItemAnchor.Get).ToList();
public List<GateBookItemAnchor> OutputAnchors => Output.Select(i => i.Split(new char[0])).Select(GateBookItemAnchor.Get).ToList();
}
public class GateBookItemAnchor
{
public string Name { get; set; }
public float X { get; set; }
public float Y { get; set; }
public string Orientation { get; set; }
public bool Big { get; set; }
public Vector2 OrientationV => new Vector2(
Orientation == "W" ? 1 : (Orientation == "E" ? -1 : 0),
Orientation == "N" ? 1 : (Orientation == "S" ? -1 : 0)
);
public static GateBookItemAnchor Get(string[] i)
{
return new GateBookItemAnchor
{
Name = i[0],
X = float.Parse(i[1], CultureInfo.InvariantCulture.NumberFormat),
Y = float.Parse(i[2], CultureInfo.InvariantCulture.NumberFormat),
Orientation = i[3],
Big = i.Length > 4 && i[4].Equals("big"),
};
}
public void ConfigAnchor(Anchor anchor)
{
anchor.Name = Name;
anchor.transform.position = new Vector3(
X,
-Y,
anchor.transform.position.z
);
anchor.Orientation = OrientationV;
}
}
#endregion
}
}
+11
View File
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e3fca8b5d02f66f458aaeb01b0ff1602
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+15
View File
@@ -15,12 +15,21 @@ namespace UntitledLogicGame.Workspace
#region Public Properties
public bool Hovering { get; internal set; }
public SpriteRenderer Renderer {
get
{
if (_renderer == null)
_renderer = GetComponentInChildren<SpriteRenderer>();
return _renderer;
}
}
#endregion
#region Private Properties
private Gate _gate;
private SpriteRenderer _renderer;
#endregion
@@ -48,6 +57,12 @@ namespace UntitledLogicGame.Workspace
#region Public Methods
public void ResetCollider()
{
Destroy(GetComponent<PolygonCollider2D>());
gameObject.AddComponent<PolygonCollider2D>();
}
#endregion
#region Private Methods
@@ -52,13 +52,13 @@ namespace UntitledLogicGame.Workspace.Gates
foreach (var inputName in definition.Inputs)
{
if (!gate.InputAnchors.Any(a => a.Name.Equals(inputName)))
throw new InvalidOperationException($"Gate has no {inputName} input anchor");
throw new InvalidOperationException($"Gate {gateType} has no {inputName} input anchor");
}
foreach (var outputName in definition.Outputs)
{
if (!gate.OutputAnchors.Any(a => a.Name.Equals(outputName)))
throw new InvalidOperationException($"Gate has no {outputName} output anchor");
throw new InvalidOperationException($"Gate {gateType} has no {outputName} output anchor");
}
if (definition.HasState)
+3 -3
View File
@@ -23,7 +23,7 @@ namespace UntitledLogicGame.Workspace
get
{
if (_outputAnchor == null)
_outputAnchor = Anchors.First(g => g.Name == "Q");
_outputAnchor = Anchors.FirstOrDefault(g => g.Name == "Q");
return _outputAnchor;
}
}
@@ -55,8 +55,8 @@ namespace UntitledLogicGame.Workspace
{
if ((Sprite.Hovering || OutputAnchor.Hovering) && PointerManager.Instance.DoubleClick())
{
State = !State;
OutputAnchor.Activated = State;
State = !State;
OutputAnchor.Activated = State;
}
}
+1 -1
View File
@@ -28,7 +28,7 @@ namespace UntitledLogicGame.Workspace
get
{
if (_inputAnchor == null)
_inputAnchor = Anchors.First(g => g.Name == "A");
_inputAnchor = Anchors.FirstOrDefault(g => g.Name == "A");
return _inputAnchor;
}
}