PUN(PhotonCloud) unitypackage, Documentatation, Connect etc

PUN(PhotonCloud) unitypackage, Documentatation, Connect etc

Сообщение newArray 23 май 2013, 14:21

Сейчас фотон Cloud отсылает качать свой PUN на ассет сторе. И стоит на асет сторе нижнее ограничение версии Unity 3.5.7 Короче его просто в виде пака для старых версий уже не найдешь. Так я решил положить старый пак на сохранение. Не знаю для каких точно версий пойдет ли на 3.5.0 - имхо должен.
Единственный кто - Леонид хранитель древностей. Без него я бы уже качал юнити 3.5.7

PhotonNetworkDocumentation.pdf

PUN.unitypackage ... Unity v.3.5.x

...
У вас нет доступа для просмотра вложений в этом сообщении.
Последний раз редактировалось newArray 31 янв 2014, 08:42, всего редактировалось 9 раз(а).
newArray
Адепт
 
Сообщения: 1226
Зарегистрирован: 14 фев 2013, 07:03
Откуда: оттуда

Скрипт коннекта с выбором левела

Сообщение newArray 26 май 2013, 15:42

Дополню еще скриптом конекта с выбором левела. Хотел скрипт написать просто - не получилось. Алгоритм получается только такой - создатель комнаты выбирает левел на котором будет играть данная комната. В игре получается можно создавать только по одной комнате для каждого левела. Левелы идентифицируются по названию игры. При нажатии на кнопку конект или создания комнаты у меня предполагается переход на другой уровень. Это для игр с выбором левела в стиле шутер - типа контры. Это как бы вариант когда игрок сам не задает имя комнаты - а имя комнаты постоянное и оно соответствует левелу на котором будет происходить игра. допустим в игре будет 8 левелов-сцен и игрок смоежт выбрать любой левел и запустить комнату.
скрипт не готов полностью для игры, просто там основной алгоритм написан
Выбирать режим присоединиться или создать комнату по кнопкам (окошки таскаемые)

Web Player 0.5 mb РАБОТАЕТ ИЗ АТАЧМЕНТА. БУДЕТ ВИДЕН ТОЛЬКО ЗАРЕГЕСТРИРОВАННЫМ ПОЛЬЗОВАТЕЛЯМ!!!

HTML код для вашего блога :
Код: Выделить всё
<script language='javascript' type="text/javascript"> document.write("<iframe marginheight='0' src='http://unity3d.ru/distribution/player.php?url=http://unity3d.ru/distribution/download/file.php?id=4466&w=700&h=500&t=true&preview=1' height='"+(500+30)+"' width='700' frameborder='0' scrolling='no'></iframe>"); </script>

скрипт просто повесить на пустой го с компонентом фотон вью:
Синтаксис:
Используется javascript
#pragma strict
//script of connect to Photon with used many levels
//free to use

public var  scroll : Vector2;
public var photonView:PhotonView;
public var windowWidth: int = 600;
public var windowHeight: int = 500;

public var windowRect : Rect;
public var windowRect2 : Rect;  
public var windowRect3 : Rect = Rect (50, 50, 800, 600);

public var textures : Texture[];
public var RoomNames : String[];
public var scenes : boolean  = false;
public var rooms : boolean = false;
public var num: int;
public var showPic : boolean;


function Start () {
  photonView =  GetComponent(PhotonView);
  //PhotonNetwork.ConnectUsingSettings ("0.1");
  PhotonNetwork.ConnectUsingSettings("v2.4");
 
  windowRect = Rect((Screen.width - windowWidth)/2, (Screen.height - windowHeight)/2, windowWidth, windowHeight);  
  windowRect2  = Rect ((Screen.width - windowWidth)/2, (Screen.height - windowHeight)/2, windowWidth, windowHeight);
}


function OnGUI () {
  GUILayout.Label (PhotonNetwork.connectionStateDetailed.ToString ());
 
   
 if (GUI.Button (Rect (Screen.width - 150,50,100,30), "Create Room"))//(window run throw update)
 {
    scenes = true;
    rooms = false;
  }  
 if (scenes)  
    windowRect2 = GUI.Window (1, windowRect2, CreateRoom, "List of Scenes");
   
 if (GUI.Button (Rect (Screen.width - 150,100,100,30), "Join Room"))
 {
      rooms = true;
      scenes = false;
  }    
  if (rooms)        
    windowRect = GUI.Window (0, windowRect, ListRoom, "List of Rooms");
 
   //show big pic of the level    
     if (showPic)
   {
     
      windowRect3 = GUI.Window (2, windowRect3, PicsLevel, "Pics of Level");
 
    }
}
 
// Make the contents of the window
function ListRoom (windowID : int) {

scroll = GUILayout.BeginScrollView(scroll, GUILayout.Width(windowWidth-15), GUILayout.Height(400));
    var i : int;
    i=0;
    for (var game : RoomInfo in PhotonNetwork.GetRoomList())
       {
           GUILayout.BeginHorizontal();
           GUILayout.Label(game.name);
           GUILayout.FlexibleSpace();
           GUILayout.Label(game.playerCount + "/" + game.maxPlayers);
           GUILayout.Space (100);
                         if(GUILayout.Button("Join Room", GUILayout.Width(100), GUILayout.Height(40)))
                                 PhotonNetwork.JoinRoom(game.name);
                        GUILayout.Space (10);
                         //find index of texture
                         for(var n:int = 0; n < RoomNames.length; n++ ) {
                            if (game.name == RoomNames[n])
                                num = n;
                         }  
                           
               if (GUILayout.Button(textures[num], GUILayout.Width(100),  GUILayout.Height(100)))
               {
                         showPic = true;
                         rooms = false;
                }        
            GUILayout.EndHorizontal();
            i++;
           
       }
 GUILayout.EndScrollView();  
    GUI.DragWindow (Rect (0,0, 10000, 20));

}



function CreateRoom (windowID : int) {
var h : int =  0;
var i : int;
var butonCreate : String = "Create Room";    //name of button "Create Room"

scroll = GUILayout.BeginScrollView(scroll, GUILayout.Width(windowWidth-15), GUILayout.Height(400));
  for(i = 0; i < RoomNames.length; i ++ ) {
     GUI.enabled = true;
     h = h + 100;
       
     
     
     GUILayout.BeginHorizontal();
     var Rname : String = "       " + RoomNames[i] + ".......";
       //turn of the games wich have run    
       for (var game : RoomInfo in PhotonNetwork.GetRoomList()){
            if (RoomNames[i]==game.name)
            {
               GUI.enabled = false;
               butonCreate = "Room already Run";
            }  
            else   butonCreate = "Create Room";
       }        
      GUILayout.Button(GUIContent(Rname,  textures[i], "Resize"), GUILayout.Width(windowWidth - 200),  GUILayout.Height(100));
          //showPic = true;
         
      GUI.Label (Rect (50, h - 100/2, 100, 40), GUI.tooltip);
     GUILayout.FlexibleSpace();
       if (GUI.Button(Rect(windowWidth-180, h - 100/2, 140,50), butonCreate)){
         
                PhotonNetwork.CreateRoom(RoomNames[i], true, true, 20);
               
                }
               
      GUILayout.EndHorizontal();
   }
 GUILayout.EndScrollView();
GUI.DragWindow (Rect (0,0, 10000, 20));


}
 

 
function PicsLevel (windowID : int) {

   GUI.Box (Rect (50,50,500,500), textures[num]);
     if (GUI.Button(Rect(400,500,100,30), "Close"))
     {
         showPic = false;
          rooms = true;
      }    
    GUI.DragWindow (Rect (0,0, 10000, 20));
   

}

 


