- Home /
Using UNET and the High Level API, what is the best way to synchronize a networked Orbital Dog Fighting Game?
>>>>>>>>>>>>>>>>>>>>This question is a work in progress<<<<<<<<<<<<<<<<<<<<
So, I think its safe to say that when working with game objects moving at high speeds good Network Synchronization is not straight forward. Add to that basic problem orbital mechanics plus fast projectiles and you have a tricky synchronization problem. As countless before me, I am trying to make a multiplayer orbital dog fighting simulation game. The game is blocked out but I have yet to solve the synchronization problem. After a lot of fiddling and reading and failing and continuing on I have finally come to make a post (Question) in attempt to gather all the voices and their particular solutions to bear on the issue of the orbital dog fighter as multiplayer game.
To narrow down here is the game outline.
The orbital dog fight takes place on a scaled down planet. Roughly several kilometers in radius. Player controlled ships fly in the planet's atmosphere and may orbit the planet once escaping the atmosphere. Players can shoot projectiles and damage the enemy ships, towers and base. Towers (turret guns at the base) may shoot at non-friendly ships, damage and destroy them.
CLAMP: The game DOES NOT contest floating point limitations but seeks to be under Kraken thresholds. This applies to position and speed.
Because of the scaled planet and mass ratios player ships may achieve orbits with velocities under roughly 400 meters per second. Velocities of course increase with the orbit.
The most closely related solution I could find is discussed in this link by Anton (Gaijin CEO and War Thunder Lead Developer) link text
Answers such as provided by link text and link text do not give a great explanation of the actual network mechanics. I have include below a Weapons System Network script that sits on my player ship prefab. It is the current iteration of the solution but is far from being complete or confirmed in the right direction.
From what I have read it may seem best to go with Anton's method of extrapolation given the space ship and its projectiles are moving about as fast a those warbirds in Warthunder. Of course in the extrapolation this means including calculations for orbital (spherical) gravity instead of just the downward vector of a flatearth. Alas I am at a crossroads. Any thoughts? If you have limited understanding of the subject feel free to not comment but rather point the wizards you know to come try their magic here. Thank you all.
using System.Collections;
using UnityEngine;
using UnityEngine.Networking;
public class WeaponSystemNet : NetworkBehaviour
{
/// <summary>
/// Needs a lot of love
/// MWG 2018
/// </summary>
[SerializeField]
private Transform[] m_Mainguns = new Transform[2];
private PlayerConnectionObject playerConnection;
private float shellSpeed;
public GameObject bullet;
private float reloadingTime = .05f;
private bool shooting;
[SerializeField] private AudioClip weaponDischarge; //sound file
private AudioSource WeaponSoundSource;
ShellNet shell;
private void Awake()
{
SetupWeaponSystems();
StartCoroutine("WaitForPlayerConnectionInit");
}
private void SetupWeaponSystems()
{
WeaponSoundSource = gameObject.AddComponent<AudioSource>();
WeaponSoundSource.playOnAwake = false;
WeaponSoundSource.clip = weaponDischarge;
shell = bullet.GetComponent<ShellNet>();
shellSpeed = shell.m_shellVelocity;
}
private IEnumerator WaitForPlayerConnectionInit()
{
yield return new WaitUntil(() => gameObject.GetComponent<PlayerControllerNet>().PlayerConnection != null);
//needs timeout
playerConnection = gameObject.GetComponent<PlayerControllerNet>().PlayerConnection;
}
[Command]
void CmdFire(int ID)
{
GameObject bulletClone0 = Instantiate(bullet, m_Mainguns[0].position, m_Mainguns[0].rotation);
Rigidbody shellRb0 = bulletClone0.GetComponent<Rigidbody>();
shellRb0.velocity = m_Mainguns[0].forward * shellSpeed * m_Mainguns[0].forward.magnitude;
bulletClone0.name = "NetShell ::" + ID.ToString();
uint netIDnum = bulletClone0.GetComponent<NetworkIdentity>().netId.Value;
NetworkConnection thisconn = playerConnection.connectionToClient;
NetworkServer.SpawnWithClientAuthority(bulletClone0, thisconn);
NetworkIdentity netId = bulletClone0.GetComponent<NetworkIdentity>();
TargetReceiveNetShellandIntegrate(thisconn, netId, ID);
}
[TargetRpc]
public void TargetReceiveNetShellandIntegrate(NetworkConnection target, NetworkIdentity netId, int localID)
{
GameObject activeShells = ClientScene.FindLocalObject(netId.netId);
Debug.Log("HEY GOT YOUR NET SHELL ::" + activeShells.name.ToString());
GameObject localShell = GameObject.Find("Shell" + localID.ToString());
Debug.Log("HEY GOT YOUR LOCAL SHELL ::" + localShell.name.ToString());
activeShells.transform.position = localShell.transform.position;
activeShells.transform.rotation = localShell.transform.rotation;
Rigidbody netshellRG = activeShells.GetComponent<Rigidbody>();
Vector3 vel = localShell.GetComponent<Rigidbody>().velocity;
netshellRG.velocity = vel;
Destroy(localShell);
}
private void LocalFire()
{
int thisBulletID;
GameObject bulletClone0 = Instantiate(bullet, m_Mainguns[0].position, m_Mainguns[0].rotation);
Rigidbody shellRb0 = bulletClone0.GetComponent<Rigidbody>();
shellRb0.velocity = m_Mainguns[0].forward * shellSpeed * m_Mainguns[0].forward.magnitude;
thisBulletID = bulletClone0.GetInstanceID();
bulletClone0.name = "Shell" + thisBulletID.ToString();
CmdFire(thisBulletID);
WeaponSoundSource.Play();
}
private IEnumerator FullAutoShooting()
{
shooting = true;
yield return new WaitForSeconds(reloadingTime);
LocalFire();
shooting = false;
}
public void WeaponFire()
{
if (!shooting)
{
StartCoroutine("FullAutoShooting");
}
}
}
UNITY 5.6.6f2 UNET HLAPI Network Synchronization Fast moving Vehicles and their Projectiles
in a virtual reality orbital dog fighter?
hey, I'm the OP in one of the links you posted. Can you better outline the problem you're trying to solve? It might help us find the answer you're looking for :)
Hi @robochase Thank you for responding. Sorry for not being more clear but I am not sure myself. I am a blind man looking for the one eyed man. I am generally asking / wondering: 1. What is the best network implementation for an orbital dog fighter? 2. Can it even be done with HLAPI or is that the wrong approach if my target is say S$$anonymous$$m? 3. Looking at Warthunder and Anton's hints, could a similar method be used with the HLAPI?
This is where I am stuck right now with my own implementation..........................
The game is has rigidbody bullets which, using the script above to shoot, work on the Client side (local bullets are used to update the network version then destroyed). Looks and works from the Client side. The Host/Server sees the updated Network bullet shot from the client and can take damage etc whatever .... good to go. However from the Client side observing the Host/Server shooting, the Client sees the Host's shell explode on the Host which is not what the Host sees, which is his(Hosts local shell) heading off in the direction fired. $$anonymous$$y process of eli$$anonymous$$ation leaves the possibility of the Host/Server not responding to the TargetRPC method thereby not updating the network shell according to the local...
I think this method could generally work for simple synchronization of bullets across players but it TRUSTS clients ( a big nono right?) and it relies on the networkTransform component which I am finding finicky.
All in all I would just rather travel the road "most stomped out" in this case... if there are enough cases of people implementing this kind of behavior (ie Warthunder style dogfight with an orbital element.. or six... haha okay)
Surely this only creates more questions but that is the point and brings me back to a close. Is it even worth all the time it will take to solve this with the HLAPI or should I just start with LLAPI and get grinding?
Thank you @robochase