Unity移动端相机绕玩家旋转穿墙遮挡问题求助(附代码)
解决Unity相机被遮挡的问题(基于Raycast动态调整位置)
你的思路完全正确——通过Raycast检测相机到玩家pivot之间的遮挡物,然后动态调整相机位置靠近pivot,就能避免被墙体挡住看不到玩家的情况。我帮你修改了代码,实现这个功能,同时修正了一些小问题:
修改后的完整代码
using UnityEngine; public class CameraController : MonoBehaviour { public Transform target1; public Transform pivot; protected ButtonLeft buttonLeft; protected ButtonRight buttonRight; public Vector3 offset; public bool useOffsetValues; public float rotateSpeed; private float originalDistance; // 存储相机到pivot的原始距离 public float minDistance = 0.5f; // 相机能靠近的最小距离(避免贴脸穿模) private void Start() { buttonLeft = FindObjectOfType<ButtonLeft>(); buttonRight = FindObjectOfType<ButtonRight>(); if (!useOffsetValues) { offset = target1.position - transform.position; } // 初始化相机到pivot的原始距离 originalDistance = offset.magnitude; pivot.position = target1.position; pivot.parent = null; } private void Update() { pivot.position = target1.position; // 处理左右旋转输入 if (buttonLeft.Pressed) { pivot.Rotate(0, -90 * Time.deltaTime, 0); Debug.Log("rotate left"); } if (buttonRight.Pressed) { pivot.Rotate(0, 90 * Time.deltaTime, 0); Debug.Log("rotate right"); // 修正原代码的日志错误 } // 计算当前旋转后的相机目标位置(无遮挡时的位置) float desiredYAngle = pivot.eulerAngles.y; float desiredXAngle = pivot.eulerAngles.x; Quaternion rotation = Quaternion.Euler(desiredXAngle, desiredYAngle, 0); Vector3 desiredPosition = target1.position - (rotation * offset); // 发射射线检测遮挡:从pivot指向相机的目标位置 Ray ray = new Ray(pivot.position, desiredPosition - pivot.position); RaycastHit hit; // 忽略玩家层,避免把玩家自身当成遮挡物(请确保你的玩家在"Player"层) LayerMask ignorePlayerMask = ~LayerMask.GetMask("Player"); if (Physics.Raycast(ray, out hit, originalDistance, ignorePlayerMask)) { // 计算新的相机距离,确保不小于最小距离 float newDistance = Vector3.Distance(pivot.position, hit.point) - 0.1f; newDistance = Mathf.Max(newDistance, minDistance); // 根据新距离调整相机位置,避免贴墙 transform.position = pivot.position + ray.direction * newDistance; } else { // 无遮挡时,回到原始位置 transform.position = desiredPosition; } // 始终让相机看向玩家 transform.LookAt(target1); } }
关键改动说明
- 新增原始距离变量:
originalDistance记录相机到pivot的初始距离,作为射线检测的最大范围,确保检测只在相机正常活动区域内进行。 - 完善射线检测逻辑:
- 发射从pivot到相机目标位置的射线,精准检测路径上的遮挡物
- 使用
LayerMask忽略玩家层,防止相机把玩家自身误判为遮挡物 - 命中遮挡物时,将相机移动到命中点前方一点(减去0.1f避免贴墙),同时通过
minDistance限制最小距离,防止相机穿模到玩家体内
- 修正细节错误:原代码中右键旋转的日志写成了"rotate left",现在改成了正确的"rotate right"
- 添加距离保护:
minDistance可以根据游戏需求调整,保证相机始终保持合理的最近视野
使用注意事项
- 确保你的玩家对象被分配到
Player层,否则射线可能会误检测到玩家自身 - 可以根据场景大小和玩家模型尺寸,调整
minDistance的值,平衡视野和防穿模效果 - 如果场景中有透明物体需要忽略,可以在
LayerMask中添加对应的层
内容的提问来源于stack exchange,提问作者Paolo Sito
相关产品推荐
相关产品推荐

