Get it on Google Play


Wm뮤 :: 'Unity' 카테고리의 글 목록

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

Recent Comment

Archive


2024. 9. 8. 07:28 Unity

 

 

Opening file failed

Opening file 경로.meta: 지정된 경로를 찾을 수 없습니다.

 

 

 

에셋 수정툴 만들때 잘못된 GUID 입력으로 발생한다

 

 

 

문제가 되는 에셋과 Library 폴더 삭제로 해결가능하다

 

 

 

 

 

그런데 라이브러리 통째로 지우는건 시간이 오래 걸려서 위 폴더만 지워도 된다

 

 

'Unity' 카테고리의 다른 글

LTCGI  (0) 2024.09.06
유니티 Assembly Definition Asset  (0) 2024.04.16
게임개발용 부하테스트 2024  (0) 2024.02.27
posted by 모카쨩
2024. 9. 6. 10:08 Unity

 

 

 

https://ltcgi.dev/#Attribution

 

✨ About LTCGI | LTCGI Documentation

LTCGI is an optimized plug-and-play realtime area light solution using the linearly transformed cosine algorithm for standalone Unity and VRChat. Free to use with attribution. It can utilize the Unity build-in lightmapper or Bakery for realistic shadows on

ltcgi.dev

 

 

화면자체가 라이팅이 되는 시스템

 

영화관같은거 만들때 쓰지 않을까 

 

 

'Unity' 카테고리의 다른 글

Opening file failed 에러  (0) 2024.09.08
유니티 Assembly Definition Asset  (0) 2024.04.16
게임개발용 부하테스트 2024  (0) 2024.02.27
posted by 모카쨩
2024. 8. 23. 06:30 Unity/C#


Root를 제외한 경로반환

v1 ~ v3

더보기


가령 Root/armature/Hips는 /armature/Hips가 된다

string ArmaturePath(Transform bone)
{
    var rootName = bone.transform.root.name;
    var hierarchyPath = bone.transform.GetHierarchyPath();
    return hierarchyPath.Substring(rootName.Length, hierarchyPath.Length - rootName.Length);
}

 

 


Root를 제외한 경로반환 v2 (상대경로)

인자를 하나 더 받고 안정성을 높였다

https://gist.github.com/ahzkwid/c89b626c0e7bace5cc317901b524672e

static string RelativePath(Transform target, Transform root = null)
{
    var rootName = "";
    var hierarchyPath = "";


    if (root != null)
    {
        try
        {
            rootName = SearchUtils.GetHierarchyPath(root.gameObject, false);

        }
        catch (System.Exception ex)
        {
            Debug.LogError(ex);
            Debug.LogError(root.ToString() + "nothing root");
            //Debug.LogError(bone.name + "는 root가 없음");
            throw;
        }
    }
    try
    {
        //hierarchyPath = bone.GetHierarchyPath();
        hierarchyPath = SearchUtils.GetHierarchyPath(target.gameObject, false);
    }
    catch (System.Exception ex)
    {
        Debug.LogError(ex);
        Debug.LogError(target.ToString() + "nothing GetHierarchyPath");
        throw;
    }

    var startIndex = rootName.Length;

    return hierarchyPath.Substring(startIndex, hierarchyPath.Length - startIndex);
}

 

v3

