質問編集履歴

4

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

2020/11/01 12:17

投稿

SeiSeis
SeiSeis

スコア12

test CHANGED
File without changes
test CHANGED
@@ -704,10 +704,10 @@
704
704
 
705
705
  SystemManager.cs
706
706
 
707
- Assets/Scripts/Utility/SystemManager.cs
707
+ SkyLow/TEST20200910/Assets/Scripts/Utility/SystemManager.cs
708
708
 
709
709
 
710
710
 
711
711
  GameSystemManager.cs
712
712
 
713
- Assets/Scripts/Manager/GameSystemManager.cs
713
+ SkyLow/TEST20200910/Assets/Scripts/Manager/GameSystemManager.cs

3

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

2020/11/01 12:17

投稿

SeiSeis
SeiSeis

スコア12

test CHANGED
File without changes
test CHANGED
@@ -691,3 +691,23 @@
691
691
  実行中に最初に起こるエラーとしてはこのクラス内のOnGroundSwitched()で、プレイヤーが設置していた場合の処理です。ゲーム開始時に設置判定が別クラスで行われるのでそれを受けてこの関数が実行されるのですが、ここでエラーが起こります。
692
692
 
693
693
  同じクラス内での処理なので指摘していただいたような、シーンの更新によって破棄されたオブジェクトへのアクセスによるエラーというようなことはないと思うのですがほかに原因も思い当たりません。
