You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity C#新手技术求助:拾取4个物品后角色持续瞬移无法自由移动问题

解决Unity角色持续瞬移的问题

嘿,我一眼就发现问题所在了——你的瞬移逻辑犯了新手常踩的典型坑:没有限制触发次数!

问题根源

你把瞬移代码放在了OnCollisionStay2D方法里,这个方法会每帧重复执行(只要角色和地面保持碰撞状态)。而scoreValue == 4的条件在你拾取4个物品后会一直成立,所以角色每帧都会被强制拉到目标位置,自然没法在新位置自由移动。

解决方案

给瞬移逻辑加一个「是否已经完成传送」的状态标记,确保只触发一次。具体步骤如下:

  1. 在脚本顶部新增一个私有布尔变量,用来标记传送状态:
private bool hasTeleported = false;
  1. 修改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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 21:12:33