static string RelativePath(Transform target, Transform root = null)
{
    var rootName = "";
    var hierarchyPath = "";


    if (root != null)
    {
        try
        {
            rootName = SearchUtils.GetHierarchyPath(root.gameObject, false);

        }
        catch (System.Exception ex)
        {
            Debug.LogError(ex);
            Debug.LogError(root.ToString() + "nothing root");
            //Debug.LogError(bone.name + "는 root가 없음");
            throw;
        }
    }
    try
    {
        //hierarchyPath = bone.GetHierarchyPath();
        hierarchyPath = SearchUtils.GetHierarchyPath(target.gameObject, false);
    }
    catch (System.Exception ex)
    {
        Debug.LogError(ex);
        Debug.LogError(target.ToString() + "nothing GetHierarchyPath");
        throw;
    }

    var startIndex = rootName.Length;

    if (rootName.Length > hierarchyPath.Length)
    {
        Debug.LogWarning("rootName.Length > hierarchyPath.Length");
        Debug.LogWarning($"{rootName} > {hierarchyPath}");
        return null;
    }

    if (hierarchyPath.Substring(0, rootName.Length) != rootName)
    {
        Debug.LogWarning("hierarchyPath.Substring(0, rootName.Length) != rootName");
        Debug.LogWarning($"{rootName} != {hierarchyPath}.Substring(0, rootName.Length)");
        return null;
    }

    try
    {
        return hierarchyPath.Substring(startIndex, hierarchyPath.Length - startIndex);
    }
    catch (System.Exception ex)
    {
        Debug.LogError(ex);
        Debug.LogError($"{hierarchyPath} - {rootName}");
        throw;
    }
}

 

 

v4

경우에 따라 앞에 슬래시는 없애도 된다

var relativePath = "/"+Path.GetRelativePath(rootpath, path);

 

 

 

 

 

 

하이어라키 경로 반환

var path = SearchUtils.GetHierarchyPath(gameObject, false);

 

 

 

패스 병합

Replace 붙은 이유는 유니티는 '/'를 쓰는데 일부 로직에서 '\'를 인식 못하기 때문

var path = Path.Join(parentPath, childPath).Replace("\\", "/");

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

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

OnSceneGUI 관련코드  (0) 2024.07.11
유니티 라이트 레졸루션 개별설정  (0) 2024.05.12
유니티 프리팹 드래그 드랍  (0) 2024.05.09
posted by 모카쨩
2024. 7. 11. 19:30 Unity/C#

 

 

 

 

 

OnDrawGizmos처럼 상시동작하는점이 비슷하지만

OnDrawGizmos는 기즈모 드로우 옵션이 켜져있을때에만 동작하므로

기능코드는 가급적 OnSceneGUI에 넣는것이 좋다

 

 

 

1. Static에서 FindObjectsOfType를 이용해 가져와서 처리하는 방식

gist : https://gist.github.com/ahzkwid/3294e9d4cf3980ae2d1c135123db145c

public class SampleClass : MonoBehaviour
{
  static void OnSceneGUI(SceneView sceneView)
  {
      foreach (var sampleClass in FindObjectsOfType<SampleClass>())
      {
          if (sceneView.camera != null)
          {
              var sceneCamera = sceneView.camera;
              //CameraCode
          }
          //otherCode
      }
  }
}
//OtherSample: https://gist.github.com/ahzkwid/6647d3aec625afe96c54bb38b2671c72

 

 

 

 

 

2. SceneView.duringSceneGui에서 이벤트를 받는 방식

원문링크 : https://forum.unity.com/threads/solved-how-to-start-draganddrop-action-so-that-sceneview-and-hierarchy-accept-it-like-with-prefabs.822531/

아래 코드는 내가 만든게 아니고 위 링크에서 가져와 간소화 한것일뿐이다

[ExecuteInEditMode]
public class SampleClass : MonoBehaviour
{
     void OnEnable()
    {
        SceneView.duringSceneGui += OnSceneGUI;
        EditorApplication.hierarchyWindowItemOnGUI += OnHierarchyGUI;
    }

     void OnDisable()
    {
        SceneView.duringSceneGui -= OnSceneGUI;
        EditorApplication.hierarchyWindowItemOnGUI -= OnHierarchyGUI;
    }
     void OnSceneGUI(SceneView obj)
    {
        HandleDragAndDropEvents();
    }

     void OnHierarchyGUI(int instanceID, Rect selectionRect)
    {
        HandleDragAndDropEvents();
    }
     void HandleDragAndDropEvents()
    {
        if (Event.current.type == EventType.DragUpdated)
        {
            OnDragUpdated();
        }
        if (Event.current.type == EventType.DragPerform)
        {
            OnDragPerform();
        }
    }
    void OnDragUpdated()
    {
        Debug.Log("OnDragUpdated()");
    }
    void OnDragPerform()
    {
        Debug.Log("OnDragPerform()");
    }
}

 

 

 

 

 

 

 

 

 

 

 

 

 

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

