Get it on Google Play


Wm뮤 :: 'Unity' 카테고리의 글 목록 (17 Page)

블로그 이미지
가끔 그림그리거나 3D모델링하거나
취미로 로봇만드는
전자과 게임프로그래머 (퇴사함)
2022.3.22f1 주로 사용
모카쨩
@Ahzkwid

Recent Comment

Archive


2020. 12. 30. 20:28 Unity

거리설정

'Unity' 카테고리의 다른 글

유니티 카메라  (0) 2021.01.27
유니티 에러코드 애니메이터  (0) 2020.12.30
유니티 단축키  (0) 2020.11.24
posted by 모카쨩
2020. 12. 30. 16:02 Unity

레이어가 두개면 각각 개별로 돌아가면서 혼합된다

 

 

기본값은 웨이트가 0이라서 혼합이 안된다 1로 변경하자

 

 

 

에러코드 100일때 뜨는 팝업

 

반드시 화살표 순서대로 한다. 순서가 어긋나면 값이 초기화된다

사진에서는 파라미터 앞글자가 대문자인데 가급적 소문자로 해주자

 

 

빠져나올땐 낫 이퀄로 한다

 

 

 

    public LoaderState state = LoaderState.None;
    public ErrorCode errorCode = ErrorCode.None;
    public enum LoaderState
    {
        None,
        Connect,
        Download,
        Error,
        Exit
    }
    public enum ErrorCode
    {
        None,
        InternetConnection = 100,
        RunExistingFile = 200,
        NoFile = 300
    }

    void Update()
    {
        animatorState.SetInteger(nameof(errorCode), (int)errorCode);
        animatorState.SetInteger(nameof(state), (int)state);
    }

파라미터를 연동시켜준다 끝

'Unity' 카테고리의 다른 글

유니티 그림자  (0) 2020.12.30
유니티 단축키  (0) 2020.11.24
Resource ID out of range in GetResource  (0) 2020.11.16
posted by 모카쨩
2020. 12. 24. 01:31 Unity/C#
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MapBorder : MonoBehaviour {

	private void OnDrawGizmos()
	{
		Gizmos.DrawWireCube(borderCenter, borderSize);
	}
	public enum DropOption
	{
		None
		, Respawn
		, Destroy
	}
	public DropOption dropOption = DropOption.Respawn;

	public Vector3 borderCenter = Vector3.zero;
	public Vector3 borderSize = new Vector3(200,100,200);
	public Transform respawnPoint;
	Vector3 firstPosition;
	Quaternion firstRotation;
	// Use this for initialization
	void Start ()
	{
		firstPosition = transform.position;
		firstRotation = transform.rotation;
	}
	
	// Update is called once per frame
	void Update () {

		var pos = transform.position;
		pos.x = Mathf.Clamp(pos.x, borderCenter.x - borderSize.x, borderCenter.x + borderSize.x );
		pos.y = Mathf.Min(pos.y, borderCenter.y + borderSize.y );
		pos.z = Mathf.Clamp(pos.z, borderCenter.z - borderSize.z , borderCenter.z + borderSize.z);



		transform.position = pos;
		if (transform.position.y<borderCenter.y- borderSize.y )
		{
			switch (dropOption)
			{
				case DropOption.None:
					break;
				case DropOption.Respawn:
					if (respawnPoint == null)
					{
						transform.position = firstPosition;
						transform.rotation = firstRotation;
					}
					else
					{
						transform.position = respawnPoint.transform.position;
						transform.rotation = respawnPoint.transform.rotation;
					}
					break;
				case DropOption.Destroy:
					Destroy(gameObject);
					break;
				default:
					break;
			}
		}
	}
}

'Unity > C#' 카테고리의 다른 글

c# 기본 문법  (0) 2021.01.15
리플렉션  (0) 2020.12.23
그래디언트효과  (0) 2020.10.20
posted by 모카쨩
2020. 12. 23. 15:34 Unity/C#

 

현재 클래스 명


