20200121のUnityに関する記事は12件です。

オブジェクトのサイズを等倍にしたい

軸の中央の四角をマウスドラッグすれば等倍でサイズ変更することができる
スクリーンショット 2020-01-21 22.25.36.png
スクリーンショット 2020-01-21 22.27.05.png
スクリーンショット 2020-01-21 22.28.52.png

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Unity/C#】コルーチンを自前で動かすためにIEnumeratorについて簡単に調べた

コルーチンを自前で動かしたい

コルーチンはMonoBehaviourを継承していればStartCoroutineで動かすことができます。しかし、MonoBehaviourを継承していなくても使いたい場面は割と多いです、多分。
MonoBehaviourなしでコルーチンを動かす方法は調べるとそれなりに出てきますが、そもそもコルーチンで使われているIEnumeratorとはなんぞ?から始めたい所存です。

IEnumeratorインターフェース?

MSDNを見てみるとシンプルに書かれています。

非ジェネリック コレクションに対する単純な反復処理をサポートします。

IEnumeratorインターフェースは反復処理を実現するためのインターフェースになります。
コルーチンはUnityが反復処理をいい感じに実行してくれてる仕組みというわけですね。

反復処理を作って動かしてみる

とりあえず物は試しということでUnityで適当な反復処理を作ってみます。
わかりやすくデバッグログも出してこんな感じに。

SampleCoroutine.cs
public IEnumerator Coroutine() {
    Debug.Log("Coroutine 1");
    yield return 1;

    Debug.Log("Coroutine 2");
    yield return 2;
}

こいつをこんな感じで動かしてみます

SampleCoroutine.cs
public void Sample() {
    var iEnumerator = Coroutine();
    while (iEnumerator.MoveNext()) {
        Debug.Log($"Coroutine Return {iEnumerator.Current}");
    }
}
Console
Coroutine 1
Coroutine Return 1
Coroutine 2
Coroutine Return 2

おもったよりかんたん!

何をやっているの?

まずは反復処理についてです。何気なく使っているyieldですが、yieldを含むブロックのことをイテレータブロックと言います。
大雑把に説明すると「1回の処理でここまでやってね」というブロックになります。yieldには値を返すreturnと処理を抜けるbreakの2つのキーワードがあります。

次にMoveNextです。これはイテレータを次に進ませます。イテレータが進んだ場合はtrueを返すため、whileを使うとイテレータを全て進めることができます。

Currentは反復処理が返した値を保持しているプロパティです。yield returnで返した値がそのまま入ってくる感じですね。
object型なので色んなものを返せます。

SampleCoroutine.cs
public IEnumerator Coroutine() {
    yield return 1;
    yield return 9.6;
    yield return "ほげえ";
}
Console
Coroutine Return 1
Coroutine Return 9.6
Coroutine Return ほげえ

また、Resetに関してですが、こちらは自前で実装する必要があります(実装してないとNotSupportedExceptionがスローされます)。
単純にIEnumeratorインターフェースで実装した反復処理メソッドをやり直したい場合は対象のメソッドを再び取得して動かします。

SampleCoroutine.cs
public void Sample() {
    var iEnumerator = Coroutine();
    while (iEnumerator.MoveNext()) {
        Debug.Log($"Coroutine Return {iEnumerator.Current}");
    }

    // iEnumerator.Reset();     <- NotSupportedExceptionがスローされる
    iEnumerator = Coroutine();
    while (iEnumerator.MoveNext()) {
        Debug.Log($"Coroutine Return {iEnumerator.Current}");
    }
}

思ったよりシンプル!これならStartCoroutineなしでもなんとかなりそう・・・?

WaitFor関係は更に自前で実装しないとダメ

注意点としてWaitForSecounds等は単純にyield returnしただけではうまくいかないです。
よくあるのがyield return WaitForSecondsでカウントをするコルーチンですが、単純にMoveNextをしただけではできません。
MoveNextは1フレーム毎にイテレータを進めるというイメージが良いと思います。この辺はStartCoroutineがいい感じに処理してくれてる部分です。

反復処理の入れ子をやりたい

反復処理から反復処理を実行するような形にすればできます。実はIEnumeratorインターフェースを調べ始めたきっかけでもあります。

SampleCoroutine.cs
public IEnumerator Coroutine() {
    Debug.Log("Coroutine Start");

    var coroutine2 = Coroutine2();
    while (coroutine2.MoveNext()) {
        yield return coroutine2.Current;
    }
    Debug.Log("Coroutine End");
}

