HTC_VR_Unity_Unet多人协同问题记录以及解决

1 篇文章 0 订阅

HTC_VR_Unity_Unet多人协同

因为要做HTC协同的项目,一开始选定了使用UNET完成协同部分操作,后来Unet碰到了很多坑,在这里记一下:
解决了场景跳转报错问题
解决了多个HTC预制冲突问题

///网络管理脚本

using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using UnityEngine.Networking;
///
/// 将NetworkManager方法按这里的方式重写
/// 因为我只用到了这些方法所以只重写这一小部分
/// 如果用到其他也需要重写不然会遇到未知的错误
/// 具体原因不清楚
///

public class VR_NetWorkeManager : NetworkManager
{

public Transform thePlayersParent;
public override void OnServerAddPlayer(NetworkConnection conn, short playerControllerId)
{
    // base.OnServerAddPlayer(conn, playerControllerId);

    var player = (GameObject)GameObject.Instantiate(playerPrefab, startPositions[0].position, Quaternion.identity);
  
    player.transform.parent = thePlayersParent;
    NetworkServer.AddPlayerForConnection(conn, player, playerControllerId);
    //NetworkServer.SendByChannelToAll();

}



public override void OnClientSceneChanged(NetworkConnection conn)
{
    Debug.Log(456);
    ClientScene.AddPlayer(conn, 0);
   //base.OnClientSceneChanged(conn);
   //ClientScene.Ready(conn);
}

public override void OnClientConnect(NetworkConnection conn)
{
    base.OnClientConnect(conn);
}

public override void OnServerSceneChanged(string sceneName)
{
    Debug.Log(sceneName);
   //base.OnServerSceneChanged(sceneName);
}

}

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
using Valve.VR;
using Assets.Scripts.VR_GameTools;
using Valve.VR.InteractionSystem;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using UnityEngine.Video;
using DG.Tweening;
///
/// 必须挂在NetWorkeManager生成的Play上
/// 需要将HTC预制体的左手和右手改名成Hand1和Hand2
/// 需要一个VR_RayPrefab射线的预制体,最好挂上网络标识NetWorkeIdentity
/// 需要给VR_CaiDan,VR_Tra赋值VR_Hand_Axis暂时没用上
///
public class VR_MyPlayer : NetworkBehaviour
{
#region 头盔相关参数
//头盔相关参数==
GameObject VR_Hand1;//手柄1
GameObject VR_Hand2;//手柄2
public SteamVR_Input_Sources VR_LeftHand;
public SteamVR_Input_Sources VR_RightHand;
public SteamVR_Action_Boolean VR_CaiDan;
public SteamVR_Action_Boolean VR_Tra;
public SteamVR_Action_Vector2 VR_Hand_Axis;
public GameObject VR_RayPrefab;
#endregion
#region 网络物体

#endregion
#region 本地客户端获取的物体

#endregion
#region  生命周期
void Start()
{
   
    if (!isLocalPlayer)
    {

        //不是本地客户端执行什么


        //这里在跳转场景时会碰到问题
        //原因是有多个客户端的预制体
        //各客户端相机显示的是同一个相机,HTC位置链接的是所有预制体所以在这里会出现问题
        //解决办法:在不是本地客户端的是隐藏除了要显示的身体模型外的所有组件
        //如果需要同步手柄位置,人物动作,可以再写一个没有相机,以及HTC同步的位置的模型,用网络连接的方式同步,PS这里没写所以没有相关代码
        return;
    }
  //本地客户端执行什么

}

void Update()
{
    if (!isLocalPlayer)
    {
        return;
    }
  
    #region hand1扳机事件
    VR_Hand1 = GameTools.FindChild(transform, "Hand1").gameObject;
    if (VR_Tra.GetStateDown(VR_LeftHand))
    {
        Ray ray1 = new Ray(VR_Hand1.transform.position, VR_Hand1.transform.forward);
        RaycastHit hitinfo;
        if (Physics.Raycast(ray1, out hitinfo))
        {
           
        }
    }
    if (VR_Tra.GetState(VR_LeftHand))
    {
        Ray ray1 = new Ray(VR_Hand1.transform.position, VR_Hand1.transform.forward);
        RaycastHit hitinfo;
        if (Physics.Raycast(ray1, out hitinfo))
        {
           
        }
    }
    if (VR_Tra.GetStateUp(VR_LeftHand))
    {
        MovePlayerId = int.Parse((GetComponent<NetworkIdentity>().netId.ToString()));
        Ray ray1 = new Ray(VR_Hand1.transform.position, VR_Hand1.transform.forward);
        RaycastHit hitinfo;
        if (Physics.Raycast(ray1, out hitinfo))
        {
          // 点击执行的方法
            TriggerEvent(hitinfo.transform.name,hitinfo.transform.gameObject);
        }
    }
    #endregion
    #region 扳机2事件
    VR_Hand2 = GameTools.FindChild(transform, "Hand2").gameObject;
    //Debug.DrawRay(ray.origin, ray.direction, Color.red);
    if (VR_Tra.GetStateDown(VR_RightHand))
    {
        Ray ray1 = new Ray(VR_Hand2.transform.position, VR_Hand2.transform.forward);
        RaycastHit hitinfo;
        if (Physics.Raycast(ray1, out hitinfo))
        {
           
        }
    }
    if (VR_Tra.GetState(VR_RightHand))
    {
        Ray ray1 = new Ray(VR_Hand2.transform.position, VR_Hand2.transform.forward);
        RaycastHit hitinfo;
        if (Physics.Raycast(ray1, out hitinfo))
        {
            
        }
    }
    if (VR_Tra.GetStateUp(VR_RightHand))
    {
        MovePlayerId = int.Parse((GetComponent<NetworkIdentity>().netId.ToString()));
        Debug.Log("手柄2名称:" + VR_Hand2.gameObject.name);
        Ray ray = new Ray(VR_Hand2.transform.position, VR_Hand2.transform.forward);
        RaycastHit hit;
        if (Physics.Raycast(ray, out hit))
        {     // 点击执行的方法
            Debug.Log("手柄2名称:" + VR_Hand2.gameObject.name);
            TriggerEvent(hit.transform.name,hit.transform.gameObject);
        }
    }
    #endregion
    ///点击菜单跳转场景
    if (VR_CaiDan.GetStateDown(VR_LeftHand)|| VR_CaiDan.GetStateDown(VR_RightHand))
    {
        //name要跳转的场景
        CmdLoadSceneAsync(name);
    }
   
}
#endregion
#region 本地方法
/// <summary>
/// 画一条射线
/// </summary>
/// <param name="hand22"></param>
void CreatRay(GameObject hand22)
{

    Vector3 pos = new Vector3(0.002f, -0.004f, 1.001f);
    Vector3 scale = new Vector3(0.001f, 0.001f, 100.0f);
    Vector3 rot = new Vector3(0, 0, 0);

    GameObject _Ray = Instantiate(VR_RayPrefab) as GameObject;
    _Ray.transform.SetParent(hand22.transform);
    _Ray.transform.localScale = new Vector3(0.002f, 0.002f, 100f);
    _Ray.transform.localPosition = Vector3.zero + new Vector3(0f, 0f, 50f);
    _Ray.transform.localRotation = Quaternion.identity;
    //NetworkServer.Spawn(_Ray);
}
/// <summary>
/// 手柄点击触发方法
/// 根据名字判断执行什么方法
/// </summary>
/// <param name="name">名字</param>
/// <param name="hit">碰撞点</param>
void TriggerEvent(string name,GameObject hit)
{
    Debug.Log("手柄2名称:" + name);
    switch (name)
    {
        case "Magnify":
            CmdScale(0.1f);
            break;
    }
}
#endregion

#region 
/// <summary>
/// 这里是客户端发给服务器
/// </summary>
/// <param name="dam">传输的数值,支持float,int ,string,Vector3等数值但是不支持GameObject等类型</param>
[Command]
void CmdScale(float dam)
{
    RpcScale(dam);
}

///
/// 点击后触发什么功能写在RPC里面
/// 这里是服务器分发给客户端执行
///
/// 传输的数值,支持float,int ,string,Vector3等数值但是不支持GameObject等类型
[ClientRpc]
void RpcScale(float dam)
{

}
#endregion

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值