sftp 로그 설정

 

1. /etc/ssh/sshd_config 설정

sftp 서브시스템이 설정이 되어있지않다면 해당 부분의 주석을 제거 또는 추가

Subsystem sftp /usr/lib/openssh/sftp-server -f local2 -l INFO

* sftp-server의 위치는 환경에 따라 다를수있다

    /usr/lib/ssh/sftp-server

    /usr/libexec/sftp-server

    /usr/lib/openssh/sftp-server

    /usr/libexec/openssh/sftp-server

sshd_config

 

sftp-server 의 옵션이 궁금하다면 

man sftp-server 로 확인해보자

#man sftp-server
더보기


     -p whitelisted_requests
             Specify a comma-separated list of SFTP protocol requests that are permitted by the server.  All
             request types that are not on the whitelist will be logged and replied to with a failure message.

             Care must be taken when using this feature to ensure that requests made implicitly by SFTP clients
             are permitted.

     -Q protocol_feature
             Query protocol features supported by sftp-server.  At present the only feature that may be queried
             is “requests”, which may be used for black or whitelisting (flags -P and -p respectively).

     -R      Places this instance of sftp-server into a read-only mode.  Attempts to open files for writing, as
             well as other operations that change the state of the filesystem, will be denied.

     -u umask
             Sets an explicit umask(2) to be applied to newly-created files and directories, instead of the
             user's default mask.

     On some systems, sftp-server must be able to access /dev/log for logging to work, and use of sftp-server in
     a chroot configuration therefore requires that syslogd(8) establish a logging socket inside the chroot
     directory.

SEE ALSO
     sftp(1), ssh(1), sshd_config(5), sshd(8)

     T. Ylonen and S. Lehtinen, SSH File Transfer Protocol, draft-ietf-secsh-filexfer-02.txt, October 2001, work
     in progress material.

HISTORY
     sftp-server first appeared in OpenBSD 2.8.

AUTHORS
     Markus Friedl <markus@openbsd.org>

 

2. /etc/syslog.conf 설정

* 환경에따라 /etc/rsyslog.conf 

 

아래 내용 추가

sshd_config 에서 설정한 로그 퍼실리티 local2 와 동일하게 설정

#sftp log
local2.*	/var/log/sftp.log

rsyslog.conf

 

3. /etc/logrotate.d/syslog 설정

* 환경에따라 /etc/logrotate.d/rsyslog 

로그 로테이션에 로그 경로를 추가

/var/log/sftp.log

 

rsyslog

 

4.  ssh ,syslog 데몬 재실행

#systemctl restart sshd
#systemctl restart rsyslog
#service sshd restart
#service rsyslog restart
or
#service syslog restart

서버 환경에따라서 ssh, syslog 를 재시작한다

 

* ssh, syslog 둘중하나만 systemd, ini.d 따로 관리되어 아래와같이 해야 할 수도 있음

#systemctl restart sshd
#service rsyslog restart

 

 

출처

https://zetawiki.com/wiki/%EB%A6%AC%EB%88%85%EC%8A%A4_SFTP_%EC%84%9C%EB%B2%84_%EC%82%AC%EC%9A%A9

https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=haengro&logNo=220959529675

https://www.serverguide.co.kr/106

git bash 실행

git for windows 사용시

 

ssh 키 생성

 

ssh-keygen -t rsa -C “email@example.com”

 

저장 경로설정

저장경로를 입력하지 않으면 기본 경로에 저장

 

비밀번호 설정

비밀번호를 입력하지않으면 키 사용시 비밀번호없이 사용가능

 

키 생성 완료

id_rsa - private key 외부 노출 금지

id_rsa_pub - public key

 

키등록

ssh-agent 실행

 

eval `ssh-agent -s`

키 추가

ssh-add ~/.ssh/id_rsa (키 저장 경로)

 

저장소 ssh 설정

 

사용하는 저장소의  ssh 설정에 위에서 만든 public key 값을 추가

