//tips
//シーンでのカプセル挙動の制御
現在のシーンではプレイヤーであるカプセルが倒れたり、斜めになったりする場合がある。アタッチしていたコンポーネントrigidbodyのrotationではx,y,zをfreezeしていたのでyだけ外して再度確認する。
プレイヤーが何もしないでも回り出す現象が発生。y軸の回転回りで重複があり変な挙動になってしまっているのかと思ったが、freezeはしておいた方が良さそう。
Rigidbodyをアタッチしたゲームオブジェクトの姿勢を変更したい場合にrigidbodyのrotationを用いると考えておくとわかりやすい。
この方法による姿勢の変更は変化ではなく上書きで、開始時点で元々の姿勢の影響を受けてしまう。カプセルが倒れていたり、斜めになっているのは、初期時点だったので、スポーン地点の被りでプレイヤー同士が生成中に衝突したのが原因ではないかと考える。
これはスポーン場所を調整すれば良い問題なのでマップが完成した際にスポーン位置指定するのでそこで考える。どちらかというと対プレイヤーへの衝突で重量が足りていないためy値が増えてしまうことに懸念を感じたので、rigidbodyのmassを100まで増やして確認したがあまり変わらず。
衝突を検知するCollision DetectionをDiscreteにし、連続衝突を行わせないようにしてみるが効果なし。
試しにrigidbodypositionのy軸移動を一度フリーズしてみたら衝突の際の傾きの変化などはなくなった。これにより衝突時yの値が増えるため姿勢が崩れることがわかる。
ただ、yをフリーズした場合、初期スポーン位置から重力で落下せず、その場で重力に反発し、微細動してしまうという問題があるので、できるだけyをフリーズせずに同様の挙動を行わせたい。
他に物体の重量を上げる方法を確認する。特定オブジェクトの重力を変更する方法があったのでそちらも実行する。下記スクリプトをプレイヤーにアタッチして挙動を確認する。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ChangeGravity : MonoBehaviour
{
[SerializeField] private Vector3 localGravity;
private Rigidbody rBody;
private void Start()
{
rBody = this.GetComponent<Rigidbody>();
rBody.useGravity = false;
}
private void FixedUpdate()
{
SetLocalGravity();
}
private void SetLocalGravity()
{
rBody.AddForce(localGravity, ForceMode.Acceleration);
}
}
これで衝突時に上へ飛ぶことがなくなり、挙動がかなり改善された。
ここでスポーン位置にも関係するのでListを使って重複しない値をランダムに取得する方法を考える。
下記が参考となる1~10の範囲の整数を重複せずにランダムで取得するサンプルコードで、Listに対象範囲の整数をすべて入れて、乱数で指定したインデックスの値を取り出している。その後、numbers.RemoveAtで、取り出した値をリストから削除して同じ値が2回取り出されないようにしている。配列の長さをnumbers.Countでindex化している。
using UnityEngine;
using System.Collections.Generic;
public class Test : MonoBehaviour {
int start = 1;
int end = 10;
List<int> numbers = new List<int>();
void Start() {
for (int i = start; i <= end; i++) {
numbers.Add(i);
}
//リストには1-10が入っている状態になる
while (numbers.Count > 0) {
int index = Random.Range(0, numbers.Count);
int Myposition = numbers[index];
Debug.Log(Myposition);
numbers.RemoveAt(index);
}
}
}
ただ、よく考えたら別々のシーンで再生されるので、シーン遷移と同様にロビーの段階でプレイヤーナンバーを割り振り、割り振った番号を、ロビーから持ち越したスクルプトで各ポジションにつくようにする感じになりそう。
次に同期されないアニメーションの挙動について考える。
PhotonViewのObserverにPhotonAnimatorViewを追加するのだが、プレイヤーは最初アニメーションがついている棒を持っておらず、何もない段階でPhotonAnimatorViewを追加するとエラ〜メッセージが表示される。
一旦、再生シーンで挙動を確認する。
MissingComponentException: There is no 'Animator' attached to the "GamePlayer1(Clone)" game object, but a script is trying to access it.
You probably need to add a Animator to the game object "GamePlayer1(Clone)". Or your script needs to check if the component is attached before using it.
Photon.Pun.PhotonAnimatorView.Update () (at Assets/Photon/PhotonUnityNetworking/Code/Views/PhotonAnimatorView.cs:129)
棒を持っていない段階で上記エラーが発生し、棒を持ってもアニメーションの同期は行われなかった。アイテムの保有状態についての情報が見つからないので、この挙動については対応策があるのか確認中。