98 lines
3.7 KiB
C#
98 lines
3.7 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using UnityEngine;
|
|
|
|
[CreateAssetMenu(fileName = "BlocksMap", menuName = "BlocksMap", order = 0)]
|
|
public class BlocksMap : ScriptableObject
|
|
{
|
|
[System.NonSerialized]
|
|
public Dictionary<string, Dictionary<Vector3, BlockNode>> blocks = new Dictionary<string, Dictionary<Vector3, BlockNode>>();
|
|
public List<BlockNode> allNodes = new List<BlockNode>();
|
|
public BlockNode rootNode;
|
|
public long calcTotalNodes()
|
|
{
|
|
long totalNodes = 0;
|
|
foreach (Dictionary<Vector3, BlockNode> map in blocks.Values)
|
|
totalNodes += map.Count;
|
|
return totalNodes;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Ensures that the main dictionary and all nested dictionaries are initialized to prevent null reference issues.
|
|
/// </summary>
|
|
public void init(BlocksMap blocksMap = null)
|
|
{
|
|
if (blocks == null) blocks = new Dictionary<string, Dictionary<Vector3, BlockNode>>();
|
|
if (allNodes == null) allNodes = new List<BlockNode>();
|
|
|
|
// load all block types into the main dictionary with null maps to ensure they exist
|
|
List<BlockData> blockDataList = Resources.LoadAll<BlockData>("BlocksData").ToList();
|
|
foreach (BlockData blockData in blockDataList)
|
|
{
|
|
if (!blocks.ContainsKey(blockData.blockName))
|
|
blocks[blockData.blockName] = new Dictionary<Vector3, BlockNode>();
|
|
}
|
|
|
|
// add root node if it exists in the blocksMap
|
|
if (blocksMap != null && blocksMap.rootNode != null)
|
|
{
|
|
Vector3 roundedPos = RoundPosition(blocksMap.rootNode.position);
|
|
Quaternion roundedRot = RoundRotation(blocksMap.rootNode.rotation);
|
|
rootNode = new BlockNode(blocksMap.rootNode.blockData, roundedPos, roundedRot);
|
|
blocks[rootNode.blockData.blockName][rootNode.position] = rootNode;
|
|
// instantiate the root node's block type without adding it to execute stack
|
|
CreateBlockCommand command = new CreateBlockCommand(rootNode.blockData.blockName, rootNode.position, rootNode.rotation, true);
|
|
command.execute();
|
|
}
|
|
}
|
|
|
|
private void OnEnable()
|
|
{
|
|
RebuildDictionary();
|
|
}
|
|
|
|
/// <summary>
|
|
/// rebuild the already filled BlocksMap
|
|
/// </summary>
|
|
private void RebuildDictionary()
|
|
{
|
|
blocks = new Dictionary<string, Dictionary<Vector3, BlockNode>>();
|
|
|
|
List<BlockData> blockDataList = Resources.LoadAll<BlockData>("BlocksData").ToList();
|
|
foreach (BlockData blockData in blockDataList)
|
|
blocks[blockData.blockName] = new Dictionary<Vector3, BlockNode>();
|
|
|
|
// rebuild from serialized allNodes
|
|
foreach (BlockNode node in allNodes)
|
|
{
|
|
if (node?.blockData == null) continue;
|
|
if (!blocks.ContainsKey(node.blockData.blockName))
|
|
blocks[node.blockData.blockName] = new Dictionary<Vector3, BlockNode>();
|
|
blocks[node.blockData.blockName][node.position] = node;
|
|
}
|
|
}
|
|
|
|
public void setRootNode(BlockNode node)
|
|
{
|
|
rootNode = node;
|
|
}
|
|
|
|
public static Vector3 RoundPosition(Vector3 position, float precision = 100f)
|
|
{
|
|
return new Vector3(
|
|
Mathf.Round(position.x * precision) / precision,
|
|
Mathf.Round(position.y * precision) / precision,
|
|
Mathf.Round(position.z * precision) / precision);
|
|
}
|
|
public static Quaternion RoundRotation(Quaternion rotation, float precision = 10f)
|
|
{
|
|
Vector3 euler = rotation.eulerAngles;
|
|
return Quaternion.Euler(
|
|
Mathf.Round(euler.x * precision) / precision,
|
|
Mathf.Round(euler.y * precision) / precision,
|
|
Mathf.Round(euler.z * precision) / precision);
|
|
}
|
|
}
|