- Home /
Photon Syncing Enemies with Other Clients?
Ok So I have Navmesh Agents that Locals move and the AI-Code operate fine. as soon as I implement a Photon Sync code:
public Vector3 realPosition = Vector3.zero;
public Vector3 positionAtLastPacket = Vector3.zero;
public double currentTime = 0.0;
public double currentPacketTime = 0.0;
public double lastPacketTime = 0.0;
public double timeToReachGoal = 0.0;
void Update ()
{
if (!PhotonNetwork.isMasterClient)
{
timeToReachGoal = currentPacketTime - lastPacketTime;
currentTime += Time.deltaTime;
transform.position = Vector3.Lerp(positionAtLastPacket, realPosition, (float)(currentTime / timeToReachGoal));
}
}
void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
{
if (stream.isWriting)
{
stream.SendNext((Vector3)transform.position);
}
else
{
currentTime = 0.0;
positionAtLastPacket = transform.position;
realPosition = (Vector3)stream.ReceiveNext();
lastPacketTime = currentPacketTime;
currentPacketTime = info.timestamp;
}
}
}
All my Enemy game objects now Converge on one position on all clients rather then moving around the Navemesh. ![alt text][1] [1]: /storage/temp/96943-screen-shot-2017-07-02-at-102947-am.png
My AI code simply moves to selected "Goals" on the map and then attacks a player once in range. (works Fine Without Synccode.) using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.AI;
public class SimpleEnemy : Photon.MonoBehaviour {
public float fireRate = 0.4f;
private float nextFire = 0.0F;
public NavMeshAgent agent;
GameObject[] AgentPoints;
GameObject currentAgentPoint;
int index;
public GameObject EnemyBullet;
private GameObject AttackTarget;
private bool UnderAttack;
//-----------------------------------------------------------------------------------------------------------
// Use this for initialization
void Start () {
if (PhotonNetwork.isMasterClient == true) {
agent = gameObject.GetComponent<NavMeshAgent> ();
AgentPoints = GameObject.FindGameObjectsWithTag ("Goal");
index = Random.Range (0, AgentPoints.Length);
currentAgentPoint = AgentPoints [index];
agent.destination = (currentAgentPoint.transform.position);
} else {
agent.enabled = false;
}
}
//-----------------------------------------------------------------------------------------------------------
void Update(){
if (PhotonNetwork.isMasterClient == true) {
if (UnderAttack == true) {
Debug.Log ("Attacked!");
agent.SetDestination (AttackTarget.transform.position);
if (Time.time > nextFire && agent.remainingDistance < 10) {
nextFire = Time.time + fireRate;
Instantiate (EnemyBullet, this.transform.position, this.transform.rotation);
}
if (agent.remainingDistance < 10) {
agent.Stop ();
} else {
agent.Resume ();
}
if (agent.remainingDistance > 40) {
UnderAttack = false;
AttackTarget = null;
}
}
if (UnderAttack == false) {
if (agent.remainingDistance < 4) {
index = Random.Range (0, AgentPoints.Length);
currentAgentPoint = AgentPoints [index];
}
}
}
}
//-----------------------------------------------------------------------------------------------------------
void OnTriggerEnter (Collider Other){
if (PhotonNetwork.isMasterClient == true) {
if (Other.gameObject.tag == ("Player")) {
AttackTarget = Other.gameObject;
UnderAttack = true;
}
if (Other.gameObject.tag == ("ThisIsMyPlayer")) {
AttackTarget = Other.gameObject;
UnderAttack = true;
}
}
}
//-----------------------------------------------------------------------------------------------------------
}
Hi,
in the first code snippet please try Lerping from transform.position to realPosition ins$$anonymous$$d of Lerping from positionAtLastPacket to realPosition. Possible reason: Update is called more often than OnPhotonSerializeView, which - I guess - results in multiple Lerp function calls doing the exact same calculation.
Please let us know if that helps solving the problem.
Answer by purpl3grape · Feb 02, 2021 at 06:21 AM
There’s another way of navmesh ai, where the navmesh agent is what the actual game object is moving toward with the “player movement physics too” so it can steer with the same freedom as an actual player. Coupled with sending simulated inputs
So master client calculates navmesh path, and then while navmesh agent is moving locally, master client ai game objects will steer toward the navmesh agent via simulated inputs that master client sends out to all other clients.
As a result, the other players will receive the commands to move their local AI smoothly without interpolation here.
Of course when Inputs gets dropped in the process sometimes, we need to make sure we check each client’s AI positions with the master to see if they’re off by an error margin. Then simply sync it back. But because most of the time the AI is moving via inputs and not interpolation this sync is not going to have much less jitter on average. If you really needed more smoothness, just do a nice interpolation instead when the distance comparison exceeds the threshold.
So it would be helpful if an input class is created containing possible inputs a player can make in your game.
Something like: strafe left, strafe right, forward, back, jump, turn left, turn right etc,
Then these will be the simulated inputs.
Your answer
Follow this Question
Related Questions
How do I create an intermediate loading room in Photon? 0 Answers
Player position in individual device in photon multiplayer 1 Answer
Photon Network syncing the transform of a moving platform 0 Answers
[UNET] Clients position not being synced after being replaced with ReplacePlayerForConnection 1 Answer