【Unity】アニメーションクリップ(人型)をスクリプトで作成する

今回は人型キャラのアニメーションクリップをスクリプトで作成する方法を紹介したいと思います。

使い方としてはゲーム上で動くキャラを録画するのではなくモーションとしてアニメーションクリップにしたいだったり、モーションキャプチャーをゲーム上で行いそのデータでアニメーションクリップを作成したいなどを想定しています。

 

まず作成するにあたりクリップに必要な情報はなにか知る必要があります。

その情報とは

どのオブジェクトどの時間にどんななのか

ということです。

たとえば1秒の手の動かすアニメーションでは

(オブジェクト)のlocalPosition.x(何)が0秒(時間)に(値)

(オブジェクト)のlocalPosition.x(何)が1秒(時間)に(値)

という情報があればlocalPosition.xをうごかすアニメーションに必要な情報は取得完了ということになります。ここではlocalPosition.xだけで例を出しましたが、他の値も動かしたいのであれば他の値もそれぞれ取得します。

 

上記の情報を格納するものを

AnimationCurve(アニメーションカーブ)といいます。

そしてこのアニメーションカーブのなかのどの時間にどんなの部分を

keyframe(キーフレーム)といいます。

 

これをUnity上で見ると

f:id:graphicalpoxy:20190615152525p:plain

こんなかんじで

赤枠AnimationCurve(アニメーションカーブ)

青枠keyframe(キーフレーム)になります。

アニメーションカーブにキーフレームをどんどん足していくと一つの要素のアニメーションが完成します。

公式では

AnimationCurve 時間の経過をとおして評価される Keyframes の集合を保存します。 

keyframe アニメーションカーブでの単一のキーフレームです。

図があるとなるほどとなりますよね。

ということで知識が充実してきたところでスクリプトの例を出して終わりたいと思います。

詳しい情報はスクリプトに書きますね。

 

 

 

スクリプト作成

 

今回のスクリプトでは適当な値で1秒のアニメーションを作っています。

using System.Collections.Generic;
using UnityEditor;
using UnityEngine;

public class animetest : MonoBehaviour
{
    private AnimationClip _clip;
    private Animator _animator;

    [SerializeField]
    private Transform _unitychan;
    private Transform _leftHand;

    private string _path;
    private AnimationCurve handPosXCurve;
    private AnimationCurve handPosYCurve;
    private List<Keyframe> keyframesPosX;
    private List<Keyframe> keyframesPosY;

    void Start()
    {
        _animator = _unitychan.GetComponent<Animator>();
        _leftHand = _animator.GetBoneTransform(HumanBodyBones.LeftHand);
        _path = FindPath();
        handPosXCurve = new AnimationCurve();
        handPosYCurve = new AnimationCurve();

        SetKeyframes();
        AddKeyframe();
        FindPath();
        SetAnimationCurve();
        ClipSave();
    }

    // keyframeの作成.
    // keyframe(float time, float value)
    // 値は適当です
    private void SetKeyframes()
    {
        keyframesPosX.Add(new Keyframe(0, 0));
        keyframesPosX.Add(new Keyframe(1, 1));
        keyframesPosY.Add(new Keyframe(0, 2));
        keyframesPosY.Add(new Keyframe(1, 3));
    }

    // CurveにKeyframeを追加.
    private void AddKeyframe()
    {
        for (var i = 0; i < keyframesPosX.Count; i++)
        {
            handPosXCurve.AddKey(keyframesPosX[i]);
        }
        for (var i = 0; i < keyframesPosY.Count; i++)
        {
            handPosYCurve.AddKey(keyframesPosY[i]);
        }
    }

    // 適応するオブジェクトのパス検索.
    private string FindPath()
    {
        string objectPath = _leftHand.name;

        Transform parent = _leftHand.parent;

        while (parent != null)
        {
            objectPath = parent.name + "/" + objectPath;
            parent = parent.parent;
        }

        return objectPath;
    }

