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

Unity 2D生存原型:拾取物品加分功能异常求助

问题描述

我正在制作一款2D四方向移动的生存游戏原型,在实现拾取物品加分功能时遇到了一系列问题:

  • 最初调试显示玩家与物品的碰撞体未触发碰撞
  • 尝试过他人建议的不存在的OnTriggerRemain2D函数,无效
  • 现在碰撞检测已生效,但仅在移动时会大量重复加分,且拾取逻辑不符合预期

现有代码

玩家移动脚本(HracMovement.cs)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class HracMovement : MonoBehaviour
{
    public float playerSpeed = 1000f;
    private Rigidbody2D rb;
    private Vector2 movementDirection;
    public LogicManager logic;

    void Start()
    {
        rb = GetComponent<Rigidbody2D>();
        logic = GameObject.FindGameObjectWithTag("Logic").GetComponent<LogicManager>();
    }

    void Update()
    {
        movementDirection = new Vector2(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical"));
    }

    void FixedUpdate()
    {
        rb.velocity = movementDirection * playerSpeed;
    }
    
    void OnTriggerStay2D(Collider2D collision)
    {
        if (collision.gameObject.CompareTag("Ker") && Input.GetKeyDown(KeyCode.Space))
        {
            logic.addStick();
            Debug.Log("touching");
        }
    }
}

逻辑管理器脚本(LogicManager.cs)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class LogicManager : MonoBehaviour
{
    public int score = 0;
    public Text scoreText;

    void Start()
    {
        
    }

    public void addStick()
    {
        score = score + 1;
        scoreText.text = score.ToString();
    }
}

解决方案

1. 修复重复加分问题(核心)

OnTriggerStay2D会在碰撞持续的每一帧都调用,这就是移动时大量加分的原因。同时Input.GetKeyDown的检测在FixedUpdate周期(OnTriggerStay2D的调用时机)可能出现延迟或重复识别,建议调整逻辑:

修改玩家脚本,拆分碰撞状态检测与按键输入检测:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class HracMovement : MonoBehaviour
{
    public float playerSpeed = 5f; // 修正速度值,原1000f过大
    private Rigidbody2D rb;
    private Vector2 movementDirection;
    public LogicManager logic;
    private Collider2D currentTouchingStick; // 记录当前触发的物品碰撞体

    void Start()
    {
        rb = GetComponent<Rigidbody2D>();
        logic = GameObject.FindGameObjectWithTag("Logic").GetComponent<LogicManager>();
    }

    void Update()
    {
        movementDirection = new Vector2(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical"));
        
        // 在Update中检测按键,保证输入响应准确
        if (currentTouchingStick != null && Input.GetKeyDown(KeyCode.Space))
        {
            logic.addStick();
            Destroy(currentTouchingStick.gameObject); // 拾取后销毁物品,避免重复触发
            currentTouchingStick = null;
            Debug.Log("物品已拾取");
        }
    }

    void FixedUpdate()
    {
        // 标准化移动方向,避免斜向移动速度过快
        if (movementDirection.magnitude > 1)
            movementDirection = movementDirection.normalized;
        
        rb.velocity = movementDirection * playerSpeed;
    }
    
    // 进入触发区域时记录物品
    void OnTriggerEnter2D(Collider2D collision)
    {
        if (collision.gameObject.CompareTag("Ker"))
        {
            currentTouchingStick = collision;
        }
    }

    // 离开触发区域时清空记录
    void OnTriggerExit2D(Collider2D collision)
    {
        if (collision == currentTouchingStick)
        {
            currentTouchingStick = null;
        }
    }
}

2. 调整碰撞体设置(确保触发正常)

  • 玩家对象:确保拥有Rigidbody2D(已添加),保持默认动态状态(不勾选Is Kinematic)
  • 物品对象(Tag为Ker):添加Collider2D(如BoxCollider2D),并勾选Is Trigger;静态物品无需额外添加Rigidbody2D,动态物品需添加Rigidbody2D并勾选Is Kinematic

3. 修正移动速度异常

原playerSpeed = 1000f数值过大,会导致玩家速度异常快,同时可能引发碰撞检测不稳定,建议改为5f~10f区间,根据游戏手感调整。


内容的提问来源于stack exchange,提问作者Slonica

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 08:32:53