はこねのはこ

はこねさんの備忘録

UnityのDestroy関数で削除されるまで遅延時間の設定

はじめに

何気なく使用しているDestroy関数ですが、
削除されるまでの遅延時間を設定できる知見を得たのでメモします。

使い方

遅延時間なし

破壊するオブジェクトだけ指定します。

Destroy(gameObject);

遅延時間あり

破壊するオブジェクトと遅延時間を指定します。

# 1.0秒後に削除
Destroy(gameObject,1.0f);

公式リファレンス

public static void Destroy (Object obj, float t= 0.0F);

obj : 破壊するオブジェクト
t : オブジェクトを破壊するまでのディレイ時間

docs.unity3d.com

Time.timeScale = 0であっても時間に関する処理がしたい時にTime.unscaledDeltaTimeを使用した話

はじめに

ポーズ機能を実装しようとしました。
ポーズからゲームを再開しようとした時、いきなり始まるのではなく、 プログレスバーのような円ゲージを用意して開始のタイミングを取りやすいようにしたのですが、 ポーズ中はTime.deltaTimeを使用した円ゲージの処理も止まってしまいました。

ゲーム時間の停止は

Time.timeScale = 0;

を使用しています。 Time.deltaTimeは止まってしまう(今思えばあたりまえ)ので、 この状態でも時間制御がしたかったので調べたことをメモ。

解決策

Time.unscaledDeltaTimeを使います。
timeScaleの影響を受けないようです。

できたもの

できました。
ポーズ中はTime.timeScale = 0としていて、
オレンジのアイコンはTime.unscaledDeltaTimeを使用しています。

アイコンイメージの設定

f:id:hakonebox:20190102201013p:plain

コード例

GameManager.cs

   public static void AdjustGameTime(float speed){
        Time.timeScale = speed;
    }

UIController.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class UIController : MonoBehaviour {

    public GameObject PauseUI;
    public GameObject LockUI;
    public Image LockIcon;
    const float openLockTime = 1.0f;//[s]
    bool openlock = false;

    // Use this for initialization
    void Start () {
        PauseUI.SetActive(false);
        LockUI.SetActive(false);
    }
    
    // Update is called once per frame
    void Update () {
        UpdateLockGauge();
    }

    public void OnPauseButtonClick() {
        Debug.Log("PauseButton");
        ClearLockGauge();
        GameManager.AdjustGameTime(0);
        PauseUI.SetActive(true);
    }

    public void OnContinueButtonClick() {
        Debug.Log("ContinueButton");
        PauseUI.SetActive(false);
        SetLockGauge();
    }

    void SetLockGauge(){
        LockUI.SetActive(true);
        LockIcon.fillAmount = 1;
        openlock = true;
    }

    void ClearLockGauge(){
        LockUI.SetActive(false);
        openlock = false;
    }

    void UpdateLockGauge(){
        if(openlock){
            if(LockIcon.fillAmount > 0){
                LockIcon.fillAmount -= 1.0f / openLockTime * Time.unscaledDeltaTime;
            }else{
                openlock = false;
                GameManager.AdjustGameTime(1);
            }
        }
    }
}

unityroomアドベントカレンダー2018"はこねこサンタがやってきた"を作った話

はじめに

本日はクリスマスイブです。

unityroomアドベントカレンダー2018に参加させていただいたので
振り返っておきます。

12/3を担当しました。

※技術的なことはほぼほぼ載っていません!!!

公開したゲーム

f:id:hakonebox:20181224203139p:plain

はこねこサンタがやってきた | 無料ゲーム投稿サイト unityroom - Unityのゲームをアップロードして公開しよう

unityroomアドベントカレンダー2018とは!

一緒に参加しました!

当時の振り返り

パーティクルを使ってみました!

この後熟睡しました!

完成!!

じわじわ表示させたり消したりする方法

アルファ値を調整して実現しています。
0になれば透明、逆に1の場合は不透明になります。

       if (redRibonQimmickFlag) {
            redRibon_1st.color = new Color (1, 1, 1, redRibonInitColorPer);
            redRibonInitColorPer -=  Time.deltaTime*0.1f;
            if (redRibonInitColorPer < 0) {
                redRibonInitColorPer = 0;
                redRibonQimmickFlag = false;
            }
        }
        if (yellowRibonQimmickFlag) {
            yellowRibon_1st.color = new Color (1, 1, 1, yellowRibonInitColorPer);
            yellowRibonInitColorPer +=  Time.deltaTime*0.1f;
            if (yellowRibonInitColorPer > 1) {
                yellowRibonInitColorPer = 1;
                yellowRibonQimmickFlag = false;
            }
        }