github
gitlab

 

Git Clone

 

저장소의 ssh 주소를 이용하여 clone

 

git clone git@github.com:user/project.git

 

yes 입력, 키생성시 비밀번호를 설정했다면 비밀번호 입력

만약 저장소의 ssh 포트가 22번이 아닐경우

ssh:// , 포트 번호를 추가

git clone ssh://git@github.com:[port]/user/project

 

github

 

gitlab

 

 

 

소스 트리 ssh 설정

 

도구 -> 옵션 -> SSH 클라이언트 OpenSSH 선택

 

 

 

참고

git-scm.com/book/ko/v2/Git-%EC%84%9C%EB%B2%84-SSH-%EA%B3%B5%EA%B0%9C%ED%82%A4-%EB%A7%8C%EB%93%A4%EA%B8%B0

 

Git - SSH 공개키 만들기

많은 Git 서버들은 SSH 공개키로 인증한다. 공개키를 사용하려면 일단 공개키를 만들어야 한다. 공개키를 만드는 방법은 모든 운영체제가 비슷하다. 먼저 키가 있는지부터 확인하자. 사용자의 SSH

git-scm.com

m.blog.naver.com/semidex37/220951282334

 

[GitLab] SSH Key 등록 후, Source Clone 받기

* 계정이 없으신 경우에는 등록 후 사용하시기바랍니다.* 프로젝트 권한을 계정 생성 후 말씀해주시면 권한...

blog.naver.com

 

2022.02.09 추가

Unity 2020.1 이후 UnityLoader.js 에서 mobile warning 관련 코드가 사라지고

index.html 부분에서 처리하고 있어 해당부분을 삭제하는것으로 간단하게 해결된다.

 

 

2020.1 미만 버전에서만 대응 된 코드

아래 파일을

Assets/Editor/RemoveMobileSupportWarningWebBuild.cs  위치시킨다 

아래 출처 참고

RemoveMobileSupportWarningWebBuild.cs
0.00MB

출처

https://gist.github.com/JohannesDeml/f551b1e60c59e8472c3e843014d7bd10

// --------------------------------------------------------------------------------------------------------------------
// <copyright file="RemoveMobileSupportWarningWebBuild.cs">
//   Copyright (c) 2021 Johannes Deml. All rights reserved.
// </copyright>
// <author>
//   Johannes Deml
//   public@deml.io
// </author>
// --------------------------------------------------------------------------------------------------------------------

#if !UNITY_2020_1_OR_NEWER //Not needed anymore in 2020 and above
using System.IO;
using UnityEditor;
using UnityEditor.Callbacks;
using UnityEngine;

namespace Supyrb
{
	/// <summary>
	/// removes a warning popup for mobile builds, that this platform might not be supported:
	/// "Please note that Unity WebGL is not currently supported on mobiles. Press OK if you wish to continue anyway."
	/// </summary>
	public class RemoveMobileSupportWarningWebBuild
	{
		[PostProcessBuild]
		public static void OnPostProcessBuild(BuildTarget target, string targetPath)
		{
			if (target != BuildTarget.WebGL)
			{
				return;
			}

			var buildFolderPath = Path.Combine(targetPath, "Build");
			var info = new DirectoryInfo(buildFolderPath);
			var files = info.GetFiles("*.js");
			for (int i = 0; i < files.Length; i++)
			{
				var file = files[i];
				var filePath = file.FullName;
				var text = File.ReadAllText(filePath);
				text = text.Replace("UnityLoader.SystemInfo.mobile", "false");

				Debug.Log("Removing mobile warning from " + filePath);
				File.WriteAllText(filePath, text);
			}
		}
	}
}
#endif

 

 

 

 

-- 기존 내용 --

유니티 webGL 빌드 후 모바일 디바이스로 접속시 아래와 같은 경고창을 볼 수 있다

Please note that Unity WebGL is not currently supported on mobiles.

 

