さて、前回記事に引き続いて、今度は敵キャラ(NPCキャラクター)の衛兵が止まったり、周りを見渡したりする。
関連記事
では例のごとく、Unity Gemsからの翻訳をどうぞ!
November 22, 2012
巡回パターンの追加
前述の文章までにNPCキャラクターに巡回させる指令を実現してきた。さらに間で別のアクションを行うようにしれすることが出来る。AからB、BからC、と盲目的に移動させる代わりに(また繰り返しの動きかいなとユーザに思われる)、AからBへと移動し、そこで見回す動きをさせて、それから次の動きをさせることが出来る。次にDに着いたときに180度回転してまた180度戻ってさらにAに向かわせる。
NPCキャラクターの動作はあなたがどういう設計にするかに依存する。もしベンチが途中にあるならばわずかな間にNPCキャラクターに座らせてからまた動作を続けることも出来る。やりたければムーンウォークさせても良いし、これはあなたの想像次第だ(ゲーム全体の見栄えによる)。まあ、ムーンウォークはシリアスなゾンビゲームやコールオブデューティみたいなゲームでは酷いセンスになるので当然やめてもらいたい。
次に準備してもらいたいのは適切なタイミングにコールしたい関数のことだ。まずはFSMをみてみる。
前述の通り、普通の動きであり、ちょっとづつ工夫を凝らしてる感じだ。キャラクターは動くし、巡回点に到達して、どの地点にいるかによりアクションを開始させる。巡回点の2および3では何も行わない。
アクションはシンプルな回転、停止、戻る回転のアニメーションであり、代わりに好きなアニメーションを使用してもかまわないし、好きなステート(状態)を使用してもかまわない。待機のステート(状態)はアイドル状態のアニメーションで2秒間待機するIEnumerator関数となる。
次にコードを見ていく:
using UnityEngine;
using System.Collections;
[RequireComponent (typeof (CharacterController))]
public class AiScript : MonoBehaviour {
CharacterController _controller;
Transform _transform;
float speed = 5f;
float gravity = 20f;
Vector3 moveDirection;
public int index;
float maxRotSpeed = 200.0f;
float minTime = 0.1f;
float _velocity;
float range = 1f;
public Transform[] _waypoint = new Transform[4];
// 新しい変数
bool walking, waiting, rotating;
bool isWaiting, isRotating;
void Start(){
// 新しい変数をセット
walking = true; waiting = false; rotating = false;
isWaiting=false; isRotating = false;
index = 0;
_controller = GetComponent <charactercontroller>();
_transform = GetComponent <transform>();
animation["RotateWait"].wrapMode = WrapMode.Once;
}
void Update(){
if(walking){
if(!isWaiting && !isRotating)
Walk ();
}else if (rotating){
StartCoroutine(RotateWait());
rotating = false;
}else if(waiting){
StartCoroutine(Wait());
waiting = false;
}
}
void Walk(){
if((_transform.position - _waypoint[index].position).sqrMagnitude >range){
Move(_waypoint[index]);
animation.CrossFade("walk");
}else{
switch(index){
case 0:
walking =false;rotating = true;
isRotating = true;
break;
case 1 :
walking =false;waiting = true;
isWaiting = true;
break;
default:
NextIndex();break;
}
}
}
IEnumerator RotateWait(){
if(!animation.IsPlaying("RotateWait"))animation.CrossFade("RotateWait");
yield return new WaitForSeconds(animation["RotateWait"].length);
walking = true; isRotating = false;
NextIndex();
}
IEnumerator Wait(){
animation.CrossFade ("idle");
yield return new WaitForSeconds(2.0f);
walking = true;isWaiting = false;
NextIndex ();
}
//Move and NextIndex functions
}
これでいくつかのboolean変数があり、キャラクターの状態を確認出来る。歩行、待機、回転のいずれかを行っている。updateにより各々のbooleanをチェックし、適切な関数がコールされる。Walk関数によりどの巡回点に到達しているかチェックしたうえで各々のbooleanを巡回点に基づいて定義する。残りはシンプルなコードなので見るだけで分かるはずだ。
この種のゲームは良く見かけるはずで、例えば入り口の衛兵がドアの前を前後に動き回り、たまに停止して周りを見回すか、停止をトリガーにしてオリジナルのアクションを行う。
0 件のコメント:
コメントを投稿