Unity C#新手技术求助:拾取4个物品后角色持续瞬移无法自由移动问题
解决Unity角色持续瞬移的问题
嘿,我一眼就发现问题所在了——你的瞬移逻辑犯了新手常踩的典型坑:没有限制触发次数!
问题根源
你把瞬移代码放在了OnCollisionStay2D方法里,这个方法会每帧重复执行(只要角色和地面保持碰撞状态)。而scoreValue == 4的条件在你拾取4个物品后会一直成立,所以角色每帧都会被强制拉到目标位置,自然没法在新位置自由移动。
解决方案
给瞬移逻辑加一个「是否已经完成传送」的状态标记,确保只触发一次。具体步骤如下:
- 在脚本顶部新增一个私有布尔变量,用来标记传送状态:
private bool hasTeleported = false;
- 修改
OnCollisionStay2D里的瞬移条件,只有当分数等于4且还没传送过时才执行瞬移,并且瞬移后把标记设为true:
if (scoreValue == 4 && !hasTeleported) { transform.position = new Vector2(64.0f, -1.0f); hasTeleported = true; }
额外优化提示
我还注意到你Update方法里有一段多余的代码块,会导致livesText每帧被重复设置,虽然不影响功能,但完全没必要:
// 这段多余的独立代码块可以删掉 { livesText.text = "Lives: " + lives.ToString(); }
你可以把livesText的初始化放在Start方法里,然后在OnCollisionEnter2D中减少lives后再更新一次,这样更高效。
修改后的完整脚本
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class PlayerScript: MonoBehaviour { private Rigidbody2D rd2d; public float speed; public Text scoreText; private int scoreValue; public GameObject winTextObject; public GameObject loseTextObject; private int lives; public Text livesText; // 新增传送状态标记 private bool hasTeleported = false; // Start is called before the first frame update void Start() { rd2d = GetComponent<Rigidbody2D>(); scoreValue = 0; scoreText.text = "Score: " + scoreValue.ToString(); winTextObject.SetActive(false); loseTextObject.SetActive(false); lives = 3; // 初始化生命值文本 livesText.text = "Lives: " + lives.ToString(); } // Update is called once per frame void FixedUpdate() { float hozMovement = Input.GetAxis("Horizontal"); float verMovement = Input.GetAxis("Vertical"); rd2d.AddForce(new Vector2(hozMovement * speed, verMovement * speed)); } private void OnCollisionEnter2D(Collision2D collision) { if (collision.collider.tag == "Coin") { scoreValue += 1; scoreText.text = "Score: " + scoreValue.ToString(); Destroy(collision.collider.gameObject); } else if (collision.collider.tag == "Enemy") { lives -= 1; // 生命值变化时更新文本 livesText.text = "Lives: " + lives.ToString(); Destroy(collision.collider.gameObject); } } void Update() { if (scoreValue >= 4) { winTextObject.SetActive(true); } if (lives <= 0) { loseTextObject.SetActive(true); } if (Input.GetKey("escape")) { Application.Quit(); } } private void OnCollisionStay2D(Collision2D collision) { if (collision.collider.tag == "Ground") { if (Input.GetKey(KeyCode.W)) { rd2d.AddForce(new Vector2(0, 3), ForceMode2D.Impulse); } } // 修改后的瞬移逻辑,只触发一次 if (scoreValue == 4 && !hasTeleported) { transform.position = new Vector2(64.0f, -1.0f); hasTeleported = true; } } }
这样修改后,角色只会在第一次满足scoreValue ==4时瞬移一次,之后就能在新位置自由移动啦!
内容的提问来源于stack exchange,提问作者warlord
相关产品推荐
相关产品推荐