Build/UnityLoader.js 를 안쪽에 모바일 디바이스 체크 부분을 수정해 주면 제거가 가능하다

빌드 때 마다 수동으로 수정을 하기는 힘드니 PostProcessBuild 콜백을 사용하여 빌드 후 해당 부분을 수정하도록 할 수있다.

 

아래 스크립트를 Assets > Editor 폴더에 넣어주면 간단하게 사용 가능하다

using System.IO;
using UnityEditor;
using UnityEditor.Callbacks;

public class PostBuildAction
{
    [PostProcessBuild]
    public static void OnPostProcessBuild(BuildTarget target, string targetPath)
    {
        var path = Path.Combine(targetPath, "Build/UnityLoader.js");
        var text = File.ReadAllText(path);
        text = text.Replace("UnityLoader.SystemInfo.mobile", "false");
        File.WriteAllText(path, text);
    }
}

참조 :

docs.unity3d.com/kr/2018.4/Manual/webgl-browsercompatibility.html

answers.unity.com/questions/1339261/unity-webgl-disable-mobile-warning.html

// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'

Shader "Custom/FlatTransparent" {
	Properties{
		_Color("Main Color", Color) = (1,1,1,1)
		_MainTex("Base (RGB) Trans (A)", 2D) = "white" {}
	}

		SubShader{
			Tags{ "Queue" = "Transparent" "IgnoreProjector" = "False" "RenderType" = "Transparent" }

			/////////////////////////////////////////////////////////
			/// First Pass
			/////////////////////////////////////////////////////////

			Pass {
		// Only render alpha channel
		ColorMask A
		Blend SrcAlpha OneMinusSrcAlpha

		CGPROGRAM
		#pragma vertex vert
		#pragma fragment frag

		fixed4 _Color;

		float4 vert(float4 vertex : POSITION) : SV_POSITION {
			return UnityObjectToClipPos(vertex);
		}

		fixed4 frag() : SV_Target {
			return _Color;
		}

		ENDCG
	}

		/////////////////////////////////////////////////////////
		/// Second Pass
		/////////////////////////////////////////////////////////

		Pass {
			// Now render color channel
			ColorMask RGB
			Blend SrcAlpha OneMinusSrcAlpha

			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag

			sampler2D _MainTex;
			fixed4 _Color;

			struct appdata {
				float4 vertex : POSITION;
				float2 uv : TEXCOORD0;
			};

			struct v2f {
				float2 uv : TEXCOORD0;
				float4 vertex : SV_POSITION;
			};

			v2f vert(appdata v) {
				v2f o;
				o.vertex = UnityObjectToClipPos(v.vertex);
				o.uv = v.uv;
				return o;
			}

			fixed4 frag(v2f i) : SV_Target{
				fixed4 col = _Color * tex2D(_MainTex, i.uv);
				return col;
			}
			ENDCG
		}
	}

		Fallback "Diffuse"
}

 

출처: answers.unity.com/questions/290333/transparent-solid-color-shader.html

안드로이드 스튜디오 34.1 기준으로 작성 

BommonVaigationView 생성

프로젝트 생성시

프로젝트 생성시 Bottom Navigation Activity 를 선택

Activity 추가시

New > Activity > Bottom Navigation Activity 선택

 

...더보기

기존 액티비티에 추가 할 때

containers > BottomNavigationView 를 끌어다넣는다 그러면 라이브러리가 필요하다고 나오는데 OK를 눌러주자 
Menu item을 슥슥 추가하고 id , icon을 적절하게 넣어준다
추가한 메뉴를 추가해준

 

MissingConstraints 에러가 나고있던것은 레이아웃에서 적절히 잡아주고 background 를 넣어주면 메뉴가 나타난다 
public class MainActivity extends AppCompatActivity {

