Scene에 Asset으로 불러온 아주 많은 3D Object가 있는데, 그것들이 전부 메시 컬라이더를 갖고 있었기 때문에, 그걸 한꺼번에 제거하고 싶었음
응용해서 Box Collider 등 다른 것도 전부 제거
#if UNITY_EDITOR
using UnityEngine;
using UnityEditor;
public class RemoveMeshCollidersEditor : MonoBehaviour
{
[MenuItem("Tools/Remove All Mesh Colliders")]
public static void RemoveAllMeshColliders()
{
// Scene에 있는 모든 MeshCollider 컴포넌트를 찾습니다.
MeshCollider[] meshColliders = FindObjectsOfType<MeshCollider>();
// 각 MeshCollider를 순회하면서 제거합니다.
foreach (MeshCollider collider in meshColliders)
{
DestroyImmediate(collider);
}
// 변동 사항을 저장합니다.
UnityEditor.SceneManagement.EditorSceneManager.MarkSceneDirty(UnityEngine.SceneManagement.SceneManager.GetActiveScene());
}
}
#endif
유니티에서의 TMP_InputField와 TMP_Text의 text 반환값은 모두 string 타입이지만, InputField에서 반환되는 text는 사용자가 입력한 값만을 포함하고, TMP_Text의 text는 추가적으로 포매팅이나 스타일에 대한 정보를 포함할 수 있습니다. 이는 TMP_Text에서 텍스트를 처리하는 방식과 관련되어 있습니다.
사용자가 "5004"라는 값을 입력했더라도, TMP_Text의 text 값을 가져오면 "\u200B5004" 또는 "5004\u200B"와 같이 보이지 않는 특수 문자가 포함된 문자열을 얻을 수 있습니다. 이 경우, int로 변환하는 과정에서 FormatException이 발생할 수 있습니다. 이는 int.Parse 또는 int.TryParse 메서드가 숫자 이외의 문자를 포함한 문자열을 int로 변환할 수 없기 때문입니다.
이 문제를 해결하려면, TMP_Text의 text에서 숫자만 추출하여 int로 변환하는 것이 필요합니다. 이를 위해서는 정규 표현식 등을 사용하여 숫자만 추출할 수 있습니다.
string inputString = _text.text;
string cleanedString = System.Text.RegularExpressions.Regex.Replace(inputString, "[^0-9]", "");
int stageIDX;
if (int.TryParse(cleanedString, out stageIDX))
{
// stageIDX 사용 가능
}
else
{
Debug.LogError($"Failed to parse {_text.text} to int");
}
이 코드는 _text.text에서 숫자 이외의 문자를 모두 제거한 후, 그 결과 문자열을 int로 변환하려고 시도합니다. 숫자 이외의 문자를 제거하는 것이 필요한 경우에 유용하게 사용될 수 있습니다.
using System.Linq;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
using Newtonsoft.Json;
public class ModuleDataDownloadTable : MonoBehaviour
{
// Constants used for API call
private const string KeyTable = "여기에 전체 공유된 구글 스프레드시트 번호 넣기";
private const string KeyAuth = "여기에 구글 스프레드시트 인증 넣기(참고: https://ajh322.tistory.com/247)";
private const string UrlFormat = "https://sheets.googleapis.com/v4/spreadsheets/{0}/values/{1}?key={2}";
// Initialization method
public void Init()
{
}
// Coroutine for downloading table data
public IEnumerator DownloadTable(string tableName, System.Action<string> afterAction)
{
Debug.LogWarning($":: Download Table : {tableName} Start");
// Create a new web request with the appropriate URL
using UnityWebRequest req = UnityWebRequest.Get(PickURL(tableName));
yield return req.SendWebRequest();
// Handle potential request errors
if (req.result == UnityWebRequest.Result.ConnectionError || req.result == UnityWebRequest.Result.ProtocolError)
{
Debug.LogError(req.error);
yield break;
}
// Deserialize the response and convert to JSON
string[][] values = DeserializeResponse(req.downloadHandler.text);
afterAction(ConvertValuesToJson(values));
Debug.Log($":: Download Table : {tableName} Complete");
}
// Deserialize the HTTP response
private string[][] DeserializeResponse(string response)
{
return JsonConvert.DeserializeObject<GoogleSheetClass>(response).values;
}
// Convert the data values to a JSON string
private string ConvertValuesToJson(string[][] values)
{
Dictionary<int, string> keys = new();
List<string> jsonObjects = new List<string>();
for (int i = 0; i < values.Length; i++)
{
if (i == 0)
{
// Set keys from the first row of values
SetKeys(keys, values[i]);
continue;
}
// Create JSON objects from subsequent rows of values
jsonObjects.Add(GenerateJsonObject(keys, values[i]));
}
return $"[{string.Join(",", jsonObjects)}]";
}
// Set keys for JSON objects from the first row of data
private void SetKeys(Dictionary<int, string> keys, string[] row)
{
for (int i = 0; i < row.Length; i++)
{
keys.Add(i, row[i]);
}
}
// Generate a JSON object as a string
private string GenerateJsonObject(Dictionary<int, string> keys, string[] row)
{
List<string> properties = new List<string>();
for (int i = 0; i < row.Length; i++)
{
if (keys[i].Contains('~')) continue;
properties.Add($"\"{keys[i]}\":\"{row[i]}\"");
}
return $"{{{string.Join(",", properties)}}}";
}
// Form URL for HTTP request
private string PickURL(string tableName)
{
return string.Format(UrlFormat, KeyTable, tableName, KeyAuth);
}
// Inner class to match the structure of the HTTP response for deserialization
private class GoogleSheetClass
{
public string range { get; set; }
public string majorDimension { get; set; }
public string[][] values { get; set; }
}
}
#region Download Table
public bool IsTableDownloaded { get; private set; } = false;
private async void DownloadTable()
{
IsTableDownloaded = false;
this._moduleDownloadTable = this.gameObject.AddComponent<ModuleDataDownloadTable>();
var task1 = InitializeData<DataText>(Constants.PATH_DATA_TEXT, (texts) =>
{
_texts = texts.ToDictionary(ele => ele.idx);
});
var task2 = InitializeData<DataCard>(Constants.PATH_DATA_CARD, (cards) =>
{
_cards = cards.ToDictionary(ele => ele.idx);
_cardsGroup = cards.GroupBy(ele => ele.group).ToDictionary(ele => ele.Key, ele => ele.ToArray());
});
var task3 = InitializeData<DataCardDropGroup>(Constants.PATH_DATA_CARD_DROP_GROUP, (cardDropGroups) =>
{
_cardDropGroup = cardDropGroups.GroupBy(ele => ele.group_idx).ToDictionary(ele => ele.Key, ele => ele.ToArray());
});
var task4 = InitializeData<DataCardBuyGroup>(Constants.PATH_DATA_CARD_BUY_GROUP, (cardBuyGroups) =>
{
_cardBuyGroup = cardBuyGroups.GroupBy(ele => ele.group_idx).ToDictionary(ele => ele.Key, ele => ele.ToArray());
});
await Task.WhenAll(task1, task2, task3, task4);
IsTableDownloaded = true;
}
async Task InitializeData<T>(string path, System.Action<T[]> afterDeserialize)
{
string cleanedPath = path.Replace("Data/", "");
var deserializedData = await Deserialize<T>(cleanedPath);
afterDeserialize(deserializedData);
}
private async Task<T[]> Deserialize<T>(string path)
{
// Create a task completion source.
TaskCompletionSource<T[]> tcs = new TaskCompletionSource<T[]>();
// Start the download table task.
StartCoroutine(_moduleDownloadTable.DownloadTable(path, (string json) =>
{
// Deserialize the json data to the specific object type array.
T[] result = JsonConvert.DeserializeObject<T[]>(json);
// Set the result to the task completion source.
tcs.SetResult(result);
}));
// Await for the task to be completed.
T[] data = await tcs.Task;
// Return the deserialized data.
return data;
}
#endregion
Visual Studio Code는 Unity에서 C# 파일을 편집하는 데 큰 도움이 될 수 있습니다. 모든 C# 기능이 지원되며 더 많은 기능이 있습니다. 아래 화면에서 코드 색상화, 괄호 매칭, 인텔리센스, 코드렌즈 등의 기능을 확인할 수 있습니다. 그리고 이것은 시작일 뿐입니다.
계속 읽어서 Unity와 프로젝트를 최상의 경험을 얻기 위해 어떻게 설정하는지 알아보세요.
Open upUnity Preferences,External Tools, then browse for the Visual Studio Code executable asExternal Script Editor.
The Visual Studio Code executable can be found at/Applications/Visual Studio Code.appon macOS,%localappdata%\Programs\Microsoft VS Code\Code.exeon Windows by default.
Unity has built-in support for opening scripts in Visual Studio Codeas an external script editor on Windows and macOS. Unity will detect when Visual Studio Code is selected as an external script editor and pass the correct arguments to it when opening scripts from Unity. Unity will also set up a default.vscode/settings.jsonwith file excludes, if it does not already exist (fromUnity 5.5 Release notes).
Since 2019.2, it is required to use theVisual Studio Code Editor package. The built-in support for opening scripts from Unity and gettingcsprojandslnfiles generated has been removed.
Unity hasa set of custom C# warnings, called analyzers, that check for common issues with your source code. These analyzers ship out of the box with Visual Studio but need to be set up manually in Visual Studio Code.
Due to how Unity handles its.csprojfiles, it does not seem possible to install packages automatically. You will need to download the analyzers from theNuGet websitemanually. Make sure to download the.nupkgfile, the source code from GitHub will not work.
When you're done, open the package file using a tool such as 7zip and extractMicrosoft.Unity.Analyzers.dllonto your project's root folder. You can place it inside a folder namedNuGet, for example. Do not place it insideAssetsorPackages, as that will cause Unity to try to process the.dll, which will make it output an error in the console.
Note: 7zip cannot open a.nupkgfile by right-click andOpen with. Instead, you have to open the 7zip application, navigate to the file, and then selectExtract.
Next, create anomnisharp.jsonfile at the root folder of your project, as explainedhere. Analyzer support in OmniSharp is experimental at the moment, so we need to enable it explicitly. We also need to point it to the.dllfile we just extracted.
Youromnisharp.jsonfile should end up looking like this:
where"./NuGet/microsoft.unity.analyzers.1.14.0/analyzers/dotnet/cs"is a relative path pointing to the folder containing the.dllfile. Depending on where you placed it, your path may look different.
The Unity analyzers should now be working in your project. You can test them by creating an emptyFixedUpdate()method inside one of yourMonoBehaviorclasses, which should trigger aThe Unity message 'FixedUpdate' is emptywarning (UNT0001).
Note that while it is possible to activate these analyzers, the suppressors they ship with the package (that turn off other C# warnings that may conflict with these custom ones) may not be picked up by OmniSharp at the moment,according to this thread. You can still turn off specific rules manually by following these steps:
Create a.editorconfigfile in your project's root folder (next to Unity's.csprojfiles).
root=truetells OmniSharp that this is your project root and it should stop looking for parent.editorconfigfiles outside of this folder.
dotnet_diagnostic.IDE0051.severity = noneis an example of turning off the analyzer with IDIDE0051by setting its severity level tonone. You can read more about these settings in theAnalyzer overview. You can add as many of these rules as you want to this file.
[*.cs]indicates that our custom rules should apply to all C# scripts (files with the.csextension).
You are now ready to code in Visual Studio Code, while getting the same warnings as you would when using Visual Studio!
You need to ensure that your solution is open in VS Code (not just a single file). Open the folder with your solution and you usually will not need to do anything else. If for some reason VS Code has not selected the right solution context, you can change the selected project by clicking on the OmniSharp flame icon on the status bar.
Choose the-CSharpversion of the solution file and VS Code will light up.
Unity creates a number of additional files that can clutter your workspace in VS Code. You can easily hide these so that you can focus on the files you actually want to edit.
To do this, add the following JSON to yourworkspace settings. By adding these excludes to your workspace settings, you will not change your global user settings and it allows anyone also working on the project to have the same file excludes.
As you can see below this will clean things up a lot...
Before
After
To edit this directly within VS Code Settings editor, go toFile>Preferences>Settings(Code>Preferences>Settingson macOS). Switch to theWorkspacetab and then type "files exclude" into the Settings editor search bar. Add a glob pattern similar to the pattern shown below by clicking theAdd Patternbutton for theFiles: Excludesetting. You will need to add each pattern separately.
[System.Flags]는 C#(.NET 프레임워크의 일부)에서 열거형(enum)을 플래그(flag)의 모음으로 처리해야 함을 나타내는 속성입니다. 이를 통해 비트 연산을 사용하여 enum 값을 결합할 수 있으며, 이는 코드에서 옵션 또는 상태 조합을 효율적으로 나타내는 데 도움이 됩니다.
[System.Flags]의 주요 사용 사례는 다양한 방식으로 결합될 수 있는 독립적인 옵션 또는 속성 집합이 있을 때입니다. 플래그 속성을 사용하면 단일 정수 값으로 이러한 옵션의 모든 조합을 나타낼 수 있습니다.
다음은 이 개념을 설명하는 예입니다:
[System.Flags]를 사용하지 않는 경우:
public enum Colors { Red, Green, Blue }
이 경우 변수에 한 번에 하나의 색상만 할당할 수 있습니다.
[System.Flags]를 사용하는 경우:
[System.Flags] public enum Colors { None = 0, Red = 1, Green = 2, Blue = 4 }