首頁>Game>source

我正在用Unity製作2D平臺遊戲.最近,我實施了壓力垫系統.基本上,当玩家觸發打击垫時,應该打開附近的一扇門.系統正常執行,但唯一的問题是玩家停留在打击板上時, OpenWhenOn 動画(用於開門的空闲動画)没有播放.我想让此播放器一直保持播放狀態,只要玩家在打击板上就可以,如果它退出觸發器,則 DoorClosing 應该播放動画.我寫這段代碼主要是為了播放動画,但是它不起作用,我得到了 Null Reference 一直出錯。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
public class PressurePad : MonoBehaviour
{
    private Animator anim;
    public UnityEvent OnActivate;
    public UnityEvent OnDeactivate;
    public GameObject door;
    public float deactivationDelay = 2f;
    int objectsInContact;
    Coroutine waitingToDeactivate;

    IEnumerator Timer()
    {
        yield return new WaitForSeconds(deactivationDelay);
        // Tell our listeners we're switched OFF.
        if (OnDeactivate != null)
            OnDeactivate.Invoke();
        // Return to ready-to-activate state:
        waitingToDeactivate = null;
    }
    void OnTriggerEnter2D(Collider2D other)
    {
       
        if (other.CompareTag("Player"))
         
        {
            anim.Play("OpenWhenOn");
        }
        door.GetComponent<Animator>().Play("OpenWhenOn");
       
        objectsInContact++;
        // Pressure pad pressed.
        if (objectsInContact == 1)
        {
            if (waitingToDeactivate != null)
            {
                // Cancel deactivation timer. 
                StopCoroutine(waitingToDeactivate);
                waitingToDeactivate = null;
            }
            else if (OnActivate != null)
            {
                // Tell our listeners we're switched ON.
                OnActivate.Invoke();
            }
        }
    }
    void OnTriggerExit2D(Collider2D other)
    {
        objectsInContact--;
        // Pressure pad released.
        if (objectsInContact == 0)
        {
            // Start a delay before telling anyone.
            waitingToDeactivate = StartCoroutine(Timer());
        }
    }
}

This is my Animator Controller. HasExitTime 禁用所有過渡. OpenWhenOn之間過渡的條件 和 DoorClosing 設置為false。

最新回復
  • 5月前
    1 #

    我建議您做這樣的事情:

    使用4種動画狀態設置您的Animator控製圖:

      Opening

      Open (single frame with the door stationary in its open position)

      Closing

      Closed (single frame with door stationary in its closed position)

    向圖形添加两个"觸發器"引數:

      "StartOpening"

      "StartClosing"

    添加過渡:

      from Opening to Open with "HasExitTime" so it transitions to the Open state when the Opening animation is finished, holding the door open

      from Closing to Closed with "HasExitTime" so it transitions to the Closed state when the Closing animation is finished, holding the door shut

      from Open/Opening to Closing with a condition on "StartClosing"

      from Closed/Closing to Opening with a condition on "StartOpening"

    在PressureSwitch上連線UnityEvents:

      OnActivate should call your door's Animator.SetTrigger() 方法,其引數為" StartOpening"

        OnDeactivate should call your door's Animator.SetTrigger() 方法,其引數為" StartClosing"

        這使您無需在壓力開關和門之間进行硬耦合就可以對門的開關行為进行接線,甚至不需要自定義門指令碼!

        当然,您也可以寫一个 DoorControl 通過让門管理自己的動画製作者狀態来稍微簡化Inspector設置的指令碼:

        [RequireComponent(typeof(Animator))]
        public class DoorControl {
            [SerializeField, HideInInspector]
            Animator _animator;
            [SerializeField]
            bool _isOpen;
            void OnValidate() {
                _animator = GetComponent<Animator>();
                SetOpen(_isOpen);
            }
            void Start() {
                SetOpen(_isOpen);
            }
            public void Open() {
                SetOpen(true);
            }
            public void Close() {
                SetOpen(false);
            }
            public void SetOpen(bool open) {
                _isOpen = open;
                _animator.SetBool("Open", _isOpen);
            }
        }
        

        現在您可以使用一个布林值而不是两个觸發器来控製您的門( SetBool 方法需要两个引數,因此我们無法通過檢查器將其連線起来).掛起事件要容易一些-您可以致電 DoorControl.Open()DoorControl.Close() 無需键入動画引數的確切名稱-该知識被委派给了 DoorControl ,使您的設置减少耦合。

  • 5月前
    2 #

    我想您可以

    this.gameObject.GetComponent<Animator>().Play("DoorOpening");
    

    所以它將播放並迴圈播放。

    如果您更類似使用動画器本身,還可以複製開門動画並為其添加新的觸發器,因此当您觸發它時,它会一直存在,或者根据您的動画器而改變

    例如,如果您在 OnTriggerEnter()中有壓力垫 您需要訪問門的Animator,然後使用我的指令碼:

    public Animator anim;
    
       void OnTriggerEnter(Collision other)
    {
      if(other.compareTag("Player")
    anim.Play("DoorOpening");
    }
    

    這只是一个示例,但是您可以在任何地方使用它

  • 5月前
    3 #

    我看不到任何將條件設置為true的地方都可以在 DoorOpening之間移動 和 OpenWhenOn 動画.尝試删除 DoorOpening之間的過渡條件 和 OpenWhenOn ,如果没有條件,那就 OpenWhenOn 應该在 DoorOpening之後自動播放 動画播放。

  • networking:通過網路Unity同步執行的代碼
  • unity:計算添加有噪声的網格法線