Unity街机游戏:如何根据玩家移动及朝向在四方向生成墙体预制件?
解决方案
核心思路
把单方向生成逻辑扩展为多方向支持,要么通过跟踪前后左右四个基础方向的下一个生成位置,根据玩家与各位置的距离判断是否生成;要么根据玩家当前朝向,只生成对应前方的墙体。
方案1:四方向自动生成(玩家靠近任意方向时触发)
通过字典维护四个方向的生成位置,遍历检查距离并生成墙体:
using System.Collections.Generic; using UnityEngine; public class WallSpawner : MonoBehaviour { public Transform Player; // 玩家Transform引用 public GameObject Walls; // 墙体预制件 public float spawnThreshold = 20f; // 触发生成的距离阈值 public float spawnOffset = 10f; // 每次生成的间隔距离 // 存储四个方向的下一个生成位置 private Dictionary<Vector3, Vector3> _nextSpawnPositions = new Dictionary<Vector3, Vector3>(); void Start() { // 初始化四个方向的初始生成位置(基于玩家初始位置) Vector3 initialPlayerPos = Player.position; _nextSpawnPositions.Add(Vector3.forward, initialPlayerPos + Vector3.forward * spawnOffset); _nextSpawnPositions.Add(Vector3.back, initialPlayerPos + Vector3.back * spawnOffset); _nextSpawnPositions.Add(Vector3.right, initialPlayerPos + Vector3.right * spawnOffset); _nextSpawnPositions.Add(Vector3.left, initialPlayerPos + Vector3.left * spawnOffset); } void Update() { // 遍历四个方向,检查是否满足生成条件 foreach (var direction in new List<Vector3>(_nextSpawnPositions.Keys)) { float distanceToSpawnPoint = Vector3.Distance(Player.position, _nextSpawnPositions[direction]); if (distanceToSpawnPoint < spawnThreshold) { SpawnWalls(direction); } } } void SpawnWalls(Vector3 spawnDirection) { // 在目标位置生成墙体 Instantiate(Walls, _nextSpawnPositions[spawnDirection], Quaternion.identity); // 更新该方向的下一个生成位置 _nextSpawnPositions[spawnDirection] += spawnDirection * spawnOffset; } }
方案2:根据玩家朝向生成(仅生成当前前方墙体)
如果需求是只在玩家朝向的方向生成墙体,可通过向量点积匹配最接近的基础方向:
using System.Collections.Generic; using UnityEngine; public class WallSpawner : MonoBehaviour { public Transform Player; public GameObject Walls; public float spawnThreshold = 20f; public float spawnOffset = 10f; private Dictionary<Vector3, Vector3> _nextSpawnPositions = new Dictionary<Vector3, Vector3>(); private Vector3[] _baseDirections = new[] { Vector3.forward, Vector3.back, Vector3.right, Vector3.left }; void Start() { Vector3 initialPlayerPos = Player.position; foreach (var dir in _baseDirections) { _nextSpawnPositions.Add(dir, initialPlayerPos + dir * spawnOffset); } } void Update() { // 获取玩家平面朝向(忽略Y轴,避免抬头低头影响判断) Vector3 playerForward = Vector3.Normalize(new Vector3(Player.forward.x, 0, Player.forward.z)); // 找到与玩家朝向最接近的基础方向 Vector3 targetDirection = GetClosestBaseDirection(playerForward); float distance = Vector3.Distance(Player.position, _nextSpawnPositions[targetDirection]); if (distance < spawnThreshold) { SpawnWalls(targetDirection); } } Vector3 GetClosestBaseDirection(Vector3 targetDir) { float maxDotProduct = float.MinValue; Vector3 closestDir = Vector3.forward; foreach (var dir in _baseDirections) { float dot = Vector3.Dot(targetDir, dir); if (dot > maxDotProduct) { maxDotProduct = dot; closestDir = dir; } } return closestDir; } void SpawnWalls(Vector3 spawnDirection) { Instantiate(Walls, _nextSpawnPositions[spawnDirection], Quaternion.identity); _nextSpawnPositions[spawnDirection] += spawnDirection * spawnOffset; } }
关键修改说明
- 用字典替换单个
SpawnPosition,实现多方向生成位置的独立跟踪 - 要么遍历四个方向检查距离,要么通过方向匹配逻辑,实现基于玩家位置/朝向的生成触发
- 把方向参数传入
SpawnWalls函数,复用生成逻辑
内容的提问来源于stack exchange,提问作者Joice Philip Thomas
相关产品推荐
相关产品推荐

