备份CatanBuilding瘦身独立工程

This commit is contained in:
JSD\13999
2026-05-26 16:15:54 +08:00
commit 2d0e6a61b7
12001 changed files with 2431925 additions and 0 deletions

View File

@@ -0,0 +1,52 @@
#if UNITY_EDITOR
using System;
using System.Collections.Generic;
using System.IO;
using UnityEditor;
#endif
using UnityEngine;
[ExecuteInEditMode]
public class BackBroadEditor : MonoBehaviour
{
#if UNITY_EDITOR
public List<GameObject> prefabs; // 棋盘格子Prefab
public int width = 10; // 棋盘宽度
public int height = 5; // 棋盘高度
public float spacing = 1f; // 格子之间的间距
public void GenerateBoard()
{
// 清除现有的子对象
foreach (Transform child in transform)
{
DestroyImmediate(child.gameObject);
}
// 生成新的棋盘
for (int x = 0; x < width; x++)
{
for (int y = 0; y < height; y++)
{
Vector3 position = new Vector3(x * spacing, y * spacing,0 );
GameObject obj = GetRandomSelection(prefabs);
GameObject broad = PrefabUtility.InstantiatePrefab(obj) as GameObject;
broad.transform.SetParent(this.transform);
broad.transform.localPosition = position;
}
}
}
private GameObject GetRandomSelection(List<GameObject> list)
{
System.Random random = new System.Random();
int n = list.Count;
int randomNumber = random.Next(0, n);
return list[randomNumber];
}
#endif
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 24c00be178dba714a8141f55021933d6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,34 @@
using UnityEngine;
[ExecuteInEditMode]
public class BoxBroadEditor : MonoBehaviour
{
#if UNITY_EDITOR
public int width = 10; // 棋盘宽度
public int height = 5; // 棋盘高度
public float scale = 1;
public void GenerateBoard()
{
// 清除现有的子对象
foreach (Transform child in transform)
{
DestroyImmediate(child.gameObject);
}
// 生成新的棋盘
for (int x = 0; x < width; x++)
{
for (int y = 0; y < height; y++)
{
Vector3 position = new Vector3(x * scale, y * scale ,0 );
GameObject cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
cube.transform.SetParent(this.transform);
cube.transform.localPosition = position;
cube.transform.localScale = new Vector3(scale, scale, scale);
}
}
}
#endif
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: c21b771449994f49b8f9fd99b5982f42
timeCreated: 1723782429

View File

@@ -0,0 +1,31 @@
#if UNITY_EDITOR
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using Newtonsoft.Json;
using UnityEditor;
#endif
using UnityEngine;
[ExecuteInEditMode]
[System.Serializable]
public class BroadScript : MonoBehaviour
{
#if UNITY_EDITOR
public int ID = 201;
[HideInInspector]
public Vector3 LocalPos = Vector3.zero;
public void Update()
{
LocalPos = this.transform.localPosition;
}
public string ToJson()
{
var serializablePos = new SerializableVector3(LocalPos);
return JsonConvert.SerializeObject(new { LocalPos = serializablePos, ID = ID });
}
#endif
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 231d5ded8f11422cb3e4cb2446515ab1
timeCreated: 1723863798

View File

@@ -0,0 +1,260 @@
#if UNITY_EDITOR
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Numerics;
using Newtonsoft.Json;
using Script.EditorScript;
using Script.RuntimeScript.GameLogic;
using UnityEditor;
using UnityEditor.SceneManagement;
#endif
using UnityEngine;
[ExecuteInEditMode]
public class ClampEditorController : MonoBehaviour
{
#if UNITY_EDITOR
public GameObject PropContainer;
public GameObject CubeContainer;
public GameObject BroadContainer;
public RandomPropsTemp RandomPropsTemp;
public void ExportData()
{
BroadScript[] allBroad = BroadContainer.GetComponentsInChildren<BroadScript>();
PropScript[] allProp = PropContainer.GetComponentsInChildren<PropScript>();
CubeScript[] allCube = CubeContainer.GetComponentsInChildren<CubeScript>();
string boxPositionStr = GetPosStr(PropContainer.transform.position);
string allBroadStr = allBroad.Length > 0 ? "[" : string.Empty;
string allPropStr = allProp.Length > 0 ? "[" : string.Empty;
string allCubeStr = allCube.Length > 0 ? "[" : string.Empty;
string allTempStr = RandomPropsTemp.ResultTemps.Count > 0 ? "[" : String.Empty;
for (int i = 0; i < allBroad.Length; i++)
{
if (i == allBroad.Length - 1)
{
allBroadStr += allBroad[i].ToJson() + "]";
}
else
{
allBroadStr += allBroad[i].ToJson() + ",";
}
}
for (int i = 0; i < allProp.Length; i++)
{
if (i == allProp.Length - 1)
{
allPropStr += allProp[i].ToJson() + "]";
}
else
{
allPropStr += allProp[i].ToJson() + ",";
}
}
for (int i = 0; i < allCube.Length; i++)
{
if (i == allCube.Length - 1)
{
allCubeStr += allCube[i].ToJson() + "]";
}
else
{
allCubeStr += allCube[i].ToJson() + ",";
}
}
for (int i = 0; i < RandomPropsTemp.ResultTemps.Count; i++)
{
List<PropTemp> propTemps = RandomPropsTemp.ResultTemps[i];
string tempStr = propTemps.Count > 0 ? "[" : String.Empty;
for (int j = 0; j < propTemps.Count; j++)
{
if (j == propTemps.Count - 1)
{
tempStr += propTemps[j].ToJson() + "]";
}
else
{
tempStr += propTemps[j].ToJson() + ",";
}
}
if (i == RandomPropsTemp.ResultTemps.Count - 1)
{
allTempStr += tempStr + "]";
}
else
{
allTempStr += tempStr + ",";
}
}
SceneObjectList all = new SceneObjectList()
{
BoxPositionJson = boxPositionStr,
AllBroadJson = allBroadStr,
AllPropJson = allPropStr,
AllCubeJson = allCubeStr,
AllTempJson = allTempStr
};
// 序列化为JSON
var activeScene = EditorSceneManager.GetActiveScene();
Debug.Log("Current Scene Name: " + activeScene.name);
string json = JsonConvert.SerializeObject(all);
string url = $"ABPackage/pkgDownloads/EventDigging/DgCommonResource/ClampJson/{activeScene.name}.json";
if (File.Exists(url))
{
File.Delete(url);
}
string filePath = Path.Combine(Application.dataPath, url);
File.WriteAllText(filePath, json);
Debug.Log("Scene exported to " + filePath);
AssetDatabase.Refresh();
}
public void CheckData()
{
PropScript[] allProp = PropContainer.GetComponentsInChildren<PropScript>();
CubeScript[] allCube = CubeContainer.GetComponentsInChildren<CubeScript>();
Dictionary<Vector2Int, int> keyValuePairs = new Dictionary<Vector2Int, int>();
CubeScript cubeScript = null;
Dictionary<int, int> prop = new Dictionary<int, int>();
for (int i = 0; i < allCube.Length; i++)
{
cubeScript = allCube[i];
if (cubeScript.PropId > 0)
{
if (prop.ContainsKey(cubeScript.PropId))
{
prop[cubeScript.PropId]++;
}
else
{
prop.Add(cubeScript.PropId, 1);
}
}
int Row = (int)cubeScript.transform.localPosition.x;
int Col = (int)cubeScript.transform.localPosition.y;
Vector2Int vector2Int = new Vector2Int(Row, Col);
if (!cubeScript.IsBorder)
{
if (keyValuePairs.ContainsKey(vector2Int))
{
Debug.LogError($"土块位置重复:{Row}--{Col}");
}
else
{
keyValuePairs.Add(vector2Int, 1);
}
GameObject prefab = PrefabUtility.GetCorrespondingObjectFromSource(cubeScript.gameObject) as GameObject;
CubeScript cubeScriptP = prefab.GetComponent<CubeScript>();
if (cubeScriptP.DoubleClick != cubeScript.DoubleClick)
{
Debug.LogError($"DoubleClick不一致{Row}--{Col}");
}
}
}
for (int i = 0; i < allProp.Length; i++)
{
int PropId = allProp[i].PropId;
if (PropId > 0)
{
if (prop.ContainsKey(PropId))
{
prop[PropId]--;
}
else
{
prop.Add(PropId, -1);
}
}
}
InspectorEntry[] RandomPropsList = RandomPropsTemp.RandomPropsList;
for (int i = 0; i < RandomPropsList.Length; i++)
{
int PropId = RandomPropsList[i].PropId;
if (RandomPropsList[i].PropId > 0)
{
if (prop.ContainsKey(PropId))
{
prop[PropId]++;
}
else
{
prop.Add(PropId, 1);
}
}
}
foreach (var item in prop)
{
if (item.Value > 0)
{
Debug.LogError($"棋盘上 {item.Key} + {item.Value}");
}
else if (item.Value < 0)
{
Debug.LogError($"棋盘上 {item.Key} {item.Value}");
}
}
}
private string GetPosStr(UnityEngine.Vector3 pos)
{
var serializablePos = new SerializableVector3(pos);
var settings = new JsonSerializerSettings
{
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
};
return JsonConvert.SerializeObject(serializablePos, settings);
}
#endif
}
[System.Serializable]
public class SerializableVector3
{
public float x;
public float y;
public float z;
public SerializableVector3(float x, float y, float z)
{
this.x = x;
this.y = y;
this.z = z;
}
public SerializableVector3(UnityEngine.Vector3 vector)
{
this.x = vector.x;
this.y = vector.y;
this.z = vector.z;
}
public UnityEngine.Vector3 ToVector3()
{
return new UnityEngine.Vector3(x, y, z);
}
}
[System.Serializable]
[ExecuteInEditMode]
public class SceneObjectList
{
public string BoxPositionJson;
public string AllBroadJson;
public string AllPropJson;
public string AllCubeJson;
public string AllTempJson;
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: e546465e63904a8f959b8697a745f4e4
timeCreated: 1723793888

View File

@@ -0,0 +1,173 @@
#if UNITY_EDITOR
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using cfg;
using Newtonsoft.Json;
using SimpleJSON;
using UnityEditor;
#endif
using UnityEngine;
using UnityEngine.UI;
[ExecuteInEditMode]
[System.Serializable]
public class CubeScript : MonoBehaviour
{
#if UNITY_EDITOR
public int PropId = 0;
[AngleSelector]
public int Angle = 0;
public bool IsBorder = false;
public bool DoubleClick = false;
public int ID = 1;
[HideInInspector]
public Vector3 LocalPos = Vector3.zero;
[HideInInspector]
public CubeConfigData ConfigData;
private int _oidAngle = 0;
private int _oidPropId = 0;
private GameObject currentInstance;
private Tables _tables;
private Tables GetTable()
{
if (_tables == null)
{
_tables = new Tables((string fileName) =>
{
return JSON.Parse(
File.ReadAllText(Application.dataPath + "/ABPackage/pkgFirstPackage/Data/" + fileName + ".json"));
});
}
return _tables;
}
private void Awake()
{
_oidAngle = Angle;
if (PropId > 0)
{
ApplyId();
}
}
void OnValidate()
{
if (PropId != _oidPropId)
{
_oidPropId = PropId;
//EditorApplication.delayCall += UpdateModel;
}
if (Angle != _oidAngle)
{
_oidAngle = Angle;
if (ConfigData != null)
{
ConfigData.PropDirection = _oidAngle;
}
EditorApplication.delayCall += UpdateAngle;
}
}
public void ApplyId()
{
UpdateModel();
}
private void UpdateAngle()
{
if (currentInstance != null && ConfigData != null)
{
ConfigData.PropDirection = _oidAngle;
currentInstance.transform.localEulerAngles = new Vector3(0, 0, -ConfigData.PropDirection);
}
}
private void UpdateModel()
{
if (PropId <= 0)
{
_oidAngle = 0;
Angle = 0;
ConfigData = null;
return;
}
string templateName = GetTable().TbDiggingItemList.Get(PropId).GridTemplate;
string templateUrl = $"Assets/AssetsPackage/art/DgSand/Scriptable/CubeConfig/{templateName}.asset";
CubeConfigData asset = AssetDatabase.LoadAssetAtPath<CubeConfigData>(templateUrl);
if (asset == null)
{
Debug.LogError("格子上的道具布局信息 没找到,请检查配置!!" + PropId);
return;
}
ConfigData = asset.Copy();
ConfigData.PropDirection = _oidAngle;
// 清空所有子物体
//foreach (Transform child in transform)
//{
// DestroyImmediate(child.gameObject);
//}
currentInstance = null;
if (!GetTable().TbDiggingItemList.DataMap.TryGetValue(PropId, out DiggingItemList info))
{
return;
}
string modelName = GetTable().TbDiggingItemList.Get(PropId).ItemGridResource;
Debug.LogWarning("目标道具资源名字:" + modelName + " x:" + LocalPos.x + " y:" + LocalPos.y + " angle:" + ConfigData.PropDirection);
string modelUrl = $"Assets/ABPackage/pkgDownloads/EventDigging/DgSand/GridProp/DgSand{modelName}.prefab";
GameObject prefab = AssetDatabase.LoadAssetAtPath<GameObject>(modelUrl);
if (prefab != null)
{
prefab.transform.localPosition = new Vector3(0, 0, -0.5f);
prefab.transform.localEulerAngles = new Vector3(0, 0, -ConfigData.PropDirection);
currentInstance = (GameObject)PrefabUtility.InstantiatePrefab(prefab, transform);
}
else
{
Debug.LogWarning("Prefab not found at path: " + modelUrl);
}
}
public void Update()
{
LocalPos = this.transform.localPosition;
}
public string ToJson()
{
if (ConfigData != null && PropId <= 0)
{
Debug.LogError("检查资源 PropId 没有设置!!!" + " x:" + LocalPos.x + " y:" + LocalPos.y);
return String.Empty;
}
if (PropId > 0 && ConfigData == null)
{
EditorUtility.DisplayDialog("格子道具配置数据没有生成 ConfigData", "PropId " + PropId + " 位置:" + " x:" + LocalPos.x + " y:" + LocalPos.y, "OK");
return String.Empty;
}
var serializablePos = new SerializableVector3(LocalPos);
return JsonConvert.SerializeObject(new { IsBorder = IsBorder, DoubleClick = DoubleClick, PropId = PropId, ConfigData = ConfigData, LocalPos = serializablePos, ID = ID });
}
#endif
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ef0a864c2b870754ba6c64afffa3b218
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 79f300bd9e084f6091a9fc7854a6b44a
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,19 @@
#if UNITY_EDITOR
using UnityEditor;
using UnityEngine;
[CustomEditor(typeof(CubeScript))]
public class CubeControllerEditor : Editor
{
public override void OnInspectorGUI()
{
DrawDefaultInspector();
CubeScript cube = (CubeScript)target;
if (GUILayout.Button("Apply Id"))
{
cube.ApplyId();
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: bb7c3ac829784c849aaf9f0e05eb96a2
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,30 @@
#if UNITY_EDITOR
using UnityEngine;
using UnityEditor;
using System.Linq;
public class AngleSelectorAttribute : PropertyAttribute { }
[CustomPropertyDrawer(typeof(AngleSelectorAttribute))]
public class CubeInspectorAngle : PropertyDrawer
{
private readonly int[] angles = { 0, 90, 180, 270 };
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
if (property.propertyType == SerializedPropertyType.Integer)
{
int currentAngle = property.intValue;
int selectedIndex = Mathf.Max(0, System.Array.IndexOf(angles, currentAngle));
selectedIndex = EditorGUI.Popup(position, label.text, selectedIndex, angles.Select(a => a.ToString()).ToArray());
property.intValue = angles[selectedIndex];
}
else
{
EditorGUI.LabelField(position, label.text, "Use [AngleSelector] with int.");
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1063df1950c112f459d37016df41eb6e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,65 @@
#if UNITY_EDITOR
using Script.EditorScript;
using UnityEditor;
using UnityEngine;
[ExecuteInEditMode]
public class ExtendedEditorWindow : EditorWindow
{
[MenuItem("Window/Tool UI")]
public static void ShowWindow()
{
GetWindow<ExtendedEditorWindow>("Tool UI");
}
void OnGUI()
{
GUILayout.Label("This is an extended editor window", EditorStyles.boldLabel);
if (GUILayout.Button("生成棋盘模板"))
{
GameObject back = GameObject.Find("Board");
BackBroadEditor board = back.GetComponent<BackBroadEditor>();
board.GenerateBoard();
}
if (GUILayout.Button("生成箱子"))
{
GameObject back = GameObject.Find("Box");
BoxBroadEditor board = back.GetComponent<BoxBroadEditor>();
board.GenerateBoard();
}
//if (GUILayout.Button("生成模板数据"))
//{
// GameObject tempObj = GameObject.Find("RandomPropsTemp");
// RandomPropsTemp temp = tempObj.GetComponent<RandomPropsTemp>();
// temp.GenerateTempData();
//}
if (GUILayout.Button("导出数据"))
{
GameObject tempObj = GameObject.Find("RandomPropsTemp");
RandomPropsTemp temp = tempObj.GetComponent<RandomPropsTemp>();
temp.GenerateTempData();
Debug.LogError("模板生成结束");
GameObject init = GameObject.Find("Init");
ClampEditorController board = init.GetComponent<ClampEditorController>();
board.ExportData();
Debug.LogError("导出数据结束");
}
if (GUILayout.Button("检查数据"))
{
GameObject init = GameObject.Find("Init");
ClampEditorController board = init.GetComponent<ClampEditorController>();
board.CheckData();
Debug.LogError("检查数据结束");
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 282a66c987406da48aeb6b92c5e54c9e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,14 @@
#if UNITY_EDITOR
using UnityEngine;
namespace Script.EditorScript
{
[System.Serializable]
[ExecuteInEditMode]
public class InspectorEntry
{
public int PropId;
public CubeConfigData resource;
}
}
#endif

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 61c9e2eb44f6466895e1a3f9cca3c185
timeCreated: 1724641684

View File

@@ -0,0 +1,31 @@
#if UNITY_EDITOR
namespace Script.EditorScript
{
using UnityEditor;
using UnityEngine;
[CustomPropertyDrawer(typeof(InspectorEntry))]
[ExecuteInEditMode]
public class InspectorEntryDrawer : PropertyDrawer
{
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
EditorGUI.BeginProperty(position, label, property);
// 计算各个字段的位置
Rect idRect = new Rect(position.x, position.y, position.width / 2, position.height);
Rect resourceRect = new Rect(position.x + position.width / 2 + 5, position.y, position.width / 2 - 5, position.height);
// 绘制字段
EditorGUI.PropertyField(idRect, property.FindPropertyRelative("PropId"), GUIContent.none);
EditorGUI.PropertyField(resourceRect, property.FindPropertyRelative("resource"), GUIContent.none);
EditorGUI.EndProperty();
}
}
}
#endif

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: fd2c0d2b9fe94df186b140844660eee8
timeCreated: 1724641613

View File

@@ -0,0 +1,20 @@
#if UNITY_EDITOR
using Script.EditorScript;
using UnityEditor;
using UnityEngine;
[CustomEditor(typeof(RandomPropsTemp))]
public class InspectorEntryEditor : Editor
{
public override void OnInspectorGUI()
{
DrawDefaultInspector();
RandomPropsTemp Temp = (RandomPropsTemp)target;
if (GUILayout.Button("Apply Id"))
{
Temp.ApplyId();
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 663bdd53aa80b964594e9a24f43d87f4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,34 @@
#if UNITY_EDITOR
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using Newtonsoft.Json;
using UnityEditor;
#endif
using UnityEngine;
[ExecuteInEditMode]
[System.Serializable]
public class PropScript : MonoBehaviour
{
#if UNITY_EDITOR
public int PropId = 0;
[HideInInspector]
public Vector3 LocalPos = Vector3.zero;
public void Update()
{
LocalPos = this.transform.localPosition;
}
public string ToJson()
{
var settings = new JsonSerializerSettings
{
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
};
return JsonConvert.SerializeObject(new { PropId = PropId, LocalPos = LocalPos }, settings);
}
#endif
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: be80f409c195dfb4abc567ab3081e791
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,465 @@
#if UNITY_EDITOR
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using cfg;
using Newtonsoft.Json;
using SimpleJSON;
using UnityEditor;
#endif
using UnityEngine;
using Random = System.Random;
namespace Script.EditorScript
{
[ExecuteInEditMode]
public class RandomPropsTemp : MonoBehaviour
{
#if UNITY_EDITOR
[Tooltip("棋子容器")]
public GameObject CubeContainer;
[Tooltip("最终导出的模板数量")]
public int TempCount = 20;
[Tooltip("模板生成上线")]
public int TempMaxCount = 10000;
public InspectorEntry[] RandomPropsList;
[NonSerialized]
public List<List<PropTemp>> ResultTemps = new List<List<PropTemp>>();
/// <summary>
/// 索引 为key,用来支持 随机道具 配置都是一样的道具
/// </summary>
private Dictionary<int, List<PropTemp>> _allPropCanPutDic = new Dictionary<int, List<PropTemp>>();
private CubeScript[] _allCube;
private Tables _tables;
private Tables GetTable()
{
if (_tables == null)
{
_tables = new Tables((string fileName) =>
{
return JSON.Parse(
File.ReadAllText(Application.dataPath + "/ABPackage/pkgFirstPackage/Data/" + fileName + ".json"));
});
}
return _tables;
}
public void ApplyId()
{
for (int i = 0; i < RandomPropsList.Length; i++)
{
if (RandomPropsList[i].PropId <= 0)
{
Debug.LogError("随机道具id==0请检查配置");
continue;
}
if (!GetTable().TbDiggingItemList.DataMap.TryGetValue(RandomPropsList[i].PropId, out DiggingItemList info))
{
Debug.LogError("随机模板 道具id配置错误 请检查!!! 错误id:" + RandomPropsList[i].PropId);
continue;
}
string templateName = GetTable().TbDiggingItemList.Get(RandomPropsList[i].PropId).GridTemplate;
string templateUrl = $"Assets/AssetsPackage/art/DgSand/Scriptable/CubeConfig/{templateName}.asset";
CubeConfigData asset = AssetDatabase.LoadAssetAtPath<CubeConfigData>(templateUrl);
if (asset == null)
{
Debug.LogError("资源id 的模板 没找到,请检查配置!!" + RandomPropsList[i].PropId);
return;
}
RandomPropsList[i].resource = asset;
}
Debug.LogError("随机道具id 已经启用");
}
public void GenerateTempData()
{
ResultTemps.Clear();
_allPropCanPutDic.Clear();
_allCube = CubeContainer.GetComponentsInChildren<CubeScript>();
List<CubeScript> allValidCubes = FindAllValidCubes();
Debug.LogWarning("空格子数量:" + allValidCubes.Count);
//分别存储每种道具 所有的摆放位置
CountPlacements(allValidCubes, RandomPropsList, 0);
//计算出所有道具同时可以存在的组合
List<List<PropTemp>> allValidCombination = CalculateAllPlacements();
Debug.LogWarning("有效组合的总个数:" + allValidCombination.Count);
if (allValidCombination.Count == 0)
{
EditorUtility.DisplayDialog("有效组合的总个数为 0", "请扩大Temp最大数量重新执行", "确定");
}
foreach (var validCombination in allValidCombination)
{
Debug.LogWarning("Valid Combination:");
foreach (var propTemp in validCombination)
{
Debug.LogWarning($"PropId: {propTemp.PropId}, angle: {propTemp.ConfigData.PropDirection},Position: ({propTemp.x}, {propTemp.y})");
}
}
// 最终随机出 最多TempCount 个模板进行存储
if (allValidCombination.Count < TempCount)
{
ResultTemps = allValidCombination;
}
else
{
ResultTemps = GetRandomSelection(allValidCombination, TempCount);
}
}
private List<T> GetRandomSelection<T>(List<T> list, int count)
{
Random random = new Random();
return list.OrderBy(x => random.Next()).Take(count).ToList();
}
/// <summary>
/// 计算每种道具 所有能摆放的位置
/// </summary>
/// <param name="validCubes"></param>
/// <param name="props"></param>
/// <param name="propIndex"></param>
private void CountPlacements(List<CubeScript> validCubes, InspectorEntry[] props, int propIndex)
{
if (propIndex >= props.Length)
{
Debug.LogWarning("所有道具位置处理完毕");
return;
}
List<PropTemp> tempFlagList = new List<PropTemp>();
InspectorEntry prop = props[propIndex];
foreach (var rotatedProp in GetRotations(prop.resource))
{
for (int i = 0; i < validCubes.Count; i++)
{
List<CubeScript> useCube = CheckPropNeedGridData(rotatedProp, validCubes[i].gameObject);
if (useCube == null)
{
continue;
}
bool canPut = GetPropIfCanPut(validCubes, useCube);
if (canPut)
{
PropTemp temp = new PropTemp();
temp.x = (int)validCubes[i].gameObject.transform.localPosition.x;
temp.y = (int)validCubes[i].gameObject.transform.localPosition.y;
temp.PropId = prop.PropId;
temp.ConfigData = rotatedProp.Copy();
temp.SetEmployCube(useCube);
tempFlagList.Add(temp);
Debug.Log("propId::" + prop.PropId + " angle::" + temp.ConfigData.PropDirection + " x::" + temp.x + " y::" + temp.y);
}
}
}
_allPropCanPutDic[propIndex] = tempFlagList;
Debug.LogWarning("所有数据propId" + prop.PropId + " 模板数量::" + _allPropCanPutDic[propIndex].Count);
CountPlacements(validCubes, props, ++propIndex);
}
#region
private List<List<PropTemp>> CalculateAllPlacements()
{
List<List<PropTemp>> allCombinations = new List<List<PropTemp>>();
GenerateCombinations(_allPropCanPutDic, new List<PropTemp>(), allCombinations, 0);
List<List<PropTemp>> validCombinations = new List<List<PropTemp>>();
foreach (var combination in allCombinations)
{
if (IsValidCombination(combination))
{
validCombinations.Add(combination);
}
}
return validCombinations;
}
private void GenerateCombinations(Dictionary<int, List<PropTemp>> allPropCanPutDic, List<PropTemp> currentCombination, List<List<PropTemp>> allCombinations, int currentIndex)
{
if (allCombinations.Count >= TempMaxCount)
{
Debug.LogError("到达模板数量上线,开始检查模板合法性");
return;
}
if (currentIndex >= allPropCanPutDic.Count)
{
allCombinations.Add(new List<PropTemp>(currentCombination));
return;
}
//int propId = allPropCanPutDic.Keys.ElementAt(currentIndex);
foreach (var propTemp in allPropCanPutDic[currentIndex])
{
if (allCombinations.Count >= TempMaxCount)
{
Debug.Log($"到达模板数量上线 {allCombinations.Count},开始检查模板合法性");
return;
}
currentCombination.Add(propTemp);
GenerateCombinations(allPropCanPutDic, currentCombination, allCombinations, currentIndex + 1);
currentCombination.RemoveAt(currentCombination.Count - 1);
}
}
/// <summary>
/// 是否是 有效的组合
/// </summary>
/// <param name="currentCombination"></param>
/// <returns></returns>
private bool IsValidCombination(List<PropTemp> currentCombination)
{
Dictionary<int, bool> dic = new Dictionary<int, bool>();
for (int i = 0; i < currentCombination.Count; i++)
{
List<CubeScript> cubes = currentCombination[i].GetEmployCubes();
foreach (var cube in cubes)
{
if (dic.TryGetValue(cube.GetInstanceID(), out bool value))
{
return false;
}
else
{
dic.Add(cube.GetInstanceID(), true);
}
}
}
return true;
}
#endregion
#region
private IEnumerable<CubeConfigData> GetRotations(CubeConfigData prop)
{
yield return GetDataByRotate(prop, 0);
yield return GetDataByRotate(prop, 90);
yield return GetDataByRotate(prop, 180);
yield return GetDataByRotate(prop, 270);
}
private CubeConfigData GetDataByRotate(CubeConfigData prop, int angle)
{
prop.PropDirection = angle;
return prop;
}
/// <summary>
/// 检查是否能放下道具
/// </summary>
/// <param name="validCubes"></param>
/// <param name="useCube"></param>
/// <returns></returns>
private bool GetPropIfCanPut(List<CubeScript> validCubes, List<CubeScript> useCube)
{
for (int i = 0; i < useCube.Count; i++)
{
bool isOk = false;
for (int j = 0; j < validCubes.Count; j++)
{
if (validCubes[j] == useCube[i])
{
isOk = true;
break;
}
}
if (!isOk)
{
return false;
}
}
return true;
}
/// <summary>
/// 找到所有没有被道具占据的空Cube
/// </summary>
/// <returns></returns>
public List<CubeScript> FindAllValidCubes()
{
List<CubeScript> allInvalidCube = new List<CubeScript>();
for (int i = 0; i < _allCube.Length; i++)
{
if (!_allCube[i].IsBorder && _allCube[i].ConfigData != null && _allCube[i].PropId > 0)
{
CubeConfigData gridData = _allCube[i].ConfigData;
//格子下道具绑定格子
List<CubeScript> cubes = CheckPropNeedGridData(gridData, _allCube[i].gameObject);
if (cubes != null)
{
allInvalidCube = allInvalidCube.Concat(cubes).ToList();
}
else
{
Debug.LogWarning("找到配置的道具 放在空格子上,检查配置");
}
}
}
//找到所有没有被道具占据的空Cube
List<CubeScript> allvalidCube = new List<CubeScript>();
bool finded = false;
for (int i = 0; i < _allCube.Length; i++)
{
CubeScript cur = _allCube[i];
finded = false;
if (!_allCube[i].IsBorder)
{
for (int j = 0; j < allInvalidCube.Count; j++)
{
if (cur == allInvalidCube[j])
{
finded = true;
}
}
if (!finded)
{
allvalidCube.Add(cur);
}
}
}
return allvalidCube;
}
/// <summary>
/// 格子下道具绑定格子
/// </summary>
public List<CubeScript> CheckPropNeedGridData(CubeConfigData data, GameObject startObj)
{
int rows = data.GetArray().GetLength(0);
int cols = data.GetArray().GetLength(1);
List<CubeScript> cubes = new List<CubeScript>();
// 起始
Vector3 startPoint = startObj.transform.localPosition;
int allCount = 0;
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
int value = data.GetArray()[i, j];
if (value > 0)
{
allCount++;
// 初始位置
Vector3 positionB = new Vector3(j, i, 0); //空间转换
Vector3 endPosition = startPoint + GetRotatePoint(data.PropDirection, Vector3.zero, positionB);
// Debug.LogWarning($"获取Grid{endPosition.x}" + " col::" + endPosition.y);
CubeScript grid = GetGridItemByRowAndCol((int)Mathf.Round(endPosition.x), (int)Mathf.Round(endPosition.y));
if (grid != null)
{
cubes.Add(grid);
}
}
}
}
if (cubes.Count == allCount)
{
return cubes;
}
else
{
return null;
}
}
public CubeScript GetGridItemByRowAndCol(int row, int col)
{
for (int i = 0; i < _allCube.Length; i++)
{
if (_allCube[i].transform.localPosition.x == row && _allCube[i].transform.localPosition.y == col)
{
return _allCube[i];
}
}
return null;
}
/// <summary>
/// 获取旋转后道具的位置
/// </summary>
/// <param name="angles"></param>
/// <param name="positionA"></param>
/// <param name="positionB"></param>
/// <returns></returns>
private Vector3 GetRotatePoint(int angles, Vector3 positionA, Vector3 positionB)
{
return RotatePointAroundPivot(positionB, positionA, new Vector3(0, 0, -angles));
}
private Vector3 RotatePointAroundPivot(Vector3 point, Vector3 pivot, Vector3 angles)
{
Vector3 dir = point - pivot; // 获取点到枢轴的向量
dir = Quaternion.Euler(angles) * dir; // 旋转向量
point = dir + pivot; // 将点移动回枢轴
return point;
}
#endregion
#endif
}
public class PropTemp
{
#if UNITY_EDITOR
public int x;
public int y;
public int PropId;
public CubeConfigData ConfigData;
//使用的格子
private List<CubeScript> _EmployCubes = new List<CubeScript>();
public List<CubeScript> GetEmployCubes()
{
return _EmployCubes;
}
public void AddEmployCube(CubeScript value)
{
_EmployCubes.Add(value);
}
public void SetEmployCube(List<CubeScript> value)
{
_EmployCubes = value;
}
public string ToJson()
{
var settings = new JsonSerializerSettings
{
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
};
return JsonConvert.SerializeObject(new { x = x, y = y, PropId = PropId, ConfigData = ConfigData }, settings);
}
#endif
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 28c90a5ebb434233b1e9af17b62b6b28
timeCreated: 1724221115

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 337eb61fdd2be5b4f87d36f64d5da9e7
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,117 @@
#if UNITY_EDITOR
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(menuName = "ScriptableObjects/CubeConfigData")]
[System.Serializable]
[ExecuteInEditMode]
public class CubeConfigData : ScriptableObject
{
[Tooltip("090180270左")]
[HideInInspector]
public int PropDirection = 0;
public int PropRows = 2; // 行数
public int PropColumns = 2; // 列数
public int[] PropArr;
[NonSerialized]
public int[,] TempArr;
private int _oidPropRows = 0;
private int _oidPropColumns = 0;
void OnValidate()
{
if (PropRows != _oidPropRows)
{
if(_oidPropRows != 0)
Reset();
_oidPropRows = PropRows;
}
if (PropColumns != _oidPropColumns)
{
if(_oidPropColumns != 0)
Reset();
_oidPropColumns = PropColumns;
}
}
public void InitializePropGrid()
{
PropArr = new int[PropRows * PropColumns];
}
public void Reset()
{
PropArr = null;
TempArr = null;
}
public void Serializable2DArray(int[,] array)
{
PropArr = new int[PropRows * PropColumns];
for (int i = 0; i < PropRows; i++)
{
for (int j = 0; j < PropColumns; j++)
{
PropArr[i * PropColumns + j] = array[i, j];
}
}
}
public int[,] To2DArray()
{
int[,] array = new int[PropRows, PropColumns];
for (int i = 0; i < PropRows; i++)
{
for (int j = 0; j < PropColumns; j++)
{
array[i, j] = PropArr[i * PropColumns + j];
}
}
return array;
}
public int[,] GetArray()
{
if (TempArr != null )
{
return TempArr;
}
if (PropArr == null || PropArr.Length == 0)
{
InitializePropGrid();
}
TempArr = new int[PropRows, PropColumns];
for (int i = 0; i < PropRows; i++)
{
for (int j = 0; j < PropColumns; j++)
{
TempArr[i, j] = PropArr[i * PropColumns + j];
}
}
return TempArr;
}
public CubeConfigData Copy()
{
CubeConfigData copy = ScriptableObject.CreateInstance<CubeConfigData>();
// copy.IdData.EnableId = this.IdData.EnableId;
// copy.IdData.PropId = this.IdData.PropId;
copy.PropDirection = this.PropDirection;
copy.PropRows = this.PropRows;
copy.PropColumns = this.PropColumns;
copy.PropArr = this.PropArr;
return copy;
}
public string ToJson()
{
return JsonUtility.ToJson(this);
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 44be26f5034e36f4fbc04cc64aedd5b2
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,49 @@
#if UNITY_EDITOR
using System;
using UnityEditor;
using UnityEngine;
[CustomEditor(typeof(CubeConfigData))]
[ExecuteInEditMode]
public class PropDataEditor : Editor
{
public override void OnInspectorGUI()
{
CubeConfigData gridData = (CubeConfigData)target;
DrawDefaultInspector();
if (GUILayout.Button("Initialize Grid"))
{
gridData.InitializePropGrid();
}
var arr = gridData.GetArray();
// 显示和编辑二维数组
if (gridData.PropArr != null)
{
for (int i = gridData.PropRows - 1; i >= 0; i--)
{
EditorGUILayout.BeginHorizontal();
for (int j = 0; j < gridData.PropColumns; j++)
{
// arr[i, j] = EditorGUILayout.IntField(i + "x" + j,arr[i, j]);
// Debug.Log(i + "x" + j);
arr[i, j] = EditorGUILayout.IntField(arr[i, j]);
}
EditorGUILayout.EndHorizontal();
}
}
if (GUILayout.Button("Save Grid"))
{
gridData.Serializable2DArray(arr);
// 修改数据后
EditorUtility.SetDirty(gridData);
AssetDatabase.SaveAssets();
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 71f7ac147135573479477bcf96432d0c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: