Star☆Unityメモ

Unityのちょっとしたことをメモって後で見返せれたらいいなサイト

array_key_exists

出来事

連想配列のkeyに一致しない数値が来たときに return したい

生み出したクソコード

$map = array(3=>array('name'=>'fuga'));

$input = 4;

$hoge = map[$input];
if( empty($hoge) ) {
    return;
}

echo $hoge;

問題

$hogeの判定時に notice エラーが出てしまう。

修正後

$map = array(3=>array('hoge'=>'fuga'));

$input = 4;
if(!array_key_exists($input, $map)){
    return 
}

echo $map[$input]['name'];

MySQL関連

初期パスワード確認

cat /var/log/mysqld.log | grep 'password is generated'

パスワード変更

set password for root@localhost=password('あなたのパスね!');

DB作成

create database hoge;

DBの利用

use hoge;

テーブルの作成

create table user(
id int,
name varchar(255),
pass varchar(255)
);

テーブルの確認

desc user;

テーブルに登録されているデータ確認

SELECT * from user;

error_log

sudo tail /var/log/httpd/error_log -f

ルーティングの設定を行う

ルーティング

  1. .htaccessファイルをルートにしたいディレクトリに設置します
<IfModule mod_rewrite.c>                                                    
RewriteEngine On
RewriteRule ^(.+)$ index.php [L]
</IfModule>
  1. appacheの設定ファイルをいじる
sudo vi /etc/httpd/conf/httpd.conf
<Directory "/var/www/html">
 AllowOverride All
  1. 更新
systemctl restart httpd

UNITY:画面サイズに比例してボタンのサイズを変える

概要

  1. ONGUI関数内でボタンを作ってあげたときに画面のサイズに比例してボタンのサイズを変更したい。

Rectについて把握しておく

https://docs.unity3d.com/ja/current/ScriptReference/Rect.html

第一引数:Xposition

第二引数:Yposition

第三引数:Width

第四引数:Height

って感じかな

画面のサイズを取得する

https://docs.unity3d.com/ja/current/ScriptReference/Screen.html

取得した数値をある数値で割ってRECTの引数に入れてあげればいいかなー

Unity:デバッグ機能(ローグライクを自分なりの解釈で作ってみる)

 イメージ

f:id:zvn_X:20170127015400g:plain

概要

  1. デバッグ中にキャラクターのHPが0になるといろいろと面倒くさかったのでデバッグ機能を追加する
  2. HPを+999するボタンを設置する.
  3. デバッグ機能はEditorで開いているときにのみ表示させたい

プラットフォーム判別

現在どのプラットフォームで動いているかを判別できます. これにより特定のプラットフォームでは一連の処理を無視することが可能になります.

下記のサイトがとてもわかり易くて参考になりました

qiita.com

私は今回【UNITYEDITOR】でのみデバッグ機能を動作させたいので対象箇所に

#if UNITY_EDITOR
#endif

を追加します

コード

using UnityEngine;
using System.Collections;

public class PlayerStatus : MonoBehaviour {

    StateManager sm;
    int m_HP = 20;
    Animator anim;

    public int HP{
        get { return m_HP; }
        set { m_HP = m_HP  + value; }
    }

    void Start(){
        sm = StateManager.Instance;
        anim = GetComponent<Animator>();
    }


    public void Receive(int damage) {
        anim.SetTrigger("Damage");
        HP -= damage;
        sm.HP.text = HP.ToString();

    }

   #if UNITY_EDITOR
    void OnGUI() {
        if (GUI.Button(new Rect(10, 10, 150, 100), "HP:+999")) {
            HP = 999;
            sm.HP.text = HP.ToString();
        }
    }
   #endif

}

デバッグ機能をまとめる

デバッグ機能と本機能がごちゃごちゃに混ざり合って可読性が落ちている気がします なのでpartialを利用してデバッグ機能と本機能を分けてあげます 参考ページ http://ftvoid.com/blog/post/803

コード

本機能

using UnityEngine;

public partial class PlayerStatus : MonoBehaviour {

    StateManager sm;
    int m_HP = 20;
    Animator anim;


    public int HP{
        get { return HP; }
        set { m_HP = m_HP  + value; }
    }


    void Start(){
        sm = StateManager.Instance;
        anim = GetComponent<Animator>();
    }


    public void Receive(int damage) {
        anim.SetTrigger("Damage");
        HP -= damage;
        sm.HP.text = HP.ToString();
    }
}

デバッグ機能

#if UNITY_EDITOR
using UnityEngine;

public partial class PlayerStatus{

