chunk 1: core gameplay scripts scenes runtime assets
This commit is contained in:
81
Assets/Scripts/Editor/BuildSettingsUpdater.cs
Normal file
81
Assets/Scripts/Editor/BuildSettingsUpdater.cs
Normal file
@@ -0,0 +1,81 @@
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using UnityEditor.SceneManagement;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
public class BuildSettingsUpdater
|
||||
{
|
||||
[UnityEditor.MenuItem("Tools/Update Build Settings with Waiting Scene")]
|
||||
public static void AddWaitingSceneToBuild()
|
||||
{
|
||||
// Get current scenes in build settings
|
||||
List<EditorBuildSettingsScene> scenes = new List<EditorBuildSettingsScene>(EditorBuildSettings.scenes);
|
||||
|
||||
// Path to the waiting scene
|
||||
string waitingScenePath = "Assets/Scenes/WaitingScene.unity";
|
||||
|
||||
// Check if the waiting scene exists in the project
|
||||
if (!System.IO.File.Exists(waitingScenePath))
|
||||
{
|
||||
Debug.LogError("WaitingScene.unity does not exist. Please create it first using Tools/Create Waiting Scene.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if the waiting scene is already in build settings
|
||||
bool alreadyInBuild = scenes.Any(scene => scene.path == waitingScenePath);
|
||||
|
||||
if (!alreadyInBuild)
|
||||
{
|
||||
// Add the waiting scene right after the MenuScene (position 1)
|
||||
int menuSceneIndex = -1;
|
||||
for (int i = 0; i < scenes.Count; i++)
|
||||
{
|
||||
if (scenes[i].path.Contains("MenuScene"))
|
||||
{
|
||||
menuSceneIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (menuSceneIndex >= 0)
|
||||
{
|
||||
scenes.Insert(menuSceneIndex + 1, new EditorBuildSettingsScene(waitingScenePath, true));
|
||||
}
|
||||
else
|
||||
{
|
||||
// If MenuScene not found, add it before Game scene
|
||||
int gameSceneIndex = -1;
|
||||
for (int i = 0; i < scenes.Count; i++)
|
||||
{
|
||||
if (scenes[i].path.Contains("Game"))
|
||||
{
|
||||
gameSceneIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (gameSceneIndex >= 0)
|
||||
{
|
||||
scenes.Insert(gameSceneIndex, new EditorBuildSettingsScene(waitingScenePath, true));
|
||||
}
|
||||
else
|
||||
{
|
||||
// If no Game scene found, add to the end
|
||||
scenes.Add(new EditorBuildSettingsScene(waitingScenePath, true));
|
||||
}
|
||||
}
|
||||
|
||||
// Save changes
|
||||
EditorBuildSettings.scenes = scenes.ToArray();
|
||||
|
||||
Debug.Log("WaitingScene added to build settings.");
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Log("WaitingScene is already in build settings.");
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
2
Assets/Scripts/Editor/BuildSettingsUpdater.cs.meta
Normal file
2
Assets/Scripts/Editor/BuildSettingsUpdater.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6a3e604b59727f135ad7d82878202662
|
||||
73
Assets/Scripts/Editor/DeviceDisplayConfiguratorEditor.cs
Normal file
73
Assets/Scripts/Editor/DeviceDisplayConfiguratorEditor.cs
Normal file
@@ -0,0 +1,73 @@
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using UnityEditorInternal;
|
||||
|
||||
[CustomEditor(typeof(DeviceDisplayConfigurator))]
|
||||
public class DeviceDisplayConfiguratorEditor : UnityEditor.Editor
|
||||
{
|
||||
|
||||
private ReorderableList listDeviceSets;
|
||||
private SerializedProperty disconnectedDeviceProperty;
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
DrawListOfDevices();
|
||||
disconnectedDeviceProperty = serializedObject.FindProperty("disconnectedDeviceSettings");
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
serializedObject.Update();
|
||||
|
||||
EditorGUILayout.LabelField("Device Sets", EditorStyles.boldLabel);
|
||||
listDeviceSets.DoLayoutList();
|
||||
|
||||
EditorGUILayout.PropertyField(disconnectedDeviceProperty);
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
|
||||
void DrawListOfDevices()
|
||||
{
|
||||
listDeviceSets = new ReorderableList(serializedObject, serializedObject.FindProperty("listDeviceSets"), true, true, true, true);
|
||||
|
||||
listDeviceSets.drawHeaderCallback = (Rect rect) => {
|
||||
|
||||
EditorGUI.LabelField(CalculateColumn(rect, 1, 15, 0), "Raw Path Name");
|
||||
EditorGUI.LabelField(CalculateColumn(rect, 2, 15, 0), "Device Display Settings");
|
||||
};
|
||||
|
||||
listDeviceSets.drawElementCallback = (Rect rect, int index, bool isActive, bool isFocused) => {
|
||||
|
||||
var element = listDeviceSets.serializedProperty.GetArrayElementAtIndex(index);
|
||||
|
||||
rect.y += 2;
|
||||
|
||||
EditorGUI.PropertyField(CalculateColumn(rect, 1, 0, 0), element.FindPropertyRelative("deviceRawPath"), GUIContent.none);
|
||||
EditorGUI.PropertyField(CalculateColumn(rect, 2, 10, 10), element.FindPropertyRelative("deviceDisplaySettings"), GUIContent.none);
|
||||
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
Rect CalculateColumn(Rect rect, int columnNumber, float xPadding, float xWidth)
|
||||
{
|
||||
float xPosition = rect.x;
|
||||
switch (columnNumber)
|
||||
{
|
||||
case 1:
|
||||
xPosition = rect.x + xPadding;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
xPosition = rect.x + rect.width/2 + xPadding;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
return new Rect(xPosition, rect.y, rect.width / 2 - xWidth, EditorGUIUtility.singleLineHeight);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3394780836865e8449248f8ede70a004
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
158
Assets/Scripts/Editor/DeviceDisplaySettingsEditor.cs
Normal file
158
Assets/Scripts/Editor/DeviceDisplaySettingsEditor.cs
Normal file
@@ -0,0 +1,158 @@
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using UnityEditorInternal;
|
||||
|
||||
[CustomEditor(typeof(DeviceDisplaySettings))]
|
||||
public class DeviceDisplaySettingsEditor : UnityEditor.Editor
|
||||
{
|
||||
|
||||
private DeviceDisplaySettings deviceDisplaySettings;
|
||||
|
||||
//Display Name
|
||||
public SerializedProperty deviceDisplayNameProperty;
|
||||
|
||||
//Display Color
|
||||
public SerializedProperty deviceDisplayColorProperty;
|
||||
|
||||
//Icons
|
||||
public SerializedProperty deviceHasContextIconsProperty;
|
||||
|
||||
//Icons - Action Buttons
|
||||
public SerializedProperty buttonNorthIconProperty;
|
||||
public SerializedProperty buttonSouthIconProperty;
|
||||
public SerializedProperty buttonWestIconProperty;
|
||||
public SerializedProperty buttonEastIconProperty;
|
||||
|
||||
//Icon - Triggers
|
||||
public SerializedProperty triggerRightFrontIconProperty;
|
||||
public SerializedProperty triggerRightBackIconProperty;
|
||||
public SerializedProperty triggerLeftFrontIconProperty;
|
||||
public SerializedProperty triggerLeftBackIconProperty;
|
||||
|
||||
//Icon - Custom Contexts
|
||||
private ReorderableList customInputContextIconList;
|
||||
|
||||
void OnEnable()
|
||||
{
|
||||
//Display Name
|
||||
deviceDisplayNameProperty = serializedObject.FindProperty("deviceDisplayName");
|
||||
|
||||
//Display Color
|
||||
deviceDisplayColorProperty = serializedObject.FindProperty("deviceDisplayColor");
|
||||
|
||||
//Icons
|
||||
deviceHasContextIconsProperty = serializedObject.FindProperty("deviceHasContextIcons");
|
||||
|
||||
//Icons - Action Buttons
|
||||
buttonNorthIconProperty = serializedObject.FindProperty("buttonNorthIcon");
|
||||
buttonSouthIconProperty = serializedObject.FindProperty("buttonSouthIcon");
|
||||
buttonWestIconProperty = serializedObject.FindProperty("buttonWestIcon");
|
||||
buttonEastIconProperty = serializedObject.FindProperty("buttonEastIcon");
|
||||
|
||||
//Icon - Triggers
|
||||
triggerRightFrontIconProperty = serializedObject.FindProperty("triggerRightFrontIcon");
|
||||
triggerRightBackIconProperty = serializedObject.FindProperty("triggerRightBackIcon");
|
||||
triggerLeftFrontIconProperty = serializedObject.FindProperty("triggerLeftFrontIcon");
|
||||
triggerLeftBackIconProperty = serializedObject.FindProperty("triggerLeftBackIcon");
|
||||
|
||||
DrawCustomContextList();
|
||||
}
|
||||
|
||||
void DrawCustomContextList()
|
||||
{
|
||||
customInputContextIconList = new ReorderableList(serializedObject, serializedObject.FindProperty("customContextIcons"), true, true, true, true);
|
||||
|
||||
customInputContextIconList.drawHeaderCallback = (Rect rect) => {
|
||||
EditorGUI.LabelField(CalculateColumn(rect, 1, 15, 0), "Input Binding String");
|
||||
EditorGUI.LabelField(CalculateColumn(rect, 2, 15, 0), "Display Icon");
|
||||
};
|
||||
|
||||
customInputContextIconList.drawElementCallback = (Rect rect, int index, bool isActive, bool isFocused) => {
|
||||
|
||||
var element = customInputContextIconList.serializedProperty.GetArrayElementAtIndex(index);
|
||||
|
||||
rect.y += 2;
|
||||
|
||||
EditorGUI.PropertyField(CalculateColumn(rect, 1, 0, 0), element.FindPropertyRelative("customInputContextString"), GUIContent.none);
|
||||
EditorGUI.PropertyField(CalculateColumn(rect, 2, 10, 10), element.FindPropertyRelative("customInputContextIcon"), GUIContent.none);
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
|
||||
deviceDisplaySettings = (DeviceDisplaySettings)target;
|
||||
|
||||
serializedObject.Update();
|
||||
|
||||
EditorGUILayout.LabelField("Display Name", EditorStyles.boldLabel);
|
||||
EditorGUILayout.PropertyField(deviceDisplayNameProperty);
|
||||
|
||||
DrawSpaceGUI(2);
|
||||
|
||||
EditorGUILayout.LabelField("Display Color", EditorStyles.boldLabel);
|
||||
EditorGUILayout.PropertyField(deviceDisplayColorProperty);
|
||||
|
||||
DrawSpaceGUI(2);
|
||||
|
||||
EditorGUILayout.LabelField("Icon Settings", EditorStyles.boldLabel);
|
||||
EditorGUILayout.PropertyField(deviceHasContextIconsProperty);
|
||||
|
||||
if(deviceDisplaySettings.deviceHasContextIcons == true)
|
||||
{
|
||||
|
||||
DrawSpaceGUI(3);
|
||||
|
||||
EditorGUILayout.LabelField("Icons - Action Buttons", EditorStyles.boldLabel);
|
||||
EditorGUILayout.PropertyField(buttonNorthIconProperty);
|
||||
EditorGUILayout.PropertyField(buttonSouthIconProperty);
|
||||
EditorGUILayout.PropertyField(buttonWestIconProperty);
|
||||
EditorGUILayout.PropertyField(buttonEastIconProperty);
|
||||
|
||||
DrawSpaceGUI(3);
|
||||
|
||||
EditorGUILayout.LabelField("Icons - Triggers", EditorStyles.boldLabel);
|
||||
EditorGUILayout.PropertyField(triggerRightFrontIconProperty);
|
||||
EditorGUILayout.PropertyField(triggerRightBackIconProperty);
|
||||
EditorGUILayout.PropertyField(triggerLeftFrontIconProperty);
|
||||
EditorGUILayout.PropertyField(triggerLeftBackIconProperty);
|
||||
|
||||
DrawSpaceGUI(3);
|
||||
|
||||
EditorGUILayout.LabelField("Icons - Custom Contexts", EditorStyles.boldLabel);
|
||||
customInputContextIconList.DoLayoutList();
|
||||
}
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
|
||||
}
|
||||
|
||||
void DrawSpaceGUI(int amountOfSpace)
|
||||
{
|
||||
for(int i = 0; i < amountOfSpace; i++)
|
||||
{
|
||||
EditorGUILayout.Space();
|
||||
}
|
||||
}
|
||||
|
||||
Rect CalculateColumn(Rect rect, int columnNumber, float xPadding, float xWidth)
|
||||
{
|
||||
float xPosition = rect.x;
|
||||
switch (columnNumber)
|
||||
{
|
||||
case 1:
|
||||
xPosition = rect.x + xPadding;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
xPosition = rect.x + rect.width/2 + xPadding;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
return new Rect(xPosition, rect.y, rect.width / 2 - xWidth, EditorGUIUtility.singleLineHeight);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
11
Assets/Scripts/Editor/DeviceDisplaySettingsEditor.cs.meta
Normal file
11
Assets/Scripts/Editor/DeviceDisplaySettingsEditor.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3f730e945f15a0743976b5b42a8307ce
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
101
Assets/Scripts/Editor/GameManagerEditor.cs
Normal file
101
Assets/Scripts/Editor/GameManagerEditor.cs
Normal file
@@ -0,0 +1,101 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using UnityEngine.InputSystem;
|
||||
|
||||
//[CustomEditor(typeof(GameManager))]
|
||||
public class GameManagerEditor : UnityEditor.Editor
|
||||
{
|
||||
|
||||
private GameManager gameManager;
|
||||
|
||||
//Game Mode
|
||||
private SerializedProperty currentGameModeProperty;
|
||||
|
||||
//Single Player
|
||||
private SerializedProperty inScenePlayerProperty;
|
||||
private SerializedProperty singlePlayerCameraModeProperty;
|
||||
|
||||
//Local Multiplayer
|
||||
private SerializedProperty playerPrefabProperty;
|
||||
private SerializedProperty numberOfPlayersProperty;
|
||||
private SerializedProperty spawnRingCenterProperty;
|
||||
private SerializedProperty spawnRingRadiusProperty;
|
||||
|
||||
void OnEnable()
|
||||
{
|
||||
|
||||
//Game Mode
|
||||
currentGameModeProperty = serializedObject.FindProperty("currentGameMode");
|
||||
|
||||
//Single Player
|
||||
inScenePlayerProperty = serializedObject.FindProperty("inScenePlayer");
|
||||
singlePlayerCameraModeProperty = serializedObject.FindProperty("singlePlayerCameraMode");
|
||||
|
||||
//Local Multiplayer
|
||||
playerPrefabProperty = serializedObject.FindProperty("playerPrefab");
|
||||
numberOfPlayersProperty = serializedObject.FindProperty("numberOfPlayers");
|
||||
spawnRingCenterProperty = serializedObject.FindProperty("spawnRingCenter");
|
||||
spawnRingRadiusProperty = serializedObject.FindProperty("spawnRingRadius");
|
||||
|
||||
}
|
||||
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
|
||||
gameManager = (GameManager)target;
|
||||
|
||||
serializedObject.Update();
|
||||
|
||||
DrawGameModeGUI();
|
||||
|
||||
DrawSpaceGUI(3);
|
||||
|
||||
EditorGUILayout.LabelField("Initialization Mode Settings", EditorStyles.boldLabel);
|
||||
|
||||
if(gameManager.currentGameMode == GameMode.SinglePlayer)
|
||||
{
|
||||
DrawSinglePlayerGUI();
|
||||
}
|
||||
|
||||
if(gameManager.currentGameMode == GameMode.LocalMultiplayer)
|
||||
{
|
||||
DrawLocalMultiplayerGUI();
|
||||
}
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
|
||||
void DrawGameModeGUI()
|
||||
{
|
||||
EditorGUILayout.LabelField("Game Mode", EditorStyles.boldLabel);
|
||||
EditorGUILayout.PropertyField(currentGameModeProperty);
|
||||
}
|
||||
|
||||
void DrawSinglePlayerGUI()
|
||||
{
|
||||
EditorGUILayout.PropertyField(inScenePlayerProperty);
|
||||
EditorGUILayout.PropertyField(singlePlayerCameraModeProperty);
|
||||
}
|
||||
|
||||
void DrawLocalMultiplayerGUI()
|
||||
{
|
||||
|
||||
EditorGUILayout.PropertyField(playerPrefabProperty);
|
||||
|
||||
EditorGUILayout.PropertyField(numberOfPlayersProperty);
|
||||
|
||||
EditorGUILayout.PropertyField(spawnRingCenterProperty);
|
||||
EditorGUILayout.PropertyField(spawnRingRadiusProperty);
|
||||
}
|
||||
|
||||
void DrawSpaceGUI(int amountOfSpace)
|
||||
{
|
||||
for(int i = 0; i < amountOfSpace; i++)
|
||||
{
|
||||
EditorGUILayout.Space();
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/Editor/GameManagerEditor.cs.meta
Normal file
11
Assets/Scripts/Editor/GameManagerEditor.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f45b0bd15cb9f794db2e1170669f343f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
20
Assets/Scripts/Editor/MediationAdapterDependencies.xml
Normal file
20
Assets/Scripts/Editor/MediationAdapterDependencies.xml
Normal file
@@ -0,0 +1,20 @@
|
||||
<!-- auto-generated. do not modify by hand. -->
|
||||
<dependencies>
|
||||
<androidPackages>
|
||||
<repositories>
|
||||
<repository>https://unity3ddist.jfrog.io/artifactory/unity-mediation-mvn-prod-local/</repository>
|
||||
</repositories>
|
||||
<!-- Mediation Android SDK -->
|
||||
<androidPackage spec="com.unity3d.mediation:mediation-sdk:[1.0,2.0[" mediation-identifier="mediation-sdk" mediation-version="1.0" />
|
||||
<!-- Mediation SDK Android Adapters -->
|
||||
<androidPackage spec="com.unity3d.mediation:unityads-adapter:[1.0,2.0[" mediation-identifier="unityads-adapter" mediation-version="latest" />
|
||||
</androidPackages>
|
||||
<iosPods>
|
||||
<!-- Mediation iOS SDK -->
|
||||
<iosPod name="UnityMediationSdk" version="~> 1.0" source="'https://github.com/Unity-Technologies/unity-mediation-cocoapods-prod.git'" mediation-identifier="mediation-sdk" mediation-version="1.0" />
|
||||
<!-- Mediation Dependency Required For resolution -->
|
||||
<iosPod name="Protobuf" />
|
||||
<!-- Mediation SDK iOS Adapters -->
|
||||
<iosPod name="UnityMediationUnityAdapter" version="" source="'https://github.com/Unity-Technologies/unity-mediation-cocoapods-prod.git'" mediation-identifier="unityads-adapter" mediation-version="latest" />
|
||||
</iosPods>
|
||||
</dependencies>
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5dd64be34b3b22743a1ad9b9770b6f90
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
0
Assets/Scripts/Editor/MenuItem.cs
Normal file
0
Assets/Scripts/Editor/MenuItem.cs
Normal file
2
Assets/Scripts/Editor/MenuItem.cs.meta
Normal file
2
Assets/Scripts/Editor/MenuItem.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 51d97f49686311824acfded63e6bf7ec
|
||||
1966
Assets/Scripts/Editor/OptimizedColliderTool.cs
Normal file
1966
Assets/Scripts/Editor/OptimizedColliderTool.cs
Normal file
File diff suppressed because it is too large
Load Diff
2
Assets/Scripts/Editor/OptimizedColliderTool.cs.meta
Normal file
2
Assets/Scripts/Editor/OptimizedColliderTool.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2f406f2d89aeacb1faa5c06de01f690c
|
||||
706
Assets/Scripts/Editor/WaitingSceneTemplate.cs
Normal file
706
Assets/Scripts/Editor/WaitingSceneTemplate.cs
Normal file
@@ -0,0 +1,706 @@
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using UnityEditor.SceneManagement;
|
||||
using Cinemachine;
|
||||
using TMPro;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
public class WaitingSceneTemplate : EditorWindow
|
||||
{
|
||||
[UnityEditor.MenuItem("Tools/Create Waiting Scene")]
|
||||
public static void CreateWaitingScene()
|
||||
{
|
||||
// Create a new scene
|
||||
var scene = EditorSceneManager.NewScene(NewSceneSetup.EmptyScene, NewSceneMode.Single);
|
||||
|
||||
// Create a basic scene setup
|
||||
CreateSceneSetup();
|
||||
|
||||
// Save the scene
|
||||
EditorSceneManager.SaveScene(scene, "Assets/Scenes/WaitingScene.unity");
|
||||
|
||||
Debug.Log("Waiting Scene created successfully!");
|
||||
}
|
||||
|
||||
private static void CreateSceneSetup()
|
||||
{
|
||||
// Create main camera
|
||||
var mainCamera = new GameObject("MainCamera");
|
||||
var camera = mainCamera.AddComponent<Camera>();
|
||||
mainCamera.tag = "MainCamera";
|
||||
camera.clearFlags = CameraClearFlags.Skybox;
|
||||
mainCamera.transform.position = new Vector3(0, 2, -10);
|
||||
|
||||
// Create Post-processing layer in project if needed
|
||||
CreateLayerIfNeeded("PostProcessing", 8);
|
||||
|
||||
// Ensure Ground layer exists
|
||||
CreateLayerIfNeeded("Ground", 9);
|
||||
|
||||
// Set up cinematic lighting
|
||||
CreateCinematicLighting();
|
||||
|
||||
// Set up atmospheric effects
|
||||
AddAtmosphericEffects();
|
||||
|
||||
// Set up post-processing
|
||||
CreatePostProcessingVolume();
|
||||
|
||||
// Create a dolly track with front viewing positions
|
||||
var dollyTrack = new GameObject("DollyTrack");
|
||||
var path = dollyTrack.AddComponent<CinemachineSmoothPath>();
|
||||
path.m_Waypoints = new CinemachineSmoothPath.Waypoint[5];
|
||||
|
||||
// Set up waypoints for a front-facing path where camera is in front of player
|
||||
// First point - directly in front of player, facing back toward spawn point
|
||||
path.m_Waypoints[0] = new CinemachineSmoothPath.Waypoint {
|
||||
position = new Vector3(0, 1.7f, -15),
|
||||
roll = 0
|
||||
};
|
||||
|
||||
// Second point - farther ahead (closer to beginning)
|
||||
path.m_Waypoints[1] = new CinemachineSmoothPath.Waypoint {
|
||||
position = new Vector3(0, 1.9f, -10),
|
||||
roll = 2 // Slight roll
|
||||
};
|
||||
|
||||
// Third point - far ahead (midway to beginning)
|
||||
path.m_Waypoints[2] = new CinemachineSmoothPath.Waypoint {
|
||||
position = new Vector3(0, 2.1f, -5),
|
||||
roll = -2 // Opposite roll
|
||||
};
|
||||
|
||||
// Fourth point - close to end (near beginning)
|
||||
path.m_Waypoints[3] = new CinemachineSmoothPath.Waypoint {
|
||||
position = new Vector3(0, 2.3f, -2),
|
||||
roll = 3 // More roll
|
||||
};
|
||||
|
||||
// Fifth point - final camera position (at beginning of path)
|
||||
path.m_Waypoints[4] = new CinemachineSmoothPath.Waypoint {
|
||||
position = new Vector3(0, 2.5f, 0),
|
||||
roll = 0 // Level out
|
||||
};
|
||||
|
||||
// Create a dolly camera
|
||||
var dollyCamera = new GameObject("DollyCamera");
|
||||
var virtualCamera = dollyCamera.AddComponent<CinemachineVirtualCamera>();
|
||||
virtualCamera.m_Priority = 10;
|
||||
virtualCamera.m_Lens.FieldOfView = 35; // Narrower FOV for more cinematic effect
|
||||
|
||||
// Add noise for handheld feel
|
||||
var noise = virtualCamera.AddCinemachineComponent<CinemachineBasicMultiChannelPerlin>();
|
||||
noise.m_AmplitudeGain = 0.15f; // Subtle shake
|
||||
noise.m_FrequencyGain = 0.3f;
|
||||
|
||||
// Set up composer for proper framing
|
||||
var composer = virtualCamera.AddCinemachineComponent<CinemachineComposer>();
|
||||
composer.m_TrackedObjectOffset = new Vector3(0, 0.5f, 0);
|
||||
composer.m_LookaheadTime = 0.2f;
|
||||
composer.m_DeadZoneWidth = 0.1f;
|
||||
composer.m_DeadZoneHeight = 0.1f;
|
||||
composer.m_SoftZoneWidth = 0.6f;
|
||||
composer.m_SoftZoneHeight = 0.6f;
|
||||
|
||||
// Set up transposer for smoother camera movement
|
||||
var transposer = virtualCamera.AddCinemachineComponent<CinemachineTransposer>();
|
||||
transposer.m_XDamping = 1f;
|
||||
transposer.m_YDamping = 1f;
|
||||
transposer.m_ZDamping = 1f;
|
||||
|
||||
// Set slight Dutch angle
|
||||
virtualCamera.m_Lens.Dutch = 2f;
|
||||
|
||||
// Add dolly cart
|
||||
var dollyCart = new GameObject("DollyCart");
|
||||
var cart = dollyCart.AddComponent<CinemachineDollyCart>();
|
||||
cart.m_Path = path;
|
||||
cart.m_Speed = 0f; // Initially stopped - will be controlled by script
|
||||
virtualCamera.transform.SetParent(dollyCart.transform);
|
||||
|
||||
// Create corridor-style entrance environment
|
||||
CreateEntranceEnvironment();
|
||||
|
||||
// Create spawn point - positioned for player to face TOWARD camera (changed direction)
|
||||
var spawnPoint = new GameObject("SpawnPoint");
|
||||
spawnPoint.transform.position = new Vector3(0, 0, -20); // Keep position but will make player face opposite direction
|
||||
|
||||
// Create UI canvas
|
||||
var canvas = new GameObject("Canvas", typeof(Canvas), typeof(UnityEngine.UI.CanvasScaler), typeof(UnityEngine.UI.GraphicRaycaster));
|
||||
var canvasComponent = canvas.GetComponent<Canvas>();
|
||||
canvasComponent.renderMode = RenderMode.ScreenSpaceOverlay;
|
||||
|
||||
// Create skip button - properly create UI elements with RectTransform
|
||||
var skipButton = new GameObject("SkipButton", typeof(RectTransform), typeof(UnityEngine.UI.Image));
|
||||
skipButton.transform.SetParent(canvas.transform, false);
|
||||
var buttonComponent = skipButton.AddComponent<UnityEngine.UI.Button>();
|
||||
var buttonRect = skipButton.GetComponent<RectTransform>();
|
||||
buttonRect.anchoredPosition = new Vector2(0, -200);
|
||||
buttonRect.sizeDelta = new Vector2(200, 50);
|
||||
|
||||
var buttonText = new GameObject("Text", typeof(RectTransform));
|
||||
buttonText.transform.SetParent(skipButton.transform, false);
|
||||
var text = buttonText.AddComponent<TMPro.TextMeshProUGUI>();
|
||||
text.text = "Skip";
|
||||
text.fontSize = 24;
|
||||
text.alignment = TMPro.TextAlignmentOptions.Center;
|
||||
var textRect = buttonText.GetComponent<RectTransform>();
|
||||
textRect.anchorMin = Vector2.zero;
|
||||
textRect.anchorMax = Vector2.one;
|
||||
textRect.sizeDelta = Vector2.zero;
|
||||
|
||||
// Create countdown text
|
||||
var countdownText = new GameObject("CountdownText", typeof(RectTransform));
|
||||
countdownText.transform.SetParent(canvas.transform, false);
|
||||
var countdown = countdownText.AddComponent<TMPro.TextMeshProUGUI>();
|
||||
countdown.text = "10";
|
||||
countdown.fontSize = 36;
|
||||
countdown.alignment = TMPro.TextAlignmentOptions.Center;
|
||||
var countdownRect = countdownText.GetComponent<RectTransform>();
|
||||
countdownRect.anchoredPosition = new Vector2(0, 200);
|
||||
countdownRect.sizeDelta = new Vector2(100, 50);
|
||||
|
||||
// Create loading overlay
|
||||
var loadingOverlay = new GameObject("LoadingOverlay", typeof(RectTransform), typeof(UnityEngine.UI.Image));
|
||||
loadingOverlay.transform.SetParent(canvas.transform, false);
|
||||
var loadingImage = loadingOverlay.GetComponent<UnityEngine.UI.Image>();
|
||||
loadingImage.color = new Color(0, 0, 0, 0.8f);
|
||||
var loadingRect = loadingOverlay.GetComponent<RectTransform>();
|
||||
loadingRect.anchorMin = Vector2.zero;
|
||||
loadingRect.anchorMax = Vector2.one;
|
||||
loadingRect.sizeDelta = Vector2.zero;
|
||||
loadingOverlay.SetActive(false);
|
||||
|
||||
// Create waiting scene manager
|
||||
var manager = new GameObject("WaitingSceneManager");
|
||||
var waitingSceneManager = manager.AddComponent<WaitingSceneManager>();
|
||||
waitingSceneManager.spawnPoint = spawnPoint.transform;
|
||||
waitingSceneManager.dollyCart = cart;
|
||||
waitingSceneManager.dollyCamera = virtualCamera;
|
||||
waitingSceneManager.skipButton = buttonComponent;
|
||||
waitingSceneManager.countdownText = countdown;
|
||||
waitingSceneManager.loadingOverlay = loadingOverlay;
|
||||
|
||||
// Setup cinematic lights reference
|
||||
var lights = GameObject.Find("CinematicLighting")?.GetComponentsInChildren<Light>();
|
||||
if (lights != null && lights.Length > 0)
|
||||
{
|
||||
waitingSceneManager.cinematicLights = lights;
|
||||
}
|
||||
|
||||
// Setup atmospheric effects reference
|
||||
var atmosphericEffectsObj = GameObject.Find("AtmosphericEffects");
|
||||
if (atmosphericEffectsObj != null)
|
||||
{
|
||||
// Get all child objects and convert to array
|
||||
int childCount = atmosphericEffectsObj.transform.childCount;
|
||||
var effectsList = new GameObject[childCount];
|
||||
for (int i = 0; i < childCount; i++)
|
||||
{
|
||||
effectsList[i] = atmosphericEffectsObj.transform.GetChild(i).gameObject;
|
||||
}
|
||||
waitingSceneManager.atmosphericEffects = effectsList;
|
||||
}
|
||||
|
||||
// Setup audio references from resources
|
||||
waitingSceneManager.dramaticMusic = Resources.Load<AudioClip>("Sounds/DramaticEntrance");
|
||||
waitingSceneManager.crowdCheering = Resources.Load<AudioClip>("Sounds/CrowdCheering");
|
||||
|
||||
// If sounds aren't found, try to create placeholder sounds
|
||||
if (waitingSceneManager.dramaticMusic == null)
|
||||
{
|
||||
Debug.LogWarning("DramaticEntrance audio clip not found. Create a 'Sounds/DramaticEntrance' audio clip in Resources folder for best experience.");
|
||||
}
|
||||
|
||||
if (waitingSceneManager.crowdCheering == null)
|
||||
{
|
||||
Debug.LogWarning("CrowdCheering audio clip not found. Create a 'Sounds/CrowdCheering' audio clip in Resources folder for best experience.");
|
||||
}
|
||||
}
|
||||
|
||||
private static void CreateCinematicLighting()
|
||||
{
|
||||
// Create a lighting rig parent object
|
||||
var lightingRig = new GameObject("CinematicLighting");
|
||||
|
||||
// Create three-point lighting system for night-time dramatic effect
|
||||
|
||||
// 1. Key Light - main illumination from front-right
|
||||
var keyLight = new GameObject("KeyLight");
|
||||
keyLight.transform.SetParent(lightingRig.transform);
|
||||
var keyLightComponent = keyLight.AddComponent<Light>();
|
||||
keyLightComponent.type = LightType.Spot;
|
||||
keyLightComponent.color = new Color(0.9f, 0.85f, 0.7f); // Warmer for night
|
||||
keyLightComponent.intensity = 2.5f; // Brighter for contrast against dark
|
||||
keyLightComponent.range = 50f;
|
||||
keyLightComponent.spotAngle = 50f; // Narrower for more dramatic shadows
|
||||
keyLightComponent.shadows = LightShadows.Soft;
|
||||
keyLightComponent.shadowStrength = 0.9f; // Stronger shadows
|
||||
keyLight.transform.position = new Vector3(5, 10, -5);
|
||||
keyLight.transform.LookAt(new Vector3(0, 1, -15)); // Look at player's expected walk path
|
||||
|
||||
// 2. Fill Light - softer light from opposite side to reduce shadows
|
||||
var fillLight = new GameObject("FillLight");
|
||||
fillLight.transform.SetParent(lightingRig.transform);
|
||||
var fillLightComponent = fillLight.AddComponent<Light>();
|
||||
fillLightComponent.type = LightType.Spot;
|
||||
fillLightComponent.color = new Color(0.5f, 0.6f, 0.9f); // Cool moonlight-like color
|
||||
fillLightComponent.intensity = 0.8f; // Lower intensity than key
|
||||
fillLightComponent.range = 50f;
|
||||
fillLightComponent.spotAngle = 70f; // Wider angle
|
||||
fillLightComponent.shadows = LightShadows.Soft;
|
||||
fillLightComponent.shadowStrength = 0.5f; // Softer shadows
|
||||
fillLight.transform.position = new Vector3(-8, 8, -10);
|
||||
fillLight.transform.LookAt(new Vector3(0, 1, -15));
|
||||
|
||||
// 3. Rim Light (Back Light) - creates outline/separation
|
||||
var rimLight = new GameObject("RimLight");
|
||||
rimLight.transform.SetParent(lightingRig.transform);
|
||||
var rimLightComponent = rimLight.AddComponent<Light>();
|
||||
rimLightComponent.type = LightType.Spot;
|
||||
rimLightComponent.color = new Color(0.7f, 0.8f, 1f); // Blue-tinted moonlight
|
||||
rimLightComponent.intensity = 2.8f; // Brighter to create rim effect
|
||||
rimLightComponent.range = 40f;
|
||||
rimLightComponent.spotAngle = 40f; // Narrower
|
||||
rimLightComponent.shadows = LightShadows.Hard; // Harder shadows for definition
|
||||
rimLightComponent.shadowStrength = 0.8f;
|
||||
rimLight.transform.position = new Vector3(0, 7, 5); // Behind player's walk path
|
||||
rimLight.transform.LookAt(new Vector3(0, 1, -15));
|
||||
|
||||
// 4. Dramatic Spotlight - for emphasis
|
||||
var spotLight = new GameObject("DramaticSpotlight");
|
||||
spotLight.transform.SetParent(lightingRig.transform);
|
||||
var spotLightComponent = spotLight.AddComponent<Light>();
|
||||
spotLightComponent.type = LightType.Spot;
|
||||
spotLightComponent.color = new Color(1f, 0.9f, 0.7f); // Warm dramatic light
|
||||
spotLightComponent.intensity = 3.5f; // Much brighter for night scene
|
||||
spotLightComponent.range = 30f;
|
||||
spotLightComponent.spotAngle = 25f; // Narrower beam for spotlight effect
|
||||
spotLightComponent.shadows = LightShadows.Soft;
|
||||
spotLightComponent.shadowStrength = 0.9f;
|
||||
spotLight.transform.position = new Vector3(0, 15, -15); // Above player's final position
|
||||
spotLight.transform.LookAt(new Vector3(0, 0, -15));
|
||||
|
||||
// 5. Ambient Floor Light - subtle uplighting
|
||||
var floorLight = new GameObject("FloorLight");
|
||||
floorLight.transform.SetParent(lightingRig.transform);
|
||||
var floorLightComponent = floorLight.AddComponent<Light>();
|
||||
floorLightComponent.type = LightType.Point;
|
||||
floorLightComponent.color = new Color(0.2f, 0.3f, 0.6f); // Blue-ish floor bounce
|
||||
floorLightComponent.intensity = 0.7f; // Subtle but visible
|
||||
floorLightComponent.range = 10f;
|
||||
floorLightComponent.shadows = LightShadows.None; // No shadows for ambient
|
||||
floorLight.transform.position = new Vector3(0, 0.1f, -15); // Just above floor
|
||||
|
||||
// 6. Add accent lights along the path for night-time effect
|
||||
for (int i = -20; i <= 0; i += 10)
|
||||
{
|
||||
// Left accent light
|
||||
var leftAccent = new GameObject($"LeftAccent_{i}");
|
||||
leftAccent.transform.SetParent(lightingRig.transform);
|
||||
var leftAccentLight = leftAccent.AddComponent<Light>();
|
||||
leftAccentLight.type = LightType.Point;
|
||||
leftAccentLight.color = new Color(0.1f, 0.2f, 0.7f); // Blue night light
|
||||
leftAccentLight.intensity = 1.5f;
|
||||
leftAccentLight.range = 8f;
|
||||
leftAccentLight.shadows = LightShadows.Soft;
|
||||
leftAccent.transform.position = new Vector3(-3, 0.5f, i);
|
||||
|
||||
// Right accent light
|
||||
var rightAccent = new GameObject($"RightAccent_{i}");
|
||||
rightAccent.transform.SetParent(lightingRig.transform);
|
||||
var rightAccentLight = rightAccent.AddComponent<Light>();
|
||||
rightAccentLight.type = LightType.Point;
|
||||
rightAccentLight.color = new Color(0.1f, 0.2f, 0.7f); // Blue night light
|
||||
rightAccentLight.intensity = 1.5f;
|
||||
rightAccentLight.range = 8f;
|
||||
rightAccentLight.shadows = LightShadows.Soft;
|
||||
rightAccent.transform.position = new Vector3(3, 0.5f, i);
|
||||
}
|
||||
|
||||
// Configure scene lighting settings for night-time
|
||||
RenderSettings.ambientMode = UnityEngine.Rendering.AmbientMode.Flat;
|
||||
RenderSettings.ambientLight = new Color(0.05f, 0.05f, 0.1f); // Very dark blue ambient for night
|
||||
RenderSettings.ambientIntensity = 0.2f; // Low ambient intensity
|
||||
RenderSettings.fog = true;
|
||||
RenderSettings.fogColor = new Color(0.02f, 0.02f, 0.05f); // Very dark night fog
|
||||
RenderSettings.fogMode = FogMode.Exponential;
|
||||
RenderSettings.fogDensity = 0.03f; // Slightly thicker fog for atmosphere
|
||||
|
||||
// Set night skybox if available
|
||||
Shader skyboxShader = Shader.Find("Skybox/Procedural");
|
||||
if (skyboxShader != null)
|
||||
{
|
||||
Material skyboxMaterial = new Material(skyboxShader);
|
||||
// Darker sky settings
|
||||
skyboxMaterial.SetFloat("_SunSize", 0.05f);
|
||||
skyboxMaterial.SetFloat("_AtmosphereThickness", 0.5f);
|
||||
skyboxMaterial.SetColor("_SkyTint", new Color(0.3f, 0.3f, 0.5f));
|
||||
skyboxMaterial.SetColor("_GroundColor", new Color(0.1f, 0.1f, 0.1f));
|
||||
skyboxMaterial.SetFloat("_Exposure", 0.8f);
|
||||
|
||||
RenderSettings.skybox = skyboxMaterial;
|
||||
}
|
||||
|
||||
Debug.Log("Created night-time cinematic lighting setup");
|
||||
}
|
||||
|
||||
private static void AddAtmosphericEffects()
|
||||
{
|
||||
// Create parent container
|
||||
var atmosphericEffects = new GameObject("AtmosphericEffects");
|
||||
|
||||
// 1. Dust Particles
|
||||
var dustParticles = new GameObject("DustParticles");
|
||||
dustParticles.transform.SetParent(atmosphericEffects.transform);
|
||||
var dustParticleSystem = dustParticles.AddComponent<ParticleSystem>();
|
||||
|
||||
// Configure dust particle system
|
||||
var dustMain = dustParticleSystem.main;
|
||||
dustMain.duration = 5.0f;
|
||||
dustMain.loop = true;
|
||||
dustMain.startLifetime = 8.0f;
|
||||
dustMain.startSpeed = 0.1f;
|
||||
dustMain.startSize = 0.05f;
|
||||
dustMain.maxParticles = 1000;
|
||||
dustMain.simulationSpace = ParticleSystemSimulationSpace.World;
|
||||
|
||||
// Set a default color that works without relying on materials
|
||||
dustMain.startColor = new ParticleSystem.MinMaxGradient(
|
||||
new Color(0.8f, 0.8f, 0.9f, 0.2f),
|
||||
new Color(0.9f, 0.9f, 1f, 0.05f)
|
||||
);
|
||||
|
||||
var dustEmission = dustParticleSystem.emission;
|
||||
dustEmission.rateOverTime = 30;
|
||||
|
||||
var dustShape = dustParticleSystem.shape;
|
||||
dustShape.shapeType = ParticleSystemShapeType.Box;
|
||||
dustShape.scale = new Vector3(10, 5, 30);
|
||||
dustShape.position = new Vector3(0, 2.5f, -10);
|
||||
|
||||
// Add renderer with material that works in all pipelines
|
||||
var dustRenderer = dustParticles.GetComponent<ParticleSystemRenderer>();
|
||||
if (dustRenderer != null)
|
||||
{
|
||||
dustRenderer.renderMode = ParticleSystemRenderMode.Billboard;
|
||||
dustRenderer.material = GetParticleMaterial(new Color(1f, 1f, 1f, 0.5f));
|
||||
}
|
||||
|
||||
dustParticles.transform.position = new Vector3(0, 0, -10);
|
||||
|
||||
// 2. Light Rays
|
||||
var lightRays = new GameObject("LightRays");
|
||||
lightRays.transform.SetParent(atmosphericEffects.transform);
|
||||
var lightRayParticleSystem = lightRays.AddComponent<ParticleSystem>();
|
||||
|
||||
// Configure light ray particle system
|
||||
var lightRayMain = lightRayParticleSystem.main;
|
||||
lightRayMain.duration = 5.0f;
|
||||
lightRayMain.loop = true;
|
||||
lightRayMain.startLifetime = 5.0f;
|
||||
lightRayMain.startSpeed = 0.0f;
|
||||
lightRayMain.startSize = 0.5f;
|
||||
lightRayMain.startColor = new Color(1f, 0.95f, 0.8f, 0.2f); // Warm light rays
|
||||
lightRayMain.maxParticles = 20;
|
||||
|
||||
var lightRayEmission = lightRayParticleSystem.emission;
|
||||
lightRayEmission.rateOverTime = 2;
|
||||
|
||||
var lightRayShape = lightRayParticleSystem.shape;
|
||||
lightRayShape.shapeType = ParticleSystemShapeType.Cone;
|
||||
lightRayShape.angle = 20;
|
||||
|
||||
// Add renderer with material that works in all pipelines
|
||||
var lightRayRenderer = lightRays.GetComponent<ParticleSystemRenderer>();
|
||||
if (lightRayRenderer != null)
|
||||
{
|
||||
lightRayRenderer.renderMode = ParticleSystemRenderMode.Billboard;
|
||||
lightRayRenderer.material = GetParticleMaterial(new Color(1f, 0.95f, 0.8f, 0.3f));
|
||||
}
|
||||
|
||||
lightRays.transform.position = new Vector3(5, 10, -5);
|
||||
lightRays.transform.rotation = Quaternion.Euler(45, -30, 0);
|
||||
|
||||
// 3. Fog Volume
|
||||
var fogVolume = new GameObject("FogVolume");
|
||||
fogVolume.transform.SetParent(atmosphericEffects.transform);
|
||||
var fogParticleSystem = fogVolume.AddComponent<ParticleSystem>();
|
||||
|
||||
// Configure fog particle system
|
||||
var fogMain = fogParticleSystem.main;
|
||||
fogMain.duration = 5.0f;
|
||||
fogMain.loop = true;
|
||||
fogMain.startLifetime = 10.0f;
|
||||
fogMain.startSpeed = 0.05f;
|
||||
fogMain.startSize = 2.0f;
|
||||
fogMain.startColor = new Color(0.1f, 0.1f, 0.2f, 0.1f); // Darker for night-time fog
|
||||
fogMain.maxParticles = 50;
|
||||
|
||||
var fogEmission = fogParticleSystem.emission;
|
||||
fogEmission.rateOverTime = 5;
|
||||
|
||||
var fogShape = fogParticleSystem.shape;
|
||||
fogShape.shapeType = ParticleSystemShapeType.Box;
|
||||
fogShape.scale = new Vector3(10, 0.5f, 30);
|
||||
|
||||
// Add renderer with material that works in all pipelines
|
||||
var fogRenderer = fogVolume.GetComponent<ParticleSystemRenderer>();
|
||||
if (fogRenderer != null)
|
||||
{
|
||||
fogRenderer.renderMode = ParticleSystemRenderMode.Billboard;
|
||||
fogRenderer.material = GetParticleMaterial(new Color(0.1f, 0.1f, 0.2f, 0.1f));
|
||||
}
|
||||
|
||||
fogVolume.transform.position = new Vector3(0, 0.25f, -10);
|
||||
|
||||
Debug.Log("Created atmospheric effects with compatible materials");
|
||||
}
|
||||
|
||||
private static Material GetParticleMaterial(Color color)
|
||||
{
|
||||
Material material = null;
|
||||
|
||||
// Try to find a suitable particle shader first
|
||||
Shader particleShader = Shader.Find("Universal Render Pipeline/Particles/Unlit");
|
||||
|
||||
if (particleShader == null)
|
||||
particleShader = Shader.Find("Particles/Standard Unlit");
|
||||
|
||||
if (particleShader == null)
|
||||
particleShader = Shader.Find("Mobile/Particles/Additive");
|
||||
|
||||
if (particleShader == null)
|
||||
particleShader = Shader.Find("Particles/Additive");
|
||||
|
||||
if (particleShader == null)
|
||||
particleShader = Shader.Find("Universal Render Pipeline/Particles/Unlit");
|
||||
|
||||
// Fallback to a basic shader
|
||||
if (particleShader == null)
|
||||
particleShader = Shader.Find("Unlit/Transparent");
|
||||
|
||||
if (particleShader == null)
|
||||
particleShader = Shader.Find("Sprites/Default");
|
||||
|
||||
// Last resort - try to use any available shader
|
||||
if (particleShader == null && Shader.Find("Standard") != null)
|
||||
particleShader = Shader.Find("Standard");
|
||||
|
||||
if (particleShader != null)
|
||||
{
|
||||
material = new Material(particleShader);
|
||||
material.color = color;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Create a default unlit material if all else fails
|
||||
material = new Material(Shader.Find("Hidden/InternalErrorShader"))
|
||||
{
|
||||
color = color
|
||||
};
|
||||
Debug.LogWarning("Could not find suitable particle shader. Using fallback material.");
|
||||
}
|
||||
|
||||
return material;
|
||||
}
|
||||
|
||||
private static void CreateEntranceEnvironment()
|
||||
{
|
||||
var entranceEnvironment = new GameObject("EntranceEnvironment");
|
||||
|
||||
// Create floor/ground - keep this but make it simpler
|
||||
var ground = GameObject.CreatePrimitive(PrimitiveType.Plane);
|
||||
ground.name = "Ground";
|
||||
ground.transform.SetParent(entranceEnvironment.transform);
|
||||
ground.transform.position = Vector3.zero;
|
||||
ground.transform.localScale = new Vector3(10, 1, 10);
|
||||
|
||||
// Add a more interesting material to the ground with proper shader detection
|
||||
var groundMaterial = GetMaterial(new Color(0.15f, 0.15f, 0.2f)); // Darker floor for night scene
|
||||
if (groundMaterial != null && ground.GetComponent<Renderer>())
|
||||
{
|
||||
ground.GetComponent<Renderer>().material = groundMaterial;
|
||||
}
|
||||
|
||||
// Ensure ground is in the correct layer
|
||||
int groundLayerIndex = LayerMask.NameToLayer("Ground");
|
||||
ground.layer = groundLayerIndex != -1 ? groundLayerIndex : 0;
|
||||
|
||||
// Create a path without side walls
|
||||
var entrancePath = GameObject.CreatePrimitive(PrimitiveType.Cube);
|
||||
entrancePath.name = "EntrancePath";
|
||||
entrancePath.transform.SetParent(entranceEnvironment.transform);
|
||||
entrancePath.transform.position = new Vector3(0, -0.05f, -10);
|
||||
entrancePath.transform.localScale = new Vector3(6, 0.1f, 30);
|
||||
|
||||
// Add material to the entrance path
|
||||
var pathMaterial = GetMaterial(new Color(0.2f, 0.2f, 0.25f)); // Slightly brighter than ground
|
||||
if (pathMaterial != null && entrancePath.GetComponent<Renderer>())
|
||||
{
|
||||
entrancePath.GetComponent<Renderer>().material = pathMaterial;
|
||||
entrancePath.GetComponent<Renderer>().receiveShadows = true;
|
||||
}
|
||||
|
||||
// Ensure entrance path is in Ground layer
|
||||
entrancePath.layer = groundLayerIndex != -1 ? groundLayerIndex : 0;
|
||||
|
||||
// Create subtle markers along the path without obstructing walls
|
||||
for (int i = -25; i <= -5; i += 5)
|
||||
{
|
||||
// Create subtle floor markers instead of pillars
|
||||
var leftMarker = GameObject.CreatePrimitive(PrimitiveType.Cube);
|
||||
leftMarker.name = $"LeftMarker_{i}";
|
||||
leftMarker.transform.SetParent(entranceEnvironment.transform);
|
||||
leftMarker.transform.position = new Vector3(-2.5f, 0.05f, i);
|
||||
leftMarker.transform.localScale = new Vector3(0.5f, 0.02f, 0.5f); // Very thin
|
||||
|
||||
var rightMarker = GameObject.CreatePrimitive(PrimitiveType.Cube);
|
||||
rightMarker.name = $"RightMarker_{i}";
|
||||
rightMarker.transform.SetParent(entranceEnvironment.transform);
|
||||
rightMarker.transform.position = new Vector3(2.5f, 0.05f, i);
|
||||
rightMarker.transform.localScale = new Vector3(0.5f, 0.02f, 0.5f); // Very thin
|
||||
|
||||
// Add subtle glow material
|
||||
var markerMaterial = GetMaterial(new Color(0.3f, 0.4f, 0.9f));
|
||||
|
||||
if (markerMaterial != null)
|
||||
{
|
||||
if (leftMarker.GetComponent<Renderer>())
|
||||
{
|
||||
leftMarker.GetComponent<Renderer>().material = markerMaterial;
|
||||
leftMarker.GetComponent<Renderer>().receiveShadows = true;
|
||||
}
|
||||
|
||||
if (rightMarker.GetComponent<Renderer>())
|
||||
{
|
||||
rightMarker.GetComponent<Renderer>().material = markerMaterial;
|
||||
rightMarker.GetComponent<Renderer>().receiveShadows = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create a subtle end marker (instead of banner)
|
||||
var endMarker = GameObject.CreatePrimitive(PrimitiveType.Cylinder);
|
||||
endMarker.name = "EndMarker";
|
||||
endMarker.transform.SetParent(entranceEnvironment.transform);
|
||||
endMarker.transform.position = new Vector3(0, 0.05f, 0);
|
||||
endMarker.transform.localScale = new Vector3(3f, 0.02f, 3f);
|
||||
endMarker.transform.rotation = Quaternion.Euler(0, 0, 0);
|
||||
|
||||
var endMarkerMaterial = GetMaterial(new Color(0.7f, 0.3f, 0.3f));
|
||||
if (endMarkerMaterial != null && endMarker.GetComponent<Renderer>())
|
||||
{
|
||||
endMarker.GetComponent<Renderer>().material = endMarkerMaterial;
|
||||
}
|
||||
|
||||
Debug.Log("Created minimalist entrance environment without walls");
|
||||
}
|
||||
|
||||
// Helper method to get appropriate material based on current render pipeline
|
||||
private static Material GetMaterial(Color color, float smoothness = 0.3f)
|
||||
{
|
||||
Material material = null;
|
||||
|
||||
// Try URP shader first
|
||||
Shader urpShader = Shader.Find("Universal Render Pipeline/Lit");
|
||||
if (urpShader != null)
|
||||
{
|
||||
material = new Material(urpShader);
|
||||
material.color = color;
|
||||
// URP specific properties
|
||||
material.SetFloat("_Smoothness", smoothness);
|
||||
}
|
||||
// Try HDRP shader
|
||||
else if (Shader.Find("HDRP/Lit") != null)
|
||||
{
|
||||
material = new Material(Shader.Find("HDRP/Lit"));
|
||||
material.color = color;
|
||||
// HDRP specific properties
|
||||
material.SetFloat("_Smoothness", smoothness);
|
||||
}
|
||||
// Try legacy Standard shader
|
||||
else if (Shader.Find("Standard") != null)
|
||||
{
|
||||
material = new Material(Shader.Find("Standard"));
|
||||
material.color = color;
|
||||
material.SetFloat("_Glossiness", smoothness);
|
||||
}
|
||||
// Fallback to built-in Diffuse shader which exists in all Unity versions
|
||||
else if (Shader.Find("Diffuse") != null)
|
||||
{
|
||||
material = new Material(Shader.Find("Diffuse"));
|
||||
material.color = color;
|
||||
}
|
||||
// Last resort fallback - Unlit color
|
||||
else
|
||||
{
|
||||
material = new Material(Shader.Find("Unlit/Color"));
|
||||
material.color = color;
|
||||
}
|
||||
|
||||
return material;
|
||||
}
|
||||
|
||||
// Create post-processing volume for cinematic look
|
||||
private static void CreatePostProcessingVolume()
|
||||
{
|
||||
// Create post-processing volume
|
||||
var ppVolumeObject = new GameObject("Post Process Volume");
|
||||
var postProcessVolume = ppVolumeObject.AddComponent<UnityEngine.Rendering.PostProcessing.PostProcessVolume>();
|
||||
ppVolumeObject.layer = LayerMask.NameToLayer("PostProcessing");
|
||||
|
||||
// If post-processing layer doesn't exist, use Default
|
||||
if (ppVolumeObject.layer == -1)
|
||||
{
|
||||
ppVolumeObject.layer = 0;
|
||||
}
|
||||
|
||||
postProcessVolume.isGlobal = true;
|
||||
postProcessVolume.priority = 1;
|
||||
|
||||
// Create a new profile
|
||||
var profile = ScriptableObject.CreateInstance<UnityEngine.Rendering.PostProcessing.PostProcessProfile>();
|
||||
postProcessVolume.profile = profile;
|
||||
|
||||
// Add post-processing layer to main camera
|
||||
var mainCamera = GameObject.FindGameObjectWithTag("MainCamera");
|
||||
if (mainCamera != null)
|
||||
{
|
||||
var ppLayer = mainCamera.AddComponent<UnityEngine.Rendering.PostProcessing.PostProcessLayer>();
|
||||
ppLayer.volumeLayer = 1 << 0; // Default layer
|
||||
ppLayer.antialiasingMode = UnityEngine.Rendering.PostProcessing.PostProcessLayer.Antialiasing.FastApproximateAntialiasing;
|
||||
}
|
||||
}
|
||||
|
||||
// Helper method to create a layer if it doesn't exist
|
||||
private static void CreateLayerIfNeeded(string layerName, int layerIndex)
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
// Open tag manager
|
||||
SerializedObject tagManager = new SerializedObject(AssetDatabase.LoadAllAssetsAtPath("ProjectSettings/TagManager.asset")[0]);
|
||||
SerializedProperty layersProp = tagManager.FindProperty("layers");
|
||||
|
||||
// Check if layer already exists
|
||||
bool exists = false;
|
||||
for (int i = 0; i < layersProp.arraySize; i++)
|
||||
{
|
||||
SerializedProperty layerProp = layersProp.GetArrayElementAtIndex(i);
|
||||
if (layerProp.stringValue == layerName)
|
||||
{
|
||||
exists = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If layer doesn't exist and layer index is valid, add it
|
||||
if (!exists && layerIndex >= 8 && layerIndex <= 31)
|
||||
{
|
||||
layersProp.GetArrayElementAtIndex(layerIndex).stringValue = layerName;
|
||||
tagManager.ApplyModifiedProperties();
|
||||
Debug.Log($"Layer '{layerName}' created at index {layerIndex}");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
2
Assets/Scripts/Editor/WaitingSceneTemplate.cs.meta
Normal file
2
Assets/Scripts/Editor/WaitingSceneTemplate.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e3ecaf5ab9e99bd2c98a634c72cf672f
|
||||
Reference in New Issue
Block a user