Unity3dスクリプトの基本



まえがき


この記事では、Unityスクリプティングの初心者を対象にしていますが、JavaScriptシンタックスや他の同様のプログラミング言語に完全に慣れているわけではありません。 ここで、Unityを使用するJavaScriptは、 OOPのサポートを改善するために元のものとわずかに異なり、それぞれUnity JavaScriptと呼ばれることを少し明確にする必要があります。 たとえば、元のJavaScriptのオブジェクト指向機能に精通している新しいUnity開発者が認識していないクラスとその継承がそこに現れたため、C#またはBooを使用して拒否します。

謝辞


まず、 Unityの記事を書いた著者に感謝します-無料のクロスプラットフォーム3Dエンジン(およびブラウザベース) 、および初心者向けUnity3Dチュートリアル-チュートリアル1これらの記事の著者がUnityのトピックについてhabra-peopleを教育するのを助けるために、彼のレッスンのアップグレードを書いても気にしないと思います。

まとめ


私は長い間、どこから始めたらよいかと考え、最後には最初から始めることにしました。 つまり、ほとんどのゲームはどこから始まるのでしょうか? いいえいない静止画やロゴ制作スタジオと間違っていないし、メインメニューから! このチュートリアルでは、ゲームGUIの主要な要素、スクリプトからシーンをロードする方法、およびさまざまなスクリプトを相互作用させる方法について詳しく説明します。 このレッスンでは、レッスンで作成した「シューター」のメインメニューを作成します。Unity3Dfor beginners-Tutorial 1 、そのレッスンでスクリプトを作成したことも伝えます。 。

1.ラベルとGUIStyle


では、 レッスンのおかげで作成したプロジェクトを開きましょう。 新しいシーンを作成し([ファイル]-> [新しいシーン])、シーン内に空のオブジェクトを作成し(GameObject-> [空を作成])、たとえばメニューと設定に名前を付けます。 空のJavaScriptファイルを作成し([アセット]-> [作成]-> [JavaScript])、メニューおよび設定オブジェクトにドラッグし、スクリプト自体をダブルクリックすると、スクリプト編集ダイアログボックスが開きます。

スクリプトファイルが完全に空ではなく、更新機能が含まれていることがわかります。後で説明します。今は削除して、次のように記述します。
public var welcomeLabel : GUIStyle; //1 function OnGUI(){ //2 GUI.Label(new Rect(Screen.width / 2, 0, 50, 20),"Welcome",welcomeLabel); //3 } 


変更を保存し、[再生]をクリックします。
上から見たところ、中央ではなく、黒字で書かれた「Welcom」というほとんど認識できない単語があります。

しかし、それは何ですか? ようこそという言葉があるはずです!
実際、テキストが書かれている正方形の幅が単語全体に収まらないと宣言したため、最後の文字は失われました。
しかし、すべてについて順番に話しましょう。プレイモードをオフにします。

誰かが理解していない場合、以下の点はコード内のコメントに対応します。
  1. タイプGUIStyleの変数welcomeLabel。 [階層]タブに移動し、GameObject(GO)-メニューと設定を選択します。スクリプトに新しいWelcome Labelフィールドが表示されていることがわかります。 展開すると、多くの子フィールドに表示されているように、WebでJavaScriptとCSSを扱った人は、おそらくこれらのプロパティの目的をすでに推測していると思います。
  2. OnGUI()関数は、GUIイベントのレンダリングと処理のために各フレームで呼び出されます; GUIに関連するすべてのものは、この関数で呼び出される必要があります。
  3. F. GUIクラスのラベル() 。 この関数の最初の引数は、 Rect構造体を渡します。実際には、座標x = Screen.width / 2、つまり画面の幅を2で割った値がわかるように、左上隅のx座標とy座標、幅と高さで与えられる正方形です。テキストを中央に揃えるために、2番目の引数はテキスト文字列「Welcome」であり、3番目の引数はフィールドWelcome Labelを使用してラベルのさまざまなパラメーターを設定するスタイルです。

[ようこそラベル]フィールドを展開し、次のオプションを設定します。


[再生]をクリックして、結果をお楽しみください。