    // アニメーションクリップの作成.
    // SetCurve(動かしたいオブジェクトパス,タイプ,プロパティ,AnimationCurve)
    private void SetAnimationCurve()
    {
        _clip.SetCurve(_path, typeof(Transform), "localPosition.x", handPosXCurve);
        _clip.SetCurve(_path, typeof(Transform), "localPosition.y", handPosYCurve);
    }

    // 保存(UnityEditorのみの動作).
    private void ClipSave()
    {
        AssetDatabase.CreateAsset(_clip, "Assets/CreateAnime");
        AssetDatabase.Refresh();
    }
}

 

間違っていたらすいません。たぶんなんかわすれたけど最後にないかつけないと滑らかに動かないような気が・・・

一応確認のためにクリップをほぞんできるようにしています。エディター上でだけですけどね。

 

今回は左手を動かすというパターンを作りましたが、これを基盤につくれば全身でできます。またキーフレームも最低限しか用意していませんがたくさんつくるといい感じになります。

モーションキャプチャー中にキーフレームを作成しまくって、これでくりっぷを作成するとすばらしいアニメーションが出来ることでしょう。

【Unity】人型キャラクターの構成要素について(キャラクターのパーツのTransformを取得する)

Unityにおいて変数を知ることは熟練度を上げることや、思ったことを再現することに非常に重要な要素だと最近思っています。

 

今回はUnityの公式アセット、Unity-chanを使いながら人型キャラクターについて軽めに説明します。

別にこれがわからないとキャラクターをうごかせない訳ではないのですが、知っておくとキャラクターの情報を取得するときに使えるかもしれません。またキャラクターのアニメーションクリップを作成するときや、一部分のパーツだけ動かしたいときなどは知っていることが必須の項目になります。

 

ユニティちゃんは一つのオブジェクトとして存在していますが中身は腕や脚・頭、詳しくみると手や足などこんな感じに細かく要素に分かれています。

f:id:graphicalpoxy:20190615130413p:plain

たとえばもしユニティちゃんの脚だけ動かしたいとなった場合は

f:id:graphicalpoxy:20190615131414p:plain

このようにCharacter1_LeftUpLegのローテーションをいじると脚だけを動かすことができます。

アニメーションはこのように各要素の数値を時間ごとに記録させ、それを再生させることで決まったモーションで動かしています。

したがってこの要素を理解し、数値を取得できるようになるとアニメーションクリップも作成できます。

 

ちなみにポジションを動かすと・・・

f:id:graphicalpoxy:20190615131652p:plain

あー!僕達のアイドルユニティちゃんの脚がああああ!

となります。

 

 

ではこの要素ってどうすれば取得できるのでしょうか?

毎回getfindしたりpublicで設定するのって非常にめんどくさいですよね。


Unity上ではこの要素についてHumanBodyBonesとして定義されています。

要素の詳細は公式のマニュアルにありますので参考にしてみてください。

docs.unity3d.com

 

どうやって使うかなのですが、実際にユニティちゃんの左脚の情報を取得するスクリプトで説明します。

using UnityEngine;

public class test : MonoBehaviour
{
    // キャラクターのオブジェクト.
    [SerializeField]
    private Transform _unitychan;
    //左脚
    private Transform _leftUpperLeg;
    // アニメーターから抜き出すため.
    private Animator animator;

    // Start is called before the first frame update
    void Start()
    {
        // キャラクターからアニメーションを取り出す.
        animator = _unitychan.GetComponent<Animator>();
        // GetBoneTransform(HumanBodyBones.”要素名”)transformを取得可能.
        _leftUpperLeg = animator.GetBoneTransform(HumanBodyBones.LeftUpperLeg);
    }