    private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener = new BottomNavigationView.OnNavigationItemSelectedListener() {
        @Override
        public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
            switch (menuItem.getItemId()) {
                case R.id.item1:
                    return true;
                case R.id.item2:
                    return true;
                case R.id.item3:
                    return true;
            }
            return false;
        }
    };


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        BottomNavigationView navView = findViewById(R.id.nav_view);
        navView.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
    }
}

activity에서 이벤트 리스너를 추가해준다.

 

Fragment 생성 

New > Fragment > Fragment (Blank) 로 Fragment 를 생성 
간단한 fragment 를 만듬으로 include fragment factory method와 include interface callback 체크를 풀어준다 

 

각 fragment 레이아웃을 알아볼수있게 적당히 배경색을 바꾼다 

 

BottomNavigation 이벤트를 통해 Fragment 변경

처음만든 레이아웃에 프래그먼트출력을위해 컨테이너를 만들자 예시를 위해 fragment_container를 대충 넣었지만 저런짓은 하지말자 

public class MainActivity extends AppCompatActivity {
    Fragment menu1Fragment;
    Fragment menu2Fragment;
    Fragment menu3Fragment;

    private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
            = new BottomNavigationView.OnNavigationItemSelectedListener() {

        @Override
        public boolean onNavigationItemSelected(@NonNull MenuItem item) {
            switch (item.getItemId()) {
                case R.id.navigation_home:
                    getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,menu1Fragment).commit();
                    return true;
                case R.id.navigation_dashboard:
                    getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,menu2Fragment).commit();
                    return true;
                case R.id.navigation_notifications:
                    getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,menu3Fragment).commit();
                    return true;
            }
            return false;
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        BottomNavigationView navView = findViewById(R.id.nav_view);
        navView.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);

        menu1Fragment = new Menu1Fragment();
        menu2Fragment = new Menu2Fragment();
        menu3Fragment = new Menu3Fragment();

        getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,menu1Fragment).commit();
    }

}

fragment 생성 후 BottonNavigationView 이벤트에  FragmentManager로 출력될 fragment를 넣어주면 원하는 fragment가 출력된다.

 

 

추가 내용

Fragment layout.xml click 이벤트 이슈

아래와 같이 Fragment layout xml 파일에서 클릭이벤트를 지정하고 해당 메소드를 Fragment Class 파일에 작성하면

 

java.lang.IllegalStateException: Could not find method onClickButton(View) in a parent or ancestor Context for android:onClick attribute defined on view class androidx.appcompat.widget.AppCompatButton with id 'button'

메소드를 찾지 못하는 것을 볼수있다.

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/colorAccent"
    tools:context=".Menu1Fragment">

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="onClickButton"
        android:text="Button" />

</FrameLayout>

 

Fragment를 생성하는 Activity 쪽에 매소드를 만들면 정상작동이 되지만 좋은방법이 아니므로 

Fragment 클래스에서 View 를 바로 리턴하지말고 View에서 버튼을 찾아 이벤트를 잡아주자.

public class Menu1Fragment extends Fragment {
    
    private View view ;
    private Button button;

    public Menu1Fragment() {
        // Required empty public constructor
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        //return inflater.inflate(R.layout.fragment_menu1, container, false);
        view= inflater.inflate(R.layout.fragment_menu1,container,false);
        button= view.findViewById(R.id.button);
        button.setOnClickListener(new Button.OnClickListener(){
            @Override
            public void onClick(View view) {

            }
        });
        return view;
    }
    
}

참고 : https://ljs93kr.tistory.com/4

        https://wimir-dev.tistory.com/13

 

 

 

 

 

xml을 파싱을 하다보면 노드 사이에 공백을 텍스트 노드로 인식하여  #text 노드가 생성이되는데 

아래와 같이 처리를 해주자.

if (node.getNodeType() == Node.ELEMENT_NODE) {
   	//
}

if(node.getNodeType() == Node.TEXT_NODE){
	//
}

 

