本日のおすすめです。
実は世界一おいしいおみそしるの作り方を伝授!
表情差分
Webへのアップロードのやり方
いままでのレシピを組み合わせるだけでできます。
記念すべき定食の完成の瞬間!!
だしまきたまごの前編にある、
いつものじゃないスクリプトを使うやつ。
『作成』→『Scripting』→『ScriptableObject』
using System.Collections.Generic; //C#で型を決めたリストを作る
using UnityEngine; //標準C#を使うよ
[CreateAssetMenu(fileName = "New Data", menuName = "StoryData")] //新しいクラスを作れるようにするよ、それの名前はこれだよ
public class StoryData : ScriptableObject //StoryDataのクラスがScriptableObjectを継承するよ
{
[System.Serializable] //クラスの前につけるとそのクラスを編集できるようになるよ
public class Story //Storyの名前がついたクラスを編集できるようにしたよ
{
public Sprite Background; //背景の画像
public Sprite CharacterImage; //キャラの立ち絵
[TextArea] //↓ここからテキスト
public string StoryText; //ストーリーのテキスト
public string CharacterName; //キャラの名前
}
public List<Story> stories = new List<Story>(); //作成したリスト【Story】に【stories】を【new】として新しいリストを作れるよ
}これで作れるようになる
『作成』→『StoryData』

このときに一緒にここにいれるための画像をCanvasとして作っておく
『UI(Canvas)』から『画像』→背景と立ち絵、テキストウィンドウ入れよう
画面が合わないならこれ見て、多分できるはず

