20210108のC#に関する記事は6件です。

UnityのInputSystemPackageをReactivePropertyに変換する

はじめに

新しいInputSystemへの移行をReactivePropertyを用いて行います

環境

Unity2020.2

従来のUnityEngine.Inputからの移行

InputAction自体がInputすべての汎用クラスなので
旧InputのInput.GetButton/Input.GetAxisと同様に使えるよう
3パターンに分けてReactivePropertyへ変換を行います。

  • Button 旧:Input.GetButton(Down/Up)
  • Delta 旧:Input.GetAxis(MouseX) マウスの移動量
  • Axis 旧:Input.GetAxis 例Joystick,Horizontal

変換には今回作成した拡張メソッドを使用しています。

InputActionの設定

  • Button

image.png
image.png
こちらはデフォルトで大丈夫ですがButtonにしておくとBindingがボタンのみ表示されます
image.png
Bindingには押したいボタンを
TriggerBehabiorにはPressAndReleaseを設定します

  • Delta

image.png
image.png
こちらはデフォルトで大丈夫ですがAxisにしておくとBindingがAxisのみ表示されます
image.png

  • Axis

image.png
ジョイスティックの場合はドリフトするのでDeadZoneを設定すると良いです。
image.png
キーボードからAxisを作成する場合1DAxisを行うと作成できます。

InputActionをReactivePropertyに変換する拡張メソッド

InputSystemExtension.cs
using System.Collections;
using System.Collections.Generic;
using UniRx;
using UnityEngine;
using UnityEngine.InputSystem;

public static class InputSystemExtension
{
        public static ReadOnlyReactiveProperty<bool> GetButtonProperty(this InputAction inputAction)
        {
            return Observable.FromEvent<InputAction.CallbackContext>(
                    h => inputAction.performed += h,
                    h => inputAction.performed -= h)
                .Select(x => x.ReadValueAsButton())
                .ToReadOnlyReactiveProperty(false);
        }

        public static ReadOnlyReactiveProperty<float> GetAxisProperty(this InputAction inputAction)
        {
            return Observable.FromEvent<InputAction.CallbackContext>(
                    h => inputAction.performed += h,
                    h => inputAction.performed -= h)
                .Select(x => x.ReadValue<float>())
                .ToReadOnlyReactiveProperty(0);
        }

        //Delta入力はUpdate基準なのでUpdate基準に変換(主にマウスで使用)
        public static ReadOnlyReactiveProperty<float> GetDeltaAxisProperty(this InputAction inputAction)
        {
            return Observable.EveryUpdate().Select(_ => inputAction.ReadValue<float>()).ToReadOnlyReactiveProperty(0);
        }

}

テストコード

TestInput.cs
using System;
using UnityEngine;
using UnityEngine.InputSystem;
using UniRx;

public class TestInput : MonoBehaviour,IDisposable
{
    //※今回はInputActionMapを用いず別々にInputActionを定義していますがInputActionMap

    [SerializeField]
    private InputActionMap inputAction;

    private ReadOnlyReactiveProperty<bool> attack = default;
    //ボタンに変換したIReactivePropertyを公開
    public IReadOnlyReactiveProperty<bool> Attack => attack;

    private ReadOnlyReactiveProperty<float> mouseX = default;
    //Mouseの移動量に変換したIReactivePropertyを公開
    public IReadOnlyReactiveProperty<float> MouseX => mouseX;

    /// <summary>
    /// 2ボタンで-1 0 1出力
    /// </summary>
    private ReadOnlyReactiveProperty<float> horizontal = default;
    //Mouseの移動量に変換したIReactivePropertyを公開
    public IReadOnlyReactiveProperty<float> Horizontal => horizontal;

    private void OnEnable()
    {
        inputAction.Enable();
    }

    private void OnDisable()
    {
        inputAction.Disable();
    }

    private void Awake()
    {
        attack =inputAction.FindAction("Attack").GetButtonProperty();
        mouseX = inputAction.FindAction("MouseX").GetDeltaAxisProperty();
        horizontal = inputAction.FindAction("Horizontal").GetAxisProperty();
    }

    private void OnDestroy()
    {
        Dispose();
    }