振り返り

難易度について

作者ふたりの中では簡単かなと思っていましたが、 激ムズだったようです。

テストプレイしていただける方募集するのも考えたほうがいいかもしれません。

そのためにもベータ版は早めに完成させなきゃですね。

おわりに

はいき丸さんのイラストすごく素敵なので
ぜひ遊んで見てください!!!

じぶんコインの腹筋回数を簡単に記録できるWebアプリを作成しました

はじめに

タイトルの通りです。
うぉぉおぉぉ...できました!!

https://hakohukkin.herokuapp.com/

公開ページ⬇︎ f:id:hakonebox:20181224185603p:plain

管理者ページ⬇︎ f:id:hakonebox:20181224193204p:plain

作った背景とか、技術的なことを メモしておこうと思います。

環境

作成に至った背景

じぶんコインの価値を腹筋に設定した

twitter.com

ひさしさんがリリースしているじぶんコイン。

みなさん楽しそうにじぶんコインを作成して交流していたので、
自分も作成して見たくなりました。

自分にできる価値とは何だろうと考えていたところ、
ふと”腹筋代行”という言葉が浮かんできました。

エンジニアの多くは運動不足(偏見)なので、 運動したいけど、する時間がない、開発が忙しい、仕事が忙しい、ゲームが忙しい...

そんな人たちの代わりに腹筋して代わりに運動不足を解消しようと
コインで手に入る価値に
"コインの数だけ腹筋します"
と設定しました。

f:id:hakonebox:20181224190735p:plain

過去のカウント方法

スマホアプリを使用してカウントしていました。

そういえばいきなり山らさんから1500回きてたんですね....

山ら (@MantleHat) | Twitter

しかしこの場合、誰の文をどれくらいやったかわかりにくかったので、
何か進捗がわかるようなものが欲しいと感じました。

Railsの力でなんとかする

ProgateのRailsを一通り終わらせて、 何かオリジナルで作成して見たいと考えていたので、
腹筋回数を簡単に記録できるWebアプリを作成しようと考えました。

取り入れたRails要素

Progateの復習もあったので、 以下のような要素を取り入れました。

  • 管理者ログイン/ログアウト機能
  • 管理者のみアクセスできるページ
  • データベースの新規追加
  • データベースの編集
  • データベースの削除

プロトタイプ⬇︎

Bulmaの力でなんとかする

Webサービスを作っていると、デザインの壁にぶち当たりました。

デザインわからんってなりました。

そんなことをキョロさんとはなしていたら、Bulmaというフレームワークを紹介してもらいました。

キョロ (@kyoro_net) | Twitter

モダンな色使いが簡単に設定できるので
Bulmaの力でデザインはなんとかしようと考えました。

データベースの確認方法

データベースの確認にはDB Browser for SQLiteを使用しました。

Progateみたいにデータベースを確認したかったとき カワカミヒロトさんに教えていただきました。

カワカミ ヒロト (@hiroto04181996) | Twitter

herokuでのデータベースの編集方法

ある程度できてから、Herokuに展開したのですが、
Heroku上のデータベースの編集の仕方がわからないということがありました
(当時は管理者ページを作成できていなかったので...)

naichiさんに教えていただきました。

naichi (@naichilab) | Twitter

herokuへのアクセス

heroku run rails c RAILS_ENV=production -a [HEROKU-NAME]

データベース変更時の注意

※データベースに反映させていない状態でアクセスするとエラーになります

heroku run rake db:migrate

Railsのメモ

表の作成

@logs.each do |log|でごりごり表示させています。