Еще прилагаю пак для версии юнити 3.5.5
Я может потом еще доделаю пример чтоб они переходили в разные сцены на простой капсуле.
У вас нет доступа для просмотра вложений в этом сообщении.
Последний раз редактировалось newArray 06 июн 2013, 16:37, всего редактировалось 2 раз(а).
newArray
Адепт
 
Сообщения: 1226
Зарегистрирован: 14 фев 2013, 07:03
Откуда: оттуда

Мультиплеер на машинах.

Сообщение newArray 29 май 2013, 13:58

Продолжу тему простых скриптов для Фотона. Простой исходник для машин по сети. Минимум кода. Здесь на машины добавлен известный, переведенный на Фотон, скрипт NetworkRiggidbody , который обеспечивает достаточную интерполяцию для машин.

Web Player 0.5 mb РАБОТАЕТ ИЗ АТАЧМЕНТА. БУДЕТ ВИДЕН ТОЛЬКО ЗАРЕГЕСТРИРОВАННЫМ ПОЛЬЗОВАТЕЛЯМ!!!

Демо в веб плеере под спойлером
Скрытый текст:
HTML код для вашего блога :
Код: Выделить всё
<script language='javascript' type="text/javascript"> document.write("<iframe marginheight='0' src='http://unity3d.ru/distribution/player.php?url=http://unity3d.ru/distribution/download/file.php?id=4467&w=700&h=500&t=true&preview=1' height='"+(500+30)+"' width='700' frameborder='0' scrolling='no'></iframe>"); </script>


исходник http://yadi.sk/d/Jfw_Df_65IFBs 6мб

Сначала задаем имя комнаты и создаем комнату.
В данном случае исходник укомплектован скриптом конекта который будет создавать комнаты по имени которое задает юзер и будет отображать список созданных комнат . окно конекта можно закрыть.
Сам скрипт получается такой
Синтаксис:
Используется javascript
#pragma strict
//script of connect to Photon with setting name of room
//free to use
var newRoomName : String;
public var  scroll : Vector2;
public var photonView:PhotonView;
public var windowWidth: int = 600;
public var windowHeight: int = 500;
public var windowRect : Rect;
//public var RoomNames : String[];
public var rooms : boolean = false;
public var allRooms : RoomInfo[];


function Start () {
  photonView =  GetComponent(PhotonView);
  allRooms = PhotonNetwork.GetRoomList();
  //PhotonNetwork.ConnectUsingSettings ("0.1");
  PhotonNetwork.ConnectUsingSettings("v2.4");
  windowRect = Rect((Screen.width - windowWidth)/2, (Screen.height - windowHeight)/2, windowWidth, windowHeight);  
 
}


function OnGUI () {
  GUILayout.Label (PhotonNetwork.connectionStateDetailed.ToString ());
 
   
 if (GUI.Button (Rect (Screen.width - 150,100,100,30), "Join Room")){
       rooms = true;
        allRooms = PhotonNetwork.GetRoomList();
 }      
     
  if (rooms)        
    windowRect = GUI.Window (0, windowRect, ListRoom, "List of Rooms");
 
 
}
 
 
function ListRoom (windowID : int) {

if (GUI.Button(Rect(windowWidth - 100,5,100,30), "Close"))
   rooms = false;

GUILayout.Space (10);
GUILayout.FlexibleSpace();
if(GUILayout.Button("Refresh List", GUILayout.Width(200), GUILayout.Height(30)))
        allRooms = PhotonNetwork.GetRoomList();

//list of rooms
scroll = GUILayout.BeginScrollView(scroll, GUILayout.Width(windowWidth-15), GUILayout.Height(400));
       for (var game : RoomInfo in allRooms)
       {
           GUILayout.BeginHorizontal();
           GUILayout.Label(game.name);
           GUILayout.FlexibleSpace();
           GUILayout.Label(game.playerCount + "/" + game.maxPlayers);
           GUILayout.Space (100);
          if(GUILayout.Button("Join Room", GUILayout.Width(100), GUILayout.Height(40)))
               PhotonNetwork.JoinRoom(game.name);
          GUILayout.Space (10);
                     
          GUILayout.EndHorizontal();
             
       }
 GUILayout.EndScrollView();
 
 
//Create new room
        GUILayout.BeginHorizontal();
                newRoomName = GUILayout.TextField (newRoomName, 35,  GUILayout.Width(345), GUILayout.Height(25));
                GUILayout.FlexibleSpace();
                if(GUILayout.Button("Create Room")){  
                //Create this room.  
                PhotonNetwork.CreateRoom(newRoomName, true, true, 20);
                //PhotonNetwork.playerName = playerName;
        allRooms = PhotonNetwork.GetRoomList();
        }
       
               
        GUILayout.EndHorizontal();
           
GUI.DragWindow (Rect (0,0, 10000, 20));

}



//send in script of instant
function OnJoinedRoom  () {
  print ("Joined room: " + newRoomName);
  for (var go: GameObject in FindObjectsOfType (GameObject))
  go.SendMessage ("OnLoaded", SendMessageOptions.DontRequireReceiver);
}



 
У вас нет доступа для просмотра вложений в этом сообщении.
Последний раз редактировалось newArray 06 июн 2013, 16:44, всего редактировалось 3 раз(а).
newArray
Адепт
 
Сообщения: 1226
Зарегистрирован: 14 фев 2013, 07:03
Откуда: оттуда

Re: Юнити пак PUN (Cloud) и простые скрипты конекта

Сообщение Friend123 31 май 2013, 17:43

