Unity3d 网络同步算法
来源:互联网 发布:考勤机如何导出数据 编辑:程序博客网 时间:2024/05/17 14:26
/****************************************************
* 作者:JESSE
* 博客:http://hi.baidu.com/jesse_luzexi
* 开发工具: Unity3D
* 语言:C#
* 用途:网络同步
* 项目:网络赛车竞技游戏
* 难点:竞技游戏的同步算法需要达到非常高的准确度,对于一定范围的网络延迟需要保持游戏的准确性。
对于非竞技性游戏而言,也需要有一定的准确度,但并不一定需要本算法,但可以以此算法进行借鉴性研究,因为网络同步的原理是相同的
本算法运用了,持续模拟行进轨迹,预拉扯算法(也就是导航推测算法)以及加上的三次参数法,所写得。
* 出处:本人项目原封不动的代码。
* * 本人保证绝无半点保留。只希望能让一些不知道怎么写网络的技术人员能有所借鉴,只为能提高中国技术人员水平。
*
* 本人崇尚算法第一,一切以数学 和 算法能力 来判断一个程序员的优劣性。
* 任何其他版本都非本人所写。只要你能看明白,就算是掌握了一门高科技了。
* 请持续关注博客,关于网络同步的各种探讨和总结,以及游戏构架的经验。
* 也可加微博进行探讨:http://t.qq.com/jesse_luzexi
*
*
* 转载请注明出自: http://hi.baidu.com/jesse_luzexi
*
****************************************/
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;
public class NetworkController : MonoBehaviour
{
// Use this for initialization
void Start ()
{
this.rigidbody.useGravity = false;
}
// Update is called once per frame
void Update ()
{
NetworkListen();
}
#region 网络监听
private void NetworkListen()
{
this.rigidbody.useGravity = false;
this.rigidbody.angularVelocity = Vector3.zero;
if( SelfInfo.GamePlayerInfo.ContainsKey(this.name) && SelfInfo.GamePlayerInfo[this.name].que.Count > 0 )
{
long networktime = ( BaseInfo.NetWorkTime + BaseInfo.DelayBackTime + (long)((Time.time - BaseInfo.GameTime)*1000f) );
int i;
for( i = 0 ; i<SelfInfo.GamePlayerInfo[this.name].que.Count ; i++ )
{
if( networktime <= long.Parse( (string)SelfInfo.GamePlayerInfo[this.name].que[i].data[18] ) )
{
break;
}
}
if( i == SelfInfo.GamePlayerInfo[this.name].que.Count )
i--;
MessageElement message_item = SelfInfo.GamePlayerInfo[this.name].que[ i ];
MessageElement message_item2;
if( i > 0 )
{
message_item2 = SelfInfo.GamePlayerInfo[this.name].que[ i-1 ];
SelfInfo.GamePlayerInfo[this.name].que.RemoveRange(0,i-1);
}
else
{
message_item2 = SelfInfo.GamePlayerInfo[this.name].que[ i ];
}
Vector3 Nowvelocity = new Vector3(float.Parse((string)message_item.data[11]) , float.Parse((string)message_item.data[12]) , float.Parse((string)message_item.data[13]) );
Vector3 Nowvelocity2 = new Vector3(float.Parse((string)message_item2.data[11]) , float.Parse((string)message_item2.data[12]) , float.Parse((string)message_item2.data[13]) );
Vector3 NowVelocityA = new Vector3(float.Parse((string)message_item.data[14]) , float.Parse((string)message_item.data[15]) , float.Parse((string)message_item.data[16]) );
Vector3 NowVelocityA2 = new Vector3(float.Parse((string)message_item2.data[14]) , float.Parse((string)message_item2.data[15]) , float.Parse((string)message_item2.data[16]) );
Quaternion Nowrotation = new Quaternion(float.Parse((string)message_item.data[7]) , float.Parse((string)message_item.data[8]) , float.Parse((string)message_item.data[9]) , float.Parse((string)message_item.data[10]) );
Quaternion Nowrotation2 = new Quaternion(float.Parse((string)message_item2.data[7]) , float.Parse((string)message_item2.data[8]) , float.Parse((string)message_item2.data[9]) , float.Parse((string)message_item2.data[10]) );
Vector3 Nowposition = new Vector3( float.Parse((string)message_item.data[4]) , float.Parse((string)message_item.data[5]) , float.Parse((string)message_item.data[6]) );
Vector3 Nowposition2 = new Vector3( float.Parse((string)message_item2.data[4]) , float.Parse((string)message_item2.data[5]) , float.Parse((string)message_item2.data[6]) );
//~ Debug.Log(networktime - long.Parse((string)message_item.data[18]));
long TimeLimitExceed = 500;
//忽略大于固定延迟时间
if( networktime - long.Parse((string)message_item.data[18]) > TimeLimitExceed )
{
//~ Debug.Log(networktime - long.Parse((string)message_item.data[18]));
return;
}
//求新的位置点
float tmptime = 0f;
float delaytime = 0.1f;
if( Nowvelocity.magnitude != 0 )
tmptime += ( Nowposition - Nowposition2 ).magnitude / Nowvelocity2.magnitude;
//求移动中间点
float AddSpeedTime = (float)( networktime - long.Parse((string)message_item.data[18]) )/1000f;
float DisTime = (float)( long.Parse( (string)message_item.data[18] ) - long.Parse( (string)message_item2.data[18] ) )/1000f;
Vector3 VelocityA = NowVelocityA;
Vector3 NewPosition = Nowposition + Nowvelocity*AddSpeedTime + VelocityA*AddSpeedTime*AddSpeedTime/2f + (Nowvelocity+AddSpeedTime*VelocityA)*delaytime ;
Vector3 NewPosition1 = Nowposition + Nowvelocity*AddSpeedTime + VelocityA*AddSpeedTime*AddSpeedTime/2f;
if( (NewPosition1 - this.transform.position).magnitude > 10f )
{
Debug.Log("Distance is larger than 10 meters!");
this.rigidbody.velocity = (Nowvelocity+AddSpeedTime*VelocityA)*delaytime;
this.rigidbody.angularVelocity = Vector3.zero;
this.transform.rotation = Nowrotation;
this.transform.position = NewPosition1;
return;
}
//~ Debug.DrawLine( NewPosition , NewPosition + Vector3.up*20f );
//~ this.transform.position = NewPosition;
//~ return;
//~ if( (NewPosition - this.rigidbody.position).magnitude > 10 )
//~ this.GetComponentInChildren<Collider>().isTrigger = true;
//~ else
//~ this.GetComponentInChildren<Collider>().isTrigger = false;
Vector3 NewVelocity;
//~ if( Vector3.Angle( ( Nowposition - NewPosition ).normalized , ( NewPosition - this.rigidbody.position ).normalized ) > 110f )
//~ {
//~ NewVelocity = ( Nowposition2 - Nowposition ).normalized * Nowvelocity.magnitude;
//~ dislen = ( (float)( networktime - long.Parse((string)message_item2.data[18]) ) + delaytime ) / ( (float)( long.Parse( (string)message_item.data[18] ) - long.Parse( (string)message_item2.data[18] ) ) );
//~ NewPosition = Vector3.Slerp( Nowposition2 , Nowposition , dislen );
//~ NewVelocity = ( NewPosition - this.rigidbody.position ).normalized * ( NewPosition - this.rigidbody.position ).magnitude / tmptime;
//~ Debug.Log("in back: "+ Vector3.Angle( ( Nowposition - NewPosition ).normalized , ( NewPosition - this.rigidbody.position ).normalized ) );
//~ }
//~ else
//~ {
//把新速度付给本物体
if( tmptime < 0.00001f )
{
NewVelocity = ( NewPosition - this.rigidbody.position ).normalized * Nowvelocity.magnitude;
}
else
{
NewVelocity = ( NewPosition - this.rigidbody.position ).normalized *( NewPosition - this.rigidbody.position ).magnitude / tmptime;
}
this.rigidbody.velocity = NewVelocity;
//车辆方向改变旋转模拟
float len = 1f;
if( (NewPosition - this.rigidbody.position).magnitude > 0 )
len = NewVelocity.magnitude*Time.deltaTime / (NewPosition - this.rigidbody.position).magnitude;
this.transform.rotation = Quaternion.Slerp( this.rigidbody.rotation , Nowrotation , len );
}
}
#endregion
- Unity3d 网络同步算法
- unity3d网络基础:状态同步(客户端实例)
- Physx Unity3D同步模拟
- Unity3D客户端实时同步
- Unity3d实现帧同步
- Unity3d 插值同步
- Unity3d多人游戏与网络功能(四)-状态机同步与远程动作
- 网络同步
- 网络同步
- MMOG网络同步算法揭秘(QQ幻想)
- 分布式算法 1 同步网络的形式化描述
- MMOG网络同步算法揭秘(QQ幻想)
- Unity3D客户端实时同步技术
- Unity3D中实现帧同步
- Unity3D中实现帧同步
- 详解rsync算法--如何减少网络同步文件时的网络传输量
- unity3D网络入门教程
- unity3D网络之OnNetworkInstantiate
- mysql去掉重复值的简单方法
- ubuntu_ftp_server配置方法【附root用户无法登陆ftp解决方案】
- 什么是.NET和.NET Framework?
- Java初始化顺序总结
- startService and bindService
- Unity3d 网络同步算法
- 网络游戏实时动作同步方案手记(1)
- 20110423晴
- 别的程序员是怎么读你的简历的
- 网络游戏实时动作同步方案手记(3)
- SiteMesh入门(四)之给莫个页面单独指定模板
- C 语言指针详解
- 64位编程命令选项
- 一个程序员的C#命名规则(挺不错的)