転職を繰り返したサラリーマンの多趣味ブログ

30才未経験でSEに転職した人の多趣味ブログ

C#を勉強する15_文字列の連結と分割

次は文字列の連結と分割。文字連結といえば、+演算子

var name = "山田" + "TARO";

連結はこの+演算子でだいたい事足りるが、文字列配列の場合はJoinメソッドを使うと便利な使い方ができる。

var languages = new[] { "C", "Java", "VB", "Ruby" ,};
// 区切り文字を指定
var separator = "+";
var result = String.Join(separator, languages);
// C+Java+VB+Rubyと出力される
Console.WriteLine(result);

Joinメソッドは、指定した区切り文字で文字配列の各要素を連結したが、Splitメソッドでは指定した文字で文字列を分割することができる。

var text = "The quick brown fox jumps over the lazy dog";
// {"The", "quick", "brown", "fox", "jumps", "over", "the", "lazy", "dog" }が格納される
string[] words = text.Split(' ');

Splitメソッドはオーバーロードされたメソッドもあり、これを使うと複数の区切り文字を指定できる。

var text = "The quick brown fox jumps over the lazy dog.";
// 空白とピリオドを区切り文字に指定している。
// 第2引数は、空の配列要素を含めないように指定
string[] words = text.Split(new[] { ' ', '.' },StringSplitOptions.RemoveEmptyEntries);

ここまで文字列連結についてまとめてきたが、文字列は不変オブジェクトである。
以下のようなコードの場合、s1は新たな6文字分のインスタンスが作成されている。

var s1 = "ABC";
s1 = s1 + "XYZ";

毎回インスタンスを作成していたのでは非効率なため、StringBuilderクラスが用意されている。

var sb = new StringBuilder();
// 文字列を追加
sb.Append("やまだ");
sb.Append("TARO");

// やまだTAROと出力
// ToString()メソッドで、文字列に変換
Console.WriteLine(sb.ToString());

C#を勉強する14_文字列の変換

次は本当によく出てくる文字列の変換。競技プログラミングの問題で、「本当は'L'と入力するところを、誤って'i'と入力した。プログラムで'i'の部分を'L'に変換すること」などがある。

文字列の前後の空白を取り除く

var target = " non-whitespace ";
// 空白が取り除かれた文字列を返す
var replaced = target.Trim();

上では前後の空白を取り除いたが、前と後ろの空白だけ取り除きたい場合のメソッドも用意されている。

var replace1 = target.TrimStart();
var replace2 = target.TrimEnd();

指定した位置から任意の数の文字を削除する

var target = "01234ABC567";
// ABCが削除され、文字列「01234567」を返す
var result = target.Remove(5, 3);

文字列に別の文字列を挿入する

var target = "01234";
// 01abc234を返す
var result = target.Insert(2, "abc");

文字列を変換する

var target = "I hope you";
// hopeがwishに置き換えられ、I wish youを返す
var replaced = target.Replace("hope", "wish");
var target = "I hope you";
// 小文字を大文字に変換し、返す
var replaced = target.ToUpper();
// 大文字を小文字に変換し、返す
var replaced2 = replaced.ToLower();

C#を勉強する13_文字列の検索と抽出

前回は、文字列の判定だった。そのため戻り値はboolだったが、今度は文字列の抽出を行う。

部分文字列を検索し、その位置を求める

var target = "1234ABC567";
// 0から始まるため「4」を返す
var index = target.IndexOf("ABC");

文字列の一部を取り出す

var target = "1234ABC567";
var index = target.IndexOf("ABC");
// 指定した開始位置から最後まで取り出す
var searchStr = target.Substring(index); // ABC567が抽出される

Substringは、取り出す長さも指定できる。
ここで注意が必要なのが、第2引数に渡すのは第1引数から数えば長さということ。以下であれば、Aからスタートした長さなので長さを3にすると「ABC」と出力されるが、長さを6を指定すると「ABC567」が出力される。

var target = "1234ABC567";
var index = target.IndexOf("ABC");
// ABCを抽出する
var searchStr = target.Substring(index, 3);

C#を勉強する12_文字列の判定

前回に引き続き、文字列の操作編。今回は文字列の判定です。
文字列に関わらず、ソースを書く際気をつけないといけないのが、nullpointerexceptionだ。Stringクラスの静的メソッドには、このnull判定が用意されている。

// null あるいは空文字列の場合、trueを返す
if(String.IsNullOrEmpty(str)) { }

空文字かどうかだけ調べる場合は

// 空文字列の場合、trueを返す
if(str == String.Empty) { }

あと、こんな判定もある。

// null 空文字列か空白文字列かを調べる
if(string.IsNullOrWhiteSpace(str)) { }

ここまではnull判定だったが、文字列判定といえば「その文字列に〜が含まれているか」などの判定が多い。まずは、指定した部分文字列で始まっているか調べる方法だ。

// 指定した部分文字列で始まっている場合は、trueを返す
if(str.StartsWith("Visual")) { }

StartsWithがあるなら、EndsWithもある。

