This commit is contained in:
2026-06-22 22:57:36 +09:30
parent 68eeef2cff
commit 4b54e57694
683 changed files with 133112 additions and 0 deletions
@@ -0,0 +1,22 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: a385a00f03d2f4d1aa06e69dc6fdeea4, type: 3}
m_Name: Default Styles - Large Font
m_EditorClassIdentifier:
m_MaskingColor: {r: 0.11213955, g: 0.179666, b: 0.2264151, a: 0.5882353}
m_HighlightColor: {r: 0.3915094, g: 0.7492484, b: 1, a: 1}
m_BlockedInteractionColor: {r: 0.16078432, g: 0.63529414, b: 0.96862745, a: 0.019607844}
m_HighlightThickness: 3
m_HighlightAnimationSpeed: 7.52
m_HighlightAnimationDelay: 0
LightThemeStyleSheet: {fileID: 7433441132597879392, guid: be4179ec15d9d4aa4a487c32c7cb868a, type: 3}
DarkThemeStyleSheet: {fileID: 7433441132597879392, guid: 29318b57ddc2f49c0be6aa320f2af055, type: 3}
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 524b9915001f74db09a5fb00cbb109ed
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:
+8
View File
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 35d611ceb8707ac4788f8daab46a064e
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,14 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: ff5e94a8a2536fc44ab893994b3be3c6, type: 3}
m_Name: TutorialCallbacks
m_EditorClassIdentifier:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 12e1dc53c29d9c240af40e95fa058bed
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,404 @@
using UnityEngine;
using UnityEditor;
using UnityEngine.Rendering.Universal;
using Unity.Tutorials.Core.Editor;
using UnityEngine.SceneManagement;
using System.Reflection;
/// <summary>
/// Implement your Tutorial callbacks here.
/// </summary>
[CreateAssetMenu(fileName = DefaultFileName, menuName = "Tutorials/" + DefaultFileName + " Instance")]
public class TutorialCallbacks : ScriptableObject
{
/// <summary>
/// The default file name used to create asset of this class type.
/// </summary>
public const string DefaultFileName = "TutorialCallbacks";
/// <summary>
/// Creates a TutorialCallbacks asset and shows it in the Project window.
/// </summary>
/// <param name="assetPath">
/// A relative path to the project's root. If not provided, the Project window's currently active folder path is used.
/// </param>
/// <returns>The created asset</returns>
public static ScriptableObject CreateAndShowAsset(string assetPath = null)
{
assetPath = assetPath ?? $"{TutorialEditorUtils.GetActiveFolderPath()}/{DefaultFileName}.asset";
var asset = CreateInstance<TutorialCallbacks>();
AssetDatabase.CreateAsset(asset, AssetDatabase.GenerateUniqueAssetPath(assetPath));
EditorUtility.FocusProjectWindow(); // needed in order to make the selection of newly created asset to really work
Selection.activeObject = asset;
return asset;
}
// ****************************
// Added by VB with help from ClaudeAI
// Used in early tutorials to select GameObject for the user.
public void SelectGameObjectInScene(string gameObjectName)
{
// Find the GameObject in the current scene
GameObject targetObject = GameObject.Find(gameObjectName);
if (targetObject != null)
{
// Select the GameObject
Selection.activeGameObject = targetObject;
// Optionally, you can also focus the Scene view on this object
if (SceneView.lastActiveSceneView != null)
{
//SceneView.lastActiveSceneView.FrameSelected();
}
}
else
{
Debug.LogWarning($"GameObject not found: {gameObjectName}");
}
}
// ****************************
// Added by VB with help from ClaudeAI
// Used in early tutorials to select asset in project for the user.
public void SelectAssetinProject(string assetName)
{
string[] guids = AssetDatabase.FindAssets(assetName);
if (guids.Length == 0)
{
Debug.LogWarning($"No asset found with name: {assetName}");
return;
}
string path = AssetDatabase.GUIDToAssetPath(guids[0]);
Object asset = AssetDatabase.LoadAssetAtPath<Object>(path);
if (asset != null)
{
Selection.activeObject = asset;
EditorUtility.FocusProjectWindow();
EditorGUIUtility.PingObject(asset);
}
else
{
Debug.LogError($"Failed to load asset at path: {path}");
}
}
// ****************************
// Added by VB with help from UAI
public void SelectFolderInProject(string folderPath)
{
Object folderObject = AssetDatabase.LoadAssetAtPath<Object>(folderPath);
if (folderObject != null)
{
EditorUtility.FocusProjectWindow();
Selection.activeObject = folderObject;
}
else
{
Debug.LogError("Folder not found: " + folderPath);
}
}
// ****************************
// Added by VB with help from Guillaume
// Used in Welcome Dialog to start tutorials from buttons.
public void StartTutorial(Tutorial tutorial)
{
TutorialWindowUtils.StartTutorial(tutorial);
}
// ****************************
// Added by VB with help from ClaudeAI
public void DisableGameObject(string objectName)
{
GameObject objectToDisable = GameObject.Find(objectName);
if (objectToDisable != null)
{
objectToDisable.SetActive(false);
Debug.Log($"GameObject '{objectName}' has been disabled.");
}
else
{
Debug.LogWarning($"GameObject '{objectName}' not found. Unable to disable.");
}
}
// ****************************
// Added by VB with help from ClaudeAI
public void EnableGameObject(string objectName)
{
Debug.Log("EnableGameObject ran. Looking for: " + objectName);
GameObject objectToEnable = GameObject.FindGameObjectWithTag(objectName);
if (objectToEnable != null)
{
objectToEnable.SetActive(false);
Debug.Log($"GameObject '{objectName}' has been enabled.");
}
else
{
Debug.LogWarning($"GameObject '{objectName}' not found. Unable to enable.");
}
}
public void EnableChildObjects(string objectTag)
{
// Find the object with the specified tag
GameObject objectToEnable = GameObject.FindGameObjectWithTag(objectTag);
if (objectToEnable != null)
{
// Iterate through all the child objects and enable them
foreach (Transform child in objectToEnable.transform)
{
child.gameObject.SetActive(true);
}
}
}
public void FrameObjectWithTag(string objectTag)
{
// Find the object with the specified tag
GameObject objectToFrame = GameObject.FindGameObjectWithTag(objectTag);
if (objectToFrame != null)
{
Selection.activeGameObject = objectToFrame;
// Get the active Scene view
SceneView sceneView = SceneView.lastActiveSceneView;
if (sceneView != null)
{
// Focus on the selected object in the Scene view
sceneView.FrameSelected();
//sceneView.Repaint();
Selection.activeGameObject = null;
}
else
{
Debug.Log("No active Scene view found.");
}
}
else
{
Debug.LogWarning($"GameObject with tag '{objectTag}' not found. Unable to frame object.");
}
}
// Camera Enable/Disable functions using Transform to find child camera and child listener
// Added by VB with help from UAI
private GameObject mainCamera;
private GameObject robotCamera;
private GameObject robotListener;
public void UseMainCamera(bool useMain)
{
// Find the cameras by their names within the scene if they haven't been found already
if (mainCamera == null)
{
mainCamera = FindGameObjectByName("Main Camera");
}
if (robotCamera == null)
{
robotCamera = FindGameObjectByName("RobotCamera");
robotListener = FindGameObjectByName("RobotListener");
}
if (mainCamera == null && useMain)
{
Debug.LogError("Main Camera not found, and can't be enabled.");
return;
}
// Enable the target camera and disable the other one.
// If there is no robotCamera or robotListener, use Main Camera (with its listener) so that there is always a camera
// No error or warning if robotCamera or robotListener is null -- sometimes the robot isn't in the scene
}
// Functions to find a GameObject by name in the Hierarchy (even if a child)
// Added by VB with help from UAI
public static GameObject FindGameObjectByName(string name)
{
GameObject[] rootObjects = UnityEngine.SceneManagement.SceneManager.GetActiveScene().GetRootGameObjects();
foreach (GameObject rootObject in rootObjects)
{
GameObject foundObject = FindGameObjectInChildren(rootObject.transform, name);
if (foundObject != null)
{
return foundObject;
}
}
return null; // if not found
}
// Recursive helper method to search through the children of a given Transform
private static GameObject FindGameObjectInChildren(Transform parent, string name)
{
if (parent.name == name)
{
return parent.gameObject;
}
foreach (Transform child in parent)
{
GameObject foundObject = FindGameObjectInChildren(child, name);
if (foundObject != null)
{
return foundObject;
}
}
return null;
}
// ****************************
// Added by VB with help from ClaudeAI
// Used to set up the layout of the Project window to match the tutorial.
// ClaudeAI warned about Internal API calls.
// NOT CALLED -- Layout appears to handle this now
public void CustomizeProjectWindowLayout()
{
try
{
// Get the ProjectBrowser type
var projectBrowserType = typeof(Editor).Assembly.GetType("UnityEditor.ProjectBrowser");
if (projectBrowserType == null)
{
Debug.LogError("Failed to find ProjectBrowser type");
return;
}
// Find all ProjectBrowser windows
var projectBrowsers = Resources.FindObjectsOfTypeAll(projectBrowserType);
if (projectBrowsers.Length == 0)
{
Debug.LogWarning("No ProjectBrowser windows found");
return;
}
foreach (EditorWindow projectBrowser in projectBrowsers)
{
if (projectBrowser == null)
{
Debug.LogWarning("Found a null ProjectBrowser window, skipping");
continue;
}
// Set to two column layout
SetProjectBrowserToTwoColumnMode();
// Set the slider value to show titles
ShowTextAndHideIcons();
// Force the window to repaint
projectBrowser.Repaint();
}
}
catch (System.Exception e)
{
Debug.LogError($"Error in CustomizeProjectWindowLayout: {e.Message}\nStack Trace: {e.StackTrace}");
}
}
public void SetProjectBrowserToTwoColumnMode()
{
System.Type projectBrowserType = typeof(Editor).Assembly.GetType("UnityEditor.ProjectBrowser");
var projectBrowsers = Resources.FindObjectsOfTypeAll(projectBrowserType);
foreach (var projectBrowser in projectBrowsers)
{
MethodInfo setTwoColumnsMethod = projectBrowserType.GetMethod("SetTwoColumns",
BindingFlags.Instance | BindingFlags.NonPublic);
setTwoColumnsMethod?.Invoke(projectBrowser, null);
}
}
public void ShowTextAndHideIcons()
{
System.Type projectBrowserType = typeof(Editor).Assembly.GetType("UnityEditor.ProjectBrowser");
var projectBrowsers = Resources.FindObjectsOfTypeAll(projectBrowserType);
foreach (var projectBrowser in projectBrowsers)
{
FieldInfo listAreaField = projectBrowserType.GetField("m_ListArea",
BindingFlags.Instance | BindingFlags.NonPublic);
var listAreaState = listAreaField?.GetValue(projectBrowser);
if (listAreaState != null)
{
System.Type listAreaType = listAreaState.GetType();
var gridSizeProperty =
listAreaType.GetProperty("gridSize", BindingFlags.Instance | BindingFlags.Public);
gridSizeProperty.SetValue(listAreaState, 16);
}
}
}
// Added by VB with help from UAI
// Closes the AI Navigation window if it opens by default
// NOT CALLED -- Layout appears to handle this now
public void CloseNavWindowOnStart()
{
// Find the Navigation window
var navigationWindowType = typeof(EditorWindow).Assembly.GetType("UnityEditor.NavMeshEditorWindow");
if (navigationWindowType != null)
{
var navigationWindow = EditorWindow.GetWindow(navigationWindowType, false, "Navigation");
if (navigationWindow != null)
{
// Close the Navigation window
navigationWindow.Close();
}
}
}
// Configure Main Camera to look at the Environment.
// Necessary because the user may create a new Scena and save over SampleScene in T1, using the Main Camer'as default config instead of the one we want, as set in SampleScene.
// 10/30/2024 AI-Tag
// This was created with assistance from Muse, a Unity Artificial Intelligence product
// Edited to use the mainCamera GameObject defined above for UseMainCamera()
public void ConfigureMainCamera()
{
if (mainCamera == null)
{
mainCamera = FindGameObjectByName("Main Camera");
}
if (mainCamera != null)
{
// Set the Transform Position and Rotation
mainCamera.transform.position = new Vector3(-18.0f, 26.0f, 0.0f);
mainCamera.transform.rotation = Quaternion.Euler(56f, 90f, 0f);
// Access the Camera component
Camera mainCameraCam = mainCamera.GetComponent<Camera>();
if (mainCamera != null)
{
// Basic Camera Settings
mainCameraCam.clearFlags = CameraClearFlags.Skybox;
mainCameraCam.backgroundColor = new Color(0.192f, 0.302f, 0.475f, 0.000f);
mainCameraCam.orthographic = false;
mainCameraCam.fieldOfView = 60f;
mainCameraCam.nearClipPlane = 0.3f;
mainCameraCam.farClipPlane = 1000f;
mainCameraCam.depth = -1;
mainCameraCam.allowHDR = true;
mainCameraCam.allowMSAA = true;
mainCameraCam.allowDynamicResolution = false;
mainCameraCam.useOcclusionCulling = true;
mainCameraCam.stereoConvergence = 10f;
mainCameraCam.stereoSeparation = 0.022f;
}
}
else
{
Debug.LogError("Main Camera GameObject not found!");
}
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: ff5e94a8a2536fc44ab893994b3be3c6
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: d134903b5a25c3c408818857f9d9de1b
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,72 @@
.container--tutorial {
border-top-color: rgba(255, 255, 255, 0.05);
background-color: #2E2E2E;
}
#TutorialStepBox1 {
font-size: 18px;
}
#InstructionTitle {
font-size: 16px;
padding-bottom: 10px;
color: #FFFCFC;
}
#InstructionDescription {
font-size: 16px;
}
#lblPageTitle {
font-size: 20px;
color: white;
}
.container {
background-color: #353535;
}
.container--tutorial-actions {
border-color: rgba(0,0,0,0.3);
}
.container--tutorial-link-icon {
border-left-color: #212421;
background-image: resource('GoToDashboard@2x');
-unity-background-scale-mode: scale-to-fit;
}
.container--header-large {
border-color: rgba(255,255,255,0.1);
}
.card {
background-color: #414141;
border-color: #212421;
}
.card:hover {
background-color: #4A4A4A;
}
.container--instruction {
background-color: #414141;
border-bottom-color: rgba(0, 0, 0, 0.4);
}
.container--welcome-dialog-content {
background-color: #2E2E2E;
}
.container--welcome-dialog-actions {
border-color: rgba(0,0,0,0.5);
}
.icon--tutorial-error-checkmark {
background-image: url('/Packages/com.unity.learn.iet-framework/Editor/UI/Images/Icons/ErrorDark.png');
}
.faq-report-icon {
background-image: resource('GoToDashboard@2x');
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 29318b57ddc2f49c0be6aa320f2af055
ScriptedImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 2
userData:
assetBundleName:
assetBundleVariant:
script: {fileID: 12385, guid: 0000000000000000e000000000000000, type: 0}
disableValidation: 0
@@ -0,0 +1,104 @@
.containercard {
background-color: #414141;
border-color: rgba(0,0,0,0.15);
flex-direction: column;
border-top-left-radius: 3px;
border-top-right-radius: 3px;
border-bottom-right-radius: 3px;
border-bottom-left-radius: 3px;
border-width: 1px;
-unity-background-scale-mode: scale-and-crop;
}
#TutorialStepBox1 {
font-size: 18px;
color: #030000;
}
#InstructionTitle {
font-size: 16px;
padding-bottom: 10px;
color: #030000;
}
#InstructionDescription {
font-size: 16px;
color: #030000;
}
#lblPageTitle {
font-size: 20px;
color: black;
}
HyperlinkLabel {
color: #3271AE;
border-bottom-color: #3271AE;
border-bottom-width: 1px;
}
.video-play-button {
background-image: resource("Icons/Animation.Play.png");
}
.video-popup-button {
background-image: resource("Icons/Animation.Play.png");
}
/****************************
* THEME SPECIFIC COLORS
****************************/
.container {
background-color: #DEDDDE;
}
.container--header-large {
border-color: rgba(0,0,0,0.2);
}
.card {
background-color: rgba(255, 255, 255, 0.8);
border-color: rgba(0,0,0,0.15);
}
.card:hover {
background-color: rgba(255, 255, 255, 1);
}
.container--tutorial {
border-top-color: rgba(0, 0, 0, 0.05);
background-color: rgb(225, 225, 225);
}
.container--instruction {
background-color: rgb(255, 255, 255);
border-bottom-color: rgba(0, 0, 0, 0.15);
}
.container--tutorial-actions {
border-color: rgba(0,0,0,0.1);
}
.container--welcome-dialog-content {
background-color: rgb(221, 221, 221);
}
.container--welcome-dialog-actions {
border-color: rgba(0,0,0,0.1);
}
.icon--tutorial-error-checkmark {
background-image: url('/Packages/com.unity.learn.iet-framework/Editor/UI/Images/Icons/ErrorLight.png');
}
.image--instruction-arrow {
background-color: #0089E4;
}
.tutorial-code-sample {
border-color: rgba(0.5,0.5,0.5,0.5);
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: be4179ec15d9d4aa4a487c32c7cb868a
ScriptedImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 2
userData:
assetBundleName:
assetBundleVariant:
script: {fileID: 12385, guid: 0000000000000000e000000000000000, type: 0}
disableValidation: 0
@@ -0,0 +1,36 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 579f019eb5d26450982c6ae506c6c3ff, type: 3}
m_Name: Tutorial Project Settings
m_EditorClassIdentifier:
m_WelcomePage: {fileID: 11400000, guid: d3ec46d7245fb7740bc81ac54e729271, type: 2}
m_InitialScene: {fileID: 102900000, guid: 6888813f2bd9e4521b9b1343abf0c60f, type: 3}
m_InitialCameraSettings:
m_CameraMode: 1
m_FocusMode: 0
m_Orthographic: 0
m_Size: 14.70745
m_Pivot: {x: 1.8053178, y: 4.1376185, z: 0.28587762}
m_Rotation: {x: 0.1678331, y: 0.6847665, z: -0.16669172, w: 0.68930453}
m_FrameObject:
m_SceneGuid:
m_GameObjectGuid:
m_SerializedComponentType:
m_TypeName:
m_ComponentIndex: 0
m_AssetObject: {fileID: 0}
m_Prefab: {fileID: 0}
m_Enabled: 1
m_TutorialStyle: {fileID: 11400000, guid: 524b9915001f74db09a5fb00cbb109ed, type: 2}
m_RestoreAssetsBackupOnTutorialReload: 0
m_ReportUrl: https://discussions.unity.com/c/learn/50?utm_source=nuo-1.0.0&utm_medium=iet
m_AppendDataToReport: 1
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 1b0d13d8b2332614f9d01a217f8223c4
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant: