Do not know how to use coroutines in Unity3D

前端 未结 3 665
被撕碎了的回忆
被撕碎了的回忆 2021-02-14 16:28

In Unity3D, this is my code:

void ActivateBuff1(){
    gun.equippedGun.msPerShot /= 2;
    gun.equippedGun.shotsLeftInMag += 10;
    StartCoroutine (WaitRage ())         


        
3条回答
  •  灰色年华
    2021-02-14 16:53

    Take a look at my approach. It is using FixedUpdate method to handle timings and does not require Coroutines. Also I used Singleton Pattern in my buffers to enable easy access.

    I have a BufferBase script where I handle start/end of buffers. I can have as many buffers as I like and derive them from this class.

    BufferBase has

    • two members: _isBufferActive and _bufferRemainingTime.

    • A method named FixedUpdateBuffer which I must call in FixedUpdate of my buffers. it is responsible for timing of the buffer and calling EndBuffer() when the time is over.

    • And 3 virtual methods which I can override in my buffer classes.

    Here is the code:

    public class BufferBase : MonoBehaviour
    {
        /// 
        /// Indicates whether the buffer is activated
        /// 
        protected bool _isBufferActive = false;
        /// 
        /// Time until buffer ends
        /// 
        protected float _bufferRemainingTime = 0f;
    
    
        protected void FixedUpdateBuffer()
        {
            if (_isBufferActive)
            {
                _bufferRemainingTime -= Time.fixedDeltaTime;
                if (_bufferRemainingTime <= 0)
                {
                    EndBuffer();
                }
            }
        }
    
        /// 
        /// Resets buffer
        /// 
        protected void ResetBuffer()
        {
            _isBufferActive = false;
            _bufferRemainingTime = 0;
        }
    
        /// 
        /// Marks the start of the buffer
        /// 
        /// 
        protected virtual void StartOrExtendBuffer(float value)
        {
            //set buffer values
            _isBufferActive = true;
            _bufferRemainingTime = value;
    
            gameObject.SetActive(true);
        }
    
        /// 
        /// Marks the end of buffer
        /// 
        protected virtual void EndBuffer()
        {
            _bufferRemainingTime = 0;
            _isBufferActive = false;
    
            gameObject.SetActive(false);
        }
    }
    

    Now for the actual buffer. I have several scripts derived from BufferBase. All of them have those virtual methods implemented in them.

    I can easily:

    1. check whether a specific type of buffer is active or not through RageController.IsActive

    2. activate a buffer using RageController.AddRage(t) where t specifies the duration. (its duration will be reset to t each time AddRage is called)

    3. turn a buffer off using RageController.Reset()

    here is a sample buffer script:

    public class RageController : BufferBase
    {
        public static RageController instance;
    
        public static bool IsActive { get { return instance._isBufferActive; } }
    
        #region Static Methods
        internal static void AddRage(float value)
        {
            instance.StartOrExtendBuffer(value);
        }
    
        internal static void Reset()
        {
            instance.ResetBuffer();
        }
        #endregion
    
        #region Overriden Methods
        protected override void StartOrExtendBuffer(float value)
        {
            base.StartOrExtendBuffer(value);
    
            //----
            //add speed etc..
            //----
        }
    
        protected override void EndBuffer()
        {
            base.EndBuffer();
    
            //----
            //remove speed etc..
            //----
        }
        #endregion   
    
        #region Unity Methods
        void Awake()
        {
            instance = this;
        }
        void FixedUpdate()
        {
            FixedUpdateBuffer();
    
            if (_isBufferActive)
            {
                //----
                //anything that changes by time
                //----
            }
        }
        #endregion
    }
    

    Notice that at the end of RageController in FixedUpdate method you can smoothly change your desired values or enable the buffer with a delay or so by reading the value of _bufferRemainingTime

提交回复
热议问题