GameMaker 日本語掲示板

【解決済】YoutubeでARPG制作チュートリアルに出てきたnot set before reading it.のエラー解消について

13 コメント
views
17 フォロー

ゲーム制作学習1ヶ月の初心者です。チュートリアルを利用してオブジェクトの動作設定をしている最中です。

Runをさせようとしたら下記の記述にてエラーが出てきました。

Variable.direction(8,-2147483648)not set before reading it.
at gml_GlobalScript_PlayerAnimateSprite(line 3)

スクリプトは以下に記載しています。

//Update Sprite
//Replaced = round(direction/90);  floor(((direction div 45) + 1) * 0.5);
var _cardinalDirection = floor(((direction div 45) + 1) * 0.5);
var _totalFrames = sprite_get_number(sprite_index) / 4;
image_index = localFrame + (_cardinalDirection * _totalFrames);
localFrame += sprite_get_speed(sprite_index) / FRAME_RATE;

//If animation would loop on next game step
if (localFrame >= _totalFrames)
{
	animationEnd = true;
	localFrame -= _totalFrames;
}else animationEnd = false;

自分なりに調べて関数の未定義とのことで

var _cardinalD

と関数を変更したり、

var _cardinalDirection;
_cardinalDirection = floor〜

と一度変数の宣言をしてから続きの文章を記述したり、
round関数に変更して記載しても起動できませんでした。

一部の記述で解決ができるか不明ではありますが、どなたかに解決方法をご教授いただければ幸いです。
よろしくお願いいたします。

yasaka
作成: 2021/10/06 (水) 20:27:26
最終更新: 2021/10/09 (土) 02:26:47
通報 ...
1

3行目にエラーがあると書かれているので、
image_index = localFrame + (_cardinalDirection _totalFrames);
を見てみると、_cardinalDirection _totalFramesの間の演算子が抜けてしまっているように見えます。
演算子がないので、2つの変数がつなげて認識されてしまってnot set before reading itエラーが出ているのではないでしょうか。

2

nuimさん
返信ありがとうございます。マークダウン記法についても理解していなかったためきちんとコメントアウト部分含め内容が記載されていませんでした。
演算子についてはすでに入っており、変数宣言に対してエラーが発生してしまいます。こちらについても改めてご教授いただければ幸いです。よろしくお願いいたします。

3

Variable.direction(8,-2147483648)not set before reading it.

これは変数が定義されてないというエラー内容です。
「directionという変数が定義されてないのに使おうとしてるよ」というエラーです。しかし変数directionはビルトイン変数なので定義しなくても使えるものです。

1つ確認したいのですが、このコードが実行されている(書かれている)のはどこでしょうか。
オブジェクトのイベントの中で、あるいはscriptファイルの中でしょうか?

4
asa 2021/10/09 (土) 01:04:31 修正 >> 3

これは当てずっぽうな推測ですが、このコードはscriptファイルに書かれていてobjectから呼び出していないでしょうか。
v2.3.3以降はfunctionの扱いが変わっています。この仕様変更によって古い記述のままだとエラーになることがあります。

具体的には、今の仕様だとスクリプト my_functions (←名前は適当)に、以下のように関数定義します。

function abc() {
   val = direction div 45;
}

これを

val = direction div 45;

と書いてないでしょうか?
そうするとRunするとスコープがglobalでこれが実行されるので、directionが定義されてないよとエラーが出るかもしれません。

関係しそうなスレッドを探しました。
https://forum.yoyogames.com/index.php?threads/important-gm-2-3-users-please-read-improper-script-usage-generates-undefined-variable-errors.79907/

一度ご確認ください。

5

asaさんコメントありがとうございます。
direction自体はそのままでも使えるのですね。今後の制作時の参考にします。ありがとうございます。

コードが書かれているのはscriptファイルの中です。

またこれとは別のscriptファイルにmacroでフレームレートの数値を設定しています。
さらにエラーの指示を受けてないオブジェクト内のファイルを書いている状態です。
Objectに対してEvents>Createイベントが下記のとおりです。

image_speed = 0;
hSpeed = 0;
vSpeed = 0;
speedWalk = 2.0;

spriteRun = sPlayerRun;
spriteIdle = sPlayer;
localFrame = 0;

またステップイベントが下記のとおりです。

//Get Player Input
keyLeft = keyboard_check(vk_left)  || keyboard_check(ord("A"));
keyRight = keyboard_check(vk_right) || keyboard_check(ord("D"));
keyUp = keyboard_check(vk_up) || keyboard_check(ord("W"));
keyDown = keyboard_check(vk_down) || keyboard_check(ord("S"));
keyActivate = keyboard_check_pressed(vk_space);
keyAttack = keyboard_check_pressed(vk_shift);
keyItem = keyboard_check_pressed(vk_control);

