TPSシューティング奮闘記~ダッシュ(Sprint)処理!~

今回は、至ってシンプル。

通常移動速度からの全力ダッシュ処理だ。

 

ダッシュボタン(キー)・・・左Shiftキー、左スティック押し込み

 

f:id:Free_Gamer:20180803072847p:plain

Shiftキー押してない時は、通常移動速度(375のスピード)で移動するが、

Shiftキー押した時は、速度が「600」になり、通常よりも速い速度で移動が可能だ。

 

ダッシュボタン処理は、AxisMappingsで作成している。

f:id:Free_Gamer:20180803073655p:plain

 

 

但し、エイム中はダッシュ不可にしてある。

エイムボタンを押した時に、Bool値「Aim」がTrueになる為、Trueの先に繋がってる「MaxWalkSpeed375」に処理が走る。

つまり、エイム中は強制的に通常移動速度になるわけだ。

f:id:Free_Gamer:20180803072359p:plain

 

移動アニメーションは、ブレンドスぺースで作成している。

 

移動速度

0・・・Idle(待機)

225・・・Walk

375・・・Run(小走り)

600・・・Sprint(ダッシュ

f:id:Free_Gamer:20180803073120p:plain

 

実際にプレイしてみよう。

youtu.be

 

分かりづらかったら申し訳ないが、しっかり移動速度が変化している。

 

シューティングゲームではよくあるシステムだと思うので、ぜひ参考に。

 

それではまた!^^ノシ

TPSシューティング奮闘記~武器の変更~

前回の続き~!

 

前にも武器変更の記事書いたけど、今回は「銃」の切り替え!

free-gamer.hatenablog.com

 

~武器変更の為のボタン(キー)~

ピストルに変更・・・1キー、十字キー

ライフルに変更・・・2キー、十字キー

ショットガンに変更・・・3キー、十字キー

 

プレイヤーのイベントグラフ

f:id:Free_Gamer:20180801215200p:plain

 

 「CurrentWeapon」という変数は、「現在装備中の武器」が格納されてる。

※Current・・・現在 Weapon・・・武器

初期装備として「Pistol」を装備させてるので、「CurrentWeapon」には「Pistol(武器名NFP-16)」のBPが格納されてる。

DoOnceがあるのは、連打してアニメーションを何度も連発させない為。

 

f:id:Free_Gamer:20180801220144p:plain

例:Rifleに変更したい場合・・・

まず当然Rifleを持ってなきゃ変更できないので、IsValidでRifleがあるかどうかを判定してる。

もし持ってればIsValidはTrueになる。

そして、Rifleを所持していて尚且つ現在装備中の武器がライフル以外の物なら、NotEqualはTrueになる。

というわけだ。

 

つまり、Rifleに武器変更したい場合は・・・

 

・変更したい武器(Rifle)を所持。

・Rifle以外の武器を装備中

 

この2つの条件を満たしていれば武器の変更が可能になるのだ。

 

武器変更した際、どの武器に変更するかのEnum値をセットしている。

例えば、Rifleに武器変更する場合はEnum値が「Rifle」にセットされる。

f:id:Free_Gamer:20180801221202p:plain

※ 初期装備として「Pistol(NFP-16)」を装備させてる。

f:id:Free_Gamer:20180801220504p:plain

 

武器変更ボタン(キー)押した時、まず現在武器変更中という情報を格納する為に、「IsWeaponChange??」というBool値をTrueにセット。

そして、武器変更アニメーション(モンタージュ)を再生。

f:id:Free_Gamer:20180801222318p:plain

 

武器変更した際にセットしたEnum値は、ここで使われる。

「AttachWeapon」というカスタムイベントが呼ばれた時、実際に武器を変更する処理を行う。

各武器によってアタッチする場所が違うのでスイッチを使用している。

f:id:Free_Gamer:20180801221958p:plain

ちなみに、「AttachWeapon」カスタムイベントはAnimBPから呼び出されている。

f:id:Free_Gamer:20180801222645p:plain

この「ChangeWeapon」というのはモンタージュに設定したAnimNotify通知の事だ。

f:id:Free_Gamer:20180801222958p:plain

武器変更ボタンを押し、アニメーションが再生され、「ChangeWeapon」通知が来た時に、プレイヤーの武器変更処理を行う為のカスタムイベント「AttachWeapon」を呼び出す。

といった感じだ。

 

アタッチ処理はこんな感じ。

アタッチする場所は、すでに各武器に備わってる構造体「WeaponInfo」に格納されてるので、そのピンをただ繋げればいいだけ。(もっといい方法があるはずだけどなぁ・・・笑)

そして、アタッチ後変更した武器を現在装備中の武器として「CurrentWeapon」に格納。

f:id:Free_Gamer:20180801223431p:plain

 

最後に、武器ごとのアニメーション(IdleやWalkなど)を変更するために、トランディションルールBool値をセット。

ピストルに変更した際は、「EquipPistol」がTrue.「EquipRifle/ShotGun」がFalse。

ライフルかショットガンに変更した際は、「EquipPistol」をFalse。「EquipRifle/ShotGun」をTrue。

f:id:Free_Gamer:20180801224049p:plain

Animグラフ側

f:id:Free_Gamer:20180801224210p:plain

Pistol→Rifle/ShotGun

f:id:Free_Gamer:20180801224232p:plain

Rifle/ShotGun→Pistol

f:id:Free_Gamer:20180801224317p:plain

 

アタッチ処理が終わった後、「WeaponChangeEnd」カスタムイベントが呼び出される。呼び出された時、武器変更が終了したという事で「IsWeaponChange??」をFalseにする。

そして、DoOnceのResetに処理が流れ、もう一度武器変更が可能になる。

f:id:Free_Gamer:20180801224836p:plain

ちなみに、「WeaponChangeEnd」カスタムイベントはAnimBP側から呼び出されている。

f:id:Free_Gamer:20180801225230p:plain

「Reset」というのは、アニメーションモンタージュで設定したAnimNotify通知の事だ。

アニメーションの終わり辺りに設置している。

f:id:Free_Gamer:20180801225333p:plain

 

これでプレイしてみよう!

youtu.be

 

しっかり武器変更が行われている!

 

最後に実際の処理の流れも!見づらいようならごめん!笑

youtu.be

 

それではまた!^^ノシ

 

TPSシューティング奮闘記~武器の取得~

以前書いたような内容だと思うが、

free-gamer.hatenablog.com

free-gamer.hatenablog.com

まあ進捗という事でw

 

武器BPの作成

「WeaponMaster」という名の親BPを作成。

その子として、それぞれ

「Pistol」

「Rifle」

「ShotGun」

「SubMachinegun」

の子BPを作成した。

 

WeaponMaster

f:id:Free_Gamer:20180801180156p:plain

Widgetコンポーネントの設定

f:id:Free_Gamer:20180801180451p:plain

コンストラクションスクリプト

「WeaponInfo」という自作の構造体変数をセット。

f:id:Free_Gamer:20180801181550p:plain

イベントグラフ

f:id:Free_Gamer:20180801180533p:plain

f:id:Free_Gamer:20180801180802p:plain

WeaponMasterを継承した子BPそれぞれに、武器やウィジェットを設定していく。

(画像はWeaponMasterを継承した子BP「ShotGun」)

f:id:Free_Gamer:20180801180901p:plain

 

構造体・列挙体(Enum)の作成

 

武器の種類を格納するための列挙体「WeaponType」

f:id:Free_Gamer:20180801181330p:plain

武器の特徴を格納するための構造体「WeaponInfo」

f:id:Free_Gamer:20180801181407p:plain

 

武器取得処理

f:id:Free_Gamer:20180801181947p:plain

武器取得した時、このカスタムイベントが呼び出される。

f:id:Free_Gamer:20180801181958p:plain

 

参照したWeaponMasterから「WeaponInfo」構造体を参照。

「WeaponInfo」を分解。

「WeaponInfo」の中にある「WeaponType(自作した列挙体「WeaponType」)」で処理をスイッチ(切り替える)。

f:id:Free_Gamer:20180801182057p:plain

 

もっといい方法があるはずだが、まあ進捗なんでw

例えば、「Rifle」タイプの武器を取得したら、スイッチによって「Rifle」に繋がってる処理が行われる。

「Rifle」タイプの武器をスポーンし、プレイヤーにアタッチ。

その後、アタッチした武器のSphereコンポーネントを破壊。

これを破壊しないと、Sphereコンポーネントによって行われてるウィジェット表示とアウトライン表示が消えないから。

最後に、落ちていた武器を破壊。

f:id:Free_Gamer:20180801182312p:plain

 

ちなみに、初期装備として「Pistol」は最初っからプレイヤーにアタッチさせてる。

f:id:Free_Gamer:20180801183053p:plain

 

これでプレイしてみよう!

youtu.be

 

しっかり武器の取得が行われている!

 

ちょっと見づらいかもだが実際の処理の流れも。

youtu.be

 

ちょっとした参考までに!

 

それではまた!^^ノシ

 

 

 

TPSシューティング奮闘記~エイム処理~

エイム時の処理について僕がよく組んでいる処理を紹介する。

(何か以前にもエイム処理の記事書いたような気がするが気にしない気にしない)

 

エイム時の処理

f:id:Free_Gamer:20180730220829p:plain

エイムボタン押したら、「Aim」というBool値をTrueにセット。

放したら、Falseにセット。

f:id:Free_Gamer:20180730221143p:plain

この「Aim」変数は、エイムアニメーションに移行するためのトランディションルールBool値である。

f:id:Free_Gamer:20180730221446p:plain

 

エイム中(エイムボタン押した時)、平行移動させる。

OrientRotationToMovementのチェックを外し、UseControllerRotationYawにチェックを入れれば、常にカメラのほうに向く。

f:id:Free_Gamer:20180730221505p:plain

 

被写界深度処理(カメラのポストプロセスの強度)をセット。

エイム中は、被写界深度をON(1.0)。非エイム時は、被写界深度をOFF(0.0)にしている。

被写界深度処理は後程出てくる。

f:id:Free_Gamer:20180730221647p:plain

タイムラインでカメラの位置とプレイヤーとの距離を変更。

CameraBoom(SpringArm)の長さをグッと縮めて、キャラの肩越し視点になるようにする。

更に、CameraBoomのSocketOffsetの位置をプレイヤーの真横辺りにずらしている。

f:id:Free_Gamer:20180730221831p:plain

タイムラインは以下の通り。

タイムラインの長さは「0.1」

SpringLengthのタイムラインで、SpringArmの長さを300~100にしている。

SpringOffSetのタイムラインで、SpringArmのX,Zをプレイヤーの右方向にずらしている。

f:id:Free_Gamer:20180730222124p:plain

タイムライン処理の後、

Aim中(True)なら、SetTimerByFunctionNameへ。

非Aim時(False)なら、SetTimerByFunctionNameを止める処理へ。

SetTimerByFunctionNameのFunctionNameには、被写界深度処理を行うためのカスタムイベント「DepthOfField」を指定している。

「DepthOfField」イベントが呼び出されると、「DepthOfFieldSystem」という関数に処理が流れる。

f:id:Free_Gamer:20180730222339p:plain

「DepthOfFieldSystem」関数の中身。

f:id:Free_Gamer:20180730222700p:plain

プレイヤーカメラの位置から「5000」の距離までトレースを飛ばす。

f:id:Free_Gamer:20180730222756p:plain

ヒットした位置とプレイヤーカメラ位置の差を計算し、その結果を「FocalDistance」Float変数にセット。

カメラのポストプロセス変数を出し、「FocalDistance」変数をFocalDistanceピンに繋ぐ。

Apeture(F-stop)の値は「0.5」にした。

Methodは「CircleDOF」に。

この被写界深度処理については、以前も書いたのでそちらも参考に。

free-gamer.hatenablog.com

f:id:Free_Gamer:20180730222819p:plain

 

これでプレイしてみよう!

youtu.be

 

エイム中は、カメラがグッとプレイヤーに近づき、プレイヤーの肩越し辺りにカメラが来ていた!

更に、エイム中は被写界深度処理がしっかり行われていた!

その証拠に、エイム中は近くのものがくっきりしたりぼやけていたりしていた!

 

TPSシューティングを作る際は、ぜひとも参考にしてみてほしい。

もちろん不満ならいくらでも改造して構わない。

 

それではまた!^^ノシ

 

イライラ棒的なゲームを作ろう!(棒じゃないけどw)

イライラ棒、いやイライラ「球」を作ろう!

仕様としては・・・

 

・マウスのドラッグ操作で球を動かす

・弾が何かにヒットしたらゲームオーバー

・ゴールに到達したらクリアー

 

~カメラの設置~

上から全体を見下ろせる位置にカメラを設置。

f:id:Free_Gamer:20180729135413p:plain

f:id:Free_Gamer:20180729135430p:plain

~プレイヤーコントローラー・ゲームモード作成~

「IraIra_Con」という名のPlayerControllerを作成。

クラスのデフォルトの詳細パネル「MouseInterface」欄の赤枠で囲った部分にチェック。

f:id:Free_Gamer:20180729135826p:plain

これでクリックイベントが有効になり、ゲーム開始時常にマウスカーソルが表示されるようになった。

 

「IraIraGameMode」という名のゲームモードを作成。

クラスのデフォルト詳細パネルの「Classes」欄の赤枠で囲った部分を変更する。

先程作成したプレイヤーコントローラー「IraIra_Con」を割り当てよう。

デフォルトポーンは、「None」で。

f:id:Free_Gamer:20180729140929p:plain

 

ワールドセッティングのGameModeに、作成したゲームモード「IraIraGameMode」を割り当てる。

f:id:Free_Gamer:20180729142107p:plain

f:id:Free_Gamer:20180729142121p:plain

 

~球の作成~

「IraIra」という名のアクタークラスのBPを作成。

コンポーネントを以下の通り。

f:id:Free_Gamer:20180729144005p:plain

ドラッグ操作するための処理

f:id:Free_Gamer:20180729142306p:plain

このアクターがクリックされたときに呼ばれるイベント「OnClicked」と、

このアクターがクリックし終わった時に呼ばれるイベント「OnReleased」を追加。

「OnClicked」は、GateノードのOpenに。

「OnReleased」は、Closeに繋げる。

f:id:Free_Gamer:20180729142510p:plain

GetHitResultUnderCursorByChannel

TraceChannel・・・カーソルのトレースチャンネル(コリジョン

HitResult・・・カーソルのヒット情報

ResultValue・・・カーソルがヒットしたかどうか

このノードは、「GetPlayerController」からじゃないと出てこない。

 

マウスカーソル位置に球を追従させたいので、HitResultを分解(BreakHitResult)し、Locationを分解(BreakVector)する。

XとYのみ自由に移動させるようにする。Zは「80」で。

理由は後程。

f:id:Free_Gamer:20180729142654p:plain

移動させる処理として、SetActorLocationを使用。

Sweepにチェックを入れるのを忘れずに。

f:id:Free_Gamer:20180729143716p:plain

 

さて、先ほどの

XとYのみ自由に移動させるようにする。Zは「80」

の理由だが、

 

例えば、Zを「0」にしたらどうなるか。

f:id:Free_Gamer:20180729144745p:plain

埋まる。

理由は、床の位置とちょうど被るから。

これは床を球とぶつからないように下げるか、球のZを「80」にすればいい。

 

今度は、以下のようにしたらどうなるだろう。

f:id:Free_Gamer:20180729145730p:plain

youtu.be

 

カメラのほうに向かって勢いよく向かってくる。

なぜなら、

カメラはワールド内のZの位置に設置している。

という事は、実際球を動かす時XとYを自由に動かせるようにしないといけない。

Zにまで移動可能にすると、Zの位置に設置してあるカメラのほうに向かってきてしまうから。

f:id:Free_Gamer:20180729150619p:plain

だから、Zにまで動かす必要が無いのだ。

f:id:Free_Gamer:20180729150858p:plain

 

何かとぶつかった時の処理

シンプル。

何かとヒットした時に、爆発エフェクトを出して、球を破壊してるだけだ。

f:id:Free_Gamer:20180729151153p:plain

 

ここで、適当にステージを組もう。

f:id:Free_Gamer:20180729163346p:plain

 

~UMGの作成~

クリアーしたときのUMG

「Clear」という名のUMGを作成。

f:id:Free_Gamer:20180729154829p:plain

「CLEAR!」というテキストを追加。

真ん中に設置。

f:id:Free_Gamer:20180729154855p:plain

 

ゲームオーバーした時のUMG

「GameOver」という名のUMGを作成。

f:id:Free_Gamer:20180729155143p:plain

先程とほとんど同じ。

f:id:Free_Gamer:20180729155236p:plain

 

ゴール位置の表示

「Goal」という名のUMGを作成。

f:id:Free_Gamer:20180729160820p:plain

先程と同じ。

f:id:Free_Gamer:20180729160831p:plain

 

 

~ゲームオーバー処理~

「IraIra」のイベントグラフに以下の処理を追加。

DestroyActorの後に、GameOverUMGを表示。

f:id:Free_Gamer:20180729155410p:plain

 

~クリアー処理~

まず、ゴールを設置。

ボックストリガーを置こう。

f:id:Free_Gamer:20180729160157p:plain

設置したボックストリガーに、コンポーネントを追加しよう。

Widgetコンポーネントを追加。

f:id:Free_Gamer:20180729160358p:plain

Widgetの詳細にある「UserInterface」欄は以下のように設定。

Space・・・Screen

WidgetClass・・・作成したUMG「Goal」を設定。

f:id:Free_Gamer:20180729160550p:plain

 

「IraIra」のイベントグラフに以下の処理を追加。

ブランチを追加し、Conditionには「Clear?」という名のBool値を繋いだ。

デフォルト値はFalseに。

f:id:Free_Gamer:20180729161435p:plain

レベルBPに以下の処理を。

レベル内に設置したボックストリガーを選択状態にしたまま、レベルBPのイベントグラフを右クリックし、

OnActorBeginOverLapを追加。

f:id:Free_Gamer:20180729162151p:plain

設置したゴール(ボックストリガー)に、「IraIra」がオーバーラップしたら、「Clear」UMGを表示し、「IraIra」BPにある「Clear」Bool値をTrueにセット。

こうすることで、ドラッグ操作による球の移動が不可能になる。

f:id:Free_Gamer:20180729161657p:plain

 

これでプレイしてみよう!

プレイ映像(死亡ラッシュ)

youtu.be

 

クリアー時

youtu.be

 

非常にシンプルだが、とりあえずゲームっぽいものはできた。

何回も死ぬ羽目になるので、リセット機能は必須かもしれないw

他にも、いろいろとステージやギミックを増やして面白くするのもいいかもしれない。

 

それではまた!^^ノシ

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

SetTimerByEvent・SetTimerByFunctionNameとは??

~SetTimerByEvent~

f:id:Free_Gamer:20180725175902p:plain

「Time」に入れた秒数後に、「Event」に繋がってるカスタムイベントを実行する。

Delayのような感じ。

「Looping」で、「Time」に入れた秒数後、Timerをリセットして再度カウントダウンを始める。

 

~使用例~

f:id:Free_Gamer:20180725180430p:plain

Qキー押す。

SetTimerByEventが実行され、Time」に入れた秒数分カウントダウンを開始。(画像だと「3.0」と入れたので、3秒間のカウントダウンとなる)

3秒後、作成したカスタムイベント「TimerTest」に処理が走り、カスタムイベントに繋がってる処理(画像だと「SpawnEmitteratLocation」)が実行される。

サードパーソンキャラの位置に、爆発エフェクトを出すようにしてある。

 

実際にやってみると・・・

youtu.be

こんなかんじになるはずだ(適当)

 

Loopingにチェックを入れると・・・

youtu.be

3秒おきにエフェクトが出ているのが分かる。

 

~SetTimerByFunctionName~

f:id:Free_Gamer:20180725181509p:plain

SetTimerByEventと違うのは、

実行するカスタムイベント名を指定できる事。

SetTimerByEventは直接ピンで繋げていたが、SetTimerByFunctionNameは「FunctionName」に実行させたいカスタムイベント名を入れる事が可能。

あとはSetTimerByEventと同じ。

Timeに入れた秒数分カウントダウン開始。

Loopingはカウントダウンをループさせるかどうか。

Object??わかんネ(マジすいません・・・)

f:id:Free_Gamer:20180725181355p:plain

先程とほぼ同じ処理。

キャラの位置でエフェクトを出す。

「1秒」おきに何度もエフェクトを出すようにしてある。

「FunctionName」には実行させたいカスタムイベント名を入力。

youtu.be

しっかり「1秒」おきにエフェクトが出てるのが分かる。

 

~カウントダウンの止め方~

さて、SetTimerByEventとSetTimerByFunctionNameの機能は分かったが、

もしかしたら「途中でカウントダウンを止めたい!」という時があるかもしれない。

止めるときはこれを使う。

f:id:Free_Gamer:20180725183027p:plain

「ClearandInvalidateTimerbyHandle」だ。

 

~使用例~

f:id:Free_Gamer:20180725183229p:plain

「0.5秒」おきに繰り返しカスタムイベントの処理を実行。

 

Qキー押した時、SetTimerByEventを実行し、カウントダウンを開始。

Qキー放した時に、実行されてるSetTimerByEventのカウントダウンを停止。

 

ClearandInvalidateTimerbyHandleの「Handle」に、停止させたいSetTimerByEventの値を繋ぐ。

f:id:Free_Gamer:20180725183755p:plain

 

youtu.be

途中でしっかり処理が止まってるはずだ。

実際にやってみよう。

 

もちろんSetTimerByFunctionNameでも同じことができるぞ。

f:id:Free_Gamer:20180725184118p:plain

 

~小ネタ~

SetTimerByEvent・SetTimerByFunctionNameを使って、EventTickとほぼ同じ動作をさせることが可能だ。

f:id:Free_Gamer:20180725184504p:plain

Timeに「0.008333」を入れてやれば、ほぼEventTickと同じ動作が可能だ。

youtu.be

非常に目に痛い動画だが、EventTickとほぼ同等の動作と言える。

 

これで、SetTimerByEventとSetTimerByFunctionNameの機能と、ちょっとした小ネタを知ることが出来た!

 

それではまた!^^ノシ

 

Splineで遊ぼう!~Splineでちょっとしたプロシージャルメッシュ作成~

ActorクラスのBPを作成。

名前は何でも。(自分は「BP_Spline」にした。)

 

~Splineコンポーネント追加~

f:id:Free_Gamer:20180719002709p:plain

「Spline」というコンポーネントを追加

 

~ConstractionScript~

f:id:Free_Gamer:20180719002752p:plain

~変数~(全部編集可能にする)

NumberOfMeshs・・・配置するメッシュの数

OrientToSpline・・・メッシュの向き(角度)をSplineの角度に合わせるか??

 

NumberOfMeshsで配置するメッシュの数を決める。

デフォルト値は「2」にした。

配置するメッシュの数が「0」、つまりNumberOfMeshsが「0」の場合、ブランチの条件によりFalseに処理が流れる。

f:id:Free_Gamer:20180719003000p:plain

NumberOfMeshsの値「2」から1引いた値をForLoopのLastIndexに渡す。

同時にNumberOfMeshsの値「2」から1引いた値をGetSplineLengthの値で割る。

 

GetSplineLength・・・Splineの長さを取得

 

ちなみに、Splineの長さはデフォルトだと「100」

つまり、NumberOfMeshsのデフォルト値には「2」を入れたので、

 

100÷1=「100」

 

になる。

「100」をIndexの値で掛け算する。

FirstIndex「0」

LastIndex「1」なので・・・

 

0×100=「0」

1×100=「100」

 

となる。

この値は、配置するメッシュの位置を決める値となる。

 

f:id:Free_Gamer:20180719003216p:plain

この値を、GetLocationAtDistanceAlongSplineでVector値に変換。

このVector値は、ワールド座標のVectorになる。

f:id:Free_Gamer:20180719004015p:plain

これを、InverseTransFormLocationで相対座標に変換。

f:id:Free_Gamer:20180719004243p:plain

相対座標に変換した値をMakeTransFormで一纏めにして、AddStaticMeshComponentノードのRelativeTransFormに繋ぐ。

これで、メッシュを指定した数の分だけ配置が可能になった。

f:id:Free_Gamer:20180719004656p:plain

最後に、GetRotationAtDistanceAlongSplineでSplineの角度をワールド座標の角度に変換。

Distanceには、先程の「Indexの値×100」の値を繋ぐ。

f:id:Free_Gamer:20180719010313p:plain

GetRotationAtDistanceAlongSplineでワールド座標に変換したSplineの角度を、SetWorldRotationに渡す。

その前に、ブランチを挟む。

ConditionがTrue・・・メッシュの角度をSplineの角度に合わせる。

ConditionがFalse・・・合わせない。

f:id:Free_Gamer:20180719005235p:plain

 

さてどうなっているか!?

youtu.be

見事!(自己満)

 

ここで整理しよう。

NumberOfMeshsの値が「2」だった場合。

f:id:Free_Gamer:20180719012153p:plain

相対座標、X「0」とX「100」の位置にメッシュが配置される。

「0」「100」は、先程やった「Indexの値×100」の奴だ。

 

0×100=「0」・・・1個目に配置するメッシュの位置

1×100=「100」・・・2個目に配置するメッシュの位置

 

となる。

 

まあ、Splineは昨日触ったばっかなので、色々違う部分はあるかもしれないw

その場合は遠慮なく指摘してほしい。

 

それではまた!^^ノシ