public class ParentClass
{
  public class TestClass
  {
      public void Log()
      {
        var className = GetType().Name
        Debug.Log(className);  //TestClass가 나옴
      }
  }
}

현재 클래스 명 (부모포함)

var className = typeof(TestClass).FullName
Debug.Log(className);   //ParentClass+TestClass가 나옴

 

해당 클래스가 존재하는지

public static bool CheckClassExists(string className)
{
    return System.Type.GetType(className) != null;
}

 

 

현재 함수 명

var methodName = System.Reflection.MethodBase.GetCurrentMethod().Name;
Debug.Log(methodName);

 

 

필드명들


string[] GetClassFieldNames<T>(T targetClass)
{
    var fields = typeof(T).GetFields();
    return System.Array.ConvertAll(fields, x => x.Name);
}

 

필드명들2

string[] GetClassFieldNames<T>(T targetClass)
{
    var fields = typeof(T).GetFields();
    return Array.ConvertAll(fields, x => $"{x.Name} - type: {x.FieldType}");
}

 

 

 

 

 

특정클래스의 필드명과 함수명에 접근

var methods = typeof(Class).GetMethods();
foreach (var method in methods)
{
    EditorGUILayout.LabelField(method.Name);
}

var fields = typeof(Class).GetFields();
foreach (var field in fields)
{
    EditorGUILayout.LabelField(field.Name);
}

 

 

 

클래스할당과 연동

구조체에는 씨알도 안 먹히니 헛고생 하지 말자


public class SampleClass
{
    string numStr = "0.5";
    int num = 1;
    float value = 1.5f;
    public SampleClass() { }
    public SampleClass (string stringData)
    {

        var fields = typeof(SampleClass).GetFields();
        var targetClass = this;

        for (int i = 0; i < fields.Length; i++)
        {
            if (fields[i].FieldType == typeof(string))
            {
                fields[i].SetValue(targetClass, stringData);
            }
            else if (fields[i].FieldType == typeof(bool))
            {
                fields[i].SetValue(targetClass, bool.Parse(stringData));
            }
            else if (fields[i].FieldType == typeof(char))
            {
                fields[i].SetValue(targetClass, char.Parse(stringData));
            }
            else if (fields[i].FieldType == typeof(int))
            {
                fields[i].SetValue(targetClass, int.Parse(stringData));
            }
            else if (fields[i].FieldType == typeof(uint))
            {
                fields[i].SetValue(targetClass, uint.Parse(stringData));
            }
            else if (fields[i].FieldType == typeof(long))
            {
                fields[i].SetValue(targetClass, long.Parse(stringData));
            }
            else if (fields[i].FieldType == typeof(ulong))
            {
                fields[i].SetValue(targetClass, ulong.Parse(stringData));
            }
            else if (fields[i].FieldType == typeof(float))
            {
                fields[i].SetValue(targetClass, float.Parse(stringData));
            }
            else if (fields[i].FieldType == typeof(double))
            {
                fields[i].SetValue(targetClass, double.Parse(stringData));
            }
            else
            {
                fields[i].SetValue(targetClass, stringData);
            }
        }
    }
    
    public override string ToString()
    {
        var fields = GetType().GetFields(System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public);
        return string.Join("\n",System.Array.ConvertAll(fields, x => $"{x.Name}: {x.GetValue(x)}" ));
    }
    /*
    public override string ToString()
    {
        var fields = typeof(SampleClass).GetFields();
        string returnString = "";
        for (int i = 0; i < fields.Length; i++)
        {
            if (i>0)
            {
                returnString += "\n";
            }
            returnString += $"{fields[i].Name}:{fields[i].GetValue(this)}";
        }

        return returnString;
    }
    */
    public static implicit operator string(SampleClass _this) //암시적 형변환, 명시적은 explicit 
    {
        return _this.ToString();
    }

}

public class MainClass : MonoBehaviour
{
	void Start()
    {
        Debug.Log("new SampleClass()\n" + new SampleClass());
        Debug.Log("new SampleClass(\"123\")\n" + new SampleClass("123"));
    }
}

 

생성자 자동 할당

