20201024のUnityに関する記事は4件です。

Unityでのドラッグアンドドロップ

学習記録として、残しておきます。

準備

図のような構成にします。
2020-10-24_21h03_19.png

Script2つ用意

Dragするものに対して

Imageに次のようなスクリプトをあててください。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;

public class Drag : MonoBehaviour, IPointerDownHandler, IBeginDragHandler, IEndDragHandler, IDragHandler
{
    private RectTransform rectTransform;
    private CanvasGroup canvasGroup;

    private void Awake()
    {
        rectTransform = GetComponent<RectTransform>();
        canvasGroup = GetComponent<CanvasGroup>();
    }
    public void OnBeginDrag(PointerEventData eventData)
    {
        canvasGroup.alpha = .6f;
        canvasGroup.blocksRaycasts = false;
    }
    public void OnDrag(PointerEventData eventData)
    {
        rectTransform.anchoredPosition += eventData.delta;//anchoredPositionは中心からの距離
    }
    public void OnEndDrag(PointerEventData eventData)
    {
        canvasGroup.alpha = 1f;
        canvasGroup.blocksRaycasts = true;
    }
}

Dropするものに対して

Image(1)に次のスクリプトをあててください。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;

public class Drop : MonoBehaviour, IDropHandler
{
    public void OnDrop(PointerEventData eventData)
    {
        if (eventData.pointerDrag != null)
        {
            eventData.pointerDrag.GetComponent<RectTransform>().anchoredPosition = GetComponent<RectTransform>().anchoredPosition;
        }
    }

}

最後にすること

Dragされる、Imageに対して、CanvasGroupをつけてください。

これで動きます。

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

Unity The AnimationClip 'xxx' used by the Animation component 'xxx' must be marked as Legacy 対処法

目的

Unityで以下のような警告が出たので、忘れないように記録に残す
「The AnimationClip 'xxx' used by the Animation component 'xxx' must be marked as Legacy」

開発環境

PC:macOS Catalina
エディター:Visual Studio for Mac
Unity:2020.1.7f1

内容

Unityでローディング画面でクルクル回るアニメーションを作成した際に、表題のような警告が出た

解決方法

作成したアニメーションを選択して、inspectorの右側にある三つの点(鍵マークの隣にある)をクリックすると、下記画像のようになります(animationがアタッチされているオブジェクトではなく、animation自体を選択します)

特に何も設定していなければ、Normalにチェックが入っているので、Debugを選択します
すると、inspectorが以下画像のようになります

ここのLegacyにチェックを入れるとタイトルにあるような警告は消えます
そして、DebugをNormalに変更して終了です

参考

https://stackoverflow.com/questions/56166350/the-animation-state-could-not-be-played-because-it-couldnt-be-found

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

UnityからSORACOM Harvestにあるデータをゲットする方法

前回のQiitaの記事
M5StackGRAYのジャイロセンサの値を3G拡張ボードを使ってSORACOM Harvestに送ってみた
で送ったデータを今度はUnityで取得します。



SORACOM Harvestのデータを取得方法については、公式サイトに書かれてます。

$ curl -X GET \
  -H "X-Soracom-API-Key: ${API-KEY}" \
  -H "X-Soracom-Token: ${API-TOKEN}" \
  https://api.soracom.io/v1/subscribers/${IMSI}/data | jq .

普通のエンジニアの方はこれからコードに反映できると思いますが、私はcurl文だけではコード化できない素人なので、すごく悩みました。
ググっても、そのものずばりのコード例が無かったので、結構苦戦しましたが、なんとか以下のやり方で、UnityからHarvestのデータをゲットすることができました。

SORACOMでの対応

SORACOMのAPIリファレンスページを開きます。
https://dev.soracom.io/jp/docs/api/

認証キーかアカウントのメールアドレスを入力し、認証ボタンを押します。
Image from Gyazo

APIキーとトークンが発行されます。
Image from Gyazo

その下は、
日本だけのSIMなら "JAPAN"
グローバルなら "GLOBAL" を選択
Image from Gyazo
※デフォルトがJAPANなのでグローバルSIMの人は注意。私はグローバルSIMだったにも関わらず、そのままにしてたため、ちょっとハマりました。



下にスクロールすると、たくさんのAPIが列挙されてます。
Image from Gyazo

Harvestのデータを取得するには、先程のcurlの例法を見ると、

/subscribers/{imsi}/data

と書いてあったので、同じものを下にスクロールして探してみると、

あった!
Image from Gyazo

ここをクリックすると、
実際にAPIが試せる画面が現れます。