    public void Dispose()
    {
        inputAction?.Dispose();
        attack?.Dispose();
        mouseX?.Dispose();
        horizontal?.Dispose();
    }
}
Test.cs
using UnityEngine;
using UniRx;
using UniRx.Triggers;

public class Test : MonoBehaviour
{
    [SerializeField]
    private TestInput input;

    private void Start()
    {
        input.Attack.Subscribe(x=>
        {
            if (x)
            {
                Debug.Log("GetButtonDown");
            }
            else
            {
                Debug.Log("GetButtonUp");
            }
        }).AddTo(this);

        this.UpdateAsObservable().Subscribe(_ =>
        {
            Debug.Log("GetButton:" + input.Attack.Value);

            Debug.Log("Horizontal"+ input.Horizontal);

            Debug.Log("MouseX" + input.MouseX);

        }).AddTo(this);        
    }
}
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Unityの新しいInputSystemをReactivePropertyに変換し使用する

はじめに

新しいInputSystemへの移行をReactivePropertyを用いて行います
新しいInputSystemそのままだと使いにくすぎる…

環境

Unity2020.2

従来のUnityEngine.Inputからの移行

InputAction自体がInputすべての汎用クラスなので
旧InputのInput.GetButton/Input.GetAxisと同様に使えるよう
3パターンに分けてReactivePropertyへ変換を行います。

  • Button 旧:Input.GetButton(Down/Up)
  • Delta 旧:Input.GetAxis(MouseX) 例マウスの移動量
  • Axis 旧:Input.GetAxis 例Joystick,Horizontal

変換には今回作成した拡張メソッドを使用しています。

InputActionの設定

  • Button

image.png
image.png
こちらはデフォルトで大丈夫ですがButtonにしておくとBindingがボタンのみ表示されます
image.png
Bindingには押したいボタンを
TriggerBehabiorにはPressAndReleaseを設定します

  • Delta

image.png
image.png
こちらはデフォルトで大丈夫ですがAxisにしておくとBindingがAxisのみ表示されます
image.png

  • Axis

image.png
ジョイスティックの場合はドリフトするのでDeadZoneを設定すると良いです。
image.png
キーボードからAxisを作成する場合1DAxisを行うと作成できます。

InputActionをReactivePropertyに変換する拡張メソッド

InputSystemExtension.cs
using System.Collections;
using System.Collections.Generic;
using UniRx;
using UnityEngine;
using UnityEngine.InputSystem;

public static class InputSystemExtension
{
        public static ReadOnlyReactiveProperty<bool> GetButtonProperty(this InputAction inputAction)
        {
            return Observable.FromEvent<InputAction.CallbackContext>(
                    h => inputAction.performed += h,
                    h => inputAction.performed -= h)
                .Select(x => x.ReadValueAsButton())
                .ToReadOnlyReactiveProperty(false);
        }

        public static ReadOnlyReactiveProperty<float> GetAxisProperty(this InputAction inputAction)
        {
            return Observable.FromEvent<InputAction.CallbackContext>(
                    h => inputAction.performed += h,
                    h => inputAction.performed -= h)
                .Select(x => x.ReadValue<float>())
                .ToReadOnlyReactiveProperty(0);
        }

        //Delta入力はUpdate基準なのでUpdate基準に変換(主にマウスで使用)
        public static ReadOnlyReactiveProperty<float> GetDeltaAxisProperty(this InputAction inputAction)
        {
            return Observable.EveryUpdate().Select(_ => inputAction.ReadValue<float>()).ToReadOnlyReactiveProperty(0);
        }

}

テストコード

TestInput.cs
using System;
using UnityEngine;
using UnityEngine.InputSystem;
using UniRx;

public class TestInput : MonoBehaviour,IDisposable
{

    [SerializeField]
    private InputActionMap inputAction;

    private ReadOnlyReactiveProperty<bool> attack = default;
    //ボタンに変換したIReactivePropertyを公開
    public IReadOnlyReactiveProperty<bool> Attack => attack;

    private ReadOnlyReactiveProperty<float> mouseX = default;
    //Mouseの移動量に変換したIReactivePropertyを公開
    public IReadOnlyReactiveProperty<float> MouseX => mouseX;

