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

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

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

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

Q&A

解決済

1回答

792閲覧

transform.position=vector3(ベジェ曲線)以外で動かす方法を教えてください

RyojiAraki

総合スコア79

C#

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

0グッド

0クリップ

投稿2022/02/12 08:57

編集2022/02/12 10:10

過去タイトル

Unity:ベクトルとtransformについて詳しくお聞かせください そしてワープの原因を教えてください

ベクトルについて

unity2dにてベジェ曲線を軌道とした敵キャラを生成しようとコーディングしています。今は2つのベジェ曲線を合わせたのに乗るという方針で進めています。

"transform.position=Vector3"という形で動かしています

初めに、2つ目のベクトルを無視して一つ目のところで敵キャラが動かなくなるというワープが発生しました。この時ベクトルの移動にかける時間は2つとも同じにしています。(1)
次に、2つ目のベクトルの移動時間を2倍にしました。すると、2番目のベクトルに到達した際にそのベクトルを半分飛ばしたものから始まりました。(2)

ここで私は仮説を立てました。
->unityのベクトルは位置座標及び方向を携えているものではなく、生成されてからすでに見えない何かがベクトル上を動いていてそれに乗せてもらう形になっている

それを検証するべく、3つのことをしました。
まず2番目のベクトルを先に動かして次に1番目を動かしました。(3) もしベクトル自体に不具合があるのならここで2番目のベクトル上で変な挙動をするはずですが正常で、予想通り1番目のベクトル上でスタート地点から半分進んだところワープしました(この時1番目のベクトルに移動時間を2番目のベクトルの二倍にしました)

その次に1番目のベクトル上を動かす前に、ベクトル移動時間と同じ時間分のコルーチンをかけてどう挙動するか確認しました。(4)結果、すごい勢いでワープして行って説明が困難な状況になりました。この結果は私の仮説を支えるものだと考えます。

最後にベクトル生成に必要な情報を出番が来てから同時に用意するようにしました。(5)もし私の仮説が正しければ、ベクトル上で動いてる玉は敵キャラと同時に動き始めるはずなので正常な動作を見せてくれるだろうと踏んでました。しかし、挙動は1番目の実験と同じく、2番目のベクトルをディアボロみたいにぶっ飛ばしてました...

どうすればワープなどせずにベクトル上に敵キャラを動かせてあげれるのでしょうか?できればベクトル上全て同じ秒数間で移動させたいです。私のベクトルの考え方はどのように間違っているのでしょうか?助けてください。

敵キャラのコード((5)の時点で)

