teratail header banner
teratail header banner
質問するログイン新規登録

質問編集履歴

4

アセットパスを修正しました

2020/11/01 12:17

投稿

SeiSeis
SeiSeis

スコア12

title CHANGED
File without changes
body CHANGED
@@ -351,7 +351,7 @@
351
351
  [GitHub](https://github.com/SeiyaKobori/SkyLow.git)
352
352
  質問にあったスクリプトのパスを載せておきます
353
353
  SystemManager.cs
354
- Assets/Scripts/Utility/SystemManager.cs
354
+ SkyLow/TEST20200910/Assets/Scripts/Utility/SystemManager.cs
355
355
 
356
356
  GameSystemManager.cs
357
- Assets/Scripts/Manager/GameSystemManager.cs
357
+ SkyLow/TEST20200910/Assets/Scripts/Manager/GameSystemManager.cs

3

SystemManager.csとGameSystemManager.csの全コードを追記しました。

2020/11/01 12:17

投稿

SeiSeis
SeiSeis

スコア12

title CHANGED
File without changes
body CHANGED
@@ -344,4 +344,14 @@
344
344
  ```
345
345
  アドバイスを受けて、PlayerLocomotorクラスの全文を追記しました。
346
346
  実行中に最初に起こるエラーとしてはこのクラス内のOnGroundSwitched()で、プレイヤーが設置していた場合の処理です。ゲーム開始時に設置判定が別クラスで行われるのでそれを受けてこの関数が実行されるのですが、ここでエラーが起こります。
347
- 同じクラス内での処理なので指摘していただいたような、シーンの更新によって破棄されたオブジェクトへのアクセスによるエラーというようなことはないと思うのですがほかに原因も思い当たりません。
347
+ 同じクラス内での処理なので指摘していただいたような、シーンの更新によって破棄されたオブジェクトへのアクセスによるエラーというようなことはないと思うのですがほかに原因も思い当たりません。
348
+
349
+ 2020/10/30追記:
350
+ ほかスクリプトのコードも載せてほしいとのことでしたが、文字数制限が来たためgithubにプロジェクトをアップロードしました。
351
+ [GitHub](https://github.com/SeiyaKobori/SkyLow.git)
352
+ 質問にあったスクリプトのパスを載せておきます
353
+ SystemManager.cs
354
+ Assets/Scripts/Utility/SystemManager.cs
355
+
356
+ GameSystemManager.cs
357
+ Assets/Scripts/Manager/GameSystemManager.cs

2

PlayerLocomotor全文を追記しました。

2020/10/30 11:55

投稿

SeiSeis
SeiSeis

スコア12

title CHANGED
File without changes
body CHANGED
@@ -62,4 +62,286 @@
62
62
  private Rigidbody RB { set { Debug.Log("passSet", rb.gameObject); rb = value; } get { Debug.Log("passGet", rb.gameObject); return rb; } }
63
63
  ```
64
64
  ![イメージ説明](a277c9f357b95d94e2a57d4205a910dd.png)
65
- ちゃんとエラー前にSetしているようです。ちなみに手前のsetはgetcomponent<>によるものでした。
65
+ ちゃんとエラー前にSetしているようです。ちなみに手前のsetはgetcomponent<>によるものでした。
66
+
67
+ 2020/10/25追記:
68
+ ```c#
69
+ using System.Collections;
70
+ using System.Collections.Generic;
71
+ using UnityEngine;
72
+ using UnityEngine.UI;
73
+
74
+
75
+ [RequireComponent(typeof(Rigidbody))]
76
+ public class PlayerLocomotor : MonoBehaviour
77
+ {
78
+ [SerializeField]
79
+ private Rigidbody rb = null;
80
+ private Rigidbody RB { set { Debug.Log("passSet", rb.gameObject); rb = value; } get { Debug.Log("passGet", rb.gameObject); return rb; } }
81
+
82
+ [SerializeField]
83
+ private float moveOnGroundPower = 100f;
84
+ [SerializeField]
85
+ private float moveInAirPower = 100f;
86
+
87
+ [SerializeField]
88
+ private float airForwardPower = 6;
89
+
90
+ private float airForwardPowerCurrent = 0;
91
+ public float airForwardPowerMAX = 200f;
92
+
93
+ private const float floatingSpeed = 7f; //システム的に前に進むスピード
94
+
95
+ [HideInInspector]
96
+ public bool isBoosted = false;
97
+ private bool isBoostedOld = false;
98
+
99
+ [SerializeField]
100
+ private Slider boostGauge = null;
101
+ private const float boostMax = 100f; //ブースト燃料のマックス
102
+ private float currentBoostRemain = 100; //ブースト燃料の残り
103
+ private const float boostCost = 10f; //ブーストするのに必要な燃料コスト。コスト毎秒必要
104
+ private const float boostRecoverValue = 30f; //燃料の自動回復速度。値毎秒回復する
105
+
106
+ public ParticleSystem boostParticle = null;
107
+
108
+ public bool isCoroutine = false;
109
+
110
+ private bool isParalyzed = false;
111
+ private Vector3 paralyzedVector = Vector3.zero; //麻痺した時の方向ベクトル
112
+
113
+ public bool isBurst = false;
114
+
115
+ private bool isIngame = false;
116
+
117
+ private void Awake()
118
+ {
119
+ currentBoostRemain = boostMax;
120
+ SystemManager.IsIngameSwitch += SetIsIngame;
121
+ RB = GetComponent<Rigidbody>();
122
+ }
123
+
124
+ private void Start()
125
+ {
126
+ SystemManager.SetRigidbodyList(RB);
127
+ SystemManager.OnIsGroundSwicthed += OnGroundSwitched;
128
+ UpdateBoostUI();
129
+
130
+ }
131
+
132
+ private void Update()
133
+ {
134
+ if (!isIngame)
135
+ return;
136
+
137
+ UpdateBoost();
138
+ UpdateBoostUI();
139
+ UpdateParalyze();
140
+
141
+ if (isBoosted)
142
+ airForwardPowerCurrent = Mathf.Lerp(airForwardPowerCurrent, airForwardPowerMAX, Time.deltaTime * airForwardPower);
143
+ else
144
+ airForwardPowerCurrent = Mathf.Lerp(airForwardPowerCurrent, 0, Time.deltaTime * airForwardPower);
145
+ }
146
+
147
+ public void MoveGround(Vector2 vector)
148
+ {
149
+ UpdateBoostOnGround();
150
+
151
+ var vec = new Vector3(vector.x * moveOnGroundPower, 0, vector.y * moveOnGroundPower);
152
+ AddForce(vec, ForceMode.Acceleration);
153
+
154
+ UpdateRotationOnGround(vec);
155
+
156
+ //var gVec = new Vector3(vec.x, 0, vec.z);
157
+ //SystemManager.PlayerMove(gVec);
158
+ }
159
+
160
+ public void MoveInAir(Vector2 vector)
161
+ {
162
+ UpdateBoostInAir();
163
+ if (currentBoostRemain <= 0)
164
+ return;
165
+
166
+ var vec = new Vector3((vector.x * moveInAirPower), (vector.y * moveInAirPower * 2.0f), airForwardPowerCurrent);
167
+ AddForce(vec, ForceMode.Acceleration);
168
+
169
+ UpdateRotationOnAir(vec);
170
+ UpdateBoostParticle(vector.y);
171
+
172
+ var gVec = new Vector3(vec.x, vec.y, vec.z - (transform.position.z < 0 ? SystemManager.gravityPower + floatingSpeed : 0));
173
+ SystemManager.PlayerMove(gVec);
174
+ }
175
+
176
+ public void AddForce(Vector3 vec, ForceMode mode = ForceMode.Acceleration)
177
+ {
178
+ if (isParalyzed)
179
+ return;
180
+
181
+ RB.AddForce(vec, mode);
182
+ }
183
+
184
+ private void UpdateRotationOnGround(Vector3 lookAtLocal)
185
+ {
186
+ if (isParalyzed)
187
+ return;
188
+
189
+ var vec = lookAtLocal.normalized;
190
+ vec += transform.position;
191
+
192
+ transform.LookAt(vec);
193
+ }
194
+
195
+ private void UpdateRotationOnAir(Vector3 lookAtLocal)
196
+ {
197
+ if (isParalyzed)
198
+ return;
199
+
200
+ var vec = lookAtLocal.normalized;
201
+
202
+ transform.rotation = Quaternion.RotateTowards(transform.rotation, Quaternion.LookRotation(vec), moveInAirPower * Time.deltaTime);
203
+ }
204
+
205
+ private void UpdateBoost()
206
+ {
207
+ if (isParalyzed)
208
+ return;
209
+
210
+ isBoosted = (TouchUtility.GetTouch() == TouchInfo.Moved || TouchUtility.GetTouch() == TouchInfo.Stationary);
211
+
212
+
213
+ if (currentBoostRemain <= 0)
214
+ isBoosted = false;
215
+
216
+ if (isBoosted != isBoostedOld)
217
+ {
218
+ isBoostedOld = isBoosted;
219
+ if(!SystemManager.GetIsGrounded())
220
+ RB.useGravity = !isBoosted;
221
+ }
222
+ }
223
+
224
+ private void OnGroundSwitched(bool isGrounded)
225
+ {
226
+ if (isParalyzed)
227
+ return;
228
+
229
+ if (isGrounded)
230
+ RB.useGravity = true;
231
+ else
232
+ RB.useGravity = !isBoosted;
233
+ }
234
+
235
+ private void UpdateBoostOnGround()
236
+ {
237
+ currentBoostRemain += boostRecoverValue * Time.deltaTime;
238
+ if (currentBoostRemain > boostMax)
239
+ currentBoostRemain = boostMax;
240
+ }
241
+
242
+ private void UpdateBoostInAir()
243
+ {
244
+ if (isParalyzed)
245
+ {
246
+ if (boostParticle.isEmitting)
247
+ SetBoostParticleActive(false);
248
+ return;
249
+ }
250
+
251
+ if (TouchUtility.GetTouch() == TouchInfo.Moved || TouchUtility.GetTouch() == TouchInfo.Stationary)
252
+ {
253
+ currentBoostRemain -= boostCost * Time.deltaTime;
254
+ if (currentBoostRemain < 0)
255
+ currentBoostRemain = 0;
256
+
257
+ if (isBurst)
258
+ currentBoostRemain = boostMax;
259
+
260
+ if (!boostParticle.isEmitting && currentBoostRemain > 0)
261
+ SetBoostParticleActive(true);
262
+ }
263
+ else if (boostParticle.isEmitting)
264
+ SetBoostParticleActive(false);
265
+ }
266
+
267
+ private void SetBoostParticleActive(bool active)
268
+ {
269
+ if (active)
270
+ boostParticle.Play();
271
+ else
272
+ boostParticle.Stop(true, ParticleSystemStopBehavior.StopEmitting);
273
+ }
274
+
275
+ private void UpdateBoostUI()
276
+ {
277
+ var v = Mathf.InverseLerp(0, boostMax, currentBoostRemain);
278
+ boostGauge.value = v;
279
+ }
280
+
281
+ public void TakeOffWithJump()
282
+ {
283
+ StartCoroutine(TakeOffCoroutine());
284
+ }
285
+
286
+ private IEnumerator TakeOffCoroutine()
287
+ {
288
+
289
+ isCoroutine = true;
290
+ var boostedY = transform.position.y;
291
+ var destY = boostedY + 3;
292
+
293
+ yield return null;
294
+
295
+ while (transform.position.y < destY)
296
+ {
297
+ var vector = transform.forward * 2 + transform.up * 5;
298
+
299
+ AddForce(vector, ForceMode.Impulse);
300
+ yield return null;
301
+ }
302
+ AddForce(Vector3.forward * 50, ForceMode.Impulse);
303
+
304
+ isCoroutine = false;
305
+ }
306
+
307
+ public void SetParalyzeActive(bool active)
308
+ {
309
+ isParalyzed = active;
310
+ RB.useGravity = active;
311
+
312
+ if (active)
313
+ paralyzedVector = transform.rotation.eulerAngles;
314
+ }
315
+
316
+ private void UpdateParalyze()
317
+ {
318
+ if (!isParalyzed)
319
+ return;
320
+
321
+ SystemManager.PlayerMove(paralyzedVector.normalized);
322
+ }
323
+
324
+ private void UpdateBoostParticle(float inputYvec)
325
+ {
326
+ if (isBurst)
327
+ return;
328
+
329
+ var main = boostParticle.main;
330
+ main.gravityModifier = inputYvec;
331
+ }
332
+
333
+ public void AddBoost(float value)
334
+ {
335
+ currentBoostRemain = Mathf.Clamp(currentBoostRemain + value, 0, boostMax);
336
+ }
337
+
338
+ private void SetIsIngame(bool active)
339
+ {
340
+ isIngame = active;
341
+ }
342
+ }
343
+
344
+ ```
345
+ アドバイスを受けて、PlayerLocomotorクラスの全文を追記しました。
346
+ 実行中に最初に起こるエラーとしてはこのクラス内のOnGroundSwitched()で、プレイヤーが設置していた場合の処理です。ゲーム開始時に設置判定が別クラスで行われるのでそれを受けてこの関数が実行されるのですが、ここでエラーが起こります。
347
+ 同じクラス内での処理なので指摘していただいたような、シーンの更新によって破棄されたオブジェクトへのアクセスによるエラーというようなことはないと思うのですがほかに原因も思い当たりません。

1

プロパティによる検証の結果を追加しました。

2020/10/25 01:40

投稿

SeiSeis
SeiSeis

スコア12

title CHANGED
File without changes
body CHANGED
@@ -52,4 +52,14 @@
52
52
  挙句、シーンを再読み込みした後のインスペクターを確認するとrigidbodyがちゃんと割り当てられています。
53
53
  ![イメージ説明](f9f7e48517583657e937265bcbba2d49.png)
54
54
 
55
- ほかにはどういう対応ができるでしょうか。どなたかよろしくお願いします。
55
+ ほかにはどういう対応ができるでしょうか。どなたかよろしくお願いします。
56
+
57
+ 2020/10/21追記:
58
+ rbにプロパティを付けてシーン再読み込み時にset/getが正しく行われているかを検証してみました。
59
+ ```c#
60
+ [SerializeField]
61
+ private Rigidbody rb = null;
62
+ private Rigidbody RB { set { Debug.Log("passSet", rb.gameObject); rb = value; } get { Debug.Log("passGet", rb.gameObject); return rb; } }
63
+ ```
64
+ ![イメージ説明](a277c9f357b95d94e2a57d4205a910dd.png)
65
+ ちゃんとエラー前にSetしているようです。ちなみに手前のsetはgetcomponent<>によるものでした。