검색결과 리스트
글
실전 Unity3D Engine Programing 과정 9일차 (2013.08.01 (목))
## 일정치 않은 네트워크 데이터 보간법
0.2초 이내로 온 데이터는 믿을 수 있는 데이터 그 이상 차이난 데이터는 오래전 데이터 이다.
interpolation (보간법)
- 유효한 네트워크 데이터 수신시 데이터를 부드럽게 보간하는 방법
extrapolation (보외법)
- 일정 시간내에 들어오는 데이터가 없을 경우 데이터의 변화를 부드럽게 보간하는 법
최근에 들어온 위치, 회전각도 time, position, rotation
다음에 들어온 위치, 회전각도 time, position, rotation
## 데디니콘..
속도는 시간분의 거리 (거리/시간)
거리는 속도 곱하기 시간
얼마나 빠른 속도로 얼마의 시간동안 움직였냐가 지금 내 위치이다.
현재 위치가 중요하다.....
데디니콘..
- 네트워크 전송 구간의 로스타임을 감안해서 데이터 수신 측에서 위치를 좀더 이동 시켜 주는 방법..
## 개발하자.
- 2DShooting(7월26일) 게임 프로젝트의 내용을 다시 불러서 이어서 처리한다.
- 아셋 > Prefabs > Player 프리팝을 하나 만든다.
- 하이어아키에서 Player 오브젝트를 선택한다.
- 컨포너트를 붙인다. Network View..
- Tag를 Player로 바꾼다.
- 이 Player오브젝트를 Player 프리팝에 저장한다.
- player를 지운다.
- Save scene, project한다.
- 스크립트에 Netowrk 폴더 만든다.
- PlayerRemote 스크립트를 만든다.
using UnityEngine;
using System.Collections;
public class PlayerRemote : MonoBehaviour {
public class State : System.Object {
public Vector3 p;
public Quaternion r;
public float t;
//스트리밍에사용할클래스.
public State(Vector3 p, Quaternion r, float t)
{
//포지션 타임 로테이션값으로만들었다.
this.p = p;
this.r = r;
this.t = t;
}
}
// 물리인터폴리에션이있다. 이것을사용한다.
public bool simulatePhysics = true;
public bool updatePostion = true;
public float phyInterp = 0.1f;
public float netInterp = 0.2f;
public float ping;
public float jitter; //고른데이터가아니라서.
public bool isResponding = false;
public string netCode = "(No Connections)";
private int m;
private Vector3 p;
private Quaternion r;
private State[] states = new State[15];
private int stateCount = 0;
private Vector3 velocity;
private State nullstate;
//Network View를적용할수있는것 오브젝트, 카메라, 스크립트.
// Use this for initialization
void Start () {
networkView.observed = this;
nullstate = new State(Vector3.zero, Quaternion.identity, 0.0f);
for(int i=0;i<states.Length;i++)
{
states[i] = new State(Vector3.zero, Quaternion.identity, 0.0f);
}
velocity = Vector3.zero;
}
//시스템의성능이든나쁜성은이드udpate는다르다
//따라서FixedUpdate()를사용한다
//시간이오르걸리는것을사용하면안된다. 물리실험만코딩한다.
void FixedUpdate()
{
if(!updatePostion || states[10].Equals(nullstate))
{
//최소데이터가들어오지않았다면.
return;
}
//jitter, ping formula
float diffTime = (float)Network.time - states[0].t;
//불필요한것을업애기에떨림현상은제거할수있다.
jitter = Mathf.Lerp(jitter, Mathf.Abs(ping-diffTime), Time.deltaTime*0.3f);
//jitter값보다너무높은것은무시한다는것이다.
ping = Mathf.Lerp(ping, (float)Network.time - states[0].t, Time.fixedDeltaTime *0.3f);
//인터포리레이션 익스폴리레이션이중요하다.
//보간타임이필요하다.
float interpolationTime = (float)Network.time - netInterp;
if(states[0].t > interpolationTime)
{
//시간내에온경우이다.
int i;
for(i=0;i<stateCount;i++)
{
//시간내에들어온것이면.
if(states[i] != null && (states[i].t <= interpolationTime || i == stateCount -1))
{
//최근에들어온것과나중에들어온것을비교한다.
State rhs = states[Mathf.Max(i-1, 0)]; //last ex.0
State lhs = states[i]; //current ex.1
float l = rhs.t -lhs.t;
float t = 0.0f;
if(l > 0.0001f)
{
//잘모르면수학책을봐라.
t= ((interpolationTime - lhs.t)/1);
}
if(simulatePhysics){
//정상적인데이터이다.
//0.5f는반반씩보간한다는뜻.
transform.position = Vector3.Lerp(transform.position, Vector3.Lerp(lhs.p, rhs.p, t), phyInterp);
transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.Slerp(lhs.r, rhs.r, t), phyInterp);
velocity = ((rhs.p - states[i+1].p)/(rhs.t - states[i+1].t)); //속도는시간분의거리.
} else{
//물리적으로 박는다 너무늦게와서.
transform.position = Vector3.Lerp(lhs.p, rhs.p, t);
transform.rotation = Quaternion.Slerp(lhs.r, rhs.r, t);
}
//응답이있었고에러코드는없었다.
isResponding = true;
netCode = " ";
return;
}
}
}else{
//시간외의경우너무늦게왔다. 외선보간.
float extrapolationLenght = (interpolationTime - states[0].t);
if(extrapolationLenght < 1.0f && states[0].Equals(nullstate)==false && states[1].Equals(nullstate)==false)
{
if(!simulatePhysics)
{
transform.position = states[0].p + (((states[0].p - states[1].p) / (states[0].t - states[1].t))*extrapolationLenght);
transform.rotation = states[0].r;
}
isResponding = true;
if(extrapolationLenght < 0.5f)
{
//윺효한응답이다.
netCode = ">allowed";
} else
{
//지연응답이다.
netCode = "(Delayed)";
}
} else{
netCode = "(Not Responding)";
isResponding = false;
}
}
if(simulatePhysics && states[0].t > states[2].t)
{
velocity = ((states[0].t -states[2].t));
}
//유니티의버그로스케일값이사라진다.스케일이사라지면보간한다.
if(transform.localScale == Vector3.zero)
{
//MakePerfectSize함수를호출해서보간한다.
gameObject.SendMessage("MakePerfectSize");
}
//여기까지가이동이다.
}
//위치와이동을15초간보내야한다.
void OnSerializeNetworkView(BitStream stream, NetworkMessageInfo info)
{
//두가지가있다 send, receive(쓸때..
if(stream.isWriting)
{
p= gameObject.transform.position;
r = gameObject.transform.rotation;
m = stateCount == 0? 0:(int)(((float)Network.time - states[0].t)*1000);
//아래순서가중용하다 동일하게받아야한다.
stream.Serialize(ref p);
stream.Serialize(ref r);
stream.Serialize(ref m);
}else
{
stream.Serialize(ref p);
stream.Serialize(ref r);
stream.Serialize(ref m);
State state = new State(p, r, (float)(info.timestamp - (m >0?(m/1000):0.0f)));
if(stateCount == 0)
{
states[0] = new State(state.p, state.r, state.t);
} else if(state.t > states[0].t)
{
for(int k= state.Length-1; k > 0;k--)
{
state[k] = states[k-1];
}
states[0] = new State(state.p, state.r, state.t);
} else
{
Debug.Log("Out-of-Order state received and ignored ~");
}
stateCount = Mathf.Min(stateCount +1, states.Length);
}
}
public Vector3 GetVelocity()
{
return this.velocity;
}
}
using UnityEngine;
using System.Collections;
public class PlayerSprite : SpriteBase {
public float Speed = 10.0f;
private float LastShootTime;
public float ShootDelay = 0.2f;
public GameObject bullet;
//new code add
public NetworkPlayer owner;
[RPC]
void SetPlayer(NetworkPlayer player)
{
Debug.Log("SetPlayer Called~");
owner = player;
//PlayerRemote 컴포너트를붙여준다.
gameObject.AddComponent("PlayerRemote");
}
// Use this for initialization
void Start () {
LastShootTime = Time.time;
}
// Update is called once per frame
void Update () {
float moveAmt = Input.GetAxis("Horizontal")
*Speed * Time.deltaTime;
transform.Translate(Vector3.right * moveAmt);
if(Time.time > LastShootTime + ShootDelay)
{
LastShootTime = Time.time;
Instantiate(bullet,transform.position,
transform.rotation);
}
}
}
UnityNetworkCs 스크립트만든다.
EnemySprite 수정하자.
using UnityEngine;
using System.Collections;
public class EnemySprite : SpriteBase {
public float Speed = 10.0f;
public GameObject explosion;
// Use this for initialization
void Start () {
gameObject.AddComponent<BoxCollider>();
}
// Update is called once per frame
void Update () {
//add
//시작한적이없으면아무것도하지않는다.
if(GameObject.FindWithTag("Player") == null) return;
float moveAmt = Speed * Time.deltaTime;
transform.Translate(Vector3.down * moveAmt);
if(transform.position.y < -4.0f)
{
InitPosition();
}
}
void InitPosition()
{
transform.position = new Vector3(
Random.Range(-3.0f,3.0f), //x
5.0f, //y
0.0f);//z
}
void OnTriggerEnter(Collider other)
{
if(other.tag == "bullet")
{
Instantiate(explosion,transform.position,
transform.rotation);
InitPosition();
GameObject main = GameObject.Find("Main");
main.SendMessage("Hit",50);
}
}
}
mainScript도 열자..
player 스크립트...에서 다시 만들자.
using UnityEngine;
using System.Collections;
public class PlayerSprite : SpriteBase {
public float Speed = 10.0f;
private float LastShootTime;
public float ShootDelay = 0.2f;
public GameObject bullet;
//new code add
public NetworkPlayer owner;
[RPC]
void SetPlayer(NetworkPlayer player)
{
Debug.Log("SetPlayer Called~");
owner = player;
//PlayerRemote 컴포너트를붙여준다.
gameObject.AddComponent("PlayerRemote");
}
// Use this for initialization
void Start () {
LastShootTime = Time.time;
}
// Update is called once per frame
void Update () {
if(Network.peerType == NetworkPeerType.Disconnected && Network.player == owner)
{
//내것일때만제어가능하다.
float moveAmt = Input.GetAxis("Horizontal")
*Speed * Time.deltaTime;
transform.Translate(Vector3.right * moveAmt);
if(Time.time > LastShootTime + ShootDelay)
{
LastShootTime = Time.time;
Instantiate(bullet,transform.position,
transform.rotation);
}
}
}
}
main 오브젝트에 콤포너트부착한다.
- networkView 상태동기화는 off
- Unity Network 스크립트를 붙인다.
- player prefabs을 링크를 건다.
- Spawn Position도 0, -2, 0
실험한다.
New 3D Text를 만든다.
- 포지션은 0.0.0
- 이것을 Player의 촬일드한다.
- Chareacer Size 0.3
- Anchor upper center
- Alig center
- Bold
- 이름은 Name
정상적으로 진행하지 못했다.
클라우드올린 자료를 봐라...
game_20130801_my
'Unity3D' 카테고리의 다른 글
실전 Unity3D Engine Programing 과정 8일차 (1) | 2013.07.31 |
---|---|
실전 Unity3D Engine Programing 과정 8일차 - 문서자료 (2) | 2013.07.31 |
실전 Unity3D Engine Programing 과정 7일차 (0) | 2013.07.30 |
실전 Unity3D Engine Programing 과정 6일차 (0) | 2013.07.29 |
실전 Unity3D Engine Programing 과정 5일차 (0) | 2013.07.26 |
RECENT COMMENT