Авто соперника двигается не плавно :( У меня в соседней ветке тоже самое, только еще и возвращается в исходную позицию
Аватара пользователя
Friend123
Старожил
 
Сообщения: 701
Зарегистрирован: 26 фев 2012, 22:12
Откуда: Тверь
  • ICQ

Re: Юнити пак PUN (Cloud) и простые скрипты конекта

Сообщение newArray 31 май 2013, 17:48

Ты знаешь что такое может быть из за теста на локальной машине 2 клиентов? связано с погрешностью уже самого компьютера - например там че то синхронное асинхронное. Ты пробовал тестить с кем то по инету?
Щас тестил на 2 машине нетбук- заметил наглаз эту дискретность. не думаю что это из за нет бука. не знаю я сделал все что мог - без скрипта netrigidbody вообще ерунда получается. может в нем можно еще какие то настройки подправить чтоб плавнее было.
Последний раз редактировалось newArray 08 июн 2013, 22:05, всего редактировалось 1 раз.
newArray
Адепт
 
Сообщения: 1226
Зарегистрирован: 14 фев 2013, 07:03
Откуда: оттуда

Re: Юнити пак PUN (Cloud) и простые скрипты конекта

Сообщение Friend123 31 май 2013, 19:07

newArray писал(а):Ты знаешь что такое может быть из за теста на локальной машине 2 клиентов? связано с погрешностью уже самого компьютера - например там че то синхронное асинхронное. Ты пробовал тестить с кем то по инету?

Собственно я знаю об этом, поэтому и тестил на компе и на ноуте - правда инет один :D
newArray писал(а):Щас тестил на 2 машине нетбук- заметил наглаз эту дискретность. не думаю что это из за нет бука. не знаю я сделал все что мог - без скрипта netrigidbody вообще ерунда получается. может в нем можно еще какие то настройки подправить чтоб плавнее было.

Вот и интересно - как сделать плавнее, всё-таки основополагающий вопрос... Я, к сожалению, новичок в фотоне, потому и интересуюсь, что хотелось бы его изучить...
Аватара пользователя
Friend123
Старожил
 
Сообщения: 701
Зарегистрирован: 26 фев 2012, 22:12
Откуда: Тверь
  • ICQ

Re: Юнити пак PUN (Cloud) и простые скрипты конекта

Сообщение newArray 31 май 2013, 19:10

Пробуй тогда команду еще lerp - точно не знаю синтаксис - на форуме где то есть. в любом случае если не найдешь я тебе через пару дней скажу. Корсар точно знает про lerp.

Мне сказали по это проблеме. Можно все исправить . просто надо в свойство обсервед фотон нетворк виев поставить еше скрипт Networkriggidbody и я тетстил там все плавно получается.

РЕШЕНИЕ ПРОБЛЕМЫ ПО ИНТЕРПОЛЯЦИИ В ВИДЕО. http://www.youtube.com/watch?v=-C6973o7 ... q20JxO0guA
как и сказали в обсервед надо установить скрипт нетворк риджидбоди
Последний раз редактировалось newArray 09 июл 2013, 20:06, всего редактировалось 2 раз(а).
newArray
Адепт
 
Сообщения: 1226
Зарегистрирован: 14 фев 2013, 07:03
Откуда: оттуда

Самые первые шаги при подключении Photon Cloud

Сообщение newArray 08 июн 2013, 22:01

Получение aplication ID Фотона и простейшее соединение.

Описано в видео http://youtu.be/CQ_xen7oKNc
newArray
Адепт
 
Сообщения: 1226
Зарегистрирован: 14 фев 2013, 07:03
Откуда: оттуда

Re: Юнити пак PUN (Cloud) , CONNECT, Туториал

Сообщение newArray 09 июл 2013, 20:43

Мне вот еще пришло в голову. Допустим мы не имеем нужного колличества подключений в тарифном плане, мало ли че может быть в реальной ситуации. В принципе бесплатных апликаций по 20 онлайна мы можем иметь любое колличество в одном аккаунте. Итак как из 20 онлайна можно сделать больше. Нужно просто как везде показать юсеру список серверов. Если один сервер на 20 коннектов будет забит он может играть на втором. (то есть второй это такой же экземпляр игры но на другом id) И для броузерной игры мы можем сделать примерно таким образом - просто указывать на веб странице какой .unity3d билд грузить.
Это будет вот этот кусок кода с веб страницы
u.initPlugin(jQuery("#unityPlayer")[0], "test1.unity3d"); здесь просто будем подставлять или первый билд или второй (они будут лежать на хостинге рядом test1 и test2)
Менять будем вот этими 2 кнопками - их вставим в теги <body> Будем запускать тот или иной билд просто в разных функциях servone() и servtwo()
<input type='button' value='server 1' onclick='servone()' />
<input type='button' value='server 2' onclick='servtwo()' />

В итоге страница webplayer.html может иметь такой вид

Синтаксис:
Используется javascript
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
        <head>
                <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
                <title>Unity Web Player | New Unity Project 4</title>
                <script type='text/javascript' src='https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js'></script>
                <script type="text/javascript">
                <!--
                var unityObjectUrl = "http://webplayer.unity3d.com/download_webplayer-3.x/3.0/uo/UnityObject2.js";
                if (document.location.protocol == 'https:')
                        unityObjectUrl = unityObjectUrl.replace("http://", "https://ssl-");
                document.write('<script type="text\/javascript" src="' + unityObjectUrl + '"><\/script>');
                -->
                </script>
                <script type="text/javascript">
                <!--
                        var config = {
                                width: 960,
                                height: 600,
                                params: { enableDebugging:"0" }
                               
                        };
                        var u = new UnityObject2(config);
         
          function servone() {

                        jQuery(function() {

                                var $missingScreen = jQuery("#unityPlayer").find(".missing");
                                var $brokenScreen = jQuery("#unityPlayer").find(".broken");
                                $missingScreen.hide();
                                $brokenScreen.hide();
                               
                                u.observeProgress(function (progress) {
                                        switch(progress.pluginStatus) {
                                                case "broken":
                                                        $brokenScreen.find("a").click(function (e) {
                                                                e.stopPropagation();
                                                                e.preventDefault();
                                                                u.installPlugin();
                                                                return false;
                                                        });
                                                        $brokenScreen.show();
                                                break;
                                                case "missing":
                                                        $missingScreen.find("a").click(function (e) {
                                                                e.stopPropagation();
                                                                e.preventDefault();
                                                                u.installPlugin();
                                                                return false;
                                                        });
                                                        $missingScreen.show();
                                                break;
                                                case "installed":
                                                        $missingScreen.remove();
                                                break;
                                                case "first":
                                                break;
                                        }
                                });
                         
                              one = "test2.unity3d";
                              u.initPlugin(jQuery("#unityPlayer")[0], one);

                       
                       
                        });
             
               }              

             
//.........................................................


                 function servtwo() {

                        jQuery(function() {

                                var $missingScreen = jQuery("#unityPlayer").find(".missing");
                                var $brokenScreen = jQuery("#unityPlayer").find(".broken");
                                $missingScreen.hide();
                                $brokenScreen.hide();
                               
                                u.observeProgress(function (progress) {
                                        switch(progress.pluginStatus) {
                                                case "broken":
                                                        $brokenScreen.find("a").click(function (e) {
                                                                e.stopPropagation();
                                                                e.preventDefault();
                                                                u.installPlugin();
                                                                return false;
                                                        });
                                                        $brokenScreen.show();
                                                break;
                                                case "missing":
                                                        $missingScreen.find("a").click(function (e) {
                                                                e.stopPropagation();
                                                                e.preventDefault();
                                                                u.installPlugin();
                                                                return false;
                                                        });
                                                        $missingScreen.show();
                                                break;
                                                case "installed":
                                                        $missingScreen.remove();
                                                break;
                                                case "first":
                                                break;
                                        }
                                });
                         
                       
                            one = "test1.unity3d";
                              u.initPlugin(jQuery("#unityPlayer")[0], one);
                       
                                     
                        });
             
               }              



                -->
                </script>
                <style type="text/css">
                <!--
                body {
                        font-family: Helvetica, Verdana, Arial, sans-serif;
                        background-color: white;
                        color: black;
                        text-align: center;
                }
                a:link, a:visited {
                        color: #000;
                }
                a:active, a:hover {
                        color: #666;
                }
                p.header {
                        font-size: small;
                }
                p.header span {
                        font-weight: bold;
                }
                p.footer {
                        font-size: x-small;
                }
                div.content {
                        margin: auto;
                        width: 960px;
                }
                div.broken,
                div.missing {
                        margin: auto;
                        position: relative;
                        top: 50%;
                        width: 193px;
                }
                div.broken a,
                div.missing a {
                        height: 63px;
                        position: relative;
                        top: -31px;
                }
                div.broken img,
                div.missing img {
                        border-width: 0px;
                }
                div.broken {
                        display: none;
                }
                div#unityPlayer {
                        cursor: default;
                        height: 600px;
                        width: 960px;
                }
                -->
                </style>
        </head>
        <body>
      <p class="header"><span>Unity Web Player | </span>New Unity Project 4</p>

       <input type='button' value='server 1' onclick='servone()' />
       
         <input type='button' value='server 2' onclick='servtwo()' />

               
                <div class="content">
                        <div id="unityPlayer">
                                <div class="missing">
                                        <a href="http://unity3d.com/webplayer/" title="Unity Web Player. Install now!">
                                                <img alt="Unity Web Player. Install now!" src="http://webplayer.unity3d.com/installation/getunity.png" width="193" height="63" />
                                        </a>
                                </div>
                                <div class="broken">
                                        <a href="http://unity3d.com/webplayer/" title="Unity Web Player. Install now! Restart your browser after install.">
                                                <img alt="Unity Web Player. Install now! Restart your browser after install." src="http://webplayer.unity3d.com/installation/getunityrestart.png" width="193" height="63" />
                                        </a>
                                </div>
                        </div>
                </div>
                <p class="footer">&laquo; created with <a href="http://unity3d.com/unity/" title="Go to unity3d.com">Unity</a> &raquo;</p>
        </body>
