Как открыть одинаковую анимацию с двумя одинаковыми коробочными коллайдерами? - PullRequest
0 голосов
/ 25 сентября 2019

У меня есть уровень в игре, когда когда вы попадаете в коробочный коллайдер, открывается портал, а когда вы покидаете его, он закрывается.Оба портала должны открываться, когда я вхожу в ящик коллайдера 1, и оба должны закрываться, когда я покидаю его.Это также должно произойти, когда я вхожу в ящик коллайдера 2 второго портала.У меня есть скрипт для боксового коллайдера 1, и я применяю его к боксовому коллайдеру 2. Он проверяет, находится ли игрок в коллайдере.У меня есть аниматор bool, который напрямую берет переменную из скрипта box collider для проверки диапазона.Я использую этот бул для анимации.Тем не менее, этот аниматор bool не работает для коробочного коллайдера 2. Переменная для коробочного коллайдера работает, но не аниматор bool.Есть ли способ подключить этот второй или мне нужно создать новый скрипт для этого коллайдера?

Код Box Collider:


    public bool inRange;

    private void OnTriggerEnter2D(Collider2D other)
    {
        if (other.CompareTag("Player"))
        {
            inRange = true;
        }
    }

    private void OnTriggerExit2D(Collider2D other)
    {
        if (other.CompareTag("Player"))
        {
            inRange = false;
        }
    } 
}

Код сценария портала:

public class Portal : MonoBehaviour {

    private Animator anim;

    private bool inPortalRange;

    public GameObject portalBorder;

    void Start ()
    {
        anim = GetComponent<Animator>();
    }

    void Update ()
    {
        OpenPortal();
        UpdateAnimation();
    }

    private void UpdateAnimation()
    {
        anim.SetBool("inPortalRange", inPortalRange);
    }

    private void OpenPortal()
    {
        PortalBorder poborder = portalBorder.GetComponent<PortalBorder>();
        inPortalRange = poborder.inRange;
    }
}

Изображение ситуации:

Portals

1 Ответ

1 голос
/ 25 сентября 2019
  • Прежде всего не следует использовать GetComponent каждый кадр.Как и anim, лучше хранить его прямо сейчас.Или вы можете просто сделать portalBorder типа PortalBorder, тогда соответствующая ссылка устанавливается автоматически при обращении к ней через инспектора.

  • Тогда да, в настоящее время вы обновляете только один из аниматоров.,Чтобы управлять ими обоими, нужно как-то их соединить.

Я бы сделал что-то вроде этого

public class Portal : MonoBehaviour 
{
    private Animator anim;
    private bool inPortalRange;
    // Public read-only access
    public bool InPortalRange => inPortalRange;

    // Reference each other via the Inspector in both portals
    public Portal OtherPortal;

    // Give this directly the according type so you don't need GetComponent at all
    public PortalBorder portalBorder;

    // I would recommend to do things always as early as possible
    // Awake is executed before Start
    private void Awake()
    {
        anim = GetComponent<Animator>();
    }

    private void Update ()
    {
        OpenPortal();
        UpdateAnimation();
    }

    private void UpdateAnimation()
    {
        // Here now use the range of either this or the other portal
        anim.SetBool("inPortalRange", InPortalRange || OtherPortal.inPortalRange );
    }

    private void OpenPortal()
    {
        inPortalRange = portalBorder.inRange;
    }
}

Однако вместо того, чтобы сделать это вызовом опроса в Update Я бы на самом деле предпочел бы использовать управляемую событиямиподход:

public class PortalBorder : MonoBehaviour
{
    public UnityEvent OnEnteredPortalRange;
    public UnityEvent OnLeftPortalRange;

    private void OnTriggerEnter2D(Collider2D other)
    {
        if (other.CompareTag("Player"))
        {
            OnEnteredPortalRange.Invoke();
        }
    }

    private void OnTriggerExit2D(Collider2D other)
    {
        if (other.CompareTag("Player"))
        {
            OnEnteredPortalRange.Invoke();
        }
    } 
}

Теперь ваш сценарий должен UnityEvent (точно так же как onClick кнопок), где вы можете добавить обратные вызовы либо с помощью инспектора, либо с помощью кода

public class Portal : MonoBehaviour 
{
    public Animator anim;
    private bool inPortalRange;
    // Public read-only access
    public bool InPortalRange => inPortalRange;

    // Reference each other via the Inspector in both portals
    public Portal OtherPortal;

    // Give this directly the according type so you don't need GetComponent at all
    public PortalBorder portalBorder;

    // I would recommend to do things always as early as possible
    // Awake is executed before Start
    private void Awake()
    {
        anim = GetComponent<Animator>();

        // Instead of checking a bool in Update simply
        // wait until the according events get invoked
        portalBorder.OnEnteredPortalRange.AddListener(EnablePortal);
        portalBorder.OnLeftPortalRange.AddListener(DisablePortal);
    }

    private void OnDestroy()
    {
        // always make sure to remove callbacks when not needed anymore
        // in roder to avoid NullReferenceExceptions
        portalBorder.OnEnteredPortalRange.RemoveListener(EnablePortal);
        portalBorder.OnLeftPortalRange.RemoveListener(DisablePortal);
    }

    public void EnablePortal()
    {
        anim.SetBool("inPortalRange", true);
        OtherPortal.anim.SetBool("inPortalRange", true);
    }

    public void DisablePortal()
    {
        anim.SetBool("inPortalRange", false);
        OtherPortal.anim.SetBool("inPortalRange", false);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...