public class SampleClass
{
    public int number;
    public string name;
    public SampleClass()//생성자(자동)
    {
        var targetClass = new SampleClass(123, "Name");

        //this.number = targetClass.number;
        //this.name = targetClass.name;
        //이렇게 안쳐도 됨

        var fields = GetType().GetFields();
        foreach (var field in fields)
        {
            field.SetValue(this, field.GetValue(targetClass));
        }
    }
    public SampleClass(int number, string name)//생성자
    {
        this.number = number;
        this.name = name;
    }

}

 

클래스 깊은복사, 간단한 형식만 된다. 다중 클래스등은 불가 (문자열도 안되는듯?)

public class SampleClass
{
    public int number;
    public string name;
    public SampleClass Clone()
    {
        var targetClass = new SampleClass();
        var fields = GetType().GetFields();
        foreach (var field in fields)
        {
            field.SetValue(this, field.GetValue(targetClass));
        }
        return targetClass;
    }

}

 

 

위에거의 외부버전

https://gist.github.com/ahzkwid/69d7703736b5bca29b0131270ee9164a

static void CopyClass<T>(T source, T target)
{
    var fields = target.GetType().GetFields();
    foreach (var field in fields)
    {
        field.SetValue(target, field.GetValue(source));
    }
}

 

 

 

 

 

 

 

BindingFlags 옵션들 (지정 안되면 논퍼블릭까지 전부 반환함)

System.Reflection.BindingFlags.NonPublic //퍼블릭이 아닌것들
System.Reflection.BindingFlags.Public //퍼블릭인것들
System.Reflection.BindingFlags.Instance  //일반적인 변수들 (지역변수)
System.Reflection.BindingFlags.Static  //전역변수들


//예시 (일반적인 필드값 불러오기)
var fields = GetType().GetFields(System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public);
        

 

 

Type검사

field.FieldType.IsValueType //bool,int,float
field.FieldType.IsArray //bool[], int[], float[]
field.FieldType.IsClass //bool[], int[], float[], string, SubClass
field.FieldType.IsEnum //Enum타입
field.FieldType.Equals(typeof(string)) //string




//클래스인지 검사
var fieldType = field.FieldType;
if (fieldType.IsClass&&(fieldType.IsArray==false)&&(fieldType.Equals(typeof(string)) == false))
{
 //Sub클래스일경우에만
}


//List인지 검사
if((fieldType.IsGenericType) && fieldType.GetGenericTypeDefinition() == typeof(List<>))

 

오브젝트에서 ?배열을 반환

이런 X같은 코드도 쓸데가 있다

object objData;
var arrDatas = (System.Collections.IList)objData;

Debug.Log($"arrDatas[0]: {arrDatas[0]}");
Debug.Log($"arrDatas[1]: {arrDatas[1]}");
Debug.Log($"arrDatas.Count: {arrDatas.Count}");

 

 

오브젝트 리스트나 오브젝트 배열을 특정 형배열로 변환

using System.Linq;

//오브젝트 리스트를 float 배열로 변환
var objList=new List<object>();
float[] floatArray=objList.Cast<float>().ToArray();


//오브젝트 배열을 string 배열로 변환
object[] objArray = new object[1];
string[] stringArray = objArray.Cast<string>().ToArray();

 

 

문자열을 FieldType으로 변환

var text = "105.0";

var converter = TypeDescriptor.GetConverter(field.FieldType);
var data = converter.ConvertFrom(text);
field.SetValue(tempClass, data);

 

 

 

배열에 할당된 변수명 추출

v1

더보기
string[] ArrayToFieldNames(object containingClassWithArray, object[] array)
{
    var fields = containingClassWithArray.GetType().GetFields();
    var fieldNames = System.Array.ConvertAll(array, x => fields.First(field => field.GetValue(containingClassWithArray) == x).Name);
    return fieldNames;
}

