20201124のC#に関する記事は7件です。

【Unity】UnityLearnおすすめ講座 -初心者用-

Unity Learnとは

リンク: Unity Learn
Unity公式が提供している、Unity学習サイト。
初心者から上級者まで幅広く講座があるにもかかわらず、全て無料。
本記事はUnity学習歴1年になる私が、受講して良かったと思えるものを抜粋(コースタイプのみ)。当然まだ受けれていないものもあるので、随時更新する。他にもこれがいいよってのがあれば教えていただけると幸いです。

※Unity Learnでの学習は基本的に英語です。とはいえ、自動翻訳を使ったり、字幕を見ながら学習すれば大した支障はないと思われる。英語の勉強にもなるので、気負わずに。

1.0 基礎講座

1.1 Create with Code

講座リンク: Create with Code

これからUnityを始める初心者に最もおすすめ!
Unityのインストール方法から、簡単な3Dゲームを作成するまでを動画付きチュートリアル形式で学習できる。
この講座を受講すればUnityの基本的な動作、基本的な注意点はマスターできる。
image.png

1.2 Beginning 3D Game Development

講座リンク: Beginning 3D Game Development

3Dゲームを作成したい人におすすめ!
GameKitを含めた3つのプロジェクトを作成していきながら、3Dゲームの基礎が学べる。
Create with Codeと違い、こちらは簡易的なゲームを丸々一本作りながら学習ができる。
image.png

1.3 Beginning 2D Game Development

講座リンク: Beginning 2D Game Development

2Dゲームを作成したい人におすすめ!
こちらは2D版。3Dのものと同様に3つのプロジェクトを作成していきながら学習できる。
image.png

2.0 プログラミング講座

2.1 Unity C# Survival Guide

講座リンク: Unity C# Survival Guide

プログラミング初心者な人におすすめ!
Unityでゲームを作りたいけど、そもそもプログラミングができない人や、C#に触れたことのない人におすすめする講座。C#の基本的な機能から、応用的な機能までを動画でサンプルを作りながら学べる。
また、学習の途中で小テスト(Challenge)もあるので、アウトプットもできる万能講座。
ゲームでのC#機能(ラムダやLINQ等)の使用方法も学べるので、中級者にもおすすめ。
image.png

2.2 Beginner Programming: Unity Game Dev Course

講座リンク: Beginner Programming: Unity Game Dev Course

Unity C# Survival Guideを終えた人におすすめ!
Survival Guideよりは若干高度な内容となっているプログラミング講座。
座学的に学べる動画もついており、UnityでC#をどのように使うかを掘り下げられる。
難点は英語が聞き取りにくい講師の方もいること。画面を見ながら雰囲気を掴むように学習すると良い。
image.png

3.0 ゲームデザイン講座

3.1 Beginner Design: Unity Game Development Course

講座リンク: Beginner Design: Unity Game Development Course

ゲームデザインを学びたい人におすすめ!
ゲームを作りたいけれど、どのように構想を膨らましていけばいいかわからない、どの作業から進めればいいのかわからない場合に強く受講をおすすめする講座。
アイデアの固め方、タイムラインとリソースの作成方法、デザインドキュメントの作成方法、アウトラインの作成方法を学習することができる。
image.png

4.0 マネジメント講座

4.1 Growing your mobile game

講座リンク: Growing your mobile game

モバイルゲームを作りたい人におすすめ!
こちらはチュートリアル形式ではなく、どのようにモバイルゲームを作成するかの設計思想等が学習できる。初心者が闇雲にモバイルゲームを作っても非効率的だし、収益性が考えられてなかったりする。最初は先人たちの知恵を借りて、どのように作られているのかを学習するのが大事だと思う。
モバイルゲームで稼ぐという目標のある方には非常におすすめの講座になっている。
image.png

終わりに

本記事の注意点としては、チュートリアルだけをやっても身につかないということです。ここまで書いてきて何を言ってるんだと思われるかもしれないけど、チュートリアルだけをやるのは「できた気になっている」段階だと思ってます。実際に自分でゲームを作ってみて、壁にぶつかりながらリリースまで持っていくのが1番の学習になる気がします(もちろんバランスは大事だけどね...)。