출처:https://stackoverflow.com/questions/4650878/how-to-remove-text-from-my-node-parsing-in-java-dom-xml-parsing

'부스러기 > Java' 카테고리의 다른 글

Static 키워드  (0) 2017.06.12
이클립스 Dex Loader] Unable to execute dex: GC overhead limit exceeded  (0) 2014.12.06
JAVA mysql 사용  (0) 2013.07.12

PhotonView Class Reference

Public Member Functions

void RequestOwnership ()
 Depending on the PhotonView's ownershipTransfer setting, any client can request to become owner of the PhotonViewMore...
 
void TransferOwnership (PhotonPlayer newOwner)
 Transfers the ownership of this PhotonView (and GameObject) to another player. More...
 
void TransferOwnership (int newOwnerId)
 Transfers the ownership of this PhotonView (and GameObject) to another player. More...
 
void OnMasterClientSwitched (PhotonPlayer newMasterClient)
 Check ownerId assignment for sceneObjects to keep being owned by the MasterClient. More...
 
void SerializeView (PhotonStream stream, PhotonMessageInfo info)
 
void DeserializeView (PhotonStream stream, PhotonMessageInfo info)
 
void RefreshRpcMonoBehaviourCache ()
 Can be used to refesh the list of MonoBehaviours on this GameObject while PhotonNetwork.UseRpcMonoBehaviourCache is true. More...
 
void RPC (string methodName, PhotonTargets target, params object[] parameters)
 Call a RPC method of this GameObject on remote clients of this room (or on all, inclunding this client). More...
 
void RpcSecure (string methodName, PhotonTargets target, bool encrypt, params object[] parameters)
 Call a RPC method of this GameObject on remote clients of this room (or on all, inclunding this client). More...
 
void RPC (string methodName, PhotonPlayer targetPlayer, params object[] parameters)
 Call a RPC method of this GameObject on remote clients of this room (or on all, inclunding this client). More...
 
void RpcSecure (string methodName, PhotonPlayer targetPlayer, bool encrypt, params object[] parameters)
 Call a RPC method of this GameObject on remote clients of this room (or on all, inclunding this client). More...
 
override string ToString ()


PhotonView 클래스는 네트워크상에 전송되는 오브젝트를 위한것으로 보인다 유니티네트워크의 NetworkIdentity 컴포넌트와 비슷한 역할을 하는듯하다


홈페이지에서는 아래와같이 설명되었있다


네트워크 객체

일반 GameObject들은 PhotonView 컴포넌트가 있는 네트워크 객체로 전환될 수 있습니다. PhotonView는 네트워크를 통해 객체를 식별하고 해당 객체의 상태를 동기화하는 데 사용됩니다. 일반적으로, PhotonView는 런타임에 인스턴스화된 프리팹에 연결됩니다. 종종 모든 선수들은 통제할 자신만의 객체들을 가지고 있습니다.

GameObject에 PhotonView를 추가하기위해서는, 단순히 GameObject를 선택하고 사용하면 됩니다:"Components/Miscellaneous/Photon View"

Transform 동기화


튜도리얼에 따르면 트랜스폼 동기화를 위한 컴포넌트가 PhotonTransformView  라고 되었는데 PUN2 에서는  튜토리얼버전은 클래식으로 되어있다. 클래식에 비해 옵션이 없기때문에 사용이 좀더 편해보인다



Animation 동기화


PhotonAnimatiorView 스크립트를 추가하면 해당 오브젝트의 animator 에서 레이어와 파라미터를 친절하게 가져와준다


Discreate : 초당 10회의 데이터를 전송

Continuous : 매 프레임마다 데이터를 전송






위에 두 컴포넌트를 추가한 뒤 PhotonView 컴포넌트에 observed components에 추가해주자





기타 컴포넌트 동기화


동기화가 필요한 컴포넌트일 경우 IPunObservable 인터페이스를 상속받아 OnPhotonSerializeView를 정의 후 