/* 
예시 

public class Coordinator : MonoBehaviour
{
    public BodyPart head;
    public BodyPart top;
    public BodyPart bottom;
    public BodyPart gloves;
    public BodyPart shoes;

    public BodyPart hair;
    public BodyPart eye;
    public BodyPart skin;
    public BodyPart[] bodyParts
    {
        get
        {
            return new BodyPart[] { head, top, bottom, gloves, shoes, hair, eye, skin };
        }
    }
}
이렇게 있을때

var bodyPartNames = ArrayToFieldNames(coordinator, coordinator.bodyParts);
Debug.Log(string.Join(",",bodyPartNames));
하면 head,top,bottom,gloves,shoes,hair,eye,skin로 나온다
*/

 

 

 

 

v2

v1과 구조상으로는 동일한데 클래스내부로 넣어버렸다.

이게 더 편함


string[] ArrayToFieldNames(object[] array)
{
    var fields = GetType().GetFields();
    var fieldNames = System.Array.ConvertAll(array, x => fields.First(field => field.GetValue(this) == x).Name);
    return fieldNames;
}
/*
//샘플
    public BodyPart head;
    public BodyPart top;
    public BodyPart bottom;
    public BodyPart gloves;
    public BodyPart shoes;

    public BodyPart hair;
    public BodyPart eye;
    public BodyPart skin;
    public BodyPart[] bodyParts
    {
        get
        {
            return new BodyPart[] { head, top, bottom, gloves, shoes, hair, eye, skin };
        }
    }
    public string[] bodyPartNames
    {
        get
        {
            return ArrayToFieldNames(bodyParts);
        }
    }
*/

근데 이방법 쓸바엔 그냥 클래스 안에 name값 넣어서 써라

 

 

 

 

 

 

 

 

 


var value = field.GetValue(component);
if (value==null)
{
    continue;
}

https://x.com/ahzkwid/status/1799549808312746276

 field.GetValue(component)을 ==null체크시 정상동작하지 않는 현상이 있는데

 

var value = field.GetValue(component);
if (value==null)
{
    continue;
}
if (value.Equals(null))
{
    continue;
}

이렇게 하면 된다

 

 

'Unity > C#' 카테고리의 다른 글

MapBorder  (0) 2020.12.24
그래디언트효과  (0) 2020.10.20
유니티 에디터 관련  (0) 2020.10.05
posted by 모카쨩
2020. 12. 2. 11:27 Unity/Photon

 

 

www.photonengine.com/ko-KR/

 

글로벌 크로스 플랫폼 실시간 게임 개발 | Photon Engine

MULTIPLAYER REALTIME PUN BOLT QUANTUM COMMUNICATION CHAT VOICE SELF-HOSTED SERVER 멀티플레이를 간단하게 실현합니다! Photon Realtime 인디/프로 개발자 누구나 실시간 멀티 플레이어 게임을 개발하여 세계로 진출할

www.photonengine.com

 

가입하고

 

dashboard.photonengine.com/ko-KR/

 

Multiplayer Game Development Made Easy | Photon Engine

MULTIPLAYER REALTIME PUN BOLT QUANTUM COMMUNICATION CHAT VOICE SELF-HOSTED SERVER We Make Multiplayer Simple Photon Realtime Develop and launch multiplayer games globally whether you are an indie developer or AAA studio. Create synchronous or asynchronous

id.photonengine.com

여기에 들어가서

 

Photon PUN은 VRChat같은거 만들때 씀, 전부 간접통신임

Photon BOLT는 오버워치 같은거 만들때 쓰고 직접통신, NAT나 방화벽등으로 인해 직접연결이 불가한경우 릴레이를 통한 간접연결이 됨, 방장이 나가면 방이 닫힌다

 

설정한다

 

 

 

어플리케이션 ID 필요함

 

 

 

 

유니티로 가서

 

PUN1

더보기

assetstore.unity.com/packages/tools/network/photon-unity-networking-classic-free-1786

 

다운로드해

 

