【问题标题】:Picking up a key from an opened drawer从打开的抽屉中取出钥匙
【发布时间】:2018-12-04 20:44:13
【问题描述】:

所以我有一个抽屉,它带有一个脚本,该脚本显示一个面板,提示玩家使用触发器打开/关闭抽屉。我也有一个带有类似脚本的钥匙,但它提示玩家也使用面板和触发器来拿起钥匙。我想把钥匙放在抽屉里,所以当玩家按'E'打开抽屉时,他们也可以按'E'来捡起钥匙。我试过让抽屉的碰撞器变小,也让钥匙碰撞器变大,但这只是意味着玩家可以在不打开抽屉的情况下拿起钥匙。实现这一目标的更有效方法是什么?如果需要,我也会附上我的代码。

绘图脚本:

using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Events;

public class DrawerScript : MonoBehaviour
{

UnityEvent Event = new UnityEvent();

public GameObject OpenPanel = null;

private bool _isInsideTrigger = false;

public Animator _animator;

public string OpenText = "Press 'E' to open drawer";

public string CloseText = "Press 'E' to close drawer";

private bool _isOpen = false;

private void Start()
{
    OpenPanel.SetActive(false);
}


void OnTriggerEnter(Collider other)
{
    if (other.tag == "Player")
    {
        _isInsideTrigger = true;
        OpenPanel.SetActive(true);
        UpdatePanelText();
        Event.Invoke();
    }
}

private void UpdatePanelText()
{
    Text panelText = OpenPanel.transform.Find("Text").GetComponent<Text>();
    if (panelText != null)
    {
        panelText.text = _isOpen ? CloseText: OpenText;
    }
}

void OnTriggerExit(Collider other)
{
    if (other.tag == "Player")
    {
        _isInsideTrigger = false;
        OpenPanel.SetActive(false);
    }
}

private bool IsOpenPanelActive
{
    get
    {
        return OpenPanel.activeInHierarchy;
    }
}

// Update is called once per frame
void Update()
{
    if (IsOpenPanelActive && _isInsideTrigger)
    {
        if (Input.GetKeyDown(KeyCode.E))
        {
            _isOpen = !_isOpen;

            Invoke ("UpdatePanelText", 1.0f);

            _animator.SetBool("open", _isOpen);
        }
      }
   }
}

钥匙拾取脚本:

 using UnityEngine.UI;
 using UnityEngine;

 public class PickUp : MonoBehaviour
 {

public Collider Collider;

public GameObject OpenPanel = null;

private bool _isInsideTrigger = false;


public string PickUpText = "Press 'E' to pick up";

private void Start()
{
    if (OpenPanel != null)
    {
        OpenPanel.SetActive(false);
    }
    Collider = GetComponent<Collider>();
}


void OnTriggerEnter(Collider other)
{
    if (other.tag == "Player")
    {
        _isInsideTrigger = true;
        OpenPanel.SetActive(true);
        UpdatePanelText();
    }
}

private void UpdatePanelText()
{
    Text panelText = OpenPanel.transform.Find("Text").GetComponent<Text>();
    if (panelText != null)
    {
        panelText.text = PickUpText;
    }
}

void OnTriggerExit(Collider other)
{
    if (other.tag == "Player")
    {
        _isInsideTrigger = false;
        OpenPanel.SetActive(false);
    }
}

private bool IsOpenPanelActive
{
    get
    {
        return OpenPanel.activeInHierarchy;
    }
}

【问题讨论】:

  • 在取钥匙之前检查抽屉是否打开怎么样..?
  • @RufusL 除非抽屉打开,否则不要让他们拿起钥匙。再说一次,如果他们只想关闭抽屉而不拿起钥匙,您可能会遇到问题。因为这两个动作都是E
  • 好吧,当玩家在抽屉上按下“E”时,您已经有了调用动画的脚本,您可以将键订阅到抽屉上的 UnityEvent,当用户按下 E 时调用它。这可以通过 addlistener 和回调函数来实现。在此功能上,您可以启用或禁用键框碰撞器。
  • @Jimenemex 这就是我遇到的问题,但我希望交互键是 E。
  • @VitorFigueredo 我将如何实现这个,我检查了 API 但我不明白

标签: c# visual-studio unity3d


【解决方案1】:

您可以使用 UnityEvent API。

这不是最好的解决方案,有几种方法可以做到这一点,但如果您想快速解决问题,例如,可以在抽屉类中创建一个 UnityEvent。

你需要添加命名空间:

using UnityEngine.Events;

并且,作为一个变量:

UnityEvent event = new UnityEvent();

这可能会在您的抽屉类上创建一个新事件(非常类似于按钮)。下一步是在您的关键类中创建一个启用或禁用对撞机的方法。方法必须公开。

之后,只需转到抽屉 GameObject 单击“+”号,将 Key GameObject 拖到其中并选择刚刚创建的类和公共方法。这将使该方法订阅该事件。

最后,在您的“打开抽屉”方法中,您只需调用:

event.Invoke();

每个“听”它的人都会被处决,包括你的班级。

【讨论】:

  • 尽管我不是一个非常强大的编码员,但我尝试尽我所能实现它,但我得到了奇怪的结果。在这里我编辑了帖子并添加了我的脚本和实现,请看一下。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-13
  • 1970-01-01
  • 2018-05-06
  • 2023-03-22
  • 2019-04-04
  • 1970-01-01
相关资源
最近更新 更多