유니티 오브젝트 경로 관련  (0) 2024.08.23
유니티 라이트 레졸루션 개별설정  (0) 2024.05.12
유니티 프리팹 드래그 드랍  (0) 2024.05.09
posted by 모카쨩
2024. 5. 12. 12:01 Unity/C#

 

 

 

 

 

 

 

 

 

 

 

유니티 2022.3.22.f1 이후의 경우

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


유니티 2022.3.22.f1 이전의 경우는 아래 스크립트 적용 

 

 

 

SettingLightResolution.unitypackage
0.00MB

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[ExecuteAlways]
public class SettingLightResolution : MonoBehaviour
{
    public Light light;
    public int resolution = 256;
    // Start is called before the first frame update
    void Start()
    {
    }

    // Update is called once per frame
    void Update()
    {
        if (light==null)
        {
            return;
        }
        light.shadowCustomResolution = resolution;
#if UNITY_EDITOR
        UnityEditor.EditorUtility.SetDirty(light);
#endif
    }
}



어쩌다보니 만들게 됨

 

 

 

 

 

 

 

 

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

OnSceneGUI 관련코드  (0) 2024.07.11
유니티 프리팹 드래그 드랍  (0) 2024.05.09
AutomaticShadowDistance  (0) 2024.04.18
posted by 모카쨩
2024. 5. 9. 11:32 Unity/C#

 

 

 

 

원문링크 : 

https://forum.unity.com/threads/solved-how-to-start-draganddrop-action-so-that-sceneview-and-hierarchy-accept-it-like-with-prefabs.822531/

 

[Solved] How to start DragAndDrop action so that SceneView and Hierarchy accept it like with prefabs

Edit: Solution below. I'm building a level design tool which shows a list of prefabs in a custom editor window and lets users drag and drop these...

forum.unity.com

 

 

이 코드는 내가 만든게 아니고 위 링크에서 가져와 간소화 한것일뿐이다

 void OnEnable()
{
    SceneView.duringSceneGui += OnSceneGUI;
    EditorApplication.hierarchyWindowItemOnGUI += OnHierarchyGUI;
}

 void OnDisable()
{
    SceneView.duringSceneGui -= OnSceneGUI;
    EditorApplication.hierarchyWindowItemOnGUI -= OnHierarchyGUI;
}
 void OnSceneGUI(SceneView obj)
{
    HandleDragAndDropEvents();
}

 void OnHierarchyGUI(int instanceID, Rect selectionRect)
{
    HandleDragAndDropEvents();
}
 void HandleDragAndDropEvents()
{
    if (Event.current.type == EventType.DragUpdated)
    {
        OnDragUpdated();
    }
    if (Event.current.type == EventType.DragPerform)
    {
        OnDragPerform();
    }
}
void OnDragUpdated()
{
    Debug.Log("OnDragUpdated()");
}
void OnDragPerform()
{
    Debug.Log("OnDragPerform()");
}

 

 

 

아바타 툴 만들때 사용되었다

 

 

 

 

 

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

유니티 라이트 레졸루션 개별설정  (0) 2024.05.12
AutomaticShadowDistance  (0) 2024.04.18
c# Dictionary(딕셔너리) 관련  (0) 2024.03.19
posted by 모카쨩
2024. 4. 18. 15:40 Unity/C#

 

 

 

https://ahzkwid.booth.pm/items/5632873

 

Automatic Shadow Distance - Wmup - BOOTH

ワールド用です DirectionalLightの影の長さをFPSに応じて自動的に変更するツールです。 動きがきれいじゃないので、キャラクターシャドウ専用に使用するのをお勧めします - Code - https://gist.githu

ahzkwid.booth.pm

여기서 다운 가능

 

 

 

 

 

using UdonSharp;
using UnityEngine;
using UnityEngine.UI;
using VRC.SDKBase;
using VRC.Udon;