펀 ID를 넣자

 

 

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PhotonInit : Photon.PunBehaviour
{
    public string serverName = "Default0001";
    public int roomNumber = 0;
    public Transform spawnPoint;
    public GameObject playerPrefab;



    // Start is called before the first frame update
    void Start()
    {
        PhotonNetwork.ConnectUsingSettings(serverName);
        PhotonNetwork.ConnectToBestCloudServer(serverName);
    }
    /// <summary>
    /// 로비에 들어가기 성공했을때
    /// </summary>
    public override void OnConnectedToPhoton()
    {
        Debug.Log("ConnectedToPhoton");
    }


    /// <summary>
    /// 로비에 들어가기 성공했을때
    /// </summary>
    public override void OnJoinedLobby()
    {
        Debug.Log("JoinedLobby");
        PhotonNetwork.JoinRandomRoom();
    }
    /// <summary>
    /// PhotonNetwork.autoJoinLobby 이 false 인 경우에만 마스터 서버에 연결되고 인증 후에 호출 
    /// </summary>
    public override void OnConnectedToMaster()
    {
        Debug.Log("ConnectedToMaster");
        PhotonNetwork.JoinLobby(); //로비접속
    }

    /// <summary>
    /// 룸입장실패
    /// </summary>
    /// <param name="codeAndMsg"></param>
    public override void OnPhotonRandomJoinFailed(object[] codeAndMsg)
    {
        Debug.LogError("PhotonRandomJoinFailed");
        PhotonNetwork.CreateRoom(roomNumber.ToString());
    }

    /// <summary>
    /// 룸생성실패
    /// </summary>
    /// <param name="codeAndMsg"></param>
    public override void OnPhotonCreateRoomFailed(object[] codeAndMsg)
    {
        Debug.LogError("PhotonCreateRoomFailed");
        PhotonNetwork.JoinRandomRoom();
    }

    /// <summary>
    /// 룸생성 성공
    /// </summary>
    public override void OnCreatedRoom()
    {
        Debug.Log("CreatedRoom");
    }

    /// <summary>
    /// 룸접속 성공
    /// </summary>
    public override void OnJoinedRoom()
    {
        Debug.Log("JoinedRoom");
        CreatePlayer();
    }
    void CreatePlayer()
    {
        var pos = Vector3.zero;
        var rot = Quaternion.identity;
        if (spawnPoint != null)
        {
            pos = spawnPoint.position;
            rot = spawnPoint.rotation;
        }
        string objName = "Player";//플레이어 프리팹이 없으면 기본 플레이어가 호출됨
        if (playerPrefab != null)
        {
            objName = playerPrefab.name; //프리팹 이름은 Player로 하면 안됨
        }
        PhotonNetwork.Instantiate(objName, pos, rot);
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

 

 

PUN2

더보기

https://assetstore.unity.com/packages/tools/network/pun-2-free-119922

 

PUN 2 - FREE | 네트워크 | Unity Asset Store

Get the PUN 2 - FREE package from Exit Games and speed up your game development process. Find this & other 네트워크 options on the Unity Asset Store.

assetstore.unity.com

다운로드해

 

펀 ID를 넣자

 

using Photon.Pun;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PhotonInit : MonoBehaviourPunCallbacks
{
    public string serverName = "Default0001";
    public int roomNumber = 0;
    public Transform spawnPoint;
    public GameObject playerPrefab;



    // Start is called before the first frame update
    void Start()
    {
        PhotonNetwork.ConnectUsingSettings();
        PhotonNetwork.ConnectToBestCloudServer();
    }

    /// <summary>
    /// 로비에 들어가기 성공했을때
    /// </summary>
    public override void OnJoinedLobby()
    {
        Debug.Log("JoinedLobby");
        //PhotonNetwork.JoinRandomRoom(); //로비사용시
    }
    /// <summary>
    /// PhotonNetwork.autoJoinLobby 이 false 인 경우에만 마스터 서버에 연결되고 인증 후에 호출 
    /// </summary>
    public override void OnConnectedToMaster()
    {
        Debug.Log("ConnectedToMaster");
        PhotonNetwork.JoinRandomRoom();
        //PhotonNetwork.JoinLobby(); //로비접속 (로비사용시)
    }

    /// <summary>
    /// 룸입장실패
    /// </summary>
    /// <param name="codeAndMsg"></param>
    public override void OnJoinRandomFailed(short returnCode, string message)
    {
        Debug.LogError("PhotonRandomJoinFailed");
        PhotonNetwork.CreateRoom(roomNumber.ToString());
    }

    /// <summary>
    /// 룸생성실패
    /// </summary>
    /// <param name="codeAndMsg"></param>
    public override void OnCreateRoomFailed(short returnCode, string message)
    {
        Debug.LogError("PhotonCreateRoomFailed");
        PhotonNetwork.JoinRandomRoom();
    }

    /// <summary>
    /// 룸생성 성공
    /// </summary>
    public override void OnCreatedRoom()
    {
        Debug.Log("CreatedRoom");
    }

    /// <summary>
    /// 룸접속 성공
    /// </summary>
    public override void OnJoinedRoom()
    {
        Debug.Log("JoinedRoom");
        CreatePlayer();
    }
    void CreatePlayer()
    {
        var pos = Vector3.zero;
        var rot = Quaternion.identity;
        if (spawnPoint != null)
        {
            pos = spawnPoint.position;
            rot = spawnPoint.rotation;
        }
        string objName = "My Robot Kyle -done-";//플레이어 프리팹이 없으면 기본 플레이어가 호출됨
        if (playerPrefab != null)
        {
            objName = playerPrefab.name; //프리팹 이름은 Player로 하면 안됨
        }
        PhotonNetwork.Instantiate(objName, pos, rot, 0);
    }

    // Update is called once per frame
    void Update()
    {

    }
}

 

 

 

 

 

 

이렇게 만들어서 

씬에 넣는다.

PUN2

 

 

 

 

api는 여기 참조

PUN1

doc-api.photonengine.com/ko-kr/pun/current/class_photon_1_1_pun_behaviour.html

 

실행하면 이렇게 나온다

 

PUN1

더보기

 

 

로그를 보면 이렇게

빨간줄이 있지만 단지 방이 없어서 뜬것이니 쫄지 말자 정상이다

 

PUN2

더보기

로그를 보면 이렇게

빨간줄이 있지만 단지 방이 없어서 뜬것이니 쫄지 말자 정상이다

 

 

 

 

 

 

시작하면 이렇게 나올것이다.

1. 포톤서버에 연결하고

2. 로비에 들어가서

3. 룸에 들어가는것이다

 

기본적인 네트워킹 시스템은 완성했다

 

 

 

'Unity > Photon' 카테고리의 다른 글

포톤 챗  (0) 2021.07.07
포톤 볼트  (0) 2021.07.06
포톤 커스텀 플레이어 만들기  (0) 2021.07.04
posted by 모카쨩
2020. 11. 24. 18:12 Unity

 

 

 

Ctrl + Shift + F : 선택한 오브젝트를 현재 씬뷰의 위치로 이동시킴

F : 씬뷰의 위치를 선택한 오브젝트의 위치로 이동시킴

posted by 모카쨩
2020. 11. 16. 11:42 Unity

Texture2D가 매프레임마다 생성됨,

얘는 씬이동이나 오브젝트 삭제시에도 안 지워지므로 반드시 한번만 생성해서 쓰는식으로 해야함

'Unity' 카테고리의 다른 글

유니티 단축키  (0) 2020.11.24
Streaming of 'mpeg' on this platform is not supported  (0) 2020.11.11
투명 렌더텍스처  (0) 2020.11.10
posted by 모카쨩
2020. 11. 11. 20:19 Unity

 

 

 

UnityWebRequestMultimedia.GetAudioClip을 사용시 빌드플랫폼이 윈도우로 설정되어있으면 발생함

안드로이드나 애플로 돌리자

'Unity' 카테고리의 다른 글

Resource ID out of range in GetResource  (0) 2020.11.16
투명 렌더텍스처  (0) 2020.11.10
유니티 아틀라스 이미지 깨질때  (0) 2020.11.09
posted by 모카쨩

저사양 유저용 블로그 진입