FC2ブログ
02 «1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.23.24.25.26.27.28.29.30.31.» 04

ハルシオンシステムの気ままBlog

株式会社ハルシオンシステムのメンバーが送る、UnityやらJavaやらの技術的話題から、自社開発のアプリの宣伝とかとかのブログです。ほんと気ままにいきたいと思います。更新日は毎週 月 木でっす!

 

【ハルシオンブログ】Unity+LinqでOrderByを使ってみる。 

おはようございます。坂内です。

昨日の雪に続き、今日もちょー寒いじゃないですか。


さて、今日もUnityxLinqのお話。

Linqを使ってGroupingをする場合はこんな感じで書くことができます。

[Test0330.cs]

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

public class Test0330 : MonoBehaviour
{
public class WeaponData {
public int WpNo;
public enum WeaponType {
Sword,
Blunt,
Spear,
}
public WeaponType weaponType;
public string WpName;
public int damage; // 攻撃力
public float speed; // 攻撃速度

public WeaponData(int no, WeaponType type, string name, int atkdamage, float atkspeed) {
WpNo = no;
weaponType = type;
WpName = name;
damage = atkdamage;
speed = atkspeed;
}
}

void Start()
{
List<WeaponData> weapon = new List<WeaponData>
{
// 剣
new WeaponData(0, WeaponData.WeaponType.Sword, "壊れた剣", 5, 2f),
new WeaponData(1, WeaponData.WeaponType.Sword, "銅の剣", 7, 1.5f),
new WeaponData(2, WeaponData.WeaponType.Sword, "鉄の剣", 9, 1.7f),
// 鈍器
new WeaponData(3, WeaponData.WeaponType.Blunt, "ひび割れたバット", 8, 5f),
new WeaponData(4, WeaponData.WeaponType.Blunt, "棍棒", 12, 7f),
new WeaponData(5, WeaponData.WeaponType.Blunt, "鉄のメイス", 8, 3f),
// 槍
new WeaponData(6, WeaponData.WeaponType.Spear, "折れた槍", 3, 2.4f),
new WeaponData(7, WeaponData.WeaponType.Spear, "銅の槍", 5, 2.1f),
new WeaponData(8, WeaponData.WeaponType.Spear, "鉄の槍", 7, 1.6f),
};

// 攻撃速度が2以上の武器を攻撃力が高い順に取り出す
Debug.Log("-----------------攻撃速度が2以上の武器を攻撃力が高い順--------------------");
IEnumerable<WeaponData> results2 = weapon
.Where(x => x.speed >= 2f)
.OrderByDescending(x => x.damage);
foreach(WeaponData result in results2) {
Debug.Log(result.WpName + " 攻撃力:" + result.damage + " 攻撃速度:" + result.speed + "s");
}

// 武器種別に攻撃速度の速い順に取り出す
Debug.Log("-----------------武器種別に攻撃速度の速い順に取り出す--------------------");
IEnumerable<IGrouping<WeaponData.WeaponType, WeaponData>> results3 = weapon
.OrderBy(x => x.speed)
.GroupBy(x => x.weaponType);
foreach(IGrouping<WeaponData.WeaponType, WeaponData> group in results3) {
Debug.Log("***" + group.Key + "***");
foreach(WeaponData result in group) {
Debug.Log(result.WpName + " 攻撃力:" + result.damage + " 攻撃速度:" + result.speed + "s");
}
}
}
}



結果はこちら



ちゃんと「武器種別に攻撃速度の速い順」で並んでますね。

GroupByというメソッドを使うことで種類別でまとめることができます。
SQLのGroupByと一緒ですね。

特殊なのは、Enumerable<IGrouping<WeaponData.WeaponType, WeaponData>> results3 = weapon.OrderBy(x => x.speed).GroupBy(x => x.weaponType);

ここ。

IGroupingというクラスがOrderByをしたときの戻りの型になっており、これが各種類別でまとめた際の1つの塊になっています。
このIGroupingのValueの方に最小単位のアイテムが格納されているので、以下の形で取り出すことができるといった感じになっているようです。

foreach(IGrouping<WeaponData.WeaponType, WeaponData> group in results3) {
Debug.Log("***" + group.Key + "***");
foreach(WeaponData result in group) {
Debug.Log(result.WpName + " 攻撃力:" + result.damage + " 攻撃速度:" + result.speed + "s");
}
}



ということで、LinqのGroupByの使い方でした!

あでゅ~ノシ

Category: 開発日記(Unity)

tb 0 : cm 0   

【ハルシオンブログ】新しくクラスを作らないでメソッドから複数の戻り値を受け取りたいとき 

こんにちは。
大坂です。

