Взаимодействующие объекты Unity - PullRequest
0 голосов
/ 29 сентября 2018

Прежде всего, извините за отсутствие информации в заголовке.но я не мог сделать лучше.Суть в том, что я создал абстрактный класс, который проверяет все мои коллизии, внутри есть публичный бул, называемый 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();
    }
}

Ну, поле камерыview (isInteractingByTriggerCollision) работает нормально только тогда, когда только один класс наследует от CollisionBehaviour, как я уже говорил.Кстати, я избегаю OntriggerStay, потому что сборщик мусора довольно высокий

1 Ответ

0 голосов
/ 30 сентября 2018

Ваше сообщение плохо отформатировано и объяснено , и мне было трудно понять, что вы хотите, чтобы ваш код делал с ошибками, тем не менее, я сделал снимок.

Этот классдолжен заменить ваш класс 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");
        }
    }
}

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...