首页 > 解决方案 > 在 Unity C# 中拾取物品

问题描述

嗨,我正在实现一个 FPS 游戏,并且我正在尝试设置一个库存系统,这样当我查看一个项目时,它会被拾取并保存在我的库存中。问题是我似乎无法只拾取/销毁一件物品。所有物品都被摧毁。以下脚本附加到我正在测试的项目上。

该项目的检查员图像如下:

附在项目上的脚本如下:

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

public class PickUpItems : MonoBehaviour
{

    Inventory invScript;
    public bool item;
    public int distanceToItem;
    public Camera fpCamera;
  //  public GameObject itemIcon;

    bool pickedUp = false;


    // Use this for initialization
    void Start()
    {
        fpCamera = Camera.main;
        invScript = GameObject.FindWithTag("GameController").GetComponent<Inventory>();
    } //Start

    private void Update()
    {
        Collect();
    }

    void Collect()
    {
        if (Input.GetKeyDown(KeyCode.E) && !pickedUp)
        {
            RaycastHit hit;
            Ray ray = fpCamera.ScreenPointToRay(Input.mousePosition);
            if (Physics.Raycast(ray, out hit, distanceToItem))
            {
                if(hit.collider.gameObject.tag == "Food")
                {
                    Debug.Log("pickedup");
                    pickedUp = true;
                    StartCoroutine("AddItem");
                    //play sound here
                }
            }
        }
    } //Collect


    IEnumerator AddItem()
    {
        yield return new WaitForSeconds(1);
        //GameObject i = Instantiate(itemIcon);
        //i.transform.SetParent(invScript.inventoryPanel.transform);
        Destroy(gameObject);
    } //AddItem


} //class

如果有人可以帮助解决这样的问题,我将不胜感激!

标签: c#unity3d

解决方案


这是因为你已经做到了,所以每个PickUpItems人只关心相机是否在看任何罐头。我还建议做distanceToItem一个浮动:

                if(hit.collider.gameObject.tag == "Food")
                {
                    Debug.Log("pickedup");
                    pickedUp = true;
                    StartCoroutine("AddItem");
                    //play sound here
                }

PickUpItems相反,如果相机指向自己,您应该考虑让每个人都担心PickUpItems

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

public class PickUpItems : MonoBehaviour
{

    Inventory invScript;
    public bool item;
    public float distanceToItem;
    public Camera fpCamera;
  //  public GameObject itemIcon;

    bool pickedUp = false;


    // Use this for initialization
    void Start()
    {
        fpCamera = Camera.main;
        invScript = GameObject.FindWithTag("GameController").GetComponent<Inventory>();
    } //Start

    private void Update()
    {
        Collect();
    }

    void Collect()
    {
        if (Input.GetKeyDown(KeyCode.E) && !pickedUp)
        {
            RaycastHit hit;
            Ray ray = fpCamera.ScreenPointToRay(Input.mousePosition);
            if (Physics.Raycast(ray, out hit, distanceToItem))
            {
                if(hit.collider.gameObject == gameObject)
                {
                    Debug.Log("pickedup");
                    pickedUp = true;
                    StartCoroutine("AddItem");
                    //play sound here
                }
            }
        }
    } //Collect


    IEnumerator AddItem()
    {
        yield return new WaitForSeconds(1);
        //GameObject i = Instantiate(itemIcon);
        //i.transform.SetParent(invScript.inventoryPanel.transform);
        Destroy(gameObject);
    } //AddItem


} //class

顺便说一句,由于它总是在 的每个实例上运行PickUpItems,因此随着场景中的实例越多,它将导致更多的计算。考虑重构,以便Physics.Raycast每帧只运行一次,可能在附加到播放器的脚本中,然后如果它碰到一个带有 的游戏对象PickUpItems,它会告诉该项目被拾取。这样在拥挤的场景中效率更高。


推荐阅读