</html>


 


Я сделаю здесь этот пример во фрейме. То есть это просто запуск в браузере 2 разных билдов на выбор






и прикреплю в атачменте архив полностью этого примера

---------------------------------------------
---------------------------------------------
Тоже самое на юнити - пример веб плеер:
https://googledrive.com/host/0B0xTRWfO- ... /test.html

Составляющие этого кода - билды
https://googledrive.com/host/0B0xTRWfO- ... st.unity3d
https://googledrive.com/host/0B0xTRWfO- ... t1.unity3d
https://googledrive.com/host/0B0xTRWfO- ... t2.unity3d

код html страницы
Синтаксис:
Используется javascript
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
        <head>
                <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
                <title>Unity Web Player | New Unity Project 2</title>
                <script type='text/javascript' src='https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js'></script>
                <script type="text/javascript">
                <!--
                var unityObjectUrl = "http://webplayer.unity3d.com/download_webplayer-3.x/3.0/uo/UnityObject2.js";
                if (document.location.protocol == 'https:')
                        unityObjectUrl = unityObjectUrl.replace("http://", "https://ssl-");
                document.write('<script type="text\/javascript" src="' + unityObjectUrl + '"><\/script>');
                -->
                </script>
                <script type="text/javascript">
                <!--
                        var config = {
                                width: 960,
                                height: 600,
                                params: { enableDebugging:"0" }
                               
                        };
                        var u = new UnityObject2(config);


   function servone() {

                        jQuery(function() {

                                var $missingScreen = jQuery("#unityPlayer").find(".missing");
                                var $brokenScreen = jQuery("#unityPlayer").find(".broken");
                                $missingScreen.hide();
                                $brokenScreen.hide();
                               
                                u.observeProgress(function (progress) {
                                        switch(progress.pluginStatus) {
                                                case "broken":
                                                        $brokenScreen.find("a").click(function (e) {
                                                                e.stopPropagation();
                                                                e.preventDefault();
                                                                u.installPlugin();
                                                                return false;
                                                        });
                                                        $brokenScreen.show();
                                                break;
                                                case "missing":
                                                        $missingScreen.find("a").click(function (e) {
                                                                e.stopPropagation();
                                                                e.preventDefault();
                                                                u.installPlugin();
                                                                return false;
                                                        });
                                                        $missingScreen.show();
                                                break;
                                                case "installed":
                                                        $missingScreen.remove();
                                                break;
                                                case "first":
                                                break;
                                        }
                                });
                         
                              one = "test1.unity3d";
                              u.initPlugin(jQuery("#unityPlayer")[0], one);

                       
                       
                        });
             
               }        


 function servtwo() {

                        jQuery(function() {

                                var $missingScreen = jQuery("#unityPlayer").find(".missing");
                                var $brokenScreen = jQuery("#unityPlayer").find(".broken");
                                $missingScreen.hide();
                                $brokenScreen.hide();
                               
                                u.observeProgress(function (progress) {
                                        switch(progress.pluginStatus) {
                                                case "broken":
                                                        $brokenScreen.find("a").click(function (e) {
                                                                e.stopPropagation();
                                                                e.preventDefault();
                                                                u.installPlugin();
                                                                return false;
                                                        });
                                                        $brokenScreen.show();
                                                break;
                                                case "missing":
                                                        $missingScreen.find("a").click(function (e) {
                                                                e.stopPropagation();
                                                                e.preventDefault();
                                                                u.installPlugin();
                                                                return false;
                                                        });
                                                        $missingScreen.show();
                                                break;
                                                case "installed":
                                                        $missingScreen.remove();
                                                break;
                                                case "first":
                                                break;
                                        }
                                });
                         
                              one = "test2.unity3d";
                              u.initPlugin(jQuery("#unityPlayer")[0], one);

                       
                       
                        });
             
               }        








                        jQuery(function() {

                                var $missingScreen = jQuery("#unityPlayer").find(".missing");
                                var $brokenScreen = jQuery("#unityPlayer").find(".broken");
                                $missingScreen.hide();
                                $brokenScreen.hide();
                               
                                u.observeProgress(function (progress) {
                                        switch(progress.pluginStatus) {
                                                case "broken":
                                                        $brokenScreen.find("a").click(function (e) {
                                                                e.stopPropagation();
                                                                e.preventDefault();
                                                                u.installPlugin();
                                                                return false;
                                                        });
                                                        $brokenScreen.show();
                                                break;
                                                case "missing":
                                                        $missingScreen.find("a").click(function (e) {
                                                                e.stopPropagation();
                                                                e.preventDefault();
                                                                u.installPlugin();
                                                                return false;
                                                        });
                                                        $missingScreen.show();
                                                break;
                                                case "installed":
                                                        $missingScreen.remove();
                                                break;
                                                case "first":
                                                break;
                                        }
                                });
                                u.initPlugin(jQuery("#unityPlayer")[0], "test.unity3d");
                        });
                -->
                </script>
                <style type="text/css">
                <!--
                body {
                        font-family: Helvetica, Verdana, Arial, sans-serif;
                        background-color: white;
                        color: black;
                        text-align: center;
                }
                a:link, a:visited {
                        color: #000;
                }
                a:active, a:hover {
                        color: #666;
                }
                p.header {
                        font-size: small;
                }
                p.header span {
                        font-weight: bold;
                }
                p.footer {
                        font-size: x-small;
                }
                div.content {
                        margin: auto;
                        width: 960px;
                }
                div.broken,
                div.missing {
                        margin: auto;
                        position: relative;
                        top: 50%;
                        width: 193px;
                }
                div.broken a,
                div.missing a {
                        height: 63px;
                        position: relative;
                        top: -31px;
                }
                div.broken img,
                div.missing img {
                        border-width: 0px;
                }
                div.broken {
                        display: none;
                }
                div#unityPlayer {
                        cursor: default;
                        height: 600px;
                        width: 960px;
                }
                -->
                </style>
        </head>
        <body>
                <p class="header"><span>Unity Web Player | </span>New Unity Project 2</p>
                <div class="content">
                        <div id="unityPlayer">
                                <div class="missing">
                                        <a href="http://unity3d.com/webplayer/" title="Unity Web Player. Install now!">
                                                <img alt="Unity Web Player. Install now!" src="http://webplayer.unity3d.com/installation/getunity.png" width="193" height="63" />
                                        </a>
                                </div>
                                <div class="broken">
                                        <a href="http://unity3d.com/webplayer/" title="Unity Web Player. Install now! Restart your browser after install.">
                                                <img alt="Unity Web Player. Install now! Restart your browser after install." src="http://webplayer.unity3d.com/installation/getunityrestart.png" width="193" height="63" />
                                        </a>
                                </div>
                        </div>
                </div>
                <p class="footer">&laquo; created with <a href="http://unity3d.com/unity/" title="Go to unity3d.com">Unity</a> &raquo;</p>
        </body>
</html>


 


И исходник в атачменте. Код веб страницы смотрите прямо на html странице демо
Чтобы вернуться в меню - надо выполнить команду перезагрузки страницы.
У вас нет доступа для просмотра вложений в этом сообщении.
Последний раз редактировалось newArray 01 дек 2013, 08:09, всего редактировалось 4 раз(а).
newArray
Адепт
 