    /// <summary>
    /// 2ボタンで-1 0 1出力
    /// </summary>
    private ReadOnlyReactiveProperty<float> horizontal = default;
    //Mouseの移動量に変換したIReactivePropertyを公開
    public IReadOnlyReactiveProperty<float> Horizontal => horizontal;

    private void OnEnable()
    {
        inputAction.Enable();
    }

    private void OnDisable()
    {
        inputAction.Disable();
    }

    private void Awake()
    {
        attack =inputAction.FindAction("Attack").GetButtonProperty();
        mouseX = inputAction.FindAction("MouseX").GetDeltaAxisProperty();
        horizontal = inputAction.FindAction("Horizontal").GetAxisProperty();
    }

    private void OnDestroy()
    {
        Dispose();
    }

    public void Dispose()
    {
        inputAction?.Dispose();
        attack?.Dispose();
        mouseX?.Dispose();
        horizontal?.Dispose();
    }
}
Test.cs
using UnityEngine;
using UniRx;
using UniRx.Triggers;

public class Test : MonoBehaviour
{
    [SerializeField]
    private TestInput input;

    private void Start()
    {
        input.Attack.Subscribe(x=>
        {
            if (x)
            {
                Debug.Log("GetButtonDown");
            }
            else
            {
                Debug.Log("GetButtonUp");
            }
        }).AddTo(this);

        this.UpdateAsObservable().Subscribe(_ =>
        {
            Debug.Log("GetButton:" + input.Attack.Value);

            Debug.Log("Horizontal"+ input.Horizontal);

            Debug.Log("MouseX" + input.MouseX);

        }).AddTo(this);        
    }
}

最後に

InputSystemPackageをそのまま使用するよりは楽に使えるようになったと思います。

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

Unityのサブスレッドで5msごとに処理

Unityのサブスレッドで5msごとに処理
多分こんな感じ

以下を参考にしました。
https://teratail.com/questions/109591

using UnityEngine;
using System.Threading;
using System;

public class UnitySubThreadTimer : MonoBehaviour
{
    Thread thread;

    // Start is called before the first frame update
    void Start()
    {
        thread = new Thread(new ThreadStart(SubThread));
        thread.Start();
    }
    void SubThread()
    {
        //Process once every 5ms
        long next = DateTime.Now.Ticks + 50000;
        long now;

        while (true)
        {
            try
            {
                Debug.Log(Time.time);
            }
            catch
            {
            }

            do
            {
                now = DateTime.Now.Ticks;
            } 
            while (now < next);
            next += 50000;
        }
    }

    void Stop()
    {
        thread.Abort();
    }

    void OnApplicationQuit()
    {
        thread.Abort();
    }
}
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

覚えておきたい書き方 

stringの配列をスッキリと intの配列に変換するには

string[] NX = System.Console.ReadLine().Trim().Split(' ');
int[] intNX = NX.Select(int.Parse).ToArray();
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

EMLからPSTへの変換 フリーソフト

4n6EMLからPSTへのコンバーター
4n6 EML to PST Converterは、EMLファイルをMS OutlookPSTファイル形式やその他の一般的なファイルターゲットに正確に変換するのに最適なツールです。 4n6 EML to PST Converterは、EMLからOffice 365への移行、EMLからLive Exchange Serverへの移行、PDFへの変換、簡単にアクセスできるファイル形式のようなMSGなど、多くの機能を提供します。 このソフトウェアは、MS Windowsのすべてのバージョンをサポートし、MSOutlookのUnicodeファイルとANSIPSTファイルの両方を処理します。 ソフトウェアの無料試用版も入手できます。 ソフトウェアのいくつかのハイライトを以下に示します。

Download https://forensiksoft.com/converter/eml.html

4n6-eml-converter.png

