4 / 4 斬撃の再生と終了状態
表示位置と濃度を時間へつなぎ、一度表示して消える動作を確認します。
再生用コンポーネント
前のステップのSlashを使います。ScriptsフォルダーへCrescentSlash.csを作り、次の全文を記述します。第08回と同じく、経過時間を0〜1へ変換してカーブを読みます。
MaterialPropertyBlockは、このRendererに渡す値を保持します。元のMaterialを書き換えず、同じMaterialを使う別の斬撃へ異なる値を渡せます。Shader GraphのReferenceと、コードの_Phase・_Speed・_Intensityを一致させてください。
using UnityEngine;
[RequireComponent(typeof(MeshRenderer))]
public class CrescentSlash : MonoBehaviour
{
[SerializeField, Min(0.01f)] private float lifeTime = 1f;
[SerializeField] private float speed = 1f;
[SerializeField] private AnimationCurve phaseCurve = AnimationCurve.Linear(0f, 0f, 1f, 1f);
[SerializeField] private AnimationCurve intensityCurve = AnimationCurve.Linear(0f, 1f, 1f, 0f);
private MeshRenderer meshRenderer;
private MaterialPropertyBlock properties;
private float elapsed;
private bool playing;
private void Awake()
{
meshRenderer = GetComponent<MeshRenderer>();
properties = new MaterialPropertyBlock();
}
private void OnEnable() => Play();
private void OnDisable() => Stop();
private void Update()
{
if (!playing)
return;
elapsed += Time.deltaTime;
float t = lifeTime <= 0f ? 1f : Mathf.Clamp01(elapsed / lifeTime);
Apply(phaseCurve.Evaluate(t), intensityCurve.Evaluate(t));
if (t >= 1f)
Stop();
}
[ContextMenu("Play")]
public void Play()
{
if (!Application.isPlaying || meshRenderer == null)
return;
elapsed = 0f;
playing = true;
Apply(phaseCurve.Evaluate(0f), intensityCurve.Evaluate(0f));
}
[ContextMenu("Stop")]
public void Stop()
{
playing = false;
if (meshRenderer != null)
Apply(phaseCurve.Evaluate(0f), 0f);
}
private void Apply(float phase, float intensity)
{
meshRenderer.GetPropertyBlock(properties);
properties.SetFloat("_Phase", phase);
properties.SetFloat("_Speed", speed);
properties.SetFloat("_Intensity", Mathf.Clamp01(intensity));
meshRenderer.SetPropertyBlock(properties);
}
}Consoleを確認してから、SlashへCrescent Slashを追加します。Life Time 1、Speed 1、Phase Curveの端点(0,0) → (1,1)、Intensity Curveの端点(0,1) → (1,0)を確認します。
再生・停止・再生し直し
- Playし、光が弧に沿って進んで1秒後に消えることを確認します。
- Play中にCrescent Slashコンポーネントのメニューを開き、
Playを選びます。同じ始点から再生します。 - Life Timeを
5へ変えて再びPlayを選び、途中で同じメニューのStopを選びます。途中の位置で光が残らず消えることを確認します。 - もう一度Playを選び、再生できることを確認します。コンポーネントを無効・有効にした場合も確認します。
- SceneのPlayを終了し、Life Timeを
1へ戻します。Intensity Curveの最後の値は0を維持します。
このコードは終了時にGameObjectを削除しません。非表示で残して、次のPlayで再利用します。途中停止ではカーブの途中値にかかわらずIntensityを0にします。
調整と提出
Life Timeを固定し、Phase Curveの途中に(0.2, 0.6)を追加すると、前半に大きく進む動きになります。基準の直線と比較してから復元し、採用する動きを決めます。ノイズを止めた比較が必要なら、Crescent Slash側のSpeedを0にします。再生中の値はこのコンポーネントが上書きするため、Material側のSpeedでは変更できません。
SlashをPrefabとして保存し、Sceneへ再配置してPlayします。元のSlashと二重にならないよう一方を無効にし、同じ見た目を再現できることを確認します。
- 一度再生して消え、途中停止でも描画が残らない。
- 再生し直すと同じ始点へ戻る。
- PhaseとIntensityを分けて説明し、変更前後の画像または動画と調整理由を提出できる。