前提・実現したいこと
タイトル通りです。検知したオブジェクトが現在生きているか死んでいるかを判定できるようにしたい。
判定される側にdeathFlagの変数を追加してプレイヤーが死んだかどうか判定できる材料を用意しました。判定する側はStartメソッド内でそれを取得しているのですが、この方法だとゲーム開始時にしか取得しないためずっとdeathFlagが0のままです。
Updateメソッド内で取得すれば実現できるのは分かっていますが、GetComponentをUpdateメソッド内に書きたくないので他の方法を教えてほしいです。
該当のソースコード
#####エージェントのソースコード(判定する側)
C#
1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4using UnityEngine.AI; 5public class Agent : MonoBehaviour 6{ 7 public Transform marisa;//魔理沙 8 public GameObject reimu;//霊夢 9 private GameObject target;//ターゲット 10 private GameObject[] towers1;//最初に取得するタワー 11 private GameObject[] towers2;//2回目以降に取得するタワー 12 13 private int Mode;//エージェントのモード 14 private int defaultTowerNum;//最初に取得するタワーの数 15 private int towerNum;//2回目以降に取得するタワーの数 16 private int targetNum = 0;//ターゲットナンバー 17 private int reimuDeathFlag;//霊夢の死亡フラグ 18 19 private float attackInterval = 1.0f;//攻撃の間隔 20 private float lastAttackTime;//最後に攻撃した時間 21 private float distance1;//魔理沙とターゲットの距離 22 private float distance2;//魔理沙と霊夢の距離 23 24 private NavMeshAgent agent;//エージェント 25 private MarisaAttack attack;//攻撃スクリプト 26 private MarisaSkillPoint skill;//スキルスクリプト 27 28 List<Action> disabledActions = new List<Action>(); 29 30 // Start is called before the first frame update 31 void Start() 32 { 33 //いろいろ取得 34 agent = GetComponent<NavMeshAgent>(); 35 attack = GetComponentInChildren<MarisaAttack>(); 36 skill = GetComponent<MarisaSkillPoint>(); 37 reimuDeathFlag = reimu.GetComponent<ReimuHealthScript>().deathFlag; 38 TowerSearch1(); 39 } 40 41 // Update is called once per frame 42 void Update() 43 { 44 //タワーの数の変動を検知 45 if (!disabledActions.Contains(Action.Search)) 46 { 47 DisableAction(Action.Search, 10.0f); 48 TowerSearch2(); 49 } 50 51 if (target) 52 { 53 //タワーが存在する場合、タワーの距離を算出 54 distance1 = Vector3.Distance(marisa.position, target.transform.position); 55 } 56 else if (targetNum < towers1.Length - 1) 57 { 58 //タワーが存在せず、次のターゲットがある場合、次のターゲットを探す 59 targetNum++; 60 target = towers1[targetNum]; 61 } 62 else 63 { 64 //タワーが存在しない場合、霊夢をターゲットにする 65 target = reimu; 66 } 67 68 //魔理沙と霊夢の距離 69 distance2 = Vector3.Distance(marisa.position, reimu.transform.position); 70 71 if (10 < distance1 && targetNum < 5)//ターゲットとの距離が10より大きく、かつターゲットナンバーが5未満の時 72 { 73 Mode = 0; 74 } 75 76 if ((5 < distance2 || reimuDeathFlag == 1) && distance1 <= 10)//霊夢との距離が5より大きいか霊夢が死んでいる、かつターゲットとの距離が10以下の時 77 { 78 Mode = 1; 79 } 80 81 if (distance2 <= 5 && reimuDeathFlag == 0)//霊夢との距離が5以下、かつ霊夢が生きている時 82 { 83 Mode = 2; 84 } 85 86 Debug.Log(Mode); 87 Debug.Log(reimuDeathFlag); 88 89 switch (Mode) 90 { 91 92 case 0: 93 94 //ターゲットに向かう 95 agent.destination = target.transform.position; 96 break; 97 98 case 1: 99 100 //ターゲットの方を向く 101 Quaternion targetRotation = Quaternion.LookRotation(target.transform.position - transform.position); 102 transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, Time.deltaTime * 1f); 103 104 //ターゲットに向かう 105 agent.destination = target.transform.position; 106 107 //ターゲットとの距離が2以下、且つ最後に攻撃した時間から1秒以上経っている時 108 if (distance1 <= 2 && Time.time > lastAttackTime + attackInterval) 109 { 110 if (skill.skillPoint >= 50) 111 { 112 attack.Attack2();//スキル攻撃 113 } 114 else 115 { 116 attack.Attack1();//通常攻撃 117 } 118 lastAttackTime = Time.time;//最後に攻撃した時間を更新 119 } 120 break; 121 122 case 2: 123 //霊夢の方を向く 124 Quaternion reimuRotation = Quaternion.LookRotation(reimu.transform.position - transform.position); 125 transform.rotation = Quaternion.Slerp(transform.rotation, reimuRotation, Time.deltaTime * 1f); 126 127 //霊夢に向かう 128 agent.destination = reimu.transform.position; 129 130 //霊夢との距離が2以下、且つ最後に攻撃した時間から1秒以上経っている時 131 if (distance2 <= 2 && Time.time > lastAttackTime + attackInterval) 132 { 133 if (skill.skillPoint >= 50) 134 { 135 attack.Attack2();//スキル攻撃 136 } 137 else 138 { 139 attack.Attack1();//通常攻撃 140 } 141 lastAttackTime = Time.time;//最後に攻撃した時間を更新 142 } 143 break; 144 } 145 } 146 147 //タワーを検知してターゲットに設定 148 public void TowerSearch1() 149 { 150 towers1 = GameObject.FindGameObjectsWithTag("ReimuTower"); 151 defaultTowerNum = towers1.Length; 152 Shuffle(); 153 target = towers1[targetNum]; 154 } 155 156 //タワーの数の変動を検知 157 public void TowerSearch2() 158 { 159 towers2 = GameObject.FindGameObjectsWithTag("ReimuTower"); 160 towerNum = towers2.Length; 161 162 if (!(defaultTowerNum == towerNum)) 163 { 164 TowerSearch1(); 165 } 166 } 167 168 //タワーの配列をシャッフル 169 public void Shuffle() 170 { 171 for (int i = 0; i < towers1.Length; i++) 172 { 173 GameObject tmp = towers1[i]; 174 int randomIndex = Random.Range(i, towers1.Length); 175 towers1[i] = towers1[randomIndex]; 176 towers1[randomIndex] = tmp; 177 } 178 } 179 180 //行動不能用コルーチン 181 IEnumerator DisableAction(Action action, float duration) 182 { 183 disabledActions.Add(action); 184 yield return new WaitForSeconds(duration); 185 disabledActions.Remove(action); 186 } 187 188 //アクション 189 public enum Action 190 { 191 Search 192 } 193} 194
#####プレイヤーのソースコード(判定される側)
C#
1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4using UnityEngine.UI; 5 6public class ReimuHealthScript : MonoBehaviour 7{ 8 [SerializeField] private float maxHealth = 1000.0f;//最大HP 9 public float health;//今のHP 10 private float respawnTime;//リスポーンをした時間 11 public int deathFlag = 0;//死亡フラグ 12 13 public Slider slider;//HPバー 14 15 private Vector3 respawnPosition;//リスポーン位置 16 private ReimuController controller;//コントローラー 17 private AttackScript attack;//攻撃スクリプト 18 private Animator anim;//アニメーター 19 private ReimuSkillPoint skillPoint;//スキルスクリプト 20 21 private void Awake() 22 { 23 //リスポーン位置を設定 24 respawnPosition = transform.root.gameObject.transform.position; 25 } 26 27 // Start is called before the first frame update 28 void Start() 29 { 30 //HPバーの初期化 31 slider.value = 1; 32 33 //HPの初期化 34 health = maxHealth; 35 36 //色々取得 37 controller = GetComponent<ReimuController>(); 38 attack = GetComponentInChildren<AttackScript>(); 39 anim = GetComponentInChildren<Animator>(); 40 skillPoint = GetComponent<ReimuSkillPoint>(); 41 } 42 43 // Update is called once per frame 44 void Update() 45 { 46 //HPバーに数値を割当 47 slider.value = (float)health / (float)maxHealth; 48 49 //死んだときの処理 50 if (health <= 0) 51 { 52 deathFlag = 1; 53 controller.enabled = false; 54 attack.enabled = false; 55 anim.SetBool("death", true); 56 if (Time.time > respawnTime) 57 { 58 StartCoroutine("Respawn"); 59 respawnTime = Time.time + 5.5f; 60 } 61 } 62 } 63 64 //水没時の処理 65 void OnTriggerStay(Collider other) 66 { 67 if (other.CompareTag("Water") && health > 0) 68 { 69 health -= 5; 70 } 71 } 72 73 //リスポーン処理 74 IEnumerator Respawn() 75 { 76 yield return new WaitForSeconds(5.0f); 77 transform.root.gameObject.transform.position = respawnPosition; 78 health = maxHealth; 79 deathFlag = 0; 80 controller.enabled = true; 81 attack.enabled = true; 82 anim.SetBool("death", false); 83 skillPoint.skillPoint -= 25; 84 } 85} 86
補足情報(FW/ツールのバージョンなど)
Unity Version 2019.4.1f1 Personal
Mac macOS Catalina ver.10.15.5
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/07/18 08:11
2020/07/18 08:16
2020/07/18 08:19
2020/07/18 08:36