这个数据库的使用是不是还要配套修改一下其它代码,比如地块生成?
地块生成:using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class 地块生成系统 : MonoBehaviour
{
public 地块数据库 数据库;
public 聊天系统 聊天系统;
private Coroutine 生成协程 = null;
private HashSet<(int X, int Y)> 已生成坐标 = new HashSet<(int X, int Y)>();
private Queue<(int X, int Y)> 边缘队列 = new Queue<(int X, int Y)>();
[Header("外出模式生成配置")]
public float 地块生成间隔 = 5f;
[System.Serializable]
public class 生态类型Config
{
public string 名称;
public float 权重;
public string[] 变异型;
public bool Is极低频 => 名称 == "文明遗骸" || 名称 == "乐园" || 名称 == "死寂岭";
}
private 生态类型Config[] 所有生态类型 = new 生态类型Config[]
{
new 生态类型Config { 名称 = "森林", 权重 = 20 },
new 生态类型Config { 名称 = "草原", 权重 = 20 },
new 生态类型Config { 名称 = "荒漠", 权重 = 20 },
new 生态类型Config { 名称 = "咸水", 权重 = 20 },
new 生态类型Config { 名称 = "淡水", 权重 = 20 },
new 生态类型Config { 名称 = "湿地", 权重 = 10 },
new 生态类型Config { 名称 = "地下洞穴", 权重 = 10 },
new 生态类型Config { 名称 = "巨树", 权重 = 3 },
new 生态类型Config { 名称 = "文明遗骸", 权重 = 1 },
new 生态类型Config { 名称 = "乐园", 变异型 = new[] {"森林", "草原", "荒漠", "咸水", "淡水", "湿地", "地下洞穴", "巨树", "文明遗骸"} },
new 生态类型Config { 名称 = "死寂岭", 变异型 = new[] {"森林", "草原", "荒漠", "咸水", "淡水", "湿地", "地下洞穴", "巨树", "文明遗骸"} }
};
public void 处于外出模式()
{
if (生成协程 != null)
{
StopCoroutine(生成协程);
生成协程 = null;
}
生成协程 = StartCoroutine(生成单次地块());
}
private IEnumerator 生成单次地块()
{
Debug.Log("🔍 开始一次性地块生成");
yield return StartCoroutine(生成单个地块());
}
private IEnumerator 生成单个地块()
{
Debug.Log("🔍 开始单次地块生成:检查初始地块状态");
if (数据库.地块列表.Count == 0)
{
var 初始地块 = new 地块Data
{
序号 = 1,
X = 0,
Y = 0,
生态类型 = 获取随机生态类型()
};
Debug.Log($"🔍 初始地块生态类型:{初始地块.生态类型},请求AI生成详情");
yield return StartCoroutine(请求AI生成内容(初始地块));
数据库.添加地块(初始地块);
已生成坐标.Add((初始地块.X, 初始地块.Y));
更新边缘队列(初始地块.X, 初始地块.Y);
Debug.Log($"✅ 初始地块生成完成:序号{初始地块.序号},坐标({初始地块.X},{初始地块.Y})");
}
else
{
if (边缘队列.Count == 0)
{
Debug.LogWarning("⚠️ 地图已填满,无法继续生成地块");
yield break;
}
List<(int X, int Y)> 候选 = new List<(int X, int Y)>();
while (边缘队列.Count > 0)
{
var coord = 边缘队列.Dequeue();
if (!已生成坐标.Contains(coord))
{
候选.Add(coord);
}
}
if (候选.Count == 0)
{
Debug.LogWarning("⚠️ 无法找到可生成的空位,跳过本次生成");
yield break;
}
var coordToUse = 候选[UnityEngine.Random.Range(0, 候选.Count)];
var 新地块 = new 地块Data
{
序号 = 数据库.地块列表.Count + 1,
X = coordToUse.X,
Y = coordToUse.Y,
生态类型 = 获取随机生态类型(coordToUse.X, coordToUse.Y)
};
Debug.Log($"🔍 新地块信息:序号{新地块.序号},坐标({新地块.X},{新地块.Y}),生态类型{新地块.生态类型},请求AI生成详情");
yield return StartCoroutine(请求AI生成内容(新地块));
数据库.添加地块(新地块);
已生成坐标.Add((新地块.X, 新地块.Y));
更新边缘队列(新地块.X, 新地块.Y);
Debug.Log($"✅ 新地块生成完成:序号{新地块.序号},坐标({新地块.X},{新地块.Y})");
}
}
private void 更新边缘队列(int x, int y)
{
var 候选 = new List<(int X, int Y)>
{
(x + 1, y),
(x - 1, y),
(x, y + 1),
(x, y - 1)
};
foreach (var coord in 候选)
{
if (!已生成坐标.Contains(coord))
{
边缘队列.Enqueue(coord);
}
}
}
private string 获取随机生态类型(int x = 0, int y = 0)
{
bool 周围有极低频 = false;
foreach (var 地块 in 数据库.地块列表)
{
if ((Mathf.Abs(地块.X - x) + Mathf.Abs(地块.Y - y)) == 1 &&
(地块.生态类型.Contains("文明遗骸") || 地块.生态类型.Contains("乐园") || 地块.生态类型.Contains("死寂岭")))
{
周围有极低频 = true;
break;
}
}
List<生态类型Config> 可选类型 = new List<生态类型Config>();
foreach (var 类型 in 所有生态类型)
{
if (类型.Is极低频 && 周围有极低频) continue;
可选类型.Add(类型);
}
float 总权重 = 0;
foreach (var 类型 in 可选类型)
{
总权重 += 类型.权重;
}
float 随机值 = UnityEngine.Random.Range(0f, 总权重);
foreach (var 类型 in 可选类型)
{
if (随机值 <= 类型.权重)
{
if (类型.变异型 != null && 类型.变异型.Length > 0)
{
string 原型 = 类型.变异型[UnityEngine.Random.Range(0, 类型.变异型.Length)];
return $"{类型.名称}({原型})";
}
return 类型.名称;
}
随机值 -= 类型.权重;
}
return "森林";
}
private IEnumerator 请求AI生成内容(地块Data 地块)
{
string 提示词 = $@"你是一个生态科考AI助手,现在要生成一个新的地块信息。
该地块序号为 {地块.序号},坐标为 ({地块.X}, {地块.Y}),生态类型为:{地块.生态类型}。
请根据以下要求生成内容:
- 描述:简洁的环境描述(1~2句话)
- 生物列表:至少3种生物(可以是动物、植物、菌类)
返回格式为 JSON,示例格式如下:
{{
""描述"": """",
""生物列表"": [""狼"", ""兔子"", ""蘑菇""]
}}";
Debug.Log($"📤 发送AI请求(地块{地块.序号}):{提示词}");
AIManager.Instance.发送消息给AI(提示词);
while (AIManager.Instance.当前回复 == null)
{
yield return null;
}
string AI回复 = AIManager.Instance.当前回复;
Debug.Log($"📥 AI返回地块{地块.序号}信息:\n{AI回复}");
try
{
var 数据 = JsonUtility.FromJson<地块Data>(AI回复);
地块.描述 = 数据.描述;
地块.生物列表 = 数据.生物列表;
}
catch (System.Exception ex)
{
Debug.LogError($"❌ 解析AI回复失败(地块{地块.序号}): " + ex.Message);
}
AIManager.Instance.当前回复 = null;
string 开场白提示词 = $@"你是一个生态科考AI助手,现在需要为以下地块生成一段开场白。
地块信息:
- 序号:{地块.序号}
- 坐标:({地块.X}, {地块.Y})
- 生态类型:{地块.生态类型}
- 描述:{地块.描述}
- 生物列表:{string.Join(", ", 地块.生物列表)}
请生成一段开场白,用于用户接受聊天邀请后显示在聊天框中。
";
Debug.Log($"📤 发送AI请求(地块{地块.序号}开场白):{开场白提示词}");
AIManager.Instance.发送消息给AI(开场白提示词);
while (AIManager.Instance.当前回复 == null)
{
yield return null;
}
string 开场白 = AIManager.Instance.当前回复;
Debug.Log($"📥 AI返回地块{地块.序号}开场白:\n{开场白}");
AIManager.Instance.当前回复 = null;
var 临时数据 = new 地块临时信息
{
地块 = 地块,
开场白 = 开场白
};
发出聊天邀请(临时数据);
}
private void 发出聊天邀请(地块临时信息 临时数据)
{
聊天邀请管理器.Instance.显示邀请(临时数据.开场白, () =>
{
聊天系统.打开聊天窗口(临时数据.地块);
});
}
}