戻り値が複数欲しいメソッドを作ったときに新しいクラスをわざわざ作りたくないときはTupleを使うと便利かもしれません。
戻り値が多くなりすぎるとぐちゃぐちゃするので使い所は気をつけたほうが良さそうですが。。

使い方はこんな感じ

void Start()
{
var test = TestMethod();
Debug.Log($"{test.Item1}:{test.Item2}");
}

private (bool, int) TestMethod()
{
return (true, 1);
}


結果。


という風に簡単に複数の戻り値を得られますね!
乱用するとコードの可読性が落ちていくので、あまり使わないほうがいいかもしれませんが・・・。

それではこれにてノシ

Category: 開発日記(Unity)

tb 0 : cm 0   

【ハルシオンブログ】Listの特定のアイテムを取り出す時って、Findを使ってますか?Linqを使ってますか? 

こんにちは!坂内です!

UnityでListから特定のアイテムを取り出す場合、Find使ってますか?Linqを使ってますか?

Findを使う場合はこんな感じ。
(複数取り出すのでFindAllを使ってます)

[TestClass.cs]

using System.Collections.Generic;
using UnityEngine;

public class Test0323 : MonoBehaviour
{
public class TestClass {
public int no;
public string name;
}
public List<TestClass> testClasses;

void Start()
{
testClasses = new List<TestClass>();
// 初期データ
for(int i = 0; i < 10; i++) {
TestClass testClass = new TestClass();
testClass.no = i;
testClass.name = "Name:" + i;
testClasses.Add(testClass);
}
ViewTestClass(testClasses);

// iが2と5の物だけを出力
List classes25 = new List<TestClass>();
classes25 = testClasses.FindAll(x => x.no == 2 || x.no == 5);
ViewTestClass(classes25);
}

void ViewTestClass(List<TestClass> args) {
Debug.Log("-----------------------------------------------");
foreach(TestClass testClass in args) {
Debug.Log("No:" + testClass.no + "/Name:" + testClass.name);
}
}
}





同じことはLinqでもできますね。


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

public class Test0323 : MonoBehaviour
{
public class TestClass {
public int no;
public string name;
}
public List<TestClass> testClasses;

void Start()
{
testClasses = new List<TestClass>();
// 初期データ
for(int i = 0; i < 10; i++) {
TestClass testClass = new TestClass();
testClass.no = i;
testClass.name = "Name:" + i;
testClasses.Add(testClass);
}
ViewTestClass(testClasses);

// iが2と5の物だけを出力
var classes25 = testClasses.Where(x => x.no == 2 || x.no == 5);
ViewTestClass(classes25);
}

void ViewTestClass(IEnumerable<TestClass> args) {
Debug.Log("-----------------------------------------------");
foreach(TestClass testClass in args) {
Debug.Log("No:" + testClass.no + "/Name:" + testClass.name);
}
}
}



LinqではFindの代わりにWhereを使うことで特定のアイテムを取り出すことが可能です。

LinqはUsing System.Linq;を書かないといけません。
また、戻り値はListではなくIEnumerableになります。

使いやすいほうを是非お使いください。

ってことで、Listデータの絞込についてでした!あでゅ~ノシ

Category: 開発日記(Unity)

tb 0 : cm 0   

【ハルシオンブログ】LinqのAny使っていますか? 

こんにちは。
大坂です。

今週ももう木曜日でした。
明日から3連休の方々もコロナであんまり出歩けないかもしれませんが、ゆっくり休んでくださいまし。

さて今週はLinqのAnyのお話です。
配列やリストなどに特定条件のものが存在するかを確認できるやつです。

では早速コードです。

int[] test_1 = { 0, 2, 1, 5, 4, 3 };
int[] test_2 = { };

// 条件なし(要素が存在するか)
Debug.Log("test_1:" + test_1.Any());
Debug.Log("test_2:" + test_2.Any());

// 条件あり
// 要素に 0 が存在するか
Debug.Log("test_1(0):" + test_1.Any(x => x == 0));
// 要素に 6 が存在するか
Debug.Log("test_1(6):" + test_1.Any(x => x == 6));

結果


とまぁこんな感じで使えますね。
条件なしの場合はLengthやCountで0以上とかを見なくて良くなりますし、
条件指定の場合はループで見なくて良くなるので結構使えますね。

ということでまたもやLinqのお話でした。
ではまたノシ

Category: 開発日記(Unity)

tb 0 : cm 0   

【ハルシオンブログ】お手軽なフリーリソース管理アセットの紹介 ResourceChecker! 

こんにちは。坂内です。

なかなか素敵なアセットがあったので紹介。

フリーなので、気軽に入れれていいですよ。




これこれ。

