のにっき

【Unity】IOS14.6からmailtoで改行コードが使えなくなった対策

Unityでメーラー機能を実装するとき、mailtoを使っていた人に悲報です。
IOS14.6以降、mailtoで改行コードが認識されない仕様になりました。
改行コード'%0D%0A'を使用すると、改行されない上に<BR>が表示されてしまいます。
developer.apple.com
詳細は上記サイトに載っていますが、

iOS 14.6以降のmailtoリンクでは、HTMLなどのリッチコンテンツのサポートが削除されました

とのことです。。。改行すらサポートしないのは致命的すぎませんか?
と思っちゃうのは私がハッカーに悩まされたことがないからでしょうか。。。
ということで今回はmailtoを利用していたメーラー機能に
IOSのみ別のやり方で、改行のサポートを行う実装方法を紹介します。

作成したアセット公開

github.com
アセットの内容は上記URLで公開しています。
ソースファイルと説明を一緒に見ていただけるとわかりやすいと思います。

ソース紹介【IOSプラグイン

mailtoに変わるメーラー機能を利用します。
MessageUIフレームワークMFMailComposeViewControllerを利用することで、
アプリケーション内でメールの作成や送信ができます。
IOS専用のプラグインになるのでObject-C形式で呼び出します。
▼MailerPlugin.mm

#import <MessageUI/MessageUI.h>
#import <MessageUI/MFMailComposeViewController.h>

@interface SocialWorker : NSObject<UIDocumentInteractionControllerDelegate, MFMailComposeViewControllerDelegate>
@property(nonatomic, retain) UIDocumentInteractionController *_dic;
@end

@implementation SocialWorker
/**
 * メール投稿
 * @param to 宛先
 * @param subject タイトル
 * @param message メッセージ
 */
- (void)postMail:(NSString *)to subject:(NSString *)subject message:(NSString *)message {
    if([MFMailComposeViewController canSendMail]) {
        MFMailComposeViewController *vc = [[MFMailComposeViewController alloc] init];
        vc.mailComposeDelegate = self;
        [vc setToRecipients:[to componentsSeparatedByString:@","]];
        [vc setSubject:subject];
        [vc setMessageBody:message isHTML:NO];
        [UnityGetGLViewController() presentViewController:vc animated:YES completion:nil];
    } else {
    }
}

/** 
 * メール結果
 */