Сообщения: 1226
Зарегистрирован: 14 фев 2013, 07:03
Откуда: оттуда

простой голосовой чат в WebPlayer на Photon (voice chat)

Сообщение newArray 04 авг 2013, 20:44

Добавлю еще одну интересную штуку. Это старый голосовой чат с офф форума. Он очень упрощенный - человек писал шутки ради. Качество звука очень плохое. На качество рации может даже сойдет. Но он переведен на фотон со стандартной сети и я добавил кусочек кода для работы его в веб плеере.
Вы можете протестировать его работу прямо на форуме в 2 экземплярах веб плеера на 1 компьютере. Вы увидите что он будет работать.
Демо будет работать только у зарегенных пользователей

HTML код для вашего блога :
Код: Выделить всё
<script language='javascript' type="text/javascript"> document.write("<iframe marginheight='0' src='http://unity3d.ru/distribution/player.php?url=http://unity3d.ru/distribution/download/file.php?id=4791&w=700&h=500&t=true&preview=1' height='"+(500+30)+"' width='700' frameborder='0' scrolling='no'></iframe>"); </script>


Сам скрипт голосового чата на си

Синтаксис:
Используется csharp
// sript of voice chat take from official forum thread
//turn on  of this script see in script "IsChild"

using UnityEngine;
using System.Collections;

public class MicTest : Photon.MonoBehaviour {

    int lastSample;
    public bool on;
        public string vlabel = "Start Voice";
       
        public string asd;
       
       
    AudioClip c;
       
//      int FREQUENCY = 44100;  
       
         IEnumerator Start() {
        yield return Application.RequestUserAuthorization(UserAuthorization.Microphone);
        if (Application.HasUserAuthorization(UserAuthorization.Microphone)) {
               
                }
               
    }
       
       
       
       
         void OnGUI () {
                GUILayout.Label(asd);
               
               if (GUI.Button(new Rect(Screen.width - 150,200,100,30), vlabel)){
                        //vlabel = "Start Voice";
                            if ( on==false ){
                              vlabel = "Stop Voice";
                                    Starts ();
                               on = true;
                             }         
                   
                        else if ( on==true ){
                              vlabel = "Start Voice";
                               
                                      photonView.RPC("of", PhotonTargets.All);
                                     //audio.clip = null;
                               on = false;
                             }         
                       
                           
                             //vlabel = "Start Voice";
                               
                            //on = true;
                       
                       
                }  
        }
       
       

    void Starts () {
               
               
        if (photonView.isMine) {

            c = Microphone.Start(null, true, 100, 8000);

            while(Microphone.GetPosition(null) < 0) {} // HACK from Riro
        }

    }



    void Update () {
               
        if (photonView.isMine && on==true) {

            int pos = Microphone.GetPosition(null);

            int diff = pos-lastSample;

            if (diff > 0) {

                float[] samples = new float[diff * c.channels];

                c.GetData(samples, lastSample);

                byte[] ba = ToByteArray(samples);

                photonView.RPC("Send", PhotonTargets.Others, ba, c.channels);

            }

            lastSample = pos;

        }
               

    }

         [RPC]

    public void of() {
           on = false;
        }
       
    [RPC]

    public void Send(byte[] ba, int chan) {

        float[] f = ToFloatArray(ba);

        audio.clip = AudioClip.Create("test", f.Length, chan, 8000,true,false);

        audio.clip.SetData(f, 0);

        if (!audio.isPlaying) audio.Play();

    }


    public byte[] ToByteArray(float[] floatArray) {

        int len = floatArray.Length * 4;

        byte[] byteArray = new byte[len];

        int pos = 0;

        foreach (float f in floatArray) {

                byte[] data = System.BitConverter.GetBytes(f);

                System.Array.Copy(data, 0, byteArray, pos, 4);

                pos += 4;

        }

        return byteArray;

    }

    public float[] ToFloatArray(byte[] byteArray) {

        int len = byteArray.Length / 4;

        float[] floatArray = new float[len];

        for (int i = 0; i < byteArray.Length; i+=4) {

                floatArray[i/4] = System.BitConverter.ToSingle(byteArray, i);

        }

        return floatArray;

    }


}

 


Без вот этого куска он будет работать в билде http://docs.unity3d.com/Documentation/S ... ation.html
Но в веб плеере без этой авторизации работать не будет - это единственная вставка для работы микрофона в веб плеере.

Также прилагаю исходник в атачменте. Он помечен. Исходник для версии unity 4.1.2. Ищите скрипт голосового чата на игроке, на объекте GameObject удочеренном игроку. И по кнопке Start Voice вы включаете или останавливаете голосовой чат именно для своей модели. при чем чужая модель вас спрашивать не будет она вам скажет даже если вы не хотите ее слышать (вы ее не отключите).

Только не юзайте мой фотоговский id в своем проекте.


Думаю еще будет полезно скрипт который позволит синхронизировать динамические объекты в игре.
То есть мы будем передавать движение от того клиента который его двигает. Для этогона наш объект повесим такой скрипт на языке Си шарп.

Синтаксис:
Используется csharp
using UnityEngine;

[RequireComponent(typeof(Collider))]
public class SomeS : Photon.MonoBehaviour {
       
        void SomeF() {
           
                int id1 = PhotonNetwork.AllocateViewID();
 
        photonView.RPC("One", PhotonTargets.AllBuffered, transform.position,
        transform.rotation, id1);
               
        }
       
       
       [RPC]
        void One (Vector3 pos, Quaternion rot, int id1) {
            PhotonView nView;
             nView = GetComponent<PhotonView>();
             nView.viewID = id1;
        }
       
}

 


Либо на Джава скрипт это будет выглдеть так
Синтаксис:
Используется javascript
class NetworkTranslatePos extends Photon.MonoBehaviour {
//script send move from clients


//receive contact from script "Fighting"
function Some() {                  
      var viewID : PhotonViewID= PhotonNetwork.AllocateViewID();
       photonView.RPC("One", PhotonTargets.AllBuffered, viewID, transform.position);
   
}




@RPC
function One (viewID : PhotonViewID, location : Vector3) {

var nView : PhotonView;
nView = GetComponent(PhotonView);
nView.viewID = viewID;

}


}
 


Мы все время передаем ай ди того клиента который начал им управлять
У вас нет доступа для просмотра вложений в этом сообщении.
newArray
Адепт
 
Сообщения: 1226
Зарегистрирован: 14 фев 2013, 07:03
Откуда: оттуда

Re: PUN(PhotonCloud) unitypackage, Documentatation, Connect etc

Сообщение newArray 07 апр 2014, 19:14

Тут напишу немного по интерполяции для объекта. Актуально для быстродвижущихся.

Насчет нетворк ригидбоди была инфа предположительная. Посмотрим на примере из пака PUNа где предлагаются варианты для интерполяции. Я этот пример дополнил тестом скрипта нетвок риггидбоди и Syncer.cs Вы можете посмотреть работу в прикрепленном билде - что лучше синхронизирует. И также тут прикреплю все скрипты для интерполяции из этого офф примера.

Скрипт интерполяции Synncer.cs найден на офф форуме фотона
Синтаксис:
Используется csharp

using UnityEngine;
using System.Collections;

//Copyright 2013 Tech Drone and William H Hendrickson

/// <summary>
/// Tech Drone PlayMaker Photon Extension:
/// To be used with (optionally) PlayMaker and Photon Unity Netowrking using the Invoke action.
/// This class will synchronize object's positions over the network when enabled.
/// Supports player characters via interpolation and rigidbodies via extrapolation.
/// This class also provides several methods to perform common tasks using Photon.
/// </summary>
///
[RequireComponent (typeof(PhotonView))]
public class Syncer : MonoBehaviour
{
       
