【问题标题】:Interactable Objects Unity可交互对象 Unity
【发布时间】:2018-09-30 13:19:22
【问题描述】:

首先,很抱歉标题中缺少信息。但我不能做得更好。 关键是我建立了一个抽象类来检查我的所有碰撞,里面有一个名为“isInteracting”的公共布尔值来检查我是否在对撞机内,如果我这样做,“isInteracting”为真,否则为假。所以,从这个父类继承的类可以使用“isInteracting”来知道我什么时候在对撞机里面做某事(例如显示消息、播放声音等),当我创建第二个继承自的类时父类我意识到我的布尔检查我是否在对撞机内没有正常工作,因为两个子类都调用它,我该如何解决?让他们独立。

简单示例:

public class Waitress : CollisionBehaviour
{
    public override void SayHi()
    {
        if (isInteracting) Debug.Log("Hi");
        else return;
    }

    public override void Update()
    {
        SayHi();
        base.Update();
    }
}

“SayHi()”是抽象类“CollisionBehaviour”的一个抽象方法,而“Update()”因为是虚拟的而被覆盖。

应@Poul Bak 的要求:

父类:

public abstract class CollisionBehaviour : MonoBehaviour
{
    [HideInInspector] public bool isInteractingByButtonAction;
    [HideInInspector] public bool isInteractingByTriggerCollision;
    private bool buttonPressed, isInside, a, b;

    private void CheckStay()
    {
        isInteractingByTriggerCollision = true;

        // GameInputs.Interact is a mapped button from my controller
        if (GameInputs.Interact && !buttonPressed)
        {
            buttonPressed = true;
            isInteractingByButtonAction = true;
        }

        a = (!buttonPressed) ? true : false;
        b = (!buttonPressed) ? true : false;
    }

    private void CheckExit()
    {
        isInside = false;
        b = false;
        isInteractingByButtonAction = false;
        isInteractingByTriggerCollision = false;

        if (buttonPressed) buttonPressed = false;
    }

    private void OnTriggerEnter(Collider other)
    {
       if (other.CompareTag("Player")) isInside = true;
    }

    private void OnTriggerExit(Collider other)
    {
        CheckExit();
    }

    private void Update()
    {
        if (isInside) CheckStay();
    }

    public virtual void LateUpdate()
    {
        if (a && b) { /* Will display a sprite to indicate which button should be pressed*/ }
    }
}

儿童班:

public class InteractableObject : CollisionBehaviour
{
    #region Exposed Variables

    public AnimationCurve ease;
    public float smoothTime;
    public float minFov = 30;
    public float maxFov = 50;
    #endregion

    private float currentVelocity;

    private void InteractionFieldOfView()
    {
        // Animerp is an animation curve interpolation... Clever name I know
        Camera.main.fieldOfView = isInteractingByTriggerCollision.Animerp(maxFov, minFov, ref currentVelocity, smoothTime, ease);
    }

    public override void LateUpdate()
    {
        InteractionFieldOfView();
        base.LateUpdate();
    }
}

好吧,正如我告诉你的那样,只有一个类从 CollisionBehaviour 继承时,相机视野 (isInteractingByTriggerCollision) 才能正常工作。 顺便说一句,我避免使用 OntriggerStay,因为垃圾收集器非常高

【问题讨论】:

  • 请显示设置 isInteracting 和其他重要内容的代码。
  • @PoulBak 抱歉回复晚了,我很忙。

标签: c# unity3d


【解决方案1】:

您的帖子格式和解释不佳,我发现很难理解您希望您的代码做什么以及面临的错误,但我还是试了一下。

这个类应该替换你的CollisionBehaviour类,它本质上是模仿OnTriggerStay,当玩家在触发器内时,每帧调用一个函数。

using UnityEngine;

[RequireComponent(typeof(SphereCollider))]
internal abstract class CollisionTrigger : MonoBehaviour
{
    private bool _isPlayerInsideTrigger = false;

    private void Update()
    {
        if(_isPlayerInsideTrigger)
        {
            FakeOnTriggerStay();
        }
    }

    private void OnTriggerEnter(Collider collider)
    {
        if(!collider.CompareTag("Player")) return;
        _isPlayerInsideTrigger = true;
    }

    public abstract void FakeOnTriggerStay();

    private void OnTriggerExit(Collider collider)
    {
        if(!collider.CompareTag("Player")) return;
        _isPlayerInsideTrigger = false;
    }
}

这是一个示例,用于演示使用上面提供的类您的 Waitress 类会是什么样子。

internal class Waitress : CollisionTrigger
{
    public override void FakeOnTriggerStay()
    {
        // Replace this with input system you are using.
        if(Input.GetKeyDown(...))
        {
            Debug.Log("Hi");
        }
    }
}

希望这会有所帮助。

【讨论】:

  • 我知道,我必须清理很多东西才能使其“易于”理解,关于“女服务员”课程,这只是一个示例,非常简单。我喜欢你所做的,但这并不是我所需要的,我想要的是避免在每次创建新类时使用重复的模式,这就是为什么我创建了一个类来检查我何时与某物发生碰撞并返回给我一个如果确实是,则布尔值。但是这个 bool 对于每个子类都是一样的,每个类都会改变他的值,所以我不能检查我是否与某些东西发生碰撞,因为我不会同时与所有这些对象发生碰撞。跨度>
  • CollisionTrigger 类将检查玩家是否与某物发生碰撞,如果发生碰撞将调用FakeOnTriggerStay 方法。它应该完全按照您的意图去做。这种更简洁的多态方法不需要布尔变量,请尝试我的代码并告诉我它是否首先不起作用。谢谢。
  • 好吧,它就像一个魅力,我现在需要用这种结构实现我的其余代码,但我有一个问题,你为什么选择内部?我以前读过关于内部的,但我不知道它是如何工作的。当然感谢。
  • 如果您没有声明访问修饰符(即public),则隐式使用关键字internal。在我的个人项目中,我倾向于使用internal,因为大多数课程不需要是publicinternal 访问器意味着在同一个程序集(即 dll)之外无法访问它(阅读更多 here),它在创建 API 库时很有用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-01-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多