IEnumerator Activate(bool frontSide, bool autoClosing = false, float delay = 0f)
    {
        AudioClip clip = null;


        yield return(new WaitForSeconds(delay));

        float duration      = 1.5f;
        float time          = 0f;
        float startAnimTime = 0f;

        // Ping pong normalized time
        if (_normalizedTime > 0f)
        {
            _normalizedTime = 1 - _normalizedTime;
        }

        if (!_isTwoWay)
        {
            frontSide = true;
        }

        if (_isClosed)
        {
            _isClosed = false;

            if (_normalizedTime > 0)
            {
                frontSide = _openFrontSide;
            }

            _openFrontSide = frontSide;

            if (_doorSounds && AudioManager.instance)
            {
                AudioManager.instance.StopSound(_oneShotSoundID);

                clip = _doorSounds[0];
                if (clip != null)
                {
                    duration = clip.length;
                    if (_audioPunchInPunchOutDatabase != null)
                    {
                        AudioPunchInPunchOutInfo info = _audioPunchInPunchOutDatabase.GetClipInfo(clip);
                        if (info != null)
                        {
                            startAnimTime = Mathf.Min(info.startTime, clip.length);
                            if (info.endTime >= startAnimTime)
                            {
                                duration = info.endTime - startAnimTime;
                            }
                            else
                            {
                                duration = clip.length - startAnimTime;
                            }
                        }
                    }
                    float playbackOffset = 0f;
                    if (_normalizedTime > 0f)
                    {
                        playbackOffset = startAnimTime + (duration * _normalizedTime);
                        startAnimTime  = 0f;
                    }

                    _oneShotSoundID = AudioManager.instance.PlayOneShotSound(_doorSounds.audioGroup,
                                                                             clip,
                                                                             transform.position,
                                                                             _doorSounds.volume,
                                                                             _doorSounds.spatialBlend,
                                                                             _doorSounds.priority,
                                                                             playbackOffset);
                }
            }

            // Determine perceived forward axis and offset and scale the collider in that dimension
            float offset = 0f;
            switch (_localForwardAxis)
            {
            case InteractiveDoorAxisAlignment.XAxis:
                offset = _openColliderSize.x / 2f - _closedColliderSize.x * 2;
                if (frontSide)
                {
                    offset = -offset;
                }
                _openColliderCenter = new Vector3(_closedColliderCenter.x - offset, _closedColliderCenter.y, _closedColliderCenter.z);
                break;

            case InteractiveDoorAxisAlignment.YAxis:
                offset = _openColliderSize.y / 2f - _closedColliderSize.y * 2;;
                if (frontSide)
                {
                    offset = -offset;
                }
                _openColliderCenter = new Vector3(_closedColliderCenter.x, _closedColliderCenter.y - offset, _closedColliderCenter.z);
                break;

            case InteractiveDoorAxisAlignment.ZAxis:
                offset = _openColliderSize.z / 2f - +_closedColliderSize.z * 2;;
                if (frontSide)
                {
                    offset = -offset;
                }
                _openColliderCenter = new Vector3(_closedColliderCenter.x, _closedColliderCenter.y, _closedColliderCenter.z - offset);
                break;

            default:
                break;
            }

            if (_offsetCollider)
            {
                _boxCollider.center = _openColliderCenter;
            }
            _boxCollider.size = _openColliderSize;

            if (startAnimTime > 0)
            {
                yield return(new WaitForSeconds(startAnimTime));
            }

            time = duration * _normalizedTime;

            while (time <= duration)
            {
                _normalizedTime = time / duration;
                foreach (InteractiveDoorInfo door in _doors)
                {
                    if (door != null && door.Transform != null)
                    {
                        door.Transform.position      = Vector3.Lerp(door.ClosedPosition, door.OpenPosition, _normalizedTime);
                        door.Transform.localRotation = door.ClosedRotation * Quaternion.Euler(frontSide || !_isTwoWay ? door.Rotation * _normalizedTime : -door.Rotation * _normalizedTime);
                    }
                }
                time += Time.deltaTime;
                yield return(null);
            }

            // Finally enable colliders of any contents if in the closed position
            if (_contentsMount != null)
            {
                Collider[] colliders = _contentsMount.GetComponentsInChildren <Collider>();
                foreach (Collider col in colliders)
                {
                    col.enabled = true;
                }
            }

            // Reset time to zero
            _normalizedTime = 0f;

            if (_autoclose)
            {
                _coroutine = Activate(frontSide, true, Random.Range(_autoCloseDelay.x, _autoCloseDelay.y));
                StartCoroutine(_coroutine);
            }

            yield break;
        }
        // The door is open so we wish to close it
        else
        {
            _isClosed = true;
            foreach (InteractiveDoorInfo door in _doors)
            {
                if (door != null && door.Transform != null)
                {
                    Quaternion rotationToOpen = Quaternion.Euler(_openFrontSide ? door.Rotation : -door.Rotation);
                    door.OpenRotation = door.ClosedRotation * rotationToOpen;
                }
            }

            // Finally disable colliders of any contents if in the closed position
            if (_contentsMount != null)
            {
                Collider[] colliders = _contentsMount.GetComponentsInChildren <Collider>();
                foreach (Collider col in colliders)
                {
                    col.enabled = false;
                }
            }

            if (_doorSounds && AudioManager.instance)
            {
                AudioManager.instance.StopSound(_oneShotSoundID);

                clip = _doorSounds[autoClosing ? 3 : 1];
                if (clip != null)
                {
                    duration = clip.length;

                    if (_audioPunchInPunchOutDatabase != null)
                    {
                        AudioPunchInPunchOutInfo info = _audioPunchInPunchOutDatabase.GetClipInfo(clip);
                        if (info != null)
                        {
                            startAnimTime = Mathf.Min(info.startTime, clip.length);
                            if (info.endTime >= startAnimTime)
                            {
                                duration = info.endTime - startAnimTime;
                            }
                            else
                            {
                                duration = clip.length - startAnimTime;
                            }
                        }
                    }
                    float playbackOffset = 0f;

                    if (_normalizedTime > 0f)
                    {
                        playbackOffset = startAnimTime + (duration * _normalizedTime);
                        startAnimTime  = 0f;
                    }

                    _oneShotSoundID = AudioManager.instance.PlayOneShotSound(_doorSounds.audioGroup,
                                                                             clip,
                                                                             transform.position,
                                                                             _doorSounds.volume,
                                                                             _doorSounds.spatialBlend,
                                                                             _doorSounds.priority, playbackOffset);
                }
            }

            if (startAnimTime > 0)
            {
                yield return(new WaitForSeconds(startAnimTime));
            }

            time = duration * _normalizedTime;

            while (time <= duration)
            {
                _normalizedTime = time / duration;
                foreach (InteractiveDoorInfo door in _doors)
                {
                    if (door != null && door.Transform != null)
                    {
                        door.Transform.position      = Vector3.Lerp(door.OpenPosition, door.ClosedPosition, _normalizedTime);
                        door.Transform.localRotation = Quaternion.Lerp(door.OpenRotation, door.ClosedRotation, _normalizedTime);
                    }
                }
                time += Time.deltaTime;
                yield return(null);
            }

            foreach (InteractiveDoorInfo door in _doors)
            {
                if (door != null && door.Transform != null)
                {
                    door.Transform.position      = door.ClosedPosition;
                    door.Transform.localRotation = door.ClosedRotation;
                }
            }

            _boxCollider.size   = _closedColliderSize;
            _boxCollider.center = _closedColliderCenter;
        }

        _normalizedTime = 0f;
        _coroutine      = null;
        yield break;
    }
