Синхронизировать объекты на клиенте и сервере, в Unet?
Сделал мультиплеер посредством Unet
На сцене есть объект (маска которую можно надеть на персонажа), сам скрипт работает корректно , что у первого что у второго игрока, но вот синхронизация оставляет желать лучшего.
Когда я на хосте (сервере, создателе сервера, как угодно) надеваю маску на своего персонажа, она нормально одевается и снимается тоже, если смотреть на это дело со стороны клиента (подключившего игрока), то прекрасно видно как он снимает и надевает его
весь код скрипта :
public class ForMask : NetworkBehaviour
{
public Transform Formask;
public Transform Formask2;
public Transform Drop;
public bool OnMe = false;
public bool Resolution = false;
public bool OnMe2 = false;
public bool Resolution2 = false;
float rotationX = 0;
public float lookSpeed = 2.0f;
public float lookXLimit = 45.0f;
public Transform mask;
public bool TextOver = false;
public Text MyTestLabel;
// Start is called before the first frame update
void Start()
{
//Formask = GameObject.FindGameObjectWithTag("Formask").transform;
//Formask2 = GameObject.FindGameObjectWithTag("Formask2").transform;
//Drop = GameObject.FindGameObjectWithTag("Drop").transform;
}
// Update is called once per frame
void Update()
{
CmdTextOverObject();
//Formask = GameObject.FindGameObjectWithTag("Formask").transform;
//Formask2 = GameObject.FindGameObjectWithTag("Formask2").transform;
//Drop = GameObject.FindGameObjectWithTag("Drop").transform;
if (Input.GetKey(KeyCode.Mouse0) && Resolution) //если нажали на лкм и игрок рядом то надеваем на него
{
Formask = GameObject.FindGameObjectWithTag("Formask").transform;
GetComponent<BoxCollider>().enabled = false;
GetComponent<Rigidbody>().useGravity = false;
transform.position = Formask.position;
OnMe = true;
}
if (Input.GetKey(KeyCode.Mouse0) && Resolution2)
{
Formask2 = GameObject.FindGameObjectWithTag("Formask2").transform;
GetComponent<BoxCollider>().enabled = false;
GetComponent<Rigidbody>().useGravity = false;
transform.position = Formask2.position;
OnMe2 = true;
}
if (Input.GetKey(KeyCode.Mouse1) && Resolution)
{
Drop = GameObject.FindGameObjectWithTag("Drop").transform;
OnMe = false;
transform.position = Drop.position;
GetComponent<Rigidbody>().useGravity = true;
GetComponent<BoxCollider>().enabled = true;
}
if(Input.GetKey(KeyCode.Mouse1) && Resolution2)
{
Drop = GameObject.FindGameObjectWithTag("Drop").transform;
OnMe2 = false;
transform.position = Drop.position;
GetComponent<Rigidbody>().useGravity = true;
GetComponent<BoxCollider>().enabled = true;
}
if (OnMe)
{
transform.position = Formask.position;
transform.rotation *= Quaternion.Euler(0, Input.GetAxis("Mouse X") * lookSpeed, 0);
}
if (OnMe2)
{
transform.position = Formask2.position;
transform.rotation *= Quaternion.Euler(0, Input.GetAxis("Mouse X") * lookSpeed, 0);
}
}
void OnTriggerEnter(Collider col) //проверяем приблизился ли игрок
{
if(col.gameObject.tag == "Player")
{
Resolution = true;
}
else if (col.gameObject.tag == "Player2")
{
Resolution2 = true;
}
}
void OnTriggerExit(Collider col)
{
if(col.gameObject.tag == "Player")
{
Resolution = false;
}
else if (col.gameObject.tag == "Player2")
{
Resolution2 = false;
}
}
Но вот со стороны клиента, когда я ее надеваю, на хосте этого не видно.
по сути я надел маску, на клиенте это видно, а у хоста она все так же продолжает лежать на столе.
Полистал в интернете насчет этого, но исчерпывающего ответа так и не нашел, везде лишь речь про синхронизацию игроков. Мне стало интересно почему же когда сервер что-то делает, то это видит клиент,а вот в обратном порядке синхронизации просто никакой.
(я настроил все что нужно, сами игроки двигаются правильно и плавно, но вот взаймодействие хромает причем на обе ноги)
В чем вопрос, как мне от лица клиента, дать хосту понять что я изменил положение этой "маски", когда надел, и то что я изменил его обратно, когда снял?
(дело не в маске, не так принципиально, оно ни каких объектах толком нормально не пашет)
знаю что код костыльный, но мне в данный момент важна его работоспособность, а не чистота
Ответы (1 шт):
через
[Commаnd]
public void Primer() { действие для второго игрока }
добился того чего надо
все что делает клиент сервер видит, клиент тоже видит что делает сервер
как оказалось, мне проще из клиента сделать "попрошайку" нежели копаться с этим
[ClientRPC]
, когда надо клиент просто просит , а сервер от себя это делает, а не от лица клиента
как писали на большинстве сайтов.
насколько я понял, от лица клиента он может что-то сделать как раз таки в этом
[ClientRPC]
, но мне нет дела до этого, поскольку оно работает, хоть как-то
и да, объясню ситуацию и дам пример кода (я же не тот злой дядька с англояз сайта, что лишь что-то втирает про АссигнЛокалАуторити, а пример рабочего кода не дает)
итак! если хотите чтоб клиент делал что-либо, и это видел сервер тоже
просто сделайте так:
-
- напишите метод комманд
-
- вызовите его когда нужно (при нажатии клавиши там или просто в апдейте)
-
- смотрите как оно работает в обе стороны
