UnityでのDelegateメモ

今回は、UnityのC#で使うDelegateとActionとFuncについて自己流解説を行います。
なぜ、いきなりDelegateの話を始めたのかは下記動画をご覧ください。

YouTube
https://youtu.be/KaNKg7zJFgo

ニコニコ動画
https://www.nicovideo.jp/watch/sm38134287

進捗報告動画で、敵の移動処理変更を行った時、DelegateとActionについての説明を省き、ここで説明するようにしました。

Delegate(デリゲート)とは

デリゲートの意味を調べると、メソッドを変数のように扱う機能と書かれることが多いです。
デリゲートの使いどころを、自分の制作に当てはめると以下のコードのようになります。

テストスクリプト1
テストスクリプト2

上記の書き方で何がいいのかを、ゲーム制作の進捗動画内容にあわせると、

・移動処理のパターンを敵の種類ごとに作れる
・修正や不具合の発見が行いやすく、影響範囲が小さくできる

個人で制作する上で、見やすくなって移動処理を作りやすくなるメリットになります。

ActionとFunc

ActionとFunc機能は、デリゲートの宣言を簡略化できるものと説明される事が多いです。
下記のサンプルコードをご覧ください

基本となる移動処理

移動スクリプト

エネミーの場合

エネミー移動処理

プレイヤーの場合

プレイヤー移動処理

大まかには、Actionは戻り値が無く、Funcは戻り値があるという違いがあります。
制作のコードではActionを良く利用しています。

終わりに

今回は動画内容の補完としてブログでコード解説を書いてみました。
自分で解説出来る範囲での記述ですので、間違いなどがあれば教えていただければ幸いです。
今後も、動画の補完解説を行っていければと思います。

[覚書]ターゲットに向かって移動するオブジェクト

久しぶりの更新です。
個人的に重要なゲームのキャラクター挙動のコードを書きます。

今回記述するUnityコードは、敵キャラクターがプレイヤーの方向を向き続け、迫ってくる動きをします。
それがこちらです。

public class HogeTarget: MonoBehaviour
{
public GameObject TargetObj;
private float maxData = 45;
private float minData;
private void Start()
{
minData = 360 -maxData;
}
private void Update()
{
this.gameObject.transform.LookAt(TargetObj.transform);
Vector3 angle= this.gameObject.transform.localEulerAngles;
if ( angle.x < maxData && 180 > angle.x)
{
angle.x = maxData ;
}
if (angle.x < minData && 180 < angle.x)
{
angle.x = minData ;
}
transform.localEulerAngles = angle;
transform.position += transform.rotation * new Vector3(0, 0, 1.0f)*Time.deltaTime;
}
}

上記の記述で重要な箇所が、[transform.LookAt]でプレイヤーの方向に向き、後のコードで敵キャラクターの向きに制限を加えています。
また、方向転換するオブジェクトの子オブジェクトに顔や腕をセットすることで、ある程度自然な挙動にすることができます。

次のコードは上記コードの

transform.position += transform.rotation * new Vector3(0, 0, 1.0f)*Time.deltaTime;

下に
transform.position += new Vector3(0, 0, 1.0f) * Time.deltaTime;

を記述することで、オブジェクトがプレイヤーに向きながら、Z軸方向に進んでいくようになります。

この挙動を入れることで、画面外に敵を移動させたい時に便利になります。

[覚書]Unityで使用するactionとevent具体例

只今誠意制作中のゲームで、仕様に躓いて知識を覚えるまで時間を要した箇所のメモを残します。
event機能を忘れないため、少し具体的なコードを載せた覚書メモになります。
まだ理解の途中ですが、自分が忘れないようにする為に記述します。

※この記事では、Unity上でのdelegateやeventについては詳しく書きません。

使用例
「プレイヤー」オブジェクトの点数が変化するたびに、「テキスト」オブジェクトがデバッグlogコメントを出す。

2つのオブジェクト間のデータ更新を、上記の仕様をUnityの点数変化の参照に対して「update」メソッドを使わずに、コードを書こうと構築したものが下記になります。

「HogeEventPoint」、「HogePointUp」をアタッチしたオブジェクトと「HogeLog」をアタッチしたオブジェクトを用意します。
最後に「HogeEventPoint.cs」をシリアライズフィールドされている「HogeEventPoint」、「HogeLog」に参照させたら完成です。

始めに、ZorXキー押すとポイントを入力されてログが出力されます。
次に、最初に押されたキー以外を押すと、ポイントが変わりログが出力されます。
以前のキーと同じキーを押した場合、ポイントも変わらずログも出力されません。

今回記述したコードは、ゲーム内で採用されたモノの最小構成になります。
別オブジェクトの値が変化したら、変化した値を取得して動作したい時に便利です。


プレイヤーオブジェクトの取得点数が変わった変化を受け取り、UIオブジェクトのテキストを変更する。

こういった具体的な動作の足掛かりになればと思い記事を書きました。

タイトルにある、「action」、「event」、そして元になっている「delegate」については、今後自分が学んだ範囲で記事を書いていこうと思っています。

OpenCVforUnity仕様メモ1

忘れないように

UnityアセットのOpenCVforUnity購入から1ヵ月ほど経ち、やっとの事でウェブカメラ映像をグレースケールに処理することに成功。
基本的な操作であるグレースケール出力まで、時間をかけすぎたという反省の意味も込めて、ブログに残します。
練習も兼ねてGitHubでのメモ用コード公開は今後も行っていきます。
最後の行にソースコードも貼り付けています。

GitHub公開はこちら

公開用のコードは単純な画像処理を記述になっています。これは後で見直した時に最低限の動作を思い出すためです。
実制作中のコードやゲームオブジェクトはもう少し機能が多いです。

バーチャル体を動かす為に購入と勉強を始めましたが、想像以上に苦戦しました。
自由にバーチャル体を動かせるまでもう少し時間がかかりそうです。

以下ソースコード

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using OpenCVForUnity.CoreModule;
using OpenCVForUnity.ImgprocModule;
using OpenCVForUnity.UnityUtils;

public class HogeWebCamOpenCvUnity : MonoBehaviour
{

//画像処理後の映像出力先
public RawImage HogeOutputRaw;

//各々のウェブカメラの設定用項目
[SerializeField] private int width = 1920;
[SerializeField] private int height = 1080;
[SerializeField] private int fps = 30;

//ウェブカメラテクスチャ
private WebCamTexture hogeWebCamTexture;

void Start()
{
//ウェブカメラの初期設定と起動
hogeWebCamTexture = new WebCamTexture(width, height, fps);
HogeOutputRaw.texture = hogeWebCamTexture;
hogeWebCamTexture.Play();
}

void Update()
{
//ウェブカメラのフレームが変更されたら処理
if (hogeWebCamTexture.didUpdateThisFrame)
{
//ウェブカメラの画像をMatに変換
Mat originMat = new Mat(hogeWebCamTexture.height, hogeWebCamTexture.width, CvType.CV_8UC4);
Utils.webCamTextureToMat(hogeWebCamTexture, originMat);

//画像処理先Mat
Mat changeMat = new Mat(originMat.cols(), originMat.rows(), CvType.CV_8UC4);

//グレースケール処理
Imgproc.cvtColor(originMat, changeMat, Imgproc.COLOR_RGB2GRAY);
//二値化(数値は各々で変更)
Imgproc.threshold(changeMat, changeMat, 100, 255, Imgproc.THRESH_BINARY);
//輪郭抽出
Imgproc.Sobel(changeMat, changeMat, -1, 1, 0);

//Matをテクスチャに変換
Texture2D endTexture = new Texture2D(changeMat.cols(), changeMat.rows(), TextureFormat.RGBA32, false);
Utils.matToTexture2D(changeMat, endTexture);

//映像出力先にテクスチャ貼付け
HogeOutputRaw.texture = endTexture;
}
}

}

ゲーム制作進捗報告8

今回は、ゲーム制作に直接関わる訳では無いですが、Gitについて勘違いしていた箇所を、訂正を込めたメモ書きになります。

今まで勘違いしていたGitリポジトリ制作先

Unityのプロジェクトフォルダ階層1つ上に作っていた

上記のリポジトリ作成していたため、これまで参考にしていた、不要なデータをコミットから外すgitgnoreの設定が、上手くいかない為困っていました。しかし、フォルダ設定を見直していたら間違いに気づきました。

Unityプロジェクトフォルダ内にリポジトリ作成

Unityのプロジェクト内に、リポジトリを作らないと意味がなかったと、ようやく気付けました。これにより、無駄なデータをコミットする必要が無くなり、少しは快適になると思います。

単純なミスに早く気付けるようになりたいです。

ゲーム制作進捗報告3

新たに杖のモデリングを行いました。

これは元にした移動用モーションを流用して制作しました。

上記のモデルを流用して、動きのモーションを統一させることが出来ました。

明確なモーションは、後日公開です。

ゲーム制作進捗報告2

今報告できる進捗はプレイヤーモデルを、Unityパッケージ化してデータ移動を楽にしました。

今後はモデル自体のアップデートとゲームシステム公開を中心に行いたいと思います。

ゲーム制作進捗報告1

今月からデジゲー博2018までに、ゲーム制作の進捗報告や制作メモをブログで上げていきたいと思います。

1回目は、Blender上で制作したモデルとUnity上に持っていた時の問題点の解決です。

間違いだけどこれはこれでモデルに使える?

Unityにモデルを持っていくと、スカートの面が一部消えてしまう問題が発生しました。

Blender上では問題なく正の表示だった為、少し悩みましたが、3Dモデルで面の表裏の問題に気づいてから試すと直せました。

Blenderの編集モードで問題のある面を選択

CTR(command)キー+Nを押すと

面がすべて表に

上記の操作をBlender上で編集する事で、Unityでのモデル破綻がなくなりました。

しかし、モデルの破綻は単純なモノだけでは無いものも多く、他に問題が生じたらまたブログに記述します。