                // Synchronize the position of the object automatically using interpolation.
                public bool interPosition = false;
                public enum InterPositionMode
                {
                                InterpolateCharacterMotion,
                                ExtrapolateRigidbodyPhysics}
                ;
                public InterPositionMode syncMode = InterPositionMode.ExtrapolateRigidbodyPhysics;
                public float interpolationBias = 5.0f;
                public Vector3 correctPosition = Vector3.zero;
                public Quaternion correctRotation = Quaternion.identity;
       
                //--Extrapolation data
                public double m_InterpolationBackTime = 0.1;//0.05;
                public double m_ExtrapolationLimit = 0.5;
                internal struct State
                {
                                internal double timestamp;
                                internal Vector3 pos;
                                internal Vector3 velocity;
                                internal Quaternion rot;
                                internal Vector3 angularVelocity;
                }

                // We store twenty states with "playback" information
                State[] m_BufferedState = new State[20];
                // Keep track of what slots are used
                int m_TimestampCount;
       
       
                [HideInInspector]
                public PhotonView
                                photonView;
       
                void Start ()
                {
                                photonView = GetComponent<PhotonView> ();
                }
       
                void Update ()
                {
                                if (interPosition && !photonView.isMine) {
                                                if (syncMode == InterPositionMode.InterpolateCharacterMotion) {
                                                                transform.position = Vector3.Lerp (transform.position, correctPosition, Time.deltaTime * interpolationBias);
                                                                transform.rotation = Quaternion.Lerp (transform.rotation, correctRotation, Time.deltaTime * interpolationBias);
                                                } else
                                                                UpdateRigidbody ();
                                }
                }
       
                void UpdateRigidbody ()
                {
                                // This is the target playback time of the rigid body
                                double interpolationTime = PhotonNetwork.time - m_InterpolationBackTime;

                                // Smoothing
                                // Use interpolation if the target playback time is present in the buffer
                                if (m_BufferedState [0].timestamp > interpolationTime) {
                                                // Go through buffer and find correct state to play back
                                                for (int i=0; i<m_TimestampCount; i++) {
                                                                if (m_BufferedState [i].timestamp <= interpolationTime || i ==
                                                                                m_TimestampCount - 1) {
                                                                                // The state one slot newer (<100ms) than the best playback state
                                                                                State rhs = m_BufferedState [Mathf.Max (i - 1, 0)];
                                                                                // The best playback state (closest to 100 ms old (default time))
                                                                                State lhs = m_BufferedState [i];
                                                                                // Use the time between the two slots to determine if interpolation is necessary
                                                                                double length = rhs.timestamp - lhs.timestamp;
                                                                                float t = 0.0F;
                                                                                // As the time difference gets closer to 100 ms t gets closer to 1 in
                                                                                // which case rhs is only used
                                                                                // Example:
                                                                                // Time is 10.000, so sampleTime is 9.900
                                                                                // lhs.time is 9.910 rhs.time is 9.980 length is 0.070
                                                                                // t is 9.900 - 9.910 / 0.070 = 0.14. So it uses 14% of rhs, 86% of lhs
                                                                                if (length > 0.0001)
                                                                                                t = (float)((interpolationTime - lhs.timestamp) / length);
                                                                                // if t=0 => lhs is used directly
                                                                                transform.localPosition = Vector3.Lerp (lhs.pos, rhs.pos, t);
                                                                                transform.localRotation = Quaternion.Slerp (lhs.rot, rhs.rot, t);
                                                                                return;
                                                                }
                                                }
                                }
                // Use extrapolation (Prediction)
                else {
                                                State latest = m_BufferedState [0];
                                                float extrapolationLength = (float)(interpolationTime - latest.timestamp);
                                                // Don't extrapolation for more than 500 ms, you would need to do that carefully
                                                if (extrapolationLength < m_ExtrapolationLimit) {
                                                                float axisLength = extrapolationLength * latest.angularVelocity.magnitude
                                                                                * Mathf.Rad2Deg;
                                                                Quaternion angularRotation = Quaternion.AngleAxis (axisLength, latest.angularVelocity);
                                                                rigidbody.position = latest.pos + latest.velocity * extrapolationLength;
                                                                rigidbody.rotation = angularRotation * latest.rot;
                                                                rigidbody.velocity = latest.velocity;
                                                                rigidbody.angularVelocity = latest.angularVelocity;
                                                }
                                }      
                }
       
       
                void UpdateTransformMetaData (PhotonStream stream, PhotonMessageInfo info)
                {
                                if (stream.isWriting) {
                                                stream.SendNext (transform.position);
                                                stream.SendNext (transform.rotation);
                                } else {
                                                correctPosition = (Vector3)stream.ReceiveNext ();
                                                correctRotation = (Quaternion)stream.ReceiveNext ();
                                }
                }
       
                void ExtrapolateRigidbodyPosition (PhotonStream stream, PhotonMessageInfo info)
                {
                                // Send data out
                                if (stream.isWriting) {
                                                Vector3 pos = rigidbody.position;
                                                Quaternion rot = rigidbody.rotation;
                                                Vector3 velocity = rigidbody.velocity;
                                                Vector3 angularVelocity = rigidbody.angularVelocity;
                                                stream.Serialize (ref pos);
                                                stream.Serialize (ref velocity);
                                                stream.Serialize (ref rot);
                                                stream.Serialize (ref angularVelocity);
                                }
                //Read data innt
                else {
                                                Vector3 pos = Vector3.zero;
                                                Vector3 velocity = Vector3.zero;
                                                Quaternion rot = Quaternion.identity;
                                                Vector3 angularVelocity = Vector3.zero;
                                                stream.Serialize (ref pos);
                                                stream.Serialize (ref velocity);
                                                stream.Serialize (ref rot);
                                                stream.Serialize (ref angularVelocity);
                                                // Shift the buffer sideways, deleting state 20
                                                for (int i=m_BufferedState.Length-1; i>=1; i--) {
                                                                m_BufferedState [i] = m_BufferedState [i - 1];
                                                }
                                                // Record current state in slot 0
                                                State state;
                                                state.timestamp = info.timestamp;
                                                state.pos = pos;
                                                state.velocity = velocity;
                                                state.rot = rot;
                                                state.angularVelocity = angularVelocity;
                                                m_BufferedState [0] = state;
                                                // Update used slot count, however never exceed the buffer size
                                                // Slots aren't actually freed so this just makes sure the buffer is
                                                // filled up and that uninitalized slots aren't used.
                                                m_TimestampCount = Mathf.Min (m_TimestampCount + 1,
                        m_BufferedState.Length);
                                                // Check if states are in order, if it is inconsistent you could reshuffel or
                                                // drop the out-of-order state. Nothing is done here
                                                for (int i=0; i<m_TimestampCount-1; i++) {
                                                                if (m_BufferedState [i].timestamp < m_BufferedState [i + 1].timestamp)
                                                                                Debug.Log ("State inconsistent");
                                                }
                                }

                }
       
                void OnPhotonSerializeView (PhotonStream stream, PhotonMessageInfo info)
                {
                                //Debug.Log ("View Serialized");
               
                                if (interPosition) {
                                                if (syncMode == InterPositionMode.ExtrapolateRigidbodyPhysics)
                                                                ExtrapolateRigidbodyPosition (stream, info);
                                                else
                                                                UpdateTransformMetaData (stream, info);
                                }
                }
       
                protected bool CheckIsConnected ()
                {
                                return PhotonNetwork.connected;
                }
       