    void OnGUI() {
        if (GUI.Button(new Rect(10, 10, 150, 100), "HP:+999")){
            HP = 999;
            sm.HP.text = HP.ToString();
        }
    }

}
#endif

UnityEditor上でもデバッグ機能をOFFにしたい.

UnityEditorを条件にしてしまうと実機テストするまでデバッグ機能がオフになったときの動作を確認することが出来ません.なのでUnityEditorで分けるのではなく独自の条件を追加してあげると良いかもしれません. File->Build Settings->PlayerSettings->Other Settings->Scripting Define Symbolsに新たに条件を追加してあげます.今回はDEVELOPという条件を追加してあげました. f:id:zvn_X:20170211030637p:plain

この箇所を削除すればDEVELOPで囲まれたコードは無視無視お疲れ様でした. もちろんこの箇所にDEVELOPを残していればEditor上でもDEVELOP機能のチェックができるよ

コレで気兼ねなくデバッグ機能を追加できそうです

Listにクラスを入れると予想以上に便利になった

概要

  1. List内要素に自作クラスの型を入れるとものすごくコードが読みやすくなったのでメモ

編集前のクソコード(モンスターコード)

// モンスターの回転と攻撃anim
if (sm.playerArray[enemyPositionX, enemyPositionZ -1] == 2) {
    iTween.RotateTo(monsterList[i], iTween.Hash("y", 180, "islocal", true, "time", 0.2f));
    monsterList[i].GetComponent<Animator>().SetTrigger("Attack");
    sm.player.GetComponent<PlayerStatus>().Receive(1);
    yield return new WaitForSeconds(0.4f);
} else if(sm.playerArray[enemyPositionX, enemyPositionZ + 1] == 2){
    iTween.RotateTo(monsterList[i], iTween.Hash("y", 0, "islocal", true, "time", 0.2f));
    monsterList[i].GetComponent<Animator>().SetTrigger("Attack");
    sm.player.GetComponent<PlayerStatus>().Receive(1);
    yield return new WaitForSeconds(0.4f);
} else if(sm.playerArray[enemyPositionX + 1, enemyPositionZ] == 2) {
    iTween.RotateTo(monsterList[i], iTween.Hash("y", 90, "islocal", true, "time", 0.2f));
    monsterList[i].GetComponent<Animator>().SetTrigger("Attack");
    sm.player.GetComponent<PlayerStatus>().Receive(1);
    yield return new WaitForSeconds(0.4f);
} else if(sm.playerArray[enemyPositionX - 1, enemyPositionZ] == 2){
    iTween.RotateTo(monsterList[i], iTween.Hash("y", 270, "islocal", true, "time", 0.2f));
    monsterList[i].GetComponent<Animator>().SetTrigger("Attack");
    sm.player.GetComponent<PlayerStatus>().Receive(1);
    yield return new WaitForSeconds(0.4f);
}

パット見でわかる同じことの繰り返し.

f:id:zvn_X:20170122164656p:plain

赤と青で囲った部分以外は全て同じなのに繰り返し繰り返し処理を書いてあげてます....これだと入力ミスの可能性は上がりますし可読性が皆無です.
この状況をなんとかしたい....

ステップ1.必要な情報を持つクラスを作る

今回は方角,またそれらに付随した回転角度などをまとめたクラスを作ります.

public class NEWS{
    public string name { get; set;}
    public int[] direction { get; set;}
    public int rotateValue { get; set; }
}

ステップ2List<リスト内の要素の型>

リスト内の要素の型を自作のクラスにしてインスタンスを作成します. 後はリストにインスタンスとそれに必要なデータを入れてあげる.

List<NEWS> news = new List<NEWS>();
news.Add(new NEWS() { name = "N", rotateValue = 0, direction = new int[] { 0, -1 } });
news.Add(new NEWS() { name = "E", rotateValue = 90, direction = new int[] { 1, 0 } });
news.Add(new NEWS() { name = "S", rotateValue = 180, direction = new int[] { 0, 1 } });
news.Add(new NEWS() { name = "W", rotateValue = 270, direction = new int[] { -1, 0 } });

ステップ3 後はfor文で回すだけ!

bool isAttack = false;
for (int j = 0; j < news.Count; j++){
    if (sm.playerArray[enemyPositionX + news[j].direction[0], enemyPositionZ - news[j].direction[1]] == 2) {
        iTween.RotateTo(monsterList[i], iTween.Hash("y", news[j].rotateValue, "islocal", true, "time", 0.2f));
        monsterList[i].GetComponent<Animator>().SetTrigger("Attack");
        sm.player.GetComponent<PlayerStatus>().Receive(1);
        yield return new WaitForSeconds(0.4f);
        isAttack = true;
    }
}