diff --git a/temp.md b/temp.md index 1957505..af6083f 100644 --- a/temp.md +++ b/temp.md @@ -1,342 +1,110 @@ -using System.Collections.Generic; -using Unity.AI.Navigation; -using UnityEngine; -using UnityEngine.AI; +# 背景故事:《玩偶末世:物件觉醒》 -public class ProceduralMapGenerator : MonoBehaviour -{ - [Header("生成配置")] - public int seed = 12345; - public int maxPieces = 20; - public float gridSize = 2.0f; - - [Header("预制体库")] - public List mapPiecePrefabs = new List(); - public GameObject wallPiecePrefab; // 封口模块 - - [Header("后处理")] - public bool enableMeshCombining = true; - public bool enableNavMesh = true; - - [Header("调试")] - public bool showDebugGizmos = true; - - // 内部状态 - private Dictionary placedPieces = new Dictionary(); - private List openConnections = new List(); - private System.Random random; - private Transform mapRoot; - - void Start() - { - GenerateMap(); - } - - [ContextMenu("生成地图")] - public void GenerateMap() - { - ClearMap(); - InitializeRandom(); - - // 创建地图根对象 - mapRoot = new GameObject("GeneratedMap").transform; - mapRoot.SetParent(transform); - - // 选择起始模块 - PlaceStartPiece(); - - // 主生成循环 - GenerateLoop(); - - // 后处理 - if (enableMeshCombining) - CombineMeshes(); - - if (enableNavMesh) - BuildNavMesh(); - } - - [ContextMenu("清除地图")] - public void ClearMap() - { - if (mapRoot != null) - DestroyImmediate(mapRoot.gameObject); - - placedPieces.Clear(); - openConnections.Clear(); - } - - private void InitializeRandom() - { - random = new System.Random(seed); - } - - private void PlaceStartPiece() - { - // 查找起始模块e - GameObject startPrefab = null; - foreach (var prefab in mapPiecePrefabs) - { - var piece = prefab.GetComponent(); - if (piece != null && piece.isStartPiece) - { - startPrefab = prefab; - break; - } - } - - if (startPrefab == null && mapPiecePrefabs.Count > 0) - { - startPrefab = mapPiecePrefabs[0]; - } - - if (startPrefab == null) - { - Debug.LogError("没有可用的起始模块预制体!"); - return; - } - - // 实例化起始模块 - var startPiece = Instantiate(startPrefab, Vector3.zero, Quaternion.identity, mapRoot); - var mapPiece = startPiece.GetComponent(); - - // 记录位置 - Vector3Int gridPos = WorldToGrid(Vector3.zero); - placedPieces[gridPos] = startPiece; - - // 添加所有连接点到开放列表 - openConnections.AddRange(mapPiece.GetAvailableConnectionPoints()); - - Debug.Log($"放置起始模块: {mapPiece.pieceName} 在位置 {gridPos}"); - } - - private void GenerateLoop() - { - int attempts = 0; - int maxAttempts = maxPieces * 3; // 最大尝试次数 - - while (openConnections.Count > 0 && placedPieces.Count < maxPieces && attempts < maxAttempts) - { - attempts++; - - // 从开放列表中取出一个连接点 - var connection = openConnections[0]; - openConnections.RemoveAt(0); - - // 尝试放置新模块 - if (TryPlacePieceAtConnection(connection)) - { - Debug.Log($"成功放置第 {placedPieces.Count} 个模块"); - } - else - { - // 放置失败,放置封口模块 - PlaceWallPiece(connection); - } - } - - Debug.Log($"生成完成!共放置 {placedPieces.Count} 个模块,尝试次数: {attempts}"); - } - - private bool TryPlacePieceAtConnection(ConnectionPoint connection) - { - // 获取连接点的世界位置和方向 - Vector3 worldPos = connection.localPosition; // 这里需要修正,应该从父对象获取 - Vector3 worldDir = connection.localDirection; - - // 计算新模块的位置 - Vector3 newPiecePos = worldPos + worldDir * gridSize; - Vector3Int gridPos = WorldToGrid(newPiecePos); - - // 检查位置是否已被占用 - if (placedPieces.ContainsKey(gridPos)) - return false; - - // 查找合适的预制体 - var candidates = FindCandidatePieces(connection); - if (candidates.Count == 0) - return false; - - // 随机选择一个候选 - GameObject selectedPrefab = candidates[random.Next(candidates.Count)]; - - // 计算旋转(使新模块的连接点与当前连接点对齐) - Quaternion rotation = Quaternion.LookRotation(-worldDir, Vector3.up); - - // 实例化新模块 - var newPiece = Instantiate(selectedPrefab, newPiecePos, rotation, mapRoot); - var newMapPiece = newPiece.GetComponent(); - - // 检查碰撞 - if (CheckCollision(newPiece)) - { - DestroyImmediate(newPiece); - return false; - } - - // 记录位置 - placedPieces[gridPos] = newPiece; - - // 添加新模块的连接点到开放列表(除了与当前连接点匹配的那个) - var newConnections = newMapPiece.GetAvailableConnectionPoints(); - foreach (var newConn in newConnections) - { - // 简单的方向检查,避免添加反向连接 - Vector3 newWorldDir = newPiece.transform.TransformDirection(newConn.localDirection); - if (Vector3.Dot(newWorldDir, worldDir) < -0.5f) // 大致相反方向 - continue; - - openConnections.Add(newConn); - } - - return true; - } - - private List FindCandidatePieces(ConnectionPoint connection) - { - var candidates = new List(); - - foreach (var prefab in mapPiecePrefabs) - { - var mapPiece = prefab.GetComponent(); - if (mapPiece == null) continue; - - // 简单的风格匹配(可扩展) - if (mapPiece.style != connection.style && connection.style != "default") - continue; - - candidates.Add(prefab); - } - - return candidates; - } - - private void PlaceWallPiece(ConnectionPoint connection) - { - if (wallPiecePrefab == null) return; - - Vector3 worldPos = connection.localPosition; - Vector3 worldDir = connection.localDirection; - Vector3 wallPos = worldPos + worldDir * gridSize * 0.5f; - Vector3Int gridPos = WorldToGrid(wallPos); - - if (!placedPieces.ContainsKey(gridPos)) - { - var wallPiece = Instantiate(wallPiecePrefab, wallPos, Quaternion.LookRotation(-worldDir), mapRoot); - placedPieces[gridPos] = wallPiece; - } - } - - private bool CheckCollision(GameObject piece) - { - var collider = piece.GetComponent(); - if (collider == null) return false; - - // 简单的重叠检测 - var bounds = collider.bounds; - foreach (var placedPiece in placedPieces.Values) - { - var placedCollider = placedPiece.GetComponent(); - if (placedCollider != null && placedCollider.bounds.Intersects(bounds)) - return true; - } - - return false; - } - - private Vector3Int WorldToGrid(Vector3 worldPos) - { - return new Vector3Int( - Mathf.RoundToInt(worldPos.x / gridSize), - Mathf.RoundToInt(worldPos.y / gridSize), - Mathf.RoundToInt(worldPos.z / gridSize) - ); - } - - private void CombineMeshes() - { - // 简单的网格合并实现 - var meshFilters = mapRoot.GetComponentsInChildren(); - if (meshFilters.Length == 0) return; - - // 按材质分组合并 - var combineInstances = new List(); - var materials = new List(); - - foreach (var meshFilter in meshFilters) - { - if (meshFilter.sharedMesh == null) continue; - - var renderer = meshFilter.GetComponent(); - if (renderer == null || renderer.sharedMaterial == null) continue; - - var combine = new CombineInstance - { - mesh = meshFilter.sharedMesh, - transform = meshFilter.transform.localToWorldMatrix - }; - - combineInstances.Add(combine); - - // 禁用原始渲染器 - renderer.enabled = false; - } - - if (combineInstances.Count > 0) - { - // 创建合并的网格对象 - var combinedObject = new GameObject("CombinedMesh"); - combinedObject.transform.SetParent(mapRoot); - - var combinedFilter = combinedObject.AddComponent(); - var combinedRenderer = combinedObject.AddComponent(); - - // 合并网格 - var combinedMesh = new Mesh(); - combinedMesh.CombineMeshes(combineInstances.ToArray()); - combinedFilter.sharedMesh = combinedMesh; - - // 设置材质(使用第一个材质) - if (materials.Count > 0) - combinedRenderer.sharedMaterial = materials[0]; - - Debug.Log($"网格合并完成,合并了 {combineInstances.Count} 个网格"); - } - } - - private void BuildNavMesh() - { - var navMeshSurface = mapRoot.gameObject.GetComponent(); - if (navMeshSurface == null) - navMeshSurface = mapRoot.gameObject.AddComponent(); - - navMeshSurface.BuildNavMesh(); - Debug.Log("NavMesh 生成完成"); - } - - private void OnDrawGizmos() - { - if (!showDebugGizmos) return; - - // 绘制已放置模块的网格位置 - Gizmos.color = Color.blue; - foreach (var kvp in placedPieces) - { - Vector3 worldPos = GridToWorld(kvp.Key); - Gizmos.DrawWireCube(worldPos, Vector3.one * gridSize * 0.8f); - } - - // 绘制开放连接点 - Gizmos.color = Color.red; - foreach (var connection in openConnections) - { - Vector3 worldPos = connection.localPosition; - Gizmos.DrawSphere(worldPos, 0.2f); - } - } - - private Vector3 GridToWorld(Vector3Int gridPos) - { - return new Vector3(gridPos.x * gridSize, gridPos.y * gridSize, gridPos.z * gridSize); - } -} \ No newline at end of file +--- + +## 序幕:寂静降临之日 + +没有人知道那一天究竟发生了什么。 + +上一秒,城市还在呼吸——汽车的鸣笛、手机的铃声、楼道里邻居的争吵。下一秒,所有属于"人类"的声响同时消失,就像有人拔掉了世界的插头。 + +公寓楼的走廊灯还亮着,电视机还开着,锅里煮了一半的面条还在冒着热气。但人不见了。所有人,在同一瞬间,像是被橡皮擦从画布上抹去一样,消失得干干净净。 + +而寂静只持续了三天。 + +第四天凌晨,走廊尽头的旧衣柜发出了第一声"吱呀"。 + +--- + +## 第一章:物件苏醒 + +那不是木料的自然收缩。那是某种意志——某种被压抑了太久、如今终于挣脱了束缚的意志。 + +没有人知道"觉醒"是从哪里开始的。也许是从那台永远在凌晨三点自动开机、播放雪花噪点的老电视。也许是从那把每次主人不在家就会自己从挂钩上掉下来的扫帚。又或许,是从那只看似不起眼、却永远在暗中注视着一切的玩具熊。 + +总之,在人类消失后的第三天到第七天之间,公寓楼里的每一件"东西",都活了过来。 + +不是像机器那样接通了电源,而是真正地——拥有了生命。拥有了情绪。拥有了**敌意**。 + +--- + +## 第二章:觉醒之阶 + +不同物件的觉醒程度并不相同,仿佛冥冥中有一条看不见的阶梯。 + +**最底层:茫然的动作者。** +拖鞋在地板上无意识地拖行,像是在模仿曾经穿着它的那个人。订书机在桌面上一点点爬动,偶尔"咔哒"一声咬下,仿佛还在执行早已无人在意的装订任务。 + +**中间层:感知者。** +扫帚学会了扫地——不是清理灰尘,而是用木杆狠狠扫向挡在它面前的一切。玻璃瓶从窗台滚落、摔碎、又自行重组,它学会了用碎裂的边缘标记自己的领地。 + +**最顶层:支配者。** +旧衣柜不一样。从苏醒的那一刻起,它就没有困惑过。它知道这栋楼现在是它的了。它记得——记得人类将东西塞进它的肚子、关上它的门、忘记它的存在。它记得被遗忘的感觉。现在,它要那些还在楼里活动的"小东西"也感受一下被遗忘的滋味。 + +于是,一场无声的战争在公寓楼的走廊和房间里蔓延开来。觉醒的物件们划分领地,吞噬彼此身上的"碎片"——一种闪着微光的、可能是生命本质的残留物——来变得更加强大。 + +--- + +## 第三章:纽扣里的光 + +而在所有物件之中,有一个最特别的存在。 + +它曾经只是一个手工缝制的玩偶,属于这栋楼里的某个孩子。当人类消失时,它被遗落在沙发上,和一只靠垫、半块橡皮、以及一本折角的《安徒生童话》作伴。 + +它不是普通物件。它身上的每一块布料、每一颗纽扣,都浸透了孩子的体温和情感。当觉醒的浪潮席卷整栋楼时,它没有像其他物件那样只剩下茫然的躁动或扭曲的敌意。在它的身体深处——也许是那颗被缝在心脏位置的老纽扣里——保留着一小簇不属于"物件"的光。 + +那是人类留下的光。 + +它睁开了纽扣做的眼睛。它从沙发上站了起来。它捡起了掉在茶几上的订书机——不是活的,不是敌人,而是一把武器。一把被它的小手紧紧握住、可以发射出金属钉的"手炮"。 + +它不知道自己要去哪里。但它隐隐觉得,楼上有什么东西在召唤它。而它必须在整栋楼——或者说,所有觉醒的物件——彻底失控之前,找到答案。 + +--- + +## 第四章:藏身处 + +玩偶找到了一个相对安全的角落:一间小小的储藏室,藏在走廊的尽头。门锁还勉强能用,窗户对着外墙,暂时没有哪个觉醒物件想到这里。它把这里叫做"藏身处"。 + +在这里,它可以修复自己战斗中破损的身体——从散落的布料和金属碎片中搜刮材料,缝补身上裂开的口子,加固即将散架的关节。它还发现,那些觉醒物件掉落的碎片可以被"编织"进自己的身体,赋予它新的力量。 + +更重要的是,它发现了一些"模块"——那些曾经只是普通工具的零件,经过觉醒能量的浸染,如今能够在战斗中自动响应它的意志。闪电从缝衣针尖迸发,扳手在身前盘旋成回旋的守护者,订书钉组成的无人机在头顶悬停警戒。 + +每拿到一个新的模块,它都感觉自己离那团"光"更近了一步。 + +--- + +## 第五章:向上 + +玩偶知道,这栋楼有二十几层。也许更多。它不知道自己能撑到第几层。每一次推开通往下一层的门,都意味着面临更危险的敌人、更密集的追杀、以及更长的撤退路线。 + +但它没有选择回头。因为每一次它从一场苦战中活下来、关好藏身处的门、把搜刮到的材料摊在桌子上时,它都能感觉到那团光在自己身体里亮了一点点。 + +而它开始隐约听到一个声音——不一定是用耳朵听的。那是一种直接传到它纽扣心脏深处的低语,来自楼顶,来自衣柜封锁的某个地方。那声音说: + +*"继续走。继续爬。你在找的不是答案。是我。"* + +它不知道那是什么。它只知道,在这栋充满敌意的楼里,所有还在"活着"的物件都在往上爬——或者往某个中心汇聚。就好像整栋公寓楼变成了一座倒悬的塔,而塔尖藏着吞噬一切的漩涡。 + +也许"觉醒"不是意外。也许"觉醒"只是某种仪式的前奏。 + +而玩偶手中的订书机,扣响了第一声扳机。 + +--- + +## 第六章:每一局都是一次挑战 + +现在,这栋公寓楼在等待新的挑战者。 + +每当你操控玩偶走出藏身处,推开走廊尽头的防火门,一局新的"向上攀登"就开始了。你将在五个楼层中厮杀前行——在杂兵楼层的混乱中站稳脚跟,在事件层做出生死抉择,在精英层的逼迫下证明自己的走位,最终直面每五层末端的衣柜Boss。 + +你可以选择在途中撤离,带着已经到手的所有材料安全返回藏身处。但你也可以赌一把——闯入下一层,面对更强的敌人,换取更多的资源。因为你知道,只有最勇敢的攀登者,才能接触到那扇被衣柜封锁的门后面隐藏的真相。 + +而无论你死了多少次,无论你撤离了多少回,藏身处的灯光永远亮着。材料还在手里。模块还在身上。你已经比昨天更强了一点。 + +这就是玩偶的末世。所有日常之物都不再日常,所有熟悉之物都变得陌生,所有被遗忘之物都开始复仇。 + +而一个巴掌大的布娃娃,将用手里的订书机,一件一件地,把这个世界拼回来。 + +--- + +*—— 故事,才刚刚开始。*