今日はマナトークンを作ろうと思います。
マナトークンって何??って思う方もいらっしゃるかもしれないので、一応説明しておきます。
ある種のカードゲームではカードを使うときにコストとしてマナを支払う必要があるのです。
そのマナを可視化したものがマナトークンです。
今日はそのマナトークンを0から作成して、皿に盛り、そこからマナトークンを取り出すと、
マナトークンが落ちてくるというのを実装しようと思います。
それでは、まずモデリングから始めたいと思います。
目次
HoudiniとUnityでマナトークンを作成する
マナトークンなので、エネルギー源というイメージでモワモワっとトークンの中でエネルギーが渦巻いている物を作成しようと思います。
まずはFBXの作成から参りましょう。
HoudiniでのトークンモデリングとUV展開
モデリングと言っても大したことはしていません、ジオメトリを作成し、ダイブして、Primitive>PlatonicSolidを選びます。
すると、色々な幾何学的形状を選べるので、Icosahedronを選ぶだけです。
そして、いつものように、UV展開をしてあげるという事になります。これについては以前の記事で述べているので、ご参考まで。
関連記事
Houdiniでのお皿モデリングとUV展開
次にお皿のモデリングです。お皿と言っても平らなプレートのようなものにしようと思いました。
まずはチューブを作り、お皿の形に引き延ばします。円周は36分割程度ならきれいに見えるかと思いました。
EndCapにチェックをいれトップとボトムのメッシュを作成します。
ただし、このままでは、キャップしたメッシュが三角形に割れていないので、作り直す必要があるのは注意です。
その前に、ポリベベルでエッジを丸めてしまいます。
この時に全てのエッジがセレクトされてしまうので、ExclusionのIgnoreFlatEdgesにチェックを入れ、角度によってエッジをセレクトしないようにします。
適当な角度で縦のエッジを省くことができました。
次に、トップとボトムのメッシュをBlastで取り除いて、Polyfillで三角メッシュを使って埋めてあげます。
これをやっておかないと、Unityでの表示がおかしくなります。FillModeはTriangleFanにします。
あとは、依然と同様にアンラップしてUVを作ってあげます。
これで、Unityに取り込む準備が出来ました!
UnityとAmplifyShaderでの動的マテリアル作成
今回の肝はこのモヤモヤエネルギーをどう表現するかでした。
参考にしたのは以下のYoutubeチャンネルです。炎のエフェクトを使用しています。
AmplifyShaderでは、Texture CoordinatesをPannerにSpeedを突っ込んでMainTexのUVに繋ぐことでメインのアルベドを動かしてあげています。
AmplifyShaderの基本的な使い方は以前述べたのでご参考まで。
関連記事
VertexTangentをつかって面によって色のバリエーションを増やしてあげています。
それから屈折(Refraction)にも値を入れていますが、これはあまり見た目に影響していない気もします。
今回やったのはそれくらいです。
このシェーダーを使ってマテリアルを作成しました。
メインのアルベドにいれているのは、石のテクスチャを改造したものです。
これが動いて、モヤモヤを作成するようになっています。
ついでにお皿にも石のマテリアルを付けてあげました。
UnityとC#とPHOTONでマナトークンを生成する
まずは先ほど作ったトークンのFBXをフォルダに格納し、ヒエラルキービューにドラッグアンドドロップして画面上に表示させます。
とりあえず7個ずつ、同様に配置したお皿の上においてみます。
そのままでは、モヤモヤが同じ方向に動いて気持ち悪いので、ローテーションをランダムで適当にいじってバラバラにしました。
このままではタダ置いてある飾りになってしまうので、インタラクションをスクリプトでつけてあげることにします。
UnityとC#とPhotonでマナトークンプレファブの作成と格納
インタラクションを付ける上で、トークンもカードと同様に動かせるようにしたいので以前にカードにつけたMouseDrag.csをアタッチします。
using System.Collections; using System.Collections.Generic; using UnityEngine; public class MouseDrag : MonoBehaviour { public AudioClip audioClip1; AudioSource audioSource; void OnMouseDrag() { //cardの位置をワールド座標からスクリーン座標に変換して、objectPointに格納 Vector3 objectPoint = Camera.main.WorldToScreenPoint(transform.position); //cardの現在位置(マウス位置)を、pointScreenに格納 Vector3 pointScreen = new Vector3(Input.mousePosition.x, Input.mousePosition.y, objectPoint.z); //cardの現在位置を、スクリーン座標からワールド座標に変換して、pointWorldに格納 Vector3 pointWorld = Camera.main.ScreenToWorldPoint(pointScreen); //pointWorld.z = transform.position.z; pointWorld.y = 4.4117f; //cardの位置を、pointWorldにする transform.position = pointWorld; } private void OnMouseDown() { audioSource = gameObject.GetComponent<AudioSource>(); audioSource.clip = audioClip1; audioSource.Play(); } private void OnMouseUp() { audioSource = gameObject.GetComponent<AudioSource>(); audioSource.clip = audioClip1; audioSource.Play(); } }
もちろん、RigidBody、BoxCollider、PhotonView、PhotonTransformViewもつけてあげます。
それからマナトークンを触った時に音を出したいので、AudioSourceもつけておきます。
MouseDragのAudioClipにオーディオソースをドラッグアンドドロップするのをお忘れなく。
この効果音は魔王魂というウェブサイトからダウンロードしました。
クレジット表記が必要ですが、センスの良い無料音源が沢山あるので重宝しています。
一通りスクリプトを付け終わったら、PhotonのResourceフォルダにヒエラルキービューからトークンをドラッグアンドドロップして、プレファブ化します。
名前はManaという名前にしておいて、後々スクリプトから呼べるようにしたいと思います。
UnityとC#とPhotonでマナトークンのOnTriggerExitでの衝突判定
お皿から、トークンを取ったら、山札の上にトークンがインスタンス化されるというのを実装したいと思います。
トークンを取り除いたら呼ばれるメソッドでOnTriggerExitというものを使おうと思います。
お皿をコピーして上図のようにSphereコライダーを付けてIsTriggerにチェックを入れておきます。
メッシュはダブってしまうので非表示にしておき、下のManaPicker.csを付けました。
これによって、トークンがSphereから出た時に、新たなトークンをライブラリの上に生み出すようになります。
using System.Collections; using System.Collections.Generic; using UnityEngine; using Photon.Pun; public class ManaPicker : MonoBehaviour { [SerializeField] Transform manaSpawnPoint; // Start is called before the first frame update private void OnTriggerExit(Collider other) { Debug.Log("collision"); if (other.gameObject.tag == "Mana") { GameObject library = (GameObject)PhotonNetwork.Instantiate("Mana", manaSpawnPoint.position, manaSpawnPoint.rotation, 0); } } }
ちょっとわかりにくいですが、お皿からマナトークンを取り出すと、ライブラリ(山札)の上にトークンが発生したのが確認できます。
おわりに
今日はマナトークンの作成とインタラクションを付けました。
これからの展開としては、トークンを資源としてカードを使用するという事になります。
それから、発生したトークンがドローの際に相手のマナトークンとして取得されるというのも実装したいと思います。
かなり複雑なので大変になりそうですが、頑張っていきたいと思います。
それでは、また!