レッスンはすでにかなり長いので、どの設定が原因であるかについては説明しません。それらを試してみて、フォントの色とサイズを変更し、テクスチャを適用します。すべてが非常にシンプルで直感的です。

余談で開始します


一般に、スクリプトエディターとして、任意の開発環境を使用できます。すべてのスクリプトは、プロジェクトのAssetsフォルダーに作成されます。 たとえば、無料のMonoDevelop開発環境を使用できます。これは主にC#およびその他の.NET言語のコーディングを目的としていますが、JSでも同様に使用できます。 Unityディストリビューションにも含まれており(インストールするには、Unityのインストールを開始する前にチェックボックスをオンにする必要があります)、このプログラムを使用してスクリプトを常に開くには、(編集)->(プリファレンス)に移動し、(外部スクリプトエディター)フィールドでエディターへのパスを指定し、同期も行いますプロジェクトファイルで作成したすべてのスクリプトは、[アセット]-> [MonoDevelopプロジェクトの同期]をクリックするだけです(別のスクリプトを作成するたびにボタンを押す必要はありません。1回クリックするだけで、追加のスクリプトがプロジェクトファイルに自動的に含まれます)。 私はそれがスクリーンショットを行います、でも私にとっては、このエディタのすべての利点を説明しません。

標準エディター:


MonoDevelop:

余談終了



2.ボタンとGUISkin


スクリプトに進み、修正します。
 public var welcomeLabel : GUIStyle; public var customSkin : GUISkin; //1 public var playGameRect : Rect; //2 public var optionsRect : Rect; //2 public var quitRect : Rect; //2 function OnGUI(){ GUI.Label(new Rect(Screen.width / 2, 0, 50, 20),"Welcome",welcomeLabel); GUI.skin = customSkin; //3 GUI.Button(playGameRect,"Play Game"); //4 GUI.Button(optionsRect,"Options"); //4 GUI.Button(quitRect,"Quit"); //4 } 


次に、新しいGUISkinを作成し、Assets-> Create-> GUI Skin、Menu Skinと呼び、Menu and settingsオブジェクトに移動して、新しく作成したMenu Skinを新しいCustom Skinフィールドにドラッグし、残りのフィールドで次の設定も設定します(PlayゲームRect、Options Rect、Quit Rect):


[再生]をクリックすると、結果は次のようになります。


[プロジェクト]タブのメニュースキンに移動し、ボタンのフォントサイズをわずかに増やします。つまり、[ボタン]フィールドを展開し、[フォントサイズ]を16に設定します。これは、ゲームモードを終了せずに行うことができ、終了すると、変更が保存され、プレハブプロパティが変更されます。

スクリプトを解析してみましょう。
  1. GUISkinは 、基本的に標準のGUI構成の全体集合であるそれらを変更するための非常に柔軟な方法を可能にします。
  2. Rectについてはすでに知っていますが、エディターから変数(変数)を構成する機会を得るために、関数の外側でパブリックアクセス修飾子を使用して変数を宣言するようになりました。
  3. GUISkinの設定をGUIクラスのスキン変数に割り当てます。これ以降、クラスのすべての関数はこのスキンを使用します。ある時点でスクリプトでスキンの使用を停止し、設定を標準にリセットする場合は、その前にGUI.skin = nullを記述するだけです。
  4. Button()関数は、bool値を返すことを除いて、Label関数と本質的に違いはありません(ボタンをクリックするとtrue、他のすべての場合はfalse)。


3.オプションとスライダーメニュー


