yumeの日記: Unity制作 メデューサ・ゲーム #21
●多態性
コメントいただいた件。
プログラムが複雑になるにつれ「同じクラスに微妙に違うことさせるの面倒だな」と思ってたら、まさにこのことだった。ありがとうございます。
ufcpp曰く、
・あるメソッドを呼び出すとき、同じ呼び出し方で、異なるオブジェクトの異なる動作をさせることができる。
たとえば二つのスライム「レッドスライム」と「ブルースライム」がいて、それぞれに微妙に異なる「ぶよぶよメソッド」を実行させたいとすると:
・スライムベースクラスをまず作る。これを基底クラスと呼ぶ。
・レッドスライムとブルースライムというクラスを作り、これにスライムベースを「継承」させる。
・スライムベースクラスには、「バーチャル」ぶよぶよメソッドを作っておく。
・レッド・ブルーのクラス内に「オーバーライド」ぶよぶよメソッドを書く。
・呼び出し側は「スライムベースクラスのぶよぶよメソッド」を呼ぶ。呼び出されたスライムがレッドかブルーなら、それぞれのオーバーライドしたぶよぶよメソッドが実行される。
class スライムベース
{
public virtual void ぶよぶよ()
{
//ぶよぶよする
}
}
public class レッドスライム : スライムベース //スライムベースを継承
{
public override void ぶよぶよ()
{
//ぶよぶよした後赤い粘液を落とす
}
}
main()
{
いまいるスライム.ぶよぶよ(); //いまいるスライムのぶよぶよメソッドが実行される(レッドなら赤い粘液も落とすとか)
}
メデューサ・ゲームの場合、「見られているとき実行されるメソッド」「見られてないとき実行されるメソッド」がそれぞれオブジェクトの種類ごとに異なりうるので、
オブジェクトごとにサブクラスコンポーネントを作っておき、それぞれに当てはめておく。
//基底クラス側
public virtual void HitEvilSeeing()
{
//邪眼の視界内に入ったとき
evilDamage += Time.deltaTime;
if (evilDamage > resistPower)
{
Mineralized();
}
evilSeeing = false;
}
//シャイ兵士側
public override void HitEvilSeeing()
{
//シャイモードスタート
if (!isPrevShy)
{
mySprite.sprite = shy;
myPath.canMove = false;
myCapture.canCapture = false;
isPrevShy = true;
}
evilSeeing = false;
}
//サングラス兵士側
public override void HitEvilSeeing()
{
//邪眼の影響を受けない。なにもしない
}
普通の兵士と太った兵士の場合はそのまんま基底クラスの動作でよいので、そのまま基底クラスをコンポーネントとしてはめた。
猫の場合は石化したとき(Mineralizedメソッド)だけが違うので、そこだけオーバライドしたサブクラスをコンポーネントとしてはめた。
継承についてもう少し勉強すべきかもしれない。
ともあれ、これで「ほとんど同じだけど一部ちょっと違う動作」などがわかりやすく実装できるようになったと思う。
--
●天板呼び出し微修正
コメントいただいた「spline.Clear()」メソッドに修正。
配列要素の削除の順序、まったくその通りでした。ありがとうございます。
--
●視界の歪みバグ修正
天板がステージ最下部からつながっているように見せるために床をステージ最下部より下にめり込ませた結果、視界に少しスキマができてしまった。
これは床のポリゴンを直接編集し、ステージ最下部と床の交差点に頂点を増やすことでクリア(交差点にも視界のRaycastが飛んで、視界メッシュを正しい形に直している)
キャラクターの動作は確認できた。
地形の描画具合も一通りテストしたいが、もう遅いので続きは明日。
Unity制作 メデューサ・ゲーム #21 More ログイン