交互对象统一

时间:2018-09-29 20:24:09

标签: c# unity3d

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

简单示例:

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,因为垃圾收集器的流量很高

1 个答案:

答案 0 :(得分:2)

您的帖子格式和解释不正确,我发现很难理解您希望代码执行的操作以及所面临的错误,尽管如此,我还是很努力。

该类应该替换您的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");
        }
    }
}

希望这会有所帮助。