694
+
695
+
696
+
697
+ 2020/10/30追記:
698
+
699
+ ほかスクリプトのコードも載せてほしいとのことでしたが、文字数制限が来たためgithubにプロジェクトをアップロードしました。
700
+
701
+ [GitHub](https://github.com/SeiyaKobori/SkyLow.git)
702
+
703
+ 質問にあったスクリプトのパスを載せておきます
704
+
705
+ SystemManager.cs
706
+
707
+ Assets/Scripts/Utility/SystemManager.cs
708
+
709
+
710
+
711
+ GameSystemManager.cs
712
+
713
+ Assets/Scripts/Manager/GameSystemManager.cs

2

PlayerLocomotor全文を追記しました。

2020/10/30 11:55

投稿

SeiSeis
SeiSeis

スコア12

test CHANGED
File without changes
test CHANGED
@@ -127,3 +127,567 @@
127
127
  ![イメージ説明](a277c9f357b95d94e2a57d4205a910dd.png)
128
128
 
129
129
  ちゃんとエラー前にSetしているようです。ちなみに手前のsetはgetcomponent<>によるものでした。
130
+
131
+
132
+
133
+ 2020/10/25追記:
134
+
135
+ ```c#
136
+
137
+ using System.Collections;
138
+
139
+ using System.Collections.Generic;
140
+
141
+ using UnityEngine;
142
+
143
+ using UnityEngine.UI;
144
+
145
+
146
+
147
+
148
+
149
+ [RequireComponent(typeof(Rigidbody))]
150
+
151
+ public class PlayerLocomotor : MonoBehaviour
152
+
153
+ {
154
+
155
+ [SerializeField]
156
+
157
+ private Rigidbody rb = null;
158
+
159
+ private Rigidbody RB { set { Debug.Log("passSet", rb.gameObject); rb = value; } get { Debug.Log("passGet", rb.gameObject); return rb; } }
160
+
161
+
162
+
163
+ [SerializeField]
164
+
165
+ private float moveOnGroundPower = 100f;
166
+
167
+ [SerializeField]
168
+
169
+ private float moveInAirPower = 100f;
170
+
171
+
172
+
173
+ [SerializeField]
174
+
175
+ private float airForwardPower = 6;
176
+
177
+
178
+
179
+ private float airForwardPowerCurrent = 0;
180
+
181
+ public float airForwardPowerMAX = 200f;
182
+
183
+
184
+
185
+ private const float floatingSpeed = 7f; //システム的に前に進むスピード
186
+
187
+
188
+
189
+ [HideInInspector]
190
+
191
+ public bool isBoosted = false;
192
+
193
+ private bool isBoostedOld = false;
194
+
195
+
196
+
197
+ [SerializeField]
198
+
199
+ private Slider boostGauge = null;
200
+
201
+ private const float boostMax = 100f; //ブースト燃料のマックス
202
+
203
+ private float currentBoostRemain = 100; //ブースト燃料の残り
204
+
205
+ private const float boostCost = 10f; //ブーストするのに必要な燃料コスト。コスト毎秒必要
206
+
207
+ private const float boostRecoverValue = 30f; //燃料の自動回復速度。値毎秒回復する
208
+
209
+
210
+
211
+ public ParticleSystem boostParticle = null;
212
+
213
+
214
+
215
+ public bool isCoroutine = false;
216
+
217
+
218
+
219
+ private bool isParalyzed = false;
220
+
221
+ private Vector3 paralyzedVector = Vector3.zero; //麻痺した時の方向ベクトル
222
+
223
+
224
+
225
+ public bool isBurst = false;
226
+
227
+
228
+
229
+ private bool isIngame = false;
230
+
231
+
232
+
233
+ private void Awake()
234
+
235
+ {
236
+
237
+ currentBoostRemain = boostMax;
238
+
239
+ SystemManager.IsIngameSwitch += SetIsIngame;
240
+
241
+ RB = GetComponent<Rigidbody>();
242
+
243
+ }
244
+
245
+
246
+
247
+ private void Start()
248
+
249
+ {
250
+
251
+ SystemManager.SetRigidbodyList(RB);
252
+
253
+ SystemManager.OnIsGroundSwicthed += OnGroundSwitched;
254
+
255
+ UpdateBoostUI();
256
+
257
+
258
+
259
+ }
260
+
261
+
262
+
263
+ private void Update()
264
+
265
+ {
266
+
267
+ if (!isIngame)
268
+
269
+ return;
270
+
271
+
272
+
273
+ UpdateBoost();
274
+
275
+ UpdateBoostUI();
276
+
277
+ UpdateParalyze();
278
+
279
+
280
+
281
+ if (isBoosted)
282
+
283
+ airForwardPowerCurrent = Mathf.Lerp(airForwardPowerCurrent, airForwardPowerMAX, Time.deltaTime * airForwardPower);
284
+
285
+ else
286
+
287
+ airForwardPowerCurrent = Mathf.Lerp(airForwardPowerCurrent, 0, Time.deltaTime * airForwardPower);
288
+
289
+ }
290
+
291
+
292
+
293
+ public void MoveGround(Vector2 vector)
294
+
295
+ {
296
+
297
+ UpdateBoostOnGround();
298
+
299
+
300
+
301
+ var vec = new Vector3(vector.x * moveOnGroundPower, 0, vector.y * moveOnGroundPower);
302
+
303
+ AddForce(vec, ForceMode.Acceleration);
304
+
305
+
306
+
307
+ UpdateRotationOnGround(vec);
308
+
309
+
310
+
311
+ //var gVec = new Vector3(vec.x, 0, vec.z);
312
+
313
+ //SystemManager.PlayerMove(gVec);
314
+
315
+ }
316
+
317
+
318
+
319
+ public void MoveInAir(Vector2 vector)
320
+
321
+ {
322
+
323
+ UpdateBoostInAir();
324
+
325
+ if (currentBoostRemain <= 0)
326
+
327
+ return;
328
+
329
+
330
+
331
+ var vec = new Vector3((vector.x * moveInAirPower), (vector.y * moveInAirPower * 2.0f), airForwardPowerCurrent);
332
+
333
+ AddForce(vec, ForceMode.Acceleration);
334
+
335
+
336
+
337
+ UpdateRotationOnAir(vec);
338
+
339
+ UpdateBoostParticle(vector.y);
340
+
341
+
342
+
343
+ var gVec = new Vector3(vec.x, vec.y, vec.z - (transform.position.z < 0 ? SystemManager.gravityPower + floatingSpeed : 0));
344
+
345
+ SystemManager.PlayerMove(gVec);
346
+
347
+ }
348
+
349
+
350
+
351
+ public void AddForce(Vector3 vec, ForceMode mode = ForceMode.Acceleration)
352
+
353
+ {
354
+
355
+ if (isParalyzed)
356
+
357
+ return;
358
+
359
+
360
+
361
+ RB.AddForce(vec, mode);
362
+
363
+ }
364
+
365
+
366
+
367
+ private void UpdateRotationOnGround(Vector3 lookAtLocal)
368
+
369
+ {
370
+
371
+ if (isParalyzed)
372
+
373
+ return;
374
+
375
+
376
+
377
+ var vec = lookAtLocal.normalized;
378
+
379
+ vec += transform.position;
380
+
381
+
382
+
383
+ transform.LookAt(vec);
384
+
385
+ }
386
+
387
+
388
+
389
+ private void UpdateRotationOnAir(Vector3 lookAtLocal)
390
+
391
+ {
392
+
393
+ if (isParalyzed)
394
+
395
+ return;
396
+
397
+
398
+
399
+ var vec = lookAtLocal.normalized;
400
+
401
+
402
+
403
+ transform.rotation = Quaternion.RotateTowards(transform.rotation, Quaternion.LookRotation(vec), moveInAirPower * Time.deltaTime);
404
+
405
+ }
406
+
407
+
408
+
409
+ private void UpdateBoost()
410
+
411
+ {
412
+
413
+ if (isParalyzed)
414
+
415
+ return;
416
+
417
+
418
+
419
+ isBoosted = (TouchUtility.GetTouch() == TouchInfo.Moved || TouchUtility.GetTouch() == TouchInfo.Stationary);
420
+
421
+
422
+
423
+
424
+
425
+ if (currentBoostRemain <= 0)
426
+
427
+ isBoosted = false;
428
+
429
+
430
+
431
+ if (isBoosted != isBoostedOld)
432
+
433
+ {
434
+
435
+ isBoostedOld = isBoosted;
436
+
437
+ if(!SystemManager.GetIsGrounded())
438
+
439
+ RB.useGravity = !isBoosted;
440
+
441
+ }
442
+
443
+ }
444
+
445
+
446
+
447
+ private void OnGroundSwitched(bool isGrounded)
448
+
449
+ {
450
+
451
+ if (isParalyzed)
452
+
453
+ return;
454
+
455
+
456
+
457
+ if (isGrounded)
458
+
459
+ RB.useGravity = true;
460
+
461
+ else
462
+
463
+ RB.useGravity = !isBoosted;
464
+
465
+ }
466
+
467
+
468
+
469
+ private void UpdateBoostOnGround()
470
+
471
+ {
472
+
473
+ currentBoostRemain += boostRecoverValue * Time.deltaTime;
474
+
475
+ if (currentBoostRemain > boostMax)
476
+
477
+ currentBoostRemain = boostMax;
478
+
479
+ }
480
+
481
+
482
+
483
+ private void UpdateBoostInAir()
484
+
485
+ {
486
+
487
+ if (isParalyzed)
488
+
489
+ {
490
+
491
+ if (boostParticle.isEmitting)
492
+
493
+ SetBoostParticleActive(false);
494
+
495
+ return;
496
+
497
+ }
498
+
499
+
500
+
501
+ if (TouchUtility.GetTouch() == TouchInfo.Moved || TouchUtility.GetTouch() == TouchInfo.Stationary)
502
+
503
+ {
504
+
505
+ currentBoostRemain -= boostCost * Time.deltaTime;
506
+
507
+ if (currentBoostRemain < 0)
508
+
509
+ currentBoostRemain = 0;
510
+
511
+
512
+
513
+ if (isBurst)
514
+
515
+ currentBoostRemain = boostMax;
516
+
517
+
518
+
519
+ if (!boostParticle.isEmitting && currentBoostRemain > 0)
520
+
521
+ SetBoostParticleActive(true);
522
+
523
+ }
524
+
525
+ else if (boostParticle.isEmitting)
526
+
527
+ SetBoostParticleActive(false);
528
+
529
+ }
530
+
531
+
532
+
533
+ private void SetBoostParticleActive(bool active)
534
+
535
+ {
536
+
537
+ if (active)
538
+
539
+ boostParticle.Play();
540
+
541
+ else
542
+
543
+ boostParticle.Stop(true, ParticleSystemStopBehavior.StopEmitting);
544
+
545
+ }
546
+
547
+
548
+
549
+ private void UpdateBoostUI()
550
+
551
+ {
552
+
553
+ var v = Mathf.InverseLerp(0, boostMax, currentBoostRemain);
554
+
555
+ boostGauge.value = v;
556
+
557
+ }
558
+
559
+
560
+
561
+ public void TakeOffWithJump()
562
+
563
+ {
564
+
565
+ StartCoroutine(TakeOffCoroutine());
566
+
567
+ }
568
+
569
+
570
+
571
+ private IEnumerator TakeOffCoroutine()
572
+
573
+ {
574
+
575
+
576
+
577
+ isCoroutine = true;
578
+
579
+ var boostedY = transform.position.y;
580
+
581
+ var destY = boostedY + 3;
582
+
583
+
584
+
585
+ yield return null;
586
+
587
+
588
+
589
+ while (transform.position.y < destY)
590
+
591
+ {
592
+
593
+ var vector = transform.forward * 2 + transform.up * 5;
594
+
595
+
596
+
597
+ AddForce(vector, ForceMode.Impulse);
598
+
599
+ yield return null;
600
+
601
+ }
602
+
603
+ AddForce(Vector3.forward * 50, ForceMode.Impulse);
604
+
605
+
606
+
607
+ isCoroutine = false;
608
+
609
+ }
610
+
611
+
612
+
613
+ public void SetParalyzeActive(bool active)
614
+
615
+ {
616
+
617
+ isParalyzed = active;
618
+
619
+ RB.useGravity = active;
620
+
621
+
622
+
623
+ if (active)
624
+
625
+ paralyzedVector = transform.rotation.eulerAngles;
626
+
627
+ }
628
+
629
+
630
+
631
+ private void UpdateParalyze()
632
+
633
+ {
634
+
635
+ if (!isParalyzed)
636
+
637
+ return;
638
+
639
+
640
+
641
+ SystemManager.PlayerMove(paralyzedVector.normalized);
642
+
643
+ }
644
+
645
+
646
+
647
+ private void UpdateBoostParticle(float inputYvec)
648
+
649
+ {
650
+
651
+ if (isBurst)
652
+
653
+ return;
654
+
655
+
656
+
657
+ var main = boostParticle.main;
658
+
659
+ main.gravityModifier = inputYvec;
660
+
661
+ }
662
+
663
+
664
+
665
+ public void AddBoost(float value)
666
+
667
+ {
668
+
669
+ currentBoostRemain = Mathf.Clamp(currentBoostRemain + value, 0, boostMax);
670
+
671
+ }
672
+
673
+
674
+
675
+ private void SetIsIngame(bool active)
676
+
677
+ {
678
+
679
+ isIngame = active;
680
+
681
+ }
682
+
683
+ }
684
+
685
+
686
+
687
+ ```
688
+
689
+ アドバイスを受けて、PlayerLocomotorクラスの全文を追記しました。
690
+
691
+ 実行中に最初に起こるエラーとしてはこのクラス内のOnGroundSwitched()で、プレイヤーが設置していた場合の処理です。ゲーム開始時に設置判定が別クラスで行われるのでそれを受けてこの関数が実行されるのですが、ここでエラーが起こります。
692
+
693
+ 同じクラス内での処理なので指摘していただいたような、シーンの更新によって破棄されたオブジェクトへのアクセスによるエラーというようなことはないと思うのですがほかに原因も思い当たりません。

1

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

2020/10/25 01:40

投稿

SeiSeis
SeiSeis

スコア12

test CHANGED
File without changes
test CHANGED
@@ -107,3 +107,23 @@
107
107
 
108
108
 
109
109
  ほかにはどういう対応ができるでしょうか。どなたかよろしくお願いします。
110
+
111
+
112
+
113
+ 2020/10/21追記:
114
+
115
+ rbにプロパティを付けてシーン再読み込み時にset/getが正しく行われているかを検証してみました。
116
+
117
+ ```c#
118
+
119
+ [SerializeField]
120
+
121
+ private Rigidbody rb = null;
122
+
123
+ private Rigidbody RB { set { Debug.Log("passSet", rb.gameObject); rb = value; } get { Debug.Log("passGet", rb.gameObject); return rb; } }
124
+
125
+ ```
126
+
127
+ ![イメージ説明](a277c9f357b95d94e2a57d4205a910dd.png)
128
+
129
+ ちゃんとエラー前にSetしているようです。ちなみに手前のsetはgetcomponent<>によるものでした。