複数のEMLからPSTファイル形式への制限なしの即時変換。
EMLファイルをハードルなしでLiveExchangeServerとOffice365にすばやくエクスポートします。
結果として生じる特大のPSTファイルは、ユーザーの必要に応じて小さなPSTファイルに分割できます。
EMLをすべての添付ファイル付きのPSTおよびMSGファイル形式に変換できます。
EML / EMLXファイルはLiveExchangeパブリックフォルダーとアーカイブメールボックスにもエクスポートできます。
Outlook PSTファイルのすべてのエディション(ANSIおよびUnicode)へのEMLファイル変換。
このソフトウェアは、MSWindowsのすべてのエディションでの作業に最適です。
データ移行のための無料のコンサルタントサービスとソフトウェアに関する24時間年中無休のテクニカルヘルプ。
EMLデータをOutlookプロファイルストアにエクスポートする

EMLをPSTに変換する

EML to PST Converterソフトウェアには、EMLをすべての添付ファイルとメタデータとともにPSTファイル形式に変換するための高度に保護されたアルゴリズムが付属しています。 ソフトウェアは、複数のEMLファイルをPSTファイル形式に変換するための安全で迅速です。

サイズ制限なし

EMLおよびEMLXファイルからプロパティを失うことなく、このツールは、EMLサイズの制限なしに大きなEMLをPSTファイル形式にエクスポートすることができます。 このソフトウェアには、ユーザーがEMLメールボックスからPSTファイル形式にデータを転送できる拡張機能が付属しているため、EMLファイルに多くの時間と労力を費やすことなく簡単にアクセスできます。

EMLをOffice365にエクスポートする

EML Converterツールを使用すると、EMLメールボックスをOffice 365にエクスポートしてクラウドサービスを利用できます。これにより、いつでもどこからでもメールにアクセスできます。 このソフトウェアを使用すると、EMLをすべての添付ファイルとファイルデータとともにOffice365にすばやく移行できます。

変換のための複数のフォーマット

EMLファイル形式をMSGやPSTファイル形式などのさまざまなファイル形式にエクスポートして、電子メールデータの尊厳と整合性を失うことなく多くの電子メールクライアントで電子メールにアクセスできるようにします。このソフトウェアで可能です。

すべての人気のある電子メールクライアントで作成されたEMLファイルをサポートする

これは、EMLユーザーにとってもう1つの魅力的な機能です。 Outlook Express、Windows Liveメール、Windowsメール、Eudora、Thunderbird、およびEMLファイルが生成されたその他の電子メールクライアントがサポートされています。

EMLとその添付ファイルのプレビュー

EMLをさまざまなファイル形式で保存するために、ツールにはさまざまなファイル形式が含まれていますが、EMLファイルをそれぞれのファイル形式で保存する前に、ユーザーが品質を保証できるようにEMLファイルをプレビューするオプションが提供されます。

選択的エクスポート用のフィルター

必要に応じてデータをフィルタリングするために、ソフトウェアは「件名」、「開始」、「終了」などのカテゴリを提供します。 ユーザーは、カテゴリを選択してフィルターを適用することにより、データを簡単にフィルター処理できます。 このオプションは、特定のデータのエクスポートが必要な場合に非常に役立ちます。

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

VBEの難読化を解除する - C#

下記を参考に、VBEの難読化の解除処理をC#で実装してみた。
VBScript の難読化と解除 - Qiita

ソースコード

VbeDecoder.cs
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;

class VbeDecoder
{
    static readonly int[] IndexTable = new int[]{0,1,2,0,1,2,1,2,2,1,2,1,0,2,1,2,0,2,1,2,0,0,1,2,2,1,0,2,1,2,2,1,0,0,2,1,2,1,2,0,2,0,0,1,2,0,2,1,0,2,1,2,0,0,1,2,2,0,0,1,2,0,2,1};