app/views/home/top.html.erb

      <section class="section">
        <table class="table is-bordered is-striped is-narrow is-hoverable is-fullwidth">
          <thead>
            <tr class="is-selected">
              <th>日付</th>
              <th>名前(敬称略)</th>
              <th>回数(進捗ゲージ)</th>
              <th>済?</th>
              <th>補足</th>
            </tr>
          </thead>
          <% @logs.each do |log| %>
          <tbody>
            <tr>
              <td><%= log.day %></td>
              <td><%= log.name %></td>
              <% case log.Supplement %>
                <% when "-" %>
                  <td><%= log.trycnt %>/<%= log.reqcnt %><progress class="progress is-danger" value="<%= log.trycnt %>" max="<%= log.reqcnt %>"></progress></td>
                <% when "逆腹筋"%>
                  <td><%= log.trycnt %>/<%= log.reqcnt %><progress class="progress is-warning" value="<%= log.trycnt %>" max="<%= log.reqcnt %>"></progress></td>
                <% when "背筋"%>
                  <td><%= log.trycnt %>/<%= log.reqcnt %><progress class="progress is-primary" value="<%= log.trycnt %>" max="<%= log.reqcnt %>"></progress></td>                
                <% when "腕立て"%>
                  <td><%= log.trycnt %>/<%= log.reqcnt %><progress class="progress is-info" value="<%= log.trycnt %>" max="<%= log.reqcnt %>"></progress></td>
                <% when "スクワット"%>
                  <td><%= log.trycnt %>/<%= log.reqcnt %><progress class="progress is-link" value="<%= log.trycnt %>" max="<%= log.reqcnt %>"></progress></td>
              <% end %>
              <td>
                <% if log.end %>
                  <span class="tag is-success">Done</span>
                <% end %>
              </td>
              <td><%= log.Supplement %></td>
            </tr>
          </tbody>
          <% end %>
        </table>
      </section>

新規追加ボタン

複数のデータを一緒に追加したかったのですが、texareaにnameを設定することで渡すことができました。

app/views/home/setting.html.erb

            <tr>
              <%= form_tag("/create") do %>
              <th><textarea name = "formday">2018-10-15 19:14:00</textarea> </th>
              <th><textarea name = "formname">はこね</textarea></th>
              <th><textarea name = "formcnt">100</textarea></th>
              <th><textarea name = "formsub">-</textarea></th>
              <th><input type="submit" class="button is-info" value="新規追加"></th>
              <% end %>
            </tr>

config/routes.rb

post "create" => "home#create"

app/controllers/home_controller.rb

  def create
    @logs = Log.new(day:params[:formday],name:params[:formname],trycnt:0,reqcnt:params[:formcnt],end:false,Supplement:params[:formsub])
    @logs.save
    redirect_to("/setting")
  end

削除

destroyで削除できます。
Progareの削除ボタンを参考にしました。

app/views/home/setting.html.erb

 <%= link_to("削除", "/#{log.id}/destroy",{method:"post",class:"button is-danger"}) %>

config/routes.rb

post "/:id/destroy" => "home#destroy"

app/controllers/home_controller.rb

  def destroy
    @logs = Log.find_by(id: params[:id])
    @logs.destroy
    redirect_to("/setting")
  end

編集

編集方法には悩んだのですが管理者ページの編集したい箇所をtextareaにして、
編集後、"編集"ボタンを押すことで更新できるようにしました。

app/views/home/setting.html.erb

              <%= form_tag("/#{log.id}/editupdate") do %>
                <td><%= log.id %></td>
                <td><textarea name = "formdayedit"><%= log.day %></textarea></td>
                <td><textarea name = "formnameedit"><%= log.name %></textarea></td>
                <td>
                  <%= link_to("-10", "/#{log.id}/subtractioncnt",{method:"post",class:"button is-link is-small"}) %>
                  <%= log.trycnt %>
                  <%= link_to("+10", "/#{log.id}/addcnt",{method:"post",class:"button is-danger is-small"}) %>
                  /
                  <textarea name = "formreqcntedit"><%= log.reqcnt %></textarea>
                </td>
                <td><%= log.end %></td>
                <td><textarea name = "formsubedit"><%= log.Supplement %></textarea></td>
                <td><input type="submit" class="button is-warning" value="編集"></td>
              <% end %>

config/routes.rb

  post "/:id/editupdate" => "home#editupdate"

app/controllers/home_controller.rb

  def editupdate
    @logs = Log.find_by(id: params[:id])
    @logs.day = params[:formdayedit]
    @logs.name = params[:formnameedit]
    @logs.reqcnt = params[:formreqcntedit]
    @logs.Supplement = params[:formsubedit]
    @logs.save
    redirect_to("/setting")
  end

おわりに

なんとか見せられる程度まではできましたが、
肝心の腹筋は全くできていないんですよ。

今日から再開するので許してください。

はてなブログのシンタックスハイライトを変更する

はじめに

はてなブログソースコードを載せた時、
今使っているテーマは個人的に少し見にくいと感じていました。

過去記事のシンタックスハイライト⬇︎

f:id:hakonebox:20181224182611p:plain

普段使っているエディタが背景グレーなのでそのせいもあるかもしれません。

自分で見返してて見にくいと感じたので、
シンタックスハイライトの配色を変更してみようと思います。

