Instantiateを使ってプレイヤーに弾をうたせたいと思います
キー入力すると、キャラクターの前に弾を発生させ、それをキャラクターの向いている方向に飛ばしていきます。
2.3.あたりは、かなーりスクリプトを失敗してます。参考にするなら4.を見てください
どんな感じで直していったのか?一緒に失敗体験したいかたは、1から順番に見てください
目次 1,大まかな今回やっていく内容の流れ こんなかんじでやっていきます 2.弾を作り弾を飛ばす velocity使いますよ 3.プレイヤーのスクリプトで弾を指定位置に生成する キャラクターに対して同じ向きで、ちょい前に生成する 4.なんやかんやで分かったこと 今回の本当の正解スクリプトとまとめ 今回かなり失敗しまくったので。たいへんでした
このページ作った時に買ったものではないですが、僕の買ったやつの2019版ですかね、どうせ買うなら、最新版、自分の使ってるunityのバージョンと合わせて買いましょう、安心ですよ※このページの内容が丸ごと乗っているわけではないです、この本プラスネット検索が大事かもです、でも1冊以上は、買ったほうがいいかもですので、おすすめのやつを紹介
1.大まかな今回のながれ
Insatantiateを使って弾を生成して飛ばしたいと思います
スクリプトは2つ作ります
大まかな流れとしては、プレイヤーのスクリプトでキー入力で弾を生成し、弾が生成されたらそれについてるスクリプトで弾を生成した位置からまっすぐ飛ばす
弾のオブジェクトにつけるスクリプトの内容
弾の進み方 生成されたらリジッドボディ物理挙動ベロシティを使い生成された向き、位置からまっすぐ飛ばしていきます
プレイヤーの移動の時に使った物理挙動移動今回は、初めて使うベロシティを試していきます、これは、いきなり速度を与えるものらしいです、楽しみー
プレイヤーオブジェクトにつけるにつけるスクリプトの内容
Instantiateで弾をマウスクリックで生成させるスクリプト
この時にプレイヤーの位置と向きを基準に生成させます
またしても出てきた、座標問題苦手なんですよねー、いつも手探りで実験しながら、プレイヤーが回転、移動してもちゃんと想定の位置にできてるか?
都合により2.3は2より先に3をやることにします理由は、座標が苦手なのでどちらで失敗しているかを特定しやすいと思ったのです
目次に戻る
2.弾のオブジェクトとそれにつけるスクリプト
流れとしては、生成されたら、ゲットコンポーネントしてベロシティで前に進む速度を与えます
using System.Collections; using System.Collections.Generic; using UnityEngine; public class スクリプトのファイル名: MonoBehaviour { // Use this for initialization void Start () { } // Update is called once per frame void Update () {} private void FixedUpdate() { GetComponent<Rigidbody>().velocity = transform.forward * 1500 * Time.fixedDeltaTime; } //赤字の部分だけ追加しました }
いきなりゲットコンポーネントしてからのーベロシティーこれでオッケーでした
かける1500してるのは、変数使ってもよかったんだけど今回は、あとから数値いじる予定ないからです、値の大きさは、好みでいろいろ試してください
3.キー入力があったらさっきの弾のプレハブを生成
ここでの課題 プレイヤーの位置を基準に生成がむずい
instantiate自体はそんなに難しくないはず
Instantiateで使うため public GameObject tama;を宣言しておいてくだい
そのあとスクリプトにtamaが出てくるのでこれにプレハブから弾に使うオブジェクトを設定してください
Instantiate(オブジェクトを指定、生成位置を指定、生成角度を指定位置)
ここまでは調べたのですが、生成位置、生成角度これが生成したオブジェクトの位置や、角度ではなくこのスクリプトをくっつけてある、つまりプレイヤーの位置や角度を基準としてる、と解釈してスクリプトの実験をしていきます(そうであってくれー)でも調べてきた情報だとInstantiateの引数の位置の部分にtransform.positionが使われてるのでワールド座標基準で、この場合プレイヤーの位置(ワールド座標問題)に生成うーん、どっちだろう、プレイヤーのちょっと前に生成する位置指定しながら実験して正解のスクリプトを貼り付けるのでしばらくお待ちください(後日やって修正します)
if (Input.GetMouseButtonDown(0)) { Instantiate (tama,transform.position.normalized*20,Quaternion.identity) ; }//これじゃ失敗だった
ノーマライズドしてかける20やったらプレイヤーの前20の距離に生成されると思ったのに
こうなりました
いろいろ試してみた結果、たぶんtransform.positionは、tamaのプレハブのポジションを指定しているみたいです。
if (Input.GetMouseButtonDown(0)) { GameObject aiueo = Instantiate(tama, transform.position, Quaternion.identity) as GameObject; }
こうしたら、ちょっとよくなった、ただプレイヤーのチョイ前に生成させないと、面白いことがおきてしまう、動画貼ります
プレイヤーに重なって生成されるのではじかれてプレイヤーが飛んで行ってしまうようです、これは、これで使えそうですが(想定道理の挙動は、難しそうですが)
if (Input.GetMouseButtonDown(0)) { GameObject aiueo = Instantiate(tama, transform.position+Vector.forward*3, Quaternion.identity) as GameObject; }
やっと完成した、プレイヤーの前にオブジェクトを生成できました
+vector3.upでもうちょい上に生成したいです
あとこっそり弾が大きすぎていたので調整しました
成功と思ったのによくみたら若干斜め前に出ていました
if (Input.GetMouseButtonDown(0)) { aiueo = Instantiate(tama, transform.position+transform.forward*3, Quaternion.identity) as GameObject; }
public GameObject aiueo;これを宣言しておいてくださいaiueo名前は、何でもいいのですが、わかりやすい名前にしたほうがいいと思います、ここに書いた以外にもいろいろ試行錯誤したので、へんなテンションになってしまってついつい、やってしまいました
public,privateたぶんどちらでもいいのですが今回は、スクリプトを分けるし、もしかしたらほかで使うかも、くらいの軽い気持ちでpublicにしました
これが本当の正解、もっといい方法ありそうだけど、今回のは、ちょっと疲れたよ、僕は、
あとは、弾にスクリプトくっつけて飛ばすのともうちょい上に生成したいかもとりあえず成功動画はります
Instantiateまとめ
Instantiate(オブジェクトを指定、生成位置を指定、生成角度を指定位置)
一応仮説ですが、Instantiateの引数にある生成位置にtransformを使う場合これは、生成されるオブジェクトを基準(プレハブの場合だと設定されているtransform情報)プレハブの位置情報をいじりまくって、いずれ実験したいですね、vector3(x、y、z)でやると、たぶんそのままワールド座標になるのかも、これも検証したいです
今回成功した理由が実は、ちゃんとわかっていないのです、いずれ検証してみたいですが、おまじないってことですませてもいいかもです
〇GameObuject aiueo;を宣言したことでInstantiateの生成位置がかわった?aiueo = Instantiate();の中の第2第3引数がスクリプトのアタッチされてるオブジェクト基準に変わった
〇as GameObject キャストというらしいのですが、これをやったから?
一応検証しましたas GameObjectを消してビルドしても想定道理の位置に生成されているので、宣言して箱を変数を用意してInstantiateを使い位置、角度の指定にtransform.fowrd等を使うと、スクリプトのアタッチされているオブジェクト基準になると解釈しておきます。
vector3を使うとたぶんワールド座標でしていできるはず(ほかでも使うかもしれないのでもう一度書いとく)
as GameObject as Rigidbody は、同じスクリプト内で弾を前に飛ばすために使うやつと勉強していました、今回は、前に飛ばすのは、弾用のスクリプトでやる予定だったので、すぐ使う予定じゃなかったのですがこれをやるときに使う、GameObuject aiueoこれが役に立ってラッキーでした、transform.forward vector3.forwardは、便利だけどものによって基準が違うので、最初の検証が大変ですね、少しずつパーツを増やしていって、知識が増えたら、迷うこともなくなるのかな、そのために勉強勉強
2018/9/18修正こっちのほうを採用しました
public GameObject tama;
void start()
{
}
void update()
{
if (Input.GetMouseButtonDown(0))
{
tama = Instantiate(tama, transform.position+transform.forward*3+transform.up*2, transform.rotation) as GameObject;
}
}
成功例の紫色のやつをちょっと修正しました、わざわざGameObuject aiueo;を宣言しなくても、public GameObuject tama;があるのでこれをつかえばよかったのです
水色の部分あとから修正しました
修正箇所と理由
+transform.up*2
生成位置が低くて地面すれすれだったのでちょい高めに設定しました
transform.rotation
最初は、Quaternion.identityでいいと思っていたのですが向きがうまくいってなかったのでこれに変えました
あとひとつ前半に今考えると意味わからんやつがあったtransform.position.normalizedこれとQuaternionさんのせいでかなり時間かけましたねw
でも今回もかなり勉強になりました
なんやかんやでわかったこと
プレイヤーキャラにつけたスクリプトのinstantiate下のスクリプトが最終作です
public GameObject tama; これをこのスクリプトで宣言するのを忘れずに
//キャラクター(操作キャラに貼り付けておくスクリプトです)
if (Input.GetMouseButtonDown(0))
{ Instantiate(tama, transform.position + transform.forward * 3+transform.up*2,transform.rotation) ;
}
//弾にくっつけるスクリプトです
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class スクリプトのファイル名: MonoBehaviour {
// Use this for initialization
void Start () { }
// Update is called once per frame
void Update () {}
private void FixedUpdate()
{
GetComponent<Rigidbody>().velocity = transform.forward * 1500 * Time.fixedDeltaTime;
} //赤字の部分だけ追加しました
}
いろいろめちゃくちゃな推論ですすめてきましたが、ほんとーに単純なとこでミスってました。Quaternion.identityがわるかったのです、これをtransform.rotationに変えると方向は、なおりました、Quaternionは、今度勉強しようと思いますが、難しいらしいですよ、あと一つ、あとでわかったのですが、これが事の始まりですねtransform.position.normalized、意味不明すぎるので説明不能です、なにがやりたかったのかわかりません。
仮説では、あるのですがInstantiate(オブジェクト);だけで呼び出すとその生成したオブジェクトのtransformを参照するのですが、引数で位置と角度を指定するときのtransformは、このスクリプトを張り付けてあるオブジェクトのtransformを参照するのです
tamaの形が変わってるのは、玉のままだとどこ向いているのかわかりにくかったので形をいじりました
初心者でも使える?インターフェースを使って攻撃を管理実装するぞ
このぺーじの次に行ってほしいページです
コメント