Upload
takuya-arakawa
View
1.196
Download
1
Embed Size (px)
DESCRIPTION
2014年9月Unity初心者ハンズオンHatchUp様勉強会資料です!
Citation preview
自己紹介
名前:荒川 巧也 Unityの本執筆や専門学校で Unityの授業を担当している 者です。 FAGStudio名義でゲーム制作 にもかかわっています。
執筆した書籍のご紹介
執筆中 2014年 12月末 発売予定
Unity4 ゲームコーディングUnity4入門
Unity4 プログラミング応用
(仮)
アプリやゲーム開発の本がたくさんあります。
ゲーム開発を勉強する時間もお金もない・・
例えば、Unity初心者向け1日社会人講座で2~3万円取られるのは普通です。
Unityが無料で使えるのに、勉強するのに1日数万円かかるのを変えたいなと思ってました。
結果的にやめちゃう人も出てくると思います。
Hatch Up様のハンズオン
その他様々なハンズオン・・
Unityもハンズオンやればいいのにな・・
(Unity本の執筆を通してUnityについての説明の仕方は相当考えてきたな・・)
自分がやろう!!
ということで始めることにしました。 Hatch Up様ありがとうございます!
今後のスケジュール(予定)
9月 3Dアクションゲームを作ってみよう 10月 2Dゲームを作ってみよう 11月 ユニティちゃんを動かそう(Mecanim解説)
12月 UGUIについて !
*実際の内容は参加者の希望で変更になる可能性 になることもあります。
Unityの勉強の進め方プログラミング初心者の方は・・
Unityやる前にC#を勉強しましょう。 (プログラミングの考え方を学ぶためです。)
Unityがなぜ人気なのか?
・個人やサークルレベルでも強力な 開発ツールが「無料」で使える。 !
・Asset Storeという開発を強力に サポートしてくれるインフラが ある。
Unityがなぜ人気なのか?
・非常に使いやすいツール。 ほかのモデル制作ツール などとの相性も良い。 !
・マルチプラットフォーム対応
Unityがなぜ人気なのか?
・ 大きなコミュニティの存在 !
・ ユニティちゃん・・
地面を作ろうHierarchy View → Create → Cylinder
Scene ViewにCylinderが表示されました。 名前を”Floor”にする。
Cylinderの中身を見てみましょう
← 位置、回転、大きさの情報
← あたり判定の情報
← 描画情報
Unityのゲーム作りについて
オブジェクト (GameObject)
位置情報、大きさの情報
当たり判定
物理的な特徴
スクリプト要素
(Component)
オブジェクトに要素を足していきます。
Floorの大きさを変更
Transformは、Position(位置情報)、Rotation(回転)、 Scale(大きさ)の情報を持ってます。
FloorのColliderを変更する
BoxColliderに変更してください。
↓
テクスチャーをFloorに貼ろうテクスチャーはScene Viewから直接貼る方法とHierarchy Viewから貼る方法があります。
Directional Lightを追加する
Directional Lightで太陽の光を再現されます。 Directional LightはPositionは関係ありません。
カメラの位置を調整する
Niwatori(Player)をHierarchy Viewに追加
PlayerにRigidbodyとCapsule Colliderを追加
AddComponent → Physics→Rigidbody
AddComponent → Physics→Capsule Collider
Colliderの大きさ調整
PlayerのTag変更
Tagとはスクリプト上で指定するために使用する ために使用します。
Tagを設定します。
Rigidbodyについて
Unityで重力を実装する際によく使用する「Rigidbody」ですが、日本語で訳すと「剛体」という名前が示すように、鉄の玉が上から下に無風状態で落ちるような自由落下をします。 そのため、風の影響がゲーム要素になるゴルフゲームなどにはRigidbodyは向きません。
PlayerMove.csusing UnityEngine; using System.Collections; !public class PlayerMove : MonoBehaviour { public float speed = 6f; Vector3 movement; Rigidbody playerRigidbody; void Start() { playerRigidbody = GetComponent<Rigidbody>(); ! } void Move (float h, float v) { movement.Set (h, 0f, v); movement = movement.normalized * speed * Time.deltaTime; playerRigidbody.MovePosition (transform.position + movement); } ! void Update(){ if(transform.position.y <-5f) Application.LoadLevel(Application.loadedLevel); } ! void FixedUpdate () { float h = Input.GetAxisRaw ("Horizontal"); float v = Input.GetAxisRaw ("Vertical"); ! Move (h, v); } } !!
Copy&Paste: http://goo.gl/chMQs1
PlayerMove.cs解説
public float speed = 6f;//移動速度 Vector3 movement;//移動方向 Rigidbody playerRigidbody;//Rigidbodyを格納
void Start() { playerRigidbody = GetComponent<Rigidbody>(); ! }
void Start( ){ }で書かれた処理内容については、ゲームを再生してまず始めに1回のみ呼ばれること
になっています。主にそのゲーム設定などを読み込まれることが多いです。
PlayerMove.cs解説playerRigidbody = GetComponent<Rigidbody>(); !!playerRigidbodyという変数にRigidbodyを代入します。GetComponent<>()
はスクリプトを付けられたGameObject自身のコンポーネント(Rigidbody)にアクセスします。
movement = movement.normalized * speed * Time.deltaTime; !Vector3.normalizedは正規化してます。 !Time.deltaTimeは、時間を基準に動作を処理します。
PlayerMove.cs解説
playerRigidbody.MovePosition (transform.position + movement);
rigidbody.MovePosition(Vector3)で物理的に動かします。
PlayerMove.cs解説void FixedUpdate () { float h = Input.GetAxisRaw ("Horizontal"); float v = Input.GetAxisRaw ("Vertical"); ! Move (h, v); }
FixedUpdate(){}は物理的動作などを処理する際に書きます。 !float h = Input.GetAxisRaw ("Horizontal"); float v = Input.GetAxisRaw ("Vertical"); !Input.GetAxisRawは矢印キーで-1~1で入力します。
Playerが転がります。
Playerが転がる理由
Capsule Colliderの形が カプセルの形をしている ためです。
シュールに転がるのを修正する。
RigidbodyのConstraints
のFreeze Rotation x y zに チェックを入れる。
Enemyを追加
Enemyに追加する
RigidbodyとCapsule Collider
を追加する。
Tagを”Enemy”にする。
EnemyにEnemyMove.cs追加
using UnityEngine; using System.Collections; !public class EnemyMove : MonoBehaviour { private GameObject target; public float speed = 10.0f; ! // Use this for initialization void Start () { target = GameObject.FindGameObjectWithTag("Player"); } // Update is called once per frame void FixedUpdate () { Vector3 direction = target.transform.position -transform.position; rigidbody.AddForce(direction.normalized * speed); } } !
Copy&Paste: http://goo.gl/N0swP1
RigidbodyのFreeze Rotationにチェック
EnemyMove.cs解説
target = GameObject.FindGameObjectWithTag("Player"); !GameObject.FindGameObjectWithTagを使うことによりタグでGameObjectを指定します(この場合はPlayer Tag)
Vector3 direction = target.transform.position -transform.position; !targetの位置からEnemyの位置を引いて、移動方向を決定します。
!rigidbody.AddForce(direction.normalized * speed); !rigidbody.AddForce(Vector3)で力で動かします。
追いかけてくるようになりました
(参考) Nav Mesh Agentについて
Add Component → Navigation → Nav Mesh Agent
Unity4.2からFree版でも使えるようになったNavigation機能を使ってもキャラクター追従を実装できます。
(参考) Nav Mesh Agentについて
FloorをStaticにします。 Window → Navigation
<参考>このようになります青くなった部分が行動範囲となります。
(参考) Nav Mesh Agentについて
using UnityEngine; using System.Collections; !public class Navigation : MonoBehaviour { public Transform destination; private NavMeshAgent nav; ! // Use this for initialization void Start () { nav = GetComponent<NavMeshAgent>(); } // Update is called once per frame void Update () { nav.SetDestination(destination.position); } } !
Enemyに追加
<参考> Navigation.csにPlayerを追加
using UnityEngine; using System.Collections; !public class PlayerMove : MonoBehaviour { public float speed = 6f; Vector3 movement; Rigidbody playerRigidbody; void Start() { playerRigidbody = GetComponent<Rigidbody>(); } void Move (float h, float v) { movement.Set (h, 0f, v); movement = movement.normalized * speed * Time.deltaTime; playerRigidbody.MovePosition (transform.position + movement); } ! void Update(){ if(transform.position.y <-5f) Application.LoadLevel(Application.loadedLevel); } void FixedUpdate () { float h = Input.GetAxisRaw ("Horizontal"); float v = Input.GetAxisRaw ("Vertical"); Move (h, v); } !void OnCollisionEnter(Collision col){ if(col.gameObject.tag =="Enemy"){ Application.LoadLevel(Application.loadedLevel); Destroy(gameObject); } } }
PlayerMove.csに追加Hone(Enemy)に当たると消滅するようにします。
Shot.csをPlayerに追加するusing UnityEngine; using System.Collections; !public class Shot : MonoBehaviour { public Vector3 direction ; public GameObject bullet; public float power = 500.0f; private float time; private float interval = 0.5f; // Use this for initialization void Start () { direction = Vector3.forward; } // Update is called once per frame void Update () { time += Time.deltaTime; if(time > interval){ GameObject attack = Instantiate (bullet,transform.position,Quaternion.identity) as GameObject; attack.transform.Translate(direction * 1.5f); attack.rigidbody.AddForce(direction * power); Destroy(attack,3f); time = 0f; } } } !
Copy&Paste: http://goo.gl/4zWirj
Shot.csの解説 void Update () { time += Time.deltaTime; if(time > interval){ GameObject attack = Instantiate (bullet,transform.position,Quaternion.identity) as GameObject; attack.transform.Translate(direction * 1.5f); attack.rigidbody.AddForce(direction * power); Destroy(attack,3f); time = 0f; } } !!!!!!!!!!!!!
time += Time.deltaTime; 時間を計っています。 if(time > interval){ }でintervalは0.5秒以上になった時に{ }内の処理を実行します。 !GameObject attack = Instantiate (bullet,transform.position,Quaternion.identity) as GameObject; Instantiate(生成するGameObject,生成する場所,生成した時の回転)
Bulletを追加する
Create → Sphere !
Rigidbodyも追加してください。
Bulletを追加する
Tagを設定する。
BulletをPrefab化します。
Prefabとは同じGameObjectを生成したり、Componentの情報を調整することができるようになります。
Shot.csにBullet Prefabを設定する
Bulletが飛ぶようになります
EnemyMove.csに追記する
using UnityEngine; using System.Collections; !public class EnemyMove : MonoBehaviour { private GameObject target; public float speed = 10.0f; ! // Use this for initialization void Start () { target = GameObject.FindGameObjectWithTag("Player"); } // Update is called once per frame void FixedUpdate () { Vector3 direction = target.transform.position -transform.position; rigidbody.AddForce(direction.normalized * speed); } ! void OnCollisionEnter(Collision col){ if(col.gameObject.tag == "Bullet"){ Destroy(gameObject); } } } !}
Bulletに当たった時にEnemyが破棄されるようにします。 EnemyMove.csに赤字部分を追記してください。
追記部分の解説
void OnCollisionEnter(Collision col){ if(col.gameObject.tag == "Bullet"){ Destroy(gameObject); } !OnCollisionEnterで衝突した時に処理を実行します。 Destroy(gameObject)でGameObjectを削除します。
OnCollisionEnter OnCollisionExit
OnCollisionStay
EnemyCreatorを追加
空のGameObjectを準備します。空のGameObjectはTransform
以外の情報は持っていません。用途としてはゲームを管理するために利用したりします。
EnemyCreator.csについて
using UnityEngine; using System.Collections; !public class EnemyCreator : MonoBehaviour { public GameObject prefab; public float interval = 3.0f; private float time = 0.0f; ! // Update is called once per frame void Update () { float x = Random.Range(-5.0f,5.0f); float z = Random.Range(-5.0f,5.0f); time += Time.deltaTime; if(time > interval){ transform.position = new Vector3(x,10,z); Instantiate(prefab,transform.position,Quaternion.identity); time = 0.0f; } } } !
Copy&Paste: http://goo.gl/q90aCN
EnemyCreator.csを設定する * Prefab化できたらHierarchy Viewの方は削除してください
Hone(Enemy)が生成されるようになった
Crystalを配置します
CrystalにはCapsule Colliderを追加します。
CrystalにCystal.csを追加
using UnityEngine; using System.Collections; !public class Crystal: MonoBehaviour { ! // Use this for initialization void Start () { } // Update is called once per frame void Update () { transform.Rotate(0,1,0); } ! void OnTriggerEnter(Collider col){ if(col.tag == "Player"){ //Score.score += 10; Destroy(gameObject); ! } ! } !} !
Copy&Paste: http://goo.gl/FzCCws
OnCollisionEnterとOnTriggerEnterの違い
< OnCollisionEnterの場合 > OnCollisionEnterは衝突した時に呼ばれます。物理挙動も発生します。
OnCollisionEnterとOnTriggerEnterの違い
< OnTriggerEnterの場合 > OnTriggerEnterは貫通(侵入)した時に呼ばれます。物理挙動も発生発生しません。 センサーに触れた時に呼ばれるような感覚です。
Scoreを追加する
TransformのPositionは0,0,0です。
Create → GUIText
ScoreにScore.csを追加using UnityEngine; using System.Collections; !public class Score : MonoBehaviour { public static int score; static int highScore; GameObject crystal; // Use this for initialization void Start () { crystal = GameObject.Find("Crystal"); crystal.SetActive(false); highScore = PlayerPrefs.GetInt("highScore",0); } void OnDestroy() { PlayerPrefs.SetInt("highScore",highScore); } // Update is called once per frame void Update () { if(score > highScore) { highScore = score; } guiText.text = "Score :" + score+ "\n HighScore :"+ highScore; if(Score.score >= 10){ crystal.SetActive(true); } } }
Copy&Paste: http://goo.gl/ms2msB
Score.cs解説crystal = GameObject.Find("Crystal"); !Hierarchy Viewから”Crystal”を探して代入しています。 !crystal.SetActive(false); !!!!!!!Crystalを非アクティブにします。 !PlayerPrefs.SetInt("highScore",highScore); スコアを保存します。 !guiText.text = "Score :" + score+ "\n HighScore :"+highScore; スコアを文字列で表示します。score.ToString()と書く方が文法的には良いです。
EnemyMove.csに追記する
using UnityEngine; using System.Collections; !public class EnemyMove : MonoBehaviour { private GameObject target; public float speed = 10.0f; // Use this for initialization void Start () { target = GameObject.FindGameObjectWithTag("Player"); } // Update is called once per frame void FixedUpdate () { Vector3 direction = target.transform.position -transform.position; rigidbody.AddForce(direction.normalized * speed); } ! void OnCollisionEnter(Collision col){ if(col.gameObject.tag == "Bullet"){ Score.score ++; Destroy(gameObject); } } } !
←こちらを追記
完成しました!
この資料やその他Unityについてご質問がある 場合は[email protected] (荒川宛)にご連絡 ください。できるだけわかりやすくご回答します。
今回のゲームはAsset Storeにて配布されている”NightMare”というチュートリアルゲームを参考に初心者向けに編集しました。