// 指定した部分文字列で終わっている場合は、trueを返す
if(str.EndsWith("Exception")) { }

次は、指定した部分文字列が含まれているかを調べる。

// 指定した部分文字列が含まれている場合は、trueを返す
if(str.Contains("Program")) { }

上は、文字列が含まれているかどうかだったが、次は文字が含まれているか。

var contains = str.Contains('b');

ここまでは部分文字列が含まれているかだったが、「小文字が入っているかどうか」など条件を満たしているかをチェックするにはLINQを使う。

var target = "C# Programming";
// 小文字がある場合は、trueを返す
var isExists = target.Any(c => Char.IsLower(c));

Anyメソッドは、文字列のうちいづれかが条件を満たしているとtrueを返した。すべての文字列が条件を満たしているかチェックする場合は、Allメソッドを使う。

var target = "141421356";
// すべての文字が数字の場合、trueを返す
var isAllDigits = target.All(c => Char.IsDigit(c));

C#を勉強する11_文字列の比較

転職活動のなかで、paizaに出会った。
paiza.jp
paizaのスキルチェックでは、プログラミングの問題を解くことができる。この問題を解く際に、文字列やリストを操作するメソッドを知っていると、ソースを簡潔に書くことができる。C#には色々便利なメソッドが用意されているので、まずは文字列操作から色々まとめていく。

文字列の比較

Javaで慣れているとequalsメソッドを使おうとするが、C#では==演算子を使える。

if (str1 == str2) { }

ただ、この文字列比較は色々種類がある。さっきの==演算子を使った比較は、完全一致が条件になるが、大文字・小文字の区別なく比較したい場合などもでてくる。
そういった時は、Compareメソッドを使う。

var str1 = "windows";
var str2 = "WINDOWS";
// 第3引数をtrueにすることで、大文字・小文字の区別なく比較
if (String.Compare(str1, str2, true) == 0) { }

このCompareメソッドはオーバーロードされたメソッドがある。

var str1 = "カステラ";
var str2 = "かすてら";
var cultureInfo = new CultureInfo("ja-JP");
// ひらがなとカタカナの区別なく文字列比較
if(String.Compare(str1, str2, cultureInfo, CompareOptions.IgnoreKanaType) == 0) { }
var str1 = "HTML5";
var str2 = "HTML5";
var cultureInfo = new CultureInfo("ja-JP");
// 全角と半角の区別なく文字列比較
if(String.Compare(str1, str2, cultureInfo, CompareOptions.IgnoreWidth) == 0) { }
var str1 = "Computer";
var str2 = "COMPUTER";
var cultureInfo = new CultureInfo("ja-JP");
// 全角・半角、大文字・小文字の区別なく文字列比較
if(String.Compare(str1, str2, cultureInfo, CompareOptions.IgnoreWidth : CompareOptions.IgnoreCase) == 0) { }

【Unity】ダメージをくらったら、Spriteを点滅させて無敵時間を作る方法

横スクロールアクションや、シューティングゲームでよくあるあれです。
まずSpriteを点滅させる方法は、SpriteRendererコンポーネントのアルファ値を変化させてやれば、実装できる。そのときのソースコードがこれ。

public SpriteRenderer sp;

// ダメージ判定フラグ
private bool isDamage{get; set;}

void Update() {

    // ダメージを受けている場合、点滅させる
    if(isDamage) {

        float level = Mathf.Abs(Mathf.Sin(Time.time * 10));
        sp.color = new Color(1f, 1f, 1f, level);

    }

}

// トリガー発生時
private void OnTriggerEnter2D(Collider2D collider) {

    StartCoroutine(OnDamage());

}

public IEnumerator OnDamage() {

    yield return new WaitForSeconds(3.0f);
        
    // 通常状態に戻す
    isDamage = false;
    sp.color = new Color(1f, 1f, 1f, 1f);

}

このソースであれば、敵からダメージを受けたら3秒間は点滅する。

あと無敵時間を作るのは簡単で、このダメージ判定フラグを利用する。
OnTriggerEnter2Dメソッド内に、ダメージを受けた際の挙動を実装する場合、ダメージ判定フラグがTrueならば処理をスキップさせてやればいい。

// トリガー発生時
private void OnTriggerEnter2D(Collider2D collider) {

    // ダメージ中は処理スキップ
    if(isDamage) {
        return;
    }

    StartCoroutine(OnDamage());

}

【Unity】TextがSpriteの後ろの隠れてしまう問題

タイトルそのまんまです。ゲーム作ってたら、こんな感じでTextオブジェクトがSpriteの後ろになってしまう問題が発生。
f:id:uuc1h:20200221200003p:plain
Sprite同士なら簡単にいくのだが、TextとSpriteだとどうしていいのかわからず、結構悩んでいた。
で、解決した方法がこちら。

  • Override Sortingにチェックをつける。
  • Order in Layerを1以上にする。

f:id:uuc1h:20200221200309p:plain
これで、さきほどSpriteに隠れていた「READY」というTextオブジェクトが、Spriteより上にくるようになった。
f:id:uuc1h:20200221200427p:plain