はこねのはこ

はこねさんの備忘録

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

tutorial.djangogirls.org

環境

原因

Djangoの1.11.xは、Python 3.7と互換性がないようです。

docs.djangoproject.com

対処方法

Djangoのアップデートを行いました。

pip install -U Django

kurozumi.github.io

さいごに

アップデート実行後、

Successfully installed Django-2.1.7

と表示されました。 再度migrateを実行すると無事成功できました。

MacBookのトラックパッドでイベントグラフをスクロールさせる時に方向を逆にしたい

はじめに

表題の通りです。

最近MacBookUE4がある程度動くこと気に気がつき、
外でUE4を扱うようになったのですが、
ブループリントのイベントグラフをスクロールさせる時、
思った方向と逆に動いてしまったので、
逆にする設定を探しました。

設定方法

エディタの環境設定で、
Direction of the scroll gesture for orthographic viewportsをNaturalにします。

f:id:hakonebox:20190129204513p:plain

おわりに

"scroll"で検索するとそれっぽいのが出てきました。

unity1week Meetup in Tokyo2019に参加しました。(+展示方法)

はじめに

unity1week Meetup in Tokyo2019に参加しました!

その振り返りとその時の展示方法を記録しておきます。

unity1week Meetup in Tokyo2019とは

meetup.unity3d.jp

当日の様子

設営や展示している時に自分で写真をとっていませんでした。 青木ととさんに写真をいただきました。
青木とと(ˊᗜˋ*) (@lycoris102) | Twitter

展示方法について

フリック入力でトリックをキメるため、 タブレットを準備しました。

タブレットで操作した場合、後ろにいた人がゲーム画面が見にくいかと思ったので、大きなディスプレイにプレイ画面を表示するように準備しました

実際の画像

f:id:hakonebox:20190114004319p:plain

よかった点

大きなディスプレイの映像はmacbookミラーリングしていたため、体験者と机を挟んだ奥側にいてもタブレットの内容、操作方法スライドの内容が確認できてよかった。

ミラーリングKeynoteのため、展示中も補足説明等あればその場で編集も楽だった。

使ったアプリ

環境がMacBook+iPadだったため、Quicktime Playerの新規ムービー収録の機能を使用しました。 知ってる方も多いと思いますが、念の為。

"ファイル"→"新規ムービー収録" f:id:hakonebox:20190114004524p:plain

iOS端末を選択 f:id:hakonebox:20190114004554p:plain

総括

  • スマホ,タブレット操作のゲームのため、後ろの人も画面が見やすいように大きなディスプレイにタブレットの画面を写すのはよかった。

  • Keynoteで操作方法を表示させていたので、説明がしやすかった気がする。

  • 無限に続くランゲームではなく、ミッションモードとして終わりを設定していたので、ゲーム体験の区切りをつけやすかった。

  • 人によって難易度の感じ方にばらつきがあったようなので、難易度別のミッションを用意して、誰でも成功体験を持てるようなデザインが欲しかった。

  • どのような観点で意見が欲しかったのか事前に決めておくべきだった。

  • お酒を飲んで正常な判断をしようとしたが、これからは自重する(事も考える)

当日いただいた意見

下記意見をいただきました。 せっかくいただいた意見なので、検討して実装しようと思います。

  • 難易度はそのままにスピード感が欲しい(ブラー等で表現)
  • 切り株の上に乗った場合はダメージ判定がないほうがいいのではないか。
  • ジャンプ台でジャンプした場合、失敗する時があるのがわかりにくい。
  • 横にスライドが早くて、通り抜けたと思ってスライドした時に障害物に当たってしまう。
  • カプセルコライダーの方が処理が軽くなる。

開発の記録

こんな感じでやってました。

開発をはじめたのは18/12/26のようです。

アニメーションを作り始める

頭の上に障害物があった時にしゃがんで回避しようとして作ったアニメーション

ポーズ機能の実装

衝突時のアニメーションの作成

はいき丸さん作成のイノシシとぴよぴよ

イノシシはオンライン対戦時のおじゃまキャラとして想定していたが、オンライン間に合いませんでした。

フリックでトリックが決められるように

簡易的なあそびかたシートの作成

おわりに

今回の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"
    }

公式リファレンス

docs.unity3d.com

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);
            }
        }
    }
}