Unity Multiplayer отправляет позицию и обновляет партнеру, socket.io - PullRequest
0 голосов
/ 27 июня 2018

Я пытаюсь создать многопользовательскую 2D-игру, и я столкнулся со следующей проблемой: анимация и движение отображаются неправильно для партнера. У них небольшая задержка, и персонаж выглядит дрожащим. Моя анимация имеет 3 состояния: (IDLE, MOVE и JUMP). В обоих объектах есть компонент твердого тела - player1, player 2. Мой код выглядит так:

Отправка позиции от игрока 1 к игроку 2: GameController.cs

public PlayerManager player1;
public PartenerManager player2;

void Update () // CODE TO SEND POSITION
    {
        if (player1.transform.position.x!=position.x || player1.transform.position.y!=position.y || player1.transform.position.z !=position.z)
        {
            int state = player1.getState();
            position = new Vector3(player1.transform.position.x, player1.transform.position.y, player1.transform.position.z);
            Dictionary<string, string> data = new Dictionary<string, string>();
            data["position"] = position.x + ";" + position.y + ";" + position.z;
            data["state"] = state.ToString();  // this is for the state of the annimation
            socket.Emit("MOVE", new JSONObject(data));
        }
    }
// RECEIVING POSITION
void Start () {
             socket.On("MOVED", onUserMove);
}
void onUserMove(SocketIOEvent obj)
    {
        string stare = obj.data.GetField("state").ToString();
        stare = stare.Substring(1);
        stare = stare.Substring(0, stare.Length - 1);
        player2.setPositionState(JsonToVector3(JsonToString(obj.data.GetField("position").ToString(),"\"")),int.Parse(stare));
    }

Получение и отображение позиции у игрока 2: PartnerManager.cs

public class PartenerManager : MonoBehaviour {
    public bool gotmove=false;
    public float speedX = 6;
    private string playerName;
    public Text username;
    Animator anim;
    Rigidbody2D rb;
    bool facingRight;
    float speed;
    Vector3 vec3;
    int stare;
    void Start () {
        rb = GetComponent<Rigidbody2D>();
        anim = GetComponent<Animator>();
        facingRight = true;
    }
    void Flip()
    {
        if ((speed> 0 && !facingRight) || (speed < 0 && facingRight))
        {
            facingRight = !facingRight;
            Vector3 temp = transform.localScale;
            temp.x *= -1;
            transform.localScale = temp;
        }
    }
    public void setPositionState(Vector3 ve,int st)
    {
        gotmove = true;
        vec3 = ve;
        stare = st;
    }
    void FixedUpdate ()
    {

        if (gotmove==true)
        {
            if (transform.position.x < vec3.x)
            {
                Debug.Log("RIGHT");
                speed = speedX;
            }
            if (transform.position.x > vec3.x)
            {
                Debug.Log("Left");
                speed= -speedX;
            }
            if (transform.position.x == vec3.x)
            {
                speed = 0;
            }
            transform.position = vec3;
            Flip();
            anim.SetInteger("State", stare);
            gotmove = false;
        }
    }
}

Код игрока 1: PlayerManager.cs

public class PlayerManager : MonoBehaviour {

    public float speedX=6;
    public float jumpSpeedY=300;
    private string playerName;
    public Text username;
    Animator anim;
    Rigidbody2D rb;
    bool facingRight;
    bool jumping;
    bool grounded;
    float speed;
    int numJumps = 0;
    void Start ()
    {
        anim = GetComponent<Animator>();
        rb = GetComponent<Rigidbody2D>();
        facingRight = true;
        grounded = false;
    }
    public int getState()
    {
        return anim.GetInteger("State");
    }
    void Update ()
    {
        MovePlayer(speed);
        Flip();

    }
    void MovePlayer(float playerSpeed)
    {
        if ((playerSpeed < 0 && !jumping) || (playerSpeed>0 && !jumping))
        {
            anim.SetInteger("State", 1);
        }
        if(playerSpeed==0 && !jumping)
        {
            anim.SetInteger("State", 0);
        }
        rb.velocity = new Vector3(speed, rb.velocity.y, 0);
    }
    void Flip()
    {
        if((speed>0 && !facingRight) || (speed<0 && facingRight))
        {
            facingRight = !facingRight;
            Vector3 temp = transform.localScale;
            temp.x *= -1;
            transform.localScale = temp;
        }
    }
    void OnCollisionEnter2D(Collision2D other)
    {
        if(other.gameObject.tag=="ground")
        {
            jumping = false;
            numJumps = 0;
            grounded = true;
            anim.SetInteger("State", 0);
        }
    }
    public void WalkLeft()
    {
        speed = -speedX;
    }
    public void WalkRight()

