首页 > 解决方案 > Unity2D:修复库存冲突

问题描述

我的目标是让我在对撞机(2D)上的角色拾取物品不起作用。
所以这是我尝试过的:

播放器控制器脚本:

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

public class PlayerController : MonoBehaviour
{

public float moveSpeed = 2f;

public Inventory inventory;


void Start()
{

}

public bool isGrounded;
public LayerMask groundLayers;



void Update()
{

    // isgrounded?
    isGrounded = Physics2D.OverlapArea(new Vector2(transform.position.x - 
0.2f, transform.position.y - 0.2f),
        new Vector2(transform.position.x + 0.2f, transform.position.y - 
0.21f), groundLayers);
    Jump();
    Vector3 movement = new Vector3(Input.GetAxis("Horizontal"), 0f, 0f);
    transform.position += movement * Time.deltaTime * moveSpeed;
}

void Jump()
{
    if(Input.GetButtonDown("Jump") && isGrounded)
    {
        gameObject.GetComponent<Rigidbody2D>().AddForce(new Vector2(0f, 
2.5f), ForceMode2D.Impulse);
    }
}

private void OnCollisionEnter2D(ControllerColliderHit hit)
{
    IInventoryItem item = hit.collider.GetComponent<IInventoryItem>();
    if (item != null)
    {
        inventory.AddItem(item);
    }
}
}

平视显示器脚本:

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

public class HUD : MonoBehaviour
{

public Inventory Inventory;


void Start ()
{
    Inventory.ItemAdded += InventoryScript_ItemAdded;
}

private void InventoryScript_ItemAdded(object sender, InventoryEventArgs 
e)
{
    Transform inventoryPanel = transform.Find("InventoryPanel");
    foreach(Transform slot in inventoryPanel)
    {
        // Border... Image
        Image image = slot.GetChild(0).GetChild(0).GetComponent<Image>();

        // We found empty slot!
        if (!image.enabled)
        {
            image.enabled = true;
            image.sprite = e.Item.Image;

            // Todo store a reference;


            break;
        }
    }
}
}

库存脚本:

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

public class Inventory : MonoBehaviour
{
private const int SLOTS = 7;

private List<IInventoryItem> mItems = new List<IInventoryItem>();

public event EventHandler<InventoryEventArgs> ItemAdded;

public void AddItem(IInventoryItem item)
{
    if(mItems.Count < SLOTS)
    {
        Collider collider = (item as MonoBehaviour).GetComponent<Collider> 
();
        if (collider.enabled)
        {
            collider.enabled = false;

            mItems.Add(item);

            item.OnPickup();


            if (ItemAdded != null)
            {
                ItemAdded(this, new InventoryEventArgs(item));
            }
        }
    }
}
}

库存物品脚本:

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

public interface IInventoryItem
{
string Name { get;  }

Sprite Image { get;  }

void OnPickup();
}

public class InventoryEventArgs : EventArgs
{
public InventoryEventArgs(IInventoryItem item)
{
    Item = item;
}

public IInventoryItem Item;
}

摇滚脚本(对象):

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

public class Rock : MonoBehaviour, IInventoryItem 
{
public string Name
{
    get
    {
        return "Rock";
    }
}


public Sprite _Image = null;

public Sprite Image
{
    get
    {
        return _Image;
    }
}

public void OnPickup()
{
    // TODO: ADD LOGIC THAT WILL MAKE THE ROCK A 'WEAPON' TO CUT DOWN THE 
TREE
    gameObject.SetActive(false);
}

}

所有这些脚本都有效,但是每当我加入我的游戏并将玩家与对象碰撞(所有 2d、2D 盒子碰撞器等)时,角色不会拿起物品并将其放入库存中?脚本相互引用。

我做错了什么?

物理 2D 截图:

物理二维

播放器检查器截图:

播放器

岩石(需要加入他的库存的对象)

岩石

标签: c#unity3d

解决方案


我注意到的一件事是您正在混合两个事件的语法来创建一个不存在的事件。void OnCollisionEnter2D(ControllerColliderHit hit)不是 Unity 中的内置事件。您可能的意思是使用void OnCollisionEnter2D(Collision2D hit)

private void OnCollisionEnter2D(Collision2D hit)
{
    IInventoryItem item = hit.collider.GetComponent<IInventoryItem>();
    if (item != null)
    {
        inventory.AddItem(item);
    }
}

另一件事是BoxCollider2D不继承自Collider. 因此,在 AddItem 中,您应该寻找一个Collider2D组件:

public void AddItem(IInventoryItem item)
{
    if(mItems.Count < SLOTS)
    {
        Collider2D collider = (item as MonoBehaviour).GetComponent<Collider2D>();
        if (collider.enabled)
        {
            collider.enabled = false;

            mItems.Add(item);

            item.OnPickup();


            if (ItemAdded != null)
            {
                ItemAdded(this, new InventoryEventArgs(item));
            }
        }
    }
}

将其视为部分解决方案,因为这可能无法捕获所需的所有更改...如果仅此一项不能解决以下评论中的问题,请告诉我。


推荐阅读