Unity 3D中如何更新出生点/检查点?重生系统问题求助
问题分析与修复方案
核心问题点
- 未保存存档点的实际位置:仅用布尔值标记是否踩中存档点,没有记录存档点坐标,重生时无法定位到存档点
TransportPlayer方法逻辑错误:错误尝试访问布尔值touchBorder的transform属性,完全不符合语法- 存档点触发后未更新重生位置:仅打印日志,没有修改重生位置变量
修复步骤
1. 添加存档点位置存储变量
在类中新增变量保存最近触发的存档点坐标:
Vector3 currentSavePointPosition;
在Start方法初始化时同步为初始出生点:
void Start() { rb = GetComponent<Rigidbody>(); touchBorder = false; touchAnchor = false; p_resetPosition = transform.position; currentSavePointPosition = p_resetPosition; // 初始化为出生点 }
2. 修正存档点检测逻辑,记录位置
修改Update中的射线检测,通过RaycastHit获取命中的存档点对象并记录坐标:
void Update() { // 边界检测 touchBorder = Physics.Raycast(transform.position, Vector3.down, playerHeight * 0.5f + 0.2f, whatIsBorder); // 存档点检测,获取命中对象 RaycastHit hit; touchAnchor = Physics.Raycast(transform.position, Vector3.down, out hit, playerHeight * 0.5f + 0.2f, whatIsSavePoint); if (touchAnchor) { currentSavePointPosition = hit.transform.position; } }
3. 修复TransportPlayer重生逻辑
替换错误的代码逻辑,直接使用存储的存档点位置:
private void TransportPlayer() { rb.transform.position = currentSavePointPosition; rb.transform.rotation = Quaternion.identity; }
4. 优化生命值判断逻辑(可选)
将playerHealth is 0改为playerHealth <= 0,避免因数值异常导致重生逻辑失效:
private void Reset_Player() { if (playerHealth <= 0) { playerHealth = 100; TransportPlayer(); } }
完整修复代码
using System.Collections; using System.Collections.Generic; using UnityEngine; public class ResetPlayer : MonoBehaviour { public float playerHeight; public float playerHealth; [Header("Border")] public LayerMask whatIsBorder; public bool touchBorder; [Header("Save Point")] public LayerMask whatIsSavePoint; public bool touchAnchor; Vector3 p_resetPosition; Vector3 currentSavePointPosition; // 存储最近存档点位置 Rigidbody rb; void Start() { rb = GetComponent<Rigidbody>(); touchBorder = false; touchAnchor = false; p_resetPosition = transform.position; currentSavePointPosition = p_resetPosition; } void Update() { // 边界检测 touchBorder = Physics.Raycast(transform.position, Vector3.down, playerHeight * 0.5f + 0.2f, whatIsBorder); // 存档点检测并记录位置 RaycastHit hit; touchAnchor = Physics.Raycast(transform.position, Vector3.down, out hit, playerHeight * 0.5f + 0.2f, whatIsSavePoint); if (touchAnchor) { currentSavePointPosition = hit.transform.position; } } private void FixedUpdate() { Reset_Player(); PlayerToSpawnpoint(); ResetPlayerFromBorder(); } // 玩家死亡触发重生 private void Reset_Player() { if (playerHealth <= 0) { playerHealth = 100; TransportPlayer(); } } // 触碰边界触发死亡 private void ResetPlayerFromBorder() { if (touchBorder) { playerHealth = 0; Debug.Log(gameObject.name + " 触碰了边界"); } } // 存档点触发提示 private void PlayerToSpawnpoint() { if (touchAnchor) { Debug.Log(gameObject.name + " 触发了存档点"); } } // 传送玩家到重生点 private void TransportPlayer() { rb.transform.position = currentSavePointPosition; rb.transform.rotation = Quaternion.identity; } }
额外注意事项
- 确保存档点对象的Layer与
whatIsSavePoint的LayerMask完全匹配,否则射线检测无法命中 - 调整射线检测距离
playerHeight * 0.5f + 0.2f,确保与玩家模型实际高度匹配,避免漏检或误检 - 可给存档点添加粒子特效等反馈,让玩家明确知晓已触发存档
内容的提问来源于stack exchange,提问作者Dreigonnadoit
相关产品推荐
相关产品推荐