今回は自分が学習してきたものだけに絞りましたが、
他にもいい講座があったら是非教えてくださいね!!

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

C#でタイムアウト付きの File.Exists および Directory.Exists を実装する

目的

Windows共有フォルダ上のファイルやディレクトリの有無を確認するときに、System.IO.File.ExistsやSystem.IO.Directory.Existsを使うと、対象のサーバーに繋がらない際に数秒から数十秒、長い場合数分待たされる場合があります。
今回は指定した秒数以内に接続できない場合 false を返すようなタイムアウト付きの有無確認を実装します。

条件

  • Windowsファイル共有 (SMB/CIFS)
  • .NET 5.0(.NET Framework 4.6以上でもおそらく動作)

対象

  • 共有フォルダを持つサーバーの死活を手っ取り早く確認したい人(PINGが使えないケースなど)
  • 死活がわからない共有フォルダ上のファイルの有無を手っ取り早く確認したい人
  • とりあえず当該動作を探していた面倒くさがりの初心者

実装

細かな例外処理等は省略。コードの美しさも省略。

using System.Threading;
using System.Threading.Tasks;
using System.IO;

public class TimeoutIOUtils
{
  //タイムアウト秒
  public static int TimeoutSeconds{ get; set; } = 3;

  //ファイル有無
  public static bool FileExists(string path)
  {
    return TimeoutCore(() => File.Exists(path));
  }

  //ディレクトリ有無
  public static bool DirectoryExists(string path)
  {
    return TimeoutCore(() => Directory.Exists(path));
  }

  //タイムアウト処理部分
  private static bool TimeoutCore(Func<bool> existFunction)
  {
    try
    {
      var source = new CancellationTokenSource();
      source.CancelAfter(TimeoutSeconds * 1000);
      var task = Task.Factory.StartNew(() => existFunction(), source.Token);
      task.Wait(source.Token);
      return task.Result;
    }
    catch (OperationCanceledException ex)
    {
      return false;
    }
    catch (Exception ex)
    {
      throw;
    }
  }
}

追記: @albireo さんのコメントより改良案取り込み版

  //タイムアウト処理部分
  private static bool TimeoutCore(Func<bool> existFunction)
  {
    var task = Task.Factory.StartNew(() => existFunction());
    return task.Wait(TimeoutSeconds * 1000) && task.Result;
  }

使い方

private void Sample()
{
  TimeoutIOUtils.TimeoutSeconds = 2; //タイムアウトを2秒に設定

  var dir = @"\\192.168.0.XXX\example";
  var file = @"\\192.168.0.XXX\example\example.txt";

  //ディレクトリの有無確認
  if(TimeoutIOUtils.DirectoryExists(dir))
  {
    Console.WriteLine("ディレクトリあります");
  }
  else
  {
    Console.WriteLine("ディレクトリないです");
  }

  //ファイルの有無確認
  if(TimeoutIOUtils.FileExists(file))
  {
    Console.WriteLine("ファイルあります");
  }
  else
  {
    Console.WriteLine("ファイルないです");    
  }
}

補足

通常のFile.Existsなどと比べ若干のオーバーヘッド増加はあるはず。

Taskの使えない.NET Framework4.0とかだとThreadで似たようなことができます。

上記でとりあえず期待通り動作はしますが、Taskの扱いは筆者も初心者なので後処理含め正しくはないかもしれません。
各々調べて適当に改良してご利用下さい。

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

LINQによるデータ操作(1)

こんにちは、Mottyです。
久々の投稿となりますが、今回はC#のLINQについてまとめてみました。

概要

LINQは総合言語クエリ(Language Integrated Query)の略称で、C#言語に直接クエリ機能を統合した言語です。LINQを使用すると、ソースから必要なデータをクエリしたり抽出したり…といったことを最小限のコーディングで実行できます。
なぜ統合なのかというと、様々な種類のデータ集合(ListやCollection,SQLデータベース、XML,JSONデータなど)に対して標準化された方法でデータに問い合わせることができるからということです。
C#においてデータの操作というと、ほぼほぼLINQ構文によるものになるので、覚えておいて損はないだろうと思います。

