前提・実現したいこと
現在、Unityで2Dゲームを作成しており、一定の範囲を上下左右ランダムに進行するNPCを作成したいと考えています。具体的には、上下左右いずれかに一定時間移動⇨向きを変えて一定時間移動⇨向きを変えて一定時間移動⇨……といった動作です。また、移動中にNPCが範囲を超える場合は、方向を変えて(反対方向を向いて)移動させたいです。
現在、以下の質問・回答を参考に、概ね実装することができている状況です。
https://teratail.com/questions/285084
発生している問題・エラーメッセージ
動かし続けていると以下のような挙動が発生します
①範囲の一番右側から一番左側にワープする(左から右もあり)
②範囲の一番右側に当たると、範囲の上下を高速で行き来する
該当のソースコード
C#
1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4using UnityEngine.UI; 5 6public class crowdHuman : MonoBehaviour 7{ 8 private float chargeTime;//動く時間 9 private float timeCount; 10 private float speed;//移動スピード 11 private float speed_Min;//Minスピード 12 private float speed_Max;//Maxスピード 13 Vector3 direction;//移動方向 14 Vector3 pos;//自分の位置 15 Vector2 minMoveArea = new Vector2(-8.9f, -3.9f);//移動範囲(最小) 16 Vector2 maxMoveArea = new Vector2(-5.9f, 2.9f);//移動範囲(最大) 17 18 // Start is called before the first frame update 19 void Start() 20 { 21 chargeTime = 1.0f; 22 23 //開始時の移動方向を決める 24 direction = RandomDirection(); 25 26 //移動スピードをランダムに決める 27 speed_Min = 0.005f; 28 speed_Max = 0.01f; 29 speed = Random.Range(speed_Min, speed_Max); 30 31 //自分の位置を取得 32 Transform myTransform = this.transform; 33 pos = myTransform.position; 34 } 35 36 // Update is called once per frame 37 void Update() 38 { 39 timeCount += Time.deltaTime; 40 41 //枠から出たら逆方向を向く 42 if ((pos.x < minMoveArea.x)||(pos.y < minMoveArea.y)||(pos.x > maxMoveArea.x)||(pos.y > maxMoveArea.y)) 43 { 44 Turn(); 45 //それ以外の場合は進む 46 } else 47 { 48 transform.position += direction * speed; 49 50 //指定した時間を経過すると 51 if (timeCount > chargeTime) 52 { 53 //進路をランダムに変更する 54 direction = RandomDirection(); 55 //TimeCountを0に戻す 56 timeCount = 0; 57 } 58 59 } 60 } 61 62 void Turn() 63 { 64 //タイムカウントを0に戻す。 65 timeCount = 0; 66 if (direction == Vector3.up) 67 { 68 transform.position = new Vector3(transform.position.x, maxMoveArea.y, transform.position.z); 69 direction = Vector3.down; 70 } 71 else if (direction == Vector3.down) 72 { 73 transform.position = new Vector3(transform.position.x, minMoveArea.y, transform.position.z); 74 direction = Vector3.up; 75 } 76 else if (direction == Vector3.left) 77 { 78 transform.position = new Vector3(minMoveArea.x, transform.position.y, transform.position.z); 79 direction = Vector3.right; 80 } 81 else if (direction == Vector3.right) 82 { 83 transform.position = new Vector3(maxMoveArea.x, transform.position.y, transform.position.z); 84 direction = Vector3.left; 85 } 86 } 87 88 Vector3 RandomDirection() 89 { 90 int r = Random.Range(0, 4); 91 switch (r) 92 { 93 default: 94 case 0: 95 return Vector3.up; 96 case 1: 97 return Vector3.down; 98 case 2: 99 return Vector3.left; 100 case 3: 101 return Vector3.right; 102 } 103 104 } 105} 106
追記コード
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class crowdHuman : MonoBehaviour { private float chargeTime;//動く時間 private float timeCount; private float speed;//移動スピード private float speed_Min;//Minスピード private float speed_Max;//Maxスピード Vector3 direction;//移動方向 Vector3 pos;//自分の位置 Vector3 minMoveArea = new Vector3(-8.9f, -4.9f, 0);//移動範囲(最小) Vector3 maxMoveArea = new Vector3(-4.9f, 4.9f, 0);//移動範囲(最大) Vector3 WorldPoint; public Sprite[] HumanSprites; Sprite HumanSprite; // Start is called before the first frame update void Start() { chargeTime = 0.9f; //開始時の移動方向を決める direction = RandomDirection(); //移動スピードをランダムに決める speed_Min = 0.01f; speed_Max = 0.02f; speed = Random.Range(speed_Min, speed_Max); //自分の位置を取得 Transform myTransform = this.transform; pos = myTransform.position; HumanSprites = Resources.LoadAll<Sprite>("image"); int i = Random.Range(0, 3); HumanSprite = HumanSprites[i]; this.GetComponent<Image>().sprite = HumanSprite; } // Update is called once per frame void Update() { timeCount += Time.deltaTime; WorldPoint = transform.TransformPoint(pos); //枠から出たら逆方向を向く //if ((pos.x < minMoveArea.x)||(pos.y < minMoveArea.y)||(pos.x > maxMoveArea.x)||(pos.y > maxMoveArea.y)) if ((WorldPoint.x < minMoveArea.x) || (WorldPoint.y < minMoveArea.y) || (WorldPoint.x > maxMoveArea.x) || (WorldPoint.y > maxMoveArea.y)) { Turn(); //それ以外の場合は進む } else { transform.position += direction * speed; //指定した時間を経過すると if (timeCount > chargeTime) { //進路をランダムに変更する direction = RandomDirection(); //TimeCountを0に戻す timeCount = 0; } } } void Turn() { //タイムカウントを0に戻す。 timeCount = 0; if (WorldPoint.y > maxMoveArea.y) { transform.position = new Vector3(transform.position.x, maxMoveArea.y-0.2f, transform.position.z); direction = Vector3.down; } else if (WorldPoint.y < minMoveArea.y) { transform.position = new Vector3(transform.position.x, minMoveArea.y+0.2f, transform.position.z); direction = Vector3.up; } else if (WorldPoint.x < minMoveArea.x) { transform.position = new Vector3(minMoveArea.x+0.2f, transform.position.y, transform.position.z); direction = Vector3.right; } else if (WorldPoint.x > maxMoveArea.x) { transform.position = new Vector3(maxMoveArea.x, transform.position.y, transform.position.z); direction = Vector3.left; } } Vector3 RandomDirection() { int r = Random.Range(0, 4); switch (r) { default: case 0: return Vector3.up; case 1: return Vector3.down; case 2: return Vector3.left; case 3: return Vector3.right; } } }
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/06/27 01:33
退会済みユーザー
2021/06/27 01:35