私たちは)(戻り値FCTボタンを使用し、さらにスクリプトを変更します。
 public var welcomeLabel : GUIStyle; public var customSkin : GUISkin; public var playGameRect : Rect; public var optionsRect : Rect; public var quitRect : Rect; private var optionsMode = false; //1 public var _bulletImpulse : float = 300; //2 public var _shootDelay : float = 1; //2 function OnGUI(){ if(!optionsMode){ //1 GUI.Label(new Rect(Screen.width / 2, 0, 50, 20), "Welcome", welcomeLabel); GUI.skin = customSkin; GUI.Button(playGameRect,"Play Game"); if(GUI.Button(optionsRect,"Options")){ optionsMode = true; //1 } GUI.Button(quitRect,"Quit"); }else{ GUI.Label(new Rect(Screen.width / 2, 0, 50, 20), "Options", welcomeLabel); GUI.skin = customSkin; //5 GUI.Label(new Rect(270, 75, 50, 20),"Bullet Impulse"); _bulletImpulse = GUI.HorizontalSlider(new Rect(50, 100, 500, 20), _bulletImpulse,10,700);//3 GUI.Label(new Rect(560, 95, 50, 20), _bulletImpulse.ToString());//4 GUI.Label(new Rect(270, 125, 50, 20),"Shoot Delay"); _shootDelay = GUI.HorizontalSlider(new Rect(50, 150, 500, 20), _shootDelay, 0.1, 3);//3 GUI.Label(new Rect(560, 145, 50, 20), _shootDelay.ToString());//4 if(GUI.Button(new Rect(20, 190, 100, 30),"<< Back")){ optionsMode = false; //1 } } } 


  1. 通常、画面では1つのサブメニューのみを開くことに慣れていますが、メインメニューのみが消え、この変数の後に続きます。
  2. 実際、これはゲームのオプションです。後でそれらに戻ります。
  3. 機能水平スライダー()スライダー上のスライダ位置の充電電流の値であり、第三引数- - (!それは驚きだ)水平スライダー«描く»を、最初の引数(のRect)はコメントせずに残して取り、2番目の引数は、右-左の値は、スペースの量、および最後です値の場合、関数は、左と右の値の間にある浮動小数点値を返します(スライダースライダーを移動した場合)。
  4. Label()関数の最後の引数に注意してください-これは、ToString()関数によって文字列に変換されるfloat値です。これは重要です。 Unityスクリプトコンパイラは、数値を文字列自体に変換する方法を知らず、エラーをスローします。
  5. GUI.skinは別のメニューに切り替えるとリセットされるため、これは発生しません。新しいメニューを描画する前にcustomSkinを割り当てる必要があります

さて、何が起こったのかを見てみましょう。[再生]と[オプション]ボタンをクリックします。

しかし、それは何ですか? Bullet and Shootとは何ですか? 弾丸インパルスとシュート遅延がなければなりません! 繰り返しますが、これらの***正方形の幅は十分ではありませんでした。本当にスクリプトに戻り、そこで幅を変更する必要がありますか

いや! しないでください! Menu Skinという名前の素晴らしいGUISkinがあります。 プレイモードを終了せずに、そこに進み、[ラベル]フィールドを展開し、[テキストクリッピング]オプションで[オーバーフロー]を選択し、[ワードラップ]の横のボックスをオフにします。

4.ゲームをプレイして終了


他のボタンにインタラクティブ機能を追加します。
 public var welcomeLabel : GUIStyle; public var customSkin : GUISkin; public var playGameRect : Rect; public var optionsRect : Rect; public var quitRect : Rect; private var optionsMode = false; public var _bulletImpulse : float = 300; public var _shootDelay : float = 1; function OnGUI(){ if(!optionsMode){ GUI.Label(new Rect(Screen.width / 2, 0, 50, 20),"Welcome",welcomeLabel); GUI.skin = customSkin; if(GUI.Button(playGameRect,"Play Game")){ Application.LoadLevel("Test Scene"); //1 } if(GUI.Button(optionsRect,"Options")){ optionsMode = true; } if(GUI.Button(quitRect,"Quit")){ Application.Quit(); //2 } }else{ GUI.Label(new Rect(Screen.width / 2, 0, 50, 20), "Options",welcomeLabel); GUI.skin = customSkin; GUI.Label(new Rect(270, 75, 50, 20),"Bullet Impulse"); _bulletImpulse = GUI.HorizontalSlider(new Rect(50, 100, 500, 20),_bulletImpulse,10,700); GUI.Label(new Rect(560, 95, 50, 20),_bulletImpulse.ToString()); GUI.Label(new Rect(270, 125, 50, 20),"Shoot Delay"); _shootDelay = GUI.HorizontalSlider(new Rect(50, 150, 500, 20),_shootDelay,0.1,3); GUI.Label(new Rect(560, 145, 50, 20),_shootDelay.ToString()); if(GUI.Button(new Rect(20, 190, 100, 30),"<< Back")){ optionsMode = false; } } } ゲーム")){ public var welcomeLabel : GUIStyle; public var customSkin : GUISkin; public var playGameRect : Rect; public var optionsRect : Rect; public var quitRect : Rect; private var optionsMode = false; public var _bulletImpulse : float = 300; public var _shootDelay : float = 1; function OnGUI(){ if(!optionsMode){ GUI.Label(new Rect(Screen.width / 2, 0, 50, 20),"Welcome",welcomeLabel); GUI.skin = customSkin; if(GUI.Button(playGameRect,"Play Game")){ Application.LoadLevel("Test Scene"); //1 } if(GUI.Button(optionsRect,"Options")){ optionsMode = true; } if(GUI.Button(quitRect,"Quit")){ Application.Quit(); //2 } }else{ GUI.Label(new Rect(Screen.width / 2, 0, 50, 20), "Options",welcomeLabel); GUI.skin = customSkin; GUI.Label(new Rect(270, 75, 50, 20),"Bullet Impulse"); _bulletImpulse = GUI.HorizontalSlider(new Rect(50, 100, 500, 20),_bulletImpulse,10,700); GUI.Label(new Rect(560, 95, 50, 20),_bulletImpulse.ToString()); GUI.Label(new Rect(270, 125, 50, 20),"Shoot Delay"); _shootDelay = GUI.HorizontalSlider(new Rect(50, 150, 500, 20),_shootDelay,0.1,3); GUI.Label(new Rect(560, 145, 50, 20),_shootDelay.ToString()); if(GUI.Button(new Rect(20, 190, 100, 30),"<< Back")){ optionsMode = false; } } } 


プレイモードに入ってこれらのボタンをクリックしようとすると、おそらくコンソール(ウィンドウ->コンソール)でプレイゲームをクリックするとエラーが表示され、「何もしない」をクリックすると何も起こらないので、その理由を見てみましょう:
  1. ApplicationクラスのLoadLevel()クラスは、「Test Scene」というシーンをロードします( 初心者向けUnity3Dチュートリアル-チュートリアル1からシーンを呼び出したように)、シーン番号をこの関数に転送することもできます。 質問があります:この番号はどこで入手できますか? 簡単です。まだ保存していない場合はシーンを保存します。[ファイル]-> [シーンに名前を付けて保存...]を選択し、[メニューシーン]に名前を付けて、[ファイル]-> [ビルド設定...


    シーンの名前の右側には、そのシリアル番号が表示されます(デフォルトでは、シーン番号0が常に最初にロードされます)。 テストシーンがビルド設定に登録されていなかったため、テストシーンがブートすることを望まなかったと他の誰が推測しませんでしたが、今ではすべてが正常になります。 [ビルド設定]ウィンドウを閉じ、プレイモードに入り、[ゲームをプレイ]ボタンをクリックします。 やった! シーンが読み込まれています!
  2. しかし、Quitボタンはまだ機能しません。 心配しないでください。プロジェクトがエディターまたはWebプレーヤーで起動されても機能しません。 ボタンが機能するためには、プロジェクトを独立したアプリケーションにする必要があります。そのためには、「ビルド」して起動する必要があります。 これを行うには、(ビルド設定)に移動し、(ビルドと実行)ボタンをクリックして、完成したアプリケーションを保存するフォルダーを指定し、保存し、設定を選択して起動し、メインメニューを確認して、(終了)をクリックします、見よ、アプリケーションが閉じます


5. DontDestroyOnLoadおよびその他の悪い言葉


最初に、 Unity3D初心者向けチュートリアル-チュートリアル1のスクリプトを見て、使用する設定と使用する理由を確認しましょう。
 public var bulletImpulse = 300; //1 public var shootSpeed; //2 public var bullet : GameObject; //3 public var lastShotTime : float; //4 function Start() { //5 lastShotTime = 0; } function Update () { //6 if (Input.GetKey(KeyCode.Mouse0)) { //7 if (Time.time>(lastShotTime + shootSpeed)){//8 var bull_clone : GameObject; //9 bull_clone = Instantiate(bullet, transform.position, transform.rotation);//10 Physics.IgnoreCollision(bull_clone.collider, collider);//11 bull_clone.rigidbody.AddForce(transform.forward*bulletImpulse, ForceMode.Impulse);//12 lastShotTime = Time.time;//13 } } } // public var bulletImpulse = 300; //1 public var shootSpeed; //2 public var bullet : GameObject; //3 public var lastShotTime : float; //4 function Start() { //5 lastShotTime = 0; } function Update () { //6 if (Input.GetKey(KeyCode.Mouse0)) { //7 if (Time.time>(lastShotTime + shootSpeed)){//8 var bull_clone : GameObject; //9 bull_clone = Instantiate(bullet, transform.position, transform.rotation);//10 Physics.IgnoreCollision(bull_clone.collider, collider);//11 bull_clone.rigidbody.AddForce(transform.forward*bulletImpulse, ForceMode.Impulse);//12 lastShotTime = Time.time;//13 } } } 


  1. お尻を蹴る勢いが弾丸に伝達されます
  2. shootSpeed、このパラメーターにはあまり良い名前ではありません これは本質的にショット間の遅延であり、MainMenuスクリプトでは後で代わりに取得するオプションで、_shootDelayと呼ばれます
  3. 弾丸自体は、プレハブまたはシーン内のオブジェクトのいずれかです
  4. 最後のショットの時間
  5. FIRST Updateメソッドの1回前にStart()が呼び出されます
  6. F- Update()は、すべてのフレームで呼び出されます(一般に、公式ドキュメントでは、物理学との相互作用があるすべての関数は、物理学のさまざまなバグを回避するためにFixedUpdate()関数で記述することをお勧めしますが、これは非常に小さいため、プロジェクションにとって重要ではありません)
  7. マウスの左ボタンが押された場合。
  8. そして、現在の時間が最後のショットの時間+ショット間の遅延よりも長い場合。
  9. GameObject型の変数を宣言します。
  10. Instantiate ()は 、オブジェクトのクローンを作成し、ワールド空間で指定された位置と回転角度でオブジェクトを返します。 最初の引数の弾丸ザ・オーナー、これは、つまり、オブジェクトをコピーするために、第2引数私たちの箇条書きで、私たちはクラスにアピール変換 (この場合は、対象プレイヤー)スクリプトに添付されたゲームオブジェクト、実際のクラスでは、 変換それから店にゲームオブジェクトの物理的な位置に関する情報を必要な2つの変数を取得します:position-ワールド空間での位置を保存し、rotation-回転の角度を保存します。
  11. Accessオブジェクト物理学と呼んでIgnoreCollision彼はスクリプトに添付された衝突型加速器オブジェクト(プレイヤー)との間の衝突(コリジョン)を無視するようになり、そして私たちの弾丸のコライダーのクローンは、このすべては、これら2つのエンティティ間ではもはや物理的相互作用しない、とすることを意味しますプレーヤーは単にボールを通り抜けます-クローン。
  12. 弾丸の剛体オブジェクトを参照します。これは、物理シミュレーションを通じてオブジェクトの位置を制御し、特定の物理効果(この場合は運動量)をオブジェクトに追加するAddForce()関数を呼び出します。最初のパラメーターは、プレイヤーの変換に対して前方に向けられたベクトルです'aに運動量の強度を掛けると、2番目のパラメーターはモードです
  13. 現在の時間を保存します-これは最後のショットの時間です

そのため、この情報の流れを処理し、2つの変数(bulletImpulseとshootSpeed)のみが必要であり、多くの人がすでに推測しているように、GameObjectのメニューと設定、またはそれに関連付けられているスクリプトからそれらを取得する必要があることがわかります。

しかし、それはなんと不幸でした。 Menu and settingsオブジェクトのスクリプトから必要なデータを取得するには、Playerオブジェクトと同じシーンに存在する必要があり、多くの人が既に気づいているように、Play Gameボタンをクリックすると、Menu Sceneのすべてのオブジェクトが破棄され、Hierarchyタブにあります2番目のシーン(テストシーン)のオブジェクトが表示されます。

この病気を倒すことは、私たちが機能するのに役立ちますDontDestroyOnLoadを() 。 スクリプトの初期化時に呼び出されるAwake()関数で1回呼び出すだけで十分です。これは、一種のコンストラクタです。

MainMenuスクリプトに次の関数を追加します。
 function Awake(){ DontDestroyOnLoad(this); } 


Playモードに入り、Play Gameをクリックします。 かっこいい! メニューは消えず、すべての上に重ねられています。これは、メニューと設定オブジェクトが破壊されていないことを意味します。また、[階層]タブに存在することも意味します。

しかし、メニューは常に表示されています! ご注文及びこれと格闘する必要があり、そのためのスクリプトを(この最後の)変更しないでください。
 public var welcomeLabel : GUIStyle; public var customSkin : GUISkin; public var playGameRect : Rect; public var optionsRect : Rect; public var quitRect : Rect; private var optionsMode = false; private var menuMode = true; //1 private var gameMode = false; //1 public var _bulletImpulse : float = 300; public var _shootDelay : float = 1; function Awake(){ DontDestroyOnLoad(this); } function OnGUI(){ if (Input.GetKey(KeyCode.Escape)){ //2 menuMode = true; //1 optionsMode = false; Time.timeScale = 0; //3 if(gameMode){ //1 var ml = GameObject.Find("Player").GetComponent(MouseLook); //4 ml.enabled = false; //4 } } if(menuMode){ if(!optionsMode){ GUI.Label(new Rect(Screen.width / 2, 0, 50, 20), "Welcome",welcomeLabel); GUI.skin = customSkin; if(!gameMode){ //1 if(GUI.Button(playGameRect, "Play Game")){ menuMode = false; //1 gameMode = true; //1 Time.timeScale = 1; //3 Application.LoadLevel("Test Scene"); } }else{ if(GUI.Button(playGameRect,"Resume")){ var _ml = GameObject.Find("Player").GetComponent(MouseLook);//4 _ml.enabled = true; //4 Time.timeScale = 1; //3 menuMode = false; //1 } } if(GUI.Button(optionsRect,"Options")){ optionsMode = true; } if(GUI.Button(quitRect,"Quit")){ Application.Quit(); } }else{ GUI.Label(new Rect(Screen.width / 2, 0, 50, 20),"Options",welcomeLabel); GUI.skin = customSkin; GUI.Label(new Rect(270, 75, 50, 20), "Bullet Impulse"); _bulletImpulse = GUI.HorizontalSlider(new Rect(50, 100, 500, 20), _bulletImpulse,10,700); GUI.Label(new Rect(560, 95, 50, 20), _bulletImpulse.ToString()); GUI.Label(new Rect(270, 125, 50, 20), "Shoot Delay"); _shootDelay = GUI.HorizontalSlider(new Rect(50, 150, 500, 20), _shootDelay,0.1,3); GUI.Label(new Rect(560, 145, 50, 20), _shootDelay.ToString()); if(GUI.Button(new Rect(20, 190, 100, 30), "<< Back")){ optionsMode = false; } } } } // public var welcomeLabel : GUIStyle; public var customSkin : GUISkin; public var playGameRect : Rect; public var optionsRect : Rect; public var quitRect : Rect; private var optionsMode = false; private var menuMode = true; //1 private var gameMode = false; //1 public var _bulletImpulse : float = 300; public var _shootDelay : float = 1; function Awake(){ DontDestroyOnLoad(this); } function OnGUI(){ if (Input.GetKey(KeyCode.Escape)){ //2 menuMode = true; //1 optionsMode = false; Time.timeScale = 0; //3 if(gameMode){ //1 var ml = GameObject.Find("Player").GetComponent(MouseLook); //4 ml.enabled = false; //4 } } if(menuMode){ if(!optionsMode){ GUI.Label(new Rect(Screen.width / 2, 0, 50, 20), "Welcome",welcomeLabel); GUI.skin = customSkin; if(!gameMode){ //1 if(GUI.Button(playGameRect, "Play Game")){ menuMode = false; //1 gameMode = true; //1 Time.timeScale = 1; //3 Application.LoadLevel("Test Scene"); } }else{ if(GUI.Button(playGameRect,"Resume")){ var _ml = GameObject.Find("Player").GetComponent(MouseLook);//4 _ml.enabled = true; //4 Time.timeScale = 1; //3 menuMode = false; //1 } } if(GUI.Button(optionsRect,"Options")){ optionsMode = true; } if(GUI.Button(quitRect,"Quit")){ Application.Quit(); } }else{ GUI.Label(new Rect(Screen.width / 2, 0, 50, 20),"Options",welcomeLabel); GUI.skin = customSkin; GUI.Label(new Rect(270, 75, 50, 20), "Bullet Impulse"); _bulletImpulse = GUI.HorizontalSlider(new Rect(50, 100, 500, 20), _bulletImpulse,10,700); GUI.Label(new Rect(560, 95, 50, 20), _bulletImpulse.ToString()); GUI.Label(new Rect(270, 125, 50, 20), "Shoot Delay"); _shootDelay = GUI.HorizontalSlider(new Rect(50, 150, 500, 20), _shootDelay,0.1,3); GUI.Label(new Rect(560, 145, 50, 20), _shootDelay.ToString()); if(GUI.Button(new Rect(20, 190, 100, 30), "<< Back")){ optionsMode = false; } } } } ゲーム")){ public var welcomeLabel : GUIStyle; public var customSkin : GUISkin; public var playGameRect : Rect; public var optionsRect : Rect; public var quitRect : Rect; private var optionsMode = false; private var menuMode = true; //1 private var gameMode = false; //1 public var _bulletImpulse : float = 300; public var _shootDelay : float = 1; function Awake(){ DontDestroyOnLoad(this); } function OnGUI(){ if (Input.GetKey(KeyCode.Escape)){ //2 menuMode = true; //1 optionsMode = false; Time.timeScale = 0; //3 if(gameMode){ //1 var ml = GameObject.Find("Player").GetComponent(MouseLook); //4 ml.enabled = false; //4 } } if(menuMode){ if(!optionsMode){ GUI.Label(new Rect(Screen.width / 2, 0, 50, 20), "Welcome",welcomeLabel); GUI.skin = customSkin; if(!gameMode){ //1 if(GUI.Button(playGameRect, "Play Game")){ menuMode = false; //1 gameMode = true; //1 Time.timeScale = 1; //3 Application.LoadLevel("Test Scene"); } }else{ if(GUI.Button(playGameRect,"Resume")){ var _ml = GameObject.Find("Player").GetComponent(MouseLook);//4 _ml.enabled = true; //4 Time.timeScale = 1; //3 menuMode = false; //1 } } if(GUI.Button(optionsRect,"Options")){ optionsMode = true; } if(GUI.Button(quitRect,"Quit")){ Application.Quit(); } }else{ GUI.Label(new Rect(Screen.width / 2, 0, 50, 20),"Options",welcomeLabel); GUI.skin = customSkin; GUI.Label(new Rect(270, 75, 50, 20), "Bullet Impulse"); _bulletImpulse = GUI.HorizontalSlider(new Rect(50, 100, 500, 20), _bulletImpulse,10,700); GUI.Label(new Rect(560, 95, 50, 20), _bulletImpulse.ToString()); GUI.Label(new Rect(270, 125, 50, 20), "Shoot Delay"); _shootDelay = GUI.HorizontalSlider(new Rect(50, 150, 500, 20), _shootDelay,0.1,3); GUI.Label(new Rect(560, 145, 50, 20), _shootDelay.ToString()); if(GUI.Button(new Rect(20, 190, 100, 30), "<< Back")){ optionsMode = false; } } } } 


  1. メニューの柔軟性を高めるには、現在の状態を知る必要があります。
  2. Escキーを押してメニューを呼び出す機能をスクリプトに追加します。
  3. ゲーム中にメニューを呼び出すと、一時停止する必要があります。これを行う最も簡単な方法は、 TimeクラスのTimeScale変数をリセットすることです。本質的に、この変数はゲームプロセスの速度を担当します。値1は通常の速度で、1未満の値はmo、1を超える-高速、0-一時停止
  4. さて、実際にスクリプト間の相互作用に到達し、この構造は次のアクションを実行します:GameObjectクラスのFind()クラスは、名前でGOを検索してそれを返し、その後、返されるGO(MouseLookクラスでクラスを見つけるGetComponent()関数が続きます)そしてそれを返し、boolにこのクラス内の有効な変数の値を割り当てます。これにより、MouseLookスクリプトを有効または無効にできます(それぞれtrueとfalse)。 メインメニューに移動したときにプレイヤーが頭を回すことができないように、これらすべての操作が必要です(ゲームを一時停止モードに切り替えても役に立たないため、これらの行をコメントアウトして確認できます)。


6.設定を取得する


最後に、メニューと設定オブジェクトから設定を取得するだけで、フィニッシュラインに到達しました。 Unity3Dチュートリアルのスクリプトを初心者向けに変更する-チュートリアル1
 //public var bulletImpulse = 300; //1 //public var shootSpeed : float = 1; //1 public var bullet : GameObject; public var lastShotTime : float; function Start() { lastShotTime = 0; } function FixedUpdate () { if (Input.GetKey(KeyCode.Mouse0)) { var go : GameObject = GameObject.Find("Menu and settings");//2 var shootSpeed : float = go.GetComponent(MainMenu)._shootDelay;//3 if (Time.time>(lastShotTime + shootSpeed)) { var bulletImpulse : float = go.GetComponent(MainMenu)._bulletImpulse; //3 var bull_clone : GameObject; bull_clone = Instantiate(bullet,transform.position,transform.rotation); Physics.IgnoreCollision(bull_clone.collider, collider); bull_clone.rigidbody.AddForce(transform.forward*bulletImpulse, ForceMode.Impulse); lastShotTime = Time.time; } } } transform.rotation)。 //public var bulletImpulse = 300; //1 //public var shootSpeed : float = 1; //1 public var bullet : GameObject; public var lastShotTime : float; function Start() { lastShotTime = 0; } function FixedUpdate () { if (Input.GetKey(KeyCode.Mouse0)) { var go : GameObject = GameObject.Find("Menu and settings");//2 var shootSpeed : float = go.GetComponent(MainMenu)._shootDelay;//3 if (Time.time>(lastShotTime + shootSpeed)) { var bulletImpulse : float = go.GetComponent(MainMenu)._bulletImpulse; //3 var bull_clone : GameObject; bull_clone = Instantiate(bullet,transform.position,transform.rotation); Physics.IgnoreCollision(bull_clone.collider, collider); bull_clone.rigidbody.AddForce(transform.forward*bulletImpulse, ForceMode.Impulse); lastShotTime = Time.time; } } } 


  1. ここではこれらの変数はもう必要ないので、別のスクリプトから値を取得します。明確にするためにコメントアウトしました。
  2. メニューと設定オブジェクトを取得します。
  3. MainMenuコンポーネントとその変数を受け取ります。

すべて、実行して確認できます。 最も明らかな狂気は、「シュート遅延」オプションを最小限に抑えたときに始まります。マシンガンからの弾丸のように、ボールがプレイヤーから高頻度で飛び出すはずです。 まあ、一般的に、今、あなたはUnityスクリプトの力を所有しているので、あなた自身がそれを理解するでしょう。

おわりに


記事を読んだ後、主にUnityのスクリプトがメインメニューをレンダリングするか、ボールを横向きに転がすためだけに必要であると考えた場合、あなたは深く間違えています。これはほんの一滴です。 彼らはもっと多くのことができます。 たとえば、人工知能をプログラミングしたり、骨格アニメーションを制御したり、最終的に核爆弾を爆発させたりすることができます。これらはすべて、エンジンが提供するものを使用する知識と能力に依存します。 まあ、この記事は、Unityでのスクリプト作成のジャングルをマスターし始めた人々に役立ち、前進するためのインセンティブを与えると思います。

Source: https://habr.com/ru/post/J113859/


All Articles