首页 > 解决方案 > Unity Multiplayer 向合作伙伴 socket.io 发送位置和更新

问题描述

我正在尝试制作 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++;
        }


    }
}

标签: c#socketsunity3dposition

解决方案


我解决了这个问题。当您发送位置时,您还必须发送旋转四元数。这是我的解决方案: 重要提示:在刚体组件中,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));
    }

推荐阅读