                protected bool CheckIsInRoom ()
                {
                                bool ret = false;
                                if (PhotonNetwork.room != null)
                                                ret = true;
                                return ret;
                }
}

 


Скрипт интерполяции для riggidbody о котором говорилось выше NetworkRiggidbody

Синтаксис:
Используется csharp
using UnityEngine;
using System.Collections;

public class NetworkRigidbody : Photon.MonoBehaviour {
       
        public double m_InterpolationBackTime = 0.1;
        public double m_ExtrapolationLimit = 0.5;
       
        internal struct  State
        {
                internal double timestamp;
                internal Vector3 pos;
                internal Vector3 velocity;
                internal Quaternion rot;
                internal Vector3 angularVelocity;
        }
       
        // We store twenty states with "playback" information
        State[] m_BufferedState = new State[20];
        // Keep track of what slots are used
        int m_TimestampCount;
       
        void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
        {
                // Send data to server
                if (stream.isWriting)
                {
                        Vector3 pos = rigidbody.position;
                        Quaternion rot = rigidbody.rotation;
                        Vector3 velocity = rigidbody.velocity;
                        Vector3 angularVelocity = rigidbody.angularVelocity;

                        stream.Serialize(ref pos);
                        stream.Serialize(ref velocity);
                        stream.Serialize(ref rot);
                        stream.Serialize(ref angularVelocity);
                }
                // Read data from remote client
                else
                {
                        Vector3 pos = Vector3.zero;
                        Vector3 velocity = Vector3.zero;
                        Quaternion rot = Quaternion.identity;
                        Vector3 angularVelocity = Vector3.zero;
                        stream.Serialize(ref pos);
                        stream.Serialize(ref velocity);
                        stream.Serialize(ref rot);
                        stream.Serialize(ref angularVelocity);
                       
                        // Shift the buffer sideways, deleting state 20
                        for (int i=m_BufferedState.Length-1;i>=1;i--)
                        {
                                m_BufferedState[i] = m_BufferedState[i-1];
                        }
                       
                        // Record current state in slot 0
                        State state;
                        state.timestamp = info.timestamp;
                        state.pos = pos;
                        state.velocity = velocity;
                        state.rot = rot;
                        state.angularVelocity = angularVelocity;
                        m_BufferedState[0] = state;
                       
                        // Update used slot count, however never exceed the buffer size
                        // Slots aren't actually freed so this just makes sure the buffer is
                        // filled up and that uninitalized slots aren't used.
                        m_TimestampCount = Mathf.Min(m_TimestampCount + 1, m_BufferedState.Length);

                        // Check if states are in order, if it is inconsistent you could reshuffel or
                        // drop the out-of-order state. Nothing is done here
                        for (int i=0;i<m_TimestampCount-1;i++)
                        {
                                if (m_BufferedState[i].timestamp < m_BufferedState[i+1].timestamp)
                                        Debug.Log("State inconsistent");
                        }      
                }
        }
       
        // We have a window of interpolationBackTime where we basically play
        // By having interpolationBackTime the average ping, you will usually use interpolation.
        // And only if no more data arrives we will use extra polation
        void Update () {
                // This is the target playback time of the rigid body
                double interpolationTime = PhotonNetwork.time - m_InterpolationBackTime;
               
                // Use interpolation if the target playback time is present in the buffer
                if (m_BufferedState[0].timestamp > interpolationTime)
                {
                        // Go through buffer and find correct state to play back
                        for (int i=0;i<m_TimestampCount;i++)
                        {
                                if (m_BufferedState[i].timestamp <= interpolationTime || i == m_TimestampCount-1)
                                {
                                        // The state one slot newer (<100ms) than the best playback state
                                        State rhs = m_BufferedState[Mathf.Max(i-1, 0)];
                                        // The best playback state (closest to 100 ms old (default time))
                                        State lhs = m_BufferedState[i];
                                       
                                        // Use the time between the two slots to determine if interpolation is necessary
                                        double length = rhs.timestamp - lhs.timestamp;
                                        float t = 0.0F;
                                        // As the time difference gets closer to 100 ms t gets closer to 1 in
                                        // which case rhs is only used
                                        // Example:
                                        // Time is 10.000, so sampleTime is 9.900
                                        // lhs.time is 9.910 rhs.time is 9.980 length is 0.070
                                        // t is 9.900 - 9.910 / 0.070 = 0.14. So it uses 14% of rhs, 86% of lhs
                                        if (length > 0.0001)
                                                t = (float)((interpolationTime - lhs.timestamp) / length);
                                       
                                        // if t=0 => lhs is used directly
                                        transform.localPosition = Vector3.Lerp(lhs.pos, rhs.pos, t);
                                        transform.localRotation = Quaternion.Slerp(lhs.rot, rhs.rot, t);
                                        return;
                                }
                        }
                }
                // Use extrapolation
                else
                {
                        State latest = m_BufferedState[0];
                       
                        float extrapolationLength = (float)(interpolationTime - latest.timestamp);
                        // Don't extrapolation for more than 500 ms, you would need to do that carefully
                        if (extrapolationLength < m_ExtrapolationLimit)
                        {
                                float axisLength = extrapolationLength * latest.angularVelocity.magnitude * Mathf.Rad2Deg;
                                Quaternion angularRotation = Quaternion.AngleAxis(axisLength, latest.angularVelocity);
                               
                                rigidbody.position = latest.pos + latest.velocity * extrapolationLength;
                                rigidbody.rotation = angularRotation * latest.rot;
                                rigidbody.velocity = latest.velocity;
                                rigidbody.angularVelocity = latest.angularVelocity;
                        }
                }
        }
}

 


демо из офф примера - это то что прикреплено в билде для теста

HTML код для вашего блога :
Код: Выделить всё
<script language='javascript' type="text/javascript"> document.write("<iframe marginheight='0' src='http://unity3d.ru/distribution/player.php?url=http://unity3d.ru/distribution/download/file.php?id=6200&w=600&h=400&t=true&preview=1' height='"+(400+30)+"' width='600' frameborder='0' scrolling='no'></iframe>"); </script>


И последовательно скрипты для синхронизации представленные в это офф демо
1. синхронизируется только фотон вью

2. интерполяция
Синтаксис:
Используется csharp
using UnityEngine;
using Hashtable = ExitGames.Client.Photon.Hashtable;

[RequireComponent(typeof(PhotonView))]
public class CubeInter : Photon.MonoBehaviour
{
       
        //
        // NOTE: Network interpolation is affected by the network sendRate.
        // By default this is 10 times/second for OnSerialize. (See PhotonNetwork.sendIntervalOnSerialize)
        // Raise the sendrate if you want to lower the interpolationBackTime.
        //
       
    public double interpolationBackTime = 0.15;

    internal struct State
    {
        internal double timestamp;
        internal Vector3 pos;
        internal Quaternion rot;
    }

    // We store twenty states with "playback" information
    State[] m_BufferedState = new State[20];
    // Keep track of what slots are used
    int m_TimestampCount;

    void Awake()
    {
        if (photonView.isMine)
            this.enabled = false;//Only enable inter/extrapol for remote players
    }

