Unity传送门Teleport异常:位置偏移且成功率低的问题与解决
解决Unity传送门随机传送的生效概率与卡顿问题
问题根源拆解
你遇到的两个核心问题其实是由不同原因导致的:
- 传送生效概率仅1/4:原代码里的
Random.Range(1, 4)是个坑!Unity的Random.Range(int min, int max)是左闭右开区间,这个调用只会生成1、2、3三个整数,永远不会选中PortalMain4。再加上你没做“排除当前触发传送门”的逻辑,导致触发某些传送门时会出现原地传送(看起来像没生效)。 - 传送后卡顿/位置错误:直接获取传送门的
transform.position,这个位置通常是传送门模型的原点(在模型内部),玩家传过去后会和传送门碰撞体重叠,连续触发OnTriggerEnter事件,导致物理卡顿甚至传送失效。
完整解决方案
我会从逻辑修正和场景设置两方面帮你解决:
第一步:场景层优化 - 新增传送出口空物体
给每个PortalMain1到PortalMain4都添加一个空子物体(命名为PortalExit),把这个空物体拖到传送门顶部的合适位置——确保玩家传过去后,不会和传送门的碰撞体重叠,也不会卡进地面/模型里。
第二步:代码优化 - 修正随机逻辑+指向出口位置
替换你原来的触发代码,用下面的优化版本:
private void OnTriggerEnter(Collider other) { // 过滤非传送门的触发事件 if (!other.gameObject.name.StartsWith("PortalMain")) return; // 提取当前触发的传送门编号 if (!int.TryParse(other.gameObject.name.Replace("PortalMain", ""), out int currentPortalNum)) { Debug.LogError("传送门命名不符合规则,请确保名称为PortalMain1/2/3/4"); return; } // 生成排除当前传送门的随机目标编号 int targetPortalNum; do { targetPortalNum = Random.Range(1, 5); // 左闭右开,生成1-4的随机整数 } while (targetPortalNum == currentPortalNum); // 找到目标传送门的出口空物体 string targetExitPath = $"PortalMain{targetPortalNum}/PortalExit"; GameObject targetExit = GameObject.Find(targetExitPath); if (targetExit == null) { Debug.LogError($"未找到目标传送出口:{targetExitPath},请检查场景内的空物体是否存在"); return; } // 处理传送逻辑(兼容有无Rigidbody的情况) Rigidbody playerRb = GetComponent<Rigidbody>(); if (playerRb != null) { // 临时禁用物理,避免传送时的碰撞冲突 playerRb.isKinematic = true; playerRb.position = targetExit.transform.position; // 重置速度,避免传送后保留之前的运动状态 playerRb.velocity = Vector3.zero; playerRb.angularVelocity = Vector3.zero; playerRb.isKinematic = false; } else { // 无Rigidbody时直接设置位置 transform.position = targetExit.transform.position; } Debug.Log($"已从PortalMain{currentPortalNum}传送到PortalMain{targetPortalNum}"); }
代码关键优化点
- 用
Random.Range(1,5)覆盖1-4所有传送门,解决之前选不到4号的问题 - 通过
do-while循环确保永远不会选中当前触发的传送门,避免原地传送 - 指向传送门的子物体
PortalExit作为目标位置,彻底解决模型重叠卡顿 - 添加了命名校验和空值判断,避免因场景设置错误导致的空引用崩溃
- 重置Rigidbody的速度,让传送后玩家状态更稳定
额外注意事项
- 确保所有传送门的碰撞体都勾选了Is Trigger,否则
OnTriggerEnter不会触发 - 玩家对象需要有非Trigger的Collider(比如CapsuleCollider),如果用物理方式传送,还需要添加Rigidbody组件
- 建议把所有传送门的
PortalExit位置调整到同一高度,保证传送体验一致性
内容的提问来源于stack exchange,提问作者Lv_InSaNe_vL
相关产品推荐
相关产品推荐