    // Update is called once per frame
    void Update()
    {
        // ポジション.
        Debug.Log(_leftUpperLeg.localPosition.x.ToString());
        Debug.Log(_leftUpperLeg.localPosition.y.ToString());
        Debug.Log(_leftUpperLeg.localPosition.z.ToString());
        // 回転(オイラー角に変換して見やすくしています).
        Debug.Log(_leftUpperLeg.localRotation.eulerAngles);
        // スケール.
        Debug.Log(_leftUpperLeg.localScale);
    }
}

 

このような手法で取得できます。

実際に実行すると

f:id:graphicalpoxy:20190615140258p:plain

このようにきちんとTransformの情報を取得できていることがわかると思います。

 

次回はこれを基礎としてアニメーションクリップを作成する方法を紹介できたらなと思います。

【Unity】C#のインターフェース機能について

インターフェース機能について勉強したので備忘録的な感じでまとめたいと思います。

特にスクリプトを作ったわけではないので他の誰かが記事にされているもので詳しくは説明ということで概念的なことで行きたいと思います。

今後自分でスクリプトを作成したら差し替えますね。

 

まずインターフェース機能があるとどんな良いことがあるかを例を使って説明したいと思います。

メリットはずばり汎用性です!

あなたがSHARP製のテレビの4チャンネルにリモコン変えたいという場合で説明したいと思います。

登場人物は

・あなた

SHARP製リモコン

だとします。それぞれの動き関数として記述すると通常だと

 

あなた

SHARP製リモコンの4を押す

SHARP製リモコン

・4が押されたらSHARP製テレビに4にしろと命令する

 

 

まぁ別にこれはこれでいいのですが仮にあなたがSONY製に買い換えたとします。

するとあなたには4chにしたいときにはSHARP製のリモコンの4を押すことしか知らないのでSONY製のチャンネルを変えることはできません。

したがってSHARP製リモコンの4を押すという関数をSONY製リモコンの4を押すという関数に変えなければならないですよね。

 

また長期旅行とかにいってホテルを転々としていたとしたらいろんなメーカーテレビがあるので各メーカのリモコンの4を押すという関数をたくさん作らないといけませんよね。それってめんどくさいですよね。

 

そこでインターフェースという機能が役に立ちます。

インターフェースを使うとあなたの関数はリモコンの4を押すということだけをします。どこ製でもいいのでリモコンの4を押すそれだけをします。

するとどうでしょう?どこ製であっても関数を変えずに4chに変えることができます。

つまり汎用性が増すということにつながります。

わかりにくかったらすいません、でもこういうことだと思ってます。

詳しいことや、実装の仕方に関しては説明しませんが、どういうメリットがあるかがわかってもらえたらうれしいです。

 

 

 

記事で言うとここらへんが見るとわかりやすいです。

下の記事のほうはUnityでのスクリプト付きで解説しててわかりやすいですよ。

 

ufcpp.net

 

qiita.com

 

 

 

エンジニアの常識(個人開発だけじゃわからなかった!)

2019年に突入してunityを触り始め、これはいけると思いいわゆる大企業を辞めて転職をしました。

6月から新たな職場にいるのですが、やはり個人で開発するのとは全然違っているなと一週間働いただけで実感させられます。

 

今現在で思ったことを箇条書きしてみます。

私と同じようなことを考えている人の参考になればいいなと思います。

 

  • わかりやすくコード書く!

たぶんエンジニアの方にとっては常識でしょうが、個人でやっていて歴も浅いとこういうところに意識の違いを感じます。

とにかく誰が見てもわかりやすいような命名や書き方をする、ということですね。

個人では自分がわかればいいわけで、好き勝手に名前をつけて好き勝手に思いついたものを書いていたのですが、現場のコードは見やすかったです。

当たり前ですが、大人数で機能ごとに開発するわけですから全員が把握するのは難しいです。なのでこういう命名や書き方は判りやすくする必要があるわけですよね。

まぁ自分で作ったコードも数ヶ月した後見直すとよくわからないときがあるのでわかりやすくしておくに越したことはないですよね。

自作したゲームでいうと、マシンガンで攻撃するスクリプトがあったとき、MG()という関数を私は作りました。

