このページでは、前回に引き続き、ゲームの監督スクリプトを記述していきます。監督スクリプトの主なお仕事は以下のような感じでしたね。
・ゲーム開始直後、数球オブジェクトを初期配置に並べる
・自分のターンにて、パワーや方向などを調節し、手球を発射
・CPUが(とあるルールにのっとり)パワーや方向などを調節し、手球を発射
・発射後、手球や数球の状況によって、次の番が自分かCPUかを決定する
前回で、一つ目の数球初期配置作業はスクリプト化完了しました。今回は二つ目の、自分のターン時の作業をスクリプト化していきましょう!自ターンの動きについては、結構話盛り沢山なので、2ページに分けて説明していきます!
今回からUpdateメソッドの中身に入っていきますが、後々のことも考えると、大まかな全体構造は↓のような感じになります。スクリプトを書いてると、どうしても細かいことに眼が行きがちですが、全体を見渡せる眼を持っておくこともめっちゃ大切です。ここでは、先に全容を把握しておきます!
int myturn = 0; //0:自分、1:相手 int waittime = 0; //0:思考時間、1:球が動いてる待ち時間 void Update () { //自分の番 if (this.myturn == 0 && this.waittime == 0){ //自分の番での操作内容→2-2、2-3で説明 } //相手の番 if (this.myturn == 1 && this.waittime == 0){ //相手の番でのCPU操作内容→2-4で説明 } //ボール動いてて待ち中… if (this.waittime == 1){ //止まるまで待ち&次はどちらの番になるかの処理→2-5、2-6で説明 }
こんな感じで、2つの変数myturnとwaittimeで今どの状況にあるかを大きく場合分けしていきます。今回はmyturn=0、waittime=0、つまり自分の番での処理を書いていきます。
ゲームが遊べるページにも書いてありますが、自ターンで調節出来ることは3種類ありましたね。1.パワー、2.方向、3.手球位置 を調節出来て、調整項目の変更は左右Shiftキー、各項目の微調整は、全て矢印キーで行い、全て調節し終わったらEnterキーで発射!という話でした。
この辺の情報をざっくりスクリプトに書いていきますと…。
int shotpower = 100; //手球発射パワー int shotangle = 0; //手球発射角度 int readyswitch = 0; //0:初期設定実施、1:初期設定しない int myturn = 0; //0:自分、1:相手、2:試合終了 int waittime = 0; //0:思考時間、1:球が動いてる待ち時間 int setting = 0; //0:shotpower設定中、1:shotangle設定中、2:手球位置設定中 int canmove = 2; //0:手球の位置移動可、1:移動不可、2:初手限定の挙動(初期値) //自分の番(Updateメソッド内) if (this.myturn == 0 && this.waittime == 0){ if (this.readyswitch == 0){ this.readyswitch = 1; //【要追加】③初期設定もろもろ } if (Input.GetKeyDown(KeyCode.LeftShift) && this.setting != 0) { this.setting --; //【要追加】②上矢印君の移動 } if (Input.GetKeyDown(KeyCode.RightShift) && this.setting != 2) { this.setting ++; //【要追加】②上矢印君の移動 } if (this.setting == 0) { //パワーを調節(0~100[%]、2%ごとに調節可) if (Input.GetKey(KeyCode.UpArrow) && this.shotpower != 100) { this.shotpower += 2; //パワーを+2% //【要追加】①左上の表示を変更 } if (Input.GetKey(KeyCode.DownArrow) && this.shotpower != 0) { this.shotpower -= 2; //パワーを-2% //【要追加】①左上の表示を変更 } } if (this.setting == 1) { //角度を調節(-178~180[度]、2度ごとに調節可) if (Input.GetKey(KeyCode.UpArrow)) { if (this.shotangle == 180){ this.shotangle = -178; } else { this.shotangle += 2; //反時計回りに2度回転 } //キューのオブジェクトを回転 this.cue.transform.Rotate(-transform.forward, 2); //【要追加】①左上の表示を変更 } if (Input.GetKey(KeyCode.DownArrow)) { if (this.shotangle == -178){ this.shotangle = 180; } else { this.shotangle -= 2; //時計回りに2度回転 } //キューのオブジェクトを回転 this.cue.transform.Rotate(-transform.forward, -2); //【要追加】①左上の表示を変更 } } if (this.setting == 2) { //手球の位置調整(canmove=1では移動不可) if (this.canmove == 0) //【要追加】⑤台上自由に移動可 if (this.canmove == 2) //【要追加】⑤台上の限られた範囲で移動可 } //調節し終わったらEnterで決定 if (Input.GetKeyDown(KeyCode.Return)) { //【要追加】④手球発射前の準備 //手球発射!…player_ballスクリプト中のメソッドを使用 this.player_ball.GetComponent<player_ball>().start_shot(this.shotpower,this.shotangle); } }
まずは↑のような大まかな流れを理解して下さい。次に細かなスクリプトを挿入していきます。コメント行の最初に【要追加】と書いてある行には、その後書いてあるような内容のスクリプトを追加する必要があります。このページでは【要追加】①~③を順に説明し、【要追加】④~⑤は次回にまわします!
あと、↑スクリプト中最後の方にある手球発射のスクリプト文については、手球スクリプト中のメソッドを使用しますので、本メソッドの詳細は制作手順3を参考にして下さい。
まず、追加が必要なスクリプトとして多いのが、左上の表示を変更という指示です。確かに、発射パワーや発射角度が変更されたら、都度左上の表示を変更する必要がありますよね。その指示は別メソッドで以下のように書けます。
void changeorder(int spower, int sangle){ //力の大きさ・向きが変更されたら左上の指示を即座に変更 this.ordertext.GetComponent<Text>().text = spower.ToString("D3") + "%の力で" + sangle.ToString("D3") + "度方向に打て!"; }
次に、制作手順1-2の時にご紹介した上矢印君の移動スクリプトを作成します。setting=0(パワー調節時)、setting=1(角度調節時)の時は固定位置に移動すれば良いですが、setting=2(手球位置調節時)では手球を指すような位置にいてほしい、つまり手球の位置によって上矢印君の位置も変えたいですよね。その辺りに気を付けて、別メソッドで以下のように書きました。
void movearrow(int setnum){ Vector3 arrowpos0 = new Vector3(7.2f, 4.0f, 3.0f); Vector3 arrowpos1 = new Vector3(4.0f, 4.0f, 3.0f); Vector3 arrowpos2p = new Vector3(0f, -0.8f, 3.0f); //this.setting=2では、上矢印君は手球の少し下に移動 Vector3 arrowpos2 = this.player_ball.transform.position + arrowpos2p; switch (setnum){ case 0: this.arrow.transform.position = arrowpos0; break; case 1: this.arrow.transform.position = arrowpos1; break; case 2: this.arrow.transform.position = arrowpos2; break; } }
ここでは、パワーとか角度とか色々設定する前に、まず以前の設定値をリセットします。あと、前回のページの補足で少しお話しましたが、Updateメソッド内で配置する(ゲーム中、定期的に何度も配置するため)オブジェクトが何個かありましたね。その辺りの処理をこの最初の段階で行っておきます。スクリプトは、別メソッドで以下のように書きました。
ちなみに、Updateメソッド内では最初に来るコイツの説明を何故最初にしないかと言うと、①、②で作成したメソッドを今から↓で使用するからです!分かりづらい説明の順番だったらすいません。m(_ _)m
//事前にStartメソッド内とかで必要なオブジェクト定義済(数が多いので省略) Vector3 nextpos = new Vector3(-6.0f, 4.8f, 0f); //Next球表示位置 Vector3 nextsize = new Vector3(1.0f, 1.0f, 1.0f); //Next球表示サイズ int minballnum; List<int> remaininglist = new List<int> {1, 2, 3, 4, 5, 6, 7, 8, 9}; //台上に残った数球の番号リスト void beforeturn(){ //初期値にリセット this.shotpower = 100; this.shotangle = 0; changeorder(this.shotpower, this.shotangle); if (this.myturn == 0){ //上矢印君追加(自ターンのみ) this.arrow = Instantiate(arrowprefab) as GameObject; this.setting = 0; movearrow(this.setting); } //赤丸強調表示君追加(最小番号数球の所に配置) this.redcircle = Instantiate(redcircleprefab) as GameObject; this.minballnum = this.remaininglist[0]; //最小番号を記憶 this.redcircle.transform.position = this.number_balls[this.minballnum - 1].transform.position; //右上のNext数球表示変更(最小番号数球オブジェクトを配置) Destroy(this.nextball); this.nextball = Instantiate(this.number_balls[this.minballnum - 1]) as GameObject; this.nextball.transform.position = this.nextpos; this.nextball.transform.rotation = Quaternion.Euler(0, -90, 0); this.nextball.transform.localScale = this.nextsize; //キュー追加 this.cue = Instantiate(cueprefab) as GameObject; this.cue.transform.position = this.player_ball.transform.position; }
よって、結果的にremaininglist[0]は残っている数球の最小番号になります。なので、上のスクリプトより、赤丸強調表示君は最小番号の数球を強調してくれますし、Next欄の数球も最小番号の数球になる、という仕組みになります。この表現はこの後も何度も登場しますので、remaininglist[0]は台上に残っている数球の最小番号というポイントだけでもおさえといて下さい。m(_ _)m
今回は、自ターンの挙動について、Updateメソッド中にスクリプトを書いていきました。長くなってしまい、すいません。m(_ _)m しかし、まだ詳細部分については全部書ききれていませんので、次回、自ターンの挙動スクリプトの残りについて、引き続きスクリプト化していきます!!