今回はユニティちゃんのRPGのタイトルシーンを作成していきたいと思います。
前回は村やワールドマップでカメラの視点を変更出来るようにしました。
ユニティちゃんのRPGを作ってみようの他の記事は
から見ることが出来ます。
前回までで最初の村のVillageシーン、ワールドマップのWorldMapシーン、戦闘のBattleシーンを作成しました。
今回はゲームのタイトルシーンを作成し、スタートボタンを押したら最初の村であるVillageシーンに遷移するような機能を作成していきます。
タイトルシーンの作成
ユニティちゃんRPGのタイトルシーンはゲームのタイトルとボタンだけ表示し、ボタンを押したらVillageシーンへと遷移させるだけでもいいんですが、タイトルシーン用にユニティちゃんを配置してみます。
ゲームタイトルはTextMeshProを使って作成します。
Assets/RPG/Scenesフォルダ内で右クリックしCreate→Sceneを選択し、名前をTitleとします。
Titleシーンをダブルクリックして開きます。
日本語のフォントをダウンロードする
タイトルシーンで使用するゲームタイトルにはTextMeshProを使用します。
日本語を使用したいので日本語のフリーフォントをダウンロードして使用させて頂きます。
以下から無料で使用できるフォントをダウンロードしてUnityに取り込みます。
わたくしは りいてがき筆フォントを使わせて頂く事にします。
ダウンロードしたら解凍し、Assets/TextMeshPro/Resources/Fonts&MaterialsフォルダにRiiT_F.otfファイルをドラッグ&ドロップします。
TextMeshPro用のフォントアセットの作成
Assets/TextMeshPro/Resources/Fonts&Materials/RiiT_F.otfを選択した状態で右クリックしてCreate→TextMeshPro→Font Assetを選択します。
するとRiiT_F SDFファイルが作成されます。
名前をTitleLogSDFに変更します。
ゲームタイトルロゴの作成
まず最初にゲームタイトルのロゴを作成します。
ゲームタイトルのロゴは以前ダメージポイントの表示の際に使ったTextMeshProを使って作成します。
ヒエラルキー上で右クリックからUI→Text – TextMeshProを選択します。
Canvasとその子要素にText(TMP)が作成されます。
CanvasのCanvas ScaleのUI Scale ModeをScale With Screen Sizeを設定し、Reference ResolutionのXを1024、Yを768とします。
Text(TMP)を選択します。
Text(TMP)のMain Settingsの設定
Text(TMP)のインスペクタで、
Anchor Presetsでtop stretchにします。
Rect TransformのHeightを300にします。
Text(TMP)のインスペクタのText Mesh Pro UGUIのMain Settingsを設定していきます。
Textにはゲームのタイトルを入力します。
今回は『ユニティちゃんの冒険』というタイトルにしました。「ユニティちゃんの」で改行を入れた後「冒険」を入力します。
Font Assetに先ほど作成したTitleLogSDFを設定します。
Font Sizeを100にします。
Alignmentは真ん中にします。
Text(TMP)のExtra Settings
Text(TMP)のインスペクタのText Mesh Pro UGUIのExtra Settingsの設定をします。
FaceのTextureにユニティちゃんのモデルに使用されている服のテクスチャを設定し、Thicknessを0.1にします。
Lightingにチェックを入れ、BevelのAmountを1にします。
出来たタイトルロゴは以下のようになります。
Text(TMP)の設定は任意なので色々試してみてください。
タイトルを少し見やすくする
タイトルロゴが背景と混じって見えづらくなるのでパネルを作成し、タイトルロゴの後ろ全体に白く薄い背景が写るようにします。
Canvasを選択した状態で右クリックからUI→Panelを選択します。
ColorのRGBを全て200にし、Aを100にします。
Panelをドラッグし、Text(TMP)の上に持っていきます。
Canvasの階層は以下のようになりました。
背景の作成
次にタイトルシーンの背景を作成します。
背景には通常のTerrainで作った地面と木を生やしてそれを映すような位置にカメラを移動させて作ります。
ヒエラルキー上で右クリックから3D Object→Terrainを選択します。
Assetsフォルダに作成されたTerrainファイルの名前をTitleSceneTerrainとし、Assets/RPG/FieldフォルダにTitleフォルダを作成しその中に移動させます。
Terrainでの地面の作成や草や木を生やすのは以前の記事でやっていますので、同じような感じでカメラに映る範囲だけを作成します。
ここまで作成して以下のような感じにカメラに映るようにMain Cameraを移動させました。
ユニティちゃんの配置と設定
背景の地面と木だけでは少し寂しいのでユニティちゃんを配置します。
カメラに近い木の近くにUnityChan/Prefabs/unitychan_dynamicをヒエラルキー上にドラッグ&ドロップします。
ユニティちゃんをカメラの方向に向かせるようにTransformのRotationのYを変更します。
ユニティちゃんのAnimatorControllerを作成する
ユニティちゃんのAnimatorに設定するAnimator Controllerを作成します。
Assets/RPG/Animators/Allyフォルダに新しくTitleUnityChanを作成します。
Pose状態を作成し、アニメーションクリップにUnityChan/AnimationsフォルダのPOSE12を設定します。
で作成したように顔用のレイヤーを作成し、unitychan_dynamicに取り付けられているIdle_Changerの横のチェックを外し無効にします。
これでアニメーターコントローラーが出来たのでヒエラルキーのunitychan_dynamicゲームオブジェクトのAnimatorにTitleUnityChanアニメーターコントローラーを設定します。
これで以下のようになりました。
大鳥ゆうじの配置と設定
次は大鳥ゆうじを配置します。
Assets/UnityChanTPK/Models/04_yuji/Prefabs/04_yujiをヒエラルキー上に配置します。
04_yujiの子要素のmodel_grp子要素のSwordを選択し、インスペクタで名前の横のチェックを外し見えないようにしておきます。
大鳥ゆうじは木に背をかけて座っているようなポーズにします。
そういったアニメーションクリップを持っている場合はユニティちゃんと同じようにアニメーターコントローラーを取り付けそのアニメーションクリップを設定するだけです。
今回は良さげなアニメーションクリップがなかったのでIKを使って大鳥ゆうじにポーズを取らせます。
ヒエラルキー上で右クリックしてCreate Emptyを5回選択し、名前をそれぞれ
YujiRightHandIK
YujiLeftHandIK
YujiRightFootIK
YujiLeftFootIK
YujiLeftElbowIKHint
とします。
大鳥ゆうじのアニメーターコントローラーの作成
次に大鳥ゆうじ用のアニメーターコントローラーを作成します。
Assets/RPG/Animators/Allyフォルダで右クリックからCreate→Animator Controllerを選択し、名前をTitleYujiとし、ヒエラルキー上に配置した04_yujiのAnimatorに設定します。
Animatorウインドウで右クリックからCreate State→Emptyを選択し、名前をPoseとしアニメーションクリップにはAssets/Standard Asset/Characters/ThirdPersonCharacter/Animation/HumanoidIdleを設定します。
HumanoidIdleのアニメーションだと下半身が微妙に動いているので、新しいレイヤーを設定し、下半身だけを別のアニメーションクリップで上書きしてなるべく動かないようにします。
AnimatorウインドウのLayerタブで+を押して新しいレイヤーを作成しLower Layerという名前にします。
次にAssets/RPG/Animators/Allyフォルダ内で右クリックからCreate→Avatar Maskを選択し、名前をLowerAvatarMaskとします。
LowerAvatarMaskのインスペクタでHumanoidの上半身部分をクリックし、下半身の緑の部分だけを適用します。
AnimatorウインドウのLower Layerの右の歯車を押してWeightを1、Avatar Maskに先ほど作成したLowerAvatarMaskを設定します。
Lower Layerを選択し、Animatorウインドウの何もない所で右クリックからCreate State→Emptyを選択し、名前をLower Poseとします。
Lower Poseには以前インポートしたC&C_Pack/Goblin_rougeのidleを設定しました。
これでBase LayerのPoseのアニメーションクリップの下半身部分だけがC&C_Pack/Goblin_rougeのidleのアニメーションになります。
Base Layerの右の歯車を押して、Ik Passにチェックを入れておきます。
IK Passにチェックを入れると左右の手と足のIKを操作する時のメソッドが呼ばれます。
これでアニメーターコントローラーの作成と設定が終わりました。
IKを操作するスクリプトの作成
アニメーターコントローラーのレイヤーのIK Passにチェックを入れたことでスクリプトでOnAnimatorIKメソッドが呼ばれるようになります。
このOnAnimatorIKメソッド内でIKのウエイトや位置と角度の設定等が行えます。
Assets/RPG/Scriptsに新しくCharacterフォルダを作り、新しくYujiIKScriptスクリプトを作成しヒエラルキー上の04_yujiに取り付けます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | using System.Collections; using System.Collections.Generic; using UnityEngine; public class YujiIKScript : MonoBehaviour { [SerializeField] private Transform rightHandIK = null; [SerializeField] private Transform leftHandIK = null; [SerializeField] private Transform leftElbowIKHint = null; [SerializeField] private Transform rightFootIK = null; [SerializeField] private Transform leftFootIK = null; private Animator animator; // Start is called before the first frame update void Start() { animator = GetComponent<Animator>(); } private void OnAnimatorIK(int layerIndex) { animator.SetIKPositionWeight(AvatarIKGoal.RightHand, 1f); animator.SetIKPositionWeight(AvatarIKGoal.LeftHand, 1f); animator.SetIKPositionWeight(AvatarIKGoal.RightFoot, 1f); animator.SetIKPositionWeight(AvatarIKGoal.LeftFoot, 1f); animator.SetIKHintPositionWeight(AvatarIKHint.LeftElbow, 1f); animator.SetIKRotationWeight(AvatarIKGoal.RightHand, 1f); animator.SetIKRotationWeight(AvatarIKGoal.LeftHand, 1f); animator.SetIKRotationWeight(AvatarIKGoal.RightFoot, 1f); animator.SetIKRotationWeight(AvatarIKGoal.LeftFoot, 1f); animator.SetIKPosition(AvatarIKGoal.RightHand, rightHandIK.position); animator.SetIKPosition(AvatarIKGoal.LeftHand, leftHandIK.position); animator.SetIKPosition(AvatarIKGoal.RightFoot, rightFootIK.position); animator.SetIKPosition(AvatarIKGoal.LeftFoot, leftFootIK.position); animator.SetIKHintPosition(AvatarIKHint.LeftElbow, leftElbowIKHint.position); animator.SetIKRotation(AvatarIKGoal.RightHand, rightHandIK.rotation); animator.SetIKRotation(AvatarIKGoal.LeftHand, leftHandIK.rotation); animator.SetIKRotation(AvatarIKGoal.RightFoot, rightFootIK.rotation); animator.SetIKRotation(AvatarIKGoal.LeftFoot, leftFootIK.rotation); } } |
ヒエラルキー上に作成したYujiRightHandIK等をインスペクタで設定出来るようにしています。
OnAnimatorIKメソッド内でIKのウエイト(1だと完全一致、0だとIKの効果なし)の設定をし、
右手のIKをどの位置や角度にするか?などを設定しています。
今回の場合はずっと同じポーズにするのでウエイトは全て1にして、各部位は先ほどヒエラルキー上に作成した空のゲームオブジェクトの位置や角度に合わせています。
左ひじはIKHintで肘の方向を位置で指定出来るだけです。
IKに関しては
等を参照してみてください。
IKはInverse Kinematicsの略で右手、左手、右足、左足の位置や角度によってそこに連結している他のボーンの位置が決定されることです。
大鳥ゆうじが座っているようにIK用のゲームオブジェクトを移動させる
大鳥ゆうじが座っているように見せる為、作成したYujiRightHandIK等のゲームオブジェクトを移動させたり回転させます。
シーンビュー上で動かしてもスクリプトでIKを設定しているので反映されません。
なのでUnityのプレイボタンを押した状態でYujiRightHandIKのゲームオブジェクト等を移動させます。
移動や回転をしたら、実行中にYujiRightHandIKのインスペクタのTransformの右の歯車を押してCopy Componentを選択します。
再生ボタンを押して停止後にYujiRightHandIKのTransformの右の歯車からPaste Component Valuesを選択します。
これを04_yuji自身の移動や回転と、IK用に作ったゲームオブジェクト5つを移動や回転させてポーズを完成させます。
わたくしの場合は以下のようなポーズにしました。
大鳥ゆうじを配置した場所が草で見えなかったり、よりかかる木が配置されていなかったら
Terrainの草や木を選択した状態でシーンビューでShiftキーを押しながらその木や草をクリックすると消すことが出来、木はBrush Sizeを1にすると1本ずつ生やせます。
ここまでのタイトルシーンは以下のようになりました。
はじめからボタンの作成
タイトルシーンのタイトルロゴと背景が出来たので後はゲーム開始ボタンを作成して最初の村であるVillageシーンを読み込むようにします。
ヒエラルキー上のCanvasを選択した状態で右クリックからUI→Button – TextMeshProを選択します。
Assets/TextMesh Pro/Resources/Fonts&Materials/TitleLogSDFを選択し、Ctrl+Dキーを押して複製し、名前をTitleButtonSDFとします。
先ほど作ったボタンの子要素のText(TMP)を選択し、Font AssetにTitleButtonSDFを設定します。
Buttonとその子要素のText(TMP)の設定はおまかせします。(´Д`)
わたくしは以下のような感じにしました。
大鳥ゆうじが地面に埋まっているのはIKが実行中しか反映されない為です。(^_^;)
LoadSceneManagerを配置とLoadSceneManagerスクリプトの追加
VillageシーンのSceneManagerゲームオブジェクトを選択した状態でCtrl+Cキーでコピーし、Titleシーンのヒエラルキー上でCtrl+Vキーで貼り付けます。
SceneManagerゲームオブジェクトに取り付けてあるLoadSceneManagerスクリプトに追加します。
1 2 3 4 5 6 7 8 | // 初めからゲームを始める public void StartGame() { isTransition = true; sceneMovementData.SetSceneType(SceneMovementData.SceneType.StartGame); StartCoroutine(FadeAndLoadScene(SceneMovementData.SceneType.StartGame)); } |
新しくStartGameメソッドを追加します。
FadeAndLoadSceneメソッドにシーンタイプがStartGameだった時の処理を追加します。
もしかしたら既に追加している可能性もあります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | // フェードをした後にシーン読み込み IEnumerator FadeAndLoadScene(SceneMovementData.SceneType scene) { if (scene != SceneMovementData.SceneType.WorldMapToBattle) { // フェードUIのインスタンス化 fadeInstance = Instantiate<GameObject>(fadePrefab); fadeImage = fadeInstance.GetComponentInChildren<Image>(); // フェードアウト処理 yield return StartCoroutine(Fade(1f)); } else { yield return StartCoroutine(FadeWorldMapToBattle(0.1f)); } // シーンの読み込み if (scene == SceneMovementData.SceneType.FirstVillage) { yield return StartCoroutine(LoadScene("Village")); } else if (scene == SceneMovementData.SceneType.FirstVillageToWorldMap) { yield return StartCoroutine(LoadScene("WorldMap")); } else if (scene == SceneMovementData.SceneType.WorldMapToBattle) { yield return StartCoroutine(LoadScene("Battle")); } else if(scene == SceneMovementData.SceneType.BattleToWorldMap) { yield return StartCoroutine(LoadScene("WorldMap")); } else if(scene == SceneMovementData.SceneType.StartGame) { yield return StartCoroutine(LoadScene("Village")); } |
今回は最初の村のシーンVillageを読み込むのでシーンタイプがFirstVillageの時と同じ処理をさせます。
本来であれば最初のシーンの前のゲーム導入部のシーン等に遷移させます。
これでスクリプトに追加が終わりました。
はじめからボタンを押した時に実行する処理を設定する
はじめからボタンを押した時にLoadSceneManagerスクリプトのStartGameメソッドを実行するようにします。
ボタンの設定なども確認してください。
ButtonのHighlighted Colorを赤色にします。
On ClickにLoadSceneManagerゲームオブジェクトのStartGameメソッドを設定します。
BGMを設定する
タイトルシーンのBGMの設定をします。
Main Cameraを選択し、Add ComponentからAudio→Audio Sourceを選択し取り付けます。
の記事でインポートしたRPG Gameの音楽フォルダであるRPG Game Music/Intro of DragonsをAudio SourceのAudioClipに設定し、PlayOnAwakeとLoopにチェックを入れます。
これでBGMの設定は終了です。
これでタイトルシーンがとりあえず出来ました。
タイトルシーンをBuild Settingsに登録する
タイトルシーンが出来ましたのでFile→Build Settings…を選択して、Titleシーンをドラッグ&ドロップして登録します。
ゲーム開始時はTitleシーンから始めたいのでTitleシーンを一番上にします。
実行して確認してみましょう。
上のようになりました。
終わりに
今回タイトルシーンを作成しましたが、常にはじめからしかゲームを開始出来ません。
次回ゲームデータのセーブとロード機能を作成した後に、タイトルシーンに『つづきから』ボタンを作成する事にします。
またUI要素を選択状態にしておく処理も次回の記事内で作成する事にします。
次回のゲームデータのセーブとロード機能を実装してこのユニティちゃんのRPGを作ってみようのコンテンツも終了です。
みなさんがんばりましょう!(^^)/
この作品はユニティちゃんライセンス条項の元に提供されています