inputDirection = point_direction(0,0,keyRight-keyLeft,keyDown-keyUp);
inputMagnitude = (keyRight - keyLeft != 0)||(keyDown - keyUp != 0);


//Movement
hSpeed = lengthdir_x(inputMagnitude * speedWalk, inputDirection);
vSpeed = lengthdir_y(inputMagnitude * speedWalk, inputDirection);

x += hSpeed;
y += vSpeed;

//Updete Sprite Index
var _oldSprite = sprite_index;
if (inputMagnitude != 0)
{
	direction = inputDirection
	sprite_index = spriteRun;
} else sprite_index = spriteIdle;
if (_oldSprite != sprite_index) localFrame = 0;

//Update Image Index
PlayerAnimateSprite();

情報量が多くなり、またエラー該当箇所ではないため記載を割愛しましたがなにか解決のご参考にしていただきたく思います。
お忙しいところ本当にありがとうございます。

6

コードが書かれているのはscriptファイルの中ということですね。

関数を呼び出してる部分を探しますと、PlayerAnimateSprite(); があります。
PlayerAnimateSprite がスクリプトファイルの名前でしょうか?
その前提で以下に説明しますと、このスクリプトを開いて、

function PlayerAnimateSprite() {
 code
}

という形になっていなければ、この形にしてください。コードを全部コピペして

function PlayerAnimateSprite() {
 
}

の中に入れるだけでOKです。

そしてRunするとどうなるでしょうか?

7

asaさんありがとうございます!できました!

どのようにお伝えしていいかわかりませんが、本当に嬉しいです!
1週間近くいろいろ変化させてみたり、全て打ち直したりしてだめだったので、本当に助かりました!
夜遅くにありがとうございます!

8
asa 2021/10/09 (土) 13:38:53 修正

直ってよかったです!!

2.3以前のチュートリアルを参考にされたのだと思います。
古いチュートリアルで学習すると同じことが起こるので、今後の参考に簡単に説明します。

バージョン2.3以前の形
scriptには処理を直接記述していました。1つのscriptは1つの関数の定義になっていました。

例:
script "PlayerAnimateSprite"

player_direction = direction + 5;



バージョン2.3以降の形
処理をfunctionで包む形で記述し、これを関数定義とするようになりました。例は1つのfunctionだけですがscriptの中に複数のfunctionを書けるようになりました。
例:
script "PlayerAnimateSprite"

function PlayerAnimateSprite() {
 player_direction = direction + 5;
}



なので、古いチュートリアルのコードは全て、この読み替え、書き換えが必要になります。
以下に少し説明しますが、説明が雑で逆に混乱するかもしれないので、参考程度に読んでみてください


2.3以前では、Runしてもscript "PlayerAnimateSprite"は実行されません。関数"PlayerAnimateSprite"が定義されるだけです。オブジェクトAからPlayerAnimateSprite();を呼び出した時点でオブジェクトAのスコープで実行されます。コードにあるdirectionはオブジェクトAのdirectionが参照されるのでエラーになりません。

2.3以降では、Runしたらscript "PlayerAnimateSprite"に書かれたコードはグローバルスコープのコードとして全て実行されます。functionで包んでないコードは全てゲーム起動のタイミングで実行されます。そこでオブジェクトの変数であるdirectionを参照すればエラーになります。
functionで包めば、それが関数定義になります。Runした時点で関数が定義され、オブジェクトから呼び出した時点で実行されます。

関連資料
https://www.yoyogames.com/en/blog/gamemaker-studio-2-dot-3-new-gml-features

9

asaさんコメントありがとうございます!

2.3以前→オブジェクトAの変数宣言したものを利用してスプリクトは実行できる。

2.3以降→"functionで包んでいないスクリプト内のコードはゲーム起動のタイミングで実行される。

"「directionという変数が定義されてないのに使おうとしてるよ」というエラーです。しかし変数directionはビルトイン変数なので定義しなくても使えるものです。"と前回asaさんが言っていました。

これはそもそもゲーム起動のタイミングだからスクリプト内のコードをしようとするから何も準備できていないよー!って状況だからビルトイン変数のdirectionが未定義エラーになるということでしょうかね。

なんかかなり腹落ちした気がします……!さらにソース提示までいただいてありがとうございます!

10

はい、そういうことです!
「グローバルスコープ」とは特定のオブジェクトではなく、ゲーム自身を参照するということです。ゲーム自身にはdirectionは無いのでエラーになるというわけです。

11
ぽんでり 2021/10/15 (金) 02:18:32

理解が深まりました。感謝します。

12

なんか最近のアプデートが原因っぽくてまたエラーはいちゃうようになりましたね…

13

function PlayerAnimateSprite() {}
で全体をかこったのにエラーが出てしまいました…
アプデによって仕様が変わったことが原因かなって思ったりしてます…