簡単にリソースの量が見れるやつ。

どんな感じになるかというと、こんな感じで1画像ファイルを置いてみます。
※イラスト屋さんお借りします



Window -> Resource Checkerを選択。


そうすると、こんなウインドウが開きます。



これでTextureの総容量が見れたり、そのファイルがどこにあるかとかも見れたりします。

ちょー便利!

ってことで、簡単にリソースを管理できるアセットの紹介でした。

あでゅ~ノシ

Category: 開発日記(Unity)

tb 0 : cm 0   

【ハルシオンブログ】LinqのOrderByとOrderByDescendingは便利ですよね 

お疲れさまです。
大坂です。

リストとかを簡単に昇順、降順に並べたいときはLinqのOrderByとOrderByDescendingを使うと便利ですよね。
    IEnumerable test = new[] { 0, 2, 1, 5, 4, 3 };
// 昇順
List orderTest = test.OrderBy(x => x).ToList();
Debug.Log(string.Join(",", orderTest));
// 降順
List orderByDescendingTest = test.OrderByDescending(x => x).ToList();
Debug.Log(string.Join(",", orderByDescendingTest));

結果


ということで昇順、降順の並べ替えを簡単にできます!

ではではノシ

Category: 開発日記(Unity)

tb 0 : cm 0   

【ハルシオンブログ】C#バージョン7のswitchでは型による分岐が可能!? 

おこんにちは!坂内っす。

また今日は寒くなりましたね・・・・・

これは風邪をひく気候!みなさん気を付けてくださいませ。

さてC#のおはなし。

C#のバージョン7以降での対応になりますが、switch分で”型による分岐”ができるようですよ。

どういうことかというと、こんな感じ。


switch(obj){
case int i:
~~~ intの場合の処理 ~~~
break;
case float f:
~~~ floatの場合の処理 ~~~
break;
case string s:
~~~ stringの場合の処理 ~~~
break;
}

なかなか面白い書き方ですよね。

ただこの書き方ができるとしても、なかなか使う機会はなさそう・・・

C#バージョン8だともっと面白いことができるみたいですよ。

またそのうちUnityが対応したら紹介したいと思います。

では!あでゅ~ノシ

Category: 開発日記(Unity)

tb 0 : cm 0   

【ハルシオンブログ】Listの中の特定の値のIndexが知りたかった 

こんにちは。
大坂です。

3月に入りましたね!
花粉の季節ですね!

Listの中の特定の値のIndexが知りたいときなんかがありました。
そんなときはLinqを使ってあげて取得してあげましょうというお話です。

こんな感じでやったら取得できます。
IEnumerable<int> test = new[] { 0, 2, 1, 0, 1, 3 };
int searchNo = 1;
var indexes =
//要素とそのインデックスを匿名クラスのリストに入れる
test.Select((item, index) => new { Index = index, Value = item })
// 特定したい検索条件を指定
.Where(item => item.Value == searchNo)
// インデックだけを取得
.Select(item => item.Index).ToList();
Debug.Log(string.Join(",", indexes));

結果


ちゃんと取れていますね~
それでは今週もこんな感じで終わりですノシ

Category: 開発日記(Unity)

tb 0 : cm 0   

【ハルシオンブログ】複数のファイルで、1つのクラスを指定する、partialについて。 

おこんにちは。坂内っす。

世の中コロナウィルスが散乱しているようですね・・・
飲みは控えましょう。

さて、Unityでコードを書いていると、めっさ1ファイル内のコードが増えてきたりしますよね。

そんな時はファイルの分割ができるぽいですよ!

例えばですが、こんなファイルがあるとします。

[Test1.cs]

using UnityEngine;

public class Test1 : MonoBehaviour
{
void Start()
{
AAA();
BBB();
}

void AAA() {
Debug.Log("AAA");
}

void BBB() {
Debug.Log("BBB");
}
}



partialという指定をクラスにすることで、複数ファイルを1つのクラスとして使用することができます。

Startの流れをTest1.csファイルに、実際の関数はTest1_2.csファイルに置くとこんな感じです。

[Test1.cs]

using UnityEngine;

public partial class Test1 : MonoBehaviour
{
void Start()
{
AAA();
BBB();
}
}



[Test1_2.cs]

using UnityEngine;

public partial class Test1 : MonoBehaviour
{
void AAA() {
Debug.Log("AAA");
}

void BBB() {
Debug.Log("BBB");
}
}



クラス名=ファイル名の決まりが、partialを付けることで、無視できます。(もちろんわかりやすい名前にしてね)

こんな感じで複数のファイルを1つのクラスとして使用できます。

では、あでゅ~ノシ

Category: 開発日記(Unity)

tb 0 : cm 0