[UdonBehaviourSyncMode(BehaviourSyncMode.None)]
public class AutomaticShadowDistance : UdonSharpBehaviour
{
    public Light directionalLight;
    public float frameCheckTimeCycle = 3f;
    int playerLayerIndex = 9;
    public Vector2 targetFps = new Vector2(30, 60);
    public Vector2 defaultShadowDistance = new Vector2(10, 80);
    public Vector2 playerShadowDistance = new Vector2(1,15);

    float tPre = 2;

    void UpdateShadowDistance(float t)
    {
        var defaultShadowDistanceMin = defaultShadowDistance.x;
        var defaultShadowDistanceMax = defaultShadowDistance.y;
        var playerShadowDistanceMin = playerShadowDistance.x;
        var playerShadowDistanceMax = playerShadowDistance.y;


        var targetDistanceDefault = Mathf.Lerp(defaultShadowDistanceMin, defaultShadowDistanceMax, t);
        var targetDistancePlayer = Mathf.Lerp(playerShadowDistanceMin, playerShadowDistanceMax, t);
        
        {
            //QualitySettings.shadowDistance = targetDistanceDefault;
        }
        {
            var ShadowCullDistances = new float[32];
            //ShadowCullDistances[0] = Mathf.Lerp(ShadowCullDistances[0], targetDistanceDefault, 0.1f);
            ShadowCullDistances[0] = targetDistanceDefault;
            ShadowCullDistances[11] = ShadowCullDistances[0];
            ShadowCullDistances[13] = ShadowCullDistances[0];
            ShadowCullDistances[14] = ShadowCullDistances[0];
            ShadowCullDistances[playerLayerIndex] = targetDistancePlayer;
            ShadowCullDistances[10] = ShadowCullDistances[playerLayerIndex];
            ShadowCullDistances[18] = ShadowCullDistances[playerLayerIndex];
            directionalLight.layerShadowCullDistances = ShadowCullDistances;

            //Camera.main.layerCullDistances = ShadowCullDistances;
        }
    }

    LightShadows shadowType = LightShadows.Soft;
    void Start()
    {
        //if (directionalLight==null)
        //{
        //    /*
        //    var lights = FindObjectsOfType<Light>();
        //    foreach (var light in lights)
        //    {
        //        if (light.type==LightType.Directional)
        //        {
        //            directionalLight = light;
        //        }
        //    }
        //    */
        //    /*
        //    var light= FindObjectOfType<Light>();
        //    if (light.type == LightType.Directional)
        //    {
        //        directionalLight = light;
        //    }
        //    */
        //}
        if (directionalLight.shadows != LightShadows.None)
        {
            shadowType = directionalLight.shadows;
        }

        UpdateShadowDistance(0);

        lastCheckTime = 0;
    }
    float lastCheckTime = 0;
    int frameCount = 0;

    public Toggle toggle;
    public Slider slider;
    public GameObject lockPanel;