    {
        speed = speedX;
    }
    public void StopMoving()
    {
        speed = 0;
    }
    public void Jump()
    {
        grounded = false;
        if (grounded == true && numJumps >= 2)
        {
            numJumps = 0;
        }
        if (numJumps < 2 )
        {
            jumping = true;
            if (numJumps == 0)
            {
                rb.AddForce(new Vector2(rb.velocity.x, jumpSpeedY));
            }
            else
            {
                rb.AddForce(new Vector2(rb.velocity.x, jumpSpeedY-100));
            }
            anim.SetInteger("State", 2);
            numJumps++;
        }


    }
}

1 Ответ

0 голосов
/ 28 июня 2018

Я решил проблему. При отправке позиции вы также должны отправить вращение - кватернион. Вот мое решение: ВАЖНО: в компоненте с жестким телом необходимо проверить вращение оси Z PartnerManager.cs - партнер. Объект, который должен быть синхронизирован

public class PartenerManager : MonoBehaviour
public Text username;
    Vector3 targetPosition;
    Quaternion targetRotation;
    Animator anim;
    bool facingRight;
    int state;
    void Start()
    {
        anim = GetComponent<Animator>();
        facingRight = true;
        anim.SetInteger("State", 0);
    }
    void Flip()
    {
        facingRight = !facingRight;
        Vector3 temp = transform.localScale;
        temp.x *= -1;
        transform.localScale = temp;
    }

    public void setPositionState(Vector3 pozitie, Quaternion rotatie, int stare)
    {

        targetPosition = pozitie;
        targetRotation = rotatie;
        state = stare;

    }
    void ApplyMovement()
    {
        Debug.Log("pozitie actuala:" + transform.position.x + " pozitie mutata: " + targetPosition.x);
        if (transform.position.x < targetPosition.x)
        {
            if (facingRight != true)
            {
                Flip();
                facingRight = true;
            }

        }

        if (transform.position.x > targetPosition.x)
        {
            if (facingRight == true)
            {
                Flip();
                facingRight = false;
            }
        }
        transform.position = Vector3.Lerp(transform.position, targetPosition, 0.5f);
        transform.rotation = Quaternion.Lerp(transform.rotation, targetRotation, 0.5f);
        anim.SetInteger("State", state);



    }
    void FixedUpdate()
    {
        ApplyMovement();

    }

GameController.cs - контролер. Здесь я отправляю и получаю сообщение с позицией

if (player1.transform.position.x != position.x || player1.transform.position.y != position.y || player1.transform.position.z != position.z)
        {
                int state = player1.getState();
                position = new Vector3(player1.transform.position.x, player1.transform.position.y, player1.transform.position.z);
                Dictionary<string, string> data = new Dictionary<string, string>();
                data["position"] = position.x + ";" + position.y + ";" + position.z;
                data["state"] = state.ToString();
                data["rotation"] = player1.transform.rotation.x + ";" + player1.transform.rotation.y + ";" + player1.transform.rotation.z + ";" + player1.transform.rotation.w;
                socket.Emit("MOVE", new JSONObject(data));
        }
Quaternion JsonToQuaternion(string target)
    {
        Quaternion newVector;
        string[] newString = Regex.Split(target, ";");
        newVector = new Quaternion(float.Parse(newString[0]), float.Parse(newString[1]), float.Parse(newString[2]),float.Parse(newString[3]));
        return newVector;
    }
void onUserMove(SocketIOEvent obj)
    {
        string stare = obj.data.GetField("state").ToString();
        stare = stare.Substring(1);
        stare = stare.Substring(0, stare.Length - 1);
        Vector3 pozitie = JsonToVector3(JsonToString(obj.data.GetField("position").ToString(), "\""));
        Quaternion rotatie= JsonToQuaternion(JsonToString(obj.data.GetField("rotation").ToString(), "\""));

        int state = int.Parse(stare);
        //Debug.Log("Partener: pozitie: " + pozitie + " rotatie " + rotatie + " stare: " + stare);
        player2.setPositionState(pozitie,rotatie,state);

        //player2.setPositionState(JsonToVector3(JsonToString(obj.data.GetField("position").ToString(),"\"")),int.Parse(stare));
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...