위 컴포넌트들 처럼 PhotoView 컴포넌트에 추가해준다


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class PlayerManager : MonoBehaviourPunCallbacks , IPunObservable
{
 
     public void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)        
    {
            if (stream.IsWriting)
            {             
                stream.SendNext(IsFiring);
            }
            else
            {          
                this.IsFiring = (bool)stream.ReceiveNext();
            }
    }
}
cs


https://doc.photonengine.com/ko-kr/pun/v2/demos-and-tutorials/pun-basics-tutorial/player-prefab


캐릭터 프리펩을 만들기 위한 애니메이션, 입력 관련이 주된내용으로 관련 내용은 따로 포스팅을 해보자


이번 장에서 사용한 포톤 관련 클래스는 PhotonView 클래스로 해당 오브젝트가 클라이언트의 소유인지 확인 할 수 있다


bool PhotonView.isMine
get

True if the PhotonView is "mine" and can be controlled by this client.

PUN has an ownership concept that defines who can control and destroy each PhotonView. True in case the owner matches the local PhotonPlayer. True if this is a scene photonview on the Master client.

https://doc-api.photonengine.com/en/pun/current/class_photon_view.html


아래와 같이 빔에 맞았을 때 본인의 캐릭터일때만 hp를 깍게 되어있다


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
void OnTriggerEnter(Collider other)
        {
            if (!photonView.IsMine)
            {
                return;
            }
 
            if (!other.name.Contains("Beam"))
            {
                return;
            }
            Health -= 0.1f;
        }
 
        void OnTriggerStay(Collider other)
        {
 
            if (!photonView.IsMine)
            {
                return;
            }
 
            if (!other.name.Contains("Beam"))
            {
                return;
            }
   
            Health -= 0.1f * Time.deltaTime;
        }
cs








1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
using System;
using System.Collections;
using UnityEngine;
using UnityEngine.SceneManagement;
using Photon.Pun;
using Photon.Realtime;
 
 
namespace Com.MyCompany.MyGame
{
    public class GameManager : MonoBehaviourPunCallbacks
    {
 
        public override void OnLeftRoom()
        {
            SceneManager.LoadScene(0);
        }
 
        public void LeaveRoom()
        {
            PhotonNetwork.LeaveRoom();
        }
 
        private void LoadArena()
        {
            if(!PhotonNetwork.IsMasterClient)
            {
                Debug.LogError("PhotonNetwork : Trying to Load a level but we are not the master Client");
            }
 
            Debug.LogFormat("PhotonNetwork : Loading Level : {0}", PhotonNetwork.CurrentRoom.PlayerCount);
            PhotonNetwork.LoadLevel("Room for " + PhotonNetwork.CurrentRoom.PlayerCount);
        }
 
 
        public override void OnPlayerEnteredRoom(Player other)
        {
            Debug.LogFormat("OnPlayerEnteredRoom() {0}", other.NickName); 
 
 
            if (PhotonNetwork.IsMasterClient)
            {
                Debug.LogFormat("OnPlayerEnteredRoom IsMasterClient {0}", PhotonNetwork.IsMasterClient);
 
                LoadArena();
            }
        }
 
        public override void OnPlayerLeftRoom(Player other)
        {
            Debug.LogFormat("OnPlayerLeftRoom() {0}", other.NickName); 
 
            if (PhotonNetwork.IsMasterClient)
            {
                Debug.LogFormat("OnPlayerLeftRoom IsMasterClient {0}", PhotonNetwork.IsMasterClient); 
 
                LoadArena();
            }
        }
    }
}
cs

GameManager 스크립트에  OnPlayerEnteredRoom 메소드로 현재 플레이 인원에 따라 만들어둔 씬을 로드하게 하자
** PhotonNetwork.LoadLevel() 는 MasterClient 만이 호출가능하다

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Photon.Pun;
using Photon.Realtime;
 