public IEnumerator Coroutine2() {
    Debug.Log("Coroutine2 1");
    yield return 1;

    Debug.Log("Coroutine2 2");
    yield return 2;
}

public void Sample() {
    var iEnumerator = Coroutine();
    while (iEnumerator.MoveNext()) {
        Debug.Log($"Coroutine Return {iEnumerator.Current}");
    }
}
Console
Coroutine Start
Coroutine2 1
Coroutine Return 1
Coroutine2 2
Coroutine Return 2
Coroutine End

おしまい

何気なく使っていたコルーチンとIEnumeratorインターフェースですが、思ったよりシンプルでした。
これでもまだ触りの部分だと思いますが、当初の目的を達成しつつある程度は分かった気がしたのでとりあえずOKとしましょう。

何かあったらコメントください。

参考

++C++; // 未確認飛行 C イテレーター
WisdomSoft 処理の分割(コルーチン)
Qiita:[C#]IEnumeratorとIEnumerableを調べた

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ひたすら回転するオブジェクトを数値入力で制御する

無理して外出しにしなくていいけれど、あとあと変えたいのであればぜひ。

public float Rot_x;
public float Rot_y;
public float Rot_z;

void Update()
{
    transform.Rotate(Rot_x,Rot_y,Rot_z);
}

コンポーネントはこんな感じ
b.png

回っている雰囲気
a.png

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

キー押下でScene再読み込みをする(リロード、リトライ的なもの)

実行ボタンのオンオフがめんどくなってきたら、
カメラなどオブジェクトの存在が一定の物に対して、スクリプトをアタッチしておくと楽チン

実質3行の追加で実装完了

必要なのは下記のとおり

using UnityEngine.SceneManagement;

void Update()
{
    if (Input.GetKey(KeyCode.Return)){
        SceneManager.LoadScene(SceneManager.GetActiveScene().name);
    }
}
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

爆速でunitychanを動かしたい時

  1. unityHubではなく、unity2018などを起動する
  2. プロジェクト新規作成の段階で、アセットのstandardAssetsとunitychanを指定してプロジェクト作成する
  3. 地面を作る
  4. unitychanをプレファブからぶっこむ
  5. アニメーターコントローラーをThirdPersonAnimatorControllerにする e.png
  6. 関係ないやつをオフるf.png
  7. カプセルコライダーをいい感じにする
  8. ThirdPersonCharacterをアタッチして、細かい挙動はあとからいい感じにするg.png
  9. カメラ設定はいろいろやり方があるけれど、とにかく時間短縮命!であれば、MultipurposeCameraRigを入れて、ターゲットをunitychanにすればオケh.png

  10. 設定をする際、画像のようにすればunitychanを定点で見るような感じになりますi.png

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

unitychanでThirdPersonCharacterを入れて壁に埋まった時

unitychanにThirdPersonCharacterを入れて遊んでいるとき、
d.png
こんな感じで埋まってしまったら...
c.png

プロトタイプであれば、とりあえずの緊急コードでその場をしのぎましょう

upup.csとか適当なスクリプトを作ります。
Uキー押下で、上に上昇します。

void Update()
{
    if (Input.GetKey(KeyCode.U)) {
        transform.position += transform.TransformDirection(Vector3.up * 10 * Time.deltaTime);
    }
}
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Unityでオブジェクトを中心にカメラを移動させるスクリプト

スワイプでカメラ移動させたい!!頼む!!

最近Unityの楽しさを知ってからというものの、業務でPHPを使いつつ、家ではがっつりゲーム開発というワケワカメな状況を送っているBuzzです。

今回はそんな初心者ゲーム開発者(仮)の私がボードゲーム(仮)を作成する際、盤面状況の把握方法として盤面を中心としたカメラ移動を画面スワイプで実現したやり方を備忘録として投稿します。そしてあわよくば猛者様の意見を頂戴できればと。

どんなものができたのか

まずは完成形をお見せします。
今回はチェスや将棋、オセロなどの盤面を想定しているのでY方向の回転は無しにしています。(Y方向回転についても後述してます)
なぜ宇宙にタイルが浮いているかは置いといて、この処理をコーディングしていきます。
ダウンロード.gif

Let's コーディング

とりあえずこんなコードになりました。今回はカメラに関する処理なのでファイル名をCameraControllerとして、カメラオブジェクトにアタッチしています。

CameraController.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CameraController : MonoBehaviour
{
    //① START
    GameObject mainCamera;  //カメラ
    GameObject fieldObject; //フィールド(中心としたいオブジェクト、今回は盤面を中心とするためfield)
    public float rotateSpeed = 1.0f; //回転スピード
    //① END

    void Start()
    {
        //② START
        this.mainCamera = Camera.main.gameObject; //カメラオブジェクトを代入
        this.fieldObject = GameObject.Find("Field"); //"Field"に中心としたいオブジェクトをHierarchyの名前から指定
        //② END
    }
    void Update()
    {
        //③ START
        if(Input.GetMouseButton(0))
        {
            rotateCamera();
        }
        //③ END
    }
    //④ START
    private void rotateCamera()
    {
        Vector3 angle = new Vector3(
                Input.GetAxis("Mouse X") * this.rotateSpeed,
                0,
                0
            );
        this.mainCamera.transform.RotateAround(this.fieldObject.transform.position, Vector3.up, angle.x);
    }
    //④ END
}

①カメラ、中心としたいオブジェクト(以降「中心オブジェ」)、回転のスピードをそれぞれ定義し、この時点ではカメラと中心オブジェは空の状態です。

②Start()の中でカメラ(mainCamera)にカメラオブジェクト、中心オブジェ(fieldObject)にFieldオブジェクトを代入しています。

③Update()の中で「もし左クリックを押している間」という条件のもと、rotateCamera()を実行しています。実際これくらいの記述量であればこの中にrotateCameraの中身を書いてもいいかもしれません。

④rotateCamera()を定義しています。Vector3引数にGetAxis関数でX方向に生じた値を取って回転スピード(rotateSpeed)と掛けた値、YとZに関しては今回用はないので0を渡しています。最後にカメラオブジェクトのRotateAround関数でfieldObjectの中心、回転の軸(今回はY)、回転方向(今回はX)とすることで回転を実現しています。

実機で動かす

これで実際にビルドしてスマートフォンで確認してみました。

、、、って、あれ?
なんか挙動がおかしいです。
ダウンロード.gif

すこし見辛いですが、画面をタップするたびに別のアングルにワープするようになってしまいました。
これでは盤面状況の確認時にかなりストレスですよね。。
こんな時はGoogle先生の出番です(最初から出番しかありませんが)

検索すると直前の回転を保持しておくことで解決できそうです。

自然にスクロール編

いろいろ調べた結果、以下に落ち着きました。

CameraController.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CameraController : MonoBehaviour
{
    GameObject mainCamera;
    GameObject fieldObject;
    public float rotateSpeed = 1.0f;
    private Vector3 lastMousePosition; //①追記
    private Vector3 newAngle = new Vector3(0, 0, 0); //②追記
    void Start()
    {
        this.mainCamera = Camera.main.gameObject;
        this.fieldObject = GameObject.Find("Field");
    }
    void Update()
    {   
        //追記 START
        if(Input.GetMouseButtonDown(0)) //③
        {
            newAngle = mainCamera.transform.localEulerAngles; //④
            lastMousePosition = Input.mousePosition; //⑤
        }
        //追記 END
        else if(Input.GetMouseButton(0))
        {
            rotateCamera();
        }
    }

    private void rotateCamera()
    {
        Vector3 angle = new Vector3(
                Input.GetAxis("Mouse X") * this.rotateSpeed,
                0,
                0
            );
        this.mainCamera.transform.RotateAround(this.fieldObject.transform.position, Vector3.up, angle.x);
    }
}

①直前の回転を保持しておくためのVector変数lastMousePositionを定義、最初の時点では空です。

②Vector型変数newAngleにX:0,Y:0,Z:0のVector3インスタンスを代入しています。

③左クリックが押下された際、一回だけ実行されます。

④newAngle変数に相対的な回転地を代入しています。

⑤lastMousePosition変数に左クリックされた際のマウス位置を代入しています。

今度こそ!

これで直前までの回転を保持してくれて、想定通りの動きをしてくれそうです!
ビルドしてみましたー
ダウンロード (1).gif

いい感じ・・・圧倒的いい感じ・・・っ!!!
そんなこんなで初心者が無事、カメラ回転を実装できました。
もっと簡単に実装できる方法などあればコメントお願いします。

おまけ

最後にY方向の回転も追加して終わろうと思います。
これは今あるコードに以下を追加することでチョチョイのチョイのお茶の子さいさいのサイって感じで実装できました。

CameraController.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CameraController : MonoBehaviour
{
    GameObject mainCamera;
    GameObject fieldObject;
    public float rotateSpeed = 1.0f;
    private Vector3 lastMousePosition;
    private Vector3 newAngle = new Vector3(0, 0, 0);
    void Start()
    {
        this.mainCamera = Camera.main.gameObject;
        this.fieldObject = GameObject.Find("Field");
    }
    void Update()
    {
        if(Input.GetMouseButtonDown(0))
        {
            newAngle = mainCamera.transform.localEulerAngles;
            lastMousePosition = Input.mousePosition;
        }
        else if(Input.GetMouseButton(0))
        {
            rotateCamera();
        }
    }

    private void rotateCamera()
    {
        Vector3 angle = new Vector3(
                Input.GetAxis("Mouse X") * this.rotateSpeed,
                Input.GetAxis("Mouse Y") * this.rotateSpeed, //追記
                0
            );
        this.mainCamera.transform.RotateAround(this.fieldObject.transform.position, Vector3.up, angle.x);
        this.mainCamera.transform.RotateAround(this.fieldObject.transform.position, transform.right, angle.y); //追記
    }
}

説明は前述しているので省きますが、以下が実現します。
ダウンロード (1).gif

盤面確認などで使うには裏面まで見る必要はないので、Y方向が一定値以下になったら固定させる処理などを追加する必要がありますね。ですが例えば入手したアイテムなどを眺めるシーンなんかにはそのまま使えそうです。まんもすうれぴー。

参考サイト

非常にお世話になりました。

https://xr-hub.com/archives/6272
https://tech.pjin.jp/blog/2018/09/05/unity_material_color-change/
https://mogi0506.com/uinty-camera-rotation/

少しでもお役に立てればと思います。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

回転させたオブジェクトを水平に動かす方法(ローカルとグローバル)

オブジェクトを回転させた後に、水平移動するとき、ぽちぽちとpositionの値を変えていませんか?
そんなときは下図のように、ローカルとグローバルを切り替えましょう!

【ローカル】
a.png

【グローバル】
b.png

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

unitychanでいきなりエラーが出た(メモ)

using System.Security.Policy;

ここを削除する

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

SteamVR導入後に設定ポップアップがしつこく出るときの対処法メモ

(いつも調べなおすのが大変なのでメモ書き)

何度許してもでてくるこいつがうざい!

Steam VR popup.PNG
いろんな記事で「“Accept All”を押して進んでください。」ってあって、
その通りにするんだけど、事あるごとにこいつがでてきて正直うざい。

ということで、このポップアップを消す方法のメモ書き。

①Asset⇒SteamVR⇒Editorの順に進み
 SteamVR_UnitySettingsWindow.csを開く。

②41行目の
const bool recommended_UnitySprashScreen = false;
 
falseをtrueに書き換える。
VRメモ.PNG
(参考スクリーンショット)

これでもうしつこく許可を乞われることはなくなるはず。
参考ページ(英語):https://stackoverflow.com/questions/41418481/in-unity-how-to-stop-popup-for-show-unity-splashscreen

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Unity】個人用にメソッド拡張してみた(随時更新予定

初めに

プログラミングしていると「なんでこの機能ないんだろ?」とか「この機能が欲しい」ということが度々行ったりするようにいつもなっているのでそろそろ拡張していきたいと思いました。

ダウンロード先

内容説明

基本的にUnityを触っている時に使うことを想定して作っています。
使う場合はusing SKTool.Unityをお忘れなく。

目次(クラス、メソッド名)

ListExtension
   ・RemoveNull()
   ・Allocation(T _add,bool _addFlag=false)

機能説明

ListExtension

RemoveNull()

List内にnullがある場合すべて削除するメソッド。
89ysu-wim00.gif

Allocation(T _add,bool _addFlag=false)

List内にnullがある場合そのnullに割り当てる、nullがない場合なにもしない。_addFlagがtrueであれば要素内にnullがない場合Addします。
2dkxn-hbh4r.gif    nymrz-q5q2f.gif

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

macOS Catalina + Unity 2019.3でAndroidビルド(IL2CPP)に失敗する場合の対処

概要

macOS Catalina + Unity 2019.3でAndroidビルド(IL2CPP)に失敗したので対処のメモを残しておく。

何が起きたか

IL2CPPでAndroid向けビルドをした時に、以下のエラーが発生。

Failed running /Applications/Unity/Hub/Editor/2019.3.0f5/Unity.app/Contents/il2cpp/build/deploy/il2cppcore/il2cppcore.dll (以下略)

原因(おそらく)

Android NDK を手動でインストールしたことにより、macOS Catalinaの強力すぎるセキュリティに引っかかってコマンドを実行できなかった。

対処方法

UnityHubからAndroid NDK をインストールする。(SDKも一緒にインストールされるが)
PreferenceからNDKのパスを設定することを忘れないこと。

環境

Mac OS 10.15.2
Unity 2019.3.0f5

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む