Created
March 29, 2018 01:17
-
-
Save CKShare/a3c00c01b9072b7c381c994359a78608 to your computer and use it in GitHub Desktop.
오브젝트별 타임스케일 적용
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public interface ITimeControl | |
{ | |
void Initialize(); | |
void AdjustTimeScale(float timeScale); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections; | |
using System.Collections.Generic; | |
using UnityEngine; | |
[RequireComponent(typeof(Rigidbody))] | |
[RequireComponent(typeof(SphereCollider))] | |
public class TimeArea : MonoBehaviour | |
{ | |
private struct ScaleTarget | |
{ | |
public ScaleTarget(Transform transform, TimeController timeController) | |
{ | |
Transform = transform; | |
TimeController = timeController; | |
} | |
public Transform Transform { get; private set; } | |
public TimeController TimeController { get; private set; } | |
} | |
[SerializeField] | |
private AnimationCurve _scaleCurve; | |
[SerializeField] | |
private float _scaleDelay = 0.1F; | |
[SerializeField] | |
private float _duration = 4F; | |
private Rigidbody _rigidbody; | |
private SphereCollider _collider; | |
private List<ScaleTarget> _targets = new List<ScaleTarget>(); | |
private Coroutine _scaleCoroutine; | |
private WaitForSeconds _scaleDelayRef; | |
private WaitForSeconds _durationRef; | |
private void Awake() | |
{ | |
_collider = GetComponent<SphereCollider>(); | |
_rigidbody = GetComponent<Rigidbody>(); | |
_rigidbody.isKinematic = true; | |
_collider.isTrigger = true; | |
_scaleDelayRef = new WaitForSeconds(_scaleDelay); | |
_durationRef = new WaitForSeconds(_duration); | |
} | |
private void OnEnable() | |
{ | |
StartCoroutine(Deactivate()); | |
_scaleCoroutine = StartCoroutine(Scale()); | |
} | |
private void OnDisable() | |
{ | |
foreach (var target in _targets) | |
target.TimeController.RemoveEffector(this); | |
_targets.Clear(); | |
StopCoroutine(_scaleCoroutine); | |
} | |
private void OnTriggerEnter(Collider collider) | |
{ | |
var timeController = collider.GetComponent<TimeController>(); | |
if (timeController != null) | |
{ | |
_targets.Add(new ScaleTarget(collider.transform, timeController)); | |
} | |
} | |
private void OnTriggerExit(Collider collider) | |
{ | |
var timeController = collider.GetComponent<TimeController>(); | |
if (timeController != null) | |
{ | |
int index = _targets.FindIndex(x => x.Transform == collider.transform); | |
_targets.RemoveAt(index); | |
timeController.RemoveEffector(this); | |
} | |
} | |
private IEnumerator Deactivate() | |
{ | |
yield return _durationRef; | |
gameObject.SetActive(false); | |
} | |
private IEnumerator Scale() | |
{ | |
Bounds bounds = _collider.bounds; | |
Vector3 center = bounds.center; | |
float radius = bounds.extents.x; | |
while (true) | |
{ | |
foreach (var target in _targets) | |
{ | |
float distance = (target.Transform.position - center).magnitude; | |
float ratio = Mathf.Clamp(distance, 0F, radius) / radius; | |
float timeScale = _scaleCurve.Evaluate(ratio); | |
target.TimeController.AddOrSetEffector(this, timeScale); | |
} | |
yield return _scaleDelayRef; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
public class TimeControllableAnimator : ITimeControl | |
{ | |
[SerializeField] | |
private Animator _animator; | |
private float _speed; | |
public void Initialize() | |
{ | |
_speed = _animator.speed; | |
} | |
public void AdjustTimeScale(float timeScale) | |
{ | |
_animator.speed = _speed * timeScale; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
public class TimeControllableAudioSource : ITimeControl | |
{ | |
[SerializeField] | |
private AudioSource _audioSource; | |
private float _pitch; | |
public void Initialize() | |
{ | |
_pitch = _audioSource.pitch; | |
} | |
public void AdjustTimeScale(float timeScale) | |
{ | |
_audioSource.pitch = _pitch * timeScale; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
public class TimeControllableParticleSystem : ITimeControl | |
{ | |
[SerializeField] | |
private ParticleSystem _particleSystem; | |
private float _simulationSpeed; | |
public void Initialize() | |
{ | |
_simulationSpeed = _particleSystem.main.simulationSpeed; | |
} | |
public void AdjustTimeScale(float timeScale) | |
{ | |
var module = _particleSystem.main; | |
module.simulationSpeed = _simulationSpeed * timeScale; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections.Generic; | |
using UnityEngine; | |
using Sirenix.OdinInspector; | |
[DefaultExecutionOrder(-32000)] | |
public class TimeController : SerializedMonoBehaviour | |
{ | |
[ShowInInspector, ReadOnly] | |
private float _timeScale = 1F; | |
[SerializeField, HideReferenceObjectPicker] | |
private ITimeControl[] _components = new ITimeControl[0]; | |
private Dictionary<object, float> _effectors = new Dictionary<object, float>(); | |
private bool _isChanged = false; | |
private void Awake() | |
{ | |
foreach (var comp in _components) | |
comp.Initialize(); | |
} | |
private void FixedUpdate() | |
{ | |
DeltaTime = Time.fixedDeltaTime * TimeScale; | |
} | |
private void Update() | |
{ | |
DeltaTime = Time.deltaTime * TimeScale; | |
} | |
public void AddOrSetEffector(object key, float value) | |
{ | |
_effectors[key] = value; | |
_isChanged = true; | |
} | |
public void RemoveEffector(object key) | |
{ | |
_effectors.Remove(key); | |
_isChanged = true; | |
} | |
private void Calculate() | |
{ | |
float timeScale = 1F; | |
foreach (var effector in _effectors) | |
timeScale *= effector.Value; | |
TimeScale = timeScale; | |
} | |
public float TimeScale | |
{ | |
get | |
{ | |
if (_isChanged) | |
{ | |
Calculate(); | |
_isChanged = false; | |
} | |
return _timeScale; | |
} | |
private set | |
{ | |
_timeScale = value; | |
foreach (var comp in _components) | |
comp.AdjustTimeScale(_timeScale); | |
} | |
} | |
public float DeltaTime { get; private set; } | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment