using System.Collections; using System.Collections.Generic; using UnityEngine; public class CPU : MonoBehaviour { FlagManager flag; GameManager game_manager; Team team; //ターゲット情報を取得 Target target; public float angle = 0; //プレイヤーの行動タイプ //0=オフェンス(ドリブル)タイプ //1=ディフェンス(パス)タイプ private int type = 0; //シュートをする範囲内に入っているか確認するフラグ private bool shootf; //パスをする範囲内に入ったか確認するフラグ private bool passf; //防衛すべきポジションについたか private bool defensef; //極力使わない //マークしている選手の座標を保存する private float before_angle; //フリーになってパスをもらえるポジションについた場合 private bool passpositionf = false; //CPUの現在の行動を記録(publicで固定) public int status = 3; //ボールを持っている選手情報を保存用 private GameObject have_ball_player; //この選手がどちらのゴールを狙うか値を保存 private int cpu_target_goal; //味方時の行動の乱数保存用 private int random_move; //汎用待機しているフラグ&フレーム private float waitflame = 100.0f; private bool waitflag = false; //フレームカウント用 public float flame = 0; //行動後遅延する秒数 private float actionf; //フレームを加算する判定 private bool addflame; //強制的に一定の方向に移動する用のフレーム private int movef = 0; //迂回するフレーム保存 private int detourf = 0; Player cpuplayer; //プレイヤーがこのキャラクターを操作できるかどうか(publicで固定) public bool playerControl; // 起動時に実行 void Start() { flag = GameObject.Find("Manager").GetComponent(); //ターゲットスクリプトを取得 target = GetComponent(); //ゲームマネージャーを取得 game_manager = GameObject.Find("Manager").GetComponent(); //チーム team = GetComponent(); //角度を求める cpuplayer = GetComponent(); //どっちのゴールを狙うか取得 cpu_target_goal = cpuplayer.targetGoalNum; //計算用に0だった場合-1に返還 if (cpu_target_goal == 0) cpu_target_goal = -1; Player player = GameObject.Find("Player").GetComponent(); angle = Mathf.Atan2((player.transform.position.x - transform.position.x), (player.transform.position.z - transform.position.z)) * Mathf.Rad2Deg; playerControl = false; } // 毎フレームごとに実行 void Update() { //ゲームプレイの許可が出ていない間は動作しない if (!game_manager.IsGamePlayOK()) return; //プレイヤーが操作できないとき if (!playerControl) { //試合中の時 if (!flag.timeOver) { // if (!flag.fieldGoal && (status == 19 || status == 20 || status == 0)) { status = 3; } //初期化 //随時追加 if (status != 4) { waitflag = false; waitflame = 100.0f; } //遅延させるかどうか判定 if (addflame) { //遅延中 //遅延発生させるならフレームをカウントする flame += Time.deltaTime; cpuplayer = GetComponent(); cpuplayer.Standby(); } else { //行動可能状態 switch (status) { case 0: mothon0(); break; //何も行動しない case 1: mothon1(); break; //ボールを持った選手へ近づく case 2: mothon2(); break; //ボールを持ったチームのボールを持っていない選手へ近づく case 3: mothon3(); break; //誰も所持していないボールを取りに行く case 4: mothon4(); break; //ドリブル、オフェンス型の攻め case 5: mothon5(); break; //パス、ディフェンス型の攻め case 6: mothon6(); break; //味方がボールを持った時、オフェンス型の行動 case 7: mothon7(); break; case 8: mothon8(); break; //ディフェンス時、ターゲットにした選手がゴール近くに移動したとき(ディフェンス、オフェンスタイプ共通) //---------------------------------------------------------------------------------------------------------------------- case 17: mothon17(); break; case 18: mothon18(); break; case 19: mothon19(); break; case 20: mothon20(); break; case 21: mothon21(); break; //---------------------------------------------------------------------------------------------------------------------- } } } if (flame >= actionf) { //遅延フレーム分行動を止めたら行動を可能にする addflame = false; flame = 0; } } } //相手がシュートしてゴールに入ってボールを持ってしまった場合、相手選手にパスをする //(mothon16を作って移動しておいてください) void mothon0() { cpuplayer.Standby(); if (cpuplayer.have_ball == true) { //味方へのパスになっているので敵のパスを作らなきゃ cpuplayer.Pass(); } } //守備は3on3を想定した簡易的なプログラムにする //(想定:相手チームがボールを持っていて尚且つボールを持った選手が近くにいるとき、ボールを持った選手へ近づく) void mothon1() { cpuplayer = GetComponent(); //守備の移動速度を遅くする cpuplayer.rewriteSpeed(0.25f); //ボールを持った選手をターゲットに指定する Vector3 mypos = transform.position; Vector3 targetpos = target.target_player.transform.position; //ターゲットの向いている向きを取得する float targetangle = target.target_player.transform.localEulerAngles.y; //ゴール前の行動 if (cpu_target_goal == 1) { if (transform.position.z <= 45.0f) { //対象の進行を妨害するように立ち回る angle = Mathf.Atan2((targetpos.x) - mypos.x, ((targetpos.z + 7) - mypos.z)) * Mathf.Rad2Deg; } else { status = 8; } } else { if (transform.position.z >= -45.0f) { //対象の進行を妨害するように立ち回る angle = Mathf.Atan2(targetpos.x - mypos.x, ((targetpos.z - 7) - mypos.z)) * Mathf.Rad2Deg; } else { status = 8; } } //目的の距離近くになるまで移動の処理をする if (Mathf.Abs((targetpos.x) - mypos.x) > 0.5f || Mathf.Abs((targetpos.z + 7 * cpu_target_goal) - mypos.z) > 0.5f) { //ターゲットが自ら近づいた場合は移動しない if (mypos.x - targetpos.x < 7.0f && mypos.x - targetpos.x > 1.5f && defensef && targetangle > 45 && targetangle < 135) { cpuplayer.Standby(); } else { if (defensef) { //遅延を発生させる actionf = 0.5f; addflame = true; } else { move(angle, 1.0f); } defensef = false; } } else { if (!defensef) { cpuplayer.rewriteSpeed(0.0f); move(Mathf.Atan2(targetpos.x - mypos.x, targetpos.z - mypos.z) * Mathf.Rad2Deg, 1.0f); //仮で遅延を発生させる actionf = 0.3f; addflame = true; } defensef = true; cpuplayer.Standby(); } //ターゲットにしている選手がボールを手から放した場合 if (target.target_player.GetComponent().have_ball == false) { status = 3; } //ボールを手に入れたら変更 if (cpuplayer.have_ball == true) { status = 4 + type; addflame = true; } } //(想定:相手チームがボールを持っていて尚且つボールを持った選手が遠くにいるとき、ボールを持っていない相手選手に近づき妨害する) void mothon2() { //ターゲットとボールを持っている選手の間に立つ cpuplayer = GetComponent(); //守備の移動速度を早くする cpuplayer.rewriteSpeed(0.25f); Vector3 mypos = transform.position; Vector3 targetpos = target.target_player.transform.position; //ターゲットの狙うゴールの座標を取得 //フラグマネージャーからボールを持っている選手を取得 have_ball_player = game_manager.ballChara; //ターゲットにしている選手がボールを手から放した場合 if ((have_ball_player == null) || (have_ball_player.GetComponent().teamNum == team.teamNum)) { actionf = 0.5f; addflame = true; status = 3; return; } Vector3 have_ball_potion = have_ball_player.transform.position; //ボールを持っている選手の座標を取得 //ターゲットの向いている向きを取得する float targetangle = Mathf.Atan2(have_ball_potion.x - targetpos.x, have_ball_potion.z - targetpos.z) * Mathf.Rad2Deg; //角度をもとに移動すべき座標を計算 float z = 8.0f * Mathf.Cos(targetangle * Mathf.Deg2Rad); float x = 8.0f * Mathf.Sin(targetangle * Mathf.Deg2Rad); //対象の進行を妨害するように立ち回る angle = Mathf.Atan2((targetpos.x + x) - mypos.x, ((targetpos.z + z) - mypos.z)) * Mathf.Rad2Deg; //目的の距離近くになるまで移動の処理をする if (Mathf.Abs((targetpos.x + x) - mypos.x) > 0.5f || Mathf.Abs((targetpos.z + z) - mypos.z) > 0.5f) { move(angle, 1.0f); defensef = true; } else { transform.LookAt(have_ball_potion); //マークしている選手より近づいた選手がいた場合その選手にマークを変更してしまう //隙を作るための調整 if (mypos.z > 20) { target.search_target(); if (have_ball_player == target.target_player) { status = 1; } } if (defensef == true) { //移動する方向が前回と違う()なら1.5秒遅延を発生させる if (angle != before_angle) { actionf = 1.5f; addflame = true; before_angle = angle; return; } } } before_angle = angle; //ボールを手に入れたら変更 if (cpuplayer.have_ball == true) { status = 4 + type; addflame = true; } } //(想定:パス中などで誰もボールを所持していないとき、ボールを近づく) void mothon3() { cpuplayer = GetComponent(); actionf = 0.5f; have_ball_player = game_manager.ballChara; //ボールを持っている時の移動速度を遅くする cpuplayer.rewriteSpeed(0.29f); //どっちのゴールを狙うか取得 cpu_target_goal = cpuplayer.targetGoalNum; //ボールを手に入れたら変更 if (have_ball_player != null) { //マーク選手をリセット target.reset_target(); //攻撃 if (cpuplayer.have_ball == true) { status = 4 + type; addflame = true; return; } //仲間がボールを持った場合 else if (have_ball_player.GetComponent().teamNum == cpu_target_goal) { status = 6; actionf = 0.2f; addflame = true; return; } //守備 else if (target.target_player.GetComponent().have_ball == true) { status = 1; addflame = true; return; } else { status = 2; addflame = true; return; } } Vector3 mypos = transform.position; Vector3 targetpos = GameObject.Find("ball").transform.position; //ボールのある方向へ向かう angle = Mathf.Atan2((targetpos.x - mypos.x), (targetpos.z - mypos.z)) * Mathf.Rad2Deg; if (Mathf.Abs(targetpos.x - mypos.x) > 0.3f || Mathf.Abs(targetpos.z - mypos.z) > 0.3f) { move(angle, 1.0f); } else { if (target.transform.position.y > 10.0f) { cpuplayer.Standby(); actionf = 2; addflame = true; } } } //以下攻撃用、2種用意 //ダッシュ型オフェンス寄り、仲間がボールを持った場合は積極的に前へ //自分がボールを持った場合はなるべく自分で攻める void mothon4() { cpuplayer = GetComponent(); Vector3 mypos = transform.position; //レイ計算用の二つの変数 Vector3 temp = game_manager.playerChara.transform.position - transform.position; Vector3 normal = temp.normalized; //目の前にいるオブジェクトを取得 RaycastHit hit; //ボールを持っている時の移動速度を遅くする cpuplayer.rewriteSpeed(0.3f); if (cpuplayer.targetGoalNum == -1) cpuplayer.targetGoalNum = 0; angle = 180.0f; //目的の距離になっているか判定 if (cpuplayer.targetGoalNum == 1) { if (mypos.z > -45.0f || mypos.z < -55) shootf = false; else shootf = true; if (mypos.z < -55) angle -= 180; } else { if (mypos.z < 45.0f || mypos.z > 55) shootf = false; else shootf = true; if (mypos.z > 55) angle -= 180; } if (cpuplayer.have_ball == false) { status = 3; actionf = 0.8f; addflame = true; } //ドリブル中に進行方向にプレイヤーが立ちふさがった場合 //その場で一時停止し味方に合図を出しパスをする if (Physics.Raycast(transform.position, normal, out hit, 5.0f, 1 << 13 | 1 << 15)) { //Debug.Log(hit.transform.gameObject); //レイを使って当たったプレイヤーがコントロールしていた場合のみ処理を行う if (hit.transform.gameObject.GetComponent().playerControl == true) { //待機フラグを正の値にするにする //五秒間待機する //何も起きなければ自分で行く if (waitflag == false) { transform.LookAt(new Vector3(hit.transform.position.x, hit.transform.position.y, -hit.transform.position.z)); waitflame = 0.0f; waitflag = true; } } } //待機する場合 if (waitflame < 5) { cpuplayer.Standby(); //最低でも一秒以上はその場で待機する。 if (waitflame > 1) { for (int i = 0; game_manager.teamList[team.teamNum].member[i] != null; i++) { //メンバーNoが自分と同じオブジェクトの場合無視をする if (game_manager.teamList[team.teamNum].member[i] != this.gameObject) { temp = game_manager.teamList[team.teamNum].member[i].transform.position - transform.position; normal = temp.normalized; //レイを飛ばしチームの人にあたった場合パスを行う if (Physics.Raycast(transform.position, normal, out hit, 20.0f)) { if (hit.transform.gameObject == game_manager.teamList[team.teamNum].member[i]) { cpuplayer.Pass(); status = 6; actionf = 0.8f; addflame = true; waitflame = 0.0f; } } } } } waitflame += Time.deltaTime; } else { //シュート撃つポジションについたらシュートを行う if (shootf) { //近づいたらシュートを行う cpuplayer.Shoot(); status = 3; actionf = 3.5f; addflame = true; waitflame = 0; } else { //シュートを打つ範囲外なら移動 if (mypos.x > 18) move(180 + cpu_target_goal * 45, 1.0f); else if (mypos.x < -18) move(180f - cpu_target_goal * 45, 1.0f); else { move(angle * -cpu_target_goal, 1.0f); } } } } //パス型ディフェンス寄り、なるべく前には攻めずパスを優先して進む void mothon5() { cpuplayer = GetComponent(); Vector3 mypos = transform.position; //ボールを持っていない一番前に出ている選手をターゲットに指定 Vector3 targetpos = target.target_player.transform.position; if (cpuplayer.targetGoalNum == -1) cpuplayer.targetGoalNum = 0; angle = 90.0f; //目的の距離近くになるまで移動の処理をする if (cpuplayer.targetGoalNum == 1) { if (mypos.z > -15.0f || mypos.z < -30) passf = false; else passf = true; if (mypos.z < -30) angle *= -1; } else { if (mypos.z < 15.0f || mypos.z > 30) passf = false; else passf = true; if (mypos.z > 30) angle *= -1; } if (target && passf) { cpuplayer.Standby(); RaycastHit hit; // ターゲットオブジェクトとの差分を求め Vector3 temp = targetpos - mypos; // 正規化して方向ベクトルを求める Vector3 normal = temp.normalized; //ターゲットと線で結び、その間に何もなければパスをする if (Physics.Raycast(mypos, normal, out hit, 25.0f)) { if (hit.transform.gameObject == target) { //TargetObjectを見つけた transform.LookAt(targetpos); cpuplayer.Pass(); status = 1 + type; actionf = 1.2f; addflame = true; } } } else { //パスをする範囲外なら移動 if (mypos.x > 18) move(180 + cpu_target_goal * 45, 1.0f); else if (mypos.x < -18) move(0.0f - cpu_target_goal * 45, 1.0f); else { move(angle * -cpu_target_goal, 1.0f); } } } //味方がボールを持った時 //シュート型の行動 void mothon6() { cpuplayer = GetComponent(); //ターゲットにする選手は味方 have_ball_player = game_manager.ballChara; if (have_ball_player == null) status = 3; else if (cpuplayer.have_ball == true) { status = 4; waitflame = 1; } else if (have_ball_player.GetComponent().teamNum != GetComponent().teamNum) status = 3; if (status != 6) { passpositionf = false; return; } //操作するプレイヤー選手をターゲットに指定する Vector3 mypos = transform.position; Vector3 targetpos = have_ball_player.transform.position; //ターゲットとの距離を求める float distance = (mypos - targetpos).magnitude; //ターゲットの向いている向きを取得する float targetangle = have_ball_player.transform.localEulerAngles.y; //ポジションの情報を数値で保存する //0 = 画面左 //1 = 画面右 int position = 0; //この選手がどちらのゴールを狙うか値を保存 int cpu_target_goal = cpuplayer.targetGoalNum; //計算用に0だった場合-1に返還 if (cpu_target_goal == 0) cpu_target_goal = -1; //ゴール前待機位置の座標を計算 float z = 53.0f * cpu_target_goal * -1 - mypos.z; float x; //3on3を想定 if (team.memberNum == 0 || (have_ball_player.GetComponent().memberNum < team.memberNum && team.memberNum != 2)) { x = 17.5f - mypos.x; position = 1; } else x = -17.5f - mypos.x; if (!passpositionf) { if (movef == 0) { //対象の進行を妨害するように立ち回る angle = Mathf.Atan2(x, z) * Mathf.Rad2Deg; //目的の距離近くになるまで移動の処理をする if (Mathf.Abs(x) > 0.5f || Mathf.Abs(z) > 0.5f) { move(angle, 1.0f); passf = false; } else { transform.LookAt(targetpos); //仮で遅延を発生させる actionf = 0.3f; addflame = true; if (!target.search_mark()) { passf = true; } } } else { passf = false; move(random_move, 1.0f); movef--; if (movef == 0) { //移動が終わったらその場で少し停止 //プレイヤーのほうへ向く transform.LookAt(targetpos); actionf = 0.6f; addflame = true; passf = true; } } } if (passf) { cpuplayer.Standby(); RaycastHit hit; // ターゲットオブジェクトとの差分を求め Vector3 temp = targetpos - mypos; // 正規化して方向ベクトルを求める Vector3 normal = temp.normalized; //ターゲットと線で結び、その間に何もなければパスをする if (Physics.Raycast(mypos, normal, out hit, 50.0f)) { if (hit.transform.gameObject == have_ball_player) { //プレイヤーのほうへ向く transform.LookAt(targetpos); passpositionf = true; if (target.search_mark()) { passf = false; passpositionf = false; } } else { //違うものが間にあった場合は上下に移動する movef = 60; if (cpu_target_goal == -1) { if (position == 0) random_move = Random.Range(180, 270); else random_move = Random.Range(90, 180); } else { if (position == 0) random_move = Random.Range(360, 450); else random_move = Random.Range(270, 360); if (random_move > 360) random_move -= 360; } passpositionf = false; } } if (mypos.x > 31.0f) { movef = 30; random_move = 270; passpositionf = false; } if (mypos.x < -31.0f) { movef = 30; random_move = 90; passpositionf = false; } } } //パス型の行動 void mothon7() { cpuplayer = GetComponent(); //ターゲットにする選手は味方 have_ball_player = game_manager.ballChara; if (have_ball_player == null) { status = 3; return; } //操作するプレイヤー選手をターゲットに指定する Vector3 mypos = transform.position; Vector3 targetpos = have_ball_player.transform.position; //ターゲットとの距離を求める float distance = (mypos - targetpos).magnitude; //ターゲットの向いている向きを取得する float targetangle = have_ball_player.transform.localEulerAngles.y; //対象物の向いている方向の座標の計算をする float z = -15.0f * Mathf.Cos(targetangle * Mathf.Deg2Rad); float x = -15.0f * Mathf.Sin(targetangle * Mathf.Deg2Rad); if ((targetangle > 30 && targetangle < 150 && cpu_target_goal == -1) || (targetangle > 210 && targetangle < 330 && cpu_target_goal == 1)) { //対象の進行を妨害するように立ち回る angle = Mathf.Atan2((targetpos.x + x) - mypos.x, ((targetpos.z + z) - mypos.z)) * Mathf.Rad2Deg; //目的の距離近くになるまで移動の処理をする if (Mathf.Abs((targetpos.x + x) - mypos.x) > 0.5f || Mathf.Abs((targetpos.z + z) - mypos.z) > 0.5f) { move(angle, 1.0f); passf = false; } else { passf = true; //仮で遅延を発生させる actionf = 0.3f; addflame = true; } } else { //対象の進行を妨害するように立ち回る angle = Mathf.Atan2((targetpos.x + 20 * cpu_target_goal) - mypos.x, ((targetpos.z) - mypos.z)) * Mathf.Rad2Deg; //目的の距離近くになるまで移動の処理をする if (Mathf.Abs((targetpos.x + 20 * -cpu_target_goal) - mypos.x) > 0.5f || Mathf.Abs(targetpos.z - mypos.z) > 0.5f) { move(angle, 1.0f); passf = false; } else { passf = true; //仮で遅延を発生させる actionf = 0.3f; addflame = true; } } } void mothon8() { cpuplayer = GetComponent(); //守備時の移動速度は上げる cpuplayer.rewriteSpeed(0.25f); //ボールを持った選手をターゲットに指定する //フラグ管理を呼び出す Vector3 mypos = transform.position; Vector3 targetpos = target.target_player.transform.position; //ターゲットの狙うゴールの座標を取得 Vector3 target_goal_potion = target.target_player.GetComponent().goalpost[target.target_player.GetComponent().targetGoalNum].transform.FindChild("GoalTargetPoint").gameObject.transform.position; //ターゲットとターゲットの狙うゴールの角度を計算 float target_goal_angle = Mathf.Atan2(target_goal_potion.x - targetpos.x, target_goal_potion.z - targetpos.z) * Mathf.Rad2Deg; //角度をもとに移動すべき座標を計算 float z = 5.5f * Mathf.Cos(target_goal_angle * Mathf.Deg2Rad); float x = 5.5f * Mathf.Sin(target_goal_angle * Mathf.Deg2Rad); //対象の進行を妨害するように立ち回る angle = Mathf.Atan2((targetpos.x + x) - mypos.x, (targetpos.z + z) - mypos.z) * Mathf.Rad2Deg; //ターゲットとの距離を求める float distance = (mypos - targetpos).magnitude; //目的の距離近くになるまで移動の処理をする if (Mathf.Abs((targetpos.x + x) - mypos.x) > 0.5f || Mathf.Abs((targetpos.z + z) - mypos.z) > 0.5f) { //ターゲットが自ら近づいた場合は移動しない if (distance < 6.0 && defensef) { cpuplayer.Standby(); } else { defensef = false; move(angle, 1.0f); } } else { if (!defensef) { cpuplayer.rewriteSpeed(0.0f); move(Mathf.Atan2(targetpos.x - mypos.x, targetpos.z - mypos.z) * Mathf.Rad2Deg, 1.0f); //仮で遅延を発生させる actionf = 0.3f; addflame = true; } defensef = true; cpuplayer.Standby(); } //ターゲットにしている選手がボールを手から放した場合 if (target.target_player.GetComponent().have_ball == false) { actionf = 0.2f; addflame = true; status = 3; } //ボールを手に入れたら変更 if (cpuplayer.have_ball == true) { status = 4 + type; addflame = true; } //一定ラインより下がったら元に戻す if (cpu_target_goal == 1) { if (mypos.x < 30) status = 1 + type; } else { if (mypos.x > -30) status = 1 + type; } } /// 6/20 まだ未完成 /// //フィールドゴールが決めた後、ゴールポストの守りに入る void mothon17() { } //フィールドゴールを決められた後、攻めに前に出る void mothon18() { } //スローインを受け取れるところに行く void mothon19() { Vector3 mypos = transform.position; //自分の座標 //ボールのある方向へ向かう angle = Mathf.Atan2((game_manager.throwinChara.transform.position.x - mypos.x), (game_manager.throwinChara.transform.position.z - mypos.z)) * Mathf.Rad2Deg; if (Mathf.Abs(game_manager.throwinChara.transform.position.x - mypos.x) >= 30f || Mathf.Abs(game_manager.throwinChara.transform.position.z - mypos.z) >= 30f) { move(angle, 1f); } } //ボールを取りに行き、スローインするところに行く void mothon20() { Vector3 mypos = transform.position; //自分の座標 //ボールを取れていない if (!cpuplayer.have_ball) { Vector3 targetpos = GameObject.Find("ball").transform.position; //ボールのある方向へ向かう angle = Mathf.Atan2((targetpos.x - mypos.x), (targetpos.z - mypos.z)) * Mathf.Rad2Deg; if (Mathf.Abs(targetpos.x - mypos.x) > 0.3f || Mathf.Abs(targetpos.z - mypos.z) > 0.3f) { move(angle, 1.0f); } } //ボールが取れた else { Vector3 throwpos = Vector3.zero; //原点で初期化 //チームによってスローインの座標が決まる if (GetComponent().teamNum == 0) { throwpos = new Vector3(-10f, 0.3f, -63f); } else if (GetComponent().teamNum == 1) { throwpos = new Vector3(10f, 0.3f, 63f); } //スローインの座標が決まったら if (throwpos != Vector3.zero) { //スローインの所への角度を取得 angle = Mathf.Atan2((throwpos.x - mypos.x), (throwpos.z - mypos.z)) * Mathf.Rad2Deg; //スローインの所についてないとき if (Mathf.Abs(throwpos.x - mypos.x) > 0.3f || Mathf.Abs(throwpos.z - mypos.z) > 0.3f) { //angleからキャラクターの向きを変更 transform.rotation = Quaternion.Euler(0, angle, 0); //キャラクターが向いている方向に移動 transform.Translate(Vector3.forward * 0.3f * 1.0f); } //近くなったら else if (transform.position != throwpos) { //スローインの場所に立たせる transform.position = throwpos; //スローインの構えアニメーションさせる cpuplayer.Standby(); //コートの方を向く transform.LookAt(new Vector3(0f, transform.position.y, transform.position.z)); } //スローインの場所についた時 else { //プレイヤーのチームの場合、操作できる状態にする if (team.teamNum == game_manager.P1TeamNum /*&& !playerControl*/) { game_manager.ControlCharaChenge(gameObject); cpuplayer.throwOK = true; } //敵チームの場合 else { status = 21; cpuplayer.throwOK = true; game_manager.CatchChara(team.teamNum); //cpuplayer.Pass(); } } } } } //スローインで近くの味方にパスする void mothon21() { Vector3 mypos = transform.position; //自分の座標 //味方が近くに来たら if (Mathf.Abs(cpuplayer.serchChara().transform.position.x - mypos.x) < 30f && Mathf.Abs(cpuplayer.serchChara().transform.position.z - mypos.z) < 30f) { cpuplayer.Pass(); } //cpuplayer.Pass(); //コートに入らせる if (!flag.fieldGoal) { status = 3; } } //移動するプログラム、衝突を避けるため補正をかける void move(float angle, float j_distance) { //目の前にいるオブジェクトを取得 RaycastHit hit; //移動するか判断するフラグ bool movef = true; //ターゲットと線で結び、その間に何もなければパスをする if (detourf > 0) { angle -= 50; detourf--; } else if (Physics.Raycast(transform.position, transform.forward, out hit, 3.0f)) { detourf = 30; if (hit.transform.gameObject == have_ball_player) movef = false; else movef = true; } if (movef) cpuplayer.CPUMove(angle, j_distance); } }