この関数では、0とリストの最大サイズの間のランダムなインデックスを取得したかったのです。戻り値の異なるコルーチンの使用
ランダムなインデックスを使用して、のノードをランダムに選ぶことができます。
私は、if文を通過し、私が選んだそのランダムノードを使用していない他オブジェクトかどうかを確認します。
他オブジェクトは、ランダムノードを使用していない場合は、私は、このメソッドを呼び出したオブジェクトはそれを使用することができますノードことを返します。そのノードは現在、別のオブジェクトで使用されている場合
しかし、その後、私はそれはそれは使用することができますノードを取得するまで、再び機能を通過するwan'tので、私は関数自体を返します。
無限に呼び出される(ゲームはまだ機能している)ので、結果はオーバーフローエラーです。私の最初の考えは遅れ(コルーチン)を使うことだったので、関数はあまり頻繁に呼び出されません。問題は、返品タイプDodgeNodeが必要なことです。
public class DodgeLocations : MonoBehaviour {
public List<DodgeNode> nodes;
private DodgeNode randomNode;
private int randomIndex;
public DodgeNode SelectRandomNode(){
randomIndex = Random.Range(0, nodes.Count);
randomNode = nodes[randomIndex];
// If the random node is not currently taken (which means if an enemy isn't currently attacking it)
if (!randomNode.IsTaken()) {
// Then the random node is now taken; and other enemies can't touch that node, until the current enemy finishes attacking it
randomNode.IsTaken (true);
return randomNode;
} else {
return SelectRandomNode(); // If the node is taken, ask again if there's another node that's free to attack
}
}
}
私はコルーチンを使用して、私はこのことについて考えた場合、それがどのように見えるだろうかブレインストーミング。もちろん
public class DodgeLocations : MonoBehaviour {
public List<DodgeNode> nodes;
private DodgeNode randomNode;
private int randomIndex;
IEnumerator SelectRandomNode(){
yield return new WaitForSeconds(2f);
randomIndex = Random.Range(0, nodes.Count);
randomNode = nodes[randomIndex];
// If the random node is not currently taken (which means if an enemy isn't currently attacking it)...
if (!randomNode.IsTaken()) {
// Then the random node is now taken; and other enemies can't touch that node, until the current enemy finishes attacking it
randomNode.IsTaken (true);
yield return randomNode;
} else {
yield return SelectRandomNode(); // If the node is taken, ask again if there's another node that's free to attack
}
}
}
私はのIEnumeratorの戻り値の型を持つ関数を持つタイプDodgeNodeの何かを返すことができないので、これは間違っています。しかし、私はまだWaitForSecondsを使用したいので、IEnumerator戻り値の型が必要です。
ここでの問題は、私はDodgeNodeを返すようにしたいということですが、同じで、私はWaitForSeconds動作するのための戻り値の型のIEnumeratorをする機能を必要としています。Serliteに対応して
、私はこの機能を使用していところですが(無関係な多くのコードを削除):私の "ソリューション" を発見
public class Bat : Enemy {
private DodgeNode nodeToTarget; // Node that bat want's to attack
private Vector3 startPoint; // Bat's original position
private Vector3 endPoint; // Bat's end position
void Start(){
startCoroutine(AttackPlayerNode());
}
IEnumerator AttackPlayerNode(){
while (true) {
nodeToTarget = dodgeLocations.SelectRandomNode();
endPoint = nodeToTarget.transform.position;
yield return new WaitForSeconds (2f);
yield return StartCoroutine(MoveToPoint(startPoint, endPoint));
nodeToTarget.IsFree(); // This makes the Node free for other object to use it
}
}
}
免責事項:私は初心者プログラマー/学生です
私は紙を手に入れて、思考のプロセスをすべて書き出しようとしたが、代わりの "解決策"で終わった。むしろSelectRandomNode()にWaitForSecondsを呼び出そうとしようとするよりも、私はすべてのノードが占有された場合SelectRandomNode()リターンヌルを作ることにしました。 のIEnumerator AttackPlayerNode()では、私はこのコードを持っている:
// If the bat doesn't have a node to target
while(nodeToTarget == null){
yield return new WaitForSeconds(0.5f);
nodeToTarget = dodgeLocations.SelectRandomNode();
}
私はヌルを返していますので、このwhileループはが開いているノードまで続けるだろう。これはまだオーバーフローエラー(私は思うはずです)を生成しますが、今はWaitForSecondsを使用しています。これはオープンノードのチェック頻度を減らし、オーバーフローエラーを防止します。
これはおそらく非常に醜い/一時的な解決策ですが、私はいつでも将来最適化のために戻ることができます!これは1日中私を忘れさせていました。私は今、ゲームの他の要素に集中することができてうれしいです。あなたはおそらくすでに疑わたよう
public class DodgeLocations : MonoBehaviour {
public List<DodgeNode> nodes;
private DodgeNode randomNode;
// Returns a randomly chosen node
public DodgeNode SelectRandomNode(){
int randomIndex = Random.Range(0, nodes.Count);
randomNode = nodes[randomIndex];
if (!randomNode.isTaken) {
randomNode.IsTaken (true);
return randomNode;
} else {
return null; // <--- What was changed
}
}
}
public class Bat : Enemy {
private DodgeNode nodeToTarget; // Node that bat want's to attack
private Vector3 startPoint; // Bat's original position
private Vector3 endPoint; // Bat's end position
void Start(){
startCoroutine(AttackPlayerNode());
}
IEnumerator AttackPlayerNode(){
while (true) {
// If the bat doesn't have a node to target
while(nodeToTarget == null){
yield return new WaitForSeconds(0.5f); // Prevent overflow error
nodeToTarget = dodgeLocations.SelectRandomNode1();
}
endPoint = nodeToTarget.transform.position;
yield return new WaitForSeconds (2f);
yield return StartCoroutine(MoveToPoint(startPoint, endPoint));
nodeToTarget.IsFree(); // This makes the Node free for other object to use it
nodeToTarget = null;
}
}
私の "ソリューション" を発見されましたか? – Serlite
上記のDodgeNodeを使用している箇所を追加しました。私は何も残していないことを願っています(無関係のコードをたくさん削除して、クラスタ化されていないようにしなければなりませんでした)。 – Junycode