//tips
//photonアニメーション改善
Walkのアクションをboolにより分岐させる処理を実装する。後ろへの方向転換の際に角度が真後ろにならなかったのでVector3 moveForward = transform.position - transform.forward * 500;へと後ろ方向の座標数値を大きくしたら改善された。
EnvPlaymove5photonスクリプトのキャラクターの動作処理部分は下記のようになった。
void FixedUpdate()
{
if (photonView.IsMine)
{
// Upキーで前に進む
if (Input.GetKey("up"))
{
Inverseflag = true;
if (!animator.IsInTransition(0) && !animator.GetCurrentAnimatorStateInfo(0).IsName("RabbitWalk3"))
{
//animator.SetTrigger("playwalking");
animator.SetBool("playwalkingbool", true);
}
Vector3 moveForward = transform.position + transform.forward * 100;
moveForward.y = 0;
//Quaternion targetRotation = Quaternion.LookRotation(moveForward);
//transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, Time.deltaTime);
rb.position = transform.position + transform.forward * 1.5f * Time.deltaTime * rabbitspeedup * wolfspeed;
//MoveGo();
}
if (Input.GetKeyUp("up"))
{
animator.SetBool("playwalkingbool", false);
}
// Downキーで後ろに進む
if (Input.GetKey("down"))
{
if (!animator.IsInTransition(0) && !animator.GetCurrentAnimatorStateInfo(0).IsName("RabbitWalk3"))
{
//animator.SetTrigger("playwalking");
animator.SetBool("playwalkingbool", true);
}
if (Inverseflag)
{
Vector3 moveForward = transform.position - transform.forward * 500;
moveForward.y = 0;
//Quaternion targetRotation = Quaternion.LookRotation(moveForward - transform.position);
Quaternion targetRotation = Quaternion.LookRotation(moveForward);
//transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, Time.deltaTime);
transform.rotation = targetRotation;
Inverseflag = false;
}
rb.position = transform.position + transform.forward * 1.0f * Time.deltaTime * rabbitspeedup * wolfspeed;
//MoveGo();//10から2
}
if (Input.GetKeyUp("down"))
{
animator.SetBool("playwalkingbool", false);
}
//right キーで右に進む
if (Input.GetKey("right"))
{
Inverseflag = true;
//animator.SetTrigger("playwalking");
if (!animator.IsInTransition(0) && !animator.GetCurrentAnimatorStateInfo(0).IsName("RabbitWalk3"))
{
//animator.SetTrigger("playwalking");
animator.SetBool("playwalkingbool", true);
}
Vector3 moveForward = transform.position + transform.right * 500;
moveForward.y = 0;
//Quaternion targetRotation = Quaternion.LookRotation(moveForward - transform.position);
Quaternion targetRotation = Quaternion.LookRotation(moveForward);
transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, 2 * Time.deltaTime);
//transform.rotation = targetRotation;
//rb.position = transform.position + transform.right * 2.0f * Time.deltaTime;
rb.position = transform.position + transform.forward * 2.0f * Time.deltaTime * rabbitspeedup * wolfspeed;
//MoveGo();
}
if (Input.GetKeyUp("right"))
{
animator.SetBool("playwalkingbool", false);
}
//left キーで左に進む
if (Input.GetKey("left"))
{
Inverseflag = true;
if (!animator.IsInTransition(0) && !animator.GetCurrentAnimatorStateInfo(0).IsName("RabbitWalk3"))
{
//animator.SetTrigger("playwalking");
animator.SetBool("playwalkingbool", true);
}
Vector3 moveForward = transform.position - transform.right * 500;
moveForward.y = 0;
//Quaternion targetRotation = Quaternion.LookRotation(moveForward - transform.position);
Quaternion targetRotation = Quaternion.LookRotation(moveForward);
transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, 2 * Time.deltaTime);
//rb.position = transform.position - transform.right * 2.0f * Time.deltaTime;
rb.position = transform.position + transform.forward * 2.0f * Time.deltaTime * rabbitspeedup * wolfspeed;
//MoveGo();
}
if (Input.GetKeyUp("left"))
{
animator.SetBool("playwalkingbool", false);
}
}
}
アニメーションが同期できなくなった要因に移る。 NetworkCharactorスクリプトをオフにして現状のアニメーションがどう反映される確認する。photonanimatorviewのsynchronize parametersで新しく追加したboolがdisableになっていたのでboolに変更。これでwalkのアニメーションも従来通り反映されるようになった。遅延もしているのだが、同期のため送られている座標とアニメーションの同期タイミングがちぐはぐであるため変に感じられるのかもしれない。アニメーションの方が同期が少し早く、座標の同期が少し遅い。
ゴーレムの攻撃判定が2体目のキャラクターでうまくいっていない問題は別途見直す。
ゲームに物理オブジェクトがある場合の遅延は、クライアントから別のクライアントにメッセージが 送信される際の所要時間が原因で、メッセージは、クライアントAが送信してからわずか100ミリ秒後にクライアントBによって受信され、その間にもAは動き続けていることが問題のよう。
このラグ補正をOnPhotonSerializeViewで実装できるようなので、そちらの手法を確認する。
下記を参考にした。
https://doc.photonengine.com/ja-jp/pun/current/gameplay/lagcompensation
受信者の設定が重要なようで、メッセージが送信され受信されるまでの経過時間を計算する必要があり、それを、メッセージが送信された時刻を表すタイムスタンプを含むPhotonMessageInfoとタイムスタンプ間の差異を計算するためにPhotonNetwork.Timeを使用する。
NetworkCharactorスクリプトをこちらの形に合うように編集。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Photon.Pun;
public class NetworkCharactor : MonoBehaviour, IPunObservable
{
void IPunObservable.OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
{
Rigidbody rigidbody = this.GetComponent<Rigidbody>();
if (stream.IsWriting)
{
stream.SendNext(rigidbody.position);
stream.SendNext(rigidbody.rotation);
stream.SendNext(rigidbody.velocity);
}
else
{
rigidbody.position = (Vector3)stream.ReceiveNext();
rigidbody.rotation = (Quaternion)stream.ReceiveNext();
rigidbody.velocity = (Vector3)stream.ReceiveNext();
float lag = Mathf.Abs((float)(PhotonNetwork.Time - info.timestamp));
rigidbody.position += rigidbody.velocity * lag;
}
}
}
上記を生成オブジェクトにアタッチすることで動きがかなり改善された。素晴らしい。
次は、2体目の生成キャラにダメージを与えられなかったゴーレムの攻撃判定についてスクリプトを見直していく。