LINQ構文の種類

LINQの書き方には主に2種類あります。SQL文風のクエリ構文と、ドットで命令をつないでいくメソッド構文です。下記それぞれ比較してみましょう。

クエリ構文

query.cs
 var list = new List<int> { 1, 51, 64, 2, 23, 24 };

//クエリ構文
 var query =
      from x  //from句のものは何でもいい、仮にxとおく
      in list //抽出したいList
      where x % 2 == 0 // 抽出条件
      orderby x //並べ替え
      select x;  //最後はSelect句で締める

foreach (var li in query)
            {
                Console.WriteLine(li);
            }
Console.Readkey();

//output
//2
//24
//64

メソッド構文

method.cs
var method = list
      .Where(x => x % 2 == 0)
      .OrderBy(x => x)

foreach (var li in method)
            {
                Console.WriteLine(li);
            }
Console.Readkey();
//output
//2
//24
//64     

比べてみるとわかるように、クエリ構文のほうがやや冗長になります。
また一部メソッド構文でしか使えない操作があり、紹介内容はメソッド構文に統一したいと思います。

構文例

要素の抽出

LINQでは条件を指定すると抽出できる構文が用意されています。

FirstOrDefault()

単一の要素を取得するメソッド。該当する要素のはじめ(First)を取得、該当しない(Default)場合はnullが返ってくる。

var list311 =new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
var query311 = list311.FirstOrDefault();
Console.WriteLine(query311); //output : 1
Console.ReadKey(); 

引数にラムダ式を指定することで条件を指定することが可能。

var list311 =new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
var query311 = list311.FirstOrDefault(x => x >= 5); //5以上のもの
Console.WriteLine(query311); //output : 5
Console.ReadKey(); 

条件に合致しない場合、規定値である0が返ってくる。

var list311 =new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
var query311 = list311.FirstOrDefault(x => x >100); //100以上のもの
Console.WriteLine(query311); //output : 0
Console.ReadKey(); 

文字列に対してのクエリ、見つからない場合はnullが返る。

var list311 = new List<string> { "Osaka", "Hokkaido", "Tokyo", "Fukuoka" };
var query311 = list311.FirstOrDefault(x => x == "Kanagawa");
Console.WriteLine(query311); // (null)
Console.ReadKey();

First

こちらも単一の要素を取得するメソッド。指定の要素が見つかればFirstOrDefaultと変わらないが見つからなかった場合、例外がthrowされる。

try
{
    var list312 = new List<string> { "Osaka", "Hokkaido", "Tokyo", "Fukuoka" };
    var query312 = list312.First(x => x == "Nagoya");
    Console.WriteLine(query312);
}
catch (Exception e)
{
    Console.WriteLine(e.Message); //output:シーケンスに一致する要素は含まれていません。
}
finally
{
    Console.ReadKey();
}

LastOrDefault

該当する要素の最後を取得する。

var list = new List<int> { 50, 60, 70, 80, 90 };
Console.WriteLine(list.LastOrDefault(x => x > 70)); //output: 90
Console.ReadKey();

SingleOrDefault

SingleOrDefault。文字通り要素数が単一であった場合に、その要素を返す。
合致しない場合は少しややこしい。複数あった場合は例外がスローされ、ひとつもなかった場合は規定値である0を返す。

var list = new List<int> { 50, 60, 70, 70, 80, 90 };
Console.WriteLine(list.SingleOrDefault(x => x == 70)); //Error:シーケンスに複数の要素が含まれています。
Console.WriteLine(list.SingleOrDefault(x => x == 80)); //output:80
Console.WriteLine(list.SingleOrDefault(x => x == 0)); //output:0
Console.ReadKey();

単一の取得に関して表に示すと、以下のようになる。

