일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 재귀
- Basic
- 문제풀이
- Material
- 기초
- guide
- parameter
- 프로그래밍
- 시작해요 언리얼 2022
- c++
- Class
- Unreal Engine 5
- python
- Unity
- 오류
- github
- dynamic
- W3Schools
- Programming
- 파이썬
- Tutorial
- loop
- UE5
- 백준
- String
- w3school
- dfs
- DP
- Algorithm
- C#
- Today
- Total
행복한 개구리
Unity 팀프 21.05.28 PUN2 - 조작, 개별스폰 본문
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using Photon.Pun;
public class CameraController : MonoBehaviourPun, IPointerDownHandler, IPointerUpHandler, IDragHandler
{
public Transform camFollow;
public Transform camera;
public GameObject target;
[SerializeField]
float speedHorizontal = 100;
[SerializeField]
float speedVertical = 40;
[SerializeField]
Vector3 offset;
[SerializeField]
float angleUp;
[SerializeField]
float angleDown;
Vector2 lastPosition;
void Start()
{
speedHorizontal = 100f;
speedVertical = 40f;
offset = new Vector3(0, 1, -5);
angleUp = 20f;
angleDown = -10f;
}
public void Init(string idx, Vector3 spawnPos)
{
target = GameObject.Find("TestPlayer(Clone)" + idx);
camFollow.position = target.transform.position + offset;
}
void Update()
{
camFollow.position = target.transform.position + offset;
var angle = camera.transform.eulerAngles;
if(angleUp < angle.x && angle.x < 180)
{
camera.transform.eulerAngles = new Vector3(angleUp, angle.y, angle.z);
}
else if(angle.x < angleDown + 360 && angle.x > 180)
{
camera.transform.eulerAngles = new Vector3(angleDown, angle.y, angle.z);
}
}
public void OnDrag(PointerEventData eventData)
{
var targetDir = (eventData.position - lastPosition).normalized;
if (targetDir.x != 0)
{
camera.RotateAround(target.transform.position, Vector3.up, targetDir.x * speedHorizontal * Time.deltaTime);
}
if (targetDir.y != 0)
{
camera.Rotate(-targetDir.y * Time.deltaTime * speedVertical, 0, 0);
}
lastPosition = eventData.position;
}
public void OnPointerDown(PointerEventData eventData)
{
lastPosition = eventData.position;
}
public void OnPointerUp(PointerEventData eventData)
{
lastPosition = Vector2.zero;
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using Photon.Pun;
using Photon.Realtime;
using Hashtable = ExitGames.Client.Photon.Hashtable;
public class InGame : MonoBehaviourPunCallbacks, IPunObservable
{
public List<Transform> spawnPoints;
public CameraController camController;
public Button btn;
//[HideInInspector]
//public Player playerCharacter;
bool isLocal;
bool s1 = true;
GameObject character;
Vector3 pos;
[HideInInspector]
public int idx;
Hashtable hash;
Dictionary<string, object> playerInfo;
public void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
{
stream.SendNext(this.character.transform.position);
pos = (Vector3)stream.ReceiveNext();
}
private void Awake()
{
PhotonNetwork.SendRate = 60;
PhotonNetwork.SerializationRate = 60;
}
void Start()
{
idx = 0;
//hash = new Hashtable();
Init();
}
void Update()
{
if (Input.GetKey(KeyCode.W))
{
this.character.transform.Translate(0, 0, 0.1f);
}
if (Input.GetKey(KeyCode.S))
{
this.character.transform.Translate(0, 0, -0.1f);
}
if (Input.GetKey(KeyCode.A))
{
this.character.transform.Translate(-0.1f, 0, 0);
}
if (Input.GetKey(KeyCode.D))
{
this.character.transform.Translate(0.1f, 0, 0);
}
}
void Init()
{
SpawnCharacter();
SpawnTreasure();
}
void SpawnTreasure()
{
if (PhotonNetwork.LocalPlayer.IsMasterClient)
PhotonNetwork.Instantiate("Treasure", Vector3.zero, Quaternion.identity);
}
void SpawnCharacter()
{
foreach (var player in PhotonNetwork.PlayerList)
{
if (player.IsLocal)
{
var spawnPosition = spawnPoints[idx].position;
this.character = PhotonNetwork.Instantiate("TestPlayer", spawnPosition, Quaternion.identity);
this.character.name = this.character.name + idx.ToString();
player.TagObject = this.character as GameObject;
this.character.GetComponent<PlayerController>().isLocal = true;
this.character.GetComponent<PlayerController>().Init();
camController.Init(idx.ToString(), spawnPosition);
}
idx++;
}
}
public override void OnPlayerPropertiesUpdate(Player targetPlayer, Hashtable changedProps)
{
Debug.Log(PhotonNetwork.LocalPlayer.CustomProperties["IsRobber"]);
Debug.Log(targetPlayer.CustomProperties["IsRobber"]);
Debug.LogFormat("{0}, {1}", targetPlayer.NickName, changedProps["IsRobber"]);
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Photon.Pun;
using Photon.Realtime;
public class PlayerController : MonoBehaviourPun
{
public Transform camera;
public Rigidbody rigid;
[HideInInspector]
public bool isLocal;
[SerializeField]
float speed;
VariableJoystick joystick;
private void Start()
{
}
public void Init()
{
if (!isLocal) return;
speed = 3f;
this.gameObject.GetComponent<CapsuleCollider>();
var cameraGo = GameObject.Find("Main Camera");
camera = cameraGo.GetComponent<Transform>();
var joystickGo = GameObject.Find("Variable Joystick");
joystick = joystickGo.GetComponent<VariableJoystick>();
}
private void FixedUpdate()
{
if (!isLocal) return;
Vector3 joystickDir = Vector3.forward * joystick.Vertical + Vector3.right * joystick.Horizontal;
if (joystickDir == Vector3.zero) return;
Vector3 playerAngle = Quaternion.LookRotation(joystickDir).eulerAngles;
Vector3 camPivotAngle = camera.eulerAngles;
Vector3 towardAngle = Vector3.up * (playerAngle.y + camPivotAngle.y);
rigid.rotation = Quaternion.Euler(towardAngle);
rigid.transform.Translate(Vector3.forward * Time.deltaTime * speed);
}
private void OnTriggerEnter(Collider other)
{
if (other.tag == "Treasure")
{
Debug.Log("Triggered");
Debug.Log(this.gameObject.name);
var treasure = other.GetComponent<PhotonView>();
PhotonNetwork.Destroy(treasure.gameObject);
PhotonNetwork.LocalPlayer.CustomProperties.Add("IsRobber", PhotonNetwork.LocalPlayer.ActorNumber);
PhotonNetwork.LocalPlayer.SetCustomProperties(PhotonNetwork.LocalPlayer.CustomProperties);
Debug.Log(PhotonNetwork.NickName);
}
}
}
- 캐릭터의 진행방향은 카메라의 앵글 + 캐릭터가 달려가는 방향으로 하여금 카메라가 어느시점을 보던 조이스틱의 방향과 연동되게 하였으며
- 카메라의 좌우회전은 RotateAround메서드를 이용하고 상하회전은 Rotate을 이용하여 축회전을 지양했다.
- 그리고 캐릭터가 바라보는 방향으로 가게하기위해서 Translate(Vector3.forward)를 사용했다.
- 카메라가 RotateAround를 하면 좌표에 변동이 있으므로 캐릭터의 Pivot역할을 하며 따라가기에는 무리가 있으므로 FollowCam 오브젝트를 만들어 그 하위에 Camera를 위치시켰다.
- Pivot역할은 FollowCam이, RotateAround의 좌표이동은 Camera가 함으로써 서로의 좌표가 독립적으로 작용한다.
++ 다른것을 테스트하느라 필요없는 내용이 꽤나 있다.
* 스폰위치가 한 곳에서 되는 이슈 => 해결 12:30
ㄴPlayerList의 인덱스에 따른 스폰위치 할당코드가 지워진 상태였음.
ㄴ수정하자마자 정상작동.
* 방장말고 다른 플레이가 Start를 하는 문제 => 해결 14:30
ㄴStart버튼은 MasterClient만 작동할 수 있도록 조건문으로 코딩
* 안드로이드 빌드시 JDK/SDK/NDK 경로 이슈 => 완료 10:20
ㄴNVIDIA에서 CodeWork for Android를 다운받아 압축을 풀고 경로를 지정해 줌.
* 서버를 통해서 다른 클라이언트의 캐릭터 값을 바꾸기
ㄴ유물을 먹은 플레이어의 태그를 바꾸려고 하는데 현재의 코드로는 로컬에서만 바뀜
ㄴCustomProperties라는 기능을 사용하면 해당 Hashtable에 저장된 값이 바뀔때마다 업데이트 된다고함.
ㄴHashtable에 대해서 찾아보니 딕셔너리와 유사
ㄴSetCustomProperties메서드의 매개변수로 키와 내용으로 Hashtable의 객체를 할당.
ㄴCustomProperties중 할당한 키의 값으로 할당한 hashtable의 내용을 불러올 수 있음.
ㄴHashtable의 Key는 PhotonNetwork.LocalPlayer.ActorNumber로 저장했으며, Value는 string으로 하여 저장.
ㄴSetCustomProperties를 통해 커스텀프로퍼티를 저장하고
ㄴSetPlayerCustomProperties의 매개변수로 PhotonNetwork.LocalPlayer.ActorNumber를 Key값으로, Player.CustomProperties를 Value값으로 할당
ㄴSetPlayerCustomProperties[PhotonNetwork.LocalPlayer.ActorNumber]의 값은 앞서 할당해둔 string타입의 value가 반환되는 것을 확인.
ㄴ하지만 CustomProperties를 등록한 디바이스에서 value가 반환되는 것을 확인했기에 확실한지는 모름 => 하지만 서버에서 가져오는 SetPlayerCustomProperties니까 됐다고 봐도 무방하다고 생각함.
ㄴ앞으로 찾아야할 부분은 Hashtable의 value또는 CustomProperties의 value값으로 GameObject같은 타입을 할당할 수 있는지 찾아봐야함
ㄴ이어서 원하는 타입의 할당가능여부에 따라 서버 내의 원하는 클라이언트의 커스텀 프로퍼티를 통해 어떻게 해당 플레이어의 태그를 바꿔줄지 찾아야함.
'Unity > Project : Cursed Treasure' 카테고리의 다른 글
Unity 팀프 21.05.31. PUN2 - CustomProperties(R&D) (0) | 2021.06.01 |
---|---|
Unity 팀프 21.05.29 PUN2 - CustomPropeties (0) | 2021.05.30 |
Unity 팀프 21.05.27 Photon - 멀티구현 R&D (0) | 2021.05.28 |
Unity 팀프 21.05.27 조작 - 3인칭 조이스틱 (0) | 2021.05.27 |
Unity 팀프 21.05.25. 3rd Person Joystick - 1단계 (0) | 2021.05.25 |