変更の仕方

はてなブログダッシュボードから
"デザイン"→"カスタマイズ"→"デザインCSS"から変更できるそうです。

f:id:hakonebox:20181224183124p:plain

CSS作成

CSSジェネレータをお借りしました

調べてみると、はてなブログシンタックスハイライトの
CSSジェネレータというwebアプリがありました。

プレビューしながらCSSの作成ができるようです。

感謝しつつ使用させてもらいます。

はてなブログシンタックスハイライト CSS ジェネレータ

f:id:hakonebox:20181224183503p:plain

使ってみる。

デフォルトの配色から、backgroundとsynConstant,SynTypeを変更しています。 使いながら調整していきましょう。

.entry-content pre.code {
    background-color: #2E2E2E;
    color: #ffffff;
}
.synComment { color: #6272a4; }
.synConstant { color: #ffff14; }
.synIdentifier { color: #58ACFA; }
.synPreProc { color: #a199c8; }
.synSpecial { color: #c000c0; }
.synStatement { color: #50fa7b; }
.synType { color: #ff1493; }

f:id:hakonebox:20181224183950p:plain

おわりに

背景が黒系になってだいぶ見やすくなった気がします。

Unity1週間ゲームジャム[10]ラーメン屋"十秒魂"公開しました。

はじめに

今回も参加しましたUnity1week(20181119-25)。
忘れないうちに振り返っておきます。 イラストははいき丸さんです。 はいき丸(@haikimaru)さん | Twitter

f:id:hakonebox:20181128205022g:plain

今回も素敵なイラストです。

URL

下記URLから遊べます。 ぜひ遊んで見てください。

ラーメン屋 "十秒魂" | 無料ゲーム投稿サイト unityroom - Unityのゲームをアップロードして公開しよう

制作過程

プロトタイプ作成

今回の作品はラーメン職人です!!
ラーメンの硬さに10秒でハリガネという硬さがあるようですね。
(世の中には粉落としとか生麺があるそうですが...)

10秒の湯切りにこだわりを持つ職人が
10秒きっかりに湯切りをするゲームにしました。

アイディアがだいたいまとまってきたので、プロトタイプを作成しました。

イラスト作成

プロトタイプを元にはいき丸さんと打ち合わせ。 可愛い絵に仕上げてもらいました。

このカットイン、何かに使いたかったのですが、実装しきれませんでしたね。
時間的にも難しかったですし、ルールが複雑化する懸念もあったで、 泣く泣く断念しました。

コアになる処理(茹でる/湯切り)の作成

できたイラストを組み込みながら、コアとなる茹でる/湯切りの処理を作成

材料を切る処理の追加

ただ10秒カウントするだけであれば物足りない気がしたので、
材料を準備する動作を追加しました。

体内時計で2つ同時に10秒測りながら材料の準備をしていると激ムズになりました。
意識が材料に向いちゃうとカウントがわからなくなりますね。

そこそこ注意を向けないとできないけど、
そこそこ10秒カウントにも意識を向けられるような動きにしました。

上から下、または下から上にドラックすると切れるようにしました。

公開へ

安定の遅刻。

一時間ほど遅刻して投稿しました。

今回ゲームを作成する上で考えていたこと

今回のゲームは、
"初めは動作が難しいけれど、動作になれたり動きが最適化されて高得点になっていく"
を考えていました。

10秒数えている間にする最中に食材を切る操作があるのですが、
操作に慣れてくると、リズミカルにできるようになるといいなと考えました。 例えば、
残り時間を見る→茹始める→材料を切る→準備を整えたら残り時間からタイミングを測って湯切り...
と、自分の中の最適化パターンを見つけることができれば、脳とマウスをリズミカルに動かして楽しめることを狙いました。

プレイしていただい方いかがだったでしょうか。

自分としては、良い難易度にできたと思いました。 ただ、操作方法がわかりにくいとの声も聞きました。

リズミカルに動かせるようになるまで遊んでもらいたかったので、 チュートリアルや練習モードを作れれば良かったですね。

さいごに

1時間ほど遅刻してしまいましたが、
今回も開発楽しかったです。

さーてアドベントもガンバルゾー

Pythonチートシート

はじめに

Pythonチュートリアルを見ながら実際に動きを試しながらチートシートを作成しました。

Python チュートリアル — Python 3.6.5 ドキュメント

どこでも見ることができるように載せておきます。

文字の入出力

print('hello python')
num = str(input('文字を入力してください:'))
print('入力した文字は['+num+']です')

a = 7
b = 3
print('a+b='+str( a + b ))       # a+b=10
print('a-b='+str( a - b ))       # a-b=4
print('a*b='+str( a * b ))       # a*b=21
print('a/b='+str( a / b ))       # a/b=2.3333333333333335
print('a//b='+str( a // b ))         # a//b=2
print('a%b='+str( a % b ))   # a%b=1
print('a**b='+str( a ** b )) # a**b=343
c= 2+3j   # おまけ 複素数を表す場合jまたはJ

文字列型

'または"で囲むと文字列になる。 ¥でエスケープする

print('single')        # single
print("double" )  # double
print('esc¥"')        # esc"

¥に続く文字を特殊文字としてされたくない場合はraw stringsを利用

print('C:¥dir¥name')
# ¥dir
# ame
print(r'C:¥dir¥name') 
# ¥dir¥name

3重で囲むと複数行にまたがって表示可能

# 最初の改行文字を含まない
print("""¥
Usage: thingy [OPTIONS]
     -h                        Display this usage message
     -H hostname               Hostname to connect to
""")

文字の連結

+で結合、*で反復

print( 3 * 'abc' +'de')  # abcabcabcde

連続している複数の文字列リテラルは自動的に連結

print('abc' 'de') # abcde

print(   'くぁwせdrftgyふじこ'
        'lp;「’」」')   # くぁwせdrftgyふじこlp;「’」」

インデックスによる取得

word = 'teizinitaisya'
print(word[0])              # t
print(word[3])              # z
print(word[-1])             # a
print(word[-8])             # n
print(word[0:5])           # teizi
print(word[7:13])          # taisya
print(word[:5]+word[5:])   # teizinitaisya
print(word[-6:])            # taisya

リスト型

editors = ['VSC','Atom','Vi','Emacs']
print(editors)       # ['VSC', 'Atom', 'Vi', 'Emacs']
print(editors[1])   # Atom
print(editors[:])    # ['VSC', 'Atom', 'Vi', 'Emacs']
print(editors[2:])  # ['Vi', 'Emacs']

# 連結が可能
editors+=['Mifes','秀丸']
print(editors)       # ['VSC', 'Atom', 'Vi', 'Emacs', 'Mifes', '秀丸']

# 入れ替えが可能
editors[0] = 'Visual Studio Code'
print(editors)       # ['Visual Studio Code', 'Atom', 'Vi', 'Emacs', 'Mifes', '秀丸']

# 追加
editors.append('sakura')
print(editors)       # ['Visual Studio Code', 'Atom', 'Vi', 'Emacs', 'Mifes', '秀丸', 'sakura']

# All clear
editors[:] = []
print(editors)       # []

# split()でリスト化する
editors = 'VSC,Atom,Vi,Emacs'
print(editors)       # VSC,Atom,Vi,Emacs
list_editors = editors.split(',')
print(list_editors)  # ['VSC', 'Atom', 'Vi', 'Emacs']

条件式

if

num = int(input('1‾5の数字を入力してください:'))
if num > 5 or num < 0:
    print('範囲外')
elif num <= 3 and num >= 0:
    print('まだまだだね')
else:
    print('やるじゃん')

繰り返し処理

for

# list型
# list
foods = ['curry', 'hamburg', 'deep-fried']
for food in foods:
    print(food)

# range
print('range(5)')
for num in range(5):
    print(num)
print('range(-2,3)')
for num in range(-2,3):
    print(num)
print('range(0,10,3)')
for num in range(0,10,3):
    print(num)
print('range(-10,-30,-5)')
for num in range(-10,-30,-5):
    print(num)

組み込み関数

len()

文字列の長さを返す

s = 'madamadadane'
print(len(s))     # 12
print(len(s)+10)     # 22 (計算が可能)

range()

イテレートした時に望んだ数列の連続した要素を返すオブジェクト

# 0‾4(増加量1)
range(5)
# -2‾2(増加量1)
range(-2,3)
# 0‾10(増加量3)
range(0,10,3)
# -10‾-30(増加量-5)
range(-10,-30,-5)

pass

文を書くことが構文上要求されているが、プログラム上何の動作もする必要がない時に使われます.

print( 'Busy-wait for keyboard interrupt (Ctrl+C)')
while True:
    pass

モジュール

random

import random

for i in range(5):
    num = random.randint(0,10)
    print(num)

おわりに

チュートリアル試しながらチートシートまとめてたら覚えてしまったっぽい