    public bool alwaysUseShdow = true;
    bool CheckT(float t)
    {
        return ((Mathf.Abs(t - tPre) > 0.1f)
            || ((t == 0) && (tPre < 0.1f))
            || ((t == 1) && (tPre > 0.9f)));
    }
    void Update()
    {
        var useShadowOff = !alwaysUseShdow;

        var toggleManual = toggle;
        lockPanel.SetActive(toggleManual.isOn == false);



        var useShadowOffvalue = 0.1f;
        if (toggleManual.isOn)
        {
            if (slider.value > useShadowOffvalue)
            {
                var t = (slider.value - useShadowOffvalue) * (1f / (1f- useShadowOffvalue));
                if (CheckT(t))
                {
                    UpdateShadowDistance(t);
                    tPre = t;
                }
                if (useShadowOff)
                {
                    if (directionalLight.shadows == LightShadows.None)
                    {
                        directionalLight.shadows = shadowType;
                    }
                }
            }
            else
            {
                if (useShadowOff)
                {
                    if (directionalLight.shadows != LightShadows.None)
                    {
                        directionalLight.shadows = LightShadows.None;
                    }
                }
            }
        }
        else
        {


            frameCount++;

            if (Time.time - lastCheckTime >= frameCheckTimeCycle)
            {
                var fps = 0f;
                if (Time.deltaTime > 0)
                {
                    fps = 1f / Time.deltaTime;
                }
                if (frameCheckTimeCycle > 0.1f)
                {
                    fps = frameCount / frameCheckTimeCycle;
                }


                var min = targetFps.x;
                var max = targetFps.y;
                var t = (Mathf.Clamp(fps, min, max) - min) / (max - min);

                /*
                if ((Mathf.Abs(t - tPre) > 0.1f)
                    || ((t == 0) && (tPre < 0.1f))
                    || ((t == 1) && (tPre > 0.9f)))
                */
                if (CheckT(t))
                {

                    UpdateShadowDistance(t);
                    tPre = t;

                }


                if (Time.time > 10)
                {
                    if (useShadowOff)
                    {
                        if (directionalLight.shadows == LightShadows.None)
                        {
                            if (t > 0.8f)
                            {
                                directionalLight.shadows = shadowType;
                            }
                        }
                        else
                        {
                            if (fps < min / 2)
                            {
                                directionalLight.shadows = LightShadows.None;
                            }
                        }
                    }
                }
                if (directionalLight.shadows == LightShadows.None)
                {
                    slider.value = 0f;
                }
                else
                {
                    slider.value = useShadowOffvalue + t * (1f- useShadowOffvalue);
                }


                frameCount = 0;
                lastCheckTime = Time.time;
            }
        }
    }
}

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

유니티 프리팹 드래그 드랍  (0) 2024.05.09
c# Dictionary(딕셔너리) 관련  (0) 2024.03.19
자주 쓰는 DateTime 코드 모음  (0) 2023.12.19
posted by 모카쨩
2024. 4. 16. 23:27 Unity

Assembly Definition Asset
네임스페이스 폴더같은 기능이다

 

에셋을 팔다보니 내가 만든 툴들 동봉해야 하는경우 많았는데 버전충돌 방지하려고 서로 다른 네임스페이스 넣는건 좋았는데 하나하나 일일히 넣으려니 ㅈㄴ 귀찮았다

 

 

 

 

이렇게 하면 파일별로 네임스페이스 수정 안 하고 저거 두개만 수정하면 된다

 

 

 

 

 

 

 

 

 

 

 

그외

define 제약을 걸필요가 있을때

 

걸고 새로고침 돌리면 된다

위 내용은 Unity 2021.1부터 사용가능하게 한다는 제약

유니티 버그인지 저거 하고 어플라이해도 새로고침전까지 에러메세지가 뜬다

에러메세지 떠도 적용은 잘 된거니 걱정말자

적용예시 : https://github.com/ahzkwid/BoothSupport/issues/10

 

 

 

 

using VRC.SDK3A.Editor;

그런데 이렇게 외부에 Assembly Definition이 적용된 클래스를 참조하려 할경우

 

Assets\Ahzkwid\AvatarTools\VRCTools\Editor\VRCBuildProcessor.cs(4,11): 
error CS0234: The type or namespace name 'SDK3A' does not exist
in the namespace 'VRC' (are you missing an assembly reference?)

 

이렇게 미싱이 떠버리는데

 


잘 찾아서 연결하면 된다

경우에 따라 GUID 참조는 안 쓰는게 좋을수도 있다

 

그런데 이렇게 해도 빌드후 업로드시에 미싱이 뜰수도 있다

에디터 함수일경우에 에디터모드가 풀리면서 그런건데

당연히 나는 폴더로 구분해놓으면 괜찮을줄 알았다
그런데 이거 왜인지 이경우에는 동작 안 하더라

#if UNITY_EDITOR

 

위 코드를 넣어서 전처리로 해결해야 한다

 

 

 

 

 

그리고 Root Namespace란은 딱히 안 넣어도 된다

 

 

 

 

 

 

 

 

 

'Unity' 카테고리의 다른 글

LTCGI  (0) 2024.09.06
게임개발용 부하테스트 2024  (0) 2024.02.27
유니티 모델 임포트 에러  (0) 2024.02.24
posted by 모카쨩

저사양 유저용 블로그 진입