Ejemplo n.º 1
0
        //=================================================================================
        //反映
        //=================================================================================

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