メソッド 要素が複数見つかった場合 要素が一つだけ見つかった場合 要素が見つからなかった場合
FirstOrDefault() はじめの要素 はじめの要素 0もしくはnull
First() はじめの要素 はじめの要素 例外がスローされる
LastOrDefault() 末尾の要素 末尾の要素 0もしくはnull
Last() 末尾の要素 末尾の要素 例外がスローされる
SingleOrDefault() 例外がスローされる 該当した要素 0もしくはnull
Single() 例外がスローされる 該当した要素 例外がスローされる

まとめ

LINQは構文としては簡単ですが、データを扱う場合はほぼかならず使う手法なので、何回も書いて覚えて損はないと思います。
次回もLINQシリーズを書こうと思っております。

参考

・Microsoft.Docs LINQ
https://docs.microsoft.com/ja-jp/dotnet/standard/linq/
・地平線に行く(LINQ構文を網羅)
https://yujisoftware.hatenablog.com/entry/20111031/1320068429
・陰干し中のゲーム開発メモ(SingleOrDefaultについての解説)
https://www.urablog.xyz/entry/2018/05/31/070000

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

WPFのListView,ListBoxで選択要素変更とコマンドを結び付ける方法

はじめに

本記事は、WPFのListView,ListBoxで選択要素変更とコマンドを結び付ける方法を備忘録として残すことを目的としています。

方法

筆者はこちらの記事を参考にしました。
以下のSampleWindowのDataContextにはSampleWindowViewModelが設定されているとします。

  • SampleWindowViewModel.cs
using Sample.ViewModels
{
    // SampleWindowViewModelのViewModel
    public class SampleWindowViewModel
    {
        // 選択変更時のコマンド
        public ICommand SelectionChangedCommand { get; }
    }
}
  • SampleWindow.xaml
<Window x:Class="Sample.Views.SampleWindow"
        xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity">

    <Grid>
        <ListView ・・・>
            <!-- ListViewのSelectionChangedイベントが発生するとSelectionChangeCommandコマンドが実行されるように設定 -->
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="SelectionChanged">
                    <i:InvokeCommandAction Command="{Biding Path = SelectionChangedCommand}" />
                </i:EventTrigger>
            </i:Interaction.Triggers>
    </Grid>
</Window>

SampleWindow.xamlの「xmlns:i=・・・」の部分でSystem.Window.Interactivityの機能を使えるように名前空間をusingしています。その後のListViewの「i:Interaction.Triggers」でトリガを設定しています。具体的には「i:EventTrigger EventName="SelectionChanged"」なので、選択変更後イベントをトリガにしてアクションを実行します。アクションは「i:InvokeCommandAction Command="{Biding Path = SlectionChangedCommand}"」なので、DataContextのSelectionChangeCommandという名前のコマンドが実行されます。具体的にはSampleWindowViewModel.SelectionChangeCommandが実行されることになります。

参考文献

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

C# PDFの結合・分割

皆さん、お元気でいらっしゃいますか?寒さ厳しい折、どうぞご自愛ください。
さて、今日はPDFファイルについての話です。Spire.PDFというライブラリを通じて、PDFを結合・分割する方法を紹介することにして、どうのようにMergeFiles ()とSplit()というメソッドでこれを実現するか見せてあげましょう。
では、始めましょう

下準備
1.E-iceblueの公式サイトからFree Spire.PDF無料版をダウンロードしてください。

f:id:lendoris:20201124150127p:plain


2.Visual Studioを起動して新規プロジェクトを作成してから、インストールされたファイルにあった相応しいSpire. PDF.dllを参照に追加してください。
(Net 4.0を例としたら、デフォルトパスは“Bin→NET4.0→PDF.dll”というようです。)

f:id:lendoris:20201124150156p:plain

PDFの結合
MergeFiles () といstaticメソッドで実現することができます。このメソッドには三つのオーバーロードがあります。
 

// Streamから
public static PdfDocumentBase MergeFiles(Stream[] streams);

//Stringから
public static PdfDocumentBase MergeFiles(string[] InputFiles);

//指定するパスから
public static PdfDocumentBase MergeFiles(string firstInputFile, string secInputFile);

結合前

 

f:id:lendoris:20201124150652p:plain