unity

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5public class iq_ufo : MonoBehaviour 6{ 7 float time; 8 ScoreManager sManager; 9 Move playerScript; 10 public GameObject _geffect; 11 public GameObject _bomeffect; 12 int hp=1; 13 //float ufoSpeedToArrive=1.0f; 14 15 Vector3 _myOriginPoint; 16 Vector3 _playerOriginPoint; 17 float _firstSlope; 18 float _secondSlope; 19 Vector3 _pointOnTheWall; 20 Vector3 _firstMiddlePoint; 21 Vector3 _secondMiddlePoint; 22 Vector3 _firstLerp; 23 Vector3 _secondLerp; 24 25 public float justCheck; 26 public float justCheck2; 27 28 29 bool _findFirstTransform; 30 public bool _1stmoveStep; 31 public bool _2ndmoveStep; 32 public bool _3rdmoveStep; 33 public bool _4thmoveStep; 34 35 void Start() 36 { 37 sManager= GameObject.Find("ScoreManager").GetComponent<ScoreManager>(); 38 playerScript= GameObject.Find("Player").GetComponent<Move>();//because i couldn't get gameobject directly, i need to get its script 39 _findFirstTransform=true; 40 _1stmoveStep =false; 41 _2ndmoveStep =false; 42 _3rdmoveStep =false; 43 _4thmoveStep =false; 44 } 45 46 void Update() 47 { 48 time+=Time.deltaTime; 49 50 if(_findFirstTransform) 51 { 52 _findFirstTransform=false; 53 54 _myOriginPoint = this.gameObject.transform.position; 55 playerScript.NotifyPos(); 56 _playerOriginPoint = playerScript.myCurrentPos; 57 _firstSlope = (_playerOriginPoint.y - _myOriginPoint.y)/(_playerOriginPoint.x - _myOriginPoint.x); 58 _secondSlope = Mathf.Pow(_firstSlope,-1)*-1.0f; 59 if(_myOriginPoint.x>0){_pointOnTheWall= new Vector3(-2.7f,((-2.7f-_playerOriginPoint.x)*_secondSlope+(-3f)),0f);} 60 else if(_myOriginPoint.x<0){_pointOnTheWall= new Vector3(2.7f,((2.7f-_playerOriginPoint.x)*_secondSlope+(-3f)),0f);} 61 _firstMiddlePoint = new Vector3(_myOriginPoint.x-0.1f*(_myOriginPoint.x-_playerOriginPoint.x),_myOriginPoint.y-1.1f*(_myOriginPoint.y-_playerOriginPoint.y),0f); 62 _secondMiddlePoint = new Vector3(_playerOriginPoint.x-0.9f*(_playerOriginPoint.x-_pointOnTheWall.x),_pointOnTheWall.y+1.1f*(_playerOriginPoint.y-_pointOnTheWall.y),0f); 63 64 _1stmoveStep=true; 65 //_2ndmoveStep=true; 66 } 67 68 if(_1stmoveStep) 69 { 70 FirstMoveStep(); 71 //StartCoroutine(Test(1.0f)); 72 } 73 if(_2ndmoveStep) 74 { 75 SecondMoveStep(); 76 } 77 } 78 79 private IEnumerator Test(float waitTime) 80 { 81 yield return new WaitForSeconds(waitTime); 82 FirstMoveStep(); 83 } 84 85 private void FirstMoveStep() 86 { 87 _firstLerp = GetPoint(_myOriginPoint,_firstMiddlePoint,_playerOriginPoint,time);// 88 transform.position=_firstLerp; 89 if(transform.position==_playerOriginPoint) 90 { 91 _1stmoveStep=false; 92 _2ndmoveStep=true; 93 } 94 } 95 private void SecondMoveStep() 96 { 97 _secondLerp = GetPoint(_playerOriginPoint,_secondMiddlePoint,_pointOnTheWall,time); 98 transform.position=_secondLerp; 99 if(transform.position==_pointOnTheWall) 100 { 101 _2ndmoveStep=false; 102 _1stmoveStep=true; 103 } 104 } 105 106 private void OnTriggerEnter2D(Collider2D collision) 107 { 108 if(collision.gameObject.tag=="Player") 109 { 110 /* 111 Vector3 tmp = this.gameObject.transform.position; 112 sManager.IQufoAttack(); 113 Instantiate(_bomeffect, tmp, Quaternion.Euler(0f, 0f, 0f)); 114 Destroy(gameObject); 115 */ 116 } 117 else if(collision.gameObject.tag=="bullet") 118 { 119 if(hp==0) 120 { 121 Vector3 tmp = this.gameObject.transform.position; 122 sManager.KillIQufo(); 123 Instantiate(_geffect, tmp, Quaternion.Euler(0f, 0f, 0f)); 124 Destroy(gameObject); 125 }else 126 { 127 hp-=1; 128 } 129 } 130 else if(collision.gameObject.tag=="laser") 131 { 132 Vector3 tmp = this.gameObject.transform.position; 133 sManager.KillIQufo(); 134 Instantiate(_bomeffect, tmp, Quaternion.Euler(0f, 0f, 0f)); 135 Destroy(gameObject); 136 } 137 138 if(collision.gameObject.name=="bullets-destroyer_buttom") 139 { 140 //Destroy(gameObject); 141 } 142 143 144 } 145 146 Vector3 GetPoint(Vector3 p0, Vector3 p1, Vector3 p2, float t) 147 { 148 var a = Vector3.Lerp(p0, p1, t); // 緑色の点1 149 var b = Vector3.Lerp(p1, p2, t); // 緑色の点2 150 151 return Vector3.Lerp(a, b, t); // 青色の点1 152 } 153} 154

後日の検証

Vector3.Lerpの性質ではないかと睨んで、違う環境で直線で試してみました。
すると、できました!!何故なのでしょうか... ?もしかしたらベクトルをtransformに代入という形だと飛んでしまうのかもしれません...しかし他にどうやってベジャ曲線上をtransformさせれるのでしょうか...
とりあえずコードを貼っておきます!

unity

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5public class BezierCurve : MonoBehaviour 6{ 7 float time; 8 public Vector3 startPos; 9 public Vector3 targetPos; 10 Vector3 finalVec; 11 12 bool first=true; 13 bool second=false; 14 15 void Start() 16 { 17 transform.position = startPos; 18 } 19 20 21 void Update() 22 { 23 time += Time.deltaTime; 24 if(first) 25 { 26 var finalVec = startPos - targetPos; 27 this.transform.position -= finalVec*Time.deltaTime; 28 if(transform.position.x>>targetPos.x) 29 { 30 first=false; 31 second=true; 32 } 33 } 34 35 if(second) 36 { 37 var finalVec = targetPos- startPos; 38 this.transform.position -= finalVec*Time.deltaTime; 39 if(transform.position.x<startPos.x) 40 { 41 first=true; 42 second=false; 43 } 44 } 45 } 46}

謝罪

実は過去に同じ内容の質問を投稿してます... しかし編集したりしてもアクティブ欄に上がらなく、焦りが出てしまってしちゃいました。ごめんなさい。

追記

ベジェ曲線ベクトルを+=式で取り込めない理由を説明いたします。あくまで私の予想なのですが、べジャ曲線はベクトルではないのかもということです。

追追記

引用テキスト直線上にある2つのベクトル間を補間する関数です。

らしいです。ということは関数のように扱えばいいってことなのでしょうか...?

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

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

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

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

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

ku__ra__ge

2022/02/12 09:44

これはベジ『ェ』曲線ですね
RyojiAraki

2022/02/12 09:45

今まで間違えてました...教えてくださりありがとうございます!すぐ訂正します!
guest

回答1

0

自己解決

解決しました!!!!
この記事の冒頭の説明でvector.lerpが何か理解することができました!
結論から言うと、ベジェ曲線の進行具合を管理している変数timeは進み続けているのでベクトルを始める前にtimeを0に戻してあげたらよかっただけでした笑
お騒がせしました!

投稿2022/02/12 10:18

RyojiAraki

総合スコア79

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問