namespace Com.MyCompany.MyGame
{  
    public class Launcher : MonoBehaviourPunCallbacks
    {
 
        [SerializeField]
        private GameObject controlPanel;
        [Tooltip("The UI Label to Inform the user that the connection is in progress")]
        [SerializeField]
        private GameObject progressLabel;
 
        string gameVersion = "1";
 
        bool isConnecting=false;
 
        private void Awake()
        {
            PhotonNetwork.AutomaticallySyncScene = true;
        }
 
        void Start()
        {
            progressLabel.SetActive(false);
            controlPanel.SetActive(true);
 
        }
   
        void Update()
        {
        
        }
        public void Connect()
        {
            isConnecting = true;
            if (PhotonNetwork.IsConnected)
            {
                PhotonNetwork.JoinRandomRoom();
            }
            else
            {
                PhotonNetwork.GameVersion = gameVersion;
                PhotonNetwork.ConnectUsingSettings();
            }
 
            progressLabel.SetActive(true);
            controlPanel.SetActive(false);
 
        }
 
        public override void OnConnectedToMaster()
        {
            Debug.Log("PUN Basics Tutorial/Launvher: OnConnectedToMaster() was called by PUN");
            if (isConnecting)
            {
                PhotonNetwork.JoinRandomRoom();
            }
        }
        public override void OnJoinRandomFailed(short returnCode, string message)
        {
            Debug.Log("PUN Basics Tutorial/Launcher:OnJoinRandomFailed() was called by PUN. No random room available, so we create one.\nCalling: PhotonNetwork.CreateRoom");
            PhotonNetwork.CreateRoom(nullnew RoomOptions());
        }
 
        public override void OnDisconnected(DisconnectCause cause)
        {
            Debug.LogWarningFormat("PUN Basics Tutorial/Launcher: OnDisconnected() was called by PUN with reason {0}", cause);
        }
 
        public override void OnJoinedRoom()
        {
            Debug.Log("OnJoinedRoom Event");
            if (PhotonNetwork.CurrentRoom.PlayerCount == 1)
            {
                Debug.Log("We load the 'Room for 1' ");
 
                PhotonNetwork.LoadLevel("Room for 1");
            }
        }
    }
}
cs


Launcher 스크립트에 PhotonNetwork.JoinRandomRoom() 으로 랜던룸에 입장을 시도 할때 방이없으면 접속에 실패하게되는데 해당 코드를 작성하지 않았다


OnJoinRandomFailed 콜백 메소드를 통하여 방이없을 때 방을 만들어보자


이 후 서버에 연결을 해보면 어제 만든 씬으로 이동하는 것을 볼 수 있다


대강 접속로직 알것같다




https://doc.photonengine.com/ko-kr/pun/v2/demos-and-tutorials/pun-basics-tutorial/game-scenes

페이지 번역이 되어있지 않지만 전 튜토리얼과 크게다르지 않다


패널에 버튼을 만들고 방나가는 이벤트를 등록하고 바닥과 벽오브젝트를 생성


씬을 같은 구조의 씬을 4개만들고 바닥과 벽스케일과 위치만 변경한다


이후 빌드 설정에서 지금까지 만든 씬들을 등록한다


이번에 만든 GameManager 스크립트는 방에서 나가는 메소드와 방을 나갔을 때 첫 로비씬으로 바꾸는 이벤트메소드말고는 없다


퇴근 후 귀가가 늦었으므로 오늘은 여기까지


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
using System;
using System.Collections;
using UnityEngine;
using UnityEngine.SceneManagement;
using Photon.Pun;
using Photon.Realtime;
 
 
namespace Com.MyCompany.MyGame
{
    public class GameManager : MonoBehaviourPunCallbacks
    {
 
        public override void OnLeftRoom()
        {
            SceneManager.LoadScene(0);
        }
 
        public void LeaveRoom()
        {
            PhotonNetwork.LeaveRoom();
        }
 
    }
}
cs



+ Recent posts