Django 2.xx でForeignKeyのon_deleteに関するエラーメモ
はじめに
DjangoGirlsでつまづいたところのメモ。
TypeError: __init__() missing 1 required positional argument: 'on_delete'
が発生した。
その時のコード
class Post(models.Model): author = models.ForeignKey('auth.User') title = models.CharField(max_length=200) text = models.TextField() created_date = models.DateTimeField(default=timezone.now) published_date = models.DateTimeField(blank=True,null=True) def publid(self): self.published_date = timezone.now() self.save def __str__(self): return self.title
環境
原因
ForeignKeyはversion2からは引数としてon_deleteを指定することが必須となっていた。
解決方法
第二引数にon_deleteを渡します。
from django.db import models from django.utils import timezone class Post(models.Model): author = models.ForeignKey('auth.User',on_delete=models.CASCADE) title = models.CharField(max_length=200) text = models.TextField() created_date = models.DateTimeField(default=timezone.now) published_date = models.DateTimeField(blank=True,null=True)
参考にさせていただきました
Django2.0から必須になったon_deleteの使い方 - Django2の実力をつけるチュートリアルサイトDjangoBrothers
Djangoでmigrateできなかった時の対処方法(Python 3.7.0 , Django 1.11)
はじめに
DjangoGirlsを進めていたのですが、
python manage.py migrate
を実行して
SyntaxError: Generator expression must be parenthesized
とエラーが発生したので対処方法をメモ
DjangoGirls
環境
原因
Djangoの1.11.xは、Python 3.7と互換性がないようです。
対処方法
Djangoのアップデートを行いました。
pip install -U Django
さいごに
アップデート実行後、
Successfully installed Django-2.1.7
と表示されました。 再度migrateを実行すると無事成功できました。
unity1week Meetup in Tokyo2019に参加しました。(+展示方法)
はじめに
unity1week Meetup in Tokyo2019に参加しました!
その振り返りとその時の展示方法を記録しておきます。
unity1week Meetup in Tokyo2019とは
当日の様子
こんな感じで設営してました!
— はこね (@hakone_san) 2019年1月12日
遊んでいただいた方、感想、改善提案等、ありがとうございました。
このような形で展示は初めてだったのでとても緊張していましたが、
学びもあり、開発欲に繋がる良い場となりました。#unity1week pic.twitter.com/4vGOLD0o59
設営や展示している時に自分で写真をとっていませんでした。
青木ととさんに写真をいただきました。
青木とと(ˊᗜˋ*) (@lycoris102) | Twitter
展示方法について
フリック入力でトリックをキメるため、 タブレットを準備しました。
タブレットで操作した場合、後ろにいた人がゲーム画面が見にくいかと思ったので、大きなディスプレイにプレイ画面を表示するように準備しました
実際の画像
よかった点
大きなディスプレイの映像はmacbookとミラーリングしていたため、体験者と机を挟んだ奥側にいてもタブレットの内容、操作方法スライドの内容が確認できてよかった。
ミラーリングKeynoteのため、展示中も補足説明等あればその場で編集も楽だった。
使ったアプリ
環境がMacBook+iPadだったため、Quicktime Playerの新規ムービー収録の機能を使用しました。 知ってる方も多いと思いますが、念の為。
"ファイル"→"新規ムービー収録"
iOS端末を選択
総括
スマホ,タブレット操作のゲームのため、後ろの人も画面が見やすいように大きなディスプレイにタブレットの画面を写すのはよかった。
Keynoteで操作方法を表示させていたので、説明がしやすかった気がする。
無限に続くランゲームではなく、ミッションモードとして終わりを設定していたので、ゲーム体験の区切りをつけやすかった。
人によって難易度の感じ方にばらつきがあったようなので、難易度別のミッションを用意して、誰でも成功体験を持てるようなデザインが欲しかった。
どのような観点で意見が欲しかったのか事前に決めておくべきだった。
お酒を飲んで正常な判断をしようとしたが、これからは自重する(事も考える)
当日いただいた意見
下記意見をいただきました。 せっかくいただいた意見なので、検討して実装しようと思います。
- 難易度はそのままにスピード感が欲しい(ブラー等で表現)
- 切り株の上に乗った場合はダメージ判定がないほうがいいのではないか。
- ジャンプ台でジャンプした場合、失敗する時があるのがわかりにくい。
- 横にスライドが早くて、通り抜けたと思ってスライドした時に障害物に当たってしまう。
- カプセルコライダーの方が処理が軽くなる。
開発の記録
こんな感じでやってました。
開発をはじめたのは18/12/26のようです。
ProBuilderでさくっとスノボ。
— はこね (@hakone_san) December 26, 2018
下から撮ると足が短いのが隠せる。 pic.twitter.com/eMSyjdtQax
アニメーションを作り始める
肘によりより人っぽいかな。
— はこね (@hakone_san) December 30, 2018
足が短いからどうトリックを決めたらいいものか。 pic.twitter.com/Jf5BRxcWMf
スノボしたことないです。 pic.twitter.com/mQhKUATNZD
— はこね (@hakone_san) December 30, 2018
頭の上に障害物があった時にしゃがんで回避しようとして作ったアニメーション
スノボの上を歩くはこねこ pic.twitter.com/gVL3kOOmtL
— はこね (@hakone_san) January 1, 2019
ポーズ機能の実装
Pause機能実装してみた。3...2...1...ってカウントダウンと悩んだけどこっちを使ってみました。 pic.twitter.com/PPEuBT6B9P
— はこね (@hakone_san) January 2, 2019
衝突時のアニメーションの作成
真顔こわいんですけど.... pic.twitter.com/H9odUhgMT1
— はこね (@hakone_san) January 3, 2019
はいき丸さん作成のイノシシとぴよぴよ
イノシシはオンライン対戦時のおじゃまキャラとして想定していたが、オンライン間に合いませんでした。
反応の鈍いはこねこ pic.twitter.com/AcxwPLA5tW
— はいき丸 (@haikimaru) January 3, 2019
ひよこちゃんと顔も書いたんだけど、あんまり見えないな… pic.twitter.com/rIrkxjQQmM
— はいき丸 (@haikimaru) January 4, 2019
混乱表現ぴよぴよ pic.twitter.com/5cOJDbWwD9
— はいき丸 (@haikimaru) January 4, 2019
はいき丸さんのぴよぴよとイノシシ組み込みました pic.twitter.com/ogbSHYRM36
— はこね (@hakone_san) January 5, 2019
フリックでトリックが決められるように
かわいいぞー!かっこいいぞー! pic.twitter.com/IX69tY1VvH
— はこね (@hakone_san) January 6, 2019
簡易的なあそびかたシートの作成
はこのぼ! pic.twitter.com/cZcrdArAIX
— はこね (@hakone_san) January 11, 2019
おわりに
今回のmeetupでますます頑張ろうと思えました。
運営の方々、参加された皆様ありがとうございました。
キャラクターコントローラーがコライダーに衝突した際の関数
はじめに
ControllerColliderを使用していて、他のColliderと衝突した際に何かしたい場合、 実現方法を毎度毎度調べ直しているのでいい加減メモして定着させます。
使い方
OnControllerColliderHit関数を使用します。
例
だいたいこんな感じで衝突した際にタグをみて判定するようにしています。
void OnControllerColliderHit(ControllerColliderHit hit){ Debug.Log("hit.gameObject.tag: "+hit.gameObject.tag); switch(hit.gameObject.tag){ case "Obstacle": //hoge break; case "enemy": //piyo break; default: //do nothing break; } }
スニペット
楽したいので作成しておきます。
"Caracter Controller Collider + Switch": { "prefix": "characollider", "body": [ "void OnControllerColliderHit(ControllerColliderHit hit){", "\tswitch(hit.gameObject.tag){", "\t\tcase $1:", "\t\t\t$2", "\t\t\tbreak;", "\t\tdefault:", "\t\t\tbreak;", "\t}", "}" ], "description": "OnControllerColliderHit + switch" }
公式リファレンス
UnityのDestroy関数で削除されるまで遅延時間の設定
はじめに
何気なく使用しているDestroy関数ですが、
削除されるまでの遅延時間を設定できる知見を得たのでメモします。
使い方
遅延時間なし
破壊するオブジェクトだけ指定します。
Destroy(gameObject);
遅延時間あり
破壊するオブジェクトと遅延時間を指定します。
# 1.0秒後に削除 Destroy(gameObject,1.0f);
公式リファレンス
public static void Destroy (Object obj, float t= 0.0F);
obj : 破壊するオブジェクト
t : オブジェクトを破壊するまでのディレイ時間
Time.timeScale = 0であっても時間に関する処理がしたい時にTime.unscaledDeltaTimeを使用した話
はじめに
ポーズ機能を実装しようとしました。
ポーズからゲームを再開しようとした時、いきなり始まるのではなく、
プログレスバーのような円ゲージを用意して開始のタイミングを取りやすいようにしたのですが、
ポーズ中はTime.deltaTimeを使用した円ゲージの処理も止まってしまいました。
ゲーム時間の停止は
Time.timeScale = 0;
を使用しています。 Time.deltaTimeは止まってしまう(今思えばあたりまえ)ので、 この状態でも時間制御がしたかったので調べたことをメモ。
解決策
Time.unscaledDeltaTimeを使います。
timeScaleの影響を受けないようです。
できたもの
できました。
ポーズ中はTime.timeScale = 0としていて、
オレンジのアイコンはTime.unscaledDeltaTimeを使用しています。
Pause機能実装してみた。3...2...1...ってカウントダウンと悩んだけどこっちを使ってみました。 pic.twitter.com/PPEuBT6B9P
— はこね (@hakone_san) 2019年1月2日
アイコンイメージの設定
コード例
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); } } } }