poi’s tech blog

3D多人数同時接続型球体アクション成人向けゲーム開発のためのアイデア、ナレッジ

ジャンプとホバリング

スペースキーでジャンプ。

f:id:poipoipoip:20190502221310g:plain

ジャンプ中にさらにスペースキーでホバリングする。

そろそろ追うのがつらくなってくるAnimatorControllerによるアニメーション管理

f:id:poipoipoip:20190502221549p:plain

ジャンプモーション終わったあたりで落下アニメーションに切り替わる。

空中ジャンプするたび手をバタつかせる。

モデルのシェイプキーにホバリング中の膨らみアニメーションを作成済みなので、ホバリング状態に遷移したらSkinnedMeshRendererのBlendShape値を変えて空気を頬張ってるっぽくしてる。

まばたきしてたのと同じクラスにBlendShapeいじったり後で実装する紅潮切り替えとか半目状態の時の処理とか記述するつもり。

値を設定したりするのは他クラスに分けてる。

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

public class ExpressionCtrl : MonoBehaviour {

    public Texture[] image_face;

    private double timeElapsed;
    private double timeMax;
    private double timeOut;

    private int blinkCount;

    private Material eye;
    private SkinnedMeshRenderer skin;

    public enum BrendShapes
    {
        Happy = 0,
        Surprise = 1,
        Omg = 2,
        Sad = 3,
        Close = 4,
        CloseSmile = 5,
        CloseCry = 6,
        Open = 7,
        Hover = 8
    }

    private BrendShapes blendShapes = BrendShapes.Happy;
    private int blendValue = 0;

    // Use this for initialization
    void Start() {
        timeMax = 3.0;
        blinkCount = 0;
        SetTimeOutSec();

        Renderer[] children = this.GetComponentsInChildren<Renderer>();
        for (int i = 0; i < children.Length; i++)
        {
            for (var j = 0; j < children[i].materials.Length; j++)
            {
                if (children[i].materials[j].name == "kirby_face1 (Instance)")
                {
                    eye = children[i].materials[j];
                }
            }
        }

        skin = this.GetComponent<SkinnedMeshRenderer>();
    }

    void Update()
    {
        timeElapsed += Time.deltaTime;

        if (timeElapsed >= timeOut)
        {
            // Do anything
            Blink();
        }

        SkinChanger();
    }

    void SetTimeOutSec()
    {
        System.Random r = new System.Random();
        timeOut = timeMax * r.NextDouble();
    }

    void Blink()
    {
        switch (blinkCount)
        {
            case 0:
                eye.mainTexture = image_face[2];
                blinkCount++;
                break;
            case 1:
                blinkCount++;
                break;
            case 2:
                eye.mainTexture = image_face[1];
                blinkCount++;
                break;
            case 3:
                blinkCount++;
                break;
            case 4:
                eye.mainTexture = image_face[0];
                blinkCount = 0;
                timeElapsed = 0.0f;
                SetTimeOutSec();
                break;
            default:
                blinkCount = 0;
                timeElapsed = 0.0f;
                SetTimeOutSec();
                break;
        }
    }

    private void SkinChanger()
    {
        if (skin.GetBlendShapeWeight((int)blendShapes) < blendValue)
            skin.SetBlendShapeWeight((int)blendShapes, skin.GetBlendShapeWeight((int)blendShapes) + 10);
        else if (skin.GetBlendShapeWeight((int)blendShapes) > blendValue)
            skin.SetBlendShapeWeight((int)blendShapes, skin.GetBlendShapeWeight((int)blendShapes) - 10);
    }

    public void SetSkin(BrendShapes blendShapeName, int value)
    {
        blendShapes = blendShapeName;
        blendValue = value;
    }
}