1、 必要最低限 imsiを入力(他の項目は任意)
 ※imsiはユーザーコンソールの該当SIMの「SIM詳細」に書かれてます。
2、 Tri it Out! をクリックします。
Image from Gyazo

こんな画面が現れます。
この画面が現れないと何かが間違ってます。
Image from Gyazo

ここで注目するのが以下の赤線で囲った
curl と Request URL
あとで、Unityのプログラムで使います。
Image from Gyazo

Unityでの対応

動作確認バージョン

Unity 2019.2.21f1

事前準備

UnityでHTTP(GET)通信によるJSONデータ取得するために、
Unityアセットストアから
JSON Object
というアセット をインポートします。

Image from Gyazo

コード

getHarvest.cs
using UnityEngine;
using System.Collections;
using UnityEngine.Networking;

public class getHarvest : MonoBehaviour
{
    private string APIKEY = "APIKEY";
    private string APITOKEN = "APITOKEN";

    void Update()
    {

      //URLは先程soracomのAPIリファレンスサイトで現れたRequestURLを記載 
      StartCoroutine(GetText("https://g.api.soracom.io/v1/subscribers/${IMSI}/data?sort=desc"));
    }


    IEnumerator GetText(string url)
    {
        using (UnityWebRequest www = UnityWebRequest.Get(url))
        {
            //soracomのAPIリファレンスにあるヘッダーの情報を設定する
            //SetRequestHeaderは何個でも書ける
            www.SetRequestHeader("Accept", "application/json");
            www.SetRequestHeader("X-Soracom-API-Key", APIKEY);
            www.SetRequestHeader("X-Soracom-Token", APITOKEN);

            yield return www.SendWebRequest();

            if (www.isNetworkError || www.isHttpError)
              {
                 Debug.Log(www.error);
             }
             else
             {
            // 結果をテキストとして表示
              Debug.Log(www.downloadHandler.text);
             }

        }
     }


}


UnityのHTTP通信について参考にしたサイト



結果

Unityのコンソール画面です。
Harvestに保存されているデータを取得できました。
Image from Gyazo

ただ、これだと、バックスラッシュがついているので、このままではデータを読めません。
前述のコードのGET Text関数にJSONを加工する処理を付け加えました。
JSON形式をいったん文字列に変換し、それからバックスラッシュを削除してからJSONに変換するという方式をとってます。
もっとキレイなやり方があると思いますが、とりあえず、動いたからヨシ!

JSONObject json = new JSONObject(www.downloadHandler.text);
JSONObject content = json[0].GetField("content"); //配列であることに注意

//いったん文字列に変換してバックッシュラッシュを削除する
string content2 = content.str; 
string str = System.Text.RegularExpressions.Regex.Unescape(content2);

//再度JSON形式に変換
JSONObject jsonObj = new JSONObject(str);

float gyroX = jsonObj.GetField("gyroX").n;
float gyroY = jsonObj.GetField("gyroY").n;
float gyroZ = jsonObj.GetField("gyroZ").n;

Debug.Log("gyroX:" + gyroX + "\t gyroY:" + gyroY + "\t gyroZ:" + gyroZ);



このようにHarvestに保存してある各ジャイロデータ(gyroX,gyroY,guroZ)のデータを取得できました。
Image from Gyazo



これを考慮したコードが以下

コード(完成版)

getHarvest.cs
using UnityEngine;
using System.Collections;
using UnityEngine.Networking;

public class getHarvest : MonoBehaviour
{
    private string APIKEY = "APIKEY";
    private string APITOKEN = "APITOKEN";

    void Update()
    {

      //URLはsoracomのAPIリファレンスサイトのRequestURLを記載 
      StartCoroutine(GetText("https://g.api.soracom.io/v1/subscribers/${IMSI}/data?sort=desc"));
    }


    IEnumerator GetText(string url)
    {
        using (UnityWebRequest www = UnityWebRequest.Get(url))
        {
            //さきほどsoracomのAPIリファレンスで現れたヘッダーの情報を設定する
            //ちなみにヘッダーを複数設定する場合は以下のようにSetRequestHeaderは何個でも書ける
            www.SetRequestHeader("Accept", "application/json");
            www.SetRequestHeader("X-Soracom-API-Key", APIKEY);
            www.SetRequestHeader("X-Soracom-Token", APITOKEN);

            yield return www.SendWebRequest();

            if (www.isNetworkError || www.isHttpError)
              {
                 Debug.Log(www.error);
             }
             else
             {
            // 結果を表示
              JSONObject json = new JSONObject(www.downloadHandler.text);
              JSONObject content = json[0].GetField("content"); //配列であることに注意

            //いったん文字列に変換してバックッシュラッシュを削除する
            string content2 = content.str; 
            string str = System.Text.RegularExpressions.Regex.Unescape(content2);

            //再度JSON形式に変換
            JSONObject jsonObj = new JSONObject(str);

            float gyroX = jsonObj.GetField("gyroX").n;
            float gyroY = jsonObj.GetField("gyroY").n;
            float gyroZ = jsonObj.GetField("gyroZ").n;

            Debug.Log("gyroX:" + gyroX + "\t gyroY:" + gyroY + "\t gyroZ:" + gyroZ);

             }

        }
     }


}

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