    static readonly Dictionary<char,string> DecoderTable = new Dictionary<char,string>(){
        {'\t', "Wn{"   }, {' '   , ".-2"   }, {'!' , "Gu0" }, {'\"', "zR!"   },
        {'#' , "V`)"   }, {'$'   , "Bq["   }, {'%' , "j^8" }, {'&' , "/I3"   },
        {'\'', "&\\="  }, {'('   , "IbX"   }, {')' , "A}:" }, {'*' , "4)5"   },
        {'+' , "26e"   }, {','   , "[ 9"   }, {'-' , "v|\\"}, {'.' , "rzV"   },
        {'/' , "C\x7fs"}, {'0'   , "8kf"   }, {'1' , "9cN" }, {'2' , "p3E"   },
        {'3' , "E+k"   }, {'4'   , "hhb"   }, {'5' , "qQY" }, {'6' , "Ofx"   },
        {'7' , "\tv^"  }, {'8'   , "b1}"   }, {'9' , "DdJ" }, {':' , "#Tm"   },
        {';' , "uCq"   }, {'='   , "~:`"   }, {'?' , "^~S" }, {'A' , "wEB"   },
        {'B' , "J,'"   }, {'C'   , "a*H"   }, {'D' , "]tr" }, {'E' , "\"'u"  },
        {'F' , "K71"   }, {'G'   , "oD7"   }, {'H' , "NyM" }, {'I' , ";YR"   },
        {'J' , "L/\""  }, {'K'   , "PoT"   }, {'L' , "g&j" }, {'M' , "*rG"   },
        {'N' , "}jd"   }, {'O'   , "t9-"   }, {'P' , "T{ " }, {'Q' , "+?\x7f"},
        {'R' , "-8."   }, {'S'   , ",wL"   }, {'T' , "0g]" }, {'U' , "nS~"   },
        {'V' , "kGl"   }, {'W'   , "f4o"   }, {'X' , "5xy" }, {'Y' , "%]t"   },
        {'Z' , "!0C"   }, {'['   , "d#&"   }, {'\\', "MZv" }, {']' , "R[%"   },
        {'^' , "cl$"   }, {'_'   , "?H+"   }, {'`' , "{U(" }, {'a' , "xp#"   },
        {'b' , ")iA"   }, {'c'   , "(.4"   }, {'d' , "sL\t"}, {'e' , "Y!*"   },
        {'f' , "3$D"   }, {'g'   , "\x7fN?"}, {'h' , "mPw" }, {'i' , "U\t;"  },
        {'j' , "SVU"   }, {'k'   , "|si"   }, {'l' , ":5a" }, {'m' , "_ac"   },
        {'n' , "eKP"   }, {'o'   , "FXg"   }, {'p' , "X;Q" }, {'q' , "1WI"   },
        {'r' , "i\"O"  }, {'s'   , "lmF"   }, {'t' , "ZMh" }, {'u' , "H%|"   },
        {'v' , "'(6"   }, {'w'   , "\\Fp"  }, {'x' , "=Jn" }, {'y' , "$2z"   },
        {'z' , "yA/"   }, {'{'   , "7=_"   }, {'|' , "`_K" }, {'}' , "QOZ"   },
        {'~' , " B,"   }, {'\x7f', "6eW"   }
    };

    static string DecodeVbeCore(string s)
    {
        s = s.Replace("@&", "\n")
             .Replace("@#", "\r")
             .Replace("@*", ">")
             .Replace("@!", "<")
             .Replace("@$", "@");

        var sb = new StringBuilder();
        int index = -1;

        foreach( char c in s ) {
            if ( 0 <= (int)c && (int)c <= 127 ) {
                index++;
            }

            if ( DecoderTable.ContainsKey(c) ) {
                sb.Append(DecoderTable[c][IndexTable[index%64]]);
            }
            else {
                sb.Append(c);
            }
        }
        return sb.ToString();
    }

    static string DecodeVbe(string s)
    {
        Regex r = new Regex(@"^#@~\^......==(.*)......==\^#~@\s*");
        Match m = r.Match(s);
        if (m.Success) {
            return DecodeVbeCore(m.Groups[1].Value);
        }
        return null;
    }

    [STAThread]
    static void Main(string[] args)
    {
        if (args.Length==1 && File.Exists(args[0])){
            string s = File.ReadAllText(args[0], Encoding.GetEncoding("Shift_JIS"));
            string result = DecodeVbe(s);

            if (result!=null){
                File.WriteAllText(Path.GetFileNameWithoutExtension(args[0])+".out.txt", result, Encoding.GetEncoding("Shift_JIS"));
            }
            else {
                Console.WriteLine("Parse Error");
            }
        }
    }
}

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