空のゲームオブジェクトに
ふたつめのスクリプト(ふつうのやつ)『StoryManager』をいれる
using System.Collections; //C#で型を決めたリストを作る
using System.Collections.Generic; //同じ処理を使い回せるようにするよ
using TMPro; //いいテキストを使うよ
using UnityEngine; //標準のC#を使うよ
using UnityEngine.UI; //標準で基本のC#を使うよ
public class StoryManager : MonoBehaviour //StoryManagerの初期スクリプトを使うよ
{
[SerializeField] private StoryData[] storyDatas; //ストーリーデータのスクリプト
[SerializeField] private Image background; //背景
[SerializeField] private Image characterImage; //キャラの立ち絵
[SerializeField] private TextMeshProUGUI storyText; //ストーリーのテキスト
[SerializeField] private TextMeshProUGUI characterName; //キャラの名前
[Header("===== テキスト演出設定 =====")]
[SerializeField, Range(0.01f, 0.2f)] //0.01fから0.2fの間で設定できるよ
private float typingSpeed = 0.05f; //0.05fで設定してるよ
[Header("===== 効果音設定 =====")]
[SerializeField] private AudioClip typingSE; //タイピング音
[SerializeField] private AudioClip nextSE; //次に進むときの音
[SerializeField, Range(0f, 1f)] //0fから1fの間で設定できるよ
private float seVolume = 0.7f; //0.7fで設定してるよ
public int storyIndex { get; private set; } = 0; //storyIndexを誰でも設定変更できるよ
public int textIndex { get; private set; } = 0; //textIndexを誰でも設定変更できるよ
private bool isTyping = false; //タイピング進行中か判定してくれる
private string currentFullText = ""; //いま表示しようとしている全文を一時的に保存してくれる
private Coroutine typingCoroutine = null; //いま表示しようとしているところのタイピング音の一時停止
private AudioSource audioSource; //効果音を再生するのに必要
private bool storyEnded = false; //ストーリーが終わったか確認してくれる 終わったら終わるための処理に入る
private void Start() //すたーと!
{
audioSource = GetComponent<AudioSource>(); //同じゲームオブジェクトに音があるか確認してくれる
if (audioSource == null) //音がなかったら自動的に音をつけてくれる
{
audioSource = gameObject.AddComponent<AudioSource>(); //音を追加してほしいよ~
audioSource.playOnAwake = false; //音が鳴らないようにしてくれる
}
if (storyDatas == null || storyDatas.Length == 0)
{ //ストーリーデータがないときに挙動がおかしくならないようにしてくれる
Debug.LogError("storyDatasが空!");
return;
} //ストーリーデータがないときにインスペクターで設定してねって教えてくれる
SetStoryElement(storyIndex, textIndex); //どこの処理をしているか教えてくれる
}
private void Update() //更新!
{
if (Input.GetMouseButtonDown(0) || Input.GetKeyDown(KeyCode.Space))
{ //左クリックかスペースキーを押されたときを検知してくれる
if (storyEnded) //このストーリーが終わったかどうかのチェックと分岐
{
Debug.Log("ストーリーは既に終了しています。"); //その時に終わっていることを教えてくれる
return;
}
if (isTyping) //タイピング中のとき
{
if (typingCoroutine != null) StopCoroutine(typingCoroutine); //タイピングを終わらせる
storyText.maxVisibleCharacters = currentFullText.Length; //全文表示
isTyping = false; //タイピングの終わりを更新してくれる
PlayNextSE(); //スキップしたよの効果音
}
else //まだ途中だよ
{
Next(); //つぎ!
}
}
}
public void Next() //つぎを始める!
{
if (storyEnded || storyIndex >= storyDatas.Length) // 全部見たか判定してくれる
{
Debug.Log("ストーリーは既に終了しています。"); //終わったか教えてくれる
return;
}
PlayNextSE(); //つぎへの効果音を鳴らすよ
textIndex++; //つぎのテキストを表示するよ
if (textIndex >= storyDatas[storyIndex].stories.Count) //全部見たか判定してくれる
{
textIndex = 0; //いまのテキスト表示が終わったよ
storyIndex++; //いまのストーリーが終わったからつぎに進む準備をするよ
if (storyIndex >= storyDatas.Length) //全部見たか教えてくれる
{
storyEnded = true; //ストーリーが終わったことを確認したら終わる準備に入る
Debug.Log("全てのストーリーが終了しました。"); //終わったら教えてくれる
return;
}
}
SetStoryElement(storyIndex, textIndex);
} //指定した位置を画面に全部反映してくれる、やっと動ける
private void SetStoryElement(int _storyIndex, int _textIndex)
{ //セリフ変わったりキャラが変わるよ
var currentStoryData = storyDatas[_storyIndex]; //いま処理しているところを編集できるようにしてくれる
var storyElement = currentStoryData.stories[_textIndex]; //いま表示するべきものを取り出して表示するとこに入れてるよ
background.sprite = storyElement.Background;
characterImage.sprite = storyElement.CharacterImage;
characterName.text = storyElement.CharacterName; //いま表示するべきものを反映してくれる
currentFullText = storyElement.StoryText; //いま表示する全文を保存してくれてる
if (typingCoroutine != null) StopCoroutine(typingCoroutine); //タイピングを終わらせてくれる
storyText.text = currentFullText; //ストーリーテキストを全文セットしてくれる
storyText.maxVisibleCharacters = 0; //何文字まで表示するかを非表示
isTyping = true; //いまタイピング中だよ
typingCoroutine = StartCoroutine(TypeText()); //一文字ずつ表示して音をだすループに入る
}
private IEnumerator TypeText() //タイピングテキストをできるように待機中
{
int total = currentFullText.Length; //全文の文字数を取得するよ
isTyping = true; //いまタイピング中を確認
for (int i = 0; i <= total; i++) //全表示終わりをループ
{
storyText.maxVisibleCharacters = i; //何文字まで出すかを指定できる
if (i < total && !char.IsWhiteSpace(currentFullText[i]) && typingSE != null)
{ //文字と効果音を設定している場合だけ
audioSource.PlayOneShot(typingSE, seVolume);
} //タイピング音を鳴らしてくれる 文字や効果音がないときは鳴らさない
yield return new WaitForSeconds(typingSpeed); //つぎの文字まで待機するよ
}
isTyping = false; //タイピング終わり
typingCoroutine = null; //再開をさせないで終了判定してくれる
}
private void PlayNextSE() //つぎへの効果音
{
if (nextSE != null) //つぎのテキストにいくとき一度だけ
audioSource.PlayOneShot(nextSE, seVolume); //つぎへ進む効果音の音量調整
}
}
ここで設定されている
背景 立ち絵 セリフ 名前 は【場所】を決めるため
増やした『要素』ひとつひとつに同じ『NewData』を入れていく
『NewData』に
別の立ち絵を入れたら表情差分になる。
別のテキストを入力したら次のテキストに進むことができる。
『Typing Speed』でテキスト表示のスピードを変えられる。
マイナスにするとゆっくりになってくれる。

ここの設定が両方になってないと動かないかも。
両方なら動くはず。
動かなかったらその都度修正しに来てください
ここ詳しく載せておきたいもあれば更新しに来て
ここからアップする方法!
続きは後編で



