
今日はマナトークンを作ろうと思います。
マナトークンって何??って思う方もいらっしゃるかもしれないので、一応説明しておきます。
ある種のカードゲームではカードを使うときにコストとしてマナを支払う必要があるのです。
そのマナを可視化したものがマナトークンです。
今日はそのマナトークンを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);
}
}
}
ちょっとわかりにくいですが、お皿からマナトークンを取り出すと、ライブラリ(山札)の上にトークンが発生したのが確認できます。

おわりに

今日はマナトークンの作成とインタラクションを付けました。
これからの展開としては、トークンを資源としてカードを使用するという事になります。
それから、発生したトークンがドローの際に相手のマナトークンとして取得されるというのも実装したいと思います。
かなり複雑なので大変になりそうですが、頑張っていきたいと思います。
それでは、また!