f:id:lendoris:20201124150705p:plain 

サンプルコード 

using Spire.Pdf;
using System;

namespace ConsoleApplication
{
class Program
{
static void Main(string[] args)
{
String[] files = new String[] { "ファイル1.pdf", "ファイル2.pdf", };
PdfDocumentBase doc = PdfDocument.MergeFiles(files);
doc.Save("結合1.pdf", FileFormat.PDF);
}
 }
  }

結合後

 

f:id:lendoris:20201124150738p:plain

PDFの分割 

PdfDocument doc = new PdfDocument("結合1.pdf");
String pattern = "分割{0}.pdf";
doc.Split(pattern);
doc.Close();

以上です。
ここまで読んでくれてありがとうございます。

 

 

 

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

LibreOffice CalcをJScriptなどから操作してみた

はじめに

を参考にさせて頂きました。圧倒的感謝……!

環境

  • Windows 10 Home (64bit)
  • Visual Studio Community 2019

サンプルソース

JScript

libreoffice.js
{
    var factory = WScript.CreateObject("com.sun.star.ServiceManager");
    var loader = factory.createInstance("com.sun.star.frame.Desktop");
    var doc = loader.loadComponentFromURL("file:///C:/data/test.ods", "_blank", 0, []);

    var sheets = doc.getSheets();
    var sheet = sheets.getByName("Sheet1");
    var cell = sheet.getCellByPosition(0, 0);
    cell.setFormula("hello, world");
}

VB.NET

Module1.vb
Module Module1

    Sub Main()
        Dim factory, loader, doc As Object
        Dim d(0) As Object

        factory = CreateObject("com.sun.star.ServiceManager")
        loader = factory.createInstance("com.sun.star.frame.Desktop")
        doc = loader.loadComponentFromURL("private:factory/scalc", "_blank", 0, d)

        Dim sheets, sheet, cell As Object
        sheets = doc.getSheets()
        sheet = sheets.getByName("Sheet1")
        cell = sheet.getCellByPosition(1, 1)
        cell.setFormula("hello, world")
    End Sub

End Module

C#

LibreOffice SDKを使う方法もあるが、使わない方法もある。

Program.cs
using System;
using System.Reflection;
using System.Runtime.InteropServices;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            var t = Type.GetTypeFromProgID("com.sun.star.ServiceManager");
            var factory = Activator.CreateInstance(t);

            object[] a = { "com.sun.star.frame.Desktop" };
            var loader = factory.GetType().InvokeMember("createInstance",
                BindingFlags.InvokeMethod, null, factory, a);

            object[] b = { };
            object[] c = { "private:factory/scalc", "_blank", 0, b };
            var doc = loader.GetType().InvokeMember("loadComponentFromURL",
                BindingFlags.InvokeMethod, null, loader, c);

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

イベントハンドラって?

初めに

5000連休欲しい

イベントハンドラとは

日々のC#学習で「イベントハンドラ」について学習しましたが、あまり理解できなかったので復習のために。

イベントハンドラとは、イベントが発生したときに実行される処理のことで、この処理を行うためにデリゲートが渡されます。

・・・急にイベントとかデリゲートとか知らない単語が出てきた、という人のために、それぞれ簡単に説明すると

イベント
コンピューター上で発生する「キーが押された」、「マウスが移動した」といった何らかの事象

デリゲート
メソッドをオブジェクトの一種として扱うことのできる機能

です。デリゲートは変数のような扱いができるので、デリゲートの中に関数を複数個入れて実行、といった使い方ができます。

まとめると

  • デリゲートに処理を格納
  • そのデリゲートをイベントハンドラに渡す
  • すると、特定のイベント発生時にデリゲートの中の処理が実行される

というわけですね。

便利なんこれ?

実は、まだ学習したばかりで自分でプログラムを書いてもいないので、あまり利点がつかめていません・・・。学習して出た感想といえば
(あるイベント発生時の処理を行う、ということはGUIアプリを作成する際に使えそうだな~)
くらいです。
今後の勉強会で、また何か分かったらサンプルプログラム付きで説明したいです。

では。

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