システム習熟はトライアンドエラーで使ってみる時間が長ければ長いほど進みますね。
//tips
//Generate Mip Mapとは
Unity の説明によると、
「ミップマップは革新的に小さなバージョンの画像リストで、リアルタイム 3D エンジンのパフォーマンスを最適化するために使用されます。カメラから離れたオブジェクトは、小さなバージョンのテクスチャを使用します。ミップマップを使用すると、33% 多くメモリを使用しますが、使用しないとパフォーマンスが大幅に低下する可能性があります。ゲーム内 テクスチャ には常にミップマップを使用します。GUI テクスチャ、スカイボックス、カーソル、クッキーなどの元々小さく作成されているテクスチャだけは例外です。 ミップマップは、様々なテクスチャエイリアシングやちらつきを避けるためにも不可欠です。」
とのことで、簡単にいうと、カメラが遠のき、被写体の写りが小さくなった際に、被写体の描画を見やすくするために生成するもので、各段階ごとの小ささの被写体カメラ写りを生成してくれる。
https://docs.unity3d.com/ja/2018.4/Manual/ImportingTextures.html#Mipmaps
https://docs.unity3d.com/ja/2018.4/Manual/class-TextureImporter.html
基本的に3Dプロジェクトに用いられる。
//Main CameraのSize
Main CameraのSizeはカメラの写す範囲を表しており、sizeの数値を小さくすればするほど、被写体をアップして写すようになる。
画面から遠ざけたいときは数値が大きくなる。
//blockの配置の簡略化
GitHubからDuplicate special for Unityをダウンロードし、スクリプトをプロジェクトにドラッグアンドドロップするだけで上部に表示されるpluginsから一気にオブジェクトの複製が行えるようになる。
使用時には複製したいオブジェクトをヒエラルキー上で事前に選択しておく必要がある。
https://github.com/riperjack/unity_duplicate_special
//色付きのcubeを作成したい場合
初期段階のCubeのインスペクター上から色を変更することができないので、自分の好きな色をプロジェクトでMaterialとして作成し、読み込ませる必要がある。
プロジェクト下のCreate→Materialから新しいマテリアルを作成し、色の部分を自分の好みに変更し、そのmaterialをオブジェクトにアタッチする。
変更時は外側の円の配色ではなく、四角内部の色を指定して初めて反映されるので設定を気を付ける。
//UnityのオブジェクトへのLightingに苦戦したときの対処方法
UnityのオブジェクトへのLightingに苦戦したときにはWindow→Rendering→Lighting Settingsを選び、Auto Generateをチェックするだけで理想的なライト設定になる。
ただ、シーンによってライトを使い分けたいときには自分でチェックを外し、カスタマイズする必要がある。
https://qiita.com/Nekomasu/items/8845d076c4356809f0ff
https://docs.unity3d.com/ja/2018.4/Manual/class-Light.html
//頂点スナップモードでフィールド上のオブジェクトをきれいに整列させる
3Dになってくるとオブジェクト同士の配置も格段に難しくなる。
きれいにオブジェクトを配置するためにはヒエラルキーでオブジェクトを選択し、Shift+Vキー(mac)で頂点スナップモードを起動し、頂点に表示される小さな四角をドラッグすることで目標の位置に自動で綺麗に配置することができる。
https://unity-shoshinsha.biz/archives/tag/%E9%A0%82%E7%82%B9%E3%82%B9%E3%83%8A%E3%83%83%E3%83%97
//sceneビュー上でのオブジェクトの消去
不要なブロックをsceneビュー上で消去したい場合には、command+backspace(macbook)を押すことでビュー上で削除できる。
さらに、commandで複数オブジェクトを選択することで一度に不要なオブジェクトを削除することができる。
//スクリプトでキューブ複数生成
キューブを複数生成するGameManagerスクリプトをemptyオブジェクトにアタッチし、prefab化したキューブを一気に生成する。
GameManagerスクリプトは以下を作成。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GameManager : MonoBehaviour
{
public GameObject prefab;
void Start()
{
for (int i = 0; i < 10; i++)
{
Instantiate(prefab, new Vector3(i, 0, 0), Quaternion.identity);
}
}
}
さらに10*10の床を作りたい場合は、forを2重にかければよいので以下になる。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GameManager : MonoBehaviour
{
public GameObject prefab;
void Start()
{
for (int i = 0; i < 10; i++)
{
for(int z=0; z < 10; z++)
Instantiate(prefab, new Vector3(i, 0, z), Quaternion.identity);
}
}
}
ただ、スクリプトで作成してしまうと、アプリ実行時にしか表示されないという欠点がある。
また、別のオブジェクトのy座標の登場位置には気を配る必要があり、重ねて表示してしまうとkinematicに設定していない方のオブジェクトが変な圧力をうけ、跳ね上がってしまう。
//Rigidbody使用時のゲームオブジェクトの角度固定
ゲームオブジェクトを画面上で回転させたくない場合は、RigidbodyのconstraintsでFreeze Rotation Zにチェックを入れる。
Z軸をフリーズさせるということにより、現在の画像が重力の影響で、時計回りや反時計回りに回転することを防ぐことができる。
穴に落ちるとき、前のめりになり、下を向くのではなく、前を向いたまま落ちることになる。
//Colliderのoffsetの理解
プレイヤーにColliderをアタッチして、Colliderのサイズを変更することもあるが、同時にOffsetも理解しておくと役に立つ。
Offsetとは、Colliderの範囲をずらすことができるもので、y=0.7を入れると、0.7マス分上に接触判定範囲が移動する。特に足回りの調整の時に知っておくと便利である。
//CanvasUIを利用したButtonsの設定
操作ボタンの設定は重要なので再度流れを記載する。
まずUIからCanvasを選択し、Order in Layerを最前面、scale with screen sizeを選び、reference resolutionをスマホのサイズに合わせる。
複数のボタンを設置する場合は、canvas下にemptyオブジェクトでButtonsを作成し、ButtonsにUIのButtonからLeft Buttonから作成。
このオブジェクトになっているため、Anchorが使え、画面左下が基準となるように設置できる。あとはButton内にあるイメージコンポーネントから画像を設定できる。
Right Buttonは先のボタンの複製およびz軸への180度回転で作成できる。
//RigidbodyのAddForceをInput.GetAxisで操作する
Maincameraをplayerの子に設定し、追従させるようにした後に、AddForceを使用してスクリプト生成したブロックの上を移動させる。
この際、Freeze rotationはx,y,z軸で設定し、回転させないようにする。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerManager : MonoBehaviour
{
public float speed = 10.0f;
public Rigidbody rb;
void Start()
{
rb = GetComponent<Rigidbody>();
}
void FixedUpdate()
{
float x = Input.GetAxis("Horizontal") * speed;
float z = Input.GetAxis("Vertical") * speed;
rb.AddForce(x, 0, z);
}
}
最初にRigidbodyのアクセスを取得し、GetAxisでキーボードの矢印のクリックを取得し、移動スピードとして変数x,zに代入し、Rigidbodyが付与されたオブジェクトに与える力として、x,zを使用している。
//UpdateとFixedUpdateの使い分け
UpdateとFixedUpdateには明確な違いがあり、
Updateは1フレームごとに中身を呼び出す関数、
FixedUpdateは、フレームに関わらず、一定間隔で中身を呼び出す関数、
という違いがある。
Update関数内では、Rigidbodyは使用されず、その理由は機種ごとのfpsの違いで動きのラグが発生してしまうことにある。
逆に、FixedUpdateではフレーム内で呼び出し処理を行うInputを使用しない方がよく、複数フレームにまたぐFixedUpdateでは必ずしもInputの入力が拾われるとは限らないからである。
下記に参考を記載する。
http://mediamonster.blog.fc2.com/blog-entry-22.html
//Rigidbodyを使わずにplayerの位置を操作する
Vector3とtransform.positionをうまく使い場所移動を行わせる。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerManager2 : MonoBehaviour
{
Vector3 MOVEX = new Vector3(1.0f, 0, 0); // x軸方向に1マス移動するときの距離
Vector3 MOVEZ = new Vector3(0, 0, 1.0f); // z軸方向に1マス移動するときの距離
float step = 2f; // 移動速度
Vector3 target; // 入力受付時、移動後の位置を算出して保存
Vector3 prevPos; // 何らかの理由で移動できなかった場合、元の位置に戻すため移動前の位置を保存
// Use this for initialization
void Start()
{
target = transform.position;
}
// Update is called once per frame
void Update()
{
// ① 移動中かどうかの判定。移動中でなければ入力を受付
if (transform.position == target)
{
SetTargetPosition();
}
Move();
}
// ② 入力に応じて移動後の位置を算出
void SetTargetPosition()
{
prevPos = target;
if (Input.GetKey(KeyCode.RightArrow))
{
target = transform.position + MOVEX;
return;
}
if (Input.GetKey(KeyCode.LeftArrow))
{
target = transform.position - MOVEX;
return;
}
if (Input.GetKey(KeyCode.UpArrow))
{
target = transform.position + MOVEZ;
return;
}
if (Input.GetKey(KeyCode.DownArrow))
{
target = transform.position - MOVEZ;
return;
}
}
// ③ 目的地へ移動する
void Move()
{
transform.position = Vector3.MoveTowards(transform.position, target, step * Time.deltaTime);
}
}
Vector3.MoveTowards は「現在地」から「目的地」まで「一定速度」で移動させてくれる関数で、引数の “current” に現在地、”target” に目的地、”maxDistanceDelta” に1フレームの最大移動距離(=速度)を指定することで目的地まで移動させることができる。
https://docs.unity3d.com/jp/current/ScriptReference/Vector3.MoveTowards.html