Beispiel #2
0
    // --------------------------------------------------------------------------------------------
    // Name :   Activate (Coroutine)
    // Desc :   This is the function that perform the actual animation of the door
    // --------------------------------------------------------------------------------------------
    private IEnumerator Activate(bool frontSide, bool autoClosing = false, float delay = 0.0f)
    {
        AudioClip clip = null;

        // Chew up any delay time that has been specified
        yield return(new WaitForSeconds(delay));

        // Used to sync animation with sound
        float duration      = 1.5f;
        float time          = 0.0f;
        float startAnimTime = 0.0f;

        if (!_isTwoWay)
        {
            frontSide = true;
        }

        // Ping Pong Normalized Time
        if (_normalizedTime > 0.0f)
        {
            _normalizedTime = 1 - _normalizedTime;
        }

        // If the door is closed then we need to open it
        if (_isClosed)
        {
            // Consider it open from this point on
            _isClosed = false;

            if (_normalizedTime > 0)
            {
                frontSide = _openedFrontside;
            }

            // Record side we opened from
            _openedFrontside = frontSide;

            // Find a sound to play
            if (_doorSounds && AudioManager.instance)
            {
                // Stop any previous animaton sound that might be playing
                AudioManager.instance.StopSound(_oneShotSoundID);

                // Fetch a sound from the open bank
                clip = _doorSounds[0];
                if (clip)
                {
                    // BY default we set the length of the animation to the length of the audo clip
                    duration = clip.length;

                    // Let's see if this clip has markers in the PunchInPunchOut database
                    if (_audioPunchInPunchOutDatabase)
                    {
                        AudioPunchInPunchOutInfo info = _audioPunchInPunchOutDatabase.GetClipInfo(clip);

                        // If it has then adjust start time and duration to match markers
                        if (info != null)
                        {
                            // Get the StartTime registered with this clip
                            startAnimTime = Mathf.Min(info.StartTime, clip.length);

                            // Assuming the end time is larger than the start time the duration of the animation
                            // is simply the time between the two markers
                            if (info.EndTime >= startAnimTime)
                            {
                                duration = info.EndTime - startAnimTime;
                            }
                            else
                            {
                                // Other wise it is assumed we with the play the clip to the end so we just
                                // subtract the start time. This allows us to put zero in the end time slot
                                // instead of having to look up the exact length of each clip we use
                                duration = clip.length - startAnimTime;
                            }
                        }
                    }

                    // If we are already part-way into the animation then we need to start the sound
                    // some way from the beginning
                    float playbackOffset = 0;
                    if (_normalizedTime > 0.0f)
                    {
                        playbackOffset = startAnimTime + (duration * _normalizedTime);
                        startAnimTime  = 0.0f;
                    }

                    _oneShotSoundID = AudioManager.instance.PlayOneShotSound(_doorSounds.audioGroup,
                                                                             clip,
                                                                             transform.position,
                                                                             _doorSounds.volume,
                                                                             _doorSounds.spatialBlend,
                                                                             _doorSounds.priority,
                                                                             playbackOffset);
                }
            }

            // Determine perceived forward axis and offset and scale the collider in that dimension
            float offset = 0.0f;
            switch (_localForwardAxis)
            {
            case InteractiveDoorAxisAlignment.XAxis:
                offset = _openColliderSize.x / 2.0f;
                if (!frontSide)
                {
                    offset = -offset;
                }
                _openColliderCenter = new Vector3(_closedColliderCenter.x - offset, _closedColliderCenter.y, _closedColliderCenter.z);
                break;

            case InteractiveDoorAxisAlignment.YAxis:
                offset = _openColliderSize.y / 2.0f;
                if (!frontSide)
                {
                    offset = -offset;
                }
                _openColliderCenter = new Vector3(_closedColliderCenter.x, _closedColliderCenter.y - offset, _closedColliderCenter.z);
                break;

            case InteractiveDoorAxisAlignment.ZAxis:
                offset = _openColliderSize.z / 2.0f;
                if (!frontSide)
                {
                    offset = -offset;
                }
                _openColliderCenter = new Vector3(_closedColliderCenter.x, _closedColliderCenter.y, _closedColliderCenter.z - offset);
                break;
            }

            if (_offsetCollider)
            {
                _boxCollider.center = _openColliderCenter;
            }
            _boxCollider.size = _openColliderSize;

            // If StartAnimTime is non-zero we need to let some of the sound play before we start animating
            // the door so let's chew up that time here.
            if (startAnimTime > 0.0f)
            {
                yield return(new WaitForSeconds(startAnimTime));
            }

            // Set the starting time of the animation
            time = duration * _normalizedTime;

            // Now complete the animation for each door
            while (time <= duration)
            {
                // Calculate new _normalizedTime
                _normalizedTime = time / duration;

                foreach (InteractiveDoorInfo door in _doors)
                {
                    if (door != null && door.Transform != null)
                    {
                        // Calculate new position and local rotation
                        door.Transform.position      = Vector3.Lerp(door.ClosedPosition, door.OpenPosition, _normalizedTime);
                        door.Transform.localRotation = door.ClosedRotation * Quaternion.Euler(frontSide ? door.Rotation * _normalizedTime : -door.Rotation * _normalizedTime);
                    }
                }
                yield return(null);

                time += Time.deltaTime;
            }


            // Finally disable colliders of any contents if in the closed position
            if (_contentsMount != null)
            {
                Collider[] colliders = _contentsMount.GetComponentsInChildren <Collider>();
                foreach (Collider col in colliders)
                {
                    col.enabled = true;
                }
            }

            // Reset time to zero
            _normalizedTime = 0.0f;

            // If autoClose is active then spawn a new coroutine to close it again
            if (_autoClose)
            {
                _coroutine = Activate(frontSide, true, Random.Range(_autoCloseDelay.x, _autoCloseDelay.y));
                StartCoroutine(_coroutine);
            }
            yield break;
        }

        // The door is open so we wish to close it
        else
        {
            _isClosed = true;

            // Cache the door in its open position
            foreach (InteractiveDoorInfo door in _doors)
            {
                if (door != null && door.Transform != null)
                {
                    Quaternion rotationToOpen = Quaternion.Euler(_openedFrontside ? door.Rotation : -door.Rotation);
                    door.OpenRotation = door.ClosedRotation * rotationToOpen;
                }
            }

            // Finally disable colliders of any contents if in the closed position
            if (_contentsMount != null)
            {
                Collider[] colliders = _contentsMount.GetComponentsInChildren <Collider>();
                foreach (Collider col in colliders)
                {
                    col.enabled = false;
                }
            }

            // Find a sound to play
            if (_doorSounds && AudioManager.instance)
            {
                // Stop any previous animaton sound that might be playing
                AudioManager.instance.StopSound(_oneShotSoundID);

                // Fetch a sound from the open bank
                clip = _doorSounds[autoClosing ? 3 : 1];
                if (clip)
                {
                    // BY default we set the length of the animation to the length of the audo clip
                    duration = clip.length;

                    if (_audioPunchInPunchOutDatabase)
                    {
                        AudioPunchInPunchOutInfo info = _audioPunchInPunchOutDatabase.GetClipInfo(clip);
                        if (info != null)
                        {
                            startAnimTime = Mathf.Min(info.StartTime, clip.length);
                            if (info.EndTime >= startAnimTime)
                            {
                                duration = info.EndTime - startAnimTime;
                            }
                            else
                            {
                                duration = clip.length - startAnimTime;
                            }
                        }
                    }

                    float playbackOffset = 0;
                    if (_normalizedTime > 0.0f)
                    {
                        playbackOffset = startAnimTime + (duration * _normalizedTime);
                        startAnimTime  = 0.0f;
                    }

                    _oneShotSoundID = AudioManager.instance.PlayOneShotSound(_doorSounds.audioGroup,
                                                                             clip,
                                                                             transform.position,
                                                                             _doorSounds.volume,
                                                                             _doorSounds.spatialBlend,
                                                                             _doorSounds.priority,
                                                                             playbackOffset);
                }
            }

            if (startAnimTime > 0.0f)
            {
                yield return(new WaitForSeconds(startAnimTime));
            }

            // Set the starting time
            time = duration * _normalizedTime;

            // Close over time
            while (time <= duration)
            {
                _normalizedTime = time / duration;

                foreach (InteractiveDoorInfo door in _doors)
                {
                    if (door != null && door.Transform != null)
                    {
                        door.Transform.position      = Vector3.Lerp(door.OpenPosition, door.ClosedPosition, _normalizedTime);
                        door.Transform.localRotation = Quaternion.Lerp(door.OpenRotation, door.ClosedRotation, _normalizedTime);
                    }
                }
                yield return(null);

                time += Time.deltaTime;
            }

            foreach (InteractiveDoorInfo door in _doors)
            {
                if (door != null && door.Transform != null)
                {
                    door.Transform.localRotation = door.ClosedRotation;
                    door.Transform.position      = door.ClosedPosition;
                }
            }


            _boxCollider.size   = _closedColliderSize;
            _boxCollider.center = _closedColliderCenter;
        }

        _normalizedTime = 0.0f;
        _coroutine      = null;
        yield break;
    }