UnityのAnimationControllerの簡易的な解説

概要

備忘録を兼ねてUnityの AnimationController の使い方を書こうと思いました。
また、VRChatのAvater3.0を理解する上でも、AnimationControllerの設定は必要です。
この記事がわかりにくい場合、参考リンクの動画を見たほうがわかりやすいと思います。

Unityにおけるアニメーション制作の概要

そもそも、Unityではアニメーション制作に使える機能として、下記の機能が用意されてます。

  • C#でプログラミングして、直接Transformの値を制御してアニメーションさせる。
  • アニメーションの内容を記録する機能を持ったAnimationClipを再生する。
    • AnimationClipをAnimationコンポーネントで呼び出す (旧式の機能)
    • AnimationClipをAnimationControllerで呼び出す (現在使われてる機能)
  • TimeLine機能を使う→主に映像制作で使われる機能

この記事で扱うのは AnimationClipAnimationController のみです。
関係性としては AnimationController に再生したい AnimationClip を割り当てて AnimationController から AnimationClip を再生します。
なので、Animation内容であるAnimationClipを作成し、そのClipを呼び出すAnimationControllerの2つの作成と編集が必要になります。(C#のプログラムで動かす場合は、プログラムも必要)
img.png
余談
AnimationControllerみたいに状態の遷移を管理する機能をもったものを一般的に「ステートマシン(状態遷移図)」といったりします。
ステートマシンっていうと堅苦しいですが、自動販売機の仲間とも言えます。
旧式のUnityのAnimationコンポーネントはプログラムからAnimationClipを直接呼び出してました。つまり、AnimationControllerのような振る舞いをするものを自分でプログラムして作成する必要があったわけです。

AnimationClipの作成

img.png

  • AnimationClipを作成したいGameObjectをHierarchy上で選択する。
  • その状態で メニューバーの[Window] > [Animation] > [Animation] を選択する。

img.png

  • Animationのタブが開かれるので [Create] を押して、AnimationClipの名前を付けて保存する。
  • Animationタブで編集が可能になるので、AnimationClipを編集する。

img.png

  • 編集可能な状態

注意点

img.jpg

  • AnimationClipを作成した後に、AnimationさせるGameObjectの名前を変えると動かなくなる。(AnimationClipは名前で紐付けてる)
  • AnimationClipを作成した後に、オブジェクトの階層構造を変えると動かなくなる。(AnimationClip作成時の階層構造を崩しちゃいけない)

AnimationClipの編集

img.png

  • 編集したいAnimationClipに紐付けられれいるGameObjectをHierarchy上で選択する
  • Hierarchy上で対応したObjectを選択しないとAnimationタブが選択可能な状態にならない
  • AnimationClipを新規作成する場合はAnimationタブのCreateNewClipから行う
  • 編集するAnimationClipの変更は左上のドロップダウンを展開する

キーの追加(Animation内容の作成)

【Lecture:20 Unity】Unityでアニメーション!作って再生してみよう!【Beginner】
上記の動画の4:38~がわかりやすいです。(リンクは4:38から再生されます)

AnimationControllerを開いて編集する

img.png
AnimationControllerはAnimationClipを作成した時に、同時に作成されています。
Projectタブのどこにあるのか分からない場合…[AnimationClipを作成したゲームオブジェクトをクリック] > Hierarchyを確認してAnimatorコンポーネントのControllerをダブルクリック > Projectタブ内にあるAnimationControllerがハイライトされる。
Projectタブ内のAnimationControllerをダブルクリックすると、Animatorタブが開いて、AnimationControllerの編集が可能になります。

img.png

  • 上記のような画面が出てくればOK

AnimationControllerのステートとパラメータを設定する

img.png
AnimationControllerを制御するにあたって、パラメータの設定ステートの設定 を行う必要があります。
パラメータとは、ステートの条件に使用する変数です。
ステートとは、AnimationClipを呼び出す順番や呼び出す条件を決めたもの。
関係性としては、Motionの変数が1になった場合…Motionが1の時に遷移するステートが呼び出され、割り当てられたAnimationClipが再生される という関係です。

余談
VRChatのAvater3.0ではユーザーが自由に作成したAnimationControllerを動かすようにするための仕組みが提供されています。
なので、AnimationControllerの仕組みを理解した上で、Avater3.0に必要な設定を行う必要があります。
img.png
パラメータの作成
[Animator]タブを開く > [Parameters]のボタンを押す > [+]のボタンを押す > float,Int,Bool,Trigger から種類を選ぶ > Newのパラメータが作成される。

AnimationClipをControllerに追加する
ProjectタブからAnimationClipをAnimatotタブにドラッグ&ドロップすると、AnimationControllerにClipが追加できる。

追加できるパラメータの種類について
float… 小数点。走る速度が変化するとモーションもだんだん変化してゆくみたいな時に使うイメージ。
int…整数。固定のモーションに切り替えるみたいな時に使うイメージ。
bool…0か1の値。武器を持ってない場合はモーションを変化させないみたいな条件に使うイメージ。
Trigger…スクリプトで有効にした後、AnimationController側で無効にしてくれる。プログラムからは呼び出すだけでいいようにしたい時に使うイメージ。

ステートの作成
img.png
ステートを作成したいクリップを選択した状態で右クリック > [Make Transition]を押す > ステート先のAnimationClipを選択する。
その後、Inspectorからステートの条件設定を行う。

ステートの条件設定
img.png

ステート設定の簡易まとめ

AnimationControllerのオプション 意味
Has Exit Time 有効の場合、前のClipの再生が終わったら自動で再生され Exit Time の条件を満たすと終了。 無効の場合、Conditionsの条件を使って再生開始
Exit Time Has Exit Time が有効の場合、Clipを何%再生したら終了するのか決める 0.75の場合は75%までClipが再生されるとそのステートが終了する。
Fixed Duration 有効の場合、遷移時間は秒単位になる。
Transition Duration ステートが変化するのに要する時間 1秒なら1秒かけて遷移元と遷移先のモーションが合成されて変化する
Transition Offset 遷移先のAnimationClipを再生する位置 0.5の場合、遷移先のAnimationを50%時点から再生する

リファレンス:アニメーション遷移 unity DOCUMENTATION

ステートの設定例
任意のモーションに任意のタイミングで変化させたいような場合はだいたい以下の用になります
1.HasExitTimeのチェックを外す(conditionsが設定できるようになる)
2.conditionsの[+]ボタンを押して項目を追加、ステートの条件にしたいパラメータを選ぶ
3.パラメータに対応した条件設定ができるので条件を設定する

パラメータ Conditionで使える条件
Float Greater(以上) Less(以下)
int Greater(以上) Less(以下) Equals(等しい) Not Equals(等しくない)
Bool true と false
Trigger なし

設定例
img.png
上記の場合、Motionというintのパラメータが 1 になった時に再生される というステートになります。

【余談】C#からAnimationControllerを制御するサンプルプログラム

CubeAnimation.cs
using UnityEngine;

public class CubeAnimation : MonoBehaviour
{
    //操作したいAnimationControllerを持ったGameObjectを割り当てる
    public Animator _animator;
    void Update()
    {
        // Int
        // 押したナンバーキーに対応したポーズを呼び出すイメージ
        if(Input.GetKeyDown(KeyCode.Alpha0))
        {
            _animator.SetInteger("Motion", 0);
        }
        if(Input.GetKeyDown(KeyCode.Alpha1))
        {
            _animator.SetInteger("Motion", 1);
        }       

        // float
        // speed に対応したモーションに変化させるイメージ
        float speed = 0.5f; // プレイヤーの移動スピード
        _animator.SetFloat("Float", speed);

        // Bool
        if(Input.GetKeyDown(KeyCode.B))
        {
            _animator.SetBool("Bool", true);
        } 

        // Trigger
        if(Input.GetKeyDown(KeyCode.T))
        {
            _animator.SetTrigger("Trigger");
        }        
    }

}

Animatorにパラメータを制御する関数が入ってるので、それを使います。
リファレンス:Animator unity DOCUMENTATION

まとめ

他にもAnimationClipではアニメーションカーブが設定できたり、レイヤー機能とか、Controllerのステートとかも色々設定がありますが、おおまかに要点をおさえました。
詳細については参考リンクなども確認してみてください。

参考リンク

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