//================================================================================= //反映 //================================================================================= /// <summary> /// 前後の情報から現在の状態を計算し、調整する /// </summary> public static void AdjustTransform(SpriteRenderer spriteRenderer, DynamicAfterImageEffect2DInfo beforeInfo, DynamicAfterImageEffect2DInfo aftereInfo, bool ignoreTimeScale) { //現在の時を取得し、前後の情報の時間との差を計算 float currentTime = ignoreTimeScale ? Time.unscaledTime : Time.time; float befonInfoTimeDiff = currentTime - beforeInfo.GenerationTime, afterInfoTimeDiff = currentTime - aftereInfo.GenerationTime; float totalTimeDiff = befonInfoTimeDiff + afterInfoTimeDiff; //前後の情報とも今と同じ時間なら表示しない if (totalTimeDiff <= 0) { spriteRenderer.enabled = false; return; } //前後の情報が今の時間とどれだけ近いのかを割合で計算 float beforeInfoRate = befonInfoTimeDiff / totalTimeDiff, afterInfoRate = afterInfoTimeDiff / totalTimeDiff; //前後近い方の画像を表示する if (beforeInfoRate > afterInfoRate) { beforeInfo.ApplySprite(spriteRenderer); } else { aftereInfo.ApplySprite(spriteRenderer); } //前後の情報とその割合から現在の状態を調整する spriteRenderer.transform.position = beforeInfo.Position * beforeInfoRate + aftereInfo.Position * afterInfoRate; spriteRenderer.transform.localScale = beforeInfo.LocalScale * beforeInfoRate + aftereInfo.LocalScale * afterInfoRate; spriteRenderer.transform.rotation = Quaternion.Euler(beforeInfo.Rotation * beforeInfoRate + aftereInfo.Rotation * afterInfoRate); }
/// <summary> /// 残像を生成するための情報を初期化する /// </summary> public void InitInfo(DynamicAfterImageEffect2DInfo initialInfo) { _infoList.Clear(); _infoList.Add(initialInfo); initialInfo.ApplySprite(_spriteRenderer); initialInfo.ApplyTransform(transform); }
//================================================================================= //状態切り替え //================================================================================= //無効状態から有効になった protected override void OnActive() { DynamicAfterImageEffect2DInfo info = new DynamicAfterImageEffect2DInfo(_targetSpriteRenderer, _ignoreTimeScale); foreach (DynamicAfterImageEffect2D afterImage in _afterImageList) { afterImage.InitInfo(info); } }
//================================================================================= //更新 //================================================================================= //状態を更新 protected override void UpdateState() { //現在レンダラーの状態から残像の情報を作成 DynamicAfterImageEffect2DInfo info = new DynamicAfterImageEffect2DInfo(_targetSpriteRenderer, _ignoreTimeScale); //各残像に情報を設定し、状態を更新 for (int i = 0; i < _afterImageList.Count; i++) { _afterImageList[i].AddInfoAndUpdateState(info); } }
/// <summary> /// DynamicAfterImageEffect2DInfoを追加し、状態を更新する /// </summary> public void AddInfoAndUpdateState(DynamicAfterImageEffect2DInfo info) { if (info != null) { _infoList.Add(info); } //レイヤー更新(後のやつほど後ろに行くように) if (_originalSpriteRenderer != null) { _spriteRenderer.sortingOrder = _originalSpriteRenderer.sortingOrder - Mathf.RoundToInt(1 + _interval * 100); } //現在の位置に該当する情報の時間を計算、その時間より1つ後の情報番号取得 float targetTime = (_ignoreTimeScale ? Time.unscaledTime : Time.time) - _interval; int afterInfoNo = 0; for (int i = 0; i < _infoList.Count; i++) { afterInfoNo = i; if (_infoList[i].GenerationTime >= targetTime) { break; } } //前後の情報から位置などを調整 int beforeInfoNo = Mathf.Max(afterInfoNo - 1, 0); DynamicAfterImageEffect2DInfo.AdjustTransform(_spriteRenderer, _infoList[beforeInfoNo], _infoList[afterInfoNo], _ignoreTimeScale); //本体と位置が近い場合は表示しないように if (_originalSpriteRenderer != null && Vector3.Distance(transform.position, _originalSpriteRenderer.transform.position) < _distanceRange) { _spriteRenderer.enabled = false; } else if (!_spriteRenderer.enabled) { _spriteRenderer.enabled = true; } //不要な情報を破棄 for (int i = 0; i < beforeInfoNo; i++) { _infoList.RemoveAt(0); } //情報が設定されず、残りの情報もなくなったら残像を無効にする if (info == null && _infoList.Count <= 2) { gameObject.SetActive(false); } }