しかしながら他の人がみるとMG()って何ってなりますよね、、、改良するならばAttackWithMachineGun()とかMachineGunFire()とかですかね。ながくなってもわかりやすくが味噌らしいです。

ちなみに私はリーダブルコードという本でそういうことを学んでいます。

 

 

  • 拡張性を意識する

これは純粋に関心したのですが、機能の拡張を意識してコードを書いているという点です。

言葉で説明するのが非常に難しいのですが、そういうことです笑

簡単に言うと攻撃力5の攻撃1と攻撃力10の攻撃2の方法があった場合それぞれで

hp-=5とhp-=10ってそれぞれ書くよりも

HPdecrease(int AttackPower){

hp -= AttackPower

って関数をつくるとこれから先攻撃力が変わったとしてもこのHPdecreaseという関数を使うといつでも対応できますよね?それが簡単に言うと拡張性です。

こういったことをいたるところで感じます。UI関連などはボタンが今後追加されるかもしれないとかを意識して作りこまれているなと感じました。

 

まぁいまはこんな感じですが、今後初心者目線で思うことがあったらどんどん記事にしていきたいと思います。

記事もたくさん書いてはいるんですがなんか重力の奴しかみられてない・・・

 

株式投資年間成績(2018.5~2019.5)

6月から新たな職場でプログラマー人生をスタートさせるのですが転職までの間、2週間ほどデイトレを行っていました。デイトレの結果はよくなかったです。。。。

 

去年5月から国内株式投資を行い1年経過したため結果を一応まとめておこうと思います。

 

400,000(現時点入金総額)→474,439(+74439)

 

年間で振り返ると、前半の6ヶ月と後半の6ヶ月で立ち振る舞いがちがっています。

 

前半6ヶ月

最初の投入資金は20万で、株に関する知識はゼロでした。

高齢化だから介護系は伸びるでしょみたいな感覚でニプロを購入し、まんまと高値掴み・・・

また資金も時々引き出していたので徐々に減っていくかんじでした。

 

後半6ヶ月

ボーナスが入ったので資金を追加し種を50万として運用開始。

レンジ相場にうすうす気づいてロゼッタで遊んでいたら好決算が出てきたため一気に利益に転じる。

ここからはいろいろバリュー系の知識を覚えていき新興系でちょくちょく利益を出すことができました。

GW後に大きく損失を出しついに損切りを覚えました。

これかもがんばっていきます。

 

【Unity】Unityで発光の制御(PostProcess・bloomをスクリプトで制御)

EDMのライブのような演出がしたいなぁと思って今いろいろと作成しています。

ライブといったら曲に合わせた光の演出は欠かせないですよね。

今回は曲に合わせたという部分は一旦置いといて(次回書いていこうと思います)光の演出について書こうと思います。

 

光の演出といってもいろいろあるのですが、私が実現したかったのは音の大きさによってオブジェクトの発光の強さを動的に制御していきたいというものです。

イメージで言うとネオン看板の光の強さをゲームプレイ中に変えていくみたいなものです。

今回もさまざまな方が詳しい記事を書かれているのでわかりやすかった記事をかいつまんでいきます。

 

(下準備)

 

まず今回やることをわかりやすくするために環境をつくって置いたほうがいいと思います。

メインカメラのBackgroundを黒に変更

DirectionalLightを非アクティブに変更

しておくと良いと思います。

他作業中だったのでいろいろあるアセットとかオブジェクトは無視してください

f:id:graphicalpoxy:20190429133140p:plain

 

オブジェクトを光らせる

 

オブジェクトを光らせるといったらこれを読めばだいたいわかる!

特に光のにじみとHDRの部分以下は読んでおくと良いです。

tsubakit1.hateblo.jp

 

余計なことは呪文だと思って簡単にどうすれば光らせることができるかというと

  • オブジェクト付けるのマテリアルにEmissionをチェック

f:id:graphicalpoxy:20190429134529p:plain

 

とりあえずこれで発光はするのですが・・・思ってたのと違いますよね

 

そこでカメラの効果であるBloom効果というのをつけて(後述します)

Intensityという値をいじるといい感じでもやができて発光感が一気に増します。

Bloom効果のありなしの比較画像を作ったので載せておきます。

とりあえずここでは光らせたいオブジェクトのマテリアルにEmissionのチェックをして置いてください。

f:id:graphicalpoxy:20190429135013p:plain

 

 

Bloom効果をPostProcessingでつける

おそらくBloom効果をカメラに付ける場合はほとんどの場合StandardAssetのEffectから行っていることが多いと思います。

しかしここではちょっと新しいものを使ってみたいと思います。

PostProcessingです。これを選んだ心としましては、新しくて他にもいろいろと効果をつけることができるのでこっちのほうがこれから役に立つかなと思いましたのでこれを使ってみました。

 

PostProcessingを使うには新たにインストールしないといけません。

はい、ここに記載されていることをすべてやってください笑

qiita.com

私もいろいろ調べて実装させていっているのですがこの記事が一番だと思います。

 

おそらくインストールして

  • カメラにPostProcessLayer
  • 空のオブジェクトにPostProcessVolume

がアタッチされた状態になったと思います。

次に

PostProcessVolumeのAdd effectからBloomを選択

Intensityにチェック、数値をいじる

 

f:id:graphicalpoxy:20190429140558p:plain

すると発光の強さを変更できることを確認できたと思います。

つまりこのIntensityの値をスクリプトから動かすことが出来ればゲーム内で動的に発光の強さを変更できるということです。

 

 

 

スクリプトでPostProcess・BloomのIntensityを変更する

 

正直ここからが本題です。

なぜかというとGetComponent<PostProcessVolume>でいじれないからです。

これが出来ればどんなに時間をつぶさずに済んだか・・・

ただすごく簡単だったのでみなさんは私の3時間ぐらいを3分で越えていってください。

今回もスクリプトを例として載せるのですがとにもかくにもおまじないが多いので気をつけてください。

今回は左クリックで明るく、右クリックで暗くするスクリプトです。

こちらをPostProcessVolumeのついたオブジェクトに付けてください。

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//ここ必須
using UnityEngine.Rendering.PostProcessing;

public class EmissionTest : MonoBehaviour
{
    Bloom bloom;

    // Start is called before the first frame update
    void Start()
    {
        //おまじない1:Bloomのところを変えると他の効果でも応用化
        bloom = ScriptableObject.CreateInstance<Bloom>();
    }

    // Update is called once per frame
    void Update()
    {

        //左クリック
       if (Input.GetMouseButton(0))
        {
            set();
        }
       //右クリック
        if (Input.GetMouseButton(1))
        {
            setback();
        }
    }
    //発光(強)関数
    private void set()
    {
        //おまじない2:書き換えOKにしている?これがないと何度も変更できない
        bloom.enabled.Override(true);
        //変更したい項目に任意の数値を渡す
        bloom.intensity.Override(10f);
        //おまじない3:QuickVolume(PostProcessのレイヤー番号,Priority,効果)
        PostProcessManager.instance.QuickVolume(gameObject.layer, 1, bloom);
    }
    //発光(弱)関数(略)
    private void setback()
    {
        bloom.enabled.Override(true);
        bloom.intensity.Override(1f);
        PostProcessManager.instance.QuickVolume(gameObject.layer, 1, bloom);
    }
}

 

まず要点だけ説明すると

  • using UnityEngine.Rendering.PostProcessingは必須

そういうものだと覚えてください、おまじないとは別ですね。

  • おまじない1

bloom = ScriptableObject.CreateInstance<Bloom>();

GetCompornentとしたいところですが、上記のようにするらしいです。

  • おまじない2

bloom.enabled.Override(true);

これを入れないと何度も変更することが出来ませんでした。

個人的には書き換えOKにしているのかなと思っています。

書き換えるごとに書き換えNGになるからこの文言をいれないといけないのかなと

  • おまじない3

一番よくわからない、ないと動かなかった

QuickVolume(PostProcessのレイヤー番号,Priority,効果)

Priorityは1にしとけばうごく

 

  • (書き換えは関数にする?)

ここは私だけの問題だと思うのですが、Update内で今回の関数部分を書いておりまして、動的に動く変数をOverrideに入れたのですが全然動いてくれいなかったという問題がありました。

そこで今回のように関数にさせてUpdateでその関数を実行させるとなんかうまくいきました。

 

次回は音楽データについて記事にしたいと思います。そして今回の発光と音楽データを紐付けてライブっぽい演出を実現させたいと思います。

 

【Unity】初心者がまず最初にすることを初心者が教える

私はプログラムに関しては全くの初心者&業務でも使ったことがないのですが1ヶ月ぐらいで簡単なゲームを作ってGooglePlayで公開することが出来ました。レベルはさておき・・・

今回はどうやって私がUnityでゲームを作ったのかを書いてみたいと思います、簡単な記事です。

私が使い方をレクチャーするわけではないです・・・

 

Unityの最低限の知識を身につける

本当の最初は右も左も・・・というかなにから始めて良いのかわからないと思います。

Unityに関する記事は結構な数をみつけることは出来るのですが、どれも断片的でなかなか1からUnityを使えるレベルまで一貫して教えてくれるものはないのかなと思います。

そこで私がガチガチの初心者のとき最初に見たサイトを紹介したいと思います。

私はUmedyという無料の講座を使ってある程度使えるレベルまで学ぶことが出来ました。ちなみに無料です。

www.udemy.com

この講座はDLから画面の説明・ゲーム制作まであるのでかなりおすすめです

網羅的に一連の使い方が学べると思います、無料なのがおかしい!

ただ私は他のサイトなどを使っていないので比較はできませんが、一つ一つやることなすことに説明があるのできちんと理解できるためPCサイトを見てブロック崩しみたいなのをつくるのよりも良いと思います。

 

 

自己学習できるようにする

おそらくこの講座を受けると簡単なゲームなら作れるようになっていると思います。

その後なのですが船のこぎ方を覚えたから海にでてください的な感じになっちゃいますよね。一気にモチベがなくなります。そういうときは近い島に上陸しましょう、比喩です。

私が行ったのはすごーく簡単なゲームを1から自力で制作したことです。

自力っていうのが重要で、要はネットに落ちているスクリプトをなにも考えずにつかわないってことです。

ちゃんと自分で読み解いてつかうことが重要です。

また1から作っているといろいろ小さな壁にぶつかるのですが、基本がわかっているとこのころからネットの記事が役に立ち始めます。

たとえば当たった時にオブジェクト消したいとか、時間制御したいとかいろいろですが、Unity 当たる 消す みたいに検索するとかなりの確率で記事が見つかり解決すると思います。

そうやっていくといつの間にかゲームは完成して知識もついていくというものです。

やはり実践のみで力は付いていくので簡単でもゲームを作り続けることが重要だと思います。

たぶん知識がついてくると作るゲームもいつのまにかレベルアップしていると思います。なのでUnityで始めてゲームつくって見た的なかんじですごい高度なことはしなくてもいいと思います。

 

おまけ

ちなみに私は転職するためにUnityを始めてから1ヶ月ぐらいしてテックアカデミーのUnity講座の8週間を受講しました。

このことはいつか記事にしたいと思いますが、正直メンターのシステムが必要ないのであれば必要ないです。今回紹介した講座で十分だと思います。

ただ割高感はいなめませんがメンターと話せるのはすごいはよかったです。

 

あと私が最初に作ったゲームと最近作ったクリッカーゲームのURLをのっけときます。

クオリティは気にしないでください。

 

play.google.com

 

play.google.com