dynamic loading of gate prefabs
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
@@ -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
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e3fca8b5d02f66f458aaeb01b0ff1602
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user