    void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
    {
        // Always send transform (depending on reliability of the network view)
        if (stream.isWriting)
        {
            Vector3 pos = transform.localPosition;
            Quaternion rot = transform.localRotation;
            stream.Serialize(ref pos);
            stream.Serialize(ref rot);
        }
        // When receiving, buffer the information
        else
        {
                        // Receive latest state information
            Vector3 pos = Vector3.zero;
            Quaternion rot = Quaternion.identity;
            stream.Serialize(ref pos);
            stream.Serialize(ref rot);

            // Shift buffer contents, oldest data erased, 18 becomes 19, ... , 0 becomes 1
            for (int i = m_BufferedState.Length - 1; i >= 1; i--)
            {
                m_BufferedState[i] = m_BufferedState[i - 1];
            }
                       
                       
            // Save currect received state as 0 in the buffer, safe to overwrite after shifting
            State state;
            state.timestamp = info.timestamp;
            state.pos = pos;
            state.rot = rot;
            m_BufferedState[0] = state;

            // Increment state count but never exceed buffer size
            m_TimestampCount = Mathf.Min(m_TimestampCount + 1, m_BufferedState.Length);

            // Check integrity, lowest numbered state in the buffer is newest and so on
            for (int i = 0; i < m_TimestampCount - 1; i++)
            {
                if (m_BufferedState[i].timestamp < m_BufferedState[i + 1].timestamp)
                    Debug.Log("State inconsistent");
            }
                }
    }

    // This only runs where the component is enabled, which is only on remote peers (server/clients)
    void Update()
    {
        double currentTime = PhotonNetwork.time;
        double interpolationTime = currentTime - interpolationBackTime;
        // We have a window of interpolationBackTime where we basically play
        // By having interpolationBackTime the average ping, you will usually use interpolation.
        // And only if no more data arrives we will use extrapolation

        // Use interpolation
        // Check if latest state exceeds interpolation time, if this is the case then
        // it is too old and extrapolation should be used
        if (m_BufferedState[0].timestamp > interpolationTime)
        {
                         for (int i = 0; i < m_TimestampCount; i++)
            {
                // Find the state which matches the interpolation time (time+0.1) or use last state
                if (m_BufferedState[i].timestamp <= interpolationTime || i == m_TimestampCount - 1)
                {
                    // The state one slot newer (<100ms) than the best playback state
                    State rhs = m_BufferedState[Mathf.Max(i - 1, 0)];
                    // The best playback state (closest to 100 ms old (default time))
                    State lhs = m_BufferedState[i];

                    // Use the time between the two slots to determine if interpolation is necessary
                    double length = rhs.timestamp - lhs.timestamp;
                    float t = 0.0F;
                    // As the time difference gets closer to 100 ms t gets closer to 1 in
                    // which case rhs is only used
                    if (length > 0.0001)
                        t = (float)((interpolationTime - lhs.timestamp) / length);

                    // if t=0 => lhs is used directly
                    transform.localPosition = Vector3.Lerp(lhs.pos, rhs.pos, t);
                    transform.localRotation = Quaternion.Slerp(lhs.rot, rhs.rot, t);
                                        return;
                }
            }
        }
        // Use extrapolation. Here we do something really simple and just repeat the last
        // received state. You can do clever stuff with predicting what should happen.
        else
        {
            State latest = m_BufferedState[0];

            transform.localPosition = Vector3.Lerp(transform.localPosition, latest.pos, Time.deltaTime * 20 );
            transform.localRotation = latest.rot;
        }
    }
}


 


3. экстраполояция

Синтаксис:
Используется csharp
using UnityEngine;
using System.Collections;

[RequireComponent(typeof(PhotonView))]
public class CubeExtra : Photon.MonoBehaviour
{
    Vector3 latestCorrectPos = Vector3.zero;
    Vector3 lastMovement = Vector3.zero;
    float lastTime = 0;

    public void Awake()
    {
        if (photonView.isMine)
        {
            this.enabled = false;   // Only enable inter/extrapol for remote players
        }

        latestCorrectPos = transform.position;
    }

    // this method is called by PUN when this script is being "observed" by a PhotonView (setup in inspector)
    public void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
    {
        // Always send transform (depending on reliability of the network view)
        if (stream.isWriting)
        {
            Vector3 pos = transform.localPosition;
            Quaternion rot = transform.localRotation;
            stream.Serialize(ref pos);
            stream.Serialize(ref rot);
        }
        // When receiving, buffer the information
        else
        {
            // Receive latest state information
            Vector3 pos = Vector3.zero;
            Quaternion rot = Quaternion.identity;
            stream.Serialize(ref pos);
            stream.Serialize(ref rot);

            lastMovement = (pos - latestCorrectPos) / (Time.time - lastTime);

            lastTime = Time.time;
            latestCorrectPos = pos;

            transform.position = latestCorrectPos;
        }
    }

    // This only runs where the component is enabled, which is only on remote peers (server/clients)
    public void Update()
    {
        transform.localPosition += lastMovement * Time.deltaTime;
    }
}


 


4. Lerp

Синтаксис:
Используется csharp
using UnityEngine;
using Hashtable = ExitGames.Client.Photon.Hashtable;

[RequireComponent(typeof(PhotonView))]
public class CubeLerp : Photon.MonoBehaviour
{
    private Vector3 latestCorrectPos;
    private Vector3 onUpdatePos;
    private float fraction;


    public void Awake()
    {
        if (photonView.isMine)
        {
            this.enabled = false;   // due to this, Update() is not called on the owner client.
        }

        latestCorrectPos = transform.position;
        onUpdatePos = transform.position;
    }

    /// <summary>
    /// While script is observed (in a PhotonView), this is called by PUN with a stream to write or read.
    /// </summary>
    /// <remarks>
    /// The property stream.isWriting is true for the owner of a PhotonView. This is the only client that
    /// should write into the stream. Others will receive the content written by the owner and can read it.
    ///
    /// Note: Send only what you actually want to consume/use, too!
    /// Note: If the owner doesn't write something into the stream, PUN won't send anything.
    /// </remarks>
    /// <param name="stream">Read or write stream to pass state of this GameObject (or whatever else).</param>
    /// <param name="info">Some info about the sender of this stream, who is the owner of this PhotonView (and GameObject).</param>
    public void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
    {
        if (stream.isWriting)
        {
            Vector3 pos = transform.localPosition;
            Quaternion rot = transform.localRotation;
            stream.Serialize(ref pos);
            stream.Serialize(ref rot);
        }
        else
        {
            // Receive latest state information
            Vector3 pos = Vector3.zero;
            Quaternion rot = Quaternion.identity;

            stream.Serialize(ref pos);
            stream.Serialize(ref rot);

            latestCorrectPos = pos;                 // save this to move towards it in FixedUpdate()
            onUpdatePos = transform.localPosition;  // we interpolate from here to latestCorrectPos
            fraction = 0;                           // reset the fraction we alreay moved. see Update()

            transform.localRotation = rot;          // this sample doesn't smooth rotation
        }
    }

    public void Update()
    {
        // We get 10 updates per sec. sometimes a few less or one or two more, depending on variation of lag.
        // Due to that we want to reach the correct position in a little over 100ms. This way, we usually avoid a stop.
        // Lerp() gets a fraction value between 0 and 1. This is how far we went from A to B.
        //
        // Our fraction variable would reach 1 in 100ms if we multiply deltaTime by 10.
        // We want it to take a bit longer, so we multiply with 9 instead.

        fraction = fraction + Time.deltaTime * 9;
        transform.localPosition = Vector3.Lerp(onUpdatePos, latestCorrectPos, fraction);    // set our pos between A and B
    }
}


 

И обратите внимание - что если это наш игрок то скрипет Lerp на нем даже не включается.
По моему скрипты нетворк риггидюоди и Syncer.cs скорее мешают чем помогают. Лучше всего работает Lerp Буду пробовать использовать его.


Это вин билд того что в веб демо, для теста http://yadi.sk/d/PbodoqPFPgyEi
У вас нет доступа для просмотра вложений в этом сообщении.
newArray
Адепт
 
Сообщения: 1226
Зарегистрирован: 14 фев 2013, 07:03
Откуда: оттуда


Вернуться в Photon

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 0