質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Unity3D

Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

Q&A

解決済

1回答

1252閲覧

unity2D 敵のAIのぐにゃぐにゃ追従

退会済みユーザー

退会済みユーザー

総合スコア0

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Unity3D

Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

1グッド

1クリップ

投稿2021/05/10 07:32

編集2021/05/11 00:15

こんにちは。敵のAIを作っています。
そこで視覚内に入ったら敵を追従するというものを作ろうとしています。
視覚内に入る→追従はできたのですが。
ぐにゃぐにゃしながら追従というものが出来ません。

イメージ
ゴリラAIが桃にぐにゃぐにゃしながら追従
イメージ説明

RandomMove

C#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5public class RandomMove : MonoBehaviour 6{ 7 protected IEnumerator NowAct; 8 9 #region 定数 10 protected const float FIELD_OF_VIEW_MAX = 60; // 視野範囲 11 protected const float DEG_ROT_MAX = 1; // 角度の許容値 12 protected const float ROTSPEED = 0.5f; // 回転速度 13 #endregion 14 15 16 /// <summary> 17 /// 非捕捉状態のときの挙動 18 /// </summary> 19 protected IEnumerator Nolock_Action() { 20 21 var now_Z = transform.localRotation.eulerAngles.z;//現在角度.z 22 var new_Z = now_Z + Random.Range(60f, -60f);//目標角度.z 23 24 float rotspeed = 3;//回転速度 25 float f = 0; //回転進行度 26 27 while (f <= 1) { 28 29 f += Time.deltaTime * rotspeed; 30 gameObject.transform.rotation = Quaternion.Euler(0, 0, Mathf.LerpAngle(now_Z, new_Z, f)); 31 32 yield return null; 33 } 34 35 float speed;// 移動スピード 36 float speed_Max = 4f; 37 38 float time = 0;//移動時間 39 float time_Max = 3; 40 41 uint move_sens = 0x00000001; 42 43 speed = Random.Range(0, speed_Max); 44 45 while (time < time_Max) { 46 var delta = Time.deltaTime; 47 48 time += delta; 49 var puls = (speed * delta) * move_sens; 50 transform.Translate(0, puls, 0); 51 52 yield return null; 53 } 54 55 NowAct = null; 56 } 57 /// <summary> 58 /// 移動 59 /// </summary> 60 protected virtual void Follow() { } 61}

Enemy_Limp_Move

C#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5public class Enemy_Limp_Move : RandomMove 6{ 7 8 [SerializeField] Enemy_Status enemy; // ステータス 9 10 float angleValue = 0; //回転進行度 11 12 void Update() 13 { 14 var en_up = transform.up; 15 var en_to_pl = (Player.player.transform.position - transform.position); 16 17 var deg = Vector3.SignedAngle(en_up, en_to_pl, Vector3.forward); 18 19 if (Mathf.Abs(deg) <= FIELD_OF_VIEW_MAX) {// 視界内(±FIELD_OF_VIEW_MAX)か? 20 21 //視界内→追従開始 22 23 if (NowAct != null) {//NowActの中がnullでない場合、非追従処理が走っている可能性が高い。→非追従処理を止めて、破棄。 24 25 StopCoroutine(NowAct); 26 NowAct = null; 27 } 28 29 Player_Of_Rotate(deg); 30 //Player_Of_Limp_Follow(); 31 32 Follow(); 33 } 34 else { 35 36 //視界外→ランダム移動開始 37 38 if (NowAct == null) {// ランダムに回転・移動 39 40 NowAct = Nolock_Action(); 41 StartCoroutine(NowAct); 42 } 43 } 44 } 45 /// <summary> 46 /// プレイヤーの方向に回転し追従 47 /// </summary> 48 void Player_Of_Rotate(float deg) 49 { 50 51 if (Mathf.Abs(deg) >= DEG_ROT_MAX) {//角度修正 52 53 var now_Z = transform.localRotation.eulerAngles.z; //現在角度.z 54 var new_Z = now_Z + deg; //目標角度.z 55 56 if (angleValue <= 1) {// 目標角度に回転 57 58 angleValue += Time.deltaTime * ROTSPEED; 59 gameObject.transform.rotation = Quaternion.Euler(0, 0, Mathf.LerpAngle(now_Z, new_Z, angleValue)); 60 } 61 else { 62 63 angleValue = 0; 64 } 65 } 66 67 // プレイヤーの方向に前進 68 transform.position += (Player.player.transform.position - transform.position).normalized * enemy.enemy_Speed * Time.deltaTime; 69 } 70 71 72 /// <summary> 73 /// ぐにゃぐにゃ追従 74 /// </summary> 75 protected override void Follow() { 76 77 //float T = 1.0f; 78 //float f = 1.0f / T; 79 80 //var pos = transform.localPosition; 81 //pos.x = Mathf.Sin(2 * Mathf.PI * f * Time.deltaTime); 82 ////pos += (Player.player.transform.localPosition - transform.localPosition).normalized * enemy.enemy_Speed * Time.deltaTime; 83 //transform.localPosition = pos; 84 85 Vector3 pos = transform.position; 86 float sin = Mathf.Sin(Time.time)/2; 87 transform.localPosition = new Vector3(pos.x + 0, pos.y + sin, 0); 88 } 89} 90

ステータス

C#

1using System; 2using System.Collections; 3using System.Collections.Generic; 4using UnityEngine; 5 6[CreateAssetMenu(fileName = "Enemy", menuName = "ScriptableObjects/CreateAsset")] 7public class Enemy_Status : ScriptableObject 8{ 9 public float enemy_Speed = 0.1f;// スピード 10} 11

今困っている事

自身の位置で横移動しない→ローカルで動かしたい。
揺れが大きい

やったこと
向きは勝手に変わるのでsinでそうゆう風な動きが出来ないかと思いやってみました。
キャラクタの正面はY軸の方向です。何種類かAIを作るので継承を使っています

この部分でSinを使ってやろうとしました。が
揺れが大きい→割る2してみたが揺れはそのまま
ローカルで移動したい→transform.localPosition に代入しているのにできない。
回答お願いします。

C#

1 Vector3 pos = transform.position; 2 float sin = Mathf.Sin(Time.time)/2; 3 transform.localPosition = new Vector3(pos.x + 0, pos.y + sin, 0);

追記

今のままのやり方
分かりにくいですが、今の状態だと桃に近づくほど揺れが大きくなります。
イメージ説明

animationcurveのやり方
これでも中心に座標が行ってしまいます。

C#

1 2 Vector3 pos = transform.localPosition; 3 transform.position = new Vector3(curve.Evaluate(pos.x + Time.time),pos.y + 0,pos.z + 0);
退会済みユーザー👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ayousanz

2021/05/10 08:15

やりたいこと(質問のタイトル)が大きすぎるので,細かくして質問したほうがいいかと思われます. ご自身が質問の題目に対してやったことは記述されていますが,現在困っていることに対してやったことが記述されていません. 現在の問題点と困っていることが明確であれば実際にやってみればいいのでないでしょうか? ローカル(ローカルポジションという意味で捉えています)で動かしたいのであればlocalPosition等,揺れが激しいのであればSinの上の幅を制限すればいいと思います.
退会済みユーザー

退会済みユーザー

2021/05/10 08:21 編集

失礼ですが、やったことは記述していますよ。 それから、やりたいことが大きいでしょうか? 角度は勝手に回転しますし、あとはぐにゃぐにゃ移動するだけなのですが、、、 ローカルでやっているのですが、試行錯誤して出来ないから質問しています。 少々質問を見やすくしますね。
退会済みユーザー

退会済みユーザー

2021/05/10 08:25

レイアウトを変え、やった事を明確にしました。どうでしょうか?
ayousanz

2021/05/10 08:50

コードのほうを詳しく確認しておらず..修正していただきありがとうございます. ローカル移動についてですが,Vector3 pos = transform.position;(follow関数)の部分をlocalPositionはどうでしょうか? 揺れ幅についてですが,割る数字が2ではなく5や10など大きい数字にしても変化がないのでしょうか?
退会済みユーザー

退会済みユーザー

2021/05/10 11:38

コードを見るに、 transform.position = 自身; transform.localPosition = 自身; transfrom.GetComponentsInChildren<Transform>()[1].localPosition = 子のローカルポジション ってなってませんか? あと、方法は違いますがAnimationCurveとか利用するのも面白いかもしれませんね using UnityEngine; public class Move : MonoBehaviour { [SerializeField]AnimationCurve curve; private void Start() { // エディターでも設定できる curve.postWrapMode = WrapMode.PingPong; } private void Update() { transform.position = new Vector3(curve.Evaluate(Time.time), 0, 0); } }
退会済みユーザー

退会済みユーザー

2021/05/11 00:07

ayousanzさんが仰られた通り、にやってみたら振れ幅などは改善できたのですが、桃に近づくほど振れ幅が大きくなってしまいます。
退会済みユーザー

退会済みユーザー

2021/05/11 00:12

1570pさんのアニメーションカーブをやってみたのですが、中心の座標で固定されてしまい、そこで揺れてしまいます。追記をご確認ください。
退会済みユーザー

退会済みユーザー

2021/05/11 02:10

そういうコードですので当然その結果になります。 こういった方法、コードを利用する、という風には考えられませんか? 例えば、この値を揺れ幅として直進移動に与えるだけでも揺れた動きは再現できます。 で、それが望む動作となるかはまた別の問題になります
退会済みユーザー

退会済みユーザー

2021/05/11 04:54

追記からtransform.localpositionに代入してみましたが、上手く行きません。ヒントのようなものを教えてくださいませんか?
退会済みユーザー

退会済みユーザー

2021/05/11 06:14

そもそも気になる部分があるのですが、localPositionとはどのようなものだと思われていますか?
退会済みユーザー

退会済みユーザー

2021/05/11 06:16

親をワールド座標にして考えるやり方だと思っています。
退会済みユーザー

退会済みユーザー

2021/05/11 06:30

親を原点とした座標ですよね? という事は、 transform.position=変更 同じtransform.localPosition=変更 これはおかしくないですか? transformは親ですよね? 上記の場合においてtransform.localPosition、この親のlocalPositionってありますか?ワールドの原点がlocalPositionではないですか? このコード上で変更したい場合、子のtransformが必要で、そのlocalPositionを変更しないといけないのではないでしょうか?
退会済みユーザー

退会済みユーザー

2021/05/11 06:49

仰る通りです。意味無いことをしておりました。 ではどういうやり方が正しいでしょうか?ヒントをお願いします。
退会済みユーザー

退会済みユーザー

2021/05/12 06:53

using System.Collections; using System.Collections.Generic; using UnityEngine; using UniRx; using UniRx.Triggers; using System; public class Move : MonoBehaviour { [SerializeField] Transform target; [SerializeField] AnimationCurve curve; private void Update() { var forward = (target.position - transform.position).normalized; var shake = (transform.right * curve.Evaluate(Time.time)).normalized; var position = (forward + shake).normalized; transform.up = target.position - transform.position + position; transform.position += position * Time.deltaTime; } } 適当に書いてみました。このままだと動きが気持ち悪いです、、、 前進と左右のブレをAnimationCurveで与えてみた、みたいな方法です。
退会済みユーザー

退会済みユーザー

2021/05/17 02:46 編集

簡単な方法により、回の決いたしました。
guest

回答1

0

ベストアンサー

解決しましたので、簡易的に書いておきます。
方法は単純で、プレイヤーの方向に進むようにしておいてから
往復するように横移動してあげるだけで出来ました。
今回の教訓は自分の質問の仕方が悪かったのと、一つの方法でしか実装しようとしていなかったので
このように簡単な方法でやることが目につきませんでした。

C#

1 [SerializeField] int counter = 0; // 移動したフレーム数 2 [SerializeField] float moveAmount = 0.05f;// 移動量 3 4 Vector3 movePower = new Vector3(moveAmount, 0, 0);// 横移動量 5 6 transform.Translate(movePower); 7 counter++; 8 9 if (counter == AMOUNTMAX) { //counterが AMOUNTMAX 溜まればになれば逆方向に動かす 10 11 counter = 0; 12 moveAmount *= -1; 13 }

投稿2021/05/17 02:45

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問