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; }
// -------------------------------------------------------------------------------------------- // 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; }