- (void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error {
    [UnityGetGLViewController() dismissViewControllerAnimated:YES completion:nil];
}

@end

/**
 * Unityから呼び出されるネイティブコード
 */
extern "C" {
    static SocialWorker *worker =[[SocialWorker alloc] init];
    UIViewController *UnityGetGLViewController();
    void UnitySendMessage(const char *, const char *, const char *);
    static NSString *getStr(char *str){
        if (str) {
            return [NSString stringWithCString: str encoding:NSUTF8StringEncoding];
        } else {
            return [NSString stringWithUTF8String: ""];
        }
    }
    void postMail(char *to, char *subject, char *message){
        [worker postMail:getStr(to) subject:getStr(subject) message:getStr(message)];
    }
}
プラグイン設定

.mmファイルはプロジェクトのAssets直下のPlugins/iOSフォルダに配置します。
ファイル作成後、Inspectorで以下の画像の設定を行います。

f:id:apuridasuo:20210628010705p:plain
メーラープラグイン設定

ソース紹介【Unity呼び出し】

上記で作成したプラグインC#で呼び出します。
▼OpenMailer.cs

public class OpenMailer 
{
    /// <summary>
    /// ネイティブプラグイン定義
    /// </summary>
#if UNITY_IPHONE
        [DllImport("__Internal")]
        private static extern void postMail(string to, string subject, string message);
#endif

    public void OpenMailerBase(string Address,string Kenmei, string Message)
    {
#if UNITY_IOS
            postMail(Address, Kenmei, Message);
#else
        string kenmeiOff = System.Uri.EscapeDataString(Kenmei);
        string messageOff = System.Uri.EscapeDataString(Message);
        string Url = $"mailto:{Address}?subject={kenmeiOff}&body={messageOff}";
        Application.OpenURL(Url);
#endif
    }
}

IOSのみ、プラグインを呼び出します。
他のプラットフォームはmailto機能できちんと改行されますので大丈夫です。
あとは宛先等の情報を引数にOpenMailerBaseを呼び出せばOKです。
※以下、呼び出す関数のサンプルコード

    void MakeMailer()
    {
        string to = "testAddressTo@gmail.com";
        string kenmei = "件名:テスト";
        string message = "▼本文\r\n" +
        "----------------------------\r\n" +
        "\r\n\r\n" +
        "----------------------------";
        OpenMailer mailCls = new OpenMailer();
        mailCls.OpenMailerBase(to, kenmei, message);
    }

参考サイト

SocialWorkerのプラグインはメール機能だけでなく、
TwitterやFaseBook連携も行っているようですので多機能でおすすめです!
github.com

【Unity】PyasicMaterial使用時、オブジェクトが跳ね返らないときの対処法

UnityでPyasicMaterialを使用してオブジェクトに跳ね返りの設定を行ったとき、
思ったように跳ね返らなかった場合の対処法をまとめます。
※弱い力で衝突した時に跳ね返らなくて悩んでる人は対策③必見!

対策①:PyasicMaterial(2D)の設定を確認

そもそも跳ねない。跳ね方がおかしい時に確認
・Bounciness
0だと跳ねない。1だと力が減らずに跳ねる。無限に跳ねさせるなら1に設定する
Bounce Combine: ※3Dのみ
Maximumに設定すると力が減らずに跳ねる。

対策②:Rigidbody(2D)の設定を確認

オブジェクトが壁をすり抜けるときに確認
・Collision Detection
デフォルトは「Discrete」。壁をすり抜けるバグが発生してなかったらこのままでOK!
壁抜けが発生している場合は「Continuous」を設定する

対策③:Project Settings → Physics(2D)の設定を確認

オブジェクトが壁に埋まる。うまく跳ね返らなかったりするときに確認
3DならBounce Threshold、2DならVelocity Threshold
跳ね返りのしきい値
簡単に言うと、設定値より低い力でぶつかったら跳ね返らないようにする。
上手く跳ね返らないときは0を設定する。

【Unity】デバッグ時にWaitForSecondsがうっとうしい時の対処法

Unityでデバッグを行っている時、
様々な場面で組み込んでいるWaitForSecondsの設定
アニメーション等で使用していると思うのですが、
デバッグの時はウェイトをスキップしてすいすいデバッグしたい!
と思う事があったので方法をまとめます。

ソースコード

    /// <summary>
    /// ウェイト付き関数
    /// </summary>
    /// <returns></returns>
    public IEnumerator Set_CzStart()
    {
        Debug.Log("ウェイト前");
        yield return new WaitForSeconds(GetWtTime(10.0f));
        Debug.Log("ウェイト後");
    }

    /// <summary>
    /// タイマー値取得
    /// </summary>
    /// <param name="SetTimer">設定したい秒数</param>
    /// <returns>デバッグ判定後秒数</returns>
    public static float GetWtTime(float SetTimer)
    {
#if Def_WaitDebug
        return 1f;
#else
        return SetTimer;
#endif
    }

この記述方法でウェイト時間をデバッグ時のみ1秒に短縮できるようになります。
WaitForSecondsに秒数を設定する時に関数を挟む感じです。

ウェイト時間の切り替え方法は、

#define Def_WaitDebug

上記のDefine設定をソースファイルの一番上に記入するかどうかで
切り替えることが出来ます。
記入する・・・ウェイト時間=1秒になる
記入しない・・ウェイト時間=設定秒になる

UnityEngineなどのソースは書き換えができなかったので
デバッグ用に新たに関数を作りました。
付け焼刃感が凄いですが、スイスイデバッグの参考にしてみてください。

【VS】KeyDownイベントが発生しない場合の対策

Windowsフォームアプリの設定の話です。
ショートカットキーの機能を組む時に知っておくととても便利です。

本当にイベントが発生していないのか?

KeyDownイベントにブレークを貼って
イベント処理が通っているかどうか確認しましょう。
イベント内の処理のせいで、イベントは正常に発生しているのに
処理が動いていない場合は処理を直せば解決です。

フォームに対してイベントを設定しているか?

KeyDownイベントを設定している対象を確認しましょう。
フォームに対してではなく、
ボタン等のコントロールに対してイベント設定を行っていると
そのコントロールにフォーカスがあっている状態でしかイベントが発生しません。
必ずフォームに対してイベント設定を行いましょう。

KeyPreviewプロパティをTrueにする

フォームのプロパティ内の「KeyPreview」の項目をTrueに変更しましょう。
デフォルト設定ではフォーム以外のコントロールにフォーカスが当たった状態だと
フォームに設定したKey系イベントが発生しないです。
(フォーカスに当たったコントロールのKey系イベントが発生します)
そこで、KeyPreviewをTrueに変更することで、
フォーム内のどこにフォーカスが当たっていても、
フォームのKey系イベントが発生するようになります。
※順番は、
「フォームのKey系イベント」→「フォーカス当たってるコントロールのイベント」
という順番になります

以上です。
KeyPreviewプロパティは知らないと
全部のコントロールにKey系イベントを設定するという
パワープレイに走ってしまうので是非、ご活用ください。

Aviutl 初心者詰まりポイント

完全に自分へのメモ帳です。

最近、趣味で動画編集を行っているのですが、

そこで使用している無料動画編集ソフトAviutl

とても機能が多く無料なので、編集初心者にはうってつけのツールだと思います。

しかしながら、初めての動画編集なので詰まるポイントも多く、

何度もミスしないようにここにまとめておきます。

 

 

Aviutlとは?

どんなユーザー向け?

▼お勧めする人

・動画に画像や文字を入れたい人

・ただ動画の一部を切り取るだけじゃなく、凝った演出を入れたい人

・凝った動画編集未経験の人

・有料ソフトに手が出ない人

▼お勧めしない人

・動画圧縮・サイズ変更だけ出来ればいい人

・動画の一部だけ切り取り出来ればいい人

インストールから基本的な使用方法まで

aviutl.info

他リンクで申し訳ないですが、すべてここに載ってます。

私はこれを見ながら

「切り取り、サイズ変更、画像・文字のテロップ設定」までできる様になりました

初心者注意点

AVI出力で出力するとめちゃ重い!

編集した動画を出力するとき、「AVI出力」で出力できます。

しかし、出力された動画はめちゃくちゃ重い(30秒で1GBとかになる)ので、

「簡単MP4出力」等の出力プラグインの導入をお勧めします

画面サイズは2で割れる数値

 上記でおススメした「MP4出力」ですが、

縦横の画面サイズが2で割り切れない数だった場合、出力できません。

サイズ指定を行う場合は、必ず偶数の値を設定しましょう

閉じるときに「保存しますか?」警告が出ない

編集後に閉じるときに警告が出ないので、上書き保存したか分かりません。。。

※保存をしていても警告が出てしまいますが

「ファイル」→「環境設定」→「システムの設定」クリック

→「編集ファイルが閉じられる時に確認ダイアログを表示する」にチェック

この設定で警告が出る様になります。

動画の終点をオブジェクトの最後にする

動画を編集後、出力してみると

映像が終わった後に黒画面で何も起きない時間が入っていることがあります。

動画の終点が作成した動画の終点より長い事が原因ですので

対処法は以下の画像を参考にしてください。

f:id:apuridasuo:20200921161749p:plain

図:動画終点の余白除去方法

拡張機能のボタンの位置が分かりずらい

 サイトで「文字の縁取り」や「画像アニメーション」等を検索して

勉強しようとしても、そもそも拡張機能の追加方法が分からん!

ってなったあなた!同士です!!

f:id:apuridasuo:20200921162806p:plain

図:拡張機能追加ボタン位置

上図を参考にしてください。

動画に限らず、文字も画像も同じボタンがあります。

 

以上です。

絶賛勉強中なので気づいたことがたまったらまた書いていこうと思います。

 

【C#】フォルダ選択ダイアログを推奨しない理由

Windowsフォームアプリ等でツールを作成する際、
フォルダのパスを取得したいとき、
なんとなく思いつくのが選択ダイアログだと思います。
このダイアログですが、個人的に推奨しません!
今回はその理由とフォルダパスを取得する時に推奨する方法をご紹介します。

ダイアログを推奨しない理由

使い手の工程数が多い!

ダイアログという手法は直感的で分かりやすいのですが、
いかんせん指定フォルダを選択するまでの手順が多すぎます!
ツール設計で大事な事は
ツールを使う時の作業工程が少ないことです。
業務で使うツールは特に、何度も使用することになります。
作業工程が少なければ少ないほど、作業時間が短縮される。
つまりは業務改善につながります。
パスを取得する作業時間は極限まで短縮するツールを作りましょう!

推奨しない使用例

こんなツールを作るときはダイアログを絶対使用してはいけません!
という例を挙げてみます。
・複数のパスを取得しないといけない
 →一つ一つダイアログを開く必要があるので、
 ものすごく手順がめんどくさいツールになります
・毎回使うたびに、違うフォルダ(ファイル)のパスを取得しないといけない
 →毎回同じパスでいいなら、前回の記入パスを記憶すればいいので
 ダイアログでも大丈夫だと思います。
 毎回新しくファイル選択が必要になるならダイアログは推奨できません

ダイアログに代わるパス設定仕様

フォルダをドラッグ&ドロップ

これにつきます!
作業対象のファイルをそのままドラッグ&ドロップ(D&D)できる仕様です。
ダイアログと違って、作業手順が一発で終了なので
とても簡単にパスの設定が可能です。

導入手順(Windowsフォームアプリ)

ドラッグ&ドロップの設定方法を、例を用いて説明します

フォームデザイン
f:id:apuridasuo:20200826191252p:plain
図:説明用フォーム内容

図のように、フォームの中にTextBoxを作って
そこにパスを記入させる仕様になります。
※フォームの中で、ドラッグできることを知らせるようにしましょう。

ソースコード

ドラッグイベント用の関数になります。

/**************************************************************************
   【EV】記入欄D&D時
**************************************************************************/
// ドロップ
private void Txt_Path_DragDrop(object sender, DragEventArgs e)
{
    // ドロップパス取得
    string[] files = (string[])e.Data.GetData(DataFormats.FileDrop, false);
    TextBox Txt_Set = (TextBox)sender;
    // 正常ならコントロールに反映
    Txt_Set.Text = files[0];
}
// ドラッグ
private void Txt_Path_DragEnter(object sender, DragEventArgs e)
{
    //マウスカーソルの表示更新
    if (e.Data.GetDataPresent(DataFormats.FileDrop))
    {
        e.Effect = DragDropEffects.All;
    }
    else
    {
        e.Effect = DragDropEffects.None;
    }
}

このソースで大事な部分は

// ドロップパス取得
string[] files = (string[])e.Data.GetData(DataFormats.FileDrop, false);

この部分だと思います。
ドロップされたファイルが複数の場合を想定して、文字列の配列で取得しています。
そして記入するパスは一つなので、
配列の先頭パスをTextBoxに記入しています。
複数パスを一気に取得したい場合も、
配列でドロップされた全てのパスを取得しているので対応可能です。

プロパティ設定
f:id:apuridasuo:20200826192623p:plain
図:プロパティ、イベント設定

上図を参考に、記入したイベント関数の設定を行います。
以上で、ドラッグ&ドロップの仕様組み込みが完了です。

ぜひ、ドラッグ&ドロップの仕様を実際にツールに取り入れてみてください。
ダイアログとは比べ物にならないくらい使いやすくなると思います。
私も昔はダイアログを当たり前のように使っていましたが、
今回紹介したドラッグ仕様に気づけてから
業務用ツールの使いやすさが格段に上がりました!

お仕事のご依頼

作っているアプリのクレジットに乗せる

ページになります。

 

依頼できる内容

・業務改善(提案からやります) 

スマホアプリ作成(Androidのみ

VBAC#、Unity講座

(質問に答える形式から

 一から教わる形式まで何でも可)

 

料金

お見積りは無料!

最低1000円から行います

 

 連絡先

・メアド

apuridasuo1192@gmail.com

Twitter

やってますので、気軽にDMください