This commit is contained in:
2021-06-13 10:28:03 +02:00
parent eb70603c85
commit df2d24cbd3
7487 changed files with 943244 additions and 0 deletions

View File

@@ -0,0 +1,7 @@
using System.Runtime.CompilerServices;
#if ENABLE_HYBRID_RENDERER_V2 && !HYBRID_0_6_0_OR_NEWER
#error Core SRP 10.0.0 or newer with Hybrid Renderer V2 requires at least version 0.6.0 of com.unity.rendering.hybrid
#endif
[assembly: InternalsVisibleTo("Unity.RenderPipelines.Core.Editor")]

View File

@@ -0,0 +1,119 @@
using UnityEngine;
namespace UnityEngine.Rendering
{
/// <summary>
/// Utility component allowing users to setup many different static camera and cycle through their positions using the Debug Window.
/// </summary>
[HelpURL(Documentation.baseURL + Documentation.version + Documentation.subURL + "Camera-Switcher" + Documentation.endURL)]
public class CameraSwitcher : MonoBehaviour
{
/// <summary>
/// List of target cameras.
/// </summary>
public Camera[] m_Cameras;
private int m_CurrentCameraIndex = -1;
private Camera m_OriginalCamera = null;
private Vector3 m_OriginalCameraPosition;
private Quaternion m_OriginalCameraRotation;
private Camera m_CurrentCamera = null;
GUIContent[] m_CameraNames = null;
int[] m_CameraIndices = null;
DebugUI.EnumField m_DebugEntry;
//saved enum fields for when repainting
int m_DebugEntryEnumIndex;
void OnEnable()
{
m_OriginalCamera = GetComponent<Camera>();
m_CurrentCamera = m_OriginalCamera;
if (m_OriginalCamera == null)
{
Debug.LogError("Camera Switcher needs a Camera component attached");
return;
}
m_CurrentCameraIndex = GetCameraCount() - 1;
m_CameraNames = new GUIContent[GetCameraCount()];
m_CameraIndices = new int[GetCameraCount()];
for (int i = 0; i < m_Cameras.Length; ++i)
{
Camera cam = m_Cameras[i];
if (cam != null)
{
m_CameraNames[i] = new GUIContent(cam.name);
}
else
{
m_CameraNames[i] = new GUIContent("null");
}
m_CameraIndices[i] = i;
}
m_CameraNames[GetCameraCount() - 1] = new GUIContent("Original Camera");
m_CameraIndices[GetCameraCount() - 1] = GetCameraCount() - 1;
m_DebugEntry = new DebugUI.EnumField { displayName = "Camera Switcher", getter = () => m_CurrentCameraIndex, setter = value => SetCameraIndex(value), enumNames = m_CameraNames, enumValues = m_CameraIndices, getIndex = () => m_DebugEntryEnumIndex, setIndex = value => m_DebugEntryEnumIndex = value };
var panel = DebugManager.instance.GetPanel("Camera", true);
panel.children.Add(m_DebugEntry);
}
void OnDisable()
{
if (m_DebugEntry != null && m_DebugEntry.panel != null)
{
var panel = m_DebugEntry.panel;
panel.children.Remove(m_DebugEntry);
}
}
int GetCameraCount()
{
return m_Cameras.Length + 1; // We need +1 for handling the original camera.
}
Camera GetNextCamera()
{
if (m_CurrentCameraIndex == m_Cameras.Length)
return m_OriginalCamera;
else
return m_Cameras[m_CurrentCameraIndex];
}
void SetCameraIndex(int index)
{
if (index > 0 && index < GetCameraCount())
{
m_CurrentCameraIndex = index;
if (m_CurrentCamera == m_OriginalCamera)
{
m_OriginalCameraPosition = m_OriginalCamera.transform.position;
m_OriginalCameraRotation = m_OriginalCamera.transform.rotation;
}
m_CurrentCamera = GetNextCamera();
if (m_CurrentCamera != null)
{
// If we witch back to the original camera, put back the transform in it.
if (m_CurrentCamera == m_OriginalCamera)
{
m_OriginalCamera.transform.position = m_OriginalCameraPosition;
m_OriginalCamera.transform.rotation = m_OriginalCameraRotation;
}
transform.position = m_CurrentCamera.transform.position;
transform.rotation = m_CurrentCamera.transform.rotation;
}
}
}
}
}

View File

@@ -0,0 +1,203 @@
#if ENABLE_INPUT_SYSTEM && ENABLE_INPUT_SYSTEM_PACKAGE
#define USE_INPUT_SYSTEM
using UnityEngine.InputSystem;
#endif
using System.Collections.Generic;
using UnityEngine;
namespace UnityEngine.Rendering
{
/// <summary>
/// Utility Free Camera component.
/// </summary>
[HelpURL(Documentation.baseURL + Documentation.version + Documentation.subURL + "Free-Camera" + Documentation.endURL)]
public class FreeCamera : MonoBehaviour
{
/// <summary>
/// Rotation speed when using a controller.
/// </summary>
public float m_LookSpeedController = 120f;
/// <summary>
/// Rotation speed when using the mouse.
/// </summary>
public float m_LookSpeedMouse = 10.0f;
/// <summary>
/// Movement speed.
/// </summary>
public float m_MoveSpeed = 10.0f;
/// <summary>
/// Value added to the speed when incrementing.
/// </summary>
public float m_MoveSpeedIncrement = 2.5f;
/// <summary>
/// Scale factor of the turbo mode.
/// </summary>
public float m_Turbo = 10.0f;
#if !USE_INPUT_SYSTEM
private static string kMouseX = "Mouse X";
private static string kMouseY = "Mouse Y";
private static string kRightStickX = "Controller Right Stick X";
private static string kRightStickY = "Controller Right Stick Y";
private static string kVertical = "Vertical";
private static string kHorizontal = "Horizontal";
private static string kYAxis = "YAxis";
private static string kSpeedAxis = "Speed Axis";
#endif
#if USE_INPUT_SYSTEM
InputAction lookAction;
InputAction moveAction;
InputAction speedAction;
InputAction fireAction;
InputAction yMoveAction;
#endif
void OnEnable()
{
RegisterInputs();
}
void RegisterInputs()
{
#if USE_INPUT_SYSTEM
var map = new InputActionMap("Free Camera");
lookAction = map.AddAction("look", binding: "<Mouse>/delta");
moveAction = map.AddAction("move", binding: "<Gamepad>/leftStick");
speedAction = map.AddAction("speed", binding: "<Gamepad>/dpad");
yMoveAction = map.AddAction("yMove");
lookAction.AddBinding("<Gamepad>/rightStick").WithProcessor("scaleVector2(x=15, y=15)");
moveAction.AddCompositeBinding("Dpad")
.With("Up", "<Keyboard>/w")
.With("Up", "<Keyboard>/upArrow")
.With("Down", "<Keyboard>/s")
.With("Down", "<Keyboard>/downArrow")
.With("Left", "<Keyboard>/a")
.With("Left", "<Keyboard>/leftArrow")
.With("Right", "<Keyboard>/d")
.With("Right", "<Keyboard>/rightArrow");
speedAction.AddCompositeBinding("Dpad")
.With("Up", "<Keyboard>/home")
.With("Down", "<Keyboard>/end");
yMoveAction.AddCompositeBinding("Dpad")
.With("Up", "<Keyboard>/pageUp")
.With("Down", "<Keyboard>/pageDown")
.With("Up", "<Keyboard>/e")
.With("Down", "<Keyboard>/q")
.With("Up", "<Gamepad>/rightshoulder")
.With("Down", "<Gamepad>/leftshoulder");
moveAction.Enable();
lookAction.Enable();
speedAction.Enable();
fireAction.Enable();
yMoveAction.Enable();
#endif
#if UNITY_EDITOR && !USE_INPUT_SYSTEM
List<InputManagerEntry> inputEntries = new List<InputManagerEntry>();
// Add new bindings
inputEntries.Add(new InputManagerEntry { name = kRightStickX, kind = InputManagerEntry.Kind.Axis, axis = InputManagerEntry.Axis.Fourth, sensitivity = 1.0f, gravity = 1.0f, deadZone = 0.2f });
inputEntries.Add(new InputManagerEntry { name = kRightStickY, kind = InputManagerEntry.Kind.Axis, axis = InputManagerEntry.Axis.Fifth, sensitivity = 1.0f, gravity = 1.0f, deadZone = 0.2f, invert = true });
inputEntries.Add(new InputManagerEntry { name = kYAxis, kind = InputManagerEntry.Kind.KeyOrButton, btnPositive = "page up", altBtnPositive = "joystick button 5", btnNegative = "page down", altBtnNegative = "joystick button 4", gravity = 1000.0f, deadZone = 0.001f, sensitivity = 1000.0f });
inputEntries.Add(new InputManagerEntry { name = kYAxis, kind = InputManagerEntry.Kind.KeyOrButton, btnPositive = "q", btnNegative = "e", gravity = 1000.0f, deadZone = 0.001f, sensitivity = 1000.0f });
inputEntries.Add(new InputManagerEntry { name = kSpeedAxis, kind = InputManagerEntry.Kind.KeyOrButton, btnPositive = "home", btnNegative = "end", gravity = 1000.0f, deadZone = 0.001f, sensitivity = 1000.0f });
inputEntries.Add(new InputManagerEntry { name = kSpeedAxis, kind = InputManagerEntry.Kind.Axis, axis = InputManagerEntry.Axis.Seventh, gravity = 1000.0f, deadZone = 0.001f, sensitivity = 1000.0f });
InputRegistering.RegisterInputs(inputEntries);
#endif
}
float inputRotateAxisX, inputRotateAxisY;
float inputChangeSpeed;
float inputVertical, inputHorizontal, inputYAxis;
bool leftShiftBoost, leftShift, fire1;
void UpdateInputs()
{
inputRotateAxisX = 0.0f;
inputRotateAxisY = 0.0f;
leftShiftBoost = false;
fire1 = false;
#if USE_INPUT_SYSTEM
var lookDelta = lookAction.ReadValue<Vector2>();
inputRotateAxisX = lookDelta.x * m_LookSpeedMouse * Time.deltaTime;
inputRotateAxisY = lookDelta.y * m_LookSpeedMouse * Time.deltaTime;
leftShift = Keyboard.current.leftShiftKey.isPressed;
fire1 = Mouse.current?.leftButton?.isPressed == true || Gamepad.current?.xButton?.isPressed == true;
inputChangeSpeed = speedAction.ReadValue<Vector2>().y;
var moveDelta = moveAction.ReadValue<Vector2>();
inputVertical = moveDelta.y;
inputHorizontal = moveDelta.x;
inputYAxis = yMoveAction.ReadValue<Vector2>().y;
#else
if (Input.GetMouseButton(1))
{
leftShiftBoost = true;
inputRotateAxisX = Input.GetAxis(kMouseX) * m_LookSpeedMouse;
inputRotateAxisY = Input.GetAxis(kMouseY) * m_LookSpeedMouse;
}
inputRotateAxisX += (Input.GetAxis(kRightStickX) * m_LookSpeedController * Time.deltaTime);
inputRotateAxisY += (Input.GetAxis(kRightStickY) * m_LookSpeedController * Time.deltaTime);
leftShift = Input.GetKey(KeyCode.LeftShift);
fire1 = Input.GetAxis("Fire1") > 0.0f;
inputChangeSpeed = Input.GetAxis(kSpeedAxis);
inputVertical = Input.GetAxis(kVertical);
inputHorizontal = Input.GetAxis(kHorizontal);
inputYAxis = Input.GetAxis(kYAxis);
#endif
}
void Update()
{
// If the debug menu is running, we don't want to conflict with its inputs.
if (DebugManager.instance.displayRuntimeUI)
return;
UpdateInputs();
if (inputChangeSpeed != 0.0f)
{
m_MoveSpeed += inputChangeSpeed * m_MoveSpeedIncrement;
if (m_MoveSpeed < m_MoveSpeedIncrement) m_MoveSpeed = m_MoveSpeedIncrement;
}
bool moved = inputRotateAxisX != 0.0f || inputRotateAxisY != 0.0f || inputVertical != 0.0f || inputHorizontal != 0.0f || inputYAxis != 0.0f;
if (moved)
{
float rotationX = transform.localEulerAngles.x;
float newRotationY = transform.localEulerAngles.y + inputRotateAxisX;
// Weird clamping code due to weird Euler angle mapping...
float newRotationX = (rotationX - inputRotateAxisY);
if (rotationX <= 90.0f && newRotationX >= 0.0f)
newRotationX = Mathf.Clamp(newRotationX, 0.0f, 90.0f);
if (rotationX >= 270.0f)
newRotationX = Mathf.Clamp(newRotationX, 270.0f, 360.0f);
transform.localRotation = Quaternion.Euler(newRotationX, newRotationY, transform.localEulerAngles.z);
float moveSpeed = Time.deltaTime * m_MoveSpeed;
if (fire1 || leftShiftBoost && leftShift)
moveSpeed *= m_Turbo;
transform.position += transform.forward * moveSpeed * inputVertical;
transform.position += transform.right * moveSpeed * inputHorizontal;
transform.position += Vector3.up * moveSpeed * inputYAxis;
}
}
}
}

View File

@@ -0,0 +1,47 @@
using System.Collections.Generic;
using UnityEngine.Events;
namespace UnityEngine.Rendering
{
/// <summary>
/// Command Buffer Pool
/// </summary>
public static class CommandBufferPool
{
static ObjectPool<CommandBuffer> s_BufferPool = new ObjectPool<CommandBuffer>(null, x => x.Clear());
/// <summary>
/// Get a new Command Buffer.
/// </summary>
/// <returns></returns>
public static CommandBuffer Get()
{
var cmd = s_BufferPool.Get();
// Set to empty on purpose, does not create profiling markers.
cmd.name = "";
return cmd;
}
/// <summary>
/// Get a new Command Buffer and assign a name to it.
/// Named Command Buffers will add profiling makers implicitly for the buffer execution.
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
public static CommandBuffer Get(string name)
{
var cmd = s_BufferPool.Get();
cmd.name = name;
return cmd;
}
/// <summary>
/// Release a Command Buffer.
/// </summary>
/// <param name="buffer"></param>
public static void Release(CommandBuffer buffer)
{
s_BufferPool.Release(buffer);
}
}
}

View File

@@ -0,0 +1,21 @@
using System;
namespace UnityEngine.Rendering
{
/// <summary>
/// Render Textures clear flag.
/// </summary>
[Flags]
public enum ClearFlag
{
/// <summary>Don't clear.</summary>
None = 0,
/// <summary>Clear the color buffer.</summary>
Color = 1,
/// <summary>Clear the depth buffer.</summary>
Depth = 2,
/// <summary>Clear both color and depth buffers.</summary>
All = Depth | Color
}
}

View File

@@ -0,0 +1,45 @@
namespace UnityEngine.Rendering
{
// Use this class to get a static instance of a component
// Mainly used to have a default instance
/// <summary>
/// Singleton of a Component class.
/// </summary>
/// <typeparam name="TType">Component type.</typeparam>
public static class ComponentSingleton<TType>
where TType : Component
{
static TType s_Instance = null;
/// <summary>
/// Instance of the required component type.
/// </summary>
public static TType instance
{
get
{
if (s_Instance == null)
{
GameObject go = new GameObject("Default " + typeof(TType).Name) { hideFlags = HideFlags.HideAndDontSave };
go.SetActive(false);
s_Instance = go.AddComponent<TType>();
}
return s_Instance;
}
}
/// <summary>
/// Release the component singleton.
/// </summary>
public static void Release()
{
if (s_Instance != null)
{
var go = s_Instance.gameObject;
CoreUtils.Destroy(go);
s_Instance = null;
}
}
}
}

View File

@@ -0,0 +1,269 @@
using System.Collections.Generic;
using Unity.Collections.LowLevel.Unsafe;
namespace UnityEngine.Rendering
{
/// <summary>
/// Constant Buffer management class.
/// </summary>
public class ConstantBuffer
{
static List<ConstantBufferBase> m_RegisteredConstantBuffers = new List<ConstantBufferBase>();
/// <summary>
/// Update the GPU data of the constant buffer and bind it globally.
/// </summary>
/// <typeparam name="CBType">The type of structure representing the constant buffer data.</typeparam>
/// <param name="cmd">Command Buffer used to execute the graphic commands.</param>
/// <param name="data">Input data of the constant buffer.</param>
/// <param name="shaderId">Shader porperty id to bind the constant buffer to.</param>
public static void PushGlobal<CBType>(CommandBuffer cmd, in CBType data, int shaderId) where CBType : struct
{
var cb = ConstantBufferSingleton<CBType>.instance;
cb.UpdateData(cmd, data);
cb.SetGlobal(cmd, shaderId);
}
/// <summary>
/// Update the GPU data of the constant buffer and bind it to a compute shader.
/// </summary>
/// <typeparam name="CBType">The type of structure representing the constant buffer data.</typeparam>
/// <param name="cmd">Command Buffer used to execute the graphic commands.</param>
/// <param name="data">Input data of the constant buffer.</param>
/// <param name="cs">Compute shader to which the constant buffer should be bound.</param>
/// <param name="shaderId">Shader porperty id to bind the constant buffer to.</param>
public static void Push<CBType>(CommandBuffer cmd, in CBType data, ComputeShader cs, int shaderId) where CBType : struct
{
var cb = ConstantBufferSingleton<CBType>.instance;
cb.UpdateData(cmd, data);
cb.Set(cmd, cs, shaderId);
}
/// <summary>
/// Update the GPU data of the constant buffer and bind it to a material.
/// </summary>
/// <typeparam name="CBType">The type of structure representing the constant buffer data.</typeparam>
/// <param name="cmd">Command Buffer used to execute the graphic commands.</param>
/// <param name="data">Input data of the constant buffer.</param>
/// <param name="mat">Material to which the constant buffer should be bound.</param>
/// <param name="shaderId">Shader porperty id to bind the constant buffer to.</param>
public static void Push<CBType>(CommandBuffer cmd, in CBType data, Material mat, int shaderId) where CBType : struct
{
var cb = ConstantBufferSingleton<CBType>.instance;
cb.UpdateData(cmd, data);
cb.Set(mat, shaderId);
}
/// <summary>
/// Update the GPU data of the constant buffer.
/// </summary>
/// <typeparam name="CBType">The type of structure representing the constant buffer data.</typeparam>
/// <param name="cmd">Command Buffer used to execute the graphic commands.</param>
/// <param name="data">Input data of the constant buffer.</param>
public static void UpdateData<CBType>(CommandBuffer cmd, in CBType data) where CBType : struct
{
var cb = ConstantBufferSingleton<CBType>.instance;
cb.UpdateData(cmd, data);
}
/// <summary>
/// Bind the constant buffer globally.
/// </summary>
/// <typeparam name="CBType">The type of structure representing the constant buffer data.</typeparam>
/// <param name="cmd">Command Buffer used to execute the graphic commands.</param>
/// <param name="shaderId">Shader porperty id to bind the constant buffer to.</param>
public static void SetGlobal<CBType>(CommandBuffer cmd, int shaderId) where CBType : struct
{
var cb = ConstantBufferSingleton<CBType>.instance;
cb.SetGlobal(cmd, shaderId);
}
/// <summary>
/// Bind the constant buffer to a compute shader.
/// </summary>
/// <typeparam name="CBType">The type of structure representing the constant buffer data.</typeparam>
/// <param name="cmd">Command Buffer used to execute the graphic commands.</param>
/// <param name="cs">Compute shader to which the constant buffer should be bound.</param>
/// <param name="shaderId">Shader porperty id to bind the constant buffer to.</param>
public static void Set<CBType>(CommandBuffer cmd, ComputeShader cs, int shaderId) where CBType : struct
{
var cb = ConstantBufferSingleton<CBType>.instance;
cb.Set(cmd, cs, shaderId);
}
/// <summary>
/// Bind the constant buffer to a material.
/// </summary>
/// <typeparam name="CBType">The type of structure representing the constant buffer data.</typeparam>
/// <param name="mat">Material to which the constant buffer should be bound.</param>
/// <param name="shaderId">Shader porperty id to bind the constant buffer to.</param>
public static void Set<CBType>(Material mat, int shaderId) where CBType : struct
{
var cb = ConstantBufferSingleton<CBType>.instance;
cb.Set(mat, shaderId);
}
/// <summary>
/// Release all currently allocated singleton constant buffers.
/// This needs to be called before shutting down the application.
/// </summary>
public static void ReleaseAll()
{
foreach (var cb in m_RegisteredConstantBuffers)
cb.Release();
m_RegisteredConstantBuffers.Clear();
}
internal static void Register(ConstantBufferBase cb)
{
m_RegisteredConstantBuffers.Add(cb);
}
}
/// <summary>
/// The base class of Constant Buffer.
/// </summary>
public abstract class ConstantBufferBase
{
/// <summary>
/// Release the constant buffer.
/// </summary>
public abstract void Release();
}
/// <summary>
/// An instance of a constant buffer.
/// </summary>
/// <typeparam name="CBType">The type of structure representing the constant buffer data.</typeparam>
public class ConstantBuffer<CBType> : ConstantBufferBase where CBType : struct
{
// Used to track all global bindings used by this CB type.
HashSet<int> m_GlobalBindings = new HashSet<int>();
// Array is required by the ComputeBuffer SetData API
CBType[] m_Data = new CBType[1];
ComputeBuffer m_GPUConstantBuffer = null;
/// <summary>
/// Constant Buffer constructor.
/// </summary>
public ConstantBuffer()
{
m_GPUConstantBuffer = new ComputeBuffer(1, UnsafeUtility.SizeOf<CBType>(), ComputeBufferType.Constant);
}
/// <summary>
/// Update the GPU data of the constant buffer.
/// </summary>
/// <param name="cmd">Command Buffer used to execute the graphic commands.</param>
/// <param name="data">Input data of the constant buffer.</param>
public void UpdateData(CommandBuffer cmd, in CBType data)
{
m_Data[0] = data;
#if UNITY_2021_1_OR_NEWER
cmd.SetBufferData(m_GPUConstantBuffer, m_Data);
#else
cmd.SetComputeBufferData(m_GPUConstantBuffer, m_Data);
#endif
}
/// <summary>
/// Bind the constant buffer globally.
/// </summary>
/// <param name="cmd">Command Buffer used to execute the graphic commands.</param>
/// <param name="shaderId">Shader porperty id to bind the constant buffer to.</param>
public void SetGlobal(CommandBuffer cmd, int shaderId)
{
m_GlobalBindings.Add(shaderId);
cmd.SetGlobalConstantBuffer(m_GPUConstantBuffer, shaderId, 0, m_GPUConstantBuffer.stride);
}
/// <summary>
/// Bind the constant buffer to a compute shader.
/// </summary>
/// <param name="cmd">Command Buffer used to execute the graphic commands.</param>
/// <param name="cs">Compute shader to which the constant buffer should be bound.</param>
/// <param name="shaderId">Shader porperty id to bind the constant buffer to.</param>
public void Set(CommandBuffer cmd, ComputeShader cs, int shaderId)
{
cmd.SetComputeConstantBufferParam(cs, shaderId, m_GPUConstantBuffer, 0, m_GPUConstantBuffer.stride);
}
/// <summary>
/// Bind the constant buffer to a material.
/// </summary>
/// <param name="mat">Material to which the constant buffer should be bound.</param>
/// <param name="shaderId">Shader porperty id to bind the constant buffer to.</param>
public void Set(Material mat, int shaderId)
{
// This isn't done via command buffer because as long as the buffer itself is not destroyed,
// the binding stays valid. Only the commit of data needs to go through the command buffer.
// We do it here anyway for now to simplify user API.
mat.SetConstantBuffer(shaderId, m_GPUConstantBuffer, 0, m_GPUConstantBuffer.stride);
}
/// <summary>
/// Update the GPU data of the constant buffer and bind it globally.
/// </summary>
/// <param name="cmd">Command Buffer used to execute the graphic commands.</param>
/// <param name="data">Input data of the constant buffer.</param>
/// <param name="shaderId">Shader porperty id to bind the constant buffer to.</param>
public void PushGlobal(CommandBuffer cmd, in CBType data, int shaderId)
{
UpdateData(cmd, data);
SetGlobal(cmd, shaderId);
}
/// <summary>
/// Release the constant buffers.
/// </summary>
public override void Release()
{
// Depending on the device, globally bound buffers can leave stale "valid" shader ids pointing to a destroyed buffer.
// In DX11 it does not cause issues but on Vulkan this will result in skipped drawcalls (even if the buffer is not actually accessed in the shader).
// To avoid this kind of issues, it's good practice to "unbind" all globally bound buffers upon destruction.
foreach (int shaderId in m_GlobalBindings)
Shader.SetGlobalConstantBuffer(shaderId, (ComputeBuffer)null, 0, 0);
m_GlobalBindings.Clear();
CoreUtils.SafeRelease(m_GPUConstantBuffer);
}
}
class ConstantBufferSingleton<CBType> : ConstantBuffer<CBType> where CBType : struct
{
static ConstantBufferSingleton<CBType> s_Instance = null;
internal static ConstantBufferSingleton<CBType> instance
{
get
{
if (s_Instance == null)
{
s_Instance = new ConstantBufferSingleton<CBType>();
ConstantBuffer.Register(s_Instance);
}
return s_Instance;
}
set
{
s_Instance = value;
}
}
public override void Release()
{
base.Release();
s_Instance = null;
}
}
}

View File

@@ -0,0 +1,24 @@
using System;
namespace UnityEngine.Rendering
{
/// <summary>
/// Attribute used to customize UI display.
/// </summary>
[AttributeUsage(AttributeTargets.Field)]
public class DisplayInfoAttribute : Attribute
{
/// <summary>Display name used in UI.</summary>
public string name;
/// <summary>Display order used in UI.</summary>
public int order;
}
/// <summary>
/// Attribute used to customize UI display to allow properties only be visible when "Show Additional Properties" is selected
/// </summary>
[AttributeUsage(AttributeTargets.Field)]
public class AdditionalPropertyAttribute : Attribute
{
}
}

View File

@@ -0,0 +1,488 @@
using System;
using System.Collections.Generic;
using Unity.Collections.LowLevel.Unsafe;
namespace UnityEngine.Rendering
{
/// <summary>
/// Static class with unsafe utility functions.
/// </summary>
public static unsafe class CoreUnsafeUtils
{
/// <summary>
/// Fixed Buffer String Queue class.
/// </summary>
public struct FixedBufferStringQueue
{
byte* m_ReadCursor;
byte* m_WriteCursor;
readonly byte* m_BufferEnd;
readonly byte* m_BufferStart;
readonly int m_BufferLength;
/// <summary>
/// Number of element in the queue.
/// </summary>
public int Count { get; private set; }
/// <summary>
/// Constructor.
/// </summary>
/// <param name="ptr">Buffer pointer.</param>
/// <param name="length">Length of the provided allocated buffer in byte.</param>
public FixedBufferStringQueue(byte* ptr, int length)
{
m_BufferStart = ptr;
m_BufferLength = length;
m_BufferEnd = m_BufferStart + m_BufferLength;
m_ReadCursor = m_BufferStart;
m_WriteCursor = m_BufferStart;
Count = 0;
Clear();
}
/// <summary>
/// Try to push a new element in the queue.
/// </summary>
/// <param name="v">Element to push in the queue.</param>
/// <returns>True if the new element could be pushed in the queue. False if reserved memory was not enough.</returns>
public bool TryPush(string v)
{
var size = v.Length * sizeof(char) + sizeof(int);
if (m_WriteCursor + size >= m_BufferEnd)
return false;
*(int*)m_WriteCursor = v.Length;
m_WriteCursor += sizeof(int);
var charPtr = (char*)m_WriteCursor;
for (int i = 0; i < v.Length; ++i, ++charPtr)
*charPtr = v[i];
m_WriteCursor += sizeof(char) * v.Length;
++Count;
return true;
}
/// <summary>
/// Pop an element of the queue.
/// </summary>
/// <param name="v">Output result string.</param>
/// <returns>True if an element was succesfuly poped.</returns>
public bool TryPop(out string v)
{
var size = *(int*)m_ReadCursor;
if (size != 0)
{
m_ReadCursor += sizeof(int);
v = new string((char*)m_ReadCursor, 0, size);
m_ReadCursor += size * sizeof(char);
return true;
}
v = default;
return false;
}
/// <summary>
/// Clear the queue.
/// </summary>
public void Clear()
{
m_WriteCursor = m_BufferStart;
m_ReadCursor = m_BufferStart;
Count = 0;
UnsafeUtility.MemClear(m_BufferStart, m_BufferLength);
}
}
/// <summary>
/// Key Getter interface.
/// </summary>
/// <typeparam name="TValue">Value</typeparam>
/// <typeparam name="TKey">Key</typeparam>
public interface IKeyGetter<TValue, TKey>
{
/// <summary>Getter</summary>
/// <param name="v">The value</param>
/// <returns>The key</returns>
TKey Get(ref TValue v);
}
internal struct DefaultKeyGetter<T> : IKeyGetter<T, T>
{ public T Get(ref T v) { return v; } }
// Note: this is a workaround needed to circumvent some AOT issues when building for xbox
internal struct UintKeyGetter : IKeyGetter<uint, uint>
{ public uint Get(ref uint v) { return v; } }
/// <summary>
/// Extension method to copy elements of a list into a buffer.
/// </summary>
/// <typeparam name="T">Type of the provided List.</typeparam>
/// <param name="list">Input List.</param>
/// <param name="dest">Destination buffer.</param>
/// <param name="count">Number of elements to copy.</param>
public static void CopyTo<T>(this List<T> list, void* dest, int count)
where T : struct
{
var c = Mathf.Min(count, list.Count);
for (int i = 0; i < c; ++i)
UnsafeUtility.WriteArrayElement<T>(dest, i, list[i]);
}
/// <summary>
/// Extension method to copy elements of an array into a buffer.
/// </summary>
/// <typeparam name="T">Type of the provided array.</typeparam>
/// <param name="list">Input List.</param>
/// <param name="dest">Destination buffer.</param>
/// <param name="count">Number of elements to copy.</param>
public static void CopyTo<T>(this T[] list, void* dest, int count)
where T : struct
{
var c = Mathf.Min(count, list.Length);
for (int i = 0; i < c; ++i)
UnsafeUtility.WriteArrayElement<T>(dest, i, list[i]);
}
/// <summary>
/// Quick Sort
/// </summary>
/// <param name="arr">uint array.</param>
/// <param name="left">Left boundary.</param>
/// <param name="right">Left boundary.</param>
public static unsafe void QuickSort(uint[] arr, int left, int right)
{
fixed(uint* ptr = arr)
CoreUnsafeUtils.QuickSort<uint, uint, UintKeyGetter>(ptr, left, right);
}
/// <summary>
/// Quick sort.
/// </summary>
/// <typeparam name="T">Type to compare.</typeparam>
/// <param name="count">Number of element.</param>
/// <param name="data">Buffer to sort.</param>
public static void QuickSort<T>(int count, void* data)
where T : struct, IComparable<T>
{
QuickSort<T, T, DefaultKeyGetter<T>>(data, 0, count - 1);
}
/// <summary>
/// Quick sort.
/// </summary>
/// <typeparam name="TValue">Value type.</typeparam>
/// <typeparam name="TKey">Key Type.</typeparam>
/// <typeparam name="TGetter">Getter type.</typeparam>
/// <param name="count">Number of element.</param>
/// <param name="data">Data to sort.</param>
public static void QuickSort<TValue, TKey, TGetter>(int count, void* data)
where TKey : struct, IComparable<TKey>
where TValue : struct
where TGetter : struct, IKeyGetter<TValue, TKey>
{
QuickSort<TValue, TKey, TGetter>(data, 0, count - 1);
}
/// <summary>
/// Quick sort.
/// </summary>
/// <typeparam name="TValue">Value type.</typeparam>
/// <typeparam name="TKey">Key Type.</typeparam>
/// <typeparam name="TGetter">Getter type.</typeparam>
/// <param name="data">Data to sort.</param>
/// <param name="left">Left boundary.</param>
/// <param name="right">Right boundary.</param>
public static void QuickSort<TValue, TKey, TGetter>(void* data, int left, int right)
where TKey : struct, IComparable<TKey>
where TValue : struct
where TGetter : struct, IKeyGetter<TValue, TKey>
{
// For Recursion
if (left < right)
{
int pivot = Partition<TValue, TKey, TGetter>(data, left, right);
if (pivot >= 1)
QuickSort<TValue, TKey, TGetter>(data, left, pivot);
if (pivot + 1 < right)
QuickSort<TValue, TKey, TGetter>(data, pivot + 1, right);
}
}
/// <summary>
/// Index of an element in a buffer.
/// </summary>
/// <typeparam name="T">Data type.</typeparam>
/// <param name="data">Data buffer.</param>
/// <param name="count">Number of elements.</param>
/// <param name="v">Element to test against.</param>
/// <returns>The first index of the provided element.</returns>
public static int IndexOf<T>(void* data, int count, T v)
where T : struct, IEquatable<T>
{
for (int i = 0; i < count; ++i)
{
if (UnsafeUtility.ReadArrayElement<T>(data, i).Equals(v))
return i;
}
return -1;
}
/// <summary>
/// Compare hashes of two collections and provide
/// a list of indices <paramref name="removeIndices"/> to remove in <paramref name="oldHashes"/>
/// and a list of indices <paramref name="addIndices"/> to add in <paramref name="newHashes"/>.
///
/// Assumes that <paramref name="newHashes"/> and <paramref name="oldHashes"/> are sorted.
/// </summary>
/// <typeparam name="TOldValue">Old value type.</typeparam>
/// <typeparam name="TOldGetter">Old getter type.</typeparam>
/// <typeparam name="TNewValue">New value type.</typeparam>
/// <typeparam name="TNewGetter">New getter type.</typeparam>
/// <param name="oldHashCount">Number of hashes in <paramref name="oldHashes"/>.</param>
/// <param name="oldHashes">Previous hashes to compare.</param>
/// <param name="newHashCount">Number of hashes in <paramref name="newHashes"/>.</param>
/// <param name="newHashes">New hashes to compare.</param>
/// <param name="addIndices">Indices of element to add in <paramref name="newHashes"/> will be written here.</param>
/// <param name="removeIndices">Indices of element to remove in <paramref name="oldHashes"/> will be written here.</param>
/// <param name="addCount">Number of elements to add will be written here.</param>
/// <param name="remCount">Number of elements to remove will be written here.</param>
/// <returns>The number of operation to perform (<code><paramref name="addCount"/> + <paramref name="remCount"/></code>)</returns>
public static int CompareHashes<TOldValue, TOldGetter, TNewValue, TNewGetter>(
int oldHashCount, void* oldHashes,
int newHashCount, void* newHashes,
// assume that the capacity of indices is >= max(oldHashCount, newHashCount)
int* addIndices, int* removeIndices,
out int addCount, out int remCount
)
where TOldValue : struct
where TNewValue : struct
where TOldGetter : struct, IKeyGetter<TOldValue, Hash128>
where TNewGetter : struct, IKeyGetter<TNewValue, Hash128>
{
var oldGetter = new TOldGetter();
var newGetter = new TNewGetter();
addCount = 0;
remCount = 0;
// Check combined hashes
if (oldHashCount == newHashCount)
{
var oldHash = new Hash128();
var newHash = new Hash128();
CombineHashes<TOldValue, TOldGetter>(oldHashCount, oldHashes, &oldHash);
CombineHashes<TNewValue, TNewGetter>(newHashCount, newHashes, &newHash);
if (oldHash == newHash)
return 0;
}
var numOperations = 0;
var oldI = 0;
var newI = 0;
while (oldI < oldHashCount || newI < newHashCount)
{
// At the end of old array.
if (oldI == oldHashCount)
{
// No more hashes in old array. Add remaining entries from new array.
for (; newI < newHashCount; ++newI)
{
addIndices[addCount++] = newI;
++numOperations;
}
continue;
}
// At end of new array.
if (newI == newHashCount)
{
// No more hashes in old array. Remove remaining entries from old array.
for (; oldI < oldHashCount; ++oldI)
{
removeIndices[remCount++] = oldI;
++numOperations;
}
continue;
}
// Both arrays have data.
var newVal = UnsafeUtility.ReadArrayElement<TNewValue>(newHashes, newI);
var oldVal = UnsafeUtility.ReadArrayElement<TOldValue>(oldHashes, oldI);
var newKey = newGetter.Get(ref newVal);
var oldKey = oldGetter.Get(ref oldVal);
if (newKey == oldKey)
{
// Matching hash, skip.
++newI;
++oldI;
continue;
}
// Both arrays have data, but hashes do not match.
if (newKey < oldKey)
{
// oldIter is the greater hash. Push "add" jobs from the new array until reaching the oldIter hash.
while (newI < newHashCount && newKey < oldKey)
{
addIndices[addCount++] = newI;
++newI;
++numOperations;
newVal = UnsafeUtility.ReadArrayElement<TNewValue>(newHashes, newI);
newKey = newGetter.Get(ref newVal);
}
}
else
{
// newIter is the greater hash. Push "remove" jobs from the old array until reaching the newIter hash.
while (oldI < oldHashCount && oldKey < newKey)
{
removeIndices[remCount++] = oldI;
++numOperations;
++oldI;
}
}
}
return numOperations;
}
/// <summary>
/// Compare hashes.
/// </summary>
/// <param name="oldHashCount">Number of hashes in <paramref name="oldHashes"/>.</param>
/// <param name="oldHashes">Previous hashes to compare.</param>
/// <param name="newHashCount">Number of hashes in <paramref name="newHashes"/>.</param>
/// <param name="newHashes">New hashes to compare.</param>
/// <param name="addIndices">Indices of element to add in <paramref name="newHashes"/> will be written here.</param>
/// <param name="removeIndices">Indices of element to remove in <paramref name="oldHashes"/> will be written here.</param>
/// <param name="addCount">Number of elements to add will be written here.</param>
/// <param name="remCount">Number of elements to remove will be written here.</param>
/// <returns>The number of operation to perform (<code><paramref name="addCount"/> + <paramref name="remCount"/></code>)</returns>
public static int CompareHashes(
int oldHashCount, Hash128* oldHashes,
int newHashCount, Hash128* newHashes,
// assume that the capacity of indices is >= max(oldHashCount, newHashCount)
int* addIndices, int* removeIndices,
out int addCount, out int remCount
)
{
return CompareHashes<Hash128, DefaultKeyGetter<Hash128>, Hash128, DefaultKeyGetter<Hash128>>(
oldHashCount, oldHashes,
newHashCount, newHashes,
addIndices, removeIndices,
out addCount, out remCount
);
}
/// <summary>Combine all of the hashes of a collection of hashes.</summary>
/// <typeparam name="TValue">Value type.</typeparam>
/// <typeparam name="TGetter">Getter type.</typeparam>
/// <param name="count">Number of hash to combine.</param>
/// <param name="hashes">Hashes to combine.</param>
/// <param name="outHash">Hash to update.</param>
public static void CombineHashes<TValue, TGetter>(int count, void* hashes, Hash128* outHash)
where TValue : struct
where TGetter : struct, IKeyGetter<TValue, Hash128>
{
var getter = new TGetter();
for (int i = 0; i < count; ++i)
{
var v = UnsafeUtility.ReadArrayElement<TValue>(hashes, i);
var h = getter.Get(ref v);
HashUtilities.AppendHash(ref h, ref *outHash);
}
}
/// <summary>
/// Combine hashes.
/// </summary>
/// <param name="count">Number of hash to combine.</param>
/// <param name="hashes">Hashes to combine.</param>
/// <param name="outHash">Hash to update.</param>
public static void CombineHashes(int count, Hash128* hashes, Hash128* outHash)
{
CombineHashes<Hash128, DefaultKeyGetter<Hash128>>(count, hashes, outHash);
}
// Just a sort function that doesn't allocate memory
// Note: Should be replace by a radix sort for positive integer
static int Partition<TValue, TKey, TGetter>(void* data, int left, int right)
where TKey : struct, IComparable<TKey>
where TValue : struct
where TGetter : struct, IKeyGetter<TValue, TKey>
{
var getter = default(TGetter);
var pivotvalue = UnsafeUtility.ReadArrayElement<TValue>(data, left);
var pivot = getter.Get(ref pivotvalue);
--left;
++right;
while (true)
{
var c = 0;
var lvalue = default(TValue);
var lkey = default(TKey);
do
{
++left;
lvalue = UnsafeUtility.ReadArrayElement<TValue>(data, left);
lkey = getter.Get(ref lvalue);
c = lkey.CompareTo(pivot);
}
while (c < 0);
var rvalue = default(TValue);
var rkey = default(TKey);
do
{
--right;
rvalue = UnsafeUtility.ReadArrayElement<TValue>(data, right);
rkey = getter.Get(ref rvalue);
c = rkey.CompareTo(pivot);
}
while (c > 0);
if (left < right)
{
UnsafeUtility.WriteArrayElement(data, right, lvalue);
UnsafeUtility.WriteArrayElement(data, left, rvalue);
}
else
{
return right;
}
}
}
/// <summary>
/// Checks for duplicates in an array.
/// </summary>
/// <param name="arr">Input array.</param>
/// <returns>True if there is any duplicate in the input array.</returns>
public static unsafe bool HaveDuplicates(int[] arr)
{
int* copy = stackalloc int[arr.Length];
arr.CopyTo<int>(copy, arr.Length);
QuickSort<int>(arr.Length, copy);
for (int i = arr.Length - 1; i > 0; --i)
{
if (UnsafeUtility.ReadArrayElement<int>(copy, i).CompareTo(UnsafeUtility.ReadArrayElement<int>(copy, i - 1)) == 0)
{
return true;
}
}
return false;
}
}
}

View File

@@ -0,0 +1,115 @@
using System;
namespace UnityEngine.Rendering
{
/// <summary>
/// Generic growable array.
/// </summary>
/// <typeparam name="T">Type of the array.</typeparam>
public class DynamicArray<T> where T : new()
{
T[] m_Array = null;
/// <summary>
/// Number of elements in the array.
/// </summary>
public int size { get; private set; }
/// <summary>
/// Allocated size of the array.
/// </summary>
public int capacity { get { return m_Array.Length; } }
/// <summary>
/// Constructor.
/// Defaults to a size of 32 elements.
/// </summary>
public DynamicArray()
{
m_Array = new T[32];
size = 0;
}
/// <summary>
/// Constructor
/// </summary>
/// <param name="size">Number of elements.</param>
public DynamicArray(int size)
{
m_Array = new T[size];
this.size = size;
}
/// <summary>
/// Clear the array of all elements.
/// </summary>
public void Clear()
{
size = 0;
}
/// <summary>
/// Add an element to the array.
/// </summary>
/// <param name="value">Element to add to the array.</param>
/// <returns>The index of the element.</returns>
public int Add(in T value)
{
int index = size;
// Grow array if needed;
if (index >= m_Array.Length)
{
var newArray = new T[m_Array.Length * 2];
Array.Copy(m_Array, newArray, m_Array.Length);
m_Array = newArray;
}
m_Array[index] = value;
size++;
return index;
}
/// <summary>
/// Resize the Dynamic Array.
/// This will reallocate memory if necessary and set the current size of the array to the provided size.
/// </summary>
/// <param name="newSize">New size for the array.</param>
/// <param name="keepContent">Set to true if you want the current content of the array to be kept.</param>
public void Resize(int newSize, bool keepContent = false)
{
if (newSize > m_Array.Length)
{
if (keepContent)
{
var newArray = new T[newSize];
Array.Copy(m_Array, newArray, m_Array.Length);
m_Array = newArray;
}
else
{
m_Array = new T[newSize];
}
}
size = newSize;
}
/// <summary>
/// ref access to an element.
/// </summary>
/// <param name="index">Element index</param>
/// <returns>The requested element.</returns>
public ref T this[int index]
{
get
{
#if DEVELOPMENT_BUILD || UNITY_EDITOR
if (index >= size)
throw new IndexOutOfRangeException();
#endif
return ref m_Array[index];
}
}
}
}

View File

@@ -0,0 +1,440 @@
using System;
using System.Collections.Generic;
namespace UnityEngine.Rendering
{
/// <summary>
/// The format of the delegate used to perofrm dynamic resolution.
/// </summary>
public delegate float PerformDynamicRes();
/// <summary>
/// The type of dynamic resolution scaler. It essentially defines what the output of the scaler is expected to be.
/// </summary>
public enum DynamicResScalePolicyType
{
/// <summary>
/// If is the option, DynamicResolutionHandler expects the scaler to return a screen percentage.
/// The value set will be clamped between the minimum and maximum percentage set in the GlobalDynamicResolutionSettings.
/// </summary>
ReturnsPercentage,
/// <summary>
/// If is the option, DynamicResolutionHandler expects the scaler to return a factor t in the [0..1] such that the final resolution percentage
/// is determined by lerp(minimumPercentage, maximumPercentage, t), where the minimum and maximum percentages are the one set in the GlobalDynamicResolutionSettings.
/// </summary>
ReturnsMinMaxLerpFactor
}
/// <summary>
/// The class responsible to handle dynamic resolution.
/// </summary>
public class DynamicResolutionHandler
{
private bool m_Enabled;
private float m_MinScreenFraction;
private float m_MaxScreenFraction;
private float m_CurrentFraction;
private bool m_ForcingRes;
private bool m_CurrentCameraRequest;
private float m_PrevFraction;
private bool m_ForceSoftwareFallback;
private float m_PrevHWScaleWidth;
private float m_PrevHWScaleHeight;
private Vector2Int m_LastScaledSize;
private void Reset()
{
m_Enabled = false;
m_MinScreenFraction = 1.0f;
m_MaxScreenFraction = 1.0f;
m_CurrentFraction = 1.0f;
m_ForcingRes = false;
m_CurrentCameraRequest = true;
m_PrevFraction = -1.0f;
m_ForceSoftwareFallback = false;
m_PrevHWScaleWidth = 1.0f;
m_PrevHWScaleHeight = 1.0f;
m_LastScaledSize = new Vector2Int(0, 0);
filter = DynamicResUpscaleFilter.Bilinear;
}
private static DynamicResScalePolicyType s_ScalerType = DynamicResScalePolicyType.ReturnsMinMaxLerpFactor;
private static PerformDynamicRes s_DynamicResMethod = DefaultDynamicResMethod;
// Debug
private Vector2Int cachedOriginalSize;
/// <summary>
/// The filter that is used to upscale the rendering result to the native resolution.
/// </summary>
public DynamicResUpscaleFilter filter { get; set; }
/// <summary>
/// The viewport of the final buffer. This is likely the resolution the dynamic resolution starts from before any scaling. Note this is NOT the target resolution the rendering will happen in
/// but the resolution the scaled rendered result will be upscaled to.
/// </summary>
public Vector2Int finalViewport { get; set; }
private DynamicResolutionType type;
private GlobalDynamicResolutionSettings m_CachedSettings = GlobalDynamicResolutionSettings.NewDefault();
private const int CameraDictionaryMaxcCapacity = 32;
private WeakReference m_OwnerCameraWeakRef = null;
private static Dictionary<int, DynamicResolutionHandler> s_CameraInstances = new Dictionary<int, DynamicResolutionHandler>(CameraDictionaryMaxcCapacity);
private static DynamicResolutionHandler s_DefaultInstance = new DynamicResolutionHandler();
private static int s_ActiveCameraId = 0;
private static DynamicResolutionHandler s_ActiveInstance = s_DefaultInstance;
//private global state of ScalableBufferManager
private static bool s_ActiveInstanceDirty = true;
private static float s_GlobalHwFraction = 1.0f;
private static bool s_GlobalHwUpresActive = false;
private bool FlushScalableBufferManagerState()
{
if (s_GlobalHwUpresActive == HardwareDynamicResIsEnabled() && s_GlobalHwFraction == m_CurrentFraction)
return false;
s_GlobalHwUpresActive = HardwareDynamicResIsEnabled();
s_GlobalHwFraction = m_CurrentFraction;
ScalableBufferManager.ResizeBuffers(s_GlobalHwFraction, s_GlobalHwFraction);
return true;
}
private static DynamicResolutionHandler GetOrCreateDrsInstanceHandler(Camera camera)
{
if (camera == null)
return null;
DynamicResolutionHandler instance = null;
var key = camera.GetInstanceID();
if (!s_CameraInstances.TryGetValue(key, out instance))
{
//if this camera is not available in the map of cameras lets try creating one.
//first and foremost, if we exceed the dictionary capacity, lets try and recycle an object that is dead.
if (s_CameraInstances.Count >= CameraDictionaryMaxcCapacity)
{
int recycledInstanceKey = 0;
DynamicResolutionHandler recycledInstance = null;
foreach (var kv in s_CameraInstances)
{
//is this object dead? that is, belongs to a camera that was destroyed?
if (kv.Value.m_OwnerCameraWeakRef == null || !kv.Value.m_OwnerCameraWeakRef.IsAlive)
{
recycledInstance = kv.Value;
recycledInstanceKey = kv.Key;
break;
}
}
if (recycledInstance != null)
{
instance = recycledInstance;
s_CameraInstances.Remove(recycledInstanceKey);
}
}
//if we didnt find a dead object, we create one from scratch.
if (instance == null)
{
instance = new DynamicResolutionHandler();
instance.m_OwnerCameraWeakRef = new WeakReference(camera);
}
else
{
//otherwise, we found a dead object, lets reset it, and have a weak ref to this camera,
//so we can possibly recycle it in the future by checking the camera's weak pointer state.
instance.Reset();
instance.m_OwnerCameraWeakRef.Target = camera;
}
s_CameraInstances.Add(key, instance);
}
return instance;
}
/// <summary>
/// Get the instance of the global dynamic resolution handler.
/// </summary>
public static DynamicResolutionHandler instance { get { return s_ActiveInstance; } }
private DynamicResolutionHandler()
{
Reset();
}
// TODO: Eventually we will need to provide a good default implementation for this.
static private float DefaultDynamicResMethod()
{
return 1.0f;
}
private void ProcessSettings(GlobalDynamicResolutionSettings settings)
{
m_Enabled = settings.enabled && (Application.isPlaying || settings.forceResolution);
if (!m_Enabled)
{
m_CurrentFraction = 1.0f;
}
else
{
type = settings.dynResType;
float minScreenFrac = Mathf.Clamp(settings.minPercentage / 100.0f, 0.1f, 1.0f);
m_MinScreenFraction = minScreenFrac;
float maxScreenFrac = Mathf.Clamp(settings.maxPercentage / 100.0f, m_MinScreenFraction, 3.0f);
m_MaxScreenFraction = maxScreenFrac;
filter = settings.upsampleFilter;
m_ForcingRes = settings.forceResolution;
if (m_ForcingRes)
{
float fraction = Mathf.Clamp(settings.forcedPercentage / 100.0f, 0.1f, 1.5f);
m_CurrentFraction = fraction;
}
}
m_CachedSettings = settings;
}
public Vector2 GetResolvedScale()
{
if (!m_Enabled || !m_CurrentCameraRequest)
{
return new Vector2(1.0f, 1.0f);
}
float scaleFractionX = m_CurrentFraction;
float scaleFractionY = m_CurrentFraction;
if (!m_ForceSoftwareFallback && type == DynamicResolutionType.Hardware)
{
scaleFractionX = ScalableBufferManager.widthScaleFactor;
scaleFractionY = ScalableBufferManager.heightScaleFactor;
}
return new Vector2(scaleFractionX, scaleFractionY);
}
/// <summary>
/// Set the scaler method used to drive dynamic resolution.
/// </summary>
/// <param name="scaler">The delegate used to determine the resolution percentage used by the dynamic resolution system.</param>
/// <param name="scalerType">The type of scaler that is used, this is used to indicate the return type of the scaler to the dynamic resolution system.</param>
static public void SetDynamicResScaler(PerformDynamicRes scaler, DynamicResScalePolicyType scalerType = DynamicResScalePolicyType.ReturnsMinMaxLerpFactor)
{
s_ScalerType = scalerType;
s_DynamicResMethod = scaler;
}
/// <summary>
/// Will clear the currently used camera. Use this function to restore the default instance when UpdateAndUseCamera is called.
/// </summary>
public static void ClearSelectedCamera()
{
s_ActiveInstance = s_DefaultInstance;
s_ActiveCameraId = 0;
s_ActiveInstanceDirty = true;
}
/// <summary>
/// Set whether the camera that is currently processed by the pipeline has requested dynamic resolution or not.
/// </summary>
/// <param name="cameraRequest">Determines whether the camera has requested dynamic resolution or not.</param>
public void SetCurrentCameraRequest(bool cameraRequest)
{
m_CurrentCameraRequest = cameraRequest;
}
/// <summary>
/// Update the state of the dynamic resolution system for a specific camera.
/// Call this function also to switch context between cameras (will set the current camera as active).
// Passing a null camera has the same effect as calling Update without the camera parameter.
/// </summary>
/// <param name="camera">Camera used to select a specific instance tied to this DynamicResolutionHandler instance.
/// </param>
/// <param name="settings">(optional) The settings that are to be used by the dynamic resolution system. passing null for the settings will result in the last update's settings used.</param>
/// <param name="OnResolutionChange">An action that will be called every time the dynamic resolution system triggers a change in resolution.</param>
public static void UpdateAndUseCamera(Camera camera, GlobalDynamicResolutionSettings? settings = null, Action OnResolutionChange = null)
{
int newCameraId;
if (camera == null)
{
s_ActiveInstance = s_DefaultInstance;
newCameraId = 0;
}
else
{
s_ActiveInstance = GetOrCreateDrsInstanceHandler(camera);
newCameraId = camera.GetInstanceID();
}
s_ActiveInstanceDirty = newCameraId != s_ActiveCameraId;
s_ActiveCameraId = newCameraId;
s_ActiveInstance.Update(settings.HasValue ? settings.Value : s_ActiveInstance.m_CachedSettings, OnResolutionChange);
}
/// <summary>
/// Update the state of the dynamic resolution system.
/// </summary>
/// <param name="settings">The settings that are to be used by the dynamic resolution system.</param>
/// <param name="OnResolutionChange">An action that will be called every time the dynamic resolution system triggers a change in resolution.</param>
public void Update(GlobalDynamicResolutionSettings settings, Action OnResolutionChange = null)
{
ProcessSettings(settings);
if (!m_Enabled && !s_ActiveInstanceDirty)
{
s_ActiveInstanceDirty = false;
return;
}
if (!m_ForcingRes)
{
if (s_ScalerType == DynamicResScalePolicyType.ReturnsMinMaxLerpFactor)
{
float currLerp = s_DynamicResMethod();
float lerpFactor = Mathf.Clamp(currLerp, 0.0f, 1.0f);
m_CurrentFraction = Mathf.Lerp(m_MinScreenFraction, m_MaxScreenFraction, lerpFactor);
}
else if (s_ScalerType == DynamicResScalePolicyType.ReturnsPercentage)
{
float percentageRequested = Mathf.Max(s_DynamicResMethod(), 5.0f);
m_CurrentFraction = Mathf.Clamp(percentageRequested / 100.0f, m_MinScreenFraction, m_MaxScreenFraction);
}
}
bool hardwareResolutionChanged = false;
bool softwareResolutionChanged = m_CurrentFraction != m_PrevFraction;
m_PrevFraction = m_CurrentFraction;
if (!m_ForceSoftwareFallback && type == DynamicResolutionType.Hardware)
{
hardwareResolutionChanged = FlushScalableBufferManagerState();
if (ScalableBufferManager.widthScaleFactor != m_PrevHWScaleWidth ||
ScalableBufferManager.heightScaleFactor != m_PrevHWScaleHeight)
{
hardwareResolutionChanged = true;
}
}
if ((softwareResolutionChanged || hardwareResolutionChanged) && OnResolutionChange != null)
OnResolutionChange();
s_ActiveInstanceDirty = false;
m_PrevHWScaleWidth = ScalableBufferManager.widthScaleFactor;
m_PrevHWScaleHeight = ScalableBufferManager.heightScaleFactor;
}
/// <summary>
/// Determines whether software dynamic resolution is enabled or not.
/// </summary>
/// <returns>True: Software dynamic resolution is enabled</returns>
public bool SoftwareDynamicResIsEnabled()
{
return m_CurrentCameraRequest && m_Enabled && m_CurrentFraction != 1.0f && (m_ForceSoftwareFallback || type == DynamicResolutionType.Software);
}
/// <summary>
/// Determines whether hardware dynamic resolution is enabled or not.
/// </summary>
/// <returns>True: Hardware dynamic resolution is enabled</returns>
public bool HardwareDynamicResIsEnabled()
{
return !m_ForceSoftwareFallback && m_CurrentCameraRequest && m_Enabled && type == DynamicResolutionType.Hardware;
}
/// <summary>
/// Identifies whether hardware dynamic resolution has been requested and is going to be used.
/// </summary>
/// <returns>True: Hardware dynamic resolution is requested by user and software fallback has not been forced</returns>
public bool RequestsHardwareDynamicResolution()
{
if (m_ForceSoftwareFallback)
return false;
return type == DynamicResolutionType.Hardware;
}
/// <summary>
/// Identifies whether dynamic resolution is enabled and scaling the render targets.
/// </summary>
/// <returns>True: Dynamic resolution is enabled.</returns>
public bool DynamicResolutionEnabled()
{
return m_CurrentCameraRequest && m_Enabled && m_CurrentFraction != 1.0f;
}
/// <summary>
/// Forces software fallback for dynamic resolution. Needs to be called in case Hardware dynamic resolution is requested by the user, but not supported by the platform.
/// </summary>
public void ForceSoftwareFallback()
{
m_ForceSoftwareFallback = true;
}
/// <summary>
/// Applies to the passed size the scale imposed by the dynamic resolution system.
/// Note: this function has the side effect of caching the last scale size.
/// </summary>
/// <param name="size">The starting size of the render target that will be scaled by dynamic resolution.</param>
/// <returns>The parameter size scaled by the dynamic resolution system.</returns>
public Vector2Int GetScaledSize(Vector2Int size)
{
cachedOriginalSize = size;
if (!m_Enabled || !m_CurrentCameraRequest)
{
return size;
}
Vector2Int scaledSize = ApplyScalesOnSize(size);
m_LastScaledSize = scaledSize;
return scaledSize;
}
/// <summary>
/// Applies to the passed size the scale imposed by the dynamic resolution system.
/// Note: this function is pure (has no side effects), this function does not cache the pre-scale size
/// </summary>
/// <param name="size">The size to apply the scaling</param>
/// <returns>The parameter size scaled by the dynamic resolution system.</returns>
public Vector2Int ApplyScalesOnSize(Vector2Int size)
{
Vector2 resolvedScales = GetResolvedScale();
Vector2Int scaledSize = new Vector2Int(Mathf.CeilToInt(size.x * resolvedScales.x), Mathf.CeilToInt(size.y * resolvedScales.y));
if (m_ForceSoftwareFallback || type != DynamicResolutionType.Hardware)
{
scaledSize.x += (1 & scaledSize.x);
scaledSize.y += (1 & scaledSize.y);
}
return scaledSize;
}
/// <summary>
/// Returns the scale that is currently applied by the dynamic resolution system.
/// </summary>
/// <returns>The scale that is currently applied by the dynamic resolution system.</returns>
public float GetCurrentScale()
{
return (m_Enabled && m_CurrentCameraRequest) ? m_CurrentFraction : 1.0f;
}
/// <summary>
/// Returns the latest scaled size that has been produced by GetScaledSize.
/// </summary>
/// <returns>The latest scaled size that has been produced by GetScaledSize.</returns>
public Vector2Int GetLastScaledSize()
{
return m_LastScaledSize;
}
}
}

View File

@@ -0,0 +1,77 @@
using System;
namespace UnityEngine.Rendering
{
/// <summary>
/// Types of dynamic resolution that can be requested. Note that if Hardware is selected, but not available on the platform, the system will fallback to Software.
/// </summary>
public enum DynamicResolutionType : byte
{
/// <summary>
/// Software dynamic resolution.
/// </summary>
Software,
/// <summary>
/// Hardware dynamic resolution.
/// </summary>
Hardware,
}
/// <summary>
/// Types of filters that can be used to upscale rendered result to native resolution.
/// </summary>
public enum DynamicResUpscaleFilter : byte
{
/// <summary>
/// Bilinear upscaling filter.
/// </summary>
Bilinear,
/// <summary>
/// Bicubic Catmull-Rom upscaling filter.
/// </summary>
CatmullRom,
/// <summary>
/// Lanczos upscaling filter.
/// </summary>
Lanczos,
/// <summary>
/// Contrast Adaptive Sharpening upscaling filter.
/// </summary>
ContrastAdaptiveSharpen,
}
/// <summary>User-facing settings for dynamic resolution.</summary>
[Serializable]
public struct GlobalDynamicResolutionSettings
{
/// <summary>Default GlobalDynamicResolutionSettings</summary>
/// <returns></returns>
public static GlobalDynamicResolutionSettings NewDefault() => new GlobalDynamicResolutionSettings()
{
maxPercentage = 100.0f,
minPercentage = 100.0f,
// It fall-backs to software when not supported, so it makes sense to have it on by default.
dynResType = DynamicResolutionType.Hardware,
upsampleFilter = DynamicResUpscaleFilter.CatmullRom,
forcedPercentage = 100.0f
};
/// <summary>Select whether the dynamic resolution is enabled or not.</summary>
public bool enabled;
/// <summary>The maximum resolution percentage that dynamic resolution can reach.</summary>
public float maxPercentage;
/// <summary>The minimum resolution percentage that dynamic resolution can reach.</summary>
public float minPercentage;
/// <summary>The type of dynamic resolution method.</summary>
public DynamicResolutionType dynResType;
/// <summary>The type of upscaling filter to use.</summary>
public DynamicResUpscaleFilter upsampleFilter;
/// <summary>Select whether dynamic resolution system will force a specific resolution percentage.</summary>
public bool forceResolution;
/// <summary>The resolution percentage forced in case forceResolution is set to true.</summary>
public float forcedPercentage;
}
}

View File

@@ -0,0 +1,13 @@
namespace UnityEngine.Rendering
{
/// <summary>
/// By implementing this interface, a render pipeline can indicate to external code it supports virtual texturing.
/// </summary>
public interface IVirtualTexturingEnabledRenderPipeline
{
/// <summary>
/// Indicates if virtual texturing is currently enabled for this render pipeline instance.
/// </summary>
bool virtualTexturingEnabled { get; }
}
}

View File

@@ -0,0 +1,163 @@
using System;
using Unity.Collections.LowLevel.Unsafe;
namespace UnityEngine.Rendering
{
/// <summary>
/// A list that stores value on a provided memory buffer.
///
/// Usually use this to have a list on stack allocated memory.
/// </summary>
/// <typeparam name="T">The type of the data stored in the list.</typeparam>
public unsafe struct ListBuffer<T>
where T : unmanaged
{
private T* m_BufferPtr;
private int m_Capacity;
private int* m_CountPtr;
/// <summary>
/// The pointer to the memory storage.
/// </summary>
internal T* BufferPtr => m_BufferPtr;
/// <summary>
/// The number of item in the list.
/// </summary>
public int Count => *m_CountPtr;
/// <summary>
/// The maximum number of item stored in this list.
/// </summary>
public int Capacity => m_Capacity;
/// <summary>
/// Instantiate a new list.
/// </summary>
/// <param name="bufferPtr">The address in memory to store the data.</param>
/// <param name="countPtr">The address in memory to store the number of item of this list..</param>
/// <param name="capacity">The number of <typeparamref name="T"/> that can be stored in the buffer.</param>
public ListBuffer(T* bufferPtr, int* countPtr, int capacity)
{
m_BufferPtr = bufferPtr;
m_Capacity = capacity;
m_CountPtr = countPtr;
}
/// <summary>
/// Get an item from the list.
/// </summary>
/// <param name="index">The index of the item to get.</param>
/// <returns>A reference to the item.</returns>
/// <exception cref="IndexOutOfRangeException">If the index is invalid.</exception>
public ref T this[in int index]
{
get
{
if (index < 0 || index >= Count)
throw new IndexOutOfRangeException(
$"Expected a value between 0 and {Count}, but received {index}.");
return ref m_BufferPtr[index];
}
}
/// <summary>
/// Get an item from the list.
///
/// Safety: index must be inside the bounds of the list.
/// </summary>
/// <param name="index">The index of the item to get.</param>
/// <returns>A reference to the item.</returns>
public unsafe ref T GetUnchecked(in int index) => ref m_BufferPtr[index];
/// <summary>
/// Try to add a value in the list.
/// </summary>
/// <param name="value">A reference to the value to add.</param>
/// <returns>
/// <code>true</code> when the value was added,
/// <code>false</code> when the value was not added because the capacity was reached.
/// </returns>
public bool TryAdd(in T value)
{
if (Count >= m_Capacity)
return false;
m_BufferPtr[Count] = value;
++*m_CountPtr;
return true;
}
/// <summary>
/// Copy the content of this list into another buffer in memory.
///
/// Safety:
/// * The destination must have enough memory to receive the copied data.
/// </summary>
/// <param name="dstBuffer">The destination buffer of the copy operation.</param>
/// <param name="startDstIndex">The index of the first element that will be copied in the destination buffer.</param>
/// <param name="copyCount">The number of item to copy.</param>
public unsafe void CopyTo(T* dstBuffer, int startDstIndex, int copyCount)
{
UnsafeUtility.MemCpy(dstBuffer + startDstIndex, m_BufferPtr,
UnsafeUtility.SizeOf<T>() * copyCount);
}
/// <summary>
/// Try to copy the list into another list.
/// </summary>
/// <param name="other">The destination of the copy.</param>
/// <returns>
/// * <code>true</code> when the copy was performed.
/// * <code>false</code> when the copy was aborted because the destination have a capacity too small.
/// </returns>
public bool TryCopyTo(ListBuffer<T> other)
{
if (other.Count + Count >= other.m_Capacity)
return false;
UnsafeUtility.MemCpy(other.m_BufferPtr + other.Count, m_BufferPtr, UnsafeUtility.SizeOf<T>() * Count);
*other.m_CountPtr += Count;
return true;
}
/// <summary>
/// Try to copy the data from a buffer in this list.
/// </summary>
/// <param name="srcPtr">The pointer of the source memory to copy.</param>
/// <param name="count">The number of item to copy from the source buffer.</param>
/// <returns>
/// * <code>true</code> when the copy was performed.
/// * <code>false</code> when the copy was aborted because the capacity of this list is too small.
/// </returns>
public bool TryCopyFrom(T* srcPtr, int count)
{
if (count + Count > m_Capacity)
return false;
UnsafeUtility.MemCpy(m_BufferPtr + Count, srcPtr, UnsafeUtility.SizeOf<T>() * count);
*m_CountPtr += count;
return true;
}
}
/// <summary>
/// Extensions for <see cref="ListBuffer{T}"/>.
/// </summary>
public static class ListBufferExtensions
{
/// <summary>
/// Perform a quick sort on a <see cref="ListBuffer{T}"/>.
/// </summary>
/// <param name="self">The list to sort.</param>
/// <typeparam name="T">The type of the element in the list.</typeparam>
public static void QuickSort<T>(this ListBuffer<T> self)
where T : unmanaged, IComparable<T>
{
unsafe
{
CoreUnsafeUtils.QuickSort<int>(self.Count, self.BufferPtr);
}
}
}
}

View File

@@ -0,0 +1,263 @@
using System;
using System.Collections.Generic;
using UnityEngine.Events;
namespace UnityEngine.Rendering
{
/// <summary>
/// Generic object pool.
/// </summary>
/// <typeparam name="T">Type of the object pool.</typeparam>
public class ObjectPool<T> where T : new()
{
readonly Stack<T> m_Stack = new Stack<T>();
readonly UnityAction<T> m_ActionOnGet;
readonly UnityAction<T> m_ActionOnRelease;
readonly bool m_CollectionCheck = true;
/// <summary>
/// Number of objects in the pool.
/// </summary>
public int countAll { get; private set; }
/// <summary>
/// Number of active objects in the pool.
/// </summary>
public int countActive { get { return countAll - countInactive; } }
/// <summary>
/// Number of inactive objects in the pool.
/// </summary>
public int countInactive { get { return m_Stack.Count; } }
/// <summary>
/// Constructor.
/// </summary>
/// <param name="actionOnGet">Action on get.</param>
/// <param name="actionOnRelease">Action on release.</param>
/// <param name="collectionCheck">True if collection integrity should be checked.</param>
public ObjectPool(UnityAction<T> actionOnGet, UnityAction<T> actionOnRelease, bool collectionCheck = true)
{
m_ActionOnGet = actionOnGet;
m_ActionOnRelease = actionOnRelease;
m_CollectionCheck = collectionCheck;
}
/// <summary>
/// Get an object from the pool.
/// </summary>
/// <returns>A new object from the pool.</returns>
public T Get()
{
T element;
if (m_Stack.Count == 0)
{
element = new T();
countAll++;
}
else
{
element = m_Stack.Pop();
}
if (m_ActionOnGet != null)
m_ActionOnGet(element);
return element;
}
/// <summary>
/// Pooled object.
/// </summary>
public struct PooledObject : IDisposable
{
readonly T m_ToReturn;
readonly ObjectPool<T> m_Pool;
internal PooledObject(T value, ObjectPool<T> pool)
{
m_ToReturn = value;
m_Pool = pool;
}
/// <summary>
/// Disposable pattern implementation.
/// </summary>
void IDisposable.Dispose() => m_Pool.Release(m_ToReturn);
}
/// <summary>
/// Get et new PooledObject.
/// </summary>
/// <param name="v">Output new typed object.</param>
/// <returns>New PooledObject</returns>
public PooledObject Get(out T v) => new PooledObject(v = Get(), this);
/// <summary>
/// Release an object to the pool.
/// </summary>
/// <param name="element">Object to release.</param>
public void Release(T element)
{
#if UNITY_EDITOR // keep heavy checks in editor
if (m_CollectionCheck && m_Stack.Count > 0)
{
if (m_Stack.Contains(element))
Debug.LogError("Internal error. Trying to destroy object that is already released to pool.");
}
#endif
if (m_ActionOnRelease != null)
m_ActionOnRelease(element);
m_Stack.Push(element);
}
}
/// <summary>
/// Generic pool.
/// </summary>
/// <typeparam name="T">Type of the objects in the pull.</typeparam>
public static class GenericPool<T>
where T : new()
{
// Object pool to avoid allocations.
static readonly ObjectPool<T> s_Pool = new ObjectPool<T>(null, null);
/// <summary>
/// Get a new object.
/// </summary>
/// <returns>A new object from the pool.</returns>
public static T Get() => s_Pool.Get();
/// <summary>
/// Get a new PooledObject
/// </summary>
/// <param name="value">Output typed object.</param>
/// <returns>A new PooledObject.</returns>
public static ObjectPool<T>.PooledObject Get(out T value) => s_Pool.Get(out value);
/// <summary>
/// Release an object to the pool.
/// </summary>
/// <param name="toRelease">Object to release.</param>
public static void Release(T toRelease) => s_Pool.Release(toRelease);
}
/// <summary>
/// Generic pool without collection checks.
/// This class is an alternative for the GenericPool for object that allocate memory when they are being compared.
/// It is the case for the CullingResult class from Unity, and because of this in HDRP HDCullingResults generates garbage whenever we use ==, .Equals or ReferenceEquals.
/// This pool doesn't do any of these comparison because we don't check if the stack already contains the element before releasing it.
/// </summary>
/// <typeparam name="T">Type of the objects in the pull.</typeparam>
public static class UnsafeGenericPool<T>
where T : new()
{
// Object pool to avoid allocations.
static readonly ObjectPool<T> s_Pool = new ObjectPool<T>(null, null, false);
/// <summary>
/// Get a new object.
/// </summary>
/// <returns>A new object from the pool.</returns>
public static T Get() => s_Pool.Get();
/// <summary>
/// Get a new PooledObject
/// </summary>
/// <param name="value">Output typed object.</param>
/// <returns>A new PooledObject.</returns>
public static ObjectPool<T>.PooledObject Get(out T value) => s_Pool.Get(out value);
/// <summary>
/// Release an object to the pool.
/// </summary>
/// <param name="toRelease">Object to release.</param>
public static void Release(T toRelease) => s_Pool.Release(toRelease);
}
/// <summary>
/// List Pool.
/// </summary>
/// <typeparam name="T">Type of the objects in the pooled lists.</typeparam>
public static class ListPool<T>
{
// Object pool to avoid allocations.
static readonly ObjectPool<List<T>> s_Pool = new ObjectPool<List<T>>(null, l => l.Clear());
/// <summary>
/// Get a new List
/// </summary>
/// <returns>A new List</returns>
public static List<T> Get() => s_Pool.Get();
/// <summary>
/// Get a new list PooledObject.
/// </summary>
/// <param name="value">Output typed List.</param>
/// <returns>A new List PooledObject.</returns>
public static ObjectPool<List<T>>.PooledObject Get(out List<T> value) => s_Pool.Get(out value);
/// <summary>
/// Release an object to the pool.
/// </summary>
/// <param name="toRelease">List to release.</param>
public static void Release(List<T> toRelease) => s_Pool.Release(toRelease);
}
/// <summary>
/// HashSet Pool.
/// </summary>
/// <typeparam name="T">Type of the objects in the pooled hashsets.</typeparam>
public static class HashSetPool<T>
{
// Object pool to avoid allocations.
static readonly ObjectPool<HashSet<T>> s_Pool = new ObjectPool<HashSet<T>>(null, l => l.Clear());
/// <summary>
/// Get a new HashSet
/// </summary>
/// <returns>A new HashSet</returns>
public static HashSet<T> Get() => s_Pool.Get();
/// <summary>
/// Get a new list PooledObject.
/// </summary>
/// <param name="value">Output typed HashSet.</param>
/// <returns>A new HashSet PooledObject.</returns>
public static ObjectPool<HashSet<T>>.PooledObject Get(out HashSet<T> value) => s_Pool.Get(out value);
/// <summary>
/// Release an object to the pool.
/// </summary>
/// <param name="toRelease">hashSet to release.</param>
public static void Release(HashSet<T> toRelease) => s_Pool.Release(toRelease);
}
/// <summary>
/// Dictionary Pool.
/// </summary>
/// <typeparam name="TKey">Key type.</typeparam>
/// <typeparam name="TValue">Value type.</typeparam>
public static class DictionaryPool<TKey, TValue>
{
// Object pool to avoid allocations.
static readonly ObjectPool<Dictionary<TKey, TValue>> s_Pool
= new ObjectPool<Dictionary<TKey, TValue>>(null, l => l.Clear());
/// <summary>
/// Get a new Dictionary
/// </summary>
/// <returns>A new Dictionary</returns>
public static Dictionary<TKey, TValue> Get() => s_Pool.Get();
/// <summary>
/// Get a new dictionary PooledObject.
/// </summary>
/// <param name="value">Output typed Dictionary.</param>
/// <returns>A new Dictionary PooledObject.</returns>
public static ObjectPool<Dictionary<TKey, TValue>>.PooledObject Get(out Dictionary<TKey, TValue> value)
=> s_Pool.Get(out value);
/// <summary>
/// Release an object to the pool.
/// </summary>
/// <param name="toRelease">Dictionary to release.</param>
public static void Release(Dictionary<TKey, TValue> toRelease) => s_Pool.Release(toRelease);
}
}

View File

@@ -0,0 +1,252 @@
using System;
using System.Collections;
using System.Collections.Generic;
namespace UnityEngine.Rendering
{
/// <summary>
/// On List Changed Event Args.
/// </summary>
/// <typeparam name="T">List type.</typeparam>
public sealed class ListChangedEventArgs<T> : EventArgs
{
/// <summary>
/// Index
/// </summary>
public readonly int index;
/// <summary>
/// Item
/// </summary>
public readonly T item;
/// <summary>
/// Constructor.
/// </summary>
/// <param name="index">Index</param>
/// <param name="item">Item</param>
public ListChangedEventArgs(int index, T item)
{
this.index = index;
this.item = item;
}
}
/// <summary>
/// List changed event handler.
/// </summary>
/// <typeparam name="T">List type.</typeparam>
/// <param name="sender">Sender.</param>
/// <param name="e">List changed even arguments.</param>
public delegate void ListChangedEventHandler<T>(ObservableList<T> sender, ListChangedEventArgs<T> e);
/// <summary>
/// Observable list.
/// </summary>
/// <typeparam name="T">Type of the list.</typeparam>
public class ObservableList<T> : IList<T>
{
IList<T> m_List;
/// <summary>
/// Added item event.
/// </summary>
public event ListChangedEventHandler<T> ItemAdded;
/// <summary>
/// Removed item event.
/// </summary>
public event ListChangedEventHandler<T> ItemRemoved;
/// <summary>
/// Accessor.
/// </summary>
/// <param name="index">Item index.</param>
/// <returns>The item at the provided index.</returns>
public T this[int index]
{
get { return m_List[index]; }
set
{
OnEvent(ItemRemoved, index, m_List[index]);
m_List[index] = value;
OnEvent(ItemAdded, index, value);
}
}
/// <summary>
/// Number of elements in the list.
/// </summary>
public int Count
{
get { return m_List.Count; }
}
/// <summary>
/// Is the list read only?
/// </summary>
public bool IsReadOnly
{
get { return false; }
}
/// <summary>
/// Default Constructor.
/// </summary>
public ObservableList()
: this(0) {}
/// <summary>
/// Constructor.
/// </summary>
/// <param name="capacity">Allocation size.</param>
public ObservableList(int capacity)
{
m_List = new List<T>(capacity);
}
/// <summary>
/// Constructor.
/// </summary>
/// <param name="collection">Input list.</param>
public ObservableList(IEnumerable<T> collection)
{
m_List = new List<T>(collection);
}
void OnEvent(ListChangedEventHandler<T> e, int index, T item)
{
if (e != null)
e(this, new ListChangedEventArgs<T>(index, item));
}
/// <summary>
/// Check if an element is present in the list.
/// </summary>
/// <param name="item">Item to test against.</param>
/// <returns>True if the item is in the list.</returns>
public bool Contains(T item)
{
return m_List.Contains(item);
}
/// <summary>
/// Get the index of an item.
/// </summary>
/// <param name="item">The object to locate in the list.</param>
/// <returns>The index of the item in the list if it exists, -1 otherwise.</returns>
public int IndexOf(T item)
{
return m_List.IndexOf(item);
}
/// <summary>
/// Add an item to the list.
/// </summary>
/// <param name="item">Item to add to the list.</param>
public void Add(T item)
{
m_List.Add(item);
OnEvent(ItemAdded, m_List.IndexOf(item), item);
}
/// <summary>
/// Add multiple objects to the list.
/// </summary>
/// <param name="items">Items to add to the list.</param>
public void Add(params T[] items)
{
foreach (var i in items)
Add(i);
}
/// <summary>
/// Insert an item in the list.
/// </summary>
/// <param name="index">Index at which to insert the new item.</param>
/// <param name="item">Item to insert in the list.</param>
public void Insert(int index, T item)
{
m_List.Insert(index, item);
OnEvent(ItemAdded, index, item);
}
/// <summary>
/// Remove an item from the list.
/// </summary>
/// <param name="item">Item to remove from the list.</param>
/// <returns>True if the item was successfuly removed. False otherise.</returns>
public bool Remove(T item)
{
int index = m_List.IndexOf(item);
bool ret = m_List.Remove(item);
if (ret)
OnEvent(ItemRemoved, index, item);
return ret;
}
/// <summary>
/// Remove multiple items from the list.
/// </summary>
/// <param name="items">Items to remove from the list.</param>
/// <returns>The number of removed items.</returns>
public int Remove(params T[] items)
{
if (items == null)
return 0;
int count = 0;
foreach (var i in items)
count += Remove(i) ? 1 : 0;
return count;
}
/// <summary>
/// Remove an item at a specific index.
/// </summary>
/// <param name="index">Index of the item to remove.</param>
public void RemoveAt(int index)
{
var item = m_List[index];
m_List.RemoveAt(index);
OnEvent(ItemRemoved, index, item);
}
/// <summary>
/// Clear the list.
/// </summary>
public void Clear()
{
for (int i = 0; i < Count; i++)
RemoveAt(i);
}
/// <summary>
/// Copy items in the list to an array.
/// </summary>
/// <param name="array">Destination array.</param>
/// <param name="arrayIndex">Starting index.</param>
public void CopyTo(T[] array, int arrayIndex)
{
m_List.CopyTo(array, arrayIndex);
}
/// <summary>
/// Get enumerator.
/// </summary>
/// <returns>The list enumerator.</returns>
public IEnumerator<T> GetEnumerator()
{
return m_List.GetEnumerator();
}
/// <summary>
/// Get enumerator.
/// </summary>
/// <returns>The list enumerator.</returns>
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
}

View File

@@ -0,0 +1,54 @@
using System;
using System.Collections.Generic;
namespace UnityEngine.Rendering
{
//
// Unity can't serialize Dictionary so here's a custom wrapper that does. Note that you have to
// extend it before it can be serialized as Unity won't serialized generic-based types either.
//
// Example:
// public sealed class MyDictionary : SerializedDictionary<KeyType, ValueType> {}
//
/// <summary>
/// Serialized Dictionary
/// </summary>
/// <typeparam name="K">Key Type</typeparam>
/// <typeparam name="V">Value Type</typeparam>
[Serializable]
public class SerializedDictionary<K, V> : Dictionary<K, V>, ISerializationCallbackReceiver
{
[SerializeField]
List<K> m_Keys = new List<K>();
[SerializeField]
List<V> m_Values = new List<V>();
/// <summary>
/// OnBeforeSerialize implementation.
/// </summary>
public void OnBeforeSerialize()
{
m_Keys.Clear();
m_Values.Clear();
foreach (var kvp in this)
{
m_Keys.Add(kvp.Key);
m_Values.Add(kvp.Value);
}
}
/// <summary>
/// OnAfterDeserialize implementation.
/// </summary>
public void OnAfterDeserialize()
{
for (int i = 0; i < m_Keys.Count; i++)
Add(m_Keys[i], m_Values[i]);
m_Keys.Clear();
m_Values.Clear();
}
}
}

View File

@@ -0,0 +1,207 @@
using System;
using UnityEditor;
#if ENABLE_VR && ENABLE_VR_MODULE
using UnityEngine.XR;
#endif
namespace UnityEngine.Rendering
{
/// <summary>
/// XRGraphics insulates SRP from API changes across platforms, Editor versions, and as XR transitions into XR SDK
/// </summary>
[Serializable]
public class XRGraphics
{
/// <summary>
/// Stereo Rendering Modes.
/// </summary>
public enum StereoRenderingMode
{
/// <summary>Multi Pass.</summary>
MultiPass = 0,
/// <summary>Single Pass.</summary>
SinglePass,
/// <summary>Single Pass Instanced.</summary>
SinglePassInstanced,
/// <summary>Single Pass Multi View.</summary>
SinglePassMultiView
};
/// <summary>
/// Eye texture resolution scale.
/// </summary>
public static float eyeTextureResolutionScale
{
get
{
#if ENABLE_VR && ENABLE_VR_MODULE
if (enabled)
return XRSettings.eyeTextureResolutionScale;
#endif
return 1.0f;
}
set
{
#if ENABLE_VR && ENABLE_VR_MODULE
XRSettings.eyeTextureResolutionScale = value;
#endif
}
}
/// <summary>
/// Render viewport scale.
/// </summary>
public static float renderViewportScale
{
get
{
#if ENABLE_VR && ENABLE_VR_MODULE
if (enabled)
return XRSettings.renderViewportScale;
#endif
return 1.0f;
}
}
/// <summary>
/// Try enable.
/// </summary>
#if UNITY_EDITOR
// TryEnable gets updated before "play" is pressed- we use this for updating GUI only.
public static bool tryEnable
{
get
{
#if UNITY_2020_1_OR_NEWER
return false;
#else
return UnityEditorInternal.VR.VREditor.GetVREnabledOnTargetGroup(BuildPipeline.GetBuildTargetGroup(EditorUserBuildSettings.activeBuildTarget));
#endif
}
}
#endif
/// <summary>
/// SRP should use this to safely determine whether XR is enabled at runtime.
/// </summary>
public static bool enabled
{
get
{
#if ENABLE_VR && ENABLE_VR_MODULE
return XRSettings.enabled;
#else
return false;
#endif
}
}
/// <summary>
/// Returns true if the XR device is active.
/// </summary>
public static bool isDeviceActive
{
get
{
#if ENABLE_VR && ENABLE_VR_MODULE
if (enabled)
return XRSettings.isDeviceActive;
#endif
return false;
}
}
/// <summary>
/// Name of the loaded XR device.
/// </summary>
public static string loadedDeviceName
{
get
{
#if ENABLE_VR && ENABLE_VR_MODULE
if (enabled)
return XRSettings.loadedDeviceName;
#endif
return "No XR device loaded";
}
}
/// <summary>
/// List of supported XR devices.
/// </summary>
public static string[] supportedDevices
{
get
{
#if ENABLE_VR && ENABLE_VR_MODULE
if (enabled)
return XRSettings.supportedDevices;
#endif
return new string[1];
}
}
/// <summary>
/// Stereo rendering mode.
/// </summary>
public static StereoRenderingMode stereoRenderingMode
{
get
{
#if ENABLE_VR && ENABLE_VR_MODULE
if (enabled)
return (StereoRenderingMode)XRSettings.stereoRenderingMode;
#endif
return StereoRenderingMode.SinglePass;
}
}
/// <summary>
/// Eye texture descriptor.
/// </summary>
public static RenderTextureDescriptor eyeTextureDesc
{
get
{
#if ENABLE_VR && ENABLE_VR_MODULE
if (enabled)
return XRSettings.eyeTextureDesc;
#endif
return new RenderTextureDescriptor(0, 0);
}
}
/// <summary>
/// Eye texture width.
/// </summary>
public static int eyeTextureWidth
{
get
{
#if ENABLE_VR && ENABLE_VR_MODULE
if (enabled)
return XRSettings.eyeTextureWidth;
#endif
return 0;
}
}
/// <summary>
/// Eye texture height.
/// </summary>
public static int eyeTextureHeight
{
get
{
#if ENABLE_VR && ENABLE_VR_MODULE
if (enabled)
return XRSettings.eyeTextureHeight;
#endif
return 0;
}
}
}
}

View File

@@ -0,0 +1,448 @@
#if ENABLE_INPUT_SYSTEM && ENABLE_INPUT_SYSTEM_PACKAGE
#define USE_INPUT_SYSTEM
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
#endif
using System.Collections.Generic;
namespace UnityEngine.Rendering
{
internal enum DebugAction
{
EnableDebugMenu,
PreviousDebugPanel,
NextDebugPanel,
Action,
MakePersistent,
MoveVertical,
MoveHorizontal,
Multiplier,
ResetAll,
DebugActionCount
}
enum DebugActionRepeatMode
{
Never,
Delay
}
public sealed partial class DebugManager
{
const string kEnableDebugBtn1 = "Enable Debug Button 1";
const string kEnableDebugBtn2 = "Enable Debug Button 2";
const string kDebugPreviousBtn = "Debug Previous";
const string kDebugNextBtn = "Debug Next";
const string kValidateBtn = "Debug Validate";
const string kPersistentBtn = "Debug Persistent";
const string kDPadVertical = "Debug Vertical";
const string kDPadHorizontal = "Debug Horizontal";
const string kMultiplierBtn = "Debug Multiplier";
const string kResetBtn = "Debug Reset";
const string kEnableDebug = "Enable Debug";
DebugActionDesc[] m_DebugActions;
DebugActionState[] m_DebugActionStates;
#if USE_INPUT_SYSTEM
InputActionMap debugActionMap = new InputActionMap("Debug Menu");
#endif
void RegisterActions()
{
m_DebugActions = new DebugActionDesc[(int)DebugAction.DebugActionCount];
m_DebugActionStates = new DebugActionState[(int)DebugAction.DebugActionCount];
var enableDebugMenu = new DebugActionDesc();
#if USE_INPUT_SYSTEM
enableDebugMenu.buttonAction = debugActionMap.FindAction(kEnableDebug);
#else
enableDebugMenu.buttonTriggerList.Add(new[] { kEnableDebugBtn1, kEnableDebugBtn2 });
enableDebugMenu.keyTriggerList.Add(new[] { KeyCode.LeftControl, KeyCode.Backspace });
#endif
enableDebugMenu.repeatMode = DebugActionRepeatMode.Never;
AddAction(DebugAction.EnableDebugMenu, enableDebugMenu);
var resetDebugMenu = new DebugActionDesc();
#if USE_INPUT_SYSTEM
resetDebugMenu.buttonAction = debugActionMap.FindAction(kResetBtn);
#else
resetDebugMenu.keyTriggerList.Add(new[] { KeyCode.LeftAlt, KeyCode.Backspace });
resetDebugMenu.buttonTriggerList.Add(new[] { kResetBtn, kEnableDebugBtn2 });
#endif
resetDebugMenu.repeatMode = DebugActionRepeatMode.Never;
AddAction(DebugAction.ResetAll, resetDebugMenu);
var nextDebugPanel = new DebugActionDesc();
#if USE_INPUT_SYSTEM
nextDebugPanel.buttonAction = debugActionMap.FindAction(kDebugNextBtn);
#else
nextDebugPanel.buttonTriggerList.Add(new[] { kDebugNextBtn });
#endif
nextDebugPanel.repeatMode = DebugActionRepeatMode.Never;
AddAction(DebugAction.NextDebugPanel, nextDebugPanel);
var previousDebugPanel = new DebugActionDesc();
#if USE_INPUT_SYSTEM
previousDebugPanel.buttonAction = debugActionMap.FindAction(kDebugPreviousBtn);
#else
previousDebugPanel.buttonTriggerList.Add(new[] { kDebugPreviousBtn });
#endif
previousDebugPanel.repeatMode = DebugActionRepeatMode.Never;
AddAction(DebugAction.PreviousDebugPanel, previousDebugPanel);
var validate = new DebugActionDesc();
#if USE_INPUT_SYSTEM
validate.buttonAction = debugActionMap.FindAction(kValidateBtn);
#else
validate.buttonTriggerList.Add(new[] { kValidateBtn });
#endif
validate.repeatMode = DebugActionRepeatMode.Never;
AddAction(DebugAction.Action, validate);
var persistent = new DebugActionDesc();
#if USE_INPUT_SYSTEM
persistent.buttonAction = debugActionMap.FindAction(kPersistentBtn);
#else
persistent.buttonTriggerList.Add(new[] { kPersistentBtn });
#endif
persistent.repeatMode = DebugActionRepeatMode.Never;
AddAction(DebugAction.MakePersistent, persistent);
var multiplier = new DebugActionDesc();
#if USE_INPUT_SYSTEM
multiplier.buttonAction = debugActionMap.FindAction(kMultiplierBtn);
#else
multiplier.buttonTriggerList.Add(new[] { kMultiplierBtn });
#endif
multiplier.repeatMode = DebugActionRepeatMode.Delay;
validate.repeatDelay = 0f;
AddAction(DebugAction.Multiplier, multiplier);
var moveVertical = new DebugActionDesc();
#if USE_INPUT_SYSTEM
moveVertical.buttonAction = debugActionMap.FindAction(kDPadVertical);
#else
moveVertical.axisTrigger = kDPadVertical;
#endif
moveVertical.repeatMode = DebugActionRepeatMode.Delay;
moveVertical.repeatDelay = 0.16f;
AddAction(DebugAction.MoveVertical, moveVertical);
var moveHorizontal = new DebugActionDesc();
#if USE_INPUT_SYSTEM
moveHorizontal.buttonAction = debugActionMap.FindAction(kDPadHorizontal);
#else
moveHorizontal.axisTrigger = kDPadHorizontal;
#endif
moveHorizontal.repeatMode = DebugActionRepeatMode.Delay;
moveHorizontal.repeatDelay = 0.16f;
AddAction(DebugAction.MoveHorizontal, moveHorizontal);
#if USE_INPUT_SYSTEM
foreach (var action in debugActionMap)
action.Enable();
#endif
}
void AddAction(DebugAction action, DebugActionDesc desc)
{
int index = (int)action;
m_DebugActions[index] = desc;
m_DebugActionStates[index] = new DebugActionState();
}
void SampleAction(int actionIndex)
{
var desc = m_DebugActions[actionIndex];
var state = m_DebugActionStates[actionIndex];
// Disable all input events if we're using the new input system
#if USE_INPUT_SYSTEM
if (state.runningAction == false)
{
if (desc.buttonAction != null)
{
var value = desc.buttonAction.ReadValue<float>();
if (!Mathf.Approximately(value, 0))
state.TriggerWithButton(desc.buttonAction, value);
}
}
#elif ENABLE_LEGACY_INPUT_MANAGER
//bool canSampleAction = (state.actionTriggered == false) || (desc.repeatMode == DebugActionRepeatMode.Delay && state.timer > desc.repeatDelay);
if (state.runningAction == false)
{
// Check button triggers
for (int buttonListIndex = 0; buttonListIndex < desc.buttonTriggerList.Count; ++buttonListIndex)
{
var buttons = desc.buttonTriggerList[buttonListIndex];
bool allButtonPressed = true;
foreach (var button in buttons)
{
allButtonPressed = Input.GetButton(button);
if (!allButtonPressed)
break;
}
if (allButtonPressed)
{
state.TriggerWithButton(buttons, 1f);
break;
}
}
// Check axis triggers
if (desc.axisTrigger != "")
{
float axisValue = Input.GetAxis(desc.axisTrigger);
if (axisValue != 0f)
state.TriggerWithAxis(desc.axisTrigger, axisValue);
}
// Check key triggers
for (int keyListIndex = 0; keyListIndex < desc.keyTriggerList.Count; ++keyListIndex)
{
bool allKeyPressed = true;
var keys = desc.keyTriggerList[keyListIndex];
foreach (var key in keys)
{
allKeyPressed = Input.GetKey(key);
if (!allKeyPressed)
break;
}
if (allKeyPressed)
{
state.TriggerWithKey(keys, 1f);
break;
}
}
}
#endif
}
void UpdateAction(int actionIndex)
{
var desc = m_DebugActions[actionIndex];
var state = m_DebugActionStates[actionIndex];
if (state.runningAction)
state.Update(desc);
}
internal void UpdateActions()
{
for (int actionIndex = 0; actionIndex < m_DebugActions.Length; ++actionIndex)
{
UpdateAction(actionIndex);
SampleAction(actionIndex);
}
}
internal float GetAction(DebugAction action)
{
return m_DebugActionStates[(int)action].actionState;
}
void RegisterInputs()
{
#if UNITY_EDITOR
var inputEntries = new List<InputManagerEntry>
{
new InputManagerEntry { name = kEnableDebugBtn1, kind = InputManagerEntry.Kind.KeyOrButton, btnPositive = "left ctrl", altBtnPositive = "joystick button 8" },
new InputManagerEntry { name = kEnableDebugBtn2, kind = InputManagerEntry.Kind.KeyOrButton, btnPositive = "backspace", altBtnPositive = "joystick button 9" },
new InputManagerEntry { name = kResetBtn, kind = InputManagerEntry.Kind.KeyOrButton, btnPositive = "left alt", altBtnPositive = "joystick button 1" },
new InputManagerEntry { name = kDebugNextBtn, kind = InputManagerEntry.Kind.KeyOrButton, btnPositive = "page down", altBtnPositive = "joystick button 5" },
new InputManagerEntry { name = kDebugPreviousBtn, kind = InputManagerEntry.Kind.KeyOrButton, btnPositive = "page up", altBtnPositive = "joystick button 4" },
new InputManagerEntry { name = kValidateBtn, kind = InputManagerEntry.Kind.KeyOrButton, btnPositive = "return", altBtnPositive = "joystick button 0" },
new InputManagerEntry { name = kPersistentBtn, kind = InputManagerEntry.Kind.KeyOrButton, btnPositive = "right shift", altBtnPositive = "joystick button 2" },
new InputManagerEntry { name = kMultiplierBtn, kind = InputManagerEntry.Kind.KeyOrButton, btnPositive = "left shift", altBtnPositive = "joystick button 3" },
new InputManagerEntry { name = kDPadHorizontal, kind = InputManagerEntry.Kind.KeyOrButton, btnPositive = "right", btnNegative = "left", gravity = 1000f, deadZone = 0.001f, sensitivity = 1000f },
new InputManagerEntry { name = kDPadVertical, kind = InputManagerEntry.Kind.KeyOrButton, btnPositive = "up", btnNegative = "down", gravity = 1000f, deadZone = 0.001f, sensitivity = 1000f },
new InputManagerEntry { name = kDPadVertical, kind = InputManagerEntry.Kind.Axis, axis = InputManagerEntry.Axis.Seventh, btnPositive = "up", btnNegative = "down", gravity = 1000f, deadZone = 0.001f, sensitivity = 1000f },
new InputManagerEntry { name = kDPadHorizontal, kind = InputManagerEntry.Kind.Axis, axis = InputManagerEntry.Axis.Sixth, btnPositive = "right", btnNegative = "left", gravity = 1000f, deadZone = 0.001f, sensitivity = 1000f },
};
InputRegistering.RegisterInputs(inputEntries);
#endif
#if USE_INPUT_SYSTEM
// Register input system actions
var enableAction = debugActionMap.AddAction(kEnableDebug, type: InputActionType.Button);
enableAction.AddCompositeBinding("ButtonWithOneModifier")
.With("Modifier", "<Gamepad>/rightStickPress")
.With("Button", "<Gamepad>/leftStickPress")
.With("Modifier", "<Keyboard>/leftCtrl")
.With("Button", "<Keyboard>/backspace");
var resetAction = debugActionMap.AddAction(kResetBtn, type: InputActionType.Button);
resetAction.AddCompositeBinding("ButtonWithOneModifier")
.With("Modifier", "<Gamepad>/rightStickPress")
.With("Button", "<Gamepad>/b")
.With("Modifier", "<Keyboard>/leftAlt")
.With("Button", "<Keyboard>/backspace");
var next = debugActionMap.AddAction(kDebugNextBtn, type: InputActionType.Button);
next.AddBinding("<Keyboard>/pageDown");
next.AddBinding("<Gamepad>/rightShoulder");
var previous = debugActionMap.AddAction(kDebugPreviousBtn, type: InputActionType.Button);
previous.AddBinding("<Keyboard>/pageUp");
previous.AddBinding("<Gamepad>/leftShoulder");
var validateAction = debugActionMap.AddAction(kValidateBtn, type: InputActionType.Button);
validateAction.AddBinding("<Keyboard>/enter");
validateAction.AddBinding("<Gamepad>/a");
var persistentAction = debugActionMap.AddAction(kPersistentBtn, type: InputActionType.Button);
persistentAction.AddBinding("<Keyboard>/rightShift");
persistentAction.AddBinding("<Gamepad>/x");
var multiplierAction = debugActionMap.AddAction(kMultiplierBtn, type: InputActionType.Value);
multiplierAction.AddBinding("<Keyboard>/leftShift");
multiplierAction.AddBinding("<Gamepad>/y");
var moveVerticalAction = debugActionMap.AddAction(kDPadVertical);
moveVerticalAction.AddCompositeBinding("1DAxis")
.With("Positive", "<Gamepad>/dpad/up")
.With("Negative", "<Gamepad>/dpad/down")
.With("Positive", "<Keyboard>/upArrow")
.With("Negative", "<Keyboard>/downArrow");
var moveHorizontalAction = debugActionMap.AddAction(kDPadHorizontal);
moveHorizontalAction.AddCompositeBinding("1DAxis")
.With("Positive", "<Gamepad>/dpad/right")
.With("Negative", "<Gamepad>/dpad/left")
.With("Positive", "<Keyboard>/rightArrow")
.With("Negative", "<Keyboard>/leftArrow");
#endif
}
}
class DebugActionDesc
{
#if USE_INPUT_SYSTEM
public InputAction buttonAction = null;
#else
public string axisTrigger = "";
public List<string[]> buttonTriggerList = new List<string[]>();
public List<KeyCode[]> keyTriggerList = new List<KeyCode[]>();
#endif
public DebugActionRepeatMode repeatMode = DebugActionRepeatMode.Never;
public float repeatDelay;
}
class DebugActionState
{
enum DebugActionKeyType
{
Button,
Axis,
Key
}
DebugActionKeyType m_Type;
#if USE_INPUT_SYSTEM
InputAction inputAction;
#else
string[] m_PressedButtons;
string m_PressedAxis = "";
KeyCode[] m_PressedKeys;
#endif
bool[] m_TriggerPressedUp;
float m_Timer;
internal bool runningAction { get; private set; }
internal float actionState { get; private set; }
void Trigger(int triggerCount, float state)
{
actionState = state;
runningAction = true;
m_Timer = 0f;
m_TriggerPressedUp = new bool[triggerCount];
for (int i = 0; i < m_TriggerPressedUp.Length; ++i)
m_TriggerPressedUp[i] = false;
}
#if USE_INPUT_SYSTEM
public void TriggerWithButton(InputAction action, float state)
{
inputAction = action;
Trigger(action.bindings.Count, state);
}
#else
public void TriggerWithButton(string[] buttons, float state)
{
m_Type = DebugActionKeyType.Button;
m_PressedButtons = buttons;
m_PressedAxis = "";
Trigger(buttons.Length, state);
}
public void TriggerWithAxis(string axis, float state)
{
m_Type = DebugActionKeyType.Axis;
m_PressedAxis = axis;
Trigger(1, state);
}
public void TriggerWithKey(KeyCode[] keys, float state)
{
m_Type = DebugActionKeyType.Key;
m_PressedKeys = keys;
m_PressedAxis = "";
Trigger(keys.Length, state);
}
#endif
void Reset()
{
runningAction = false;
m_Timer = 0f;
m_TriggerPressedUp = null;
}
public void Update(DebugActionDesc desc)
{
// Always reset this so that the action can only be caught once until repeat/reset
actionState = 0f;
if (m_TriggerPressedUp != null)
{
m_Timer += Time.deltaTime;
for (int i = 0; i < m_TriggerPressedUp.Length; ++i)
{
#if USE_INPUT_SYSTEM
if (inputAction != null)
m_TriggerPressedUp[i] |= Mathf.Approximately(inputAction.ReadValue<float>(), 0f);
#else
if (m_Type == DebugActionKeyType.Button)
m_TriggerPressedUp[i] |= Input.GetButtonUp(m_PressedButtons[i]);
else if (m_Type == DebugActionKeyType.Axis)
m_TriggerPressedUp[i] |= Mathf.Approximately(Input.GetAxis(m_PressedAxis), 0f);
else
m_TriggerPressedUp[i] |= Input.GetKeyUp(m_PressedKeys[i]);
#endif
}
bool allTriggerUp = true;
foreach (bool value in m_TriggerPressedUp)
allTriggerUp &= value;
if (allTriggerUp || (m_Timer > desc.repeatDelay && desc.repeatMode == DebugActionRepeatMode.Delay))
Reset();
}
}
}
}

View File

@@ -0,0 +1,368 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using UnityEngine.Assertions;
using UnityEngine.Rendering.UI;
namespace UnityEngine.Rendering
{
using UnityObject = UnityEngine.Object;
/// <summary>
/// IDebugData interface.
/// </summary>
public interface IDebugData
{
/// <summary>Get the reset callback for this DebugData</summary>
/// <returns>The reset callback</returns>
Action GetReset();
//Action GetLoad();
//Action GetSave();
}
/// <summary>
/// Manager class for the Debug Window.
/// </summary>
public sealed partial class DebugManager
{
static readonly Lazy<DebugManager> s_Instance = new Lazy<DebugManager>(() => new DebugManager());
/// <summary>
/// Global instance of the DebugManager.
/// </summary>
public static DebugManager instance => s_Instance.Value;
ReadOnlyCollection<DebugUI.Panel> m_ReadOnlyPanels;
readonly List<DebugUI.Panel> m_Panels = new List<DebugUI.Panel>();
void UpdateReadOnlyCollection()
{
m_Panels.Sort();
m_ReadOnlyPanels = m_Panels.AsReadOnly();
}
/// <summary>
/// List of currently registered debug panels.
/// </summary>
public ReadOnlyCollection<DebugUI.Panel> panels
{
get
{
if (m_ReadOnlyPanels == null)
UpdateReadOnlyCollection();
return m_ReadOnlyPanels;
}
}
/// <summary>
/// Callback called when the runtime UI changed.
/// </summary>
public event Action<bool> onDisplayRuntimeUIChanged = delegate {};
/// <summary>
/// Callback called when the debug window is dirty.
/// </summary>
public event Action onSetDirty = delegate {};
event Action resetData;
/// <summary>
/// Force an editor request.
/// </summary>
public bool refreshEditorRequested;
GameObject m_Root;
DebugUIHandlerCanvas m_RootUICanvas;
GameObject m_PersistentRoot;
DebugUIHandlerPersistentCanvas m_RootUIPersistentCanvas;
// Knowing if the DebugWindows is open, is done by event as it is in another assembly.
// The DebugWindows is responsible to link its event to ToggleEditorUI.
bool m_EditorOpen = false;
/// <summary>
/// Is the debug editor window open.
/// </summary>
public bool displayEditorUI => m_EditorOpen;
/// <summary>
/// Toggle the debug window.
/// </summary>
/// <param name="open">State of the debug window.</param>
public void ToggleEditorUI(bool open) => m_EditorOpen = open;
/// <summary>
/// Displays the runtime version of the debug window.
/// </summary>
public bool displayRuntimeUI
{
get => m_Root != null && m_Root.activeInHierarchy;
set
{
if (value)
{
m_Root = UnityObject.Instantiate(Resources.Load<Transform>("DebugUICanvas")).gameObject;
m_Root.name = "[Debug Canvas]";
m_Root.transform.localPosition = Vector3.zero;
m_RootUICanvas = m_Root.GetComponent<DebugUIHandlerCanvas>();
m_Root.SetActive(true);
}
else
{
CoreUtils.Destroy(m_Root);
m_Root = null;
m_RootUICanvas = null;
}
onDisplayRuntimeUIChanged(value);
}
}
/// <summary>
/// Displays the persistent runtime debug window.
/// </summary>
public bool displayPersistentRuntimeUI
{
get => m_RootUIPersistentCanvas != null && m_PersistentRoot.activeInHierarchy;
set
{
CheckPersistentCanvas();
m_PersistentRoot.SetActive(value);
}
}
DebugManager()
{
if (!Debug.isDebugBuild)
return;
RegisterInputs();
RegisterActions();
}
/// <summary>
/// Refresh the debug window.
/// </summary>
public void RefreshEditor()
{
refreshEditorRequested = true;
}
/// <summary>
/// Reset the debug window.
/// </summary>
public void Reset()
{
resetData?.Invoke();
ReDrawOnScreenDebug();
}
/// <summary>
/// Redraw the runtime debug UI.
/// </summary>
public void ReDrawOnScreenDebug()
{
if (displayRuntimeUI)
m_RootUICanvas?.ResetAllHierarchy();
}
/// <summary>
/// Register debug data.
/// </summary>
/// <param name="data">Data to be registered.</param>
public void RegisterData(IDebugData data) => resetData += data.GetReset();
/// <summary>
/// Register debug data.
/// </summary>
/// <param name="data">Data to be registered.</param>
public void UnregisterData(IDebugData data) => resetData -= data.GetReset();
/// <summary>
/// Get hashcode state of the Debug Window.
/// </summary>
/// <returns></returns>
public int GetState()
{
int hash = 17;
foreach (var panel in m_Panels)
hash = hash * 23 + panel.GetHashCode();
return hash;
}
internal void RegisterRootCanvas(DebugUIHandlerCanvas root)
{
Assert.IsNotNull(root);
m_Root = root.gameObject;
m_RootUICanvas = root;
}
internal void ChangeSelection(DebugUIHandlerWidget widget, bool fromNext)
{
m_RootUICanvas.ChangeSelection(widget, fromNext);
}
void CheckPersistentCanvas()
{
if (m_RootUIPersistentCanvas == null)
{
var uiManager = UnityObject.FindObjectOfType<DebugUIHandlerPersistentCanvas>();
if (uiManager == null)
{
m_PersistentRoot = UnityObject.Instantiate(Resources.Load<Transform>("DebugUIPersistentCanvas")).gameObject;
m_PersistentRoot.name = "[Debug Canvas - Persistent]";
m_PersistentRoot.transform.localPosition = Vector3.zero;
}
else
{
m_PersistentRoot = uiManager.gameObject;
}
m_RootUIPersistentCanvas = m_PersistentRoot.GetComponent<DebugUIHandlerPersistentCanvas>();
}
}
internal void TogglePersistent(DebugUI.Widget widget)
{
if (widget == null)
return;
var valueWidget = widget as DebugUI.Value;
if (valueWidget == null)
{
Debug.Log("Only DebugUI.Value items can be made persistent.");
return;
}
CheckPersistentCanvas();
m_RootUIPersistentCanvas.Toggle(valueWidget);
}
void OnPanelDirty(DebugUI.Panel panel)
{
onSetDirty();
}
// TODO: Optimally we should use a query path here instead of a display name
/// <summary>
/// Returns a debug panel.
/// </summary>
/// <param name="displayName">Name of the debug panel.</param>
/// <param name="createIfNull">Create the panel if it does not exists.</param>
/// <param name="groupIndex">Group index.</param>
/// <param name="overrideIfExist">Replace an existing panel.</param>
/// <returns></returns>
public DebugUI.Panel GetPanel(string displayName, bool createIfNull = false, int groupIndex = 0, bool overrideIfExist = false)
{
DebugUI.Panel p = null;
foreach (var panel in m_Panels)
{
if (panel.displayName == displayName)
{
p = panel;
break;
}
}
if (p != null)
{
if (overrideIfExist)
{
p.onSetDirty -= OnPanelDirty;
RemovePanel(p);
p = null;
}
else
return p;
}
if (createIfNull)
{
p = new DebugUI.Panel { displayName = displayName, groupIndex = groupIndex };
p.onSetDirty += OnPanelDirty;
m_Panels.Add(p);
UpdateReadOnlyCollection();
}
return p;
}
// TODO: Use a query path here as well instead of a display name
/// <summary>
/// Remove a debug panel.
/// </summary>
/// <param name="displayName">Name of the debug panel to remove.</param>
public void RemovePanel(string displayName)
{
DebugUI.Panel panel = null;
foreach (var p in m_Panels)
{
if (p.displayName == displayName)
{
p.onSetDirty -= OnPanelDirty;
panel = p;
break;
}
}
RemovePanel(panel);
}
/// <summary>
/// Remove a debug panel.
/// </summary>
/// <param name="panel">Reference to the debug panel to remove.</param>
public void RemovePanel(DebugUI.Panel panel)
{
if (panel == null)
return;
m_Panels.Remove(panel);
UpdateReadOnlyCollection();
}
/// <summary>
/// Get a Debug Item.
/// </summary>
/// <param name="queryPath">Path of the debug item.</param>
/// <returns>Reference to the requested debug item.</returns>
public DebugUI.Widget GetItem(string queryPath)
{
foreach (var panel in m_Panels)
{
var w = GetItem(queryPath, panel);
if (w != null)
return w;
}
return null;
}
/// <summary>
/// Get a debug item from a specific container.
/// </summary>
/// <param name="queryPath">Path of the debug item.</param>
/// <param name="container">Container to query.</param>
/// <returns>Reference to the requested debug item.</returns>
DebugUI.Widget GetItem(string queryPath, DebugUI.IContainer container)
{
foreach (var child in container.children)
{
if (child.queryPath == queryPath)
return child;
var containerChild = child as DebugUI.IContainer;
if (containerChild != null)
{
var w = GetItem(queryPath, containerChild);
if (w != null)
return w;
}
}
return null;
}
}
}

View File

@@ -0,0 +1,516 @@
namespace UnityEngine.Rendering
{
/// <summary>Debug class containing several debug shapes for debugging</summary>
public partial class DebugShapes
{
// Singleton
static DebugShapes s_Instance = null;
/// <summary>Singleton instance</summary>
static public DebugShapes instance
{
get
{
if (s_Instance == null)
{
s_Instance = new DebugShapes();
}
return s_Instance;
}
}
Mesh m_sphereMesh = null;
Mesh m_boxMesh = null;
Mesh m_coneMesh = null;
Mesh m_pyramidMesh = null;
// This code has been grabbed from http://wiki.unity3d.com/index.php/ProceduralPrimitives
void BuildSphere(ref Mesh outputMesh, float radius, uint longSubdiv, uint latSubdiv)
{
// Make sure it is empty before pushing anything to it
outputMesh.Clear();
// Build the vertices array
Vector3[] vertices = new Vector3[(longSubdiv + 1) * latSubdiv + 2];
float _pi = Mathf.PI;
float _2pi = _pi * 2f;
vertices[0] = Vector3.up * radius;
for (int lat = 0; lat < latSubdiv; lat++)
{
float a1 = _pi * (float)(lat + 1) / (latSubdiv + 1);
float sin1 = Mathf.Sin(a1);
float cos1 = Mathf.Cos(a1);
for (int lon = 0; lon <= longSubdiv; lon++)
{
float a2 = _2pi * (float)(lon == longSubdiv ? 0 : lon) / longSubdiv;
float sin2 = Mathf.Sin(a2);
float cos2 = Mathf.Cos(a2);
vertices[lon + lat * (longSubdiv + 1) + 1] = new Vector3(sin1 * cos2, cos1, sin1 * sin2) * radius;
}
}
vertices[vertices.Length - 1] = Vector3.up * -radius;
// Build the normals array
Vector3[] normals = new Vector3[vertices.Length];
for (int n = 0; n < vertices.Length; n++)
{
normals[n] = vertices[n].normalized;
}
// Build the UV array
Vector2[] uvs = new Vector2[vertices.Length];
uvs[0] = Vector2.up;
uvs[uvs.Length - 1] = Vector2.zero;
for (int lat = 0; lat < latSubdiv; lat++)
{
for (int lon = 0; lon <= longSubdiv; lon++)
{
uvs[lon + lat * (longSubdiv + 1) + 1] = new Vector2((float)lon / longSubdiv, 1f - (float)(lat + 1) / (latSubdiv + 1));
}
}
// Build the index array
int nbFaces = vertices.Length;
int nbTriangles = nbFaces * 2;
int nbIndexes = nbTriangles * 3;
int[] triangles = new int[nbIndexes];
// Top Cap
int i = 0;
for (int lon = 0; lon < longSubdiv; lon++)
{
triangles[i++] = lon + 2;
triangles[i++] = lon + 1;
triangles[i++] = 0;
}
//Middle
for (uint lat = 0; lat < latSubdiv - 1; lat++)
{
for (uint lon = 0; lon < longSubdiv; lon++)
{
uint current = lon + lat * (longSubdiv + 1) + 1;
uint next = current + longSubdiv + 1;
triangles[i++] = (int)current;
triangles[i++] = (int)current + 1;
triangles[i++] = (int)next + 1;
triangles[i++] = (int)current;
triangles[i++] = (int)next + 1;
triangles[i++] = (int)next;
}
}
// Bottom Cap
for (int lon = 0; lon < longSubdiv; lon++)
{
triangles[i++] = vertices.Length - 1;
triangles[i++] = vertices.Length - (lon + 2) - 1;
triangles[i++] = vertices.Length - (lon + 1) - 1;
}
// Assign them to
outputMesh.vertices = vertices;
outputMesh.normals = normals;
outputMesh.uv = uvs;
outputMesh.triangles = triangles;
outputMesh.RecalculateBounds();
}
void BuildBox(ref Mesh outputMesh, float length, float width, float height)
{
outputMesh.Clear();
Vector3 p0 = new Vector3(-length * .5f, -width * .5f, height * .5f);
Vector3 p1 = new Vector3(length * .5f, -width * .5f, height * .5f);
Vector3 p2 = new Vector3(length * .5f, -width * .5f, -height * .5f);
Vector3 p3 = new Vector3(-length * .5f, -width * .5f, -height * .5f);
Vector3 p4 = new Vector3(-length * .5f, width * .5f, height * .5f);
Vector3 p5 = new Vector3(length * .5f, width * .5f, height * .5f);
Vector3 p6 = new Vector3(length * .5f, width * .5f, -height * .5f);
Vector3 p7 = new Vector3(-length * .5f, width * .5f, -height * .5f);
Vector3[] vertices = new Vector3[]
{
// Bottom
p0, p1, p2, p3,
// Left
p7, p4, p0, p3,
// Front
p4, p5, p1, p0,
// Back
p6, p7, p3, p2,
// Right
p5, p6, p2, p1,
// Top
p7, p6, p5, p4
};
Vector3 up = Vector3.up;
Vector3 down = Vector3.down;
Vector3 front = Vector3.forward;
Vector3 back = Vector3.back;
Vector3 left = Vector3.left;
Vector3 right = Vector3.right;
Vector3[] normales = new Vector3[]
{
// Bottom
down, down, down, down,
// Left
left, left, left, left,
// Front
front, front, front, front,
// Back
back, back, back, back,
// Right
right, right, right, right,
// Top
up, up, up, up
};
Vector2 _00 = new Vector2(0f, 0f);
Vector2 _10 = new Vector2(1f, 0f);
Vector2 _01 = new Vector2(0f, 1f);
Vector2 _11 = new Vector2(1f, 1f);
Vector2[] uvs = new Vector2[]
{
// Bottom
_11, _01, _00, _10,
// Left
_11, _01, _00, _10,
// Front
_11, _01, _00, _10,
// Back
_11, _01, _00, _10,
// Right
_11, _01, _00, _10,
// Top
_11, _01, _00, _10,
};
int[] triangles = new int[]
{
// Bottom
3, 1, 0,
3, 2, 1,
// Left
3 + 4 * 1, 1 + 4 * 1, 0 + 4 * 1,
3 + 4 * 1, 2 + 4 * 1, 1 + 4 * 1,
// Front
3 + 4 * 2, 1 + 4 * 2, 0 + 4 * 2,
3 + 4 * 2, 2 + 4 * 2, 1 + 4 * 2,
// Back
3 + 4 * 3, 1 + 4 * 3, 0 + 4 * 3,
3 + 4 * 3, 2 + 4 * 3, 1 + 4 * 3,
// Right
3 + 4 * 4, 1 + 4 * 4, 0 + 4 * 4,
3 + 4 * 4, 2 + 4 * 4, 1 + 4 * 4,
// Top
3 + 4 * 5, 1 + 4 * 5, 0 + 4 * 5,
3 + 4 * 5, 2 + 4 * 5, 1 + 4 * 5,
};
outputMesh.vertices = vertices;
outputMesh.normals = normales;
outputMesh.uv = uvs;
outputMesh.triangles = triangles;
outputMesh.RecalculateBounds();
}
void BuildCone(ref Mesh outputMesh, float height, float topRadius, float bottomRadius, int nbSides)
{
outputMesh.Clear();
int nbVerticesCap = nbSides + 1;
// bottom + top + sides
Vector3[] vertices = new Vector3[nbVerticesCap + nbVerticesCap + nbSides * 2 + 2];
int vert = 0;
float _2pi = Mathf.PI * 2f;
// Bottom cap
vertices[vert++] = new Vector3(0f, 0f, 0f);
while (vert <= nbSides)
{
float rad = (float)vert / nbSides * _2pi;
vertices[vert] = new Vector3(Mathf.Sin(rad) * bottomRadius, Mathf.Cos(rad) * bottomRadius, 0f);
vert++;
}
// Top cap
vertices[vert++] = new Vector3(0f, 0f , height);
while (vert <= nbSides * 2 + 1)
{
float rad = (float)(vert - nbSides - 1) / nbSides * _2pi;
vertices[vert] = new Vector3(Mathf.Sin(rad) * topRadius, Mathf.Cos(rad) * topRadius, height);
vert++;
}
// Sides
int v = 0;
while (vert <= vertices.Length - 4)
{
float rad = (float)v / nbSides * _2pi;
vertices[vert] = new Vector3(Mathf.Sin(rad) * topRadius, Mathf.Cos(rad) * topRadius, height);
vertices[vert + 1] = new Vector3(Mathf.Sin(rad) * bottomRadius, Mathf.Cos(rad) * bottomRadius, 0);
vert += 2;
v++;
}
vertices[vert] = vertices[nbSides * 2 + 2];
vertices[vert + 1] = vertices[nbSides * 2 + 3];
// bottom + top + sides
Vector3[] normales = new Vector3[vertices.Length];
vert = 0;
// Bottom cap
while (vert <= nbSides)
{
normales[vert++] = new Vector3(0, 0, -1);
}
// Top cap
while (vert <= nbSides * 2 + 1)
{
normales[vert++] = new Vector3(0, 0, 1);
}
// Sides
v = 0;
while (vert <= vertices.Length - 4)
{
float rad = (float)v / nbSides * _2pi;
float cos = Mathf.Cos(rad);
float sin = Mathf.Sin(rad);
normales[vert] = new Vector3(sin, cos, 0f);
normales[vert + 1] = normales[vert];
vert += 2;
v++;
}
normales[vert] = normales[nbSides * 2 + 2];
normales[vert + 1] = normales[nbSides * 2 + 3];
Vector2[] uvs = new Vector2[vertices.Length];
// Bottom cap
int u = 0;
uvs[u++] = new Vector2(0.5f, 0.5f);
while (u <= nbSides)
{
float rad = (float)u / nbSides * _2pi;
uvs[u] = new Vector2(Mathf.Cos(rad) * .5f + .5f, Mathf.Sin(rad) * .5f + .5f);
u++;
}
// Top cap
uvs[u++] = new Vector2(0.5f, 0.5f);
while (u <= nbSides * 2 + 1)
{
float rad = (float)u / nbSides * _2pi;
uvs[u] = new Vector2(Mathf.Cos(rad) * .5f + .5f, Mathf.Sin(rad) * .5f + .5f);
u++;
}
// Sides
int u_sides = 0;
while (u <= uvs.Length - 4)
{
float t = (float)u_sides / nbSides;
uvs[u] = new Vector3(t, 1f);
uvs[u + 1] = new Vector3(t, 0f);
u += 2;
u_sides++;
}
uvs[u] = new Vector2(1f, 1f);
uvs[u + 1] = new Vector2(1f, 0f);
int nbTriangles = nbSides + nbSides + nbSides * 2;
int[] triangles = new int[nbTriangles * 3 + 3];
// Bottom cap
int tri = 0;
int i = 0;
while (tri < nbSides - 1)
{
triangles[i] = 0;
triangles[i + 1] = tri + 1;
triangles[i + 2] = tri + 2;
tri++;
i += 3;
}
triangles[i] = 0;
triangles[i + 1] = tri + 1;
triangles[i + 2] = 1;
tri++;
i += 3;
// Top cap
//tri++;
while (tri < nbSides * 2)
{
triangles[i] = tri + 2;
triangles[i + 1] = tri + 1;
triangles[i + 2] = nbVerticesCap;
tri++;
i += 3;
}
triangles[i] = nbVerticesCap + 1;
triangles[i + 1] = tri + 1;
triangles[i + 2] = nbVerticesCap;
tri++;
i += 3;
tri++;
// Sides
while (tri <= nbTriangles)
{
triangles[i] = tri + 2;
triangles[i + 1] = tri + 1;
triangles[i + 2] = tri + 0;
tri++;
i += 3;
triangles[i] = tri + 1;
triangles[i + 1] = tri + 2;
triangles[i + 2] = tri + 0;
tri++;
i += 3;
}
outputMesh.vertices = vertices;
outputMesh.normals = normales;
outputMesh.uv = uvs;
outputMesh.triangles = triangles;
outputMesh.RecalculateBounds();
}
void BuildPyramid(ref Mesh outputMesh, float width, float height, float depth)
{
outputMesh.Clear();
// Allocate the buffer
Vector3[] vertices = new Vector3[16];
// Top Face
vertices[0] = new Vector3(0f, 0f, 0f);
vertices[1] = new Vector3(-width / 2.0f, height / 2.0f, depth);
vertices[2] = new Vector3(width / 2.0f, height / 2.0f, depth);
// Left Face
vertices[3] = new Vector3(0f, 0f, 0f);
vertices[4] = new Vector3(width / 2.0f, height / 2.0f, depth);
vertices[5] = new Vector3(width / 2.0f, -height / 2.0f, depth);
// Bottom Face
vertices[6] = new Vector3(0f, 0f, 0f);
vertices[7] = new Vector3(width / 2.0f, -height / 2.0f, depth);
vertices[8] = new Vector3(-width / 2.0f, -height / 2.0f, depth);
// Right Face
vertices[9] = new Vector3(0f, 0f, 0f);
vertices[10] = new Vector3(-width / 2.0f, -height / 2.0f, depth);
vertices[11] = new Vector3(-width / 2.0f, height / 2.0f, depth);
// Cap
vertices[12] = new Vector3(-width / 2.0f, height / 2.0f, depth);
vertices[13] = new Vector3(-width / 2.0f, -height / 2.0f, depth);
vertices[14] = new Vector3(width / 2.0f, -height / 2.0f, depth);
vertices[15] = new Vector3(width / 2.0f, height / 2.0f, depth);
// TODO: support the uv/normals
Vector3[] normals = new Vector3[vertices.Length];
Vector2[] uvs = new Vector2[vertices.Length];
// The indexes for the side part is simple
int[] triangles = new int[18];
for (int idx = 0; idx < 12; ++idx)
{
triangles[idx] = idx;
}
// Cap indexes
triangles[12] = 12;
triangles[13] = 13;
triangles[14] = 14;
triangles[15] = 12;
triangles[16] = 14;
triangles[17] = 15;
outputMesh.vertices = vertices;
outputMesh.normals = normals;
outputMesh.uv = uvs;
outputMesh.triangles = triangles;
outputMesh.RecalculateBounds();
}
void BuildShapes()
{
m_sphereMesh = new Mesh();
BuildSphere(ref m_sphereMesh, 1.0f, 24, 16);
m_boxMesh = new Mesh();
BuildBox(ref m_boxMesh, 1.0f, 1.0f, 1.0f);
m_coneMesh = new Mesh();
BuildCone(ref m_coneMesh, 1.0f, 1.0f, 0.0f, 16);
m_pyramidMesh = new Mesh();
BuildPyramid(ref m_pyramidMesh, 1.0f, 1.0f, 1.0f);
}
void RebuildResources()
{
if (m_sphereMesh == null || m_boxMesh == null || m_coneMesh == null || m_pyramidMesh == null)
{
BuildShapes();
}
}
/// <summary>Get a Sphere Mesh</summary>
/// <returns>A Sphere Mesh</returns>
public Mesh RequestSphereMesh()
{
RebuildResources();
return m_sphereMesh;
}
/// <summary>Get a Box Mesh</summary>
/// <returns>A Box Mesh</returns>
public Mesh RequestBoxMesh()
{
RebuildResources();
return m_boxMesh;
}
/// <summary>Get a Cone Mesh</summary>
/// <returns>A Cone Mesh</returns>
public Mesh RequestConeMesh()
{
RebuildResources();
return m_coneMesh;
}
/// <summary>Get a Pyramid Mesh</summary>
/// <returns>A Pyramid Mesh</returns>
public Mesh RequestPyramidMesh()
{
RebuildResources();
return m_pyramidMesh;
}
}
}

View File

@@ -0,0 +1,410 @@
namespace UnityEngine.Rendering
{
public partial class DebugUI
{
/// <summary>
/// Base class for "container" type widgets, although it can be used on its own (if a display name is set then it'll behave as a group with a header)
/// </summary>
public class Container : Widget, IContainer
{
/// <summary>
/// List of children.
/// </summary>
public ObservableList<Widget> children { get; private set; }
/// <summary>
/// Panel the container is attached to.
/// </summary>
public override Panel panel
{
get { return m_Panel; }
internal set
{
m_Panel = value;
// Bubble down
foreach (var child in children)
child.panel = value;
}
}
/// <summary>
/// Constructor
/// </summary>
public Container()
{
displayName = "";
children = new ObservableList<Widget>();
children.ItemAdded += OnItemAdded;
children.ItemRemoved += OnItemRemoved;
}
/// <summary>
/// Constructor.
/// </summary>
/// <param name="displayName">Display name of the container.</param>
/// <param name="children">List of attached children.</param>
public Container(string displayName, ObservableList<Widget> children)
{
this.displayName = displayName;
this.children = children;
children.ItemAdded += OnItemAdded;
children.ItemRemoved += OnItemRemoved;
}
internal override void GenerateQueryPath()
{
base.GenerateQueryPath();
foreach (var child in children)
child.GenerateQueryPath();
}
/// <summary>
/// Method called when a children is added.
/// </summary>
/// <param name="sender">Sender widget.</param>
/// <param name="e">List of added children.</param>
protected virtual void OnItemAdded(ObservableList<Widget> sender, ListChangedEventArgs<Widget> e)
{
if (e.item != null)
{
e.item.panel = m_Panel;
e.item.parent = this;
}
if (m_Panel != null)
m_Panel.SetDirty();
}
/// <summary>
/// Method called when a children is removed.
/// </summary>
/// <param name="sender">Sender widget.</param>
/// <param name="e">List of removed children.</param>
protected virtual void OnItemRemoved(ObservableList<Widget> sender, ListChangedEventArgs<Widget> e)
{
if (e.item != null)
{
e.item.panel = null;
e.item.parent = null;
}
if (m_Panel != null)
m_Panel.SetDirty();
}
/// <summary>
/// Returns the hash code of the widget.
/// </summary>
/// <returns>Hash code of the widget.</returns>
public override int GetHashCode()
{
int hash = 17;
hash = hash * 23 + queryPath.GetHashCode();
foreach (var child in children)
hash = hash * 23 + child.GetHashCode();
return hash;
}
}
/// <summary>
/// Unity-like foldout that can be collapsed.
/// </summary>
public class Foldout : Container, IValueField
{
/// <summary>
/// Always false.
/// </summary>
public bool isReadOnly { get { return false; } }
/// <summary>
/// Opened state of the foldout.
/// </summary>
public bool opened;
/// <summary>
/// List of columns labels.
/// </summary>
public string[] columnLabels { get; set; } = null;
/// <summary>
/// Constructor.
/// </summary>
public Foldout() : base() {}
/// <summary>
/// Constructor.
/// </summary>
/// <param name="displayName">Display name of the foldout.</param>
/// <param name="children">List of attached children.</param>
/// <param name="columnLabels">Optional list of column names.</param>
public Foldout(string displayName, ObservableList<Widget> children, string[] columnLabels = null)
: base(displayName, children)
{
this.columnLabels = columnLabels;
}
/// <summary>
/// Get the opened state of the foldout.
/// </summary>
/// <returns>True if the foldout is opened.</returns>
public bool GetValue() => opened;
/// <summary>
/// Get the opened state of the foldout.
/// </summary>
/// <returns>True if the foldout is opened.</returns>
object IValueField.GetValue() => GetValue();
/// <summary>
/// Set the opened state of the foldout.
/// </summary>
/// <param name="value">True to open the foldout, false to close it.</param>
public void SetValue(object value) => SetValue((bool)value);
/// <summary>
/// Validates the value of the widget before setting it.
/// </summary>
/// <param name="value">Input value.</param>
/// <returns>The validated value.</returns>
public object ValidateValue(object value) => value;
/// <summary>
/// Set the value of the widget.
/// </summary>
/// <param name="value">Input value.</param>
public void SetValue(bool value) => opened = value;
}
/// <summary>
/// Horizontal Layout Container.
/// </summary>
public class HBox : Container
{
/// <summary>
/// Constructor.
/// </summary>
public HBox()
{
displayName = "HBox";
}
}
/// <summary>
/// Vertical Layout Container.
/// </summary>
public class VBox : Container
{
/// <summary>
/// Constructor.
/// </summary>
public VBox()
{
displayName = "VBox";
}
}
/// <summary>
/// Array Container.
/// </summary>
public class Table : Container
{
/// <summary>Row Container.</summary>
public class Row : Foldout
{
/// <summary>Constructor.</summary>
public Row() { displayName = "Row"; }
}
/// <summary>
/// True if the table is read only.
/// </summary>
public bool isReadOnly = false;
/// <summary>Constructor.</summary>
public Table() { displayName = "Array"; }
/// <summary>
/// Set column visibility.
/// </summary>
/// <param name="index">Index of the column.</param>
/// <param name="visible">True if the column should be visible.</param>
public void SetColumnVisibility(int index, bool visible)
{
#if UNITY_EDITOR
var header = Header;
if (index < 0 || index >= m_ColumnCount)
return;
index++;
if (header.IsColumnVisible(index) != visible)
{
var newVisibleColumns = new System.Collections.Generic.List<int>(header.state.visibleColumns);
if (newVisibleColumns.Contains(index))
{
newVisibleColumns.Remove(index);
}
else
{
newVisibleColumns.Add(index);
newVisibleColumns.Sort();
}
header.state.visibleColumns = newVisibleColumns.ToArray();
var cols = header.state.columns;
for (int i = 0; i < cols.Length; i++)
cols[i].width = 50f;
header.ResizeToFit();
}
#else
var columns = VisibleColumns;
if (index < 0 || index > columns.Length)
return;
columns[index] = visible;
#endif
}
/// <summary>
/// Get column visibility.
/// </summary>
/// <param name="index">Index of the column.</param>
/// <returns>True if the column is visible.</returns>
public bool GetColumnVisibility(int index)
{
#if UNITY_EDITOR
var header = Header;
if (index < 0 || index >= m_ColumnCount)
return false;
return header.IsColumnVisible(index + 1);
#else
var columns = VisibleColumns;
if (index < 0 || index > columns.Length)
return false;
return columns[index];
#endif
}
#if UNITY_EDITOR
/// <summary>
/// The scroll position of the table.
/// </summary>
public Vector2 scroll = Vector2.zero;
int m_ColumnCount;
UnityEditor.IMGUI.Controls.MultiColumnHeader m_Header = null;
/// <summary>
/// The table header for drawing
/// </summary>
public UnityEditor.IMGUI.Controls.MultiColumnHeader Header
{
get
{
if (m_Header != null)
return m_Header;
if (children.Count != 0)
{
m_ColumnCount = ((Container)children[0]).children.Count;
for (int i = 1; i < children.Count; i++)
{
if (((Container)children[i]).children.Count != m_ColumnCount)
{
Debug.LogError("All rows must have the same number of children.");
return null;
}
}
}
UnityEditor.IMGUI.Controls.MultiColumnHeaderState.Column CreateColumn(string name)
{
var col = new UnityEditor.IMGUI.Controls.MultiColumnHeaderState.Column()
{
canSort = false,
headerTextAlignment = TextAlignment.Center,
headerContent = new GUIContent(name),
};
GUIStyle style = UnityEditor.IMGUI.Controls.MultiColumnHeader.DefaultStyles.columnHeaderCenterAligned;
style.CalcMinMaxWidth(col.headerContent, out col.width, out float _);
col.width = Mathf.Min(col.width, 50f);
return col;
}
var cols = new UnityEditor.IMGUI.Controls.MultiColumnHeaderState.Column[m_ColumnCount + 1];
cols[0] = CreateColumn(displayName);
cols[0].allowToggleVisibility = false;
for (int i = 0; i < m_ColumnCount; i++)
cols[i + 1] = CreateColumn(((Container)children[0]).children[i].displayName);
var state = new UnityEditor.IMGUI.Controls.MultiColumnHeaderState(cols);
m_Header = new UnityEditor.IMGUI.Controls.MultiColumnHeader(state) { height = 23 };
m_Header.ResizeToFit();
return m_Header;
}
}
#else
bool[] m_Header = null;
/// <summary>
/// The visible columns
/// </summary>
public bool[] VisibleColumns
{
get
{
if (m_Header != null)
return m_Header;
int columnCount = 0;
if (children.Count != 0)
{
columnCount = ((Container)children[0]).children.Count;
for (int i = 1; i < children.Count; i++)
{
if (((Container)children[i]).children.Count != columnCount)
{
Debug.LogError("All rows must have the same number of children.");
return null;
}
}
}
m_Header = new bool[columnCount];
for (int i = 0; i < columnCount; i++)
m_Header[i] = true;
return m_Header;
}
}
#endif
/// <summary>
/// Method called when a children is added.
/// </summary>
/// <param name="sender">Sender widget.</param>
/// <param name="e">List of added children.</param>
protected override void OnItemAdded(ObservableList<Widget> sender, ListChangedEventArgs<Widget> e)
{
base.OnItemAdded(sender, e);
m_Header = null;
}
/// <summary>
/// Method called when a children is removed.
/// </summary>
/// <param name="sender">Sender widget.</param>
/// <param name="e">List of removed children.</param>
protected override void OnItemRemoved(ObservableList<Widget> sender, ListChangedEventArgs<Widget> e)
{
base.OnItemRemoved(sender, e);
m_Header = null;
}
}
}
}

View File

@@ -0,0 +1,514 @@
using System;
using System.Linq;
using UnityEngine.Assertions;
namespace UnityEngine.Rendering
{
public partial class DebugUI
{
/// <summary>
/// Generic field - will be serialized in the editor if it's not read-only
/// </summary>
/// <typeparam name="T"></typeparam>
public abstract class Field<T> : Widget, IValueField
{
/// <summary>
/// Getter for this field.
/// </summary>
public Func<T> getter { get; set; }
/// <summary>
/// Setter for this field.
/// </summary>
public Action<T> setter { get; set; }
// This should be an `event` but they don't play nice with object initializers in the
// version of C# we use.
/// <summary>
/// Callback used when the value of the field changes.
/// </summary>
public Action<Field<T>, T> onValueChanged;
/// <summary>
/// Function used to validate the value when updating the field.
/// </summary>
/// <param name="value">Input value.</param>
/// <returns>Validated value.</returns>
object IValueField.ValidateValue(object value)
{
return ValidateValue((T)value);
}
/// <summary>
/// Function used to validate the value when updating the field.
/// </summary>
/// <param name="value">Input value.</param>
/// <returns>Validated value.</returns>
public virtual T ValidateValue(T value)
{
return value;
}
/// <summary>
/// Get the value of the field.
/// </summary>
/// <returns>Value of the field.</returns>
object IValueField.GetValue()
{
return GetValue();
}
/// <summary>
/// Get the value of the field.
/// </summary>
/// <returns>Value of the field.</returns>
public T GetValue()
{
Assert.IsNotNull(getter);
return getter();
}
/// <summary>
/// Set the value of the field.
/// </summary>
/// <param name="value">Input value.</param>
public void SetValue(object value)
{
SetValue((T)value);
}
/// <summary>
/// Set the value of the field.
/// </summary>
/// <param name="value">Input value.</param>
public void SetValue(T value)
{
Assert.IsNotNull(setter);
var v = ValidateValue(value);
if (!v.Equals(getter()))
{
setter(v);
if (onValueChanged != null)
onValueChanged(this, v);
}
}
}
/// <summary>
/// Boolean field.
/// </summary>
public class BoolField : Field<bool> {}
/// <summary>
/// Boolean field with history.
/// </summary>
public class HistoryBoolField : BoolField
{
/// <summary>
/// History getter for this field.
/// </summary>
public Func<bool>[] historyGetter { get; set; }
/// <summary>
/// Depth of the field's history.
/// </summary>
public int historyDepth => historyGetter?.Length ?? 0;
/// <summary>
/// Get the value of the field at a certain history index.
/// </summary>
/// <param name="historyIndex">Index of the history to query.</param>
/// <returns>Value of the field at the provided history index.</returns>
public bool GetHistoryValue(int historyIndex)
{
Assert.IsNotNull(historyGetter);
Assert.IsTrue(historyIndex >= 0 && historyIndex < historyGetter.Length, "out of range historyIndex");
Assert.IsNotNull(historyGetter[historyIndex]);
return historyGetter[historyIndex]();
}
}
/// <summary>
/// Integer field.
/// </summary>
public class IntField : Field<int>
{
/// <summary>
/// Minimum value function.
/// </summary>
public Func<int> min;
/// <summary>
/// Maximum value function.
/// </summary>
public Func<int> max;
// Runtime-only
/// <summary>
/// Step increment.
/// </summary>
public int incStep = 1;
/// <summary>
/// Step increment multiplier.
/// </summary>
public int intStepMult = 10;
/// <summary>
/// Function used to validate the value when updating the field.
/// </summary>
/// <param name="value">Input value.</param>
/// <returns>Validated value.</returns>
public override int ValidateValue(int value)
{
if (min != null) value = Mathf.Max(value, min());
if (max != null) value = Mathf.Min(value, max());
return value;
}
}
/// <summary>
/// Unsigned integer field.
/// </summary>
public class UIntField : Field<uint>
{
/// <summary>
/// Minimum value function.
/// </summary>
public Func<uint> min;
/// <summary>
/// Maximum value function.
/// </summary>
public Func<uint> max;
// Runtime-only
/// <summary>
/// Step increment.
/// </summary>
public uint incStep = 1u;
/// <summary>
/// Step increment multiplier.
/// </summary>
public uint intStepMult = 10u;
/// <summary>
/// Function used to validate the value when updating the field.
/// </summary>
/// <param name="value">Input value.</param>
/// <returns>Validated value.</returns>
public override uint ValidateValue(uint value)
{
if (min != null) value = (uint)Mathf.Max((int)value, (int)min());
if (max != null) value = (uint)Mathf.Min((int)value, (int)max());
return value;
}
}
/// <summary>
/// Float field.
/// </summary>
public class FloatField : Field<float>
{
/// <summary>
/// Minimum value function.
/// </summary>
public Func<float> min;
/// <summary>
/// Maximum value function.
/// </summary>
public Func<float> max;
// Runtime-only
/// <summary>
/// Step increment.
/// </summary>
public float incStep = 0.1f;
/// <summary>
/// Step increment multiplier.
/// </summary>
public float incStepMult = 10f;
/// <summary>
/// Number of decimals.
/// </summary>
public int decimals = 3;
/// <summary>
/// Function used to validate the value when updating the field.
/// </summary>
/// <param name="value">Input value.</param>
/// <returns>Validated value.</returns>
public override float ValidateValue(float value)
{
if (min != null) value = Mathf.Max(value, min());
if (max != null) value = Mathf.Min(value, max());
return value;
}
}
/// <summary>
/// Enumerator field.
/// </summary>
public class EnumField : Field<int>
{
/// <summary>
/// List of names of the enumerator entries.
/// </summary>
public GUIContent[] enumNames;
/// <summary>
/// List of values of the enumerator entries.
/// </summary>
public int[] enumValues;
internal int[] quickSeparators;
internal int[] indexes;
/// <summary>
/// Get the enumeration value index.
/// </summary>
public Func<int> getIndex { get; set; }
/// <summary>
/// Set the enumeration value index.
/// </summary>
public Action<int> setIndex { get; set; }
/// <summary>
/// Current enumeration value index.
/// </summary>
public int currentIndex { get { return getIndex(); } set { setIndex(value); } }
/// <summary>
/// Generates enumerator values and names automatically based on the provided type.
/// </summary>
public Type autoEnum
{
set
{
enumNames = Enum.GetNames(value).Select(x => new GUIContent(x)).ToArray();
// Linq.Cast<T> on a typeless Array breaks the JIT on PS4/Mono so we have to do it manually
//enumValues = Enum.GetValues(value).Cast<int>().ToArray();
var values = Enum.GetValues(value);
enumValues = new int[values.Length];
for (int i = 0; i < values.Length; i++)
enumValues[i] = (int)values.GetValue(i);
InitIndexes();
InitQuickSeparators();
}
}
internal void InitQuickSeparators()
{
var enumNamesPrefix = enumNames.Select(x =>
{
string[] splitted = x.text.Split('/');
if (splitted.Length == 1)
return "";
else
return splitted[0];
});
quickSeparators = new int[enumNamesPrefix.Distinct().Count()];
string lastPrefix = null;
for (int i = 0, wholeNameIndex = 0; i < quickSeparators.Length; ++i)
{
var currentTestedPrefix = enumNamesPrefix.ElementAt(wholeNameIndex);
while (lastPrefix == currentTestedPrefix)
{
currentTestedPrefix = enumNamesPrefix.ElementAt(++wholeNameIndex);
}
lastPrefix = currentTestedPrefix;
quickSeparators[i] = wholeNameIndex++;
}
}
internal void InitIndexes()
{
if (enumNames == null)
enumNames = new GUIContent[0];
indexes = new int[enumNames.Length];
for (int i = 0; i < enumNames.Length; i++)
{
indexes[i] = i;
}
}
}
/// <summary>
/// Enumerator field with history.
/// </summary>
public class HistoryEnumField : EnumField
{
/// <summary>
/// History getter for this field.
/// </summary>
public Func<int>[] historyIndexGetter { get; set; }
/// <summary>
/// Depth of the field's history.
/// </summary>
public int historyDepth => historyIndexGetter?.Length ?? 0;
/// <summary>
/// Get the value of the field at a certain history index.
/// </summary>
/// <param name="historyIndex">Index of the history to query.</param>
/// <returns>Value of the field at the provided history index.</returns>
public int GetHistoryValue(int historyIndex)
{
Assert.IsNotNull(historyIndexGetter);
Assert.IsTrue(historyIndex >= 0 && historyIndex < historyIndexGetter.Length, "out of range historyIndex");
Assert.IsNotNull(historyIndexGetter[historyIndex]);
return historyIndexGetter[historyIndex]();
}
}
/// <summary>
/// Bitfield enumeration field.
/// </summary>
public class BitField : Field<Enum>
{
/// <summary>
/// List of names of the enumerator entries.
/// </summary>
public GUIContent[] enumNames { get; private set; }
/// <summary>
/// List of values of the enumerator entries.
/// </summary>
public int[] enumValues { get; private set; }
internal Type m_EnumType;
/// <summary>
/// Generates bitfield values and names automatically based on the provided type.
/// </summary>
public Type enumType
{
set
{
enumNames = Enum.GetNames(value).Select(x => new GUIContent(x)).ToArray();
// Linq.Cast<T> on a typeless Array breaks the JIT on PS4/Mono so we have to do it manually
//enumValues = Enum.GetValues(value).Cast<int>().ToArray();
var values = Enum.GetValues(value);
enumValues = new int[values.Length];
for (int i = 0; i < values.Length; i++)
enumValues[i] = (int)values.GetValue(i);
m_EnumType = value;
}
get { return m_EnumType; }
}
}
/// <summary>
/// Color field.
/// </summary>
public class ColorField : Field<Color>
{
/// <summary>
/// HDR color.
/// </summary>
public bool hdr = false;
/// <summary>
/// Show alpha of the color field.
/// </summary>
public bool showAlpha = true;
// Editor-only
/// <summary>
/// Show the color picker.
/// </summary>
public bool showPicker = true;
// Runtime-only
/// <summary>
/// Step increment.
/// </summary>
public float incStep = 0.025f;
/// <summary>
/// Step increment multiplier.
/// </summary>
public float incStepMult = 5f;
/// <summary>
/// Number of decimals.
/// </summary>
public int decimals = 3;
/// <summary>
/// Function used to validate the value when updating the field.
/// </summary>
/// <param name="value">Input value.</param>
/// <returns>Validated value.</returns>
public override Color ValidateValue(Color value)
{
if (!hdr)
{
value.r = Mathf.Clamp01(value.r);
value.g = Mathf.Clamp01(value.g);
value.b = Mathf.Clamp01(value.b);
value.a = Mathf.Clamp01(value.a);
}
return value;
}
}
/// <summary>
/// Vector2 field.
/// </summary>
public class Vector2Field : Field<Vector2>
{
// Runtime-only
/// <summary>
/// Step increment.
/// </summary>
public float incStep = 0.025f;
/// <summary>
/// Step increment multiplier.
/// </summary>
public float incStepMult = 10f;
/// <summary>
/// Number of decimals.
/// </summary>
public int decimals = 3;
}
/// <summary>
/// Vector3 field.
/// </summary>
public class Vector3Field : Field<Vector3>
{
// Runtime-only
/// <summary>
/// Step increment.
/// </summary>
public float incStep = 0.025f;
/// <summary>
/// Step increment multiplier.
/// </summary>
public float incStepMult = 10f;
/// <summary>
/// Number of decimals.
/// </summary>
public int decimals = 3;
}
/// <summary>
/// Vector4 field.
/// </summary>
public class Vector4Field : Field<Vector4>
{
// Runtime-only
/// <summary>
/// Step increment.
/// </summary>
public float incStep = 0.025f;
/// <summary>
/// Step increment multiplier.
/// </summary>
public float incStepMult = 10f;
/// <summary>
/// Number of decimals.
/// </summary>
public int decimals = 3;
}
}
}

View File

@@ -0,0 +1,133 @@
using System;
namespace UnityEngine.Rendering
{
public partial class DebugUI
{
// Root panel class - we don't want to extend Container here because we need a clear
// separation between debug panels and actual widgets
/// <summary>
/// Root panel class.
/// </summary>
public class Panel : IContainer, IComparable<Panel>
{
/// <summary>
/// Widget flags for this panel.
/// </summary>
public Flags flags { get; set; }
/// <summary>
/// Display name of the panel.
/// </summary>
public string displayName { get; set; }
/// <summary>
/// Group index of the panel.
/// </summary>
public int groupIndex { get; set; }
/// <summary>
/// Path of the panel.
/// </summary>
public string queryPath { get { return displayName; } }
/// <summary>
/// Specify if the panel is editor only.
/// </summary>
public bool isEditorOnly { get { return (flags & Flags.EditorOnly) != 0; } }
/// <summary>
/// Specify if the panel is runtime only.
/// </summary>
public bool isRuntimeOnly { get { return (flags & Flags.RuntimeOnly) != 0; } }
/// <summary>
/// Returns true if the panel is inactive in the editor.
/// </summary>
public bool isInactiveInEditor { get { return (isRuntimeOnly && !Application.isPlaying); } }
/// <summary>
/// Returns true if the panel should always be updated.
/// </summary>
public bool editorForceUpdate { get { return (flags & Flags.EditorForceUpdate) != 0; } }
/// <summary>
/// List of children.
/// </summary>
public ObservableList<Widget> children { get; private set; }
/// <summary>
/// Callback used when the panel is set dirty.
/// </summary>
public event Action<Panel> onSetDirty = delegate {};
/// <summary>
/// Constructor.
/// </summary>
public Panel()
{
children = new ObservableList<Widget>();
children.ItemAdded += OnItemAdded;
children.ItemRemoved += OnItemRemoved;
}
/// <summary>
/// Callback used when a child is added.
/// </summary>
/// <param name="sender">Sender widget.</param>
/// <param name="e">List of added children.</param>
protected virtual void OnItemAdded(ObservableList<Widget> sender, ListChangedEventArgs<Widget> e)
{
if (e.item != null)
{
e.item.panel = this;
e.item.parent = this;
}
SetDirty();
}
/// <summary>
/// Callback used when a child is removed.
/// </summary>
/// <param name="sender">Sender widget.</param>
/// <param name="e">List of removed children.</param>
protected virtual void OnItemRemoved(ObservableList<Widget> sender, ListChangedEventArgs<Widget> e)
{
if (e.item != null)
{
e.item.panel = null;
e.item.parent = null;
}
SetDirty();
}
/// <summary>
/// Set the panel dirty.
/// </summary>
public void SetDirty()
{
foreach (var child in children)
child.GenerateQueryPath();
onSetDirty(this);
}
/// <summary>
/// Returns the hash code of the panel.
/// </summary>
/// <returns>Hash code of the panel.</returns>
public override int GetHashCode()
{
int hash = 17;
hash = hash * 23 + displayName.GetHashCode();
foreach (var child in children)
hash = hash * 23 + child.GetHashCode();
return hash;
}
/// <summary>
/// Comparison function.
/// </summary>
/// <param name="other">Panel to compare to.</param>
/// <returns>True if the panels share the same group index.</returns>
int IComparable<Panel>.CompareTo(Panel other) => other == null ? 1 : groupIndex.CompareTo(other.groupIndex);
}
}
}

View File

@@ -0,0 +1,197 @@
using System;
using UnityEngine.Assertions;
namespace UnityEngine.Rendering
{
/// <summary>
/// Debug UI Class
/// </summary>
public partial class DebugUI
{
/// <summary>
/// Flags for Debug UI widgets.
/// </summary>
[Flags]
public enum Flags
{
/// <summary>
/// None.
/// </summary>
None = 0,
/// <summary>
/// This widget is Editor only.
/// </summary>
EditorOnly = 1 << 1,
/// <summary>
/// This widget is Runtime only.
/// </summary>
RuntimeOnly = 1 << 2,
/// <summary>
/// This widget will force the Debug Editor Window refresh.
/// </summary>
EditorForceUpdate = 1 << 3
}
/// <summary>
/// Base class for all debug UI widgets.
/// </summary>
public abstract class Widget
{
// Set to null until it's added to a panel, be careful
/// <summary>
/// Panels containing the widget.
/// </summary>
protected Panel m_Panel;
/// <summary>
/// Panels containing the widget.
/// </summary>
public virtual Panel panel
{
get { return m_Panel; }
internal set { m_Panel = value; }
}
/// <summary>
/// Parent container.
/// </summary>
protected IContainer m_Parent;
/// <summary>
/// Parent container.
/// </summary>
public virtual IContainer parent
{
get { return m_Parent; }
internal set { m_Parent = value; }
}
/// <summary>
/// Flags for the widget.
/// </summary>
public Flags flags { get; set; }
/// <summary>
/// Display name.
/// </summary>
public string displayName { get; set; }
/// <summary>
/// Path of the widget.
/// </summary>
public string queryPath { get; private set; }
/// <summary>
/// True if the widget is Editor only.
/// </summary>
public bool isEditorOnly { get { return (flags & Flags.EditorOnly) != 0; } }
/// <summary>
/// True if the widget is Runtime only.
/// </summary>
public bool isRuntimeOnly { get { return (flags & Flags.RuntimeOnly) != 0; } }
/// <summary>
/// True if the widget is inactive in the editor (ie: widget is runtime only and the application is not 'Playing')
/// </summary>
public bool isInactiveInEditor { get { return (isRuntimeOnly && !Application.isPlaying); } }
internal virtual void GenerateQueryPath()
{
queryPath = displayName.Trim();
if (m_Parent != null)
queryPath = m_Parent.queryPath + " -> " + queryPath;
}
/// <summary>
/// Returns the hash code of the widget.
/// </summary>
/// <returns>The hash code of the widget.</returns>
public override int GetHashCode()
{
return queryPath.GetHashCode();
}
}
/// <summary>
/// Interface for widgets that can contain other widgets.
/// </summary>
public interface IContainer
{
/// <summary>
/// List of children of the container.
/// </summary>
ObservableList<Widget> children { get; }
/// <summary>
/// Display name of the container.
/// </summary>
string displayName { get; set; }
/// <summary>
/// Path of the container.
/// </summary>
string queryPath { get; }
}
/// <summary>
/// Any widget that implements this will be considered for serialization (only if the setter is set and thus is not read-only)
/// </summary>
public interface IValueField
{
/// <summary>
/// Return the value of the field.
/// </summary>
/// <returns>Value of the field.</returns>
object GetValue();
/// <summary>
/// Set the value of the field.
/// </summary>
/// <param name="value">Input value.</param>
void SetValue(object value);
/// <summary>
/// Function used to validate the value when setting it.
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
object ValidateValue(object value);
}
// Miscellaneous
/// <summary>
/// Button widget.
/// </summary>
public class Button : Widget
{
/// <summary>
/// Action performed by the button.
/// </summary>
public Action action { get; set; }
}
/// <summary>
/// Read only Value widget.
/// </summary>
public class Value : Widget
{
/// <summary>
/// Getter for the Value.
/// </summary>
public Func<object> getter { get; set; }
/// <summary>
/// Refresh rate for the read-only value (runtime only)
/// </summary>
public float refreshRate = 0.1f;
/// <summary>
/// Constructor.
/// </summary>
public Value() { displayName = ""; }
/// <summary>
/// Returns the value of the widget.
/// </summary>
/// <returns>The value of the widget.</returns>
public object GetValue()
{
Assert.IsNotNull(getter);
return getter();
}
}
}
}

View File

@@ -0,0 +1,27 @@
namespace UnityEngine.Rendering
{
class DebugUpdater : MonoBehaviour
{
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterSceneLoad)]
static void RuntimeInit()
{
if (!Debug.isDebugBuild || FindObjectOfType<DebugUpdater>() != null)
return;
var go = new GameObject { name = "[Debug Updater]" };
go.AddComponent<DebugUpdater>();
DontDestroyOnLoad(go);
}
void Update()
{
DebugManager.instance.UpdateActions();
if (DebugManager.instance.GetAction(DebugAction.EnableDebugMenu) != 0.0f)
DebugManager.instance.displayRuntimeUI = !DebugManager.instance.displayRuntimeUI;
if (DebugManager.instance.displayRuntimeUI && DebugManager.instance.GetAction(DebugAction.ResetAll) != 0.0f)
DebugManager.instance.Reset();
}
}
}

View File

@@ -0,0 +1,205 @@
#if ENABLE_INPUT_SYSTEM && ENABLE_INPUT_SYSTEM_PACKAGE
#define USE_INPUT_SYSTEM
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
#endif
using UnityEditor;
namespace UnityEngine.Rendering
{
/// <summary>
/// Provides mouse position for debugging purpose.
/// </summary>
public class MousePositionDebug
{
// Singleton
private static MousePositionDebug s_Instance = null;
/// <summary>
/// Singleton instance.
/// </summary>
static public MousePositionDebug instance
{
get
{
if (s_Instance == null)
{
s_Instance = new MousePositionDebug();
}
return s_Instance;
}
}
#if UNITY_EDITOR
[ExecuteAlways]
class GameViewEventCatcher : MonoBehaviour
{
public static GameViewEventCatcher s_Instance = null;
public static void Cleanup()
{
if (s_Instance != null)
{
// Either we call DestroyImmediate or Destroy we get an error :(
// GameViewEventCatcher is only use for SSR debugging currently so comment this code and uncomment it if you want to debug SSR
//DestroyImmediate(s_Instance.gameObject);
//Destroy(s_Instance.gameObject);
}
}
public static void Build()
{
Cleanup();
var go = new GameObject("__GameViewEventCatcher");
go.hideFlags = HideFlags.HideAndDontSave;
s_Instance = go.AddComponent<GameViewEventCatcher>();
}
void Update()
{
Vector2 mousePosition;
bool rightClickPressed = false;
bool endKeyPressed = false;
#if USE_INPUT_SYSTEM
mousePosition = Pointer.current != null ? Pointer.current.position.ReadValue() : new Vector2(-1, -1);
if (Mouse.current != null)
rightClickPressed = Mouse.current.rightButton.isPressed;
if (Keyboard.current != null)
endKeyPressed = Keyboard.current.endKey.isPressed;
#else
mousePosition = Input.mousePosition;
rightClickPressed = Input.GetMouseButton(1);
endKeyPressed = Input.GetKey(KeyCode.End);
#endif
if (mousePosition.x < 0
|| mousePosition.y < 0
|| mousePosition.x > Screen.width
|| mousePosition.y > Screen.height)
return;
instance.m_mousePosition = mousePosition;
instance.m_mousePosition.y = Screen.height - instance.m_mousePosition.y;
if (rightClickPressed)
instance.m_MouseClickPosition = instance.m_mousePosition;
if (endKeyPressed)
instance.m_MouseClickPosition = instance.m_mousePosition;
}
}
private Vector2 m_mousePosition = Vector2.zero;
Vector2 m_MouseClickPosition = Vector2.zero;
private void OnSceneGUI(UnityEditor.SceneView sceneview)
{
m_mousePosition = Event.current.mousePosition;
switch (Event.current.type)
{
case EventType.MouseDown:
m_MouseClickPosition = m_mousePosition;
break;
case EventType.KeyDown:
switch (Event.current.keyCode)
{
case KeyCode.End:
// Usefull we you don't want to change the scene viewport but still update the mouse click position
m_MouseClickPosition = m_mousePosition;
sceneview.Repaint();
break;
}
break;
}
}
#endif
/// <summary>
/// Initialize the MousePositionDebug class.
/// </summary>
public void Build()
{
#if UNITY_EDITOR
UnityEditor.SceneView.duringSceneGui -= OnSceneGUI;
UnityEditor.SceneView.duringSceneGui += OnSceneGUI;
// Disabled as it cause error: GameViewEventCatcher is only use for SSR debugging currently so comment this code and uncomment it if you want to debug SSR
//GameViewEventCatcher.Build();
#endif
}
/// <summary>
/// Cleanup the MousePositionDebug class.
/// </summary>
public void Cleanup()
{
#if UNITY_EDITOR
UnityEditor.SceneView.duringSceneGui -= OnSceneGUI;
// Disabled as it cause error: GameViewEventCatcher is only use for SSR debugging currently so comment this code and uncomment it if you want to debug SSR
//GameViewEventCatcher.Cleanup();
#endif
}
/// <summary>
/// Get the mouse position in the scene or game view.
/// </summary>
/// <param name="ScreenHeight">Window height.</param>
/// <param name="sceneView">Get position in the scene view?</param>
/// <returns>Coordinates of the mouse in the specified window.</returns>
public Vector2 GetMousePosition(float ScreenHeight, bool sceneView)
{
#if UNITY_EDITOR
if (sceneView)
{
// In play mode, m_mousePosition the one in the scene view
Vector2 mousePixelCoord = m_mousePosition;
mousePixelCoord.y = (ScreenHeight - 1.0f) - mousePixelCoord.y;
return mousePixelCoord;
}
else
{
// In play mode, Input.mousecoords matches the position in the game view
if (EditorApplication.isPlayingOrWillChangePlaymode)
{
return GetInputMousePosition();
}
else
{
// In non-play mode, only m_mousePosition is valid.
// We force -1, -1 as a game view pixel pos to avoid
// rendering un-wanted effects
return new Vector2(-1.0f, -1.0f);
}
}
#else
// In app mode, we only use the Input.mousecoords
return GetInputMousePosition();
#endif
}
Vector2 GetInputMousePosition()
{
#if USE_INPUT_SYSTEM
return Pointer.current != null ? Pointer.current.position.ReadValue() : new Vector2(-1, -1);
#else
return Input.mousePosition;
#endif
}
/// <summary>
/// Returns the position of the mouse click.
/// </summary>
/// <param name="ScreenHeight">Window height.</param>
/// <returns>The coordinates of the mouse click.</returns>
public Vector2 GetMouseClickPosition(float ScreenHeight)
{
#if UNITY_EDITOR
Vector2 mousePixelCoord = m_MouseClickPosition;
mousePixelCoord.y = (ScreenHeight - 1.0f) - mousePixelCoord.y;
return mousePixelCoord;
#else
return Vector2.zero;
#endif
}
}
}

View File

@@ -0,0 +1,175 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &1153602445894428
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 224711363741255626}
- component: {fileID: 223912878945851142}
- component: {fileID: 114908889885781782}
- component: {fileID: 114649910605725082}
- component: {fileID: 114530362809716058}
m_Layer: 5
m_Name: DebugUI Canvas
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &224711363741255626
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1153602445894428}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 0, y: 0, z: 0}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0, y: 0}
--- !u!223 &223912878945851142
Canvas:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1153602445894428}
m_Enabled: 1
serializedVersion: 3
m_RenderMode: 0
m_Camera: {fileID: 0}
m_PlaneDistance: 100
m_PixelPerfect: 1
m_ReceivesEvents: 1
m_OverrideSorting: 0
m_OverridePixelPerfect: 0
m_SortingBucketNormalizedSize: 0
m_AdditionalShaderChannelsFlag: 0
m_SortingLayerID: 0
m_SortingOrder: 0
m_TargetDisplay: 0
--- !u!114 &114908889885781782
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1153602445894428}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 0cd44c1031e13a943bb63640046fad76, type: 3}
m_Name:
m_EditorClassIdentifier:
m_UiScaleMode: 0
m_ReferencePixelsPerUnit: 100
m_ScaleFactor: 1
m_ReferenceResolution: {x: 800, y: 600}
m_ScreenMatchMode: 0
m_MatchWidthOrHeight: 0
m_PhysicalUnit: 3
m_FallbackScreenDPI: 96
m_DefaultSpriteDPI: 96
m_DynamicPixelsPerUnit: 1
--- !u!114 &114649910605725082
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1153602445894428}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: dc42784cf147c0c48a680349fa168899, type: 3}
m_Name:
m_EditorClassIdentifier:
m_IgnoreReversedGraphics: 1
m_BlockingObjects: 0
m_BlockingMask:
serializedVersion: 2
m_Bits: 4294967295
--- !u!114 &114530362809716058
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1153602445894428}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 76db615e524a19c4990482d75a475543, type: 3}
m_Name:
m_EditorClassIdentifier:
panelPrefab: {fileID: 224481716535368988, guid: daa46a58178a6ad41ae1ddc2dc7f856d, type: 3}
prefabs:
- type: UnityEngine.Rendering.DebugUI+Value, Unity.RenderPipelines.Core.Runtime,
Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
prefab: {fileID: 224720214277421396, guid: dc0f88987826e6e48b1fe9c7c2b53a53, type: 3}
- type: UnityEngine.Rendering.DebugUI+BoolField, Unity.RenderPipelines.Core.Runtime,
Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
prefab: {fileID: 224131888606727344, guid: ce347ad101f41ee4ab5c3fbc0ea447db, type: 3}
- type: UnityEngine.Rendering.DebugUI+IntField, Unity.RenderPipelines.Core.Runtime,
Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
prefab: {fileID: 224720214277421396, guid: ae00bb75e0cd5b04b8fe7fb4ab662629, type: 3}
- type: UnityEngine.Rendering.DebugUI+UIntField, Unity.RenderPipelines.Core.Runtime,
Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
prefab: {fileID: 224720214277421396, guid: f22bcc84a5f4a1944b075a2c4ac71493, type: 3}
- type: UnityEngine.Rendering.DebugUI+FloatField, Unity.RenderPipelines.Core.Runtime,
Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
prefab: {fileID: 224720214277421396, guid: 7d4fd3415ea7dd64bbcfe13fb48a730b, type: 3}
- type: UnityEngine.Rendering.DebugUI+EnumField, Unity.RenderPipelines.Core.Runtime,
Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
prefab: {fileID: 224224135738715566, guid: 988db55689193434fb0b3b89538f978f, type: 3}
- type: UnityEngine.Rendering.DebugUI+Button, Unity.RenderPipelines.Core.Runtime,
Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
prefab: {fileID: 224438017010656346, guid: f6ce33b91f6ffe54cadacbf4bb112440, type: 3}
- type: UnityEngine.Rendering.DebugUI+Foldout, Unity.RenderPipelines.Core.Runtime,
Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
prefab: {fileID: 224053494956566916, guid: 1c87ab2ce8b8b304d98fbe9a734b1f74, type: 3}
- type: UnityEngine.Rendering.DebugUI+ColorField, Unity.RenderPipelines.Core.Runtime,
Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
prefab: {fileID: 224636372931965878, guid: 77c185820dd1a464eac89cae3abccddf, type: 3}
- type: UnityEngine.Rendering.DebugUI+Vector2Field, Unity.RenderPipelines.Core.Runtime,
Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
prefab: {fileID: 224169904409585018, guid: 326f7c58aed965d41bf7805a782d1e44, type: 3}
- type: UnityEngine.Rendering.DebugUI+Vector3Field, Unity.RenderPipelines.Core.Runtime,
Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
prefab: {fileID: 224119945032119512, guid: 94afea5f242d72547979595ba963f335, type: 3}
- type: UnityEngine.Rendering.DebugUI+Vector4Field, Unity.RenderPipelines.Core.Runtime,
Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
prefab: {fileID: 224325631027038092, guid: d47f009476100f545971a81ede14c750, type: 3}
- type: UnityEngine.Rendering.DebugUI+VBox, Unity.RenderPipelines.Core.Runtime,
Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
prefab: {fileID: 224489511352681190, guid: ca3e294656861a64b8aeeb9f916da0a9, type: 3}
- type: UnityEngine.Rendering.DebugUI+HBox, Unity.RenderPipelines.Core.Runtime,
Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
prefab: {fileID: 224719784157228276, guid: f7f5e36797cf0c1408561665c67b179b, type: 3}
- type: UnityEngine.Rendering.DebugUI+Container, Unity.RenderPipelines.Core.Runtime,
Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
prefab: {fileID: 224284813447651300, guid: 38a07789c9e87004dad98c2909f58369, type: 3}
- type: UnityEngine.Rendering.DebugUI+BitField, Unity.RenderPipelines.Core.Runtime,
Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
prefab: {fileID: 5833802642077810669, guid: 7c78b588b2e1f7c4a86ca4a985cf6e4a, type: 3}
- type: UnityEngine.Rendering.DebugUI+HistoryBoolField, Unity.RenderPipelines.Core.Runtime,
Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
prefab: {fileID: 108402283379224504, guid: 5088d0220f0c4df439cf06c5c270eacb, type: 3}
- type: UnityEngine.Rendering.DebugUI+HistoryEnumField, Unity.RenderPipelines.Core.Runtime,
Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
prefab: {fileID: 8535926254376877601, guid: b2da6b27df236b144b3516ed8e7d36ac, type: 3}
- type: UnityEngine.Rendering.DebugUI+Table, Unity.RenderPipelines.Core.Runtime,
Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
prefab: {fileID: 224284813447651300, guid: 38a07789c9e87004dad98c2909f58369, type: 3}
- type: UnityEngine.Rendering.DebugUI+Table+Row, Unity.RenderPipelines.Core.Runtime,
Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
prefab: {fileID: 224053494956566916, guid: 2d019437ff89b8d44949727731cd9357, type: 3}

View File

@@ -0,0 +1,227 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1001 &100100000
Prefab:
m_ObjectHideFlags: 1
serializedVersion: 2
m_Modification:
m_TransformParent: {fileID: 0}
m_Modifications: []
m_RemovedComponents: []
m_ParentPrefab: {fileID: 0}
m_RootGameObject: {fileID: 1822588063230394}
m_IsPrefabParent: 1
--- !u!1 &1388241697787146
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 5
m_Component:
- component: {fileID: 224499400523491650}
- component: {fileID: 222203031975944290}
- component: {fileID: 114530022413994304}
- component: {fileID: 114399612179518328}
- component: {fileID: 114307594989265542}
m_Layer: 5
m_Name: DebugUI Persistent Panel
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!1 &1822588063230394
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 5
m_Component:
- component: {fileID: 224556897823040040}
- component: {fileID: 223125086719629416}
- component: {fileID: 114876729554496680}
- component: {fileID: 114213191034542798}
- component: {fileID: 114605181728370468}
m_Layer: 5
m_Name: DebugUI Persistent Canvas
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &114213191034542798
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1822588063230394}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 1301386320, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
m_Name:
m_EditorClassIdentifier:
m_IgnoreReversedGraphics: 1
m_BlockingObjects: 0
m_BlockingMask:
serializedVersion: 2
m_Bits: 4294967295
--- !u!114 &114307594989265542
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1388241697787146}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 1741964061, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
m_Name:
m_EditorClassIdentifier:
m_HorizontalFit: 0
m_VerticalFit: 1
--- !u!114 &114399612179518328
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1388241697787146}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 1297475563, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Padding:
m_Left: 5
m_Right: 0
m_Top: 0
m_Bottom: 0
m_ChildAlignment: 0
m_Spacing: 0
m_ChildForceExpandWidth: 1
m_ChildForceExpandHeight: 1
m_ChildControlWidth: 1
m_ChildControlHeight: 0
--- !u!114 &114530022413994304
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1388241697787146}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: -765806418, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 0.1, g: 0.1, b: 0.1, a: 0.8509804}
m_RaycastTarget: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
m_Sprite: {fileID: 21300000, guid: 127279d577f25ac4ea17dae3782e5074, type: 3}
m_Type: 0
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
--- !u!114 &114605181728370468
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1822588063230394}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 87177621604658d4e893f55be7cfae4a, type: 3}
m_Name:
m_EditorClassIdentifier:
panel: {fileID: 224499400523491650}
valuePrefab: {fileID: 224720214277421396, guid: dc0f88987826e6e48b1fe9c7c2b53a53,
type: 2}
--- !u!114 &114876729554496680
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1822588063230394}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 1980459831, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
m_Name:
m_EditorClassIdentifier:
m_UiScaleMode: 0
m_ReferencePixelsPerUnit: 100
m_ScaleFactor: 1
m_ReferenceResolution: {x: 800, y: 600}
m_ScreenMatchMode: 0
m_MatchWidthOrHeight: 0
m_PhysicalUnit: 3
m_FallbackScreenDPI: 96
m_DefaultSpriteDPI: 96
m_DynamicPixelsPerUnit: 1
--- !u!222 &222203031975944290
CanvasRenderer:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1388241697787146}
--- !u!223 &223125086719629416
Canvas:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1822588063230394}
m_Enabled: 1
serializedVersion: 3
m_RenderMode: 0
m_Camera: {fileID: 0}
m_PlaneDistance: 100
m_PixelPerfect: 1
m_ReceivesEvents: 1
m_OverrideSorting: 0
m_OverridePixelPerfect: 0
m_SortingBucketNormalizedSize: 0
m_AdditionalShaderChannelsFlag: 0
m_SortingLayerID: 0
m_SortingOrder: 0
m_TargetDisplay: 0
--- !u!224 &224499400523491650
RectTransform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1388241697787146}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 224556897823040040}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 1, y: 1}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: -5, y: -5}
m_SizeDelta: {x: 400, y: 0}
m_Pivot: {x: 1, y: 1}
--- !u!224 &224556897823040040
RectTransform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1822588063230394}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 0, y: 0, z: 0}
m_Children:
- {fileID: 224499400523491650}
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0, y: 0}

View File

@@ -0,0 +1,173 @@
using System.Collections.Generic;
using UnityEngine.UI;
namespace UnityEngine.Rendering.UI
{
/// <summary>
/// DebugUIHandler for Bitfield widget. Require the enum to have a None field set to 0 in it's values.
/// </summary>
public class DebugUIHandlerBitField : DebugUIHandlerWidget
{
/// <summary>Name of the widget.</summary>
public Text nameLabel;
/// <summary>Value toggle.</summary>
public UIFoldout valueToggle;
/// <summary>Toggles for the bitfield.</summary>
public List<DebugUIHandlerIndirectToggle> toggles;
DebugUI.BitField m_Field;
DebugUIHandlerContainer m_Container;
internal override void SetWidget(DebugUI.Widget widget)
{
base.SetWidget(widget);
m_Field = CastWidget<DebugUI.BitField>();
m_Container = GetComponent<DebugUIHandlerContainer>();
nameLabel.text = m_Field.displayName;
int toggleIndex = 0;
foreach (var enumName in m_Field.enumNames)
{
if (toggleIndex >= toggles.Count)
continue;
var toggle = toggles[toggleIndex];
toggle.getter = GetValue;
toggle.setter = SetValue;
toggle.nextUIHandler = toggleIndex < (m_Field.enumNames.Length - 1) ? toggles[toggleIndex + 1] : null;
toggle.previousUIHandler = toggleIndex > 0 ? toggles[toggleIndex - 1] : null;
toggle.parentUIHandler = this;
toggle.index = toggleIndex;
toggle.nameLabel.text = enumName.text;
toggle.Init();
toggleIndex++;
}
;
for (; toggleIndex < toggles.Count; ++toggleIndex)
{
toggles[toggleIndex].transform.SetParent(null);
}
}
bool GetValue(int index)
{
if (index == 0)
{
// None can't be selected
return false;
}
else
{
// We need to remove 1 to the index because there is the None element on top of
// the enum and it doesn't count in the bit field because it's value is 0
index--;
int intValue = System.Convert.ToInt32(m_Field.GetValue());
return (intValue & (1 << index)) != 0;
}
}
void SetValue(int index, bool value)
{
if (index == 0)
{
// None was selected so we reset all the bits to false
m_Field.SetValue(System.Enum.ToObject(m_Field.enumType, 0));
foreach (var toggle in toggles)
{
if (toggle.getter != null)
toggle.UpdateValueLabel();
}
}
else
{
int intValue = System.Convert.ToInt32(m_Field.GetValue());
if (value)
intValue |= m_Field.enumValues[index];
else
intValue &= ~m_Field.enumValues[index];
m_Field.SetValue(System.Enum.ToObject(m_Field.enumType, intValue));
}
}
/// <summary>
/// OnSelection implementation.
/// </summary>
/// <param name="fromNext">True if the selection wrapped around.</param>
/// <param name="previous">Previous widget.</param>
/// <returns>True if the selection is allowed.</returns>
public override bool OnSelection(bool fromNext, DebugUIHandlerWidget previous)
{
if (fromNext || valueToggle.isOn == false)
{
nameLabel.color = colorSelected;
}
else if (valueToggle.isOn)
{
if (m_Container.IsDirectChild(previous))
{
nameLabel.color = colorSelected;
}
else
{
var lastItem = m_Container.GetLastItem();
DebugManager.instance.ChangeSelection(lastItem, false);
}
}
return true;
}
/// <summary>
/// OnDeselection implementation.
/// </summary>
public override void OnDeselection()
{
nameLabel.color = colorDefault;
}
/// <summary>
/// OnIncrement implementation.
/// </summary>
/// <param name="fast">True if incrementing fast.</param>
public override void OnIncrement(bool fast)
{
valueToggle.isOn = true;
}
/// <summary>
/// OnDecrement implementation.
/// </summary>
/// <param name="fast">Trye if decrementing fast.</param>
public override void OnDecrement(bool fast)
{
valueToggle.isOn = false;
}
/// <summary>
/// OnAction implementation.
/// </summary>
public override void OnAction()
{
valueToggle.isOn = !valueToggle.isOn;
}
/// <summary>
/// Next implementation.
/// </summary>
/// <returns>Next widget UI handler, parent if there is none.</returns>
public override DebugUIHandlerWidget Next()
{
if (!valueToggle.isOn || m_Container == null)
return base.Next();
var firstChild = m_Container.GetFirstItem();
if (firstChild == null)
return base.Next();
return firstChild;
}
}
}

View File

@@ -0,0 +1,50 @@
using UnityEngine.UI;
namespace UnityEngine.Rendering.UI
{
/// <summary>
/// DebugUIHandler for Button widget.
/// </summary>
public class DebugUIHandlerButton : DebugUIHandlerWidget
{
/// <summary>Name of the widget.</summary>
public Text nameLabel;
DebugUI.Button m_Field;
internal override void SetWidget(DebugUI.Widget widget)
{
base.SetWidget(widget);
m_Field = CastWidget<DebugUI.Button>();
nameLabel.text = m_Field.displayName;
}
/// <summary>
/// OnSelection implementation.
/// </summary>
/// <param name="fromNext">True if the selection wrapped around.</param>
/// <param name="previous">Previous widget.</param>
/// <returns>State of the widget.</returns>
public override bool OnSelection(bool fromNext, DebugUIHandlerWidget previous)
{
nameLabel.color = colorSelected;
return true;
}
/// <summary>
/// OnDeselection implementation.
/// </summary>
public override void OnDeselection()
{
nameLabel.color = colorDefault;
}
/// <summary>
/// OnAction implementation.
/// </summary>
public override void OnAction()
{
if (m_Field.action != null)
m_Field.action();
}
}
}

View File

@@ -0,0 +1,299 @@
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine.Rendering;
namespace UnityEngine.Rendering.UI
{
/// <summary>
/// Debug UI Prefab bundle.
/// </summary>
[Serializable]
public class DebugUIPrefabBundle
{
/// <summary>type of the widget.</summary>
public string type;
/// <summary>Prefab for the widget.</summary>
public RectTransform prefab;
}
/// <summary>
/// DebugUIHandler for canvas widget.
/// </summary>
public class DebugUIHandlerCanvas : MonoBehaviour
{
int m_DebugTreeState;
Dictionary<Type, Transform> m_PrefabsMap;
/// <summary>Panel prefab.</summary>
public Transform panelPrefab;
/// <summary>List of prefabs.</summary>
public List<DebugUIPrefabBundle> prefabs;
List<DebugUIHandlerPanel> m_UIPanels;
int m_SelectedPanel;
DebugUIHandlerWidget m_SelectedWidget;
string m_CurrentQueryPath;
void OnEnable()
{
if (prefabs == null)
prefabs = new List<DebugUIPrefabBundle>();
if (m_PrefabsMap == null)
m_PrefabsMap = new Dictionary<Type, Transform>();
if (m_UIPanels == null)
m_UIPanels = new List<DebugUIHandlerPanel>();
DebugManager.instance.RegisterRootCanvas(this);
}
void Update()
{
int state = DebugManager.instance.GetState();
if (m_DebugTreeState != state)
{
ResetAllHierarchy();
}
HandleInput();
// Update scroll position in the panel
if (m_UIPanels != null && m_SelectedPanel < m_UIPanels.Count && m_UIPanels[m_SelectedPanel] != null)
m_UIPanels[m_SelectedPanel].ScrollTo(m_SelectedWidget);
}
internal void ResetAllHierarchy()
{
foreach (Transform t in transform)
CoreUtils.Destroy(t.gameObject);
Rebuild();
}
void Rebuild()
{
// Check prefab associations
m_PrefabsMap.Clear();
foreach (var bundle in prefabs)
{
var type = Type.GetType(bundle.type);
if (type != null && bundle.prefab != null)
m_PrefabsMap.Add(type, bundle.prefab);
}
m_UIPanels.Clear();
m_DebugTreeState = DebugManager.instance.GetState();
var panels = DebugManager.instance.panels;
foreach (var panel in panels)
{
if (panel.isEditorOnly || panel.children.Count(x => !x.isEditorOnly) == 0)
continue;
var go = Instantiate(panelPrefab, transform, false).gameObject;
go.name = panel.displayName;
var uiPanel = go.GetComponent<DebugUIHandlerPanel>();
uiPanel.SetPanel(panel);
m_UIPanels.Add(uiPanel);
var container = go.GetComponent<DebugUIHandlerContainer>();
Traverse(panel, container.contentHolder, null);
}
ActivatePanel(m_SelectedPanel, true);
}
void Traverse(DebugUI.IContainer container, Transform parentTransform, DebugUIHandlerWidget parentUIHandler)
{
DebugUIHandlerWidget previousUIHandler = null;
for (int i = 0; i < container.children.Count; i++)
{
var child = container.children[i];
if (child.isEditorOnly)
continue;
Transform prefab;
if (!m_PrefabsMap.TryGetValue(child.GetType(), out prefab))
{
Debug.LogWarning("DebugUI widget doesn't have a prefab: " + child.GetType());
continue;
}
var go = Instantiate(prefab, parentTransform, false).gameObject;
go.name = child.displayName;
var uiHandler = go.GetComponent<DebugUIHandlerWidget>();
if (uiHandler == null)
{
Debug.LogWarning("DebugUI prefab is missing a DebugUIHandler for: " + child.GetType());
continue;
}
if (previousUIHandler != null) previousUIHandler.nextUIHandler = uiHandler;
uiHandler.previousUIHandler = previousUIHandler;
previousUIHandler = uiHandler;
uiHandler.parentUIHandler = parentUIHandler;
uiHandler.SetWidget(child);
var childContainer = go.GetComponent<DebugUIHandlerContainer>();
if (childContainer != null && child is DebugUI.IContainer)
Traverse(child as DebugUI.IContainer, childContainer.contentHolder, uiHandler);
}
}
DebugUIHandlerWidget GetWidgetFromPath(string queryPath)
{
if (string.IsNullOrEmpty(queryPath))
return null;
var panel = m_UIPanels[m_SelectedPanel];
return panel
.GetComponentsInChildren<DebugUIHandlerWidget>()
.FirstOrDefault(w => w.GetWidget().queryPath == queryPath);
}
void ActivatePanel(int index, bool tryAndKeepSelection = false)
{
if (m_UIPanels.Count == 0)
return;
if (index >= m_UIPanels.Count)
index = m_UIPanels.Count - 1;
m_UIPanels.ForEach(p => p.gameObject.SetActive(false));
m_UIPanels[index].gameObject.SetActive(true);
m_SelectedPanel = index;
DebugUIHandlerWidget widget = null;
if (tryAndKeepSelection && !string.IsNullOrEmpty(m_CurrentQueryPath))
{
widget = m_UIPanels[m_SelectedPanel]
.GetComponentsInChildren<DebugUIHandlerWidget>()
.FirstOrDefault(w => w.GetWidget().queryPath == m_CurrentQueryPath);
}
if (widget == null)
widget = m_UIPanels[index].GetFirstItem();
ChangeSelection(widget, true);
}
internal void ChangeSelection(DebugUIHandlerWidget widget, bool fromNext)
{
if (widget == null)
return;
if (m_SelectedWidget != null)
m_SelectedWidget.OnDeselection();
var prev = m_SelectedWidget;
m_SelectedWidget = widget;
if (!m_SelectedWidget.OnSelection(fromNext, prev))
{
if (fromNext)
SelectNextItem();
else
SelectPreviousItem();
}
else
{
if (m_SelectedWidget == null || m_SelectedWidget.GetWidget() == null)
m_CurrentQueryPath = string.Empty;
else
m_CurrentQueryPath = m_SelectedWidget.GetWidget().queryPath;
}
}
void SelectPreviousItem()
{
if (m_SelectedWidget == null)
return;
var newSelection = m_SelectedWidget.Previous();
if (newSelection != null)
ChangeSelection(newSelection, false);
}
void SelectNextItem()
{
if (m_SelectedWidget == null)
return;
var newSelection = m_SelectedWidget.Next();
if (newSelection != null)
ChangeSelection(newSelection, true);
}
void ChangeSelectionValue(float multiplier)
{
if (m_SelectedWidget == null)
return;
bool fast = DebugManager.instance.GetAction(DebugAction.Multiplier) != 0f;
if (multiplier < 0f)
m_SelectedWidget.OnDecrement(fast);
else
m_SelectedWidget.OnIncrement(fast);
}
void ActivateSelection()
{
if (m_SelectedWidget == null)
return;
m_SelectedWidget.OnAction();
}
void HandleInput()
{
if (DebugManager.instance.GetAction(DebugAction.PreviousDebugPanel) != 0f)
{
int index = m_SelectedPanel - 1;
if (index < 0)
index = m_UIPanels.Count - 1;
index = Mathf.Clamp(index, 0, m_UIPanels.Count - 1);
ActivatePanel(index);
}
if (DebugManager.instance.GetAction(DebugAction.NextDebugPanel) != 0f)
{
int index = m_SelectedPanel + 1;
if (index >= m_UIPanels.Count)
index = 0;
index = Mathf.Clamp(index, 0, m_UIPanels.Count - 1);
ActivatePanel(index);
}
if (DebugManager.instance.GetAction(DebugAction.Action) != 0f)
ActivateSelection();
if (DebugManager.instance.GetAction(DebugAction.MakePersistent) != 0f && m_SelectedWidget != null)
DebugManager.instance.TogglePersistent(m_SelectedWidget.GetWidget());
float moveHorizontal = DebugManager.instance.GetAction(DebugAction.MoveHorizontal);
if (moveHorizontal != 0f)
ChangeSelectionValue(moveHorizontal);
float moveVertical = DebugManager.instance.GetAction(DebugAction.MoveVertical);
if (moveVertical != 0f)
{
if (moveVertical < 0f)
SelectNextItem();
else
SelectPreviousItem();
}
}
}
}

View File

@@ -0,0 +1,167 @@
using UnityEngine.UI;
namespace UnityEngine.Rendering.UI
{
/// <summary>
/// DebugUIHandler for color widget.
/// </summary>
public class DebugUIHandlerColor : DebugUIHandlerWidget
{
/// <summary>Name of the widget.</summary>
public Text nameLabel;
/// <summary>/// <summary>Name of the widget.</summary>alue toggle.</summary>
public UIFoldout valueToggle;
/// <summary>Color image.</summary>
public Image colorImage;
/// <summary>Red float field.</summary>
public DebugUIHandlerIndirectFloatField fieldR;
/// <summary>Green float field.</summary>
public DebugUIHandlerIndirectFloatField fieldG;
/// <summary>Blue float field.</summary>
public DebugUIHandlerIndirectFloatField fieldB;
/// <summary>Alpha float field.</summary>
public DebugUIHandlerIndirectFloatField fieldA;
DebugUI.ColorField m_Field;
DebugUIHandlerContainer m_Container;
internal override void SetWidget(DebugUI.Widget widget)
{
base.SetWidget(widget);
m_Field = CastWidget<DebugUI.ColorField>();
m_Container = GetComponent<DebugUIHandlerContainer>();
nameLabel.text = m_Field.displayName;
fieldR.getter = () => m_Field.GetValue().r;
fieldR.setter = x => SetValue(x, r: true);
fieldR.nextUIHandler = fieldG;
SetupSettings(fieldR);
fieldG.getter = () => m_Field.GetValue().g;
fieldG.setter = x => SetValue(x, g: true);
fieldG.previousUIHandler = fieldR;
fieldG.nextUIHandler = fieldB;
SetupSettings(fieldG);
fieldB.getter = () => m_Field.GetValue().b;
fieldB.setter = x => SetValue(x, b: true);
fieldB.previousUIHandler = fieldG;
fieldB.nextUIHandler = m_Field.showAlpha ? fieldA : null;
SetupSettings(fieldB);
fieldA.gameObject.SetActive(m_Field.showAlpha);
fieldA.getter = () => m_Field.GetValue().a;
fieldA.setter = x => SetValue(x, a: true);
fieldA.previousUIHandler = fieldB;
SetupSettings(fieldA);
UpdateColor();
}
void SetValue(float x, bool r = false, bool g = false, bool b = false, bool a = false)
{
var color = m_Field.GetValue();
if (r) color.r = x;
if (g) color.g = x;
if (b) color.b = x;
if (a) color.a = x;
m_Field.SetValue(color);
UpdateColor();
}
void SetupSettings(DebugUIHandlerIndirectFloatField field)
{
field.parentUIHandler = this;
field.incStepGetter = () => m_Field.incStep;
field.incStepMultGetter = () => m_Field.incStepMult;
field.decimalsGetter = () => m_Field.decimals;
field.Init();
}
/// <summary>
/// OnSelection implementation.
/// </summary>
/// <param name="fromNext">True if the selection wrapped around.</param>
/// <param name="previous">Previous widget.</param>
/// <returns>State of the widget.</returns>
public override bool OnSelection(bool fromNext, DebugUIHandlerWidget previous)
{
if (fromNext || valueToggle.isOn == false)
{
nameLabel.color = colorSelected;
}
else if (valueToggle.isOn)
{
if (m_Container.IsDirectChild(previous))
{
nameLabel.color = colorSelected;
}
else
{
var lastItem = m_Container.GetLastItem();
DebugManager.instance.ChangeSelection(lastItem, false);
}
}
return true;
}
/// <summary>
/// OnDeselection implementation.
/// </summary>
public override void OnDeselection()
{
nameLabel.color = colorDefault;
}
/// <summary>
/// OnIncrement implementation.
/// </summary>
/// <param name="fast">True if incrementing fast.</param>
public override void OnIncrement(bool fast)
{
valueToggle.isOn = true;
}
/// <summary>
/// OnDecrement implementation.
/// </summary>
/// <param name="fast">Trye if decrementing fast.</param>
public override void OnDecrement(bool fast)
{
valueToggle.isOn = false;
}
/// <summary>
/// OnAction implementation.
/// </summary>
public override void OnAction()
{
valueToggle.isOn = !valueToggle.isOn;
}
internal void UpdateColor()
{
if (colorImage != null)
colorImage.color = m_Field.GetValue();
}
/// <summary>
/// Next implementation.
/// </summary>
/// <returns>Next child.</returns>
public override DebugUIHandlerWidget Next()
{
if (!valueToggle.isOn || m_Container == null)
return base.Next();
var firstChild = m_Container.GetFirstItem();
if (firstChild == null)
return base.Next();
return firstChild;
}
}
}

View File

@@ -0,0 +1,67 @@
using System.Collections.Generic;
using System.Linq;
namespace UnityEngine.Rendering.UI
{
/// <summary>
/// DebugUIHandler for container widget.
/// </summary>
public class DebugUIHandlerContainer : MonoBehaviour
{
/// <summary>Content holder.</summary>
[SerializeField]
public RectTransform contentHolder;
internal DebugUIHandlerWidget GetFirstItem()
{
if (contentHolder.childCount == 0)
return null;
var items = GetActiveChildren();
if (items.Count == 0)
return null;
return items[0];
}
internal DebugUIHandlerWidget GetLastItem()
{
if (contentHolder.childCount == 0)
return null;
var items = GetActiveChildren();
if (items.Count == 0)
return null;
return items[items.Count - 1];
}
internal bool IsDirectChild(DebugUIHandlerWidget widget)
{
if (contentHolder.childCount == 0)
return false;
return GetActiveChildren()
.Count(x => x == widget) > 0;
}
List<DebugUIHandlerWidget> GetActiveChildren()
{
var list = new List<DebugUIHandlerWidget>();
foreach (Transform t in contentHolder)
{
if (!t.gameObject.activeInHierarchy)
continue;
var c = t.GetComponent<DebugUIHandlerWidget>();
if (c != null)
list.Add(c);
}
return list;
}
}
}

View File

@@ -0,0 +1,180 @@
using System;
using UnityEngine.UI;
namespace UnityEngine.Rendering.UI
{
/// <summary>
/// DebugUIHandler for enumerator widget.
/// </summary>
public class DebugUIHandlerEnumField : DebugUIHandlerWidget
{
/// <summary>Name of the enum field.</summary>
public Text nameLabel;
/// <summary>Value of the enum field.</summary>
public Text valueLabel;
internal protected DebugUI.EnumField m_Field;
internal override void SetWidget(DebugUI.Widget widget)
{
base.SetWidget(widget);
m_Field = CastWidget<DebugUI.EnumField>();
nameLabel.text = m_Field.displayName;
UpdateValueLabel();
}
/// <summary>
/// OnSelection implementation.
/// </summary>
/// <param name="fromNext">True if the selection wrapped around.</param>
/// <param name="previous">Previous widget.</param>
/// <returns>State of the widget.</returns>
public override bool OnSelection(bool fromNext, DebugUIHandlerWidget previous)
{
nameLabel.color = colorSelected;
valueLabel.color = colorSelected;
return true;
}
/// <summary>
/// OnDeselection implementation.
/// </summary>
public override void OnDeselection()
{
nameLabel.color = colorDefault;
valueLabel.color = colorDefault;
}
/// <summary>
/// OnAction implementation.
/// </summary>
public override void OnAction()
{
OnIncrement(false);
}
/// <summary>
/// OnIncrement implementation.
/// </summary>
/// <param name="fast">True if incrementing fast.</param>
public override void OnIncrement(bool fast)
{
if (m_Field.enumValues.Length == 0)
return;
var array = m_Field.enumValues;
int index = m_Field.currentIndex;
if (index == array.Length - 1)
{
index = 0;
}
else
{
if (fast)
{
//check if quickSeparators have not been constructed
//it is the case when not constructed with autoenum
var separators = m_Field.quickSeparators;
if (separators == null)
{
m_Field.InitQuickSeparators();
separators = m_Field.quickSeparators;
}
int idxSup = 0;
for (; idxSup < separators.Length && index + 1 > separators[idxSup]; ++idxSup) ;
if (idxSup == separators.Length)
{
index = 0;
}
else
{
index = separators[idxSup];
}
}
else
{
index += 1;
}
}
m_Field.SetValue(array[index]);
m_Field.currentIndex = index;
UpdateValueLabel();
}
/// <summary>
/// OnDecrement implementation.
/// </summary>
/// <param name="fast">Trye if decrementing fast.</param>
public override void OnDecrement(bool fast)
{
if (m_Field.enumValues.Length == 0)
return;
var array = m_Field.enumValues;
int index = m_Field.currentIndex;
if (index == 0)
{
if (fast)
{
//check if quickSeparators have not been constructed
//it is thecase when not constructed with autoenum
var separators = m_Field.quickSeparators;
if (separators == null)
{
m_Field.InitQuickSeparators();
separators = m_Field.quickSeparators;
}
index = separators[separators.Length - 1];
}
else
{
index = array.Length - 1;
}
}
else
{
if (fast)
{
//check if quickSeparators have not been constructed
//it is the case when not constructed with autoenum
var separators = m_Field.quickSeparators;
if (separators == null)
{
m_Field.InitQuickSeparators();
separators = m_Field.quickSeparators;
}
int idxInf = separators.Length - 1;
for (; idxInf > 0 && index <= separators[idxInf]; --idxInf) ;
index = separators[idxInf];
}
else
{
index -= 1;
}
}
m_Field.SetValue(array[index]);
m_Field.currentIndex = index;
UpdateValueLabel();
}
/// <summary>
/// Update the label of the widget.
/// </summary>
protected virtual void UpdateValueLabel()
{
int index = m_Field.currentIndex;
// Fallback just in case, we may be handling sub/sectionned enums here
if (index < 0)
index = 0;
valueLabel.text = "< " + m_Field.enumNames[index].text + " >";
}
}
}

View File

@@ -0,0 +1,65 @@
using System.Collections;
using UnityEngine.UI;
namespace UnityEngine.Rendering.UI
{
/// <summary>
/// DebugUIHandler for enum with history widget.
/// </summary>
public class DebugUIHandlerEnumHistory : DebugUIHandlerEnumField
{
Text[] historyValues;
const float xDecal = 60f;
internal override void SetWidget(DebugUI.Widget widget)
{
int historyDepth = (widget as DebugUI.HistoryEnumField)?.historyDepth ?? 0;
historyValues = new Text[historyDepth];
for (int index = 0; index < historyDepth; ++index)
{
var historyValue = Instantiate(valueLabel, transform);
Vector3 pos = historyValue.transform.position;
pos.x += (index + 1) * xDecal;
historyValue.transform.position = pos;
var text = historyValue.GetComponent<Text>();
text.color = new Color32(110, 110, 110, 255);
historyValues[index] = text;
}
//this call UpdateValueLabel which will rely on historyToggles
base.SetWidget(widget);
}
/// <summary>
/// Update the label of the widget.
/// </summary>
protected override void UpdateValueLabel()
{
int index = m_Field.currentIndex;
// Fallback just in case, we may be handling sub/sectionned enums here
if (index < 0)
index = 0;
valueLabel.text = m_Field.enumNames[index].text;
DebugUI.HistoryEnumField field = m_Field as DebugUI.HistoryEnumField;
int historyDepth = field?.historyDepth ?? 0;
for (int indexHistory = 0; indexHistory < historyDepth; ++indexHistory)
{
if (indexHistory < historyValues.Length && historyValues[indexHistory] != null)
historyValues[indexHistory].text = field.enumNames[field.GetHistoryValue(indexHistory)].text;
}
if (isActiveAndEnabled)
StartCoroutine(RefreshAfterSanitization());
}
IEnumerator RefreshAfterSanitization()
{
yield return null; //wait one frame
m_Field.currentIndex = m_Field.getIndex();
valueLabel.text = m_Field.enumNames[m_Field.currentIndex].text;
}
}
}

View File

@@ -0,0 +1,77 @@
using UnityEngine.UI;
namespace UnityEngine.Rendering.UI
{
/// <summary>
/// DebugUIHandler for float widget.
/// </summary>
public class DebugUIHandlerFloatField : DebugUIHandlerWidget
{
/// <summary>Name of the enum field.</summary>
public Text nameLabel;
/// <summary>Value of the enum field.</summary>
public Text valueLabel;
DebugUI.FloatField m_Field;
internal override void SetWidget(DebugUI.Widget widget)
{
base.SetWidget(widget);
m_Field = CastWidget<DebugUI.FloatField>();
nameLabel.text = m_Field.displayName;
UpdateValueLabel();
}
/// <summary>
/// OnSelection implementation.
/// </summary>
/// <param name="fromNext">True if the selection wrapped around.</param>
/// <param name="previous">Previous widget.</param>
/// <returns>True if the selection is allowed.</returns>
public override bool OnSelection(bool fromNext, DebugUIHandlerWidget previous)
{
nameLabel.color = colorSelected;
valueLabel.color = colorSelected;
return true;
}
/// <summary>
/// OnDeselection implementation.
/// </summary>
public override void OnDeselection()
{
nameLabel.color = colorDefault;
valueLabel.color = colorDefault;
}
/// <summary>
/// OnIncrement implementation.
/// </summary>
/// <param name="fast">True if incrementing fast.</param>
public override void OnIncrement(bool fast)
{
ChangeValue(fast, 1);
}
/// <summary>
/// OnDecrement implementation.
/// </summary>
/// <param name="fast">Trye if decrementing fast.</param>
public override void OnDecrement(bool fast)
{
ChangeValue(fast, -1);
}
void ChangeValue(bool fast, float multiplier)
{
float value = m_Field.GetValue();
value += m_Field.incStep * (fast ? m_Field.incStepMult : 1f) * multiplier;
m_Field.SetValue(value);
UpdateValueLabel();
}
void UpdateValueLabel()
{
valueLabel.text = m_Field.GetValue().ToString("N" + m_Field.decimals);
}
}
}

View File

@@ -0,0 +1,138 @@
using UnityEngine.UI;
namespace UnityEngine.Rendering.UI
{
/// <summary>
/// DebugUIHandler for foldout widget.
/// </summary>
public class DebugUIHandlerFoldout : DebugUIHandlerWidget
{
/// <summary>Name of the Foldout.</summary>
public Text nameLabel;
/// <summary>Toggle value of the Foldout.</summary>
public UIFoldout valueToggle;
DebugUI.Foldout m_Field;
DebugUIHandlerContainer m_Container;
const float xDecal = 60f;
const float xDecalInit = 230f;
internal override void SetWidget(DebugUI.Widget widget)
{
base.SetWidget(widget);
m_Field = CastWidget<DebugUI.Foldout>();
m_Container = GetComponent<DebugUIHandlerContainer>();
nameLabel.text = m_Field.displayName;
int columnNumber = m_Field.columnLabels?.Length ?? 0;
for (int index = 0; index < columnNumber; ++index)
{
var column = Instantiate(nameLabel.gameObject, GetComponent<DebugUIHandlerContainer>().contentHolder);
column.AddComponent<LayoutElement>().ignoreLayout = true;
var rectTransform = column.transform as RectTransform;
var originalTransform = nameLabel.transform as RectTransform;
rectTransform.anchorMax = rectTransform.anchorMin = new Vector2(0, 1);
rectTransform.sizeDelta = new Vector2(100, 26);
Vector3 pos = originalTransform.anchoredPosition;
pos.x += (index + 1) * xDecal + xDecalInit;
rectTransform.anchoredPosition = pos;
rectTransform.pivot = new Vector2(0, 0.5f);
rectTransform.eulerAngles = new Vector3(0, 0, 13);
var text = column.GetComponent<Text>();
text.fontSize = 15;
text.text = m_Field.columnLabels[index];
}
UpdateValue();
}
/// <summary>
/// OnSelection implementation.
/// </summary>
/// <param name="fromNext">True if the selection wrapped around.</param>
/// <param name="previous">Previous widget.</param>
/// <returns>True if the selection is allowed.</returns>
public override bool OnSelection(bool fromNext, DebugUIHandlerWidget previous)
{
if (fromNext || valueToggle.isOn == false)
{
nameLabel.color = colorSelected;
}
else if (valueToggle.isOn)
{
if (m_Container.IsDirectChild(previous))
{
nameLabel.color = colorSelected;
}
else
{
var lastItem = m_Container.GetLastItem();
DebugManager.instance.ChangeSelection(lastItem, false);
}
}
return true;
}
/// <summary>
/// OnDeselection implementation.
/// </summary>
public override void OnDeselection()
{
nameLabel.color = colorDefault;
}
/// <summary>
/// OnIncrement implementation.
/// </summary>
/// <param name="fast">True if incrementing fast.</param>
public override void OnIncrement(bool fast)
{
m_Field.SetValue(true);
UpdateValue();
}
/// <summary>
/// OnDecrement implementation.
/// </summary>
/// <param name="fast">Trye if decrementing fast.</param>
public override void OnDecrement(bool fast)
{
m_Field.SetValue(false);
UpdateValue();
}
/// <summary>
/// OnAction implementation.
/// </summary>
public override void OnAction()
{
bool value = !m_Field.GetValue();
m_Field.SetValue(value);
UpdateValue();
}
void UpdateValue()
{
valueToggle.isOn = m_Field.GetValue();
}
/// <summary>
/// Next implementation.
/// </summary>
/// <returns>Next widget UI handler, parent if there is none.</returns>
public override DebugUIHandlerWidget Next()
{
if (!m_Field.GetValue() || m_Container == null)
return base.Next();
var firstChild = m_Container.GetFirstItem();
if (firstChild == null)
return base.Next();
return firstChild;
}
}
}

View File

@@ -0,0 +1,64 @@
using UnityEngine.UI;
namespace UnityEngine.Rendering.UI
{
/// <summary>
/// DebugUIHandler for group widget.
/// </summary>
public class DebugUIHandlerGroup : DebugUIHandlerWidget
{
/// <summary>Name of the group.</summary>
public Text nameLabel;
/// <summary>Header of the group.</summary>
public Transform header;
DebugUI.Container m_Field;
DebugUIHandlerContainer m_Container;
internal override void SetWidget(DebugUI.Widget widget)
{
base.SetWidget(widget);
m_Field = CastWidget<DebugUI.Container>();
m_Container = GetComponent<DebugUIHandlerContainer>();
if (string.IsNullOrEmpty(m_Field.displayName))
header.gameObject.SetActive(false);
else
nameLabel.text = m_Field.displayName;
}
/// <summary>
/// OnSelection implementation.
/// </summary>
/// <param name="fromNext">True if the selection wrapped around.</param>
/// <param name="previous">Previous widget.</param>
/// <returns>True if the selection is allowed.</returns>
public override bool OnSelection(bool fromNext, DebugUIHandlerWidget previous)
{
if (!fromNext && !m_Container.IsDirectChild(previous))
{
var lastItem = m_Container.GetLastItem();
DebugManager.instance.ChangeSelection(lastItem, false);
return true;
}
return false;
}
/// <summary>
/// Next implementation.
/// </summary>
/// <returns>Next widget UI handler, parent if there is none.</returns>
public override DebugUIHandlerWidget Next()
{
if (m_Container == null)
return base.Next();
var firstChild = m_Container.GetFirstItem();
if (firstChild == null)
return base.Next();
return firstChild;
}
}
}

View File

@@ -0,0 +1,51 @@
namespace UnityEngine.Rendering.UI
{
/// <summary>
/// DebugUIHandler for Horizontal Layout widget.
/// </summary>
public class DebugUIHandlerHBox : DebugUIHandlerWidget
{
DebugUIHandlerContainer m_Container;
internal override void SetWidget(DebugUI.Widget widget)
{
base.SetWidget(widget);
m_Container = GetComponent<DebugUIHandlerContainer>();
}
/// <summary>
/// OnSelection implementation.
/// </summary>
/// <param name="fromNext">True if the selection wrapped around.</param>
/// <param name="previous">Previous widget.</param>
/// <returns>True if the selection is allowed.</returns>
public override bool OnSelection(bool fromNext, DebugUIHandlerWidget previous)
{
if (!fromNext && !m_Container.IsDirectChild(previous))
{
var lastItem = m_Container.GetLastItem();
DebugManager.instance.ChangeSelection(lastItem, false);
return true;
}
return false;
}
/// <summary>
/// Next implementation.
/// </summary>
/// <returns>Next widget UI handler, parent if there is none.</returns>
public override DebugUIHandlerWidget Next()
{
if (m_Container == null)
return base.Next();
var firstChild = m_Container.GetFirstItem();
if (firstChild == null)
return base.Next();
return firstChild;
}
}
}

View File

@@ -0,0 +1,100 @@
using System;
using UnityEngine.UI;
namespace UnityEngine.Rendering.UI
{
/// <summary>
/// DebugUIHandler for indirect float widget.
/// </summary>
public class DebugUIHandlerIndirectFloatField : DebugUIHandlerWidget
{
/// <summary>Name of the indirect float field.</summary>
public Text nameLabel;
/// <summary>Value of the indirect float field.</summary>
public Text valueLabel;
/// <summary>
/// Getter function for this indirect widget.
/// </summary>
public Func<float> getter;
/// <summary>
/// Setter function for this indirect widget.
/// </summary>
public Action<float> setter;
/// <summary>
/// Getter function for the increment step of this indirect widget.
/// </summary>
public Func<float> incStepGetter;
/// <summary>
/// Getter function for the increment step multiplier of this indirect widget.
/// </summary>
public Func<float> incStepMultGetter;
/// <summary>
/// Getter function for the number of decimals of this indirect widget.
/// </summary>
public Func<float> decimalsGetter;
/// <summary>
/// Initialize the indirect widget.
/// </summary>
public void Init()
{
UpdateValueLabel();
}
/// <summary>
/// OnSelection implementation.
/// </summary>
/// <param name="fromNext">True if the selection wrapped around.</param>
/// <param name="previous">Previous widget.</param>
/// <returns>True if the selection is allowed.</returns>
public override bool OnSelection(bool fromNext, DebugUIHandlerWidget previous)
{
nameLabel.color = colorSelected;
valueLabel.color = colorSelected;
return true;
}
/// <summary>
/// OnDeselection implementation.
/// </summary>
public override void OnDeselection()
{
nameLabel.color = colorDefault;
valueLabel.color = colorDefault;
}
/// <summary>
/// OnIncrement implementation.
/// </summary>
/// <param name="fast">True if incrementing fast.</param>
public override void OnIncrement(bool fast)
{
ChangeValue(fast, 1);
}
/// <summary>
/// OnDecrement implementation.
/// </summary>
/// <param name="fast">Trye if decrementing fast.</param>
public override void OnDecrement(bool fast)
{
ChangeValue(fast, -1);
}
void ChangeValue(bool fast, float multiplier)
{
float value = getter();
value += incStepGetter() * (fast ? incStepMultGetter() : 1f) * multiplier;
setter(value);
UpdateValueLabel();
}
void UpdateValueLabel()
{
if (valueLabel != null)
valueLabel.text = getter().ToString("N" + decimalsGetter());
}
}
}

View File

@@ -0,0 +1,78 @@
using System;
using UnityEngine.UI;
namespace UnityEngine.Rendering.UI
{
/// <summary>
/// DebugUIHandler for indirect toggle widget.
/// </summary>
public class DebugUIHandlerIndirectToggle : DebugUIHandlerWidget
{
/// <summary>
/// Label of the widget.
/// </summary>
public Text nameLabel;
/// <summary>Toggle of the toggle field.</summary>
public Toggle valueToggle;
/// <summary>Checkmark image.</summary>
public Image checkmarkImage;
/// <summary>
/// Getter function for this indirect widget.
/// </summary>
public Func<int, bool> getter;
/// <summary>
/// Setter function for this indirect widget.
/// </summary>
public Action<int, bool> setter;
// Should not be here, this is a byproduct of the Bitfield UI Handler implementation.
internal int index;
/// <summary>
/// Initialize the indirect widget.
/// </summary>
public void Init()
{
UpdateValueLabel();
}
/// <summary>
/// OnSelection implementation.
/// </summary>
/// <param name="fromNext">True if the selection wrapped around.</param>
/// <param name="previous">Previous widget.</param>
/// <returns>True if the selection is allowed.</returns>
public override bool OnSelection(bool fromNext, DebugUIHandlerWidget previous)
{
nameLabel.color = colorSelected;
checkmarkImage.color = colorSelected;
return true;
}
/// <summary>
/// OnDeselection implementation.
/// </summary>
public override void OnDeselection()
{
nameLabel.color = colorDefault;
checkmarkImage.color = colorDefault;
}
/// <summary>
/// OnAction implementation.
/// </summary>
public override void OnAction()
{
bool value = !getter(index);
setter(index, value);
UpdateValueLabel();
}
internal void UpdateValueLabel()
{
if (valueToggle != null)
valueToggle.isOn = getter(index);
}
}
}

View File

@@ -0,0 +1,78 @@
using UnityEngine.UI;
namespace UnityEngine.Rendering.UI
{
/// <summary>
/// DebugUIHandler for integer widget.
/// </summary>
public class DebugUIHandlerIntField : DebugUIHandlerWidget
{
/// <summary>Name of the int field.</summary>
public Text nameLabel;
/// <summary>Value of the int field.</summary>
public Text valueLabel;
DebugUI.IntField m_Field;
internal override void SetWidget(DebugUI.Widget widget)
{
base.SetWidget(widget);
m_Field = CastWidget<DebugUI.IntField>();
nameLabel.text = m_Field.displayName;
UpdateValueLabel();
}
/// <summary>
/// OnSelection implementation.
/// </summary>
/// <param name="fromNext">True if the selection wrapped around.</param>
/// <param name="previous">Previous widget.</param>
/// <returns>True if the selection is allowed.</returns>
public override bool OnSelection(bool fromNext, DebugUIHandlerWidget previous)
{
nameLabel.color = colorSelected;
valueLabel.color = colorSelected;
return true;
}
/// <summary>
/// OnDeselection implementation.
/// </summary>
public override void OnDeselection()
{
nameLabel.color = colorDefault;
valueLabel.color = colorDefault;
}
/// <summary>
/// OnIncrement implementation.
/// </summary>
/// <param name="fast">True if incrementing fast.</param>
public override void OnIncrement(bool fast)
{
ChangeValue(fast, 1);
}
/// <summary>
/// OnDecrement implementation.
/// </summary>
/// <param name="fast">Trye if decrementing fast.</param>
public override void OnDecrement(bool fast)
{
ChangeValue(fast, -1);
}
void ChangeValue(bool fast, int multiplier)
{
int value = m_Field.GetValue();
value += m_Field.incStep * (fast ? m_Field.intStepMult : 1) * multiplier;
m_Field.SetValue(value);
UpdateValueLabel();
}
void UpdateValueLabel()
{
if (valueLabel != null)
valueLabel.text = m_Field.GetValue().ToString("N0");
}
}
}

View File

@@ -0,0 +1,75 @@
using UnityEngine.UI;
namespace UnityEngine.Rendering.UI
{
/// <summary>
/// DebugUIHandler for panels.
/// </summary>
public class DebugUIHandlerPanel : MonoBehaviour
{
/// <summary>Name of the panel.</summary>
public Text nameLabel;
/// <summary>Scroll rect of the panel.</summary>
public ScrollRect scrollRect;
/// <summary>Viewport of the panel.</summary>
public RectTransform viewport;
RectTransform m_ScrollTransform;
RectTransform m_ContentTransform;
RectTransform m_MaskTransform;
internal protected DebugUI.Panel m_Panel;
void OnEnable()
{
m_ScrollTransform = scrollRect.GetComponent<RectTransform>();
m_ContentTransform = GetComponent<DebugUIHandlerContainer>().contentHolder;
m_MaskTransform = GetComponentInChildren<Mask>(true).rectTransform;
}
internal void SetPanel(DebugUI.Panel panel)
{
m_Panel = panel;
nameLabel.text = "< " + panel.displayName + " >";
}
internal DebugUI.Panel GetPanel()
{
return m_Panel;
}
// TODO: Jumps around with foldouts and the likes, fix me
internal void ScrollTo(DebugUIHandlerWidget target)
{
if (target == null)
return;
var targetTransform = target.GetComponent<RectTransform>();
float itemY = GetYPosInScroll(targetTransform);
float targetY = GetYPosInScroll(m_MaskTransform);
float normalizedDiffY = (targetY - itemY) / (m_ContentTransform.rect.size.y - m_ScrollTransform.rect.size.y);
float normalizedPosY = scrollRect.verticalNormalizedPosition - normalizedDiffY;
normalizedPosY = Mathf.Clamp01(normalizedPosY);
scrollRect.verticalNormalizedPosition = Mathf.Lerp(scrollRect.verticalNormalizedPosition, normalizedPosY, Time.deltaTime * 10f);
}
float GetYPosInScroll(RectTransform target)
{
var pivotOffset = new Vector3(
(0.5f - target.pivot.x) * target.rect.size.x,
(0.5f - target.pivot.y) * target.rect.size.y,
0f
);
var localPos = target.localPosition + pivotOffset;
var worldPos = target.parent.TransformPoint(localPos);
return m_ScrollTransform.TransformPoint(worldPos).y;
}
internal DebugUIHandlerWidget GetFirstItem()
{
return GetComponent<DebugUIHandlerContainer>()
.GetFirstItem();
}
}
}

View File

@@ -0,0 +1,45 @@
using System.Collections.Generic;
using UnityEngine.Rendering;
namespace UnityEngine.Rendering.UI
{
class DebugUIHandlerPersistentCanvas : MonoBehaviour
{
public RectTransform panel;
public RectTransform valuePrefab;
List<DebugUIHandlerValue> m_Items = new List<DebugUIHandlerValue>();
internal void Toggle(DebugUI.Value widget)
{
int index = m_Items.FindIndex(x => x.GetWidget() == widget);
// Remove
if (index > -1)
{
var item = m_Items[index];
CoreUtils.Destroy(item.gameObject);
m_Items.RemoveAt(index);
return;
}
// Add
var go = Instantiate(valuePrefab, panel, false).gameObject;
go.name = widget.displayName;
var uiHandler = go.GetComponent<DebugUIHandlerValue>();
uiHandler.SetWidget(widget);
m_Items.Add(uiHandler);
}
internal void Clear()
{
if (m_Items == null)
return;
foreach (var item in m_Items)
CoreUtils.Destroy(item.gameObject);
m_Items.Clear();
}
}
}

View File

@@ -0,0 +1,81 @@
using UnityEngine.UI;
namespace UnityEngine.Rendering.UI
{
/// <summary>
/// DebugUIHandler for row widget.
/// </summary>
public class DebugUIHandlerRow : DebugUIHandlerFoldout
{
float m_Timer;
/// <summary>
/// OnEnable implementation.
/// </summary>
protected override void OnEnable()
{
m_Timer = 0f;
}
/// <summary>
/// Update implementation.
/// </summary>
protected void Update()
{
var row = CastWidget<DebugUI.Table.Row>();
var table = row.parent as DebugUI.Table;
float refreshRate = 0.1f;
bool refreshRow = m_Timer >= refreshRate;
if (refreshRow)
m_Timer -= refreshRate;
m_Timer += Time.deltaTime;
for (int i = 0; i < row.children.Count; i++)
{
var child = gameObject.transform.GetChild(1).GetChild(i).gameObject;
var active = table.GetColumnVisibility(i);
child.SetActive(active);
if (active && refreshRow)
{
if (child.TryGetComponent<DebugUIHandlerColor>(out var color))
color.UpdateColor();
if (child.TryGetComponent<DebugUIHandlerToggle>(out var toggle))
toggle.UpdateValueLabel();
}
}
// Update previous and next ui handlers to pass over hidden volumes
var item = gameObject.transform.GetChild(1).GetChild(0).gameObject;
var itemWidget = item.GetComponent<DebugUIHandlerWidget>();
DebugUIHandlerWidget previous = null;
for (int i = 0; i < row.children.Count; i++)
{
itemWidget.previousUIHandler = previous;
if (table.GetColumnVisibility(i))
previous = itemWidget;
bool found = false;
for (int j = i + 1; j < row.children.Count; j++)
{
if (table.GetColumnVisibility(j))
{
var child = gameObject.transform.GetChild(1).GetChild(j).gameObject;
var childWidget = child.GetComponent<DebugUIHandlerWidget>();
itemWidget.nextUIHandler = childWidget;
item = child;
itemWidget = childWidget;
i = j - 1;
found = true;
break;
}
}
if (!found)
{
itemWidget.nextUIHandler = null;
break;
}
}
}
}
}

View File

@@ -0,0 +1,68 @@
using UnityEngine.UI;
namespace UnityEngine.Rendering.UI
{
/// <summary>
/// DebugUIHandler for toggle widget.
/// </summary>
public class DebugUIHandlerToggle : DebugUIHandlerWidget
{
/// <summary>Name of the toggle.</summary>
public Text nameLabel;
/// <summary>Value of the toggle.</summary>
public Toggle valueToggle;
/// <summary>Checkermark image.</summary>
public Image checkmarkImage;
internal protected DebugUI.BoolField m_Field;
internal override void SetWidget(DebugUI.Widget widget)
{
base.SetWidget(widget);
m_Field = CastWidget<DebugUI.BoolField>();
nameLabel.text = m_Field.displayName;
UpdateValueLabel();
}
/// <summary>
/// OnSelection implementation.
/// </summary>
/// <param name="fromNext">True if the selection wrapped around.</param>
/// <param name="previous">Previous widget.</param>
/// <returns>True if the selection is allowed.</returns>
public override bool OnSelection(bool fromNext, DebugUIHandlerWidget previous)
{
nameLabel.color = colorSelected;
checkmarkImage.color = colorSelected;
return true;
}
/// <summary>
/// OnDeselection implementation.
/// </summary>
public override void OnDeselection()
{
nameLabel.color = colorDefault;
checkmarkImage.color = colorDefault;
}
/// <summary>
/// OnAction implementation.
/// </summary>
public override void OnAction()
{
bool value = !m_Field.GetValue();
m_Field.SetValue(value);
UpdateValueLabel();
}
/// <summary>
/// Update the label.
/// </summary>
internal protected virtual void UpdateValueLabel()
{
if (valueToggle != null)
valueToggle.isOn = m_Field.GetValue();
}
}
}

View File

@@ -0,0 +1,60 @@
using System.Collections;
using UnityEngine.UI;
namespace UnityEngine.Rendering.UI
{
/// <summary>
/// DebugUIHandler for toggle with history widget.
/// </summary>
public class DebugUIHandlerToggleHistory : DebugUIHandlerToggle
{
Toggle[] historyToggles;
const float xDecal = 60f;
internal override void SetWidget(DebugUI.Widget widget)
{
int historyDepth = (widget as DebugUI.HistoryBoolField)?.historyDepth ?? 0;
historyToggles = new Toggle[historyDepth];
for (int index = 0; index < historyDepth; ++index)
{
var historyToggle = Instantiate(valueToggle, transform);
Vector3 pos = historyToggle.transform.position;
pos.x += (index + 1) * xDecal;
historyToggle.transform.position = pos;
var background = historyToggle.transform.GetChild(0).GetComponent<Image>();
background.sprite = Sprite.Create(Texture2D.whiteTexture, new Rect(-1, -1, 2, 2), Vector2.zero);
background.color = new Color32(50, 50, 50, 120);
var checkmark = background.transform.GetChild(0).GetComponent<Image>();
checkmark.color = new Color32(110, 110, 110, 255);
historyToggles[index] = historyToggle.GetComponent<Toggle>();
}
//this call UpdateValueLabel which will rely on historyToggles
base.SetWidget(widget);
}
/// <summary>
/// Update the label.
/// </summary>
internal protected override void UpdateValueLabel()
{
base.UpdateValueLabel();
DebugUI.HistoryBoolField field = m_Field as DebugUI.HistoryBoolField;
int historyDepth = field?.historyDepth ?? 0;
for (int index = 0; index < historyDepth; ++index)
{
if (index < historyToggles.Length && historyToggles[index] != null)
historyToggles[index].isOn = field.GetHistoryValue(index);
}
if (isActiveAndEnabled)
StartCoroutine(RefreshAfterSanitization());
}
IEnumerator RefreshAfterSanitization()
{
yield return null; //wait one frame
valueToggle.isOn = m_Field.getter();
}
}
}

View File

@@ -0,0 +1,83 @@
using System;
using UnityEngine.UI;
namespace UnityEngine.Rendering.UI
{
/// <summary>
/// DebugUIHandler for unsigned integer widget.
/// </summary>
public class DebugUIHandlerUIntField : DebugUIHandlerWidget
{
/// <summary>Name of the indirect uint field.</summary>
public Text nameLabel;
/// <summary>Value of the indirect uint field.</summary>
public Text valueLabel;
DebugUI.UIntField m_Field;
internal override void SetWidget(DebugUI.Widget widget)
{
base.SetWidget(widget);
m_Field = CastWidget<DebugUI.UIntField>();
nameLabel.text = m_Field.displayName;
UpdateValueLabel();
}
/// <summary>
/// OnSelection implementation.
/// </summary>
/// <param name="fromNext">True if the selection wrapped around.</param>
/// <param name="previous">Previous widget.</param>
/// <returns>True if the selection is allowed.</returns>
public override bool OnSelection(bool fromNext, DebugUIHandlerWidget previous)
{
nameLabel.color = colorSelected;
valueLabel.color = colorSelected;
return true;
}
/// <summary>
/// OnDeselection implementation.
/// </summary>
public override void OnDeselection()
{
nameLabel.color = colorDefault;
valueLabel.color = colorDefault;
}
/// <summary>
/// OnIncrement implementation.
/// </summary>
/// <param name="fast">True if incrementing fast.</param>
public override void OnIncrement(bool fast)
{
ChangeValue(fast, 1);
}
/// <summary>
/// OnDecrement implementation.
/// </summary>
/// <param name="fast">Trye if decrementing fast.</param>
public override void OnDecrement(bool fast)
{
ChangeValue(fast, -1);
}
void ChangeValue(bool fast, int multiplier)
{
long value = m_Field.GetValue();
if (value == 0 && multiplier < 0)
return;
value += m_Field.incStep * (fast ? m_Field.intStepMult : 1) * multiplier;
m_Field.SetValue((uint)value);
UpdateValueLabel();
}
void UpdateValueLabel()
{
if (valueLabel != null)
valueLabel.text = m_Field.GetValue().ToString("N0");
}
}
}

View File

@@ -0,0 +1,51 @@
namespace UnityEngine.Rendering.UI
{
/// <summary>
/// DebugUIHandler for vertical layoyut widget.
/// </summary>
public class DebugUIHandlerVBox : DebugUIHandlerWidget
{
DebugUIHandlerContainer m_Container;
internal override void SetWidget(DebugUI.Widget widget)
{
base.SetWidget(widget);
m_Container = GetComponent<DebugUIHandlerContainer>();
}
/// <summary>
/// OnSelection implementation.
/// </summary>
/// <param name="fromNext">True if the selection wrapped around.</param>
/// <param name="previous">Previous widget.</param>
/// <returns>True if the selection is allowed.</returns>
public override bool OnSelection(bool fromNext, DebugUIHandlerWidget previous)
{
if (!fromNext && !m_Container.IsDirectChild(previous))
{
var lastItem = m_Container.GetLastItem();
DebugManager.instance.ChangeSelection(lastItem, false);
return true;
}
return false;
}
/// <summary>
/// Next implementation.
/// </summary>
/// <returns>Next widget UI handler, parent if there is none.</returns>
public override DebugUIHandlerWidget Next()
{
if (m_Container == null)
return base.Next();
var firstChild = m_Container.GetFirstItem();
if (firstChild == null)
return base.Next();
return firstChild;
}
}
}

View File

@@ -0,0 +1,66 @@
using UnityEngine.UI;
namespace UnityEngine.Rendering.UI
{
/// <summary>
/// DebugUIHandler for value widgets.
/// </summary>
public class DebugUIHandlerValue : DebugUIHandlerWidget
{
/// <summary>Name of the value field.</summary>
public Text nameLabel;
/// <summary>Value of the value field.</summary>
public Text valueLabel;
DebugUI.Value m_Field;
float m_Timer;
/// <summary>
/// OnEnable implementation.
/// </summary>
protected override void OnEnable()
{
m_Timer = 0f;
}
internal override void SetWidget(DebugUI.Widget widget)
{
base.SetWidget(widget);
m_Field = CastWidget<DebugUI.Value>();
nameLabel.text = m_Field.displayName;
}
/// <summary>
/// OnSelection implementation.
/// </summary>
/// <param name="fromNext">True if the selection wrapped around.</param>
/// <param name="previous">Previous widget.</param>
/// <returns>True if the selection is allowed.</returns>
public override bool OnSelection(bool fromNext, DebugUIHandlerWidget previous)
{
nameLabel.color = colorSelected;
valueLabel.color = colorSelected;
return true;
}
/// <summary>
/// OnDeselection implementation.
/// </summary>
public override void OnDeselection()
{
nameLabel.color = colorDefault;
valueLabel.color = colorDefault;
}
void Update()
{
if (m_Timer >= m_Field.refreshRate)
{
valueLabel.text = m_Field.GetValue().ToString();
m_Timer -= m_Field.refreshRate;
}
m_Timer += Time.deltaTime;
}
}
}

View File

@@ -0,0 +1,137 @@
using UnityEngine.UI;
namespace UnityEngine.Rendering.UI
{
/// <summary>
/// DebugUIHandler for vector2 widgets.
/// </summary>
public class DebugUIHandlerVector2 : DebugUIHandlerWidget
{
/// <summary>Name of the Vector2 field.</summary>
public Text nameLabel;
/// <summary>Value of the Vector2 toggle.</summary>
public UIFoldout valueToggle;
/// <summary>X float field.</summary>
public DebugUIHandlerIndirectFloatField fieldX;
/// <summary>Y float field.</summary>
public DebugUIHandlerIndirectFloatField fieldY;
DebugUI.Vector2Field m_Field;
DebugUIHandlerContainer m_Container;
internal override void SetWidget(DebugUI.Widget widget)
{
base.SetWidget(widget);
m_Field = CastWidget<DebugUI.Vector2Field>();
m_Container = GetComponent<DebugUIHandlerContainer>();
nameLabel.text = m_Field.displayName;
fieldX.getter = () => m_Field.GetValue().x;
fieldX.setter = x => SetValue(x, x: true);
fieldX.nextUIHandler = fieldY;
SetupSettings(fieldX);
fieldY.getter = () => m_Field.GetValue().y;
fieldY.setter = x => SetValue(x, y: true);
fieldY.previousUIHandler = fieldX;
SetupSettings(fieldY);
}
void SetValue(float v, bool x = false, bool y = false)
{
var vec = m_Field.GetValue();
if (x) vec.x = v;
if (y) vec.y = v;
m_Field.SetValue(vec);
}
void SetupSettings(DebugUIHandlerIndirectFloatField field)
{
field.parentUIHandler = this;
field.incStepGetter = () => m_Field.incStep;
field.incStepMultGetter = () => m_Field.incStepMult;
field.decimalsGetter = () => m_Field.decimals;
field.Init();
}
/// <summary>
/// OnSelection implementation.
/// </summary>
/// <param name="fromNext">True if the selection wrapped around.</param>
/// <param name="previous">Previous widget.</param>
/// <returns>True if the selection is allowed.</returns>
public override bool OnSelection(bool fromNext, DebugUIHandlerWidget previous)
{
if (fromNext || valueToggle.isOn == false)
{
nameLabel.color = colorSelected;
}
else if (valueToggle.isOn)
{
if (m_Container.IsDirectChild(previous))
{
nameLabel.color = colorSelected;
}
else
{
var lastItem = m_Container.GetLastItem();
DebugManager.instance.ChangeSelection(lastItem, false);
}
}
return true;
}
/// <summary>
/// OnDeselection implementation.
/// </summary>
public override void OnDeselection()
{
nameLabel.color = colorDefault;
}
/// <summary>
/// OnIncrement implementation.
/// </summary>
/// <param name="fast">True if incrementing fast.</param>
public override void OnIncrement(bool fast)
{
valueToggle.isOn = true;
}
/// <summary>
/// OnDecrement implementation.
/// </summary>
/// <param name="fast">Trye if decrementing fast.</param>
public override void OnDecrement(bool fast)
{
valueToggle.isOn = false;
}
/// <summary>
/// OnAction implementation.
/// </summary>
public override void OnAction()
{
valueToggle.isOn = !valueToggle.isOn;
}
/// <summary>
/// Next implementation.
/// </summary>
/// <returns>Next widget UI handler, parent if there is none.</returns>
public override DebugUIHandlerWidget Next()
{
if (!valueToggle.isOn || m_Container == null)
return base.Next();
var firstChild = m_Container.GetFirstItem();
if (firstChild == null)
return base.Next();
return firstChild;
}
}
}

View File

@@ -0,0 +1,146 @@
using UnityEngine.UI;
namespace UnityEngine.Rendering.UI
{
/// <summary>
/// DebugUIHandler for vector3 widget.
/// </summary>
public class DebugUIHandlerVector3 : DebugUIHandlerWidget
{
/// <summary>Name of the Vector3 field.</summary>
public Text nameLabel;
/// <summary>Value of the Vector3 toggle.</summary>
public UIFoldout valueToggle;
/// <summary>X float field.</summary>
public DebugUIHandlerIndirectFloatField fieldX;
/// <summary>Y float field.</summary>
public DebugUIHandlerIndirectFloatField fieldY;
/// <summary>Z float field.</summary>
public DebugUIHandlerIndirectFloatField fieldZ;
DebugUI.Vector3Field m_Field;
DebugUIHandlerContainer m_Container;
internal override void SetWidget(DebugUI.Widget widget)
{
base.SetWidget(widget);
m_Field = CastWidget<DebugUI.Vector3Field>();
m_Container = GetComponent<DebugUIHandlerContainer>();
nameLabel.text = m_Field.displayName;
fieldX.getter = () => m_Field.GetValue().x;
fieldX.setter = v => SetValue(v, x: true);
fieldX.nextUIHandler = fieldY;
SetupSettings(fieldX);
fieldY.getter = () => m_Field.GetValue().y;
fieldY.setter = v => SetValue(v, y: true);
fieldY.previousUIHandler = fieldX;
fieldY.nextUIHandler = fieldZ;
SetupSettings(fieldY);
fieldZ.getter = () => m_Field.GetValue().z;
fieldZ.setter = v => SetValue(v, z: true);
fieldZ.previousUIHandler = fieldY;
SetupSettings(fieldZ);
}
void SetValue(float v, bool x = false, bool y = false, bool z = false)
{
var vec = m_Field.GetValue();
if (x) vec.x = v;
if (y) vec.y = v;
if (z) vec.z = v;
m_Field.SetValue(vec);
}
void SetupSettings(DebugUIHandlerIndirectFloatField field)
{
field.parentUIHandler = this;
field.incStepGetter = () => m_Field.incStep;
field.incStepMultGetter = () => m_Field.incStepMult;
field.decimalsGetter = () => m_Field.decimals;
field.Init();
}
/// <summary>
/// OnSelection implementation.
/// </summary>
/// <param name="fromNext">True if the selection wrapped around.</param>
/// <param name="previous">Previous widget.</param>
/// <returns>True if the selection is allowed.</returns>
public override bool OnSelection(bool fromNext, DebugUIHandlerWidget previous)
{
if (fromNext || valueToggle.isOn == false)
{
nameLabel.color = colorSelected;
}
else if (valueToggle.isOn)
{
if (m_Container.IsDirectChild(previous))
{
nameLabel.color = colorSelected;
}
else
{
var lastItem = m_Container.GetLastItem();
DebugManager.instance.ChangeSelection(lastItem, false);
}
}
return true;
}
/// <summary>
/// OnDeselection implementation.
/// </summary>
public override void OnDeselection()
{
nameLabel.color = colorDefault;
}
/// <summary>
/// OnIncrement implementation.
/// </summary>
/// <param name="fast">True if incrementing fast.</param>
public override void OnIncrement(bool fast)
{
valueToggle.isOn = true;
}
/// <summary>
/// OnDecrement implementation.
/// </summary>
/// <param name="fast">Trye if decrementing fast.</param>
public override void OnDecrement(bool fast)
{
valueToggle.isOn = false;
}
/// <summary>
/// OnAction implementation.
/// </summary>
public override void OnAction()
{
valueToggle.isOn = !valueToggle.isOn;
}
/// <summary>
/// Next implementation.
/// </summary>
/// <returns>Next widget UI handler, parent if there is none.</returns>
public override DebugUIHandlerWidget Next()
{
if (!valueToggle.isOn || m_Container == null)
return base.Next();
var firstChild = m_Container.GetFirstItem();
if (firstChild == null)
return base.Next();
return firstChild;
}
}
}

View File

@@ -0,0 +1,155 @@
using UnityEngine.UI;
namespace UnityEngine.Rendering.UI
{
/// <summary>
/// DebugUIHandler for vector4 widget.
/// </summary>
public class DebugUIHandlerVector4 : DebugUIHandlerWidget
{
/// <summary>Name of the Vector4 field.</summary>
public Text nameLabel;
/// <summary>Value of the Vector4 toggle.</summary>
public UIFoldout valueToggle;
/// <summary>X float field.</summary>
public DebugUIHandlerIndirectFloatField fieldX;
/// <summary>Y float field.</summary>
public DebugUIHandlerIndirectFloatField fieldY;
/// <summary>Z float field.</summary>
public DebugUIHandlerIndirectFloatField fieldZ;
/// <summary>W float field.</summary>
public DebugUIHandlerIndirectFloatField fieldW;
DebugUI.Vector4Field m_Field;
DebugUIHandlerContainer m_Container;
internal override void SetWidget(DebugUI.Widget widget)
{
base.SetWidget(widget);
m_Field = CastWidget<DebugUI.Vector4Field>();
m_Container = GetComponent<DebugUIHandlerContainer>();
nameLabel.text = m_Field.displayName;
fieldX.getter = () => m_Field.GetValue().x;
fieldX.setter = x => SetValue(x, x: true);
fieldX.nextUIHandler = fieldY;
SetupSettings(fieldX);
fieldY.getter = () => m_Field.GetValue().y;
fieldY.setter = x => SetValue(x, y: true);
fieldY.previousUIHandler = fieldX;
fieldY.nextUIHandler = fieldZ;
SetupSettings(fieldY);
fieldZ.getter = () => m_Field.GetValue().z;
fieldZ.setter = x => SetValue(x, z: true);
fieldZ.previousUIHandler = fieldY;
fieldZ.nextUIHandler = fieldW;
SetupSettings(fieldZ);
fieldW.getter = () => m_Field.GetValue().w;
fieldW.setter = x => SetValue(x, w: true);
fieldW.previousUIHandler = fieldZ;
SetupSettings(fieldW);
}
void SetValue(float v, bool x = false, bool y = false, bool z = false, bool w = false)
{
var vec = m_Field.GetValue();
if (x) vec.x = v;
if (y) vec.y = v;
if (z) vec.z = v;
if (w) vec.w = v;
m_Field.SetValue(vec);
}
void SetupSettings(DebugUIHandlerIndirectFloatField field)
{
field.parentUIHandler = this;
field.incStepGetter = () => m_Field.incStep;
field.incStepMultGetter = () => m_Field.incStepMult;
field.decimalsGetter = () => m_Field.decimals;
field.Init();
}
/// <summary>
/// OnSelection implementation.
/// </summary>
/// <param name="fromNext">True if the selection wrapped around.</param>
/// <param name="previous">Previous widget.</param>
/// <returns>True if the selection is allowed.</returns>
public override bool OnSelection(bool fromNext, DebugUIHandlerWidget previous)
{
if (fromNext || valueToggle.isOn == false)
{
nameLabel.color = colorSelected;
}
else if (valueToggle.isOn)
{
if (m_Container.IsDirectChild(previous))
{
nameLabel.color = colorSelected;
}
else
{
var lastItem = m_Container.GetLastItem();
DebugManager.instance.ChangeSelection(lastItem, false);
}
}
return true;
}
/// <summary>
/// OnDeselection implementation.
/// </summary>
public override void OnDeselection()
{
nameLabel.color = colorDefault;
}
/// <summary>
/// OnIncrement implementation.
/// </summary>
/// <param name="fast">True if incrementing fast.</param>
public override void OnIncrement(bool fast)
{
valueToggle.isOn = true;
}
/// <summary>
/// OnDecrement implementation.
/// </summary>
/// <param name="fast">Trye if decrementing fast.</param>
public override void OnDecrement(bool fast)
{
valueToggle.isOn = false;
}
/// <summary>
/// OnAction implementation.
/// </summary>
public override void OnAction()
{
valueToggle.isOn = !valueToggle.isOn;
}
/// <summary>
/// Next implementation.
/// </summary>
/// <returns>Next widget UI handler, parent if there is none.</returns>
public override DebugUIHandlerWidget Next()
{
if (!valueToggle.isOn || m_Container == null)
return base.Next();
var firstChild = m_Container.GetFirstItem();
if (firstChild == null)
return base.Next();
return firstChild;
}
}
}

View File

@@ -0,0 +1,146 @@
using System;
namespace UnityEngine.Rendering.UI
{
/// <summary>
/// Base class for handling UI actions for widgets.
/// </summary>
public class DebugUIHandlerWidget : MonoBehaviour
{
/// <summary>
/// Default widget color.
/// </summary>
[HideInInspector]
public Color colorDefault = new Color(0.8f, 0.8f, 0.8f, 1f);
/// <summary>
/// Selected widget color.
/// </summary>
[HideInInspector]
public Color colorSelected = new Color(0.25f, 0.65f, 0.8f, 1f);
/// <summary>
/// Parent widget UI Handler.
/// </summary>
public DebugUIHandlerWidget parentUIHandler { get; set; }
/// <summary>
/// Previous widget UI Handler.
/// </summary>
public DebugUIHandlerWidget previousUIHandler { get; set; }
/// <summary>
/// Next widget UI Handler.
/// </summary>
public DebugUIHandlerWidget nextUIHandler { get; set; }
/// <summary>
/// Associated widget.
/// </summary>
protected DebugUI.Widget m_Widget;
/// <summary>
/// OnEnable implementation.
/// </summary>
protected virtual void OnEnable() {}
internal virtual void SetWidget(DebugUI.Widget widget)
{
m_Widget = widget;
}
internal DebugUI.Widget GetWidget()
{
return m_Widget;
}
/// <summary>
/// Casts the widget to the correct type.
/// </summary>
/// <typeparam name="T">Type of the widget.</typeparam>
/// <returns>Properly cast reference to the widget.</returns>
protected T CastWidget<T>()
where T : DebugUI.Widget
{
var casted = m_Widget as T;
string typeName = m_Widget == null ? "null" : m_Widget.GetType().ToString();
if (casted == null)
throw new InvalidOperationException("Can't cast " + typeName + " to " + typeof(T));
return casted;
}
/// <summary>
/// OnSelection implementation.
/// </summary>
/// <param name="fromNext">True if the selection wrapped around.</param>
/// <param name="previous">Previous widget.</param>
/// <returns>True if the selection is allowed.</returns>
public virtual bool OnSelection(bool fromNext, DebugUIHandlerWidget previous)
{
return true;
}
/// <summary>
/// OnDeselection implementation.
/// </summary>
public virtual void OnDeselection() {}
/// <summary>
/// OnAction implementation.
/// </summary>
public virtual void OnAction() {}
/// <summary>
/// OnIncrement implementation.
/// </summary>
/// <param name="fast">True if incrementing fast.</param>
public virtual void OnIncrement(bool fast) {}
/// <summary>
/// OnDecrement implementation.
/// </summary>
/// <param name="fast">Trye if decrementing fast.</param>
public virtual void OnDecrement(bool fast) {}
/// <summary>
/// Previous implementation.
/// </summary>
/// <returns>Previous widget UI handler, parent if there is none.</returns>
public virtual DebugUIHandlerWidget Previous()
{
if (previousUIHandler != null)
return previousUIHandler;
if (parentUIHandler != null)
return parentUIHandler;
return null;
}
/// <summary>
/// Next implementation.
/// </summary>
/// <returns>Next widget UI handler, parent if there is none.</returns>
public virtual DebugUIHandlerWidget Next()
{
if (nextUIHandler != null)
return nextUIHandler;
if (parentUIHandler != null)
{
var p = parentUIHandler;
while (p != null)
{
var n = p.nextUIHandler;
if (n != null)
return n;
p = p.parentUIHandler;
}
}
return null;
}
}
}

View File

@@ -0,0 +1,60 @@
using UnityEngine.UI;
namespace UnityEngine.Rendering.UI
{
/// <summary>Foldout in the DebugMenu</summary>
[ExecuteAlways]
public class UIFoldout : Toggle
{
/// <summary>Contents inside the toggle</summary>
public GameObject content;
/// <summary>Arror in state opened</summary>
public GameObject arrowOpened;
/// <summary>Arror in state closed</summary>
public GameObject arrowClosed;
/// <summary>Start of this GameObject lifecicle</summary>
protected override void Start()
{
base.Start();
onValueChanged.AddListener(SetState);
SetState(isOn);
}
#pragma warning disable 108,114
void OnValidate()
{
SetState(isOn, false);
}
#pragma warning restore 108,114
/// <summary>Change the state of this foldout</summary>
/// <param name="state">The new State</param>
public void SetState(bool state)
{
SetState(state, true);
}
/// <summary>Change the state of this foldout</summary>
/// <param name="state">The new State</param>
/// <param name="rebuildLayout">If True, the layout will be rebuild</param>
public void SetState(bool state, bool rebuildLayout)
{
if (arrowOpened == null || arrowClosed == null || content == null)
return;
if (arrowOpened.activeSelf != state)
arrowOpened.SetActive(state);
if (arrowClosed.activeSelf == state)
arrowClosed.SetActive(!state);
if (content.activeSelf != state)
content.SetActive(state);
if (rebuildLayout)
LayoutRebuilder.ForceRebuildLayoutImmediate(transform.parent as RectTransform);
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 977 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 973 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 942 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 927 B

View File

@@ -0,0 +1,213 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1001 &100100000
Prefab:
m_ObjectHideFlags: 1
serializedVersion: 2
m_Modification:
m_TransformParent: {fileID: 0}
m_Modifications: []
m_RemovedComponents: []
m_ParentPrefab: {fileID: 0}
m_RootGameObject: {fileID: 1349998662384948}
m_IsPrefabParent: 1
--- !u!1 &1346781532117404
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 5
m_Component:
- component: {fileID: 224019920140556580}
- component: {fileID: 222080438315005238}
- component: {fileID: 114152708984687776}
m_Layer: 5
m_Name: Text
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!1 &1349998662384948
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 5
m_Component:
- component: {fileID: 224438017010656346}
- component: {fileID: 222869912906783786}
- component: {fileID: 114163390439191134}
- component: {fileID: 114467080906542876}
- component: {fileID: 114307598231942114}
m_Layer: 5
m_Name: DebugUI Button
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &114152708984687776
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1346781532117404}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 0.8, g: 0.8, b: 0.8, a: 1}
m_RaycastTarget: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
m_FontData:
m_Font: {fileID: 12800000, guid: 74a5091d8707f334b9a5c31ef71a64ba, type: 3}
m_FontSize: 16
m_FontStyle: 0
m_BestFit: 0
m_MinSize: 10
m_MaxSize: 40
m_Alignment: 4
m_AlignByGeometry: 0
m_RichText: 0
m_HorizontalOverflow: 0
m_VerticalOverflow: 0
m_LineSpacing: 1
m_Text: Button
--- !u!114 &114163390439191134
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1349998662384948}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
m_Sprite: {fileID: 21300000, guid: d49e78756811bfa4aafb8b6535417991, type: 3}
m_Type: 1
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
--- !u!114 &114307598231942114
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1349998662384948}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 8bff080b4e3bae64c80b54402ced6cc6, type: 3}
m_Name:
m_EditorClassIdentifier:
colorDefault: {r: 0.8, g: 0.8, b: 0.8, a: 1}
colorSelected: {r: 0.25, g: 0.65, b: 0.8, a: 1}
nameLabel: {fileID: 114152708984687776}
--- !u!114 &114467080906542876
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1349998662384948}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 1392445389, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Navigation:
m_Mode: 0
m_SelectOnUp: {fileID: 0}
m_SelectOnDown: {fileID: 0}
m_SelectOnLeft: {fileID: 0}
m_SelectOnRight: {fileID: 0}
m_Transition: 0
m_Colors:
m_NormalColor: {r: 0, g: 0, b: 0, a: 0.60784316}
m_HighlightedColor: {r: 0, g: 0, b: 0, a: 0.8666667}
m_PressedColor: {r: 0.28235295, g: 0.28235295, b: 0.28235295, a: 1}
m_DisabledColor: {r: 0, g: 0, b: 0, a: 0.28627452}
m_ColorMultiplier: 1
m_FadeDuration: 0.1
m_SpriteState:
m_HighlightedSprite: {fileID: 0}
m_PressedSprite: {fileID: 0}
m_DisabledSprite: {fileID: 0}
m_AnimationTriggers:
m_NormalTrigger: Normal
m_HighlightedTrigger: Highlighted
m_PressedTrigger: Pressed
m_DisabledTrigger: Disabled
m_Interactable: 1
m_TargetGraphic: {fileID: 114163390439191134}
m_OnClick:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.Button+ButtonClickedEvent, UnityEngine.UI, Version=1.0.0.0,
Culture=neutral, PublicKeyToken=null
--- !u!222 &222080438315005238
CanvasRenderer:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1346781532117404}
--- !u!222 &222869912906783786
CanvasRenderer:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1349998662384948}
--- !u!224 &224019920140556580
RectTransform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1346781532117404}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 224438017010656346}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!224 &224438017010656346
RectTransform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1349998662384948}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children:
- {fileID: 224019920140556580}
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 26}
m_Pivot: {x: 0.5, y: 0.5}

View File

@@ -0,0 +1,212 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1001 &100100000
Prefab:
m_ObjectHideFlags: 1
serializedVersion: 2
m_Modification:
m_TransformParent: {fileID: 0}
m_Modifications: []
m_RemovedComponents: []
m_ParentPrefab: {fileID: 0}
m_RootGameObject: {fileID: 1311110376158742}
m_IsPrefabParent: 1
--- !u!1 &1311110376158742
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 5
m_Component:
- component: {fileID: 224224135738715566}
- component: {fileID: 114506562444320092}
m_Layer: 5
m_Name: DebugUI EnumField
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!1 &1318931732956078
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 5
m_Component:
- component: {fileID: 224082802897306466}
- component: {fileID: 222666496576361700}
- component: {fileID: 114749518858187484}
m_Layer: 5
m_Name: Text
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!1 &1489651458712568
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 5
m_Component:
- component: {fileID: 224794258446302326}
- component: {fileID: 222110064721837410}
- component: {fileID: 114525189159037378}
m_Layer: 5
m_Name: Value
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &114506562444320092
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1311110376158742}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 0ca07cb82ca30874c849ad6a8be4ce42, type: 3}
m_Name:
m_EditorClassIdentifier:
colorDefault: {r: 0.8, g: 0.8, b: 0.8, a: 1}
colorSelected: {r: 0.25, g: 0.65, b: 0.8, a: 1}
nameLabel: {fileID: 114749518858187484}
valueLabel: {fileID: 114525189159037378}
--- !u!114 &114525189159037378
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1489651458712568}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 0.8, g: 0.8, b: 0.8, a: 1}
m_RaycastTarget: 0
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
m_FontData:
m_Font: {fileID: 12800000, guid: 74a5091d8707f334b9a5c31ef71a64ba, type: 3}
m_FontSize: 16
m_FontStyle: 0
m_BestFit: 0
m_MinSize: 1
m_MaxSize: 40
m_Alignment: 3
m_AlignByGeometry: 0
m_RichText: 0
m_HorizontalOverflow: 1
m_VerticalOverflow: 0
m_LineSpacing: 1
m_Text: < 0 >
--- !u!114 &114749518858187484
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1318931732956078}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 0.8, g: 0.8, b: 0.8, a: 1}
m_RaycastTarget: 0
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
m_FontData:
m_Font: {fileID: 12800000, guid: 74a5091d8707f334b9a5c31ef71a64ba, type: 3}
m_FontSize: 16
m_FontStyle: 0
m_BestFit: 0
m_MinSize: 1
m_MaxSize: 40
m_Alignment: 3
m_AlignByGeometry: 0
m_RichText: 0
m_HorizontalOverflow: 0
m_VerticalOverflow: 0
m_LineSpacing: 1
m_Text: New Text
--- !u!222 &222110064721837410
CanvasRenderer:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1489651458712568}
--- !u!222 &222666496576361700
CanvasRenderer:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1318931732956078}
--- !u!224 &224082802897306466
RectTransform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1318931732956078}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 224224135738715566}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0.5, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0.5, y: 1}
--- !u!224 &224224135738715566
RectTransform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1311110376158742}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children:
- {fileID: 224082802897306466}
- {fileID: 224794258446302326}
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 26}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!224 &224794258446302326
RectTransform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1489651458712568}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 224224135738715566}
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0.5, y: 0.5}

View File

@@ -0,0 +1,217 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &1205328279998559140
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 8828311818677054686}
- component: {fileID: 6892336960305635697}
- component: {fileID: 7366739618473192611}
m_Layer: 5
m_Name: Value
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &8828311818677054686
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1205328279998559140}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 8535926254376877601}
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &6892336960305635697
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1205328279998559140}
m_CullTransparentMesh: 0
--- !u!114 &7366739618473192611
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1205328279998559140}
m_Enabled: 1
m_EditorHideFlags: 0
m_GeneratorAsset: {fileID: 0}
m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 0.8, g: 0.8, b: 0.8, a: 1}
m_RaycastTarget: 0
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
m_FontData:
m_Font: {fileID: 12800000, guid: 74a5091d8707f334b9a5c31ef71a64ba, type: 3}
m_FontSize: 12
m_FontStyle: 0
m_BestFit: 0
m_MinSize: 1
m_MaxSize: 40
m_Alignment: 3
m_AlignByGeometry: 0
m_RichText: 0
m_HorizontalOverflow: 1
m_VerticalOverflow: 0
m_LineSpacing: 1
m_Text: < 0 >
--- !u!1 &3734445388003485314
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 8535926254376877601}
- component: {fileID: 6127496435193308922}
m_Layer: 5
m_Name: DebugUI EnumHistory
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &8535926254376877601
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3734445388003485314}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children:
- {fileID: 5991805839592987070}
- {fileID: 8828311818677054686}
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 26}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &6127496435193308922
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3734445388003485314}
m_Enabled: 1
m_EditorHideFlags: 0
m_GeneratorAsset: {fileID: 0}
m_Script: {fileID: 11500000, guid: ecc0d22e5e3de604f9e4d3d8997e9122, type: 3}
m_Name:
m_EditorClassIdentifier:
colorDefault: {r: 0.8, g: 0.8, b: 0.8, a: 1}
colorSelected: {r: 0.25, g: 0.65, b: 0.8, a: 1}
nameLabel: {fileID: 2309423972571977096}
valueLabel: {fileID: 7366739618473192611}
--- !u!1 &3930833054956949072
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 5991805839592987070}
- component: {fileID: 1594499422264008796}
- component: {fileID: 2309423972571977096}
m_Layer: 5
m_Name: Text
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &5991805839592987070
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3930833054956949072}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 8535926254376877601}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0.5, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0.5, y: 1}
--- !u!222 &1594499422264008796
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3930833054956949072}
m_CullTransparentMesh: 0
--- !u!114 &2309423972571977096
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3930833054956949072}
m_Enabled: 1
m_EditorHideFlags: 0
m_GeneratorAsset: {fileID: 0}
m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 0.8, g: 0.8, b: 0.8, a: 1}
m_RaycastTarget: 0
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
m_FontData:
m_Font: {fileID: 12800000, guid: 74a5091d8707f334b9a5c31ef71a64ba, type: 3}
m_FontSize: 16
m_FontStyle: 0
m_BestFit: 0
m_MinSize: 1
m_MaxSize: 40
m_Alignment: 3
m_AlignByGeometry: 0
m_RichText: 0
m_HorizontalOverflow: 0
m_VerticalOverflow: 0
m_LineSpacing: 1
m_Text: New Text

View File

@@ -0,0 +1,214 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1001 &100100000
Prefab:
m_ObjectHideFlags: 1
serializedVersion: 2
m_Modification:
m_TransformParent: {fileID: 0}
m_Modifications: []
m_RemovedComponents: []
m_ParentPrefab: {fileID: 0}
m_RootGameObject: {fileID: 1100371661045084}
m_IsPrefabParent: 1
--- !u!1 &1100371661045084
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 5
m_Component:
- component: {fileID: 224720214277421396}
- component: {fileID: 114688613186139690}
m_Layer: 5
m_Name: DebugUI FloatField
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!1 &1207032646716234
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 5
m_Component:
- component: {fileID: 224309343631572978}
- component: {fileID: 222840031335149136}
- component: {fileID: 114601347101323698}
m_Layer: 5
m_Name: Text
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!1 &1644687155343164
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 5
m_Component:
- component: {fileID: 224518799942003328}
- component: {fileID: 222991141768779948}
- component: {fileID: 114504040572925244}
m_Layer: 5
m_Name: Float
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &114504040572925244
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1644687155343164}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 0.8, g: 0.8, b: 0.8, a: 1}
m_RaycastTarget: 0
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
m_FontData:
m_Font: {fileID: 12800000, guid: 74a5091d8707f334b9a5c31ef71a64ba, type: 3}
m_FontSize: 16
m_FontStyle: 0
m_BestFit: 0
m_MinSize: 1
m_MaxSize: 40
m_Alignment: 3
m_AlignByGeometry: 0
m_RichText: 0
m_HorizontalOverflow: 0
m_VerticalOverflow: 0
m_LineSpacing: 1
m_Text: '0
'
--- !u!114 &114601347101323698
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1207032646716234}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 0.8, g: 0.8, b: 0.8, a: 1}
m_RaycastTarget: 0
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
m_FontData:
m_Font: {fileID: 12800000, guid: 74a5091d8707f334b9a5c31ef71a64ba, type: 3}
m_FontSize: 16
m_FontStyle: 0
m_BestFit: 0
m_MinSize: 10
m_MaxSize: 40
m_Alignment: 3
m_AlignByGeometry: 0
m_RichText: 0
m_HorizontalOverflow: 0
m_VerticalOverflow: 0
m_LineSpacing: 1
m_Text: New Text
--- !u!114 &114688613186139690
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1100371661045084}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 2c71addad67814c418e8376c7fabd008, type: 3}
m_Name:
m_EditorClassIdentifier:
colorDefault: {r: 0.8, g: 0.8, b: 0.8, a: 1}
colorSelected: {r: 0.25, g: 0.65, b: 0.8, a: 1}
nameLabel: {fileID: 114601347101323698}
valueLabel: {fileID: 114504040572925244}
--- !u!222 &222840031335149136
CanvasRenderer:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1207032646716234}
--- !u!222 &222991141768779948
CanvasRenderer:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1644687155343164}
--- !u!224 &224309343631572978
RectTransform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1207032646716234}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 224720214277421396}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0.5, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0.5, y: 1}
--- !u!224 &224518799942003328
RectTransform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1644687155343164}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 224720214277421396}
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!224 &224720214277421396
RectTransform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1100371661045084}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children:
- {fileID: 224309343631572978}
- {fileID: 224518799942003328}
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 26}
m_Pivot: {x: 0.5, y: 0.5}

View File

@@ -0,0 +1,516 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1001 &100100000
Prefab:
m_ObjectHideFlags: 1
serializedVersion: 2
m_Modification:
m_TransformParent: {fileID: 0}
m_Modifications: []
m_RemovedComponents: []
m_ParentPrefab: {fileID: 0}
m_RootGameObject: {fileID: 1880654171993120}
m_IsPrefabParent: 1
--- !u!1 &1117777935091328
GameObject:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 5
m_Component:
- component: {fileID: 224404899962668226}
- component: {fileID: 222292134107675628}
- component: {fileID: 114934813895219466}
m_Layer: 5
m_Name: Arrow Closed
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!1 &1157130882260826
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 5
m_Component:
- component: {fileID: 224091637017424492}
- component: {fileID: 114246251359002098}
- component: {fileID: 114721609938004740}
- component: {fileID: 222580990534994246}
- component: {fileID: 114267363758275858}
m_Layer: 5
m_Name: Content
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 0
--- !u!1 &1675372956212332
GameObject:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 5
m_Component:
- component: {fileID: 224861680556189892}
- component: {fileID: 222407094714348334}
- component: {fileID: 114534572167021932}
m_Layer: 5
m_Name: Arrow Opened
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 0
--- !u!1 &1741108581676328
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 5
m_Component:
- component: {fileID: 224398617048880834}
- component: {fileID: 114589844970474540}
m_Layer: 5
m_Name: Header
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!1 &1880654171993120
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 5
m_Component:
- component: {fileID: 224053494956566916}
- component: {fileID: 114903677526224182}
- component: {fileID: 114617406789257194}
- component: {fileID: 114488953024160460}
- component: {fileID: 114624457690215086}
m_Layer: 0
m_Name: DebugUI Foldout
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!1 &1887383709356810
GameObject:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 5
m_Component:
- component: {fileID: 224133929923872250}
- component: {fileID: 222546040197109316}
- component: {fileID: 114398791307483412}
m_Layer: 5
m_Name: Text
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &114246251359002098
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1157130882260826}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 1297475563, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Padding:
m_Left: 25
m_Right: 0
m_Top: 0
m_Bottom: 0
m_ChildAlignment: 0
m_Spacing: 1
m_ChildForceExpandWidth: 1
m_ChildForceExpandHeight: 0
m_ChildControlWidth: 1
m_ChildControlHeight: 0
--- !u!114 &114267363758275858
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1157130882260826}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 0, g: 0, b: 0, a: 0.2509804}
m_RaycastTarget: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
m_Sprite: {fileID: 21300000, guid: 127279d577f25ac4ea17dae3782e5074, type: 3}
m_Type: 0
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
--- !u!114 &114398791307483412
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1887383709356810}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 0.8, g: 0.8, b: 0.8, a: 1}
m_RaycastTarget: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
m_FontData:
m_Font: {fileID: 12800000, guid: 74a5091d8707f334b9a5c31ef71a64ba, type: 3}
m_FontSize: 16
m_FontStyle: 0
m_BestFit: 0
m_MinSize: 1
m_MaxSize: 40
m_Alignment: 3
m_AlignByGeometry: 0
m_RichText: 0
m_HorizontalOverflow: 0
m_VerticalOverflow: 0
m_LineSpacing: 1
m_Text: 'Foldout
'
--- !u!114 &114488953024160460
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1880654171993120}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 2bd470ffc0c0fe54faddbf8d466bf519, type: 3}
m_Name:
m_EditorClassIdentifier:
contentHolder: {fileID: 224091637017424492}
--- !u!114 &114534572167021932
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1675372956212332}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
m_Sprite: {fileID: 21300000, guid: a674720496c1ed248a5b7ea3e22a11fd, type: 3}
m_Type: 0
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
--- !u!114 &114589844970474540
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1741108581676328}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: e4786b5477cac0a42855b21fdaa2242f, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Navigation:
m_Mode: 3
m_SelectOnUp: {fileID: 0}
m_SelectOnDown: {fileID: 0}
m_SelectOnLeft: {fileID: 0}
m_SelectOnRight: {fileID: 0}
m_Transition: 0
m_Colors:
m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
m_ColorMultiplier: 1
m_FadeDuration: 0.1
m_SpriteState:
m_HighlightedSprite: {fileID: 0}
m_PressedSprite: {fileID: 0}
m_DisabledSprite: {fileID: 0}
m_AnimationTriggers:
m_NormalTrigger: Normal
m_HighlightedTrigger: Highlighted
m_PressedTrigger: Pressed
m_DisabledTrigger: Disabled
m_Interactable: 1
m_TargetGraphic: {fileID: 0}
toggleTransition: 0
graphic: {fileID: 0}
m_Group: {fileID: 0}
onValueChanged:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.Toggle+ToggleEvent, UnityEngine.UI, Version=1.0.0.0,
Culture=neutral, PublicKeyToken=null
m_IsOn: 0
content: {fileID: 1157130882260826}
arrowOpened: {fileID: 1675372956212332}
arrowClosed: {fileID: 1117777935091328}
--- !u!114 &114617406789257194
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1880654171993120}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 1741964061, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_HorizontalFit: 0
m_VerticalFit: 1
--- !u!114 &114624457690215086
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1880654171993120}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 4e5dc9f9bba5df14fbe439bcc4c67063, type: 3}
m_Name:
m_EditorClassIdentifier:
colorDefault: {r: 0.8, g: 0.8, b: 0.8, a: 1}
colorSelected: {r: 0.25, g: 0.65, b: 0.8, a: 1}
nameLabel: {fileID: 114398791307483412}
valueToggle: {fileID: 114589844970474540}
--- !u!114 &114721609938004740
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1157130882260826}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 1741964061, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_HorizontalFit: 0
m_VerticalFit: 1
--- !u!114 &114903677526224182
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1880654171993120}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 1297475563, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Padding:
m_Left: 0
m_Right: 0
m_Top: 0
m_Bottom: 0
m_ChildAlignment: 0
m_Spacing: 0
m_ChildForceExpandWidth: 1
m_ChildForceExpandHeight: 1
m_ChildControlWidth: 1
m_ChildControlHeight: 0
--- !u!114 &114934813895219466
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1117777935091328}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
m_Sprite: {fileID: 21300000, guid: 7a0568d5e3330b84687e307992be3030, type: 3}
m_Type: 0
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
--- !u!222 &222292134107675628
CanvasRenderer:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1117777935091328}
--- !u!222 &222407094714348334
CanvasRenderer:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1675372956212332}
--- !u!222 &222546040197109316
CanvasRenderer:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1887383709356810}
--- !u!222 &222580990534994246
CanvasRenderer:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1157130882260826}
--- !u!224 &224053494956566916
RectTransform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1880654171993120}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children:
- {fileID: 224398617048880834}
- {fileID: 224091637017424492}
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 295, y: 0}
m_SizeDelta: {x: 590, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!224 &224091637017424492
RectTransform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1157130882260826}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 224053494956566916}
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 590, y: -50}
m_SizeDelta: {x: 590, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!224 &224133929923872250
RectTransform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1887383709356810}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 224398617048880834}
m_RootOrder: 2
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 10, y: 0}
m_SizeDelta: {x: -20, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!224 &224398617048880834
RectTransform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1741108581676328}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children:
- {fileID: 224861680556189892}
- {fileID: 224404899962668226}
- {fileID: 224133929923872250}
m_Father: {fileID: 224053494956566916}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 590, y: 26}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!224 &224404899962668226
RectTransform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1117777935091328}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 224398617048880834}
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0.5}
m_AnchorMax: {x: 0, y: 0.5}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 11, y: 11}
m_Pivot: {x: 0, y: 0.5}
--- !u!224 &224861680556189892
RectTransform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1675372956212332}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 224398617048880834}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0.5}
m_AnchorMax: {x: 0, y: 0.5}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 11, y: 11}
m_Pivot: {x: 0, y: 0.5}

View File

@@ -0,0 +1,327 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1001 &100100000
Prefab:
m_ObjectHideFlags: 1
serializedVersion: 2
m_Modification:
m_TransformParent: {fileID: 0}
m_Modifications: []
m_RemovedComponents: []
m_ParentPrefab: {fileID: 0}
m_RootGameObject: {fileID: 1674137683461036}
m_IsPrefabParent: 1
--- !u!1 &1047138471361452
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 5
m_Component:
- component: {fileID: 224838436133260374}
- component: {fileID: 114269244846615282}
- component: {fileID: 114671355267802142}
- component: {fileID: 222568876084187722}
- component: {fileID: 114039123162685916}
m_Layer: 5
m_Name: Content
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!1 &1352568934393662
GameObject:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 5
m_Component:
- component: {fileID: 224249004839589914}
- component: {fileID: 222594547984964154}
- component: {fileID: 114000192492716826}
m_Layer: 5
m_Name: Text
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!1 &1665738837227174
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 5
m_Component:
- component: {fileID: 224710425033387306}
m_Layer: 5
m_Name: Header
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!1 &1674137683461036
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 5
m_Component:
- component: {fileID: 224284813447651300}
- component: {fileID: 114639219832853812}
- component: {fileID: 114477368065491246}
- component: {fileID: 114331217329802032}
- component: {fileID: 114429264468334814}
m_Layer: 0
m_Name: DebugUI Group
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &114000192492716826
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1352568934393662}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 0.8, g: 0.8, b: 0.8, a: 1}
m_RaycastTarget: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
m_FontData:
m_Font: {fileID: 12800000, guid: 74a5091d8707f334b9a5c31ef71a64ba, type: 3}
m_FontSize: 16
m_FontStyle: 0
m_BestFit: 0
m_MinSize: 1
m_MaxSize: 40
m_Alignment: 3
m_AlignByGeometry: 0
m_RichText: 0
m_HorizontalOverflow: 0
m_VerticalOverflow: 0
m_LineSpacing: 1
m_Text: Foldout
--- !u!114 &114039123162685916
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1047138471361452}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 0, g: 0, b: 0, a: 0.2509804}
m_RaycastTarget: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
m_Sprite: {fileID: 21300000, guid: 127279d577f25ac4ea17dae3782e5074, type: 3}
m_Type: 0
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
--- !u!114 &114269244846615282
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1047138471361452}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 1297475563, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Padding:
m_Left: 25
m_Right: 0
m_Top: 0
m_Bottom: 0
m_ChildAlignment: 0
m_Spacing: 1
m_ChildForceExpandWidth: 1
m_ChildForceExpandHeight: 0
m_ChildControlWidth: 1
m_ChildControlHeight: 0
--- !u!114 &114331217329802032
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1674137683461036}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 2bd470ffc0c0fe54faddbf8d466bf519, type: 3}
m_Name:
m_EditorClassIdentifier:
contentHolder: {fileID: 224838436133260374}
--- !u!114 &114429264468334814
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1674137683461036}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: c5d44b76204264d4eb90d4a92b067d7d, type: 3}
m_Name:
m_EditorClassIdentifier:
colorDefault: {r: 0.8, g: 0.8, b: 0.8, a: 1}
colorSelected: {r: 0.25, g: 0.65, b: 0.8, a: 1}
nameLabel: {fileID: 114000192492716826}
header: {fileID: 224710425033387306}
--- !u!114 &114477368065491246
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1674137683461036}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 1741964061, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_HorizontalFit: 0
m_VerticalFit: 1
--- !u!114 &114639219832853812
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1674137683461036}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 1297475563, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Padding:
m_Left: 0
m_Right: 0
m_Top: 0
m_Bottom: 0
m_ChildAlignment: 0
m_Spacing: 0
m_ChildForceExpandWidth: 1
m_ChildForceExpandHeight: 1
m_ChildControlWidth: 1
m_ChildControlHeight: 0
--- !u!114 &114671355267802142
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1047138471361452}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 1741964061, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_HorizontalFit: 0
m_VerticalFit: 1
--- !u!222 &222568876084187722
CanvasRenderer:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1047138471361452}
--- !u!222 &222594547984964154
CanvasRenderer:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1352568934393662}
--- !u!224 &224249004839589914
RectTransform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1352568934393662}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 224710425033387306}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!224 &224284813447651300
RectTransform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1674137683461036}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children:
- {fileID: 224710425033387306}
- {fileID: 224838436133260374}
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 293.5, y: 0}
m_SizeDelta: {x: 577, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!224 &224710425033387306
RectTransform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1665738837227174}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children:
- {fileID: 224249004839589914}
m_Father: {fileID: 224284813447651300}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: -4, y: 0}
m_SizeDelta: {x: 0, y: 26}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!224 &224838436133260374
RectTransform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1047138471361452}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 224284813447651300}
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 284.5, y: 0}
m_SizeDelta: {x: 577, y: 0}
m_Pivot: {x: 0.5, y: 0.5}

View File

@@ -0,0 +1,113 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1001 &100100000
Prefab:
m_ObjectHideFlags: 1
serializedVersion: 2
m_Modification:
m_TransformParent: {fileID: 0}
m_Modifications: []
m_RemovedComponents: []
m_ParentPrefab: {fileID: 0}
m_RootGameObject: {fileID: 1302053982947836}
m_IsPrefabParent: 1
--- !u!1 &1302053982947836
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 5
m_Component:
- component: {fileID: 224719784157228276}
- component: {fileID: 114992251083577052}
- component: {fileID: 114369077888295230}
- component: {fileID: 114537156113323346}
- component: {fileID: 114050720182901700}
m_Layer: 5
m_Name: DebugUI HBox
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &114050720182901700
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1302053982947836}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: e8261e6f2e5fac44da64da2b23939e9a, type: 3}
m_Name:
m_EditorClassIdentifier:
colorDefault: {r: 0.8, g: 0.8, b: 0.8, a: 1}
colorSelected: {r: 0.25, g: 0.65, b: 0.8, a: 1}
parentUIHandler: {fileID: 0}
previousUIHandler: {fileID: 0}
nextUIHandler: {fileID: 0}
--- !u!114 &114369077888295230
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1302053982947836}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 1741964061, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_HorizontalFit: 0
m_VerticalFit: 2
--- !u!114 &114537156113323346
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1302053982947836}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 2bd470ffc0c0fe54faddbf8d466bf519, type: 3}
m_Name:
m_EditorClassIdentifier:
contentHolder: {fileID: 224719784157228276}
--- !u!114 &114992251083577052
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1302053982947836}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: -405508275, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Padding:
m_Left: 0
m_Right: 0
m_Top: 0
m_Bottom: 0
m_ChildAlignment: 0
m_Spacing: 2
m_ChildForceExpandWidth: 1
m_ChildForceExpandHeight: 0
m_ChildControlWidth: 1
m_ChildControlHeight: 0
--- !u!224 &224719784157228276
RectTransform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1302053982947836}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 26}
m_Pivot: {x: 0.5, y: 1}

View File

@@ -0,0 +1,212 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1001 &100100000
Prefab:
m_ObjectHideFlags: 1
serializedVersion: 2
m_Modification:
m_TransformParent: {fileID: 0}
m_Modifications: []
m_RemovedComponents: []
m_ParentPrefab: {fileID: 0}
m_RootGameObject: {fileID: 1100371661045084}
m_IsPrefabParent: 1
--- !u!1 &1100371661045084
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 5
m_Component:
- component: {fileID: 224720214277421396}
- component: {fileID: 114971047630175700}
m_Layer: 5
m_Name: DebugUI IntField
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!1 &1207032646716234
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 5
m_Component:
- component: {fileID: 224309343631572978}
- component: {fileID: 222840031335149136}
- component: {fileID: 114601347101323698}
m_Layer: 5
m_Name: Text
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!1 &1644687155343164
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 5
m_Component:
- component: {fileID: 224518799942003328}
- component: {fileID: 222991141768779948}
- component: {fileID: 114504040572925244}
m_Layer: 5
m_Name: Int
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &114504040572925244
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1644687155343164}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 0.8, g: 0.8, b: 0.8, a: 1}
m_RaycastTarget: 0
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
m_FontData:
m_Font: {fileID: 12800000, guid: 74a5091d8707f334b9a5c31ef71a64ba, type: 3}
m_FontSize: 16
m_FontStyle: 0
m_BestFit: 0
m_MinSize: 1
m_MaxSize: 40
m_Alignment: 3
m_AlignByGeometry: 0
m_RichText: 0
m_HorizontalOverflow: 0
m_VerticalOverflow: 0
m_LineSpacing: 1
m_Text: 0
--- !u!114 &114601347101323698
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1207032646716234}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 0.8, g: 0.8, b: 0.8, a: 1}
m_RaycastTarget: 0
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
m_FontData:
m_Font: {fileID: 12800000, guid: 74a5091d8707f334b9a5c31ef71a64ba, type: 3}
m_FontSize: 16
m_FontStyle: 0
m_BestFit: 0
m_MinSize: 10
m_MaxSize: 40
m_Alignment: 3
m_AlignByGeometry: 0
m_RichText: 0
m_HorizontalOverflow: 0
m_VerticalOverflow: 0
m_LineSpacing: 1
m_Text: New Text
--- !u!114 &114971047630175700
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1100371661045084}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 3de67e2fb3c96a542b808862989985e0, type: 3}
m_Name:
m_EditorClassIdentifier:
colorDefault: {r: 0.8, g: 0.8, b: 0.8, a: 1}
colorSelected: {r: 0.25, g: 0.65, b: 0.8, a: 1}
nameLabel: {fileID: 114601347101323698}
valueLabel: {fileID: 114504040572925244}
--- !u!222 &222840031335149136
CanvasRenderer:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1207032646716234}
--- !u!222 &222991141768779948
CanvasRenderer:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1644687155343164}
--- !u!224 &224309343631572978
RectTransform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1207032646716234}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 224720214277421396}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0.5, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0.5, y: 1}
--- !u!224 &224518799942003328
RectTransform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1644687155343164}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 224720214277421396}
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!224 &224720214277421396
RectTransform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1100371661045084}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children:
- {fileID: 224309343631572978}
- {fileID: 224518799942003328}
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 26}
m_Pivot: {x: 0.5, y: 0.5}

View File

@@ -0,0 +1,953 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1001 &100100000
Prefab:
m_ObjectHideFlags: 1
serializedVersion: 2
m_Modification:
m_TransformParent: {fileID: 0}
m_Modifications: []
m_RemovedComponents: []
m_ParentPrefab: {fileID: 0}
m_RootGameObject: {fileID: 1481385858290834}
m_IsPrefabParent: 1
--- !u!1 &1031930737030514
GameObject:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 5
m_Component:
- component: {fileID: 224222931961724930}
m_Layer: 5
m_Name: Sliding Area
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!1 &1157659775779164
GameObject:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 5
m_Component:
- component: {fileID: 224032405375473854}
- component: {fileID: 222502714886812374}
- component: {fileID: 114258963550902032}
m_Layer: 5
m_Name: Handle
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!1 &1193163269005052
GameObject:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 5
m_Component:
- component: {fileID: 224563081888437474}
- component: {fileID: 222723792781457702}
- component: {fileID: 114607729654368332}
- component: {fileID: 114080217410698576}
m_Layer: 5
m_Name: Scrollbar Horizontal
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 0
--- !u!1 &1481385858290834
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 5
m_Component:
- component: {fileID: 224481716535368988}
- component: {fileID: 222334382701207864}
- component: {fileID: 114641895251469650}
- component: {fileID: 114200909511311822}
- component: {fileID: 114095782430481536}
- component: {fileID: 114358209095303848}
- component: {fileID: 114002074949699770}
m_Layer: 5
m_Name: DebugUI Panel
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!1 &1488004196661762
GameObject:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 5
m_Component:
- component: {fileID: 224982697890735170}
- component: {fileID: 114062238365270692}
- component: {fileID: 114646799636776326}
m_Layer: 5
m_Name: Content
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!1 &1566365363825024
GameObject:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 5
m_Component:
- component: {fileID: 224331172789687600}
- component: {fileID: 222881498785153132}
- component: {fileID: 114674513437991784}
m_Layer: 5
m_Name: Handle
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!1 &1599979385028726
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 5
m_Component:
- component: {fileID: 224734842163899044}
- component: {fileID: 222387563949684278}
- component: {fileID: 114807868571886560}
- component: {fileID: 114121917159994304}
m_Layer: 5
m_Name: Header
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!1 &1722629955080566
GameObject:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 5
m_Component:
- component: {fileID: 224230088708445616}
- component: {fileID: 222067053952777220}
- component: {fileID: 114584516951306838}
- component: {fileID: 114517050931817002}
m_Layer: 5
m_Name: Scrollbar Vertical
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!1 &1865759466118732
GameObject:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 5
m_Component:
- component: {fileID: 224917764046594536}
m_Layer: 5
m_Name: Sliding Area
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!1 &1905254433598784
GameObject:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 5
m_Component:
- component: {fileID: 224367139880787956}
- component: {fileID: 222968323484495154}
- component: {fileID: 114379239449222426}
- component: {fileID: 114990942331515556}
m_Layer: 5
m_Name: Viewport
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!1 &1934506059440930
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 5
m_Component:
- component: {fileID: 224093067269654272}
- component: {fileID: 222390109283270248}
- component: {fileID: 114589248217440660}
- component: {fileID: 114259601227683192}
- component: {fileID: 114664006040389854}
m_Layer: 5
m_Name: Scroll View
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &114002074949699770
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1481385858290834}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 5f61540bb3be4c2409cf6d2f51435714, type: 3}
m_Name:
m_EditorClassIdentifier:
nameLabel: {fileID: 114807868571886560}
scrollRect: {fileID: 114589248217440660}
viewport: {fileID: 224367139880787956}
--- !u!114 &114062238365270692
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1488004196661762}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 1297475563, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Padding:
m_Left: 5
m_Right: 0
m_Top: 0
m_Bottom: 0
m_ChildAlignment: 0
m_Spacing: 1
m_ChildForceExpandWidth: 1
m_ChildForceExpandHeight: 0
m_ChildControlWidth: 1
m_ChildControlHeight: 0
--- !u!114 &114080217410698576
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1193163269005052}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: -2061169968, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Navigation:
m_Mode: 3
m_SelectOnUp: {fileID: 0}
m_SelectOnDown: {fileID: 0}
m_SelectOnLeft: {fileID: 0}
m_SelectOnRight: {fileID: 0}
m_Transition: 1
m_Colors:
m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
m_ColorMultiplier: 1
m_FadeDuration: 0.1
m_SpriteState:
m_HighlightedSprite: {fileID: 0}
m_PressedSprite: {fileID: 0}
m_DisabledSprite: {fileID: 0}
m_AnimationTriggers:
m_NormalTrigger: Normal
m_HighlightedTrigger: Highlighted
m_PressedTrigger: Pressed
m_DisabledTrigger: Disabled
m_Interactable: 1
m_TargetGraphic: {fileID: 114258963550902032}
m_HandleRect: {fileID: 224032405375473854}
m_Direction: 0
m_Value: 0
m_Size: 1
m_NumberOfSteps: 0
m_OnValueChanged:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.Scrollbar+ScrollEvent, UnityEngine.UI, Version=1.0.0.0,
Culture=neutral, PublicKeyToken=null
--- !u!114 &114095782430481536
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1481385858290834}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 1741964061, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_HorizontalFit: 0
m_VerticalFit: 0
--- !u!114 &114121917159994304
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1599979385028726}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 1679637790, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_IgnoreLayout: 0
m_MinWidth: -1
m_MinHeight: -1
m_PreferredWidth: -1
m_PreferredHeight: -1
m_FlexibleWidth: -1
m_FlexibleHeight: -1
m_LayoutPriority: 1
--- !u!114 &114200909511311822
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1481385858290834}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 1297475563, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Padding:
m_Left: 5
m_Right: 5
m_Top: 5
m_Bottom: 5
m_ChildAlignment: 0
m_Spacing: 5
m_ChildForceExpandWidth: 1
m_ChildForceExpandHeight: 0
m_ChildControlWidth: 1
m_ChildControlHeight: 1
--- !u!114 &114258963550902032
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1157659775779164}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 0.3, g: 0.3, b: 0.3, a: 1}
m_RaycastTarget: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
m_Sprite: {fileID: 21300000, guid: 127279d577f25ac4ea17dae3782e5074, type: 3}
m_Type: 0
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
--- !u!114 &114259601227683192
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1934506059440930}
m_Enabled: 0
m_EditorHideFlags: 0
m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 0, b: 0, a: 0.392}
m_RaycastTarget: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
m_Sprite: {fileID: 21300000, guid: 127279d577f25ac4ea17dae3782e5074, type: 3}
m_Type: 0
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
--- !u!114 &114358209095303848
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1481385858290834}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 2bd470ffc0c0fe54faddbf8d466bf519, type: 3}
m_Name:
m_EditorClassIdentifier:
contentHolder: {fileID: 224982697890735170}
--- !u!114 &114379239449222426
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1905254433598784}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: -1200242548, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_ShowMaskGraphic: 0
--- !u!114 &114517050931817002
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1722629955080566}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: -2061169968, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Navigation:
m_Mode: 3
m_SelectOnUp: {fileID: 0}
m_SelectOnDown: {fileID: 0}
m_SelectOnLeft: {fileID: 0}
m_SelectOnRight: {fileID: 0}
m_Transition: 1
m_Colors:
m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
m_ColorMultiplier: 1
m_FadeDuration: 0.1
m_SpriteState:
m_HighlightedSprite: {fileID: 0}
m_PressedSprite: {fileID: 0}
m_DisabledSprite: {fileID: 0}
m_AnimationTriggers:
m_NormalTrigger: Normal
m_HighlightedTrigger: Highlighted
m_PressedTrigger: Pressed
m_DisabledTrigger: Disabled
m_Interactable: 1
m_TargetGraphic: {fileID: 114674513437991784}
m_HandleRect: {fileID: 224331172789687600}
m_Direction: 2
m_Value: 0
m_Size: 1
m_NumberOfSteps: 0
m_OnValueChanged:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.Scrollbar+ScrollEvent, UnityEngine.UI, Version=1.0.0.0,
Culture=neutral, PublicKeyToken=null
--- !u!114 &114584516951306838
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1722629955080566}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 0, g: 0, b: 0, a: 1}
m_RaycastTarget: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
m_Sprite: {fileID: 21300000, guid: 127279d577f25ac4ea17dae3782e5074, type: 3}
m_Type: 0
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
--- !u!114 &114589248217440660
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1934506059440930}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 1367256648, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Content: {fileID: 224982697890735170}
m_Horizontal: 0
m_Vertical: 1
m_MovementType: 2
m_Elasticity: 0.1
m_Inertia: 0
m_DecelerationRate: 0.135
m_ScrollSensitivity: 50
m_Viewport: {fileID: 224367139880787956}
m_HorizontalScrollbar: {fileID: 114080217410698576}
m_VerticalScrollbar: {fileID: 114517050931817002}
m_HorizontalScrollbarVisibility: 0
m_VerticalScrollbarVisibility: 2
m_HorizontalScrollbarSpacing: -3
m_VerticalScrollbarSpacing: 3
m_OnValueChanged:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.ScrollRect+ScrollRectEvent, UnityEngine.UI, Version=1.0.0.0,
Culture=neutral, PublicKeyToken=null
--- !u!114 &114607729654368332
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1193163269005052}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 0, g: 0, b: 0, a: 1}
m_RaycastTarget: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
m_Sprite: {fileID: 21300000, guid: 127279d577f25ac4ea17dae3782e5074, type: 3}
m_Type: 0
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
--- !u!114 &114641895251469650
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1481385858290834}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 0.1, g: 0.1, b: 0.1, a: 0.8509804}
m_RaycastTarget: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
m_Sprite: {fileID: 21300000, guid: 127279d577f25ac4ea17dae3782e5074, type: 3}
m_Type: 0
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
--- !u!114 &114646799636776326
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1488004196661762}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 1741964061, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_HorizontalFit: 0
m_VerticalFit: 1
--- !u!114 &114664006040389854
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1934506059440930}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 1679637790, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_IgnoreLayout: 0
m_MinWidth: -1
m_MinHeight: -1
m_PreferredWidth: -1
m_PreferredHeight: -1
m_FlexibleWidth: 1
m_FlexibleHeight: 1
m_LayoutPriority: 1
--- !u!114 &114674513437991784
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1566365363825024}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 0.3, g: 0.3, b: 0.3, a: 1}
m_RaycastTarget: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
m_Sprite: {fileID: 21300000, guid: 127279d577f25ac4ea17dae3782e5074, type: 3}
m_Type: 0
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
--- !u!114 &114807868571886560
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1599979385028726}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 0.24586153, g: 0.6510919, b: 0.8018868, a: 1}
m_RaycastTarget: 0
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
m_FontData:
m_Font: {fileID: 12800000, guid: 74a5091d8707f334b9a5c31ef71a64ba, type: 3}
m_FontSize: 16
m_FontStyle: 0
m_BestFit: 0
m_MinSize: 1
m_MaxSize: 101
m_Alignment: 1
m_AlignByGeometry: 0
m_RichText: 0
m_HorizontalOverflow: 1
m_VerticalOverflow: 1
m_LineSpacing: 1
m_Text: < Panel Title >
--- !u!114 &114990942331515556
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1905254433598784}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
m_Sprite: {fileID: 10917, guid: 0000000000000000f000000000000000, type: 0}
m_Type: 1
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
--- !u!222 &222067053952777220
CanvasRenderer:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1722629955080566}
--- !u!222 &222334382701207864
CanvasRenderer:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1481385858290834}
--- !u!222 &222387563949684278
CanvasRenderer:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1599979385028726}
--- !u!222 &222390109283270248
CanvasRenderer:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1934506059440930}
--- !u!222 &222502714886812374
CanvasRenderer:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1157659775779164}
--- !u!222 &222723792781457702
CanvasRenderer:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1193163269005052}
--- !u!222 &222881498785153132
CanvasRenderer:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1566365363825024}
--- !u!222 &222968323484495154
CanvasRenderer:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1905254433598784}
--- !u!224 &224032405375473854
RectTransform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1157659775779164}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 224917764046594536}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 275, y: -15}
m_SizeDelta: {x: 20, y: 20}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!224 &224093067269654272
RectTransform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1934506059440930}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children:
- {fileID: 224367139880787956}
- {fileID: 224563081888437474}
- {fileID: 224230088708445616}
m_Father: {fileID: 224481716535368988}
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0, y: 1}
--- !u!224 &224222931961724930
RectTransform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1031930737030514}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children:
- {fileID: 224331172789687600}
m_Father: {fileID: 224230088708445616}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: -20, y: -20}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!224 &224230088708445616
RectTransform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1722629955080566}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children:
- {fileID: 224222931961724930}
m_Father: {fileID: 224093067269654272}
m_RootOrder: 2
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 1, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 5, y: -2}
m_Pivot: {x: 1, y: 1}
--- !u!224 &224331172789687600
RectTransform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1566365363825024}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 224222931961724930}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 20, y: 20}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!224 &224367139880787956
RectTransform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1905254433598784}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children:
- {fileID: 224982697890735170}
m_Father: {fileID: 224093067269654272}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0, y: 1}
--- !u!224 &224481716535368988
RectTransform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1481385858290834}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children:
- {fileID: 224734842163899044}
- {fileID: 224093067269654272}
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 1}
m_AnchoredPosition: {x: 5, y: 0}
m_SizeDelta: {x: 600, y: -10}
m_Pivot: {x: 0, y: 0.5}
--- !u!224 &224563081888437474
RectTransform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1193163269005052}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children:
- {fileID: 224917764046594536}
m_Father: {fileID: 224093067269654272}
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 5}
m_Pivot: {x: 0, y: 0}
--- !u!224 &224734842163899044
RectTransform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1599979385028726}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 224481716535368988}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!224 &224917764046594536
RectTransform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1865759466118732}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children:
- {fileID: 224032405375473854}
m_Father: {fileID: 224563081888437474}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 295, y: 0}
m_SizeDelta: {x: -20, y: -20}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!224 &224982697890735170
RectTransform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1488004196661762}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 224367139880787956}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 1}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0, y: 1}

View File

@@ -0,0 +1,545 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &1117777935091328
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 224404899962668226}
- component: {fileID: 222292134107675628}
- component: {fileID: 114934813895219466}
m_Layer: 5
m_Name: Arrow Closed
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &224404899962668226
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1117777935091328}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 224398617048880834}
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0.5}
m_AnchorMax: {x: 0, y: 0.5}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 11, y: 11}
m_Pivot: {x: 0, y: 0.5}
--- !u!222 &222292134107675628
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1117777935091328}
m_CullTransparentMesh: 0
--- !u!114 &114934813895219466
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1117777935091328}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_Sprite: {fileID: 21300000, guid: 7a0568d5e3330b84687e307992be3030, type: 3}
m_Type: 0
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
m_UseSpriteMesh: 0
m_PixelsPerUnitMultiplier: 1
--- !u!1 &1157130882260826
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 224091637017424492}
- component: {fileID: 114246251359002098}
- component: {fileID: 114721609938004740}
- component: {fileID: 222580990534994246}
- component: {fileID: 114267363758275858}
m_Layer: 5
m_Name: Content
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 0
--- !u!224 &224091637017424492
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1157130882260826}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 224053494956566916}
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 590, y: -50}
m_SizeDelta: {x: 590, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &114246251359002098
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1157130882260826}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 59f8146938fff824cb5fd77236b75775, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Padding:
m_Left: 25
m_Right: 0
m_Top: 0
m_Bottom: 0
m_ChildAlignment: 0
m_Spacing: 1
m_ChildForceExpandWidth: 1
m_ChildForceExpandHeight: 0
m_ChildControlWidth: 1
m_ChildControlHeight: 0
m_ChildScaleWidth: 0
m_ChildScaleHeight: 0
m_ReverseArrangement: 0
--- !u!114 &114721609938004740
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1157130882260826}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 3245ec927659c4140ac4f8d17403cc18, type: 3}
m_Name:
m_EditorClassIdentifier:
m_HorizontalFit: 0
m_VerticalFit: 1
--- !u!222 &222580990534994246
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1157130882260826}
m_CullTransparentMesh: 0
--- !u!114 &114267363758275858
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1157130882260826}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 0, g: 0, b: 0, a: 0.2509804}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_Sprite: {fileID: 21300000, guid: 127279d577f25ac4ea17dae3782e5074, type: 3}
m_Type: 0
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
m_UseSpriteMesh: 0
m_PixelsPerUnitMultiplier: 1
--- !u!1 &1675372956212332
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 224861680556189892}
- component: {fileID: 222407094714348334}
- component: {fileID: 114534572167021932}
m_Layer: 5
m_Name: Arrow Opened
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 0
--- !u!224 &224861680556189892
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1675372956212332}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 224398617048880834}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0.5}
m_AnchorMax: {x: 0, y: 0.5}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 11, y: 11}
m_Pivot: {x: 0, y: 0.5}
--- !u!222 &222407094714348334
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1675372956212332}
m_CullTransparentMesh: 0
--- !u!114 &114534572167021932
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1675372956212332}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_Sprite: {fileID: 21300000, guid: a674720496c1ed248a5b7ea3e22a11fd, type: 3}
m_Type: 0
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
m_UseSpriteMesh: 0
m_PixelsPerUnitMultiplier: 1
--- !u!1 &1741108581676328
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 224398617048880834}
- component: {fileID: 114589844970474540}
m_Layer: 5
m_Name: Header
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &224398617048880834
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1741108581676328}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children:
- {fileID: 224861680556189892}
- {fileID: 224404899962668226}
- {fileID: 224133929923872250}
m_Father: {fileID: 224053494956566916}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 590, y: 26}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &114589844970474540
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1741108581676328}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: e4786b5477cac0a42855b21fdaa2242f, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Navigation:
m_Mode: 3
m_SelectOnUp: {fileID: 0}
m_SelectOnDown: {fileID: 0}
m_SelectOnLeft: {fileID: 0}
m_SelectOnRight: {fileID: 0}
m_Transition: 0
m_Colors:
m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
m_ColorMultiplier: 1
m_FadeDuration: 0.1
m_SpriteState:
m_HighlightedSprite: {fileID: 0}
m_PressedSprite: {fileID: 0}
m_SelectedSprite: {fileID: 0}
m_DisabledSprite: {fileID: 0}
m_AnimationTriggers:
m_NormalTrigger: Normal
m_HighlightedTrigger: Highlighted
m_PressedTrigger: Pressed
m_SelectedTrigger: Highlighted
m_DisabledTrigger: Disabled
m_Interactable: 1
m_TargetGraphic: {fileID: 0}
toggleTransition: 0
graphic: {fileID: 0}
m_Group: {fileID: 0}
onValueChanged:
m_PersistentCalls:
m_Calls: []
m_IsOn: 0
content: {fileID: 1157130882260826}
arrowOpened: {fileID: 1675372956212332}
arrowClosed: {fileID: 1117777935091328}
--- !u!1 &1880654171993120
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 224053494956566916}
- component: {fileID: 114903677526224182}
- component: {fileID: 114617406789257194}
- component: {fileID: 114488953024160460}
- component: {fileID: 114624457690215086}
m_Layer: 0
m_Name: DebugUI Row
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &224053494956566916
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1880654171993120}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children:
- {fileID: 224398617048880834}
- {fileID: 224091637017424492}
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 295, y: 0}
m_SizeDelta: {x: 590, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &114903677526224182
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1880654171993120}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 59f8146938fff824cb5fd77236b75775, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Padding:
m_Left: 0
m_Right: 0
m_Top: 0
m_Bottom: 0
m_ChildAlignment: 0
m_Spacing: 0
m_ChildForceExpandWidth: 1
m_ChildForceExpandHeight: 1
m_ChildControlWidth: 1
m_ChildControlHeight: 0
m_ChildScaleWidth: 0
m_ChildScaleHeight: 0
m_ReverseArrangement: 0
--- !u!114 &114617406789257194
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1880654171993120}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 3245ec927659c4140ac4f8d17403cc18, type: 3}
m_Name:
m_EditorClassIdentifier:
m_HorizontalFit: 0
m_VerticalFit: 1
--- !u!114 &114488953024160460
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1880654171993120}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 2bd470ffc0c0fe54faddbf8d466bf519, type: 3}
m_Name:
m_EditorClassIdentifier:
contentHolder: {fileID: 224091637017424492}
--- !u!114 &114624457690215086
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1880654171993120}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 4822e5675c12bf14d93b254d27ec8bd7, type: 3}
m_Name:
m_EditorClassIdentifier:
colorDefault: {r: 0.8, g: 0.8, b: 0.8, a: 1}
colorSelected: {r: 0.25, g: 0.65, b: 0.8, a: 1}
nameLabel: {fileID: 114398791307483412}
valueToggle: {fileID: 114589844970474540}
--- !u!1 &1887383709356810
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 224133929923872250}
- component: {fileID: 222546040197109316}
- component: {fileID: 114398791307483412}
m_Layer: 5
m_Name: Text
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &224133929923872250
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1887383709356810}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 224398617048880834}
m_RootOrder: 2
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 10, y: 0}
m_SizeDelta: {x: -20, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &222546040197109316
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1887383709356810}
m_CullTransparentMesh: 0
--- !u!114 &114398791307483412
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1887383709356810}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 0.8, g: 0.8, b: 0.8, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_FontData:
m_Font: {fileID: 12800000, guid: 74a5091d8707f334b9a5c31ef71a64ba, type: 3}
m_FontSize: 16
m_FontStyle: 0
m_BestFit: 0
m_MinSize: 1
m_MaxSize: 40
m_Alignment: 3
m_AlignByGeometry: 0
m_RichText: 0
m_HorizontalOverflow: 0
m_VerticalOverflow: 0
m_LineSpacing: 1
m_Text: 'Foldout
'

View File

@@ -0,0 +1,359 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1001 &100100000
Prefab:
m_ObjectHideFlags: 1
serializedVersion: 2
m_Modification:
m_TransformParent: {fileID: 0}
m_Modifications: []
m_RemovedComponents: []
m_ParentPrefab: {fileID: 0}
m_RootGameObject: {fileID: 1437325305121156}
m_IsPrefabParent: 1
--- !u!1 &1065939112215114
GameObject:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 5
m_Component:
- component: {fileID: 224966733864680812}
- component: {fileID: 222377872708390736}
- component: {fileID: 114292651576274254}
m_Layer: 5
m_Name: Checkmark
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!1 &1270668410908612
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 5
m_Component:
- component: {fileID: 224880713722797300}
- component: {fileID: 222015033422095748}
- component: {fileID: 114837831741351564}
m_Layer: 5
m_Name: Text
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!1 &1437325305121156
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 5
m_Component:
- component: {fileID: 224131888606727344}
- component: {fileID: 114161427897257596}
m_Layer: 5
m_Name: DebugUI Toggle
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!1 &1827389558877520
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 5
m_Component:
- component: {fileID: 224857934284754986}
- component: {fileID: 114917248682948150}
m_Layer: 5
m_Name: Toggle
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!1 &1884732763285276
GameObject:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 5
m_Component:
- component: {fileID: 224363072221133230}
- component: {fileID: 222337274610193516}
- component: {fileID: 114150752865928086}
m_Layer: 5
m_Name: Background
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &114150752865928086
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1884732763285276}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
m_Sprite: {fileID: 21300000, guid: d49e78756811bfa4aafb8b6535417991, type: 3}
m_Type: 1
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
--- !u!114 &114161427897257596
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1437325305121156}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 99811d558fd910d4b95f1fd7c0ba9ce9, type: 3}
m_Name:
m_EditorClassIdentifier:
colorDefault: {r: 0.8, g: 0.8, b: 0.8, a: 1}
colorSelected: {r: 0.25, g: 0.65, b: 0.8, a: 1}
parentUIHandler: {fileID: 0}
previousUIHandler: {fileID: 0}
nextUIHandler: {fileID: 0}
nameLabel: {fileID: 114837831741351564}
valueToggle: {fileID: 114917248682948150}
checkmarkImage: {fileID: 114292651576274254}
--- !u!114 &114292651576274254
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1065939112215114}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
m_Sprite: {fileID: 21300000, guid: b346b2a2df1d290438be3287b6419408, type: 3}
m_Type: 0
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
--- !u!114 &114837831741351564
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1270668410908612}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 0.8, g: 0.8, b: 0.8, a: 1}
m_RaycastTarget: 0
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
m_FontData:
m_Font: {fileID: 12800000, guid: 74a5091d8707f334b9a5c31ef71a64ba, type: 3}
m_FontSize: 16
m_FontStyle: 0
m_BestFit: 0
m_MinSize: 1
m_MaxSize: 40
m_Alignment: 3
m_AlignByGeometry: 0
m_RichText: 0
m_HorizontalOverflow: 0
m_VerticalOverflow: 0
m_LineSpacing: 1
m_Text: New Text
--- !u!114 &114917248682948150
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1827389558877520}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 2109663825, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Navigation:
m_Mode: 3
m_SelectOnUp: {fileID: 0}
m_SelectOnDown: {fileID: 0}
m_SelectOnLeft: {fileID: 0}
m_SelectOnRight: {fileID: 0}
m_Transition: 0
m_Colors:
m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
m_ColorMultiplier: 1
m_FadeDuration: 0.1
m_SpriteState:
m_HighlightedSprite: {fileID: 0}
m_PressedSprite: {fileID: 0}
m_DisabledSprite: {fileID: 0}
m_AnimationTriggers:
m_NormalTrigger: Normal
m_HighlightedTrigger: Highlighted
m_PressedTrigger: Pressed
m_DisabledTrigger: Disabled
m_Interactable: 1
m_TargetGraphic: {fileID: 114150752865928086}
toggleTransition: 1
graphic: {fileID: 114292651576274254}
m_Group: {fileID: 0}
onValueChanged:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.Toggle+ToggleEvent, UnityEngine.UI, Version=1.0.0.0,
Culture=neutral, PublicKeyToken=null
m_IsOn: 1
--- !u!222 &222015033422095748
CanvasRenderer:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1270668410908612}
--- !u!222 &222337274610193516
CanvasRenderer:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1884732763285276}
--- !u!222 &222377872708390736
CanvasRenderer:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1065939112215114}
--- !u!224 &224131888606727344
RectTransform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1437325305121156}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children:
- {fileID: 224880713722797300}
- {fileID: 224857934284754986}
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 26}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!224 &224363072221133230
RectTransform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1884732763285276}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children:
- {fileID: 224966733864680812}
m_Father: {fileID: 224857934284754986}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 1}
m_AnchorMax: {x: 0, y: 1}
m_AnchoredPosition: {x: 10, y: -14}
m_SizeDelta: {x: 25, y: 25}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!224 &224857934284754986
RectTransform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1827389558877520}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children:
- {fileID: 224363072221133230}
m_Father: {fileID: 224131888606727344}
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!224 &224880713722797300
RectTransform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1270668410908612}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 224131888606727344}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0.5, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0.5, y: 1}
--- !u!224 &224966733864680812
RectTransform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1065939112215114}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 224363072221133230}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: -1, y: 0}
m_SizeDelta: {x: 11, y: 11}
m_Pivot: {x: 0.5, y: 0.5}

View File

@@ -0,0 +1,376 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &2368718078528869817
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1673340790989863129}
- component: {fileID: 3503763130880174647}
- component: {fileID: 3018950842132618206}
m_Layer: 5
m_Name: Background
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &1673340790989863129
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2368718078528869817}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children:
- {fileID: 5120158742204622507}
m_Father: {fileID: 8149065848021925743}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 1}
m_AnchorMax: {x: 0, y: 1}
m_AnchoredPosition: {x: 10, y: -14}
m_SizeDelta: {x: 25, y: 25}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &3503763130880174647
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2368718078528869817}
m_CullTransparentMesh: 0
--- !u!114 &3018950842132618206
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2368718078528869817}
m_Enabled: 1
m_EditorHideFlags: 0
m_GeneratorAsset: {fileID: 0}
m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
m_Sprite: {fileID: 21300000, guid: d49e78756811bfa4aafb8b6535417991, type: 3}
m_Type: 1
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
m_UseSpriteMesh: 0
--- !u!1 &6088400672834037823
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 3714948537159544433}
- component: {fileID: 3051664556868383130}
- component: {fileID: 4555019519957560431}
m_Layer: 5
m_Name: Text
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &3714948537159544433
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 6088400672834037823}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 108402283379224504}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0.5, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0.5, y: 1}
--- !u!222 &3051664556868383130
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 6088400672834037823}
m_CullTransparentMesh: 0
--- !u!114 &4555019519957560431
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 6088400672834037823}
m_Enabled: 1
m_EditorHideFlags: 0
m_GeneratorAsset: {fileID: 0}
m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 0.8, g: 0.8, b: 0.8, a: 1}
m_RaycastTarget: 0
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
m_FontData:
m_Font: {fileID: 12800000, guid: 74a5091d8707f334b9a5c31ef71a64ba, type: 3}
m_FontSize: 16
m_FontStyle: 0
m_BestFit: 0
m_MinSize: 1
m_MaxSize: 40
m_Alignment: 3
m_AlignByGeometry: 0
m_RichText: 0
m_HorizontalOverflow: 0
m_VerticalOverflow: 0
m_LineSpacing: 1
m_Text: TEST
--- !u!1 &6319085260396780317
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 8149065848021925743}
- component: {fileID: 5350503726096508716}
m_Layer: 5
m_Name: Toggle
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &8149065848021925743
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 6319085260396780317}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children:
- {fileID: 1673340790989863129}
m_Father: {fileID: 108402283379224504}
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &5350503726096508716
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 6319085260396780317}
m_Enabled: 1
m_EditorHideFlags: 0
m_GeneratorAsset: {fileID: 0}
m_Script: {fileID: 2109663825, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Navigation:
m_Mode: 3
m_SelectOnUp: {fileID: 0}
m_SelectOnDown: {fileID: 0}
m_SelectOnLeft: {fileID: 0}
m_SelectOnRight: {fileID: 0}
m_Transition: 0
m_Colors:
m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
m_ColorMultiplier: 1
m_FadeDuration: 0.1
m_SpriteState:
m_HighlightedSprite: {fileID: 0}
m_PressedSprite: {fileID: 0}
m_SelectedSprite: {fileID: 0}
m_DisabledSprite: {fileID: 0}
m_AnimationTriggers:
m_NormalTrigger: Normal
m_HighlightedTrigger: Highlighted
m_PressedTrigger: Pressed
m_SelectedTrigger: Highlighted
m_DisabledTrigger: Disabled
m_Interactable: 1
m_TargetGraphic: {fileID: 3018950842132618206}
toggleTransition: 1
graphic: {fileID: 5560730182145989459}
m_Group: {fileID: 0}
onValueChanged:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.Toggle+ToggleEvent, UnityEngine.UI, Version=1.0.0.0,
Culture=neutral, PublicKeyToken=null
m_IsOn: 1
--- !u!1 &7797485299855706120
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 108402283379224504}
- component: {fileID: 3791955773124009916}
m_Layer: 5
m_Name: DebugUI ToggleHistory
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &108402283379224504
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7797485299855706120}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children:
- {fileID: 3714948537159544433}
- {fileID: 8149065848021925743}
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 26}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &3791955773124009916
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7797485299855706120}
m_Enabled: 1
m_EditorHideFlags: 0
m_GeneratorAsset: {fileID: 0}
m_Script: {fileID: 11500000, guid: 5535c6474b864a44eb65121514d1edd2, type: 3}
m_Name:
m_EditorClassIdentifier:
colorDefault: {r: 0.8, g: 0.8, b: 0.8, a: 1}
colorSelected: {r: 0.25, g: 0.65, b: 0.8, a: 1}
nameLabel: {fileID: 4555019519957560431}
valueToggle: {fileID: 5350503726096508716}
checkmarkImage: {fileID: 5560730182145989459}
--- !u!1 &8435239307204561265
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 5120158742204622507}
- component: {fileID: 313288647622822694}
- component: {fileID: 5560730182145989459}
m_Layer: 5
m_Name: Checkmark
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &5120158742204622507
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8435239307204561265}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 1673340790989863129}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: -1, y: 0}
m_SizeDelta: {x: 11, y: 11}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &313288647622822694
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8435239307204561265}
m_CullTransparentMesh: 0
--- !u!114 &5560730182145989459
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8435239307204561265}
m_Enabled: 1
m_EditorHideFlags: 0
m_GeneratorAsset: {fileID: 0}
m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
m_Sprite: {fileID: 21300000, guid: b346b2a2df1d290438be3287b6419408, type: 3}
m_Type: 0
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
m_UseSpriteMesh: 0

View File

@@ -0,0 +1,217 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1001 &100100000
Prefab:
m_ObjectHideFlags: 1
serializedVersion: 2
m_Modification:
m_TransformParent: {fileID: 0}
m_Modifications: []
m_RemovedComponents: []
m_ParentPrefab: {fileID: 0}
m_RootGameObject: {fileID: 1100371661045084}
m_IsPrefabParent: 1
--- !u!1 &1100371661045084
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 5
m_Component:
- component: {fileID: 224720214277421396}
- component: {fileID: 114663689249701822}
m_Layer: 5
m_Name: DebugUI UIntField
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!1 &1207032646716234
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 5
m_Component:
- component: {fileID: 224309343631572978}
- component: {fileID: 222840031335149136}
- component: {fileID: 114601347101323698}
m_Layer: 5
m_Name: Text
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!1 &1644687155343164
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 5
m_Component:
- component: {fileID: 224518799942003328}
- component: {fileID: 222991141768779948}
- component: {fileID: 114504040572925244}
m_Layer: 5
m_Name: UInt
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &114504040572925244
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1644687155343164}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 0.8, g: 0.8, b: 0.8, a: 1}
m_RaycastTarget: 0
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
m_FontData:
m_Font: {fileID: 12800000, guid: 74a5091d8707f334b9a5c31ef71a64ba, type: 3}
m_FontSize: 16
m_FontStyle: 0
m_BestFit: 0
m_MinSize: 1
m_MaxSize: 40
m_Alignment: 3
m_AlignByGeometry: 0
m_RichText: 0
m_HorizontalOverflow: 0
m_VerticalOverflow: 0
m_LineSpacing: 1
m_Text: '0
'
--- !u!114 &114601347101323698
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1207032646716234}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 0.8, g: 0.8, b: 0.8, a: 1}
m_RaycastTarget: 0
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
m_FontData:
m_Font: {fileID: 12800000, guid: 74a5091d8707f334b9a5c31ef71a64ba, type: 3}
m_FontSize: 16
m_FontStyle: 0
m_BestFit: 0
m_MinSize: 10
m_MaxSize: 40
m_Alignment: 3
m_AlignByGeometry: 0
m_RichText: 0
m_HorizontalOverflow: 0
m_VerticalOverflow: 0
m_LineSpacing: 1
m_Text: New Text
--- !u!114 &114663689249701822
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1100371661045084}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: e4700d8d03bde1e4c9138b22dc84d06e, type: 3}
m_Name:
m_EditorClassIdentifier:
colorDefault: {r: 0.8, g: 0.8, b: 0.8, a: 1}
colorSelected: {r: 0.25, g: 0.65, b: 0.8, a: 1}
parentUIHandler: {fileID: 0}
previousUIHandler: {fileID: 0}
nextUIHandler: {fileID: 0}
nameLabel: {fileID: 114601347101323698}
valueLabel: {fileID: 114504040572925244}
--- !u!222 &222840031335149136
CanvasRenderer:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1207032646716234}
--- !u!222 &222991141768779948
CanvasRenderer:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1644687155343164}
--- !u!224 &224309343631572978
RectTransform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1207032646716234}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 224720214277421396}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0.5, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0.5, y: 1}
--- !u!224 &224518799942003328
RectTransform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1644687155343164}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 224720214277421396}
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!224 &224720214277421396
RectTransform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1100371661045084}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children:
- {fileID: 224309343631572978}
- {fileID: 224518799942003328}
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 26}
m_Pivot: {x: 0.5, y: 0.5}

View File

@@ -0,0 +1,113 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1001 &100100000
Prefab:
m_ObjectHideFlags: 1
serializedVersion: 2
m_Modification:
m_TransformParent: {fileID: 0}
m_Modifications: []
m_RemovedComponents: []
m_ParentPrefab: {fileID: 0}
m_RootGameObject: {fileID: 1932304026370548}
m_IsPrefabParent: 1
--- !u!1 &1932304026370548
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 5
m_Component:
- component: {fileID: 224489511352681190}
- component: {fileID: 114973694596060540}
- component: {fileID: 114186061498625504}
- component: {fileID: 114415231330772934}
- component: {fileID: 114675398277375380}
m_Layer: 5
m_Name: DebugUI VBox
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &114186061498625504
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1932304026370548}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 1741964061, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_HorizontalFit: 0
m_VerticalFit: 2
--- !u!114 &114415231330772934
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1932304026370548}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 2bd470ffc0c0fe54faddbf8d466bf519, type: 3}
m_Name:
m_EditorClassIdentifier:
contentHolder: {fileID: 224489511352681190}
--- !u!114 &114675398277375380
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1932304026370548}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: ee7ce141c3937674f8ac247bbcf63711, type: 3}
m_Name:
m_EditorClassIdentifier:
colorDefault: {r: 0.8, g: 0.8, b: 0.8, a: 1}
colorSelected: {r: 0.25, g: 0.65, b: 0.8, a: 1}
parentUIHandler: {fileID: 0}
previousUIHandler: {fileID: 0}
nextUIHandler: {fileID: 0}
--- !u!114 &114973694596060540
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1932304026370548}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 1297475563, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Padding:
m_Left: 0
m_Right: 0
m_Top: 0
m_Bottom: 0
m_ChildAlignment: 0
m_Spacing: 1
m_ChildForceExpandWidth: 1
m_ChildForceExpandHeight: 0
m_ChildControlWidth: 1
m_ChildControlHeight: 0
--- !u!224 &224489511352681190
RectTransform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1932304026370548}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 297.5, y: 0}
m_SizeDelta: {x: 585, y: 0}
m_Pivot: {x: 0.5, y: 0.5}

View File

@@ -0,0 +1,215 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1001 &100100000
Prefab:
m_ObjectHideFlags: 1
serializedVersion: 2
m_Modification:
m_TransformParent: {fileID: 0}
m_Modifications: []
m_RemovedComponents: []
m_ParentPrefab: {fileID: 0}
m_RootGameObject: {fileID: 1100371661045084}
m_IsPrefabParent: 1
--- !u!1 &1100371661045084
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 5
m_Component:
- component: {fileID: 224720214277421396}
- component: {fileID: 114728986975802896}
m_Layer: 5
m_Name: DebugUI Value
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!1 &1207032646716234
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 5
m_Component:
- component: {fileID: 224309343631572978}
- component: {fileID: 222840031335149136}
- component: {fileID: 114601347101323698}
m_Layer: 5
m_Name: Text
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!1 &1644687155343164
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 5
m_Component:
- component: {fileID: 224518799942003328}
- component: {fileID: 222991141768779948}
- component: {fileID: 114504040572925244}
m_Layer: 5
m_Name: Value
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &114504040572925244
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1644687155343164}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 0.8, g: 0.8, b: 0.8, a: 1}
m_RaycastTarget: 0
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
m_FontData:
m_Font: {fileID: 12800000, guid: 74a5091d8707f334b9a5c31ef71a64ba, type: 3}
m_FontSize: 16
m_FontStyle: 0
m_BestFit: 0
m_MinSize: 1
m_MaxSize: 40
m_Alignment: 3
m_AlignByGeometry: 0
m_RichText: 0
m_HorizontalOverflow: 0
m_VerticalOverflow: 0
m_LineSpacing: 1
m_Text: '-'
--- !u!114 &114601347101323698
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1207032646716234}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 0.8, g: 0.8, b: 0.8, a: 1}
m_RaycastTarget: 0
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
m_FontData:
m_Font: {fileID: 12800000, guid: 74a5091d8707f334b9a5c31ef71a64ba, type: 3}
m_FontSize: 16
m_FontStyle: 0
m_BestFit: 0
m_MinSize: 10
m_MaxSize: 40
m_Alignment: 3
m_AlignByGeometry: 0
m_RichText: 0
m_HorizontalOverflow: 0
m_VerticalOverflow: 0
m_LineSpacing: 1
m_Text: New Text
--- !u!114 &114728986975802896
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1100371661045084}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: bc78ce7c3bda3b845b1e94eade19277f, type: 3}
m_Name:
m_EditorClassIdentifier:
colorDefault: {r: 0.8, g: 0.8, b: 0.8, a: 1}
colorSelected: {r: 0.25, g: 0.65, b: 0.8, a: 1}
parentUIHandler: {fileID: 0}
previousUIHandler: {fileID: 0}
nextUIHandler: {fileID: 0}
nameLabel: {fileID: 114601347101323698}
valueLabel: {fileID: 114504040572925244}
--- !u!222 &222840031335149136
CanvasRenderer:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1207032646716234}
--- !u!222 &222991141768779948
CanvasRenderer:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1644687155343164}
--- !u!224 &224309343631572978
RectTransform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1207032646716234}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 224720214277421396}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0.5, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0.5, y: 1}
--- !u!224 &224518799942003328
RectTransform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1644687155343164}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 224720214277421396}
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!224 &224720214277421396
RectTransform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1100371661045084}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children:
- {fileID: 224309343631572978}
- {fileID: 224518799942003328}
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 26}
m_Pivot: {x: 0.5, y: 0.5}

View File

@@ -0,0 +1,918 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1001 &100100000
Prefab:
m_ObjectHideFlags: 1
serializedVersion: 2
m_Modification:
m_TransformParent: {fileID: 0}
m_Modifications: []
m_RemovedComponents: []
m_ParentPrefab: {fileID: 0}
m_RootGameObject: {fileID: 1824161537160572}
m_IsPrefabParent: 1
--- !u!1 &1000253583962742
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 5
m_Component:
- component: {fileID: 224567491695975322}
- component: {fileID: 114081939383876678}
- component: {fileID: 114434434898593228}
- component: {fileID: 222204674852569514}
- component: {fileID: 114464518795440322}
m_Layer: 5
m_Name: Content
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 0
--- !u!1 &1012720931439766
GameObject:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 5
m_Component:
- component: {fileID: 224830884550109362}
- component: {fileID: 114052755486438782}
m_Layer: 5
m_Name: Y
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!1 &1130115472082746
GameObject:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 5
m_Component:
- component: {fileID: 224706956361671994}
- component: {fileID: 222005006668798890}
- component: {fileID: 114329069004064474}
m_Layer: 5
m_Name: Arrow Opened
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 0
--- !u!1 &1148007685381894
GameObject:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 5
m_Component:
- component: {fileID: 224164519412943956}
- component: {fileID: 222567969018017144}
- component: {fileID: 114436501280300254}
m_Layer: 5
m_Name: Float
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!1 &1152789203095516
GameObject:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 5
m_Component:
- component: {fileID: 224968136025723832}
- component: {fileID: 222055709189933652}
- component: {fileID: 114237068256633500}
m_Layer: 5
m_Name: Text
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!1 &1274862592617490
GameObject:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 5
m_Component:
- component: {fileID: 224893115642743000}
- component: {fileID: 222632083614627112}
- component: {fileID: 114978663805510782}
m_Layer: 5
m_Name: Text
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!1 &1542407194814678
GameObject:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 5
m_Component:
- component: {fileID: 224549454960910334}
- component: {fileID: 222171717351467336}
- component: {fileID: 114418590756337294}
m_Layer: 5
m_Name: Arrow Closed
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!1 &1566192875931650
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 5
m_Component:
- component: {fileID: 224170233976618892}
- component: {fileID: 114607134917420868}
m_Layer: 5
m_Name: Header
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!1 &1600372330852584
GameObject:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 5
m_Component:
- component: {fileID: 224825524383815906}
- component: {fileID: 222695356751001088}
- component: {fileID: 114528877921578766}
m_Layer: 5
m_Name: Text
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!1 &1824161537160572
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 5
m_Component:
- component: {fileID: 224169904409585018}
- component: {fileID: 114748588260806824}
- component: {fileID: 114305449451372118}
- component: {fileID: 114659607754701708}
- component: {fileID: 114978099781231812}
m_Layer: 0
m_Name: DebugUI Vector2
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!1 &1933346971002712
GameObject:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 5
m_Component:
- component: {fileID: 224476615423791208}
- component: {fileID: 114700987091432614}
m_Layer: 5
m_Name: X
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!1 &1938873859003020
GameObject:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 5
m_Component:
- component: {fileID: 224939911741753398}
- component: {fileID: 222798688748188130}
- component: {fileID: 114079233188468464}
m_Layer: 5
m_Name: Float
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &114052755486438782
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1012720931439766}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: c42b71ff0e23e2d4a8a32a2bc85acac0, type: 3}
m_Name:
m_EditorClassIdentifier:
colorDefault: {r: 0.8, g: 0.8, b: 0.8, a: 1}
colorSelected: {r: 0.25, g: 0.65, b: 0.8, a: 1}
nameLabel: {fileID: 114978663805510782}
valueLabel: {fileID: 114079233188468464}
--- !u!114 &114079233188468464
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1938873859003020}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 0.8, g: 0.8, b: 0.8, a: 1}
m_RaycastTarget: 0
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
m_FontData:
m_Font: {fileID: 12800000, guid: 74a5091d8707f334b9a5c31ef71a64ba, type: 3}
m_FontSize: 16
m_FontStyle: 0
m_BestFit: 0
m_MinSize: 1
m_MaxSize: 40
m_Alignment: 3
m_AlignByGeometry: 0
m_RichText: 0
m_HorizontalOverflow: 0
m_VerticalOverflow: 0
m_LineSpacing: 1
m_Text: 0
--- !u!114 &114081939383876678
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1000253583962742}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 1297475563, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Padding:
m_Left: 25
m_Right: 0
m_Top: 0
m_Bottom: 0
m_ChildAlignment: 0
m_Spacing: 1
m_ChildForceExpandWidth: 1
m_ChildForceExpandHeight: 0
m_ChildControlWidth: 1
m_ChildControlHeight: 0
--- !u!114 &114237068256633500
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1152789203095516}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 0.8, g: 0.8, b: 0.8, a: 1}
m_RaycastTarget: 0
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
m_FontData:
m_Font: {fileID: 12800000, guid: 74a5091d8707f334b9a5c31ef71a64ba, type: 3}
m_FontSize: 16
m_FontStyle: 0
m_BestFit: 0
m_MinSize: 10
m_MaxSize: 40
m_Alignment: 3
m_AlignByGeometry: 0
m_RichText: 0
m_HorizontalOverflow: 0
m_VerticalOverflow: 0
m_LineSpacing: 1
m_Text: X
--- !u!114 &114305449451372118
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1824161537160572}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 1741964061, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_HorizontalFit: 0
m_VerticalFit: 2
--- !u!114 &114329069004064474
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1130115472082746}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
m_Sprite: {fileID: 21300000, guid: a674720496c1ed248a5b7ea3e22a11fd, type: 3}
m_Type: 0
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
--- !u!114 &114418590756337294
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1542407194814678}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
m_Sprite: {fileID: 21300000, guid: 7a0568d5e3330b84687e307992be3030, type: 3}
m_Type: 0
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
--- !u!114 &114434434898593228
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1000253583962742}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 1741964061, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_HorizontalFit: 0
m_VerticalFit: 1
--- !u!114 &114436501280300254
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1148007685381894}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 0.8, g: 0.8, b: 0.8, a: 1}
m_RaycastTarget: 0
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
m_FontData:
m_Font: {fileID: 12800000, guid: 74a5091d8707f334b9a5c31ef71a64ba, type: 3}
m_FontSize: 16
m_FontStyle: 0
m_BestFit: 0
m_MinSize: 1
m_MaxSize: 40
m_Alignment: 3
m_AlignByGeometry: 0
m_RichText: 0
m_HorizontalOverflow: 0
m_VerticalOverflow: 0
m_LineSpacing: 1
m_Text: 0
--- !u!114 &114464518795440322
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1000253583962742}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 0, g: 0, b: 0, a: 0.2509804}
m_RaycastTarget: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
m_Sprite: {fileID: 21300000, guid: 127279d577f25ac4ea17dae3782e5074, type: 3}
m_Type: 0
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
--- !u!114 &114528877921578766
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1600372330852584}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 0.8, g: 0.8, b: 0.8, a: 1}
m_RaycastTarget: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
m_FontData:
m_Font: {fileID: 12800000, guid: 74a5091d8707f334b9a5c31ef71a64ba, type: 3}
m_FontSize: 16
m_FontStyle: 0
m_BestFit: 0
m_MinSize: 1
m_MaxSize: 40
m_Alignment: 3
m_AlignByGeometry: 0
m_RichText: 0
m_HorizontalOverflow: 0
m_VerticalOverflow: 0
m_LineSpacing: 1
m_Text: 'Vector2
'
--- !u!114 &114607134917420868
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1566192875931650}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: e4786b5477cac0a42855b21fdaa2242f, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Navigation:
m_Mode: 3
m_SelectOnUp: {fileID: 0}
m_SelectOnDown: {fileID: 0}
m_SelectOnLeft: {fileID: 0}
m_SelectOnRight: {fileID: 0}
m_Transition: 0
m_Colors:
m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
m_ColorMultiplier: 1
m_FadeDuration: 0.1
m_SpriteState:
m_HighlightedSprite: {fileID: 0}
m_PressedSprite: {fileID: 0}
m_DisabledSprite: {fileID: 0}
m_AnimationTriggers:
m_NormalTrigger: Normal
m_HighlightedTrigger: Highlighted
m_PressedTrigger: Pressed
m_DisabledTrigger: Disabled
m_Interactable: 1
m_TargetGraphic: {fileID: 0}
toggleTransition: 0
graphic: {fileID: 0}
m_Group: {fileID: 0}
onValueChanged:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.Toggle+ToggleEvent, UnityEngine.UI, Version=1.0.0.0,
Culture=neutral, PublicKeyToken=null
m_IsOn: 0
content: {fileID: 1000253583962742}
arrowOpened: {fileID: 1130115472082746}
arrowClosed: {fileID: 1542407194814678}
--- !u!114 &114659607754701708
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1824161537160572}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 2bd470ffc0c0fe54faddbf8d466bf519, type: 3}
m_Name:
m_EditorClassIdentifier:
contentHolder: {fileID: 224567491695975322}
--- !u!114 &114700987091432614
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1933346971002712}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: c42b71ff0e23e2d4a8a32a2bc85acac0, type: 3}
m_Name:
m_EditorClassIdentifier:
colorDefault: {r: 0.8, g: 0.8, b: 0.8, a: 1}
colorSelected: {r: 0.25, g: 0.65, b: 0.8, a: 1}
nameLabel: {fileID: 114237068256633500}
valueLabel: {fileID: 114436501280300254}
--- !u!114 &114748588260806824
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1824161537160572}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 1297475563, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Padding:
m_Left: 0
m_Right: 0
m_Top: 0
m_Bottom: 0
m_ChildAlignment: 0
m_Spacing: 0
m_ChildForceExpandWidth: 1
m_ChildForceExpandHeight: 1
m_ChildControlWidth: 1
m_ChildControlHeight: 0
--- !u!114 &114978099781231812
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1824161537160572}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 45cb393cffafe3e4292c35a3a3a94c26, type: 3}
m_Name:
m_EditorClassIdentifier:
colorDefault: {r: 0.8, g: 0.8, b: 0.8, a: 1}
colorSelected: {r: 0.25, g: 0.65, b: 0.8, a: 1}
nameLabel: {fileID: 114528877921578766}
valueToggle: {fileID: 114607134917420868}
fieldX: {fileID: 114700987091432614}
fieldY: {fileID: 114052755486438782}
--- !u!114 &114978663805510782
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1274862592617490}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 0.8, g: 0.8, b: 0.8, a: 1}
m_RaycastTarget: 0
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
m_FontData:
m_Font: {fileID: 12800000, guid: 74a5091d8707f334b9a5c31ef71a64ba, type: 3}
m_FontSize: 16
m_FontStyle: 0
m_BestFit: 0
m_MinSize: 10
m_MaxSize: 40
m_Alignment: 3
m_AlignByGeometry: 0
m_RichText: 0
m_HorizontalOverflow: 0
m_VerticalOverflow: 0
m_LineSpacing: 1
m_Text: Y
--- !u!222 &222005006668798890
CanvasRenderer:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1130115472082746}
--- !u!222 &222055709189933652
CanvasRenderer:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1152789203095516}
--- !u!222 &222171717351467336
CanvasRenderer:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1542407194814678}
--- !u!222 &222204674852569514
CanvasRenderer:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1000253583962742}
--- !u!222 &222567969018017144
CanvasRenderer:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1148007685381894}
--- !u!222 &222632083614627112
CanvasRenderer:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1274862592617490}
--- !u!222 &222695356751001088
CanvasRenderer:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1600372330852584}
--- !u!222 &222798688748188130
CanvasRenderer:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1938873859003020}
--- !u!224 &224164519412943956
RectTransform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1148007685381894}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 224476615423791208}
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!224 &224169904409585018
RectTransform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1824161537160572}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children:
- {fileID: 224170233976618892}
- {fileID: 224567491695975322}
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 295, y: 0}
m_SizeDelta: {x: 590, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!224 &224170233976618892
RectTransform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1566192875931650}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children:
- {fileID: 224706956361671994}
- {fileID: 224549454960910334}
- {fileID: 224825524383815906}
m_Father: {fileID: 224169904409585018}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 590, y: 26}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!224 &224476615423791208
RectTransform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1933346971002712}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children:
- {fileID: 224968136025723832}
- {fileID: 224164519412943956}
m_Father: {fileID: 224567491695975322}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 1}
m_AnchorMax: {x: 0, y: 1}
m_AnchoredPosition: {x: 307.5, y: -13}
m_SizeDelta: {x: 565, y: 26}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!224 &224549454960910334
RectTransform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1542407194814678}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 224170233976618892}
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0.5}
m_AnchorMax: {x: 0, y: 0.5}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 11, y: 11}
m_Pivot: {x: 0, y: 0.5}
--- !u!224 &224567491695975322
RectTransform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1000253583962742}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children:
- {fileID: 224476615423791208}
- {fileID: 224830884550109362}
m_Father: {fileID: 224169904409585018}
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 1}
m_AnchorMax: {x: 0, y: 1}
m_AnchoredPosition: {x: 295, y: -56.5}
m_SizeDelta: {x: 590, y: 53}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!224 &224706956361671994
RectTransform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1130115472082746}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 224170233976618892}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0.5}
m_AnchorMax: {x: 0, y: 0.5}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 11, y: 11}
m_Pivot: {x: 0, y: 0.5}
--- !u!224 &224825524383815906
RectTransform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1600372330852584}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 224170233976618892}
m_RootOrder: 2
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 10, y: 0}
m_SizeDelta: {x: -20, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!224 &224830884550109362
RectTransform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1012720931439766}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children:
- {fileID: 224893115642743000}
- {fileID: 224939911741753398}
m_Father: {fileID: 224567491695975322}
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 1}
m_AnchorMax: {x: 0, y: 1}
m_AnchoredPosition: {x: 307.5, y: -40}
m_SizeDelta: {x: 565, y: 26}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!224 &224893115642743000
RectTransform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1274862592617490}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 224830884550109362}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0.5, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0.5, y: 1}
--- !u!224 &224939911741753398
RectTransform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1938873859003020}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 224830884550109362}
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!224 &224968136025723832
RectTransform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1152789203095516}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 224476615423791208}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0.5, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0.5, y: 1}

View File

@@ -0,0 +1,379 @@
// TProfilingSampler<TEnum>.samples should just be an array. Unfortunately, Enum cannot be converted to int without generating garbage.
// This could be worked around by using Unsafe but it's not available at the moment.
// So in the meantime we use a Dictionary with a perf hit...
//#define USE_UNSAFE
#if UNITY_2020_1_OR_NEWER
#define UNITY_USE_RECORDER
#endif
using System;
using System.Linq;
using System.Collections.Generic;
using UnityEngine.Profiling;
namespace UnityEngine.Rendering
{
class TProfilingSampler<TEnum> : ProfilingSampler where TEnum : Enum
{
#if USE_UNSAFE
internal static TProfilingSampler<TEnum>[] samples;
#else
internal static Dictionary<TEnum, TProfilingSampler<TEnum>> samples = new Dictionary<TEnum, TProfilingSampler<TEnum>>();
#endif
static TProfilingSampler()
{
var names = Enum.GetNames(typeof(TEnum));
#if USE_UNSAFE
var values = Enum.GetValues(typeof(TEnum)).Cast<int>().ToArray();
samples = new TProfilingSampler<TEnum>[values.Max() + 1];
#else
var values = Enum.GetValues(typeof(TEnum));
#endif
for (int i = 0; i < names.Length; i++)
{
var sample = new TProfilingSampler<TEnum>(names[i]);
#if USE_UNSAFE
samples[values[i]] = sample;
#else
samples.Add((TEnum)values.GetValue(i), sample);
#endif
}
}
public TProfilingSampler(string name)
: base(name)
{
}
}
/// <summary>
/// Wrapper around CPU and GPU profiling samplers.
/// Use this along ProfilingScope to profile a piece of code.
/// </summary>
public class ProfilingSampler
{
/// <summary>
/// Get the sampler for the corresponding enumeration value.
/// </summary>
/// <typeparam name="TEnum">Type of the enumeration.</typeparam>
/// <param name="marker">Enumeration value.</param>
/// <returns>The profiling sampler for the given enumeration value.</returns>
public static ProfilingSampler Get<TEnum>(TEnum marker)
where TEnum : Enum
{
#if USE_UNSAFE
return TProfilingSampler<TEnum>.samples[Unsafe.As<TEnum, int>(ref marker)];
#else
TProfilingSampler<TEnum>.samples.TryGetValue(marker, out var sampler);
return sampler;
#endif
}
/// <summary>
/// Constructor.
/// </summary>
/// <param name="name">Name of the profiling sampler.</param>
public ProfilingSampler(string name)
{
// Caution: Name of sampler MUST not match name provide to cmd.BeginSample(), otherwise
// we get a mismatch of marker when enabling the profiler.
#if UNITY_USE_RECORDER
sampler = CustomSampler.Create(name, true); // Event markers, command buffer CPU profiling and GPU profiling
#else
// In this case, we need to use the BeginSample(string) API, since it creates a new sampler by that name under the hood,
// we need rename this sampler to not clash with the implicit one (it won't be used in this case)
sampler = CustomSampler.Create($"Dummy_{name}");
#endif
inlineSampler = CustomSampler.Create($"Inl_{name}"); // Profiles code "immediately"
this.name = name;
#if UNITY_USE_RECORDER
m_Recorder = sampler.GetRecorder();
m_Recorder.enabled = false;
m_InlineRecorder = inlineSampler.GetRecorder();
m_InlineRecorder.enabled = false;
#endif
}
/// <summary>
/// Begin the profiling block.
/// </summary>
/// <param name="cmd">Command buffer used by the profiling block.</param>
public void Begin(CommandBuffer cmd)
{
if (cmd != null)
#if UNITY_USE_RECORDER
if (sampler != null && sampler.isValid)
cmd.BeginSample(sampler);
else
cmd.BeginSample(name);
#else
cmd.BeginSample(name);
#endif
inlineSampler?.Begin();
}
/// <summary>
/// End the profiling block.
/// </summary>
/// <param name="cmd">Command buffer used by the profiling block.</param>
public void End(CommandBuffer cmd)
{
if (cmd != null)
#if UNITY_USE_RECORDER
if (sampler != null && sampler.isValid)
cmd.EndSample(sampler);
else
cmd.EndSample(name);
#else
m_Cmd.EndSample(name);
#endif
inlineSampler?.End();
}
internal bool IsValid() { return (sampler != null && inlineSampler != null); }
internal CustomSampler sampler { get; private set; }
internal CustomSampler inlineSampler { get; private set; }
/// <summary>
/// Name of the Profiling Sampler
/// </summary>
public string name { get; private set; }
#if UNITY_USE_RECORDER
Recorder m_Recorder;
Recorder m_InlineRecorder;
#endif
/// <summary>
/// Set to true to enable recording of profiling sampler timings.
/// </summary>
public bool enableRecording
{
set
{
#if UNITY_USE_RECORDER
m_Recorder.enabled = value;
m_InlineRecorder.enabled = value;
#endif
}
}
#if UNITY_USE_RECORDER
/// <summary>
/// GPU Elapsed time in milliseconds.
/// </summary>
public float gpuElapsedTime => m_Recorder.enabled ? m_Recorder.gpuElapsedNanoseconds / 1000000.0f : 0.0f;
/// <summary>
/// Number of times the Profiling Sampler has hit on the GPU
/// </summary>
public int gpuSampleCount => m_Recorder.enabled ? m_Recorder.gpuSampleBlockCount : 0;
/// <summary>
/// CPU Elapsed time in milliseconds (Command Buffer execution).
/// </summary>
public float cpuElapsedTime => m_Recorder.enabled ? m_Recorder.elapsedNanoseconds / 1000000.0f : 0.0f;
/// <summary>
/// Number of times the Profiling Sampler has hit on the CPU in the command buffer.
/// </summary>
public int cpuSampleCount => m_Recorder.enabled ? m_Recorder.sampleBlockCount : 0;
/// <summary>
/// CPU Elapsed time in milliseconds (Direct execution).
/// </summary>
public float inlineCpuElapsedTime => m_InlineRecorder.enabled ? m_InlineRecorder.elapsedNanoseconds / 1000000.0f : 0.0f;
/// <summary>
/// Number of times the Profiling Sampler has hit on the CPU.
/// </summary>
public int inlineCpuSampleCount => m_InlineRecorder.enabled ? m_InlineRecorder.sampleBlockCount : 0;
#else
/// <summary>
/// GPU Elapsed time in milliseconds.
/// </summary>
public float gpuElapsedTime => 0.0f;
/// <summary>
/// Number of times the Profiling Sampler has hit on the GPU
/// </summary>
public int gpuSampleCount => 0;
/// <summary>
/// CPU Elapsed time in milliseconds (Command Buffer execution).
/// </summary>
public float cpuElapsedTime => 0.0f;
/// <summary>
/// Number of times the Profiling Sampler has hit on the CPU in the command buffer.
/// </summary>
public int cpuSampleCount => 0;
/// <summary>
/// CPU Elapsed time in milliseconds (Direct execution).
/// </summary>
public float inlineCpuElapsedTime => 0.0f;
/// <summary>
/// Number of times the Profiling Sampler has hit on the CPU.
/// </summary>
public int inlineCpuSampleCount => 0;
#endif
// Keep the constructor private
ProfilingSampler() {}
}
#if DEVELOPMENT_BUILD || UNITY_EDITOR
/// <summary>
/// Scoped Profiling markers
/// </summary>
public struct ProfilingScope : IDisposable
{
CommandBuffer m_Cmd;
bool m_Disposed;
ProfilingSampler m_Sampler;
/// <summary>
/// Profiling Scope constructor
/// </summary>
/// <param name="cmd">Command buffer used to add markers and compute execution timings.</param>
/// <param name="sampler">Profiling Sampler to be used for this scope.</param>
public ProfilingScope(CommandBuffer cmd, ProfilingSampler sampler)
{
// NOTE: Do not mix with named CommandBuffers.
// Currently there's an issue which results in mismatched markers.
// The named CommandBuffer will close its "profiling scope" on execution.
// That will orphan ProfilingScope markers as the named CommandBuffer marker
// is their "parent".
// Resulting in following pattern:
// exec(cmd.start, scope.start, cmd.end) and exec(cmd.start, scope.end, cmd.end)
m_Cmd = cmd;
m_Disposed = false;
m_Sampler = sampler;
m_Sampler?.Begin(m_Cmd);
}
/// <summary>
/// Dispose pattern implementation
/// </summary>
public void Dispose()
{
Dispose(true);
}
// Protected implementation of Dispose pattern.
void Dispose(bool disposing)
{
if (m_Disposed)
return;
// As this is a struct, it could have been initialized using an empty constructor so we
// need to make sure `cmd` isn't null to avoid a crash. Switching to a class would fix
// this but will generate garbage on every frame (and this struct is used quite a lot).
if (disposing)
{
m_Sampler?.End(m_Cmd);
}
m_Disposed = true;
}
}
#else
/// <summary>
/// Scoped Profiling markers
/// </summary>
public struct ProfilingScope : IDisposable
{
/// <summary>
/// Profiling Scope constructor
/// </summary>
/// <param name="cmd">Command buffer used to add markers and compute execution timings.</param>
/// <param name="sampler">Profiling Sampler to be used for this scope.</param>
public ProfilingScope(CommandBuffer cmd, ProfilingSampler sampler)
{
}
/// <summary>
/// Dispose pattern implementation
/// </summary>
public void Dispose()
{
}
}
#endif
/// <summary>
/// Profiling Sampler class.
/// </summary>
[System.Obsolete("Please use ProfilingScope")]
public struct ProfilingSample : IDisposable
{
readonly CommandBuffer m_Cmd;
readonly string m_Name;
bool m_Disposed;
CustomSampler m_Sampler;
/// <summary>
/// Constructor
/// </summary>
/// <param name="cmd">Command Buffer.</param>
/// <param name="name">Name of the profiling sample.</param>
/// <param name="sampler">Custom sampler for CPU profiling.</param>
public ProfilingSample(CommandBuffer cmd, string name, CustomSampler sampler = null)
{
m_Cmd = cmd;
m_Name = name;
m_Disposed = false;
if (cmd != null && name != "")
cmd.BeginSample(name);
m_Sampler = sampler;
m_Sampler?.Begin();
}
// Shortcut to string.Format() using only one argument (reduces Gen0 GC pressure)
/// <summary>
/// Constructor
/// </summary>
/// <param name="cmd">Command Buffer.</param>
/// <param name="format">Formating of the profiling sample.</param>
/// <param name="arg">Parameters for formating the name.</param>
public ProfilingSample(CommandBuffer cmd, string format, object arg) : this(cmd, string.Format(format, arg))
{
}
// Shortcut to string.Format() with variable amount of arguments - for performance critical
// code you should pre-build & cache the marker name instead of using this
/// <summary>
/// Constructor.
/// </summary>
/// <param name="cmd">Command Buffer.</param>
/// <param name="format">Formating of the profiling sample.</param>
/// <param name="args">Parameters for formating the name.</param>
public ProfilingSample(CommandBuffer cmd, string format, params object[] args) : this(cmd, string.Format(format, args))
{
}
/// <summary>
/// Dispose pattern implementation
/// </summary>
public void Dispose()
{
Dispose(true);
}
// Protected implementation of Dispose pattern.
void Dispose(bool disposing)
{
if (m_Disposed)
return;
// As this is a struct, it could have been initialized using an empty constructor so we
// need to make sure `cmd` isn't null to avoid a crash. Switching to a class would fix
// this but will generate garbage on every frame (and this struct is used quite a lot).
if (disposing)
{
if (m_Cmd != null && m_Name != "")
m_Cmd.EndSample(m_Name);
m_Sampler?.End();
}
m_Disposed = true;
}
}
}

View File

@@ -0,0 +1,38 @@
using System.Runtime.CompilerServices;
[assembly: InternalsVisibleTo("Unity.RenderPipelines.Core.Editor.Tests")]
namespace UnityEngine.Rendering
{
//We need to have only one version number amongst packages (so public)
/// <summary>
/// Documentation Info class.
/// </summary>
public class DocumentationInfo
{
//Update this field when upgrading the target Documentation for the package
//Should be linked to the package version somehow.
/// <summary>
/// Current version of the documentation.
/// </summary>
public const string version = "11.0";
}
//Need to live in Runtime as Attribute of documentation is on Runtime classes \o/
/// <summary>
/// Documentation class.
/// </summary>
class Documentation : DocumentationInfo
{
//This must be used like
//[HelpURL(Documentation.baseURL + Documentation.version + Documentation.subURL + "some-page" + Documentation.endURL)]
//It cannot support String.Format nor string interpolation
internal const string baseURL = "https://docs.unity3d.com/Packages/com.unity.render-pipelines.core@";
internal const string subURL = "/manual/";
internal const string endURL = ".html";
//Temporary for now, there is several part of the Core documentation that are misplaced in HDRP documentation.
//use this base url for them:
internal const string baseURLHDRP = "https://docs.unity3d.com/Packages/com.unity.render-pipelines.high-definition@";
}
}

View File

@@ -0,0 +1,93 @@
using System.Collections.Generic;
namespace UnityEngine
{
#if UNITY_EDITOR
using UnityEditor;
public class InputManagerEntry
{
public enum Kind { KeyOrButton, Mouse, Axis }
public enum Axis { X, Y, Third, Fourth, Fifth, Sixth, Seventh, Eigth }
public enum Joy { All, First, Second }
public string name = "";
public string desc = "";
public string btnNegative = "";
public string btnPositive = "";
public string altBtnNegative = "";
public string altBtnPositive = "";
public float gravity = 0.0f;
public float deadZone = 0.0f;
public float sensitivity = 0.0f;
public bool snap = false;
public bool invert = false;
public Kind kind = Kind.Axis;
public Axis axis = Axis.X;
public Joy joystick = Joy.All;
}
public class InputRegistering
{
static bool InputAlreadyRegistered(string name, InputManagerEntry.Kind kind, SerializedProperty spAxes)
{
for (var i = 0; i < spAxes.arraySize; ++i)
{
var spAxis = spAxes.GetArrayElementAtIndex(i);
var axisName = spAxis.FindPropertyRelative("m_Name").stringValue;
var kindValue = spAxis.FindPropertyRelative("type").intValue;
if (axisName == name && (int)kind == kindValue)
return true;
}
return false;
}
static void WriteEntry(SerializedProperty spAxes, InputManagerEntry entry)
{
if (InputAlreadyRegistered(entry.name, entry.kind, spAxes))
return;
spAxes.InsertArrayElementAtIndex(spAxes.arraySize);
var spAxis = spAxes.GetArrayElementAtIndex(spAxes.arraySize - 1);
spAxis.FindPropertyRelative("m_Name").stringValue = entry.name;
spAxis.FindPropertyRelative("descriptiveName").stringValue = entry.desc;
spAxis.FindPropertyRelative("negativeButton").stringValue = entry.btnNegative;
spAxis.FindPropertyRelative("altNegativeButton").stringValue = entry.altBtnNegative;
spAxis.FindPropertyRelative("positiveButton").stringValue = entry.btnPositive;
spAxis.FindPropertyRelative("altPositiveButton").stringValue = entry.altBtnPositive;
spAxis.FindPropertyRelative("gravity").floatValue = entry.gravity;
spAxis.FindPropertyRelative("dead").floatValue = entry.deadZone;
spAxis.FindPropertyRelative("sensitivity").floatValue = entry.sensitivity;
spAxis.FindPropertyRelative("snap").boolValue = entry.snap;
spAxis.FindPropertyRelative("invert").boolValue = entry.invert;
spAxis.FindPropertyRelative("type").intValue = (int)entry.kind;
spAxis.FindPropertyRelative("axis").intValue = (int)entry.axis;
spAxis.FindPropertyRelative("joyNum").intValue = (int)entry.joystick;
}
public static void RegisterInputs(List<InputManagerEntry> entries)
{
// Grab reference to input manager
var assets = AssetDatabase.LoadAllAssetsAtPath("ProjectSettings/InputManager.asset");
// Temporary fix. This happens some time with HDRP init when it's called before asset database is initialized (probably related to package load order).
if (assets.Length == 0)
return;
var inputManager = assets[0];
// Wrap in serialized object
var soInputManager = new SerializedObject(inputManager);
var spAxes = soInputManager.FindProperty("m_Axes");
foreach (InputManagerEntry entry in entries)
{
WriteEntry(spAxes, entry);
}
// Commit
soInputManager.ApplyModifiedProperties();
}
}
#endif
}

View File

@@ -0,0 +1,109 @@
using System.Collections.Generic;
namespace UnityEngine.Rendering.LookDev
{
/// <summary>
/// Interface that Scriptable Render Pipelines should implement to be able to use LookDev window
/// </summary>
public interface IDataProvider
{
/// <summary>Additional configuration required by this SRP on LookDev's scene creation</summary>
/// <param name="stage">Access element of the LookDev's scene</param>
void FirstInitScene(StageRuntimeInterface stage);
/// <summary>Notify the SRP that sky have changed in LookDev</summary>
/// <param name="camera">The camera of the LookDev's scene</param>
/// <param name="sky">The new Sky informations</param>
/// <param name="stage">Access element of the LookDev's scene</param>
void UpdateSky(Camera camera, Sky sky, StageRuntimeInterface stage);
/// <summary>Notify the LookDev about what debug view mode are available in this SRP</summary>
/// <returns>The list of the mode, None is not required.</returns>
IEnumerable<string> supportedDebugModes { get; }
/// <summary>Notify the SRP about a change in the DebugMode used</summary>
/// <param name="debugIndex">
/// -1: None
/// Others: map the result of <see cref="supportedDebugModes()"/>
/// </param>
void UpdateDebugMode(int debugIndex);
/// <summary>
/// Compute the shadow mask in SRP for LookDev sun simulation
/// </summary>
/// <param name="output">The computed ShadowMask</param>
/// <param name="stage">Access element of the LookDev's scene</param>
void GetShadowMask(ref RenderTexture output, StageRuntimeInterface stage);
/// <summary>
/// Callback called at the beginning of LookDev rendering.
/// </summary>
/// <param name="stage">Access element of the LookDev's scene</param>
void OnBeginRendering(StageRuntimeInterface stage);
/// <summary>
/// Callback called at the beginning of LookDev rendering.
/// </summary>
/// <param name="stage">Access element of the LookDev's scene</param>
void OnEndRendering(StageRuntimeInterface stage);
/// <summary>
/// Callback called to do any necessary cleanup.
/// </summary>
/// <param name="SRI">Access element of the LookDev's scene</param>
void Cleanup(StageRuntimeInterface SRI);
}
/// <summary>
/// Runtime container representing Sky data given to the scriptable render pipeline for rendering
/// </summary>
public struct Sky
{
/// <summary>The cubemap representing this sky</summary>
public Cubemap cubemap;
/// <summary>The longitude offset to rotate this cubemap</summary>
public float longitudeOffset;
/// <summary>The sky exposure</summary>
public float exposure;
}
/// <summary>Runtime link to reflect some Stage functionality for SRP editing</summary>
public class StageRuntimeInterface
{
System.Func<bool, GameObject> m_AddGameObject;
System.Func<Camera> m_GetCamera;
System.Func<Light> m_GetSunLight;
/// <summary>Construct a StageRuntimeInterface</summary>
/// <param name="AddGameObject">Callback to call when adding a GameObject</param>
/// <param name="GetCamera">Callback to call for getting the Camera</param>
/// <param name="GetSunLight">Callback to call for getting the sun Light</param>
public StageRuntimeInterface(
System.Func<bool, GameObject> AddGameObject,
System.Func<Camera> GetCamera,
System.Func<Light> GetSunLight)
{
m_AddGameObject = AddGameObject;
m_GetCamera = GetCamera;
m_GetSunLight = GetSunLight;
}
/// <summary>Create a gameObject in the stage</summary>
/// <param name="persistent">
/// [OPTIONAL] If true, the object is not recreated with the scene update.
/// Default value: false.
/// </param>
/// <returns></returns>
public GameObject AddGameObject(bool persistent = false)
=> m_AddGameObject?.Invoke(persistent);
/// <summary>Get the camera used in the stage</summary>
public Camera camera => m_GetCamera?.Invoke();
/// <summary>Get the sun used in the stage</summary>
public Light sunLight => m_GetSunLight?.Invoke();
/// <summary>Custom data pointer for convenience</summary>
public object SRPData;
}
}

View File

@@ -0,0 +1,285 @@
using System;
using System.Collections.Generic;
using UnityEngine.Rendering;
namespace UnityEngine.Experimental.Rendering.RenderGraphModule
{
/// <summary>
/// Use this struct to set up a new Render Pass.
/// </summary>
public struct RenderGraphBuilder : IDisposable
{
RenderGraphPass m_RenderPass;
RenderGraphResourceRegistry m_Resources;
RenderGraph m_RenderGraph;
bool m_Disposed;
#region Public Interface
/// <summary>
/// Specify that the pass will use a Texture resource as a color render target.
/// This has the same effect as WriteTexture and also automatically sets the Texture to use as a render target.
/// </summary>
/// <param name="input">The Texture resource to use as a color render target.</param>
/// <param name="index">Index for multiple render target usage.</param>
/// <returns>An updated resource handle to the input resource.</returns>
public TextureHandle UseColorBuffer(in TextureHandle input, int index)
{
CheckResource(input.handle);
m_Resources.IncrementWriteCount(input.handle);
m_RenderPass.SetColorBuffer(input, index);
return input;
}
/// <summary>
/// Specify that the pass will use a Texture resource as a depth buffer.
/// </summary>
/// <param name="input">The Texture resource to use as a depth buffer during the pass.</param>
/// <param name="flags">Specify the access level for the depth buffer. This allows you to say whether you will read from or write to the depth buffer, or do both.</param>
/// <returns>An updated resource handle to the input resource.</returns>
public TextureHandle UseDepthBuffer(in TextureHandle input, DepthAccess flags)
{
CheckResource(input.handle);
m_Resources.IncrementWriteCount(input.handle);
m_RenderPass.SetDepthBuffer(input, flags);
return input;
}
/// <summary>
/// Specify a Texture resource to read from during the pass.
/// </summary>
/// <param name="input">The Texture resource to read from during the pass.</param>
/// <returns>An updated resource handle to the input resource.</returns>
public TextureHandle ReadTexture(in TextureHandle input)
{
CheckResource(input.handle);
if (!m_Resources.IsRenderGraphResourceImported(input.handle) && m_Resources.TextureNeedsFallback(input))
{
var texDimension = m_Resources.GetTextureResourceDesc(input.handle).dimension;
if (texDimension == TextureXR.dimension)
{
return m_RenderGraph.defaultResources.blackTextureXR;
}
else if (texDimension == TextureDimension.Tex3D)
{
return m_RenderGraph.defaultResources.blackTexture3DXR;
}
else
{
return m_RenderGraph.defaultResources.blackTexture;
}
}
m_RenderPass.AddResourceRead(input.handle);
return input;
}
/// <summary>
/// Specify a Texture resource to write to during the pass.
/// </summary>
/// <param name="input">The Texture resource to write to during the pass.</param>
/// <returns>An updated resource handle to the input resource.</returns>
public TextureHandle WriteTexture(in TextureHandle input)
{
CheckResource(input.handle);
m_Resources.IncrementWriteCount(input.handle);
// TODO RENDERGRAPH: Manage resource "version" for debugging purpose
m_RenderPass.AddResourceWrite(input.handle);
return input;
}
/// <summary>
/// Specify a Texture resource to read and write to during the pass.
/// </summary>
/// <param name="input">The Texture resource to read and write to during the pass.</param>
/// <returns>An updated resource handle to the input resource.</returns>
public TextureHandle ReadWriteTexture(in TextureHandle input)
{
CheckResource(input.handle);
m_Resources.IncrementWriteCount(input.handle);
m_RenderPass.AddResourceWrite(input.handle);
m_RenderPass.AddResourceRead(input.handle);
return input;
}
/// <summary>
/// Create a new Render Graph Texture resource.
/// This texture will only be available for the current pass and will be assumed to be both written and read so users don't need to add explicit read/write declarations.
/// </summary>
/// <param name="desc">Texture descriptor.</param>
/// <returns>A new transient TextureHandle.</returns>
public TextureHandle CreateTransientTexture(in TextureDesc desc)
{
var result = m_Resources.CreateTexture(desc, m_RenderPass.index);
m_RenderPass.AddTransientResource(result.handle);
return result;
}
/// <summary>
/// Create a new Render Graph Texture resource using the descriptor from another texture.
/// This texture will only be available for the current pass and will be assumed to be both written and read so users don't need to add explicit read/write declarations.
/// </summary>
/// <param name="texture">Texture from which the descriptor should be used.</param>
/// <returns>A new transient TextureHandle.</returns>
public TextureHandle CreateTransientTexture(in TextureHandle texture)
{
var desc = m_Resources.GetTextureResourceDesc(texture.handle);
var result = m_Resources.CreateTexture(desc, m_RenderPass.index);
m_RenderPass.AddTransientResource(result.handle);
return result;
}
/// <summary>
/// Specify a Renderer List resource to use during the pass.
/// </summary>
/// <param name="input">The Renderer List resource to use during the pass.</param>
/// <returns>An updated resource handle to the input resource.</returns>
public RendererListHandle UseRendererList(in RendererListHandle input)
{
m_RenderPass.UseRendererList(input);
return input;
}
/// <summary>
/// Specify a Compute Buffer resource to read from during the pass.
/// </summary>
/// <param name="input">The Compute Buffer resource to read from during the pass.</param>
/// <returns>An updated resource handle to the input resource.</returns>
public ComputeBufferHandle ReadComputeBuffer(in ComputeBufferHandle input)
{
CheckResource(input.handle);
m_RenderPass.AddResourceRead(input.handle);
return input;
}
/// <summary>
/// Specify a Compute Buffer resource to write to during the pass.
/// </summary>
/// <param name="input">The Compute Buffer resource to write to during the pass.</param>
/// <returns>An updated resource handle to the input resource.</returns>
public ComputeBufferHandle WriteComputeBuffer(in ComputeBufferHandle input)
{
CheckResource(input.handle);
m_RenderPass.AddResourceWrite(input.handle);
m_Resources.IncrementWriteCount(input.handle);
return input;
}
/// <summary>
/// Create a new Render Graph Compute Buffer resource.
/// This Compute Buffer will only be available for the current pass and will be assumed to be both written and read so users don't need to add explicit read/write declarations.
/// </summary>
/// <param name="desc">Compute Buffer descriptor.</param>
/// <returns>A new transient ComputeBufferHandle.</returns>
public ComputeBufferHandle CreateTransientComputeBuffer(in ComputeBufferDesc desc)
{
var result = m_Resources.CreateComputeBuffer(desc, m_RenderPass.index);
m_RenderPass.AddTransientResource(result.handle);
return result;
}
/// <summary>
/// Create a new Render Graph Compute Buffer resource using the descriptor from another Compute Buffer.
/// This Compute Buffer will only be available for the current pass and will be assumed to be both written and read so users don't need to add explicit read/write declarations.
/// </summary>
/// <param name="computebuffer">Compute Buffer from which the descriptor should be used.</param>
/// <returns>A new transient ComputeBufferHandle.</returns>
public ComputeBufferHandle CreateTransientComputeBuffer(in ComputeBufferHandle computebuffer)
{
var desc = m_Resources.GetComputeBufferResourceDesc(computebuffer.handle);
var result = m_Resources.CreateComputeBuffer(desc, m_RenderPass.index);
m_RenderPass.AddTransientResource(result.handle);
return result;
}
/// <summary>
/// Specify the render function to use for this pass.
/// A call to this is mandatory for the pass to be valid.
/// </summary>
/// <typeparam name="PassData">The Type of the class that provides data to the Render Pass.</typeparam>
/// <param name="renderFunc">Render function for the pass.</param>
public void SetRenderFunc<PassData>(RenderFunc<PassData> renderFunc) where PassData : class, new()
{
((RenderGraphPass<PassData>)m_RenderPass).renderFunc = renderFunc;
}
/// <summary>
/// Enable asynchronous compute for this pass.
/// </summary>
/// <param name="value">Set to true to enable asynchronous compute.</param>
public void EnableAsyncCompute(bool value)
{
m_RenderPass.EnableAsyncCompute(value);
}
/// <summary>
/// Allow or not pass culling
/// By default all passes can be culled out if the render graph detects it's not actually used.
/// In some cases, a pass may not write or read any texture but rather do something with side effects (like setting a global texture parameter for example).
/// This function can be used to tell the system that it should not cull this pass.
/// </summary>
/// <param name="value">True to allow pass culling.</param>
public void AllowPassCulling(bool value)
{
m_RenderPass.AllowPassCulling(value);
}
/// <summary>
/// Dispose the RenderGraphBuilder instance.
/// </summary>
public void Dispose()
{
Dispose(true);
}
#endregion
#region Internal Interface
internal RenderGraphBuilder(RenderGraphPass renderPass, RenderGraphResourceRegistry resources, RenderGraph renderGraph)
{
m_RenderPass = renderPass;
m_Resources = resources;
m_RenderGraph = renderGraph;
m_Disposed = false;
}
void Dispose(bool disposing)
{
if (m_Disposed)
return;
m_RenderGraph.OnPassAdded(m_RenderPass);
m_Disposed = true;
}
void CheckResource(in ResourceHandle res)
{
#if DEVELOPMENT_BUILD || UNITY_EDITOR
if (res.IsValid())
{
int transientIndex = m_Resources.GetRenderGraphResourceTransientIndex(res);
if (transientIndex == m_RenderPass.index)
{
Debug.LogError($"Trying to read or write a transient resource at pass {m_RenderPass.name}.Transient resource are always assumed to be both read and written.");
}
if (transientIndex != -1 && transientIndex != m_RenderPass.index)
{
throw new ArgumentException($"Trying to use a transient texture (pass index {transientIndex}) in a different pass (pass index {m_RenderPass.index}).");
}
}
else
{
throw new ArgumentException($"Trying to use an invalid resource (pass {m_RenderPass.name}).");
}
#endif
}
internal void GenerateDebugData(bool value)
{
m_RenderPass.GenerateDebugData(value);
}
#endregion
}
}

View File

@@ -0,0 +1,61 @@
using UnityEngine.Rendering;
namespace UnityEngine.Experimental.Rendering.RenderGraphModule
{
/// <summary>
/// Helper class allowing access to default resources (black or white texture, etc.) during render passes.
/// </summary>
public class RenderGraphDefaultResources
{
bool m_IsValid;
// We need to keep around a RTHandle version of default regular 2D textures since RenderGraph API is all RTHandle.
RTHandle m_BlackTexture2D;
RTHandle m_WhiteTexture2D;
/// <summary>Default black 2D texture.</summary>
public TextureHandle blackTexture { get; private set; }
/// <summary>Default white 2D texture.</summary>
public TextureHandle whiteTexture { get; private set; }
/// <summary>Default clear color XR 2D texture.</summary>
public TextureHandle clearTextureXR { get; private set; }
/// <summary>Default magenta XR 2D texture.</summary>
public TextureHandle magentaTextureXR { get; private set; }
/// <summary>Default black XR 2D texture.</summary>
public TextureHandle blackTextureXR { get; private set; }
/// <summary>Default black XR 2D Array texture.</summary>
public TextureHandle blackTextureArrayXR { get; private set; }
/// <summary>Default black (UInt) XR 2D texture.</summary>
public TextureHandle blackUIntTextureXR { get; private set; }
/// <summary>Default black XR 3D texture.</summary>
public TextureHandle blackTexture3DXR { get; private set; }
/// <summary>Default white XR 2D texture.</summary>
public TextureHandle whiteTextureXR { get; private set; }
internal RenderGraphDefaultResources()
{
m_BlackTexture2D = RTHandles.Alloc(Texture2D.blackTexture);
m_WhiteTexture2D = RTHandles.Alloc(Texture2D.whiteTexture);
}
internal void Cleanup()
{
m_BlackTexture2D.Release();
m_WhiteTexture2D.Release();
}
internal void InitializeForRendering(RenderGraph renderGraph)
{
blackTexture = renderGraph.ImportTexture(m_BlackTexture2D);
whiteTexture = renderGraph.ImportTexture(m_WhiteTexture2D);
clearTextureXR = renderGraph.ImportTexture(TextureXR.GetClearTexture());
magentaTextureXR = renderGraph.ImportTexture(TextureXR.GetMagentaTexture());
blackTextureXR = renderGraph.ImportTexture(TextureXR.GetBlackTexture());
blackTextureArrayXR = renderGraph.ImportTexture(TextureXR.GetBlackTextureArray());
blackUIntTextureXR = renderGraph.ImportTexture(TextureXR.GetBlackUIntTexture());
blackTexture3DXR = renderGraph.ImportTexture(TextureXR.GetBlackTexture3D());
whiteTextureXR = renderGraph.ImportTexture(TextureXR.GetWhiteTexture());
}
}
}

View File

@@ -0,0 +1,76 @@
using System;
using System.Text;
namespace UnityEngine.Experimental.Rendering.RenderGraphModule
{
struct RenderGraphLogIndent : IDisposable
{
int m_Indentation;
RenderGraphLogger m_Logger;
bool m_Disposed;
public RenderGraphLogIndent(RenderGraphLogger logger, int indentation = 1)
{
m_Disposed = false;
m_Indentation = indentation;
m_Logger = logger;
m_Logger.IncrementIndentation(m_Indentation);
}
public void Dispose()
{
Dispose(true);
}
void Dispose(bool disposing)
{
Debug.Assert(m_Logger != null, "RenderGraphLogIndent: logger parameter should not be null.");
if (m_Disposed)
return;
if (disposing && m_Logger != null)
{
m_Logger.DecrementIndentation(m_Indentation);
}
m_Disposed = true;
}
}
class RenderGraphLogger
{
StringBuilder m_Builder = new StringBuilder();
int m_CurrentIndentation;
public void Initialize()
{
m_Builder.Clear();
m_CurrentIndentation = 0;
}
public void IncrementIndentation(int value)
{
m_CurrentIndentation += Math.Abs(value);
}
public void DecrementIndentation(int value)
{
m_CurrentIndentation = Math.Max(0, m_CurrentIndentation - Math.Abs(value));
}
public void LogLine(string format, params object[] args)
{
for (int i = 0; i < m_CurrentIndentation; ++i)
m_Builder.Append('\t');
m_Builder.AppendFormat(format, args);
m_Builder.AppendLine();
}
public string GetLog()
{
return m_Builder.ToString();
}
}
}

View File

@@ -0,0 +1,101 @@
using System;
using System.Collections.Generic;
namespace UnityEngine.Experimental.Rendering.RenderGraphModule
{
/// <summary>
/// Helper class provided in the RenderGraphContext to all Render Passes.
/// It allows you to do temporary allocations of various objects during a Render Pass.
/// </summary>
public sealed class RenderGraphObjectPool
{
class SharedObjectPool<T> where T : new()
{
Stack<T> m_Pool = new Stack<T>();
public T Get()
{
var result = m_Pool.Count == 0 ? new T() : m_Pool.Pop();
return result;
}
public void Release(T value)
{
m_Pool.Push(value);
}
static readonly Lazy<SharedObjectPool<T>> s_Instance = new Lazy<SharedObjectPool<T>>();
public static SharedObjectPool<T> sharedPool => s_Instance.Value;
}
Dictionary<(Type, int), Stack<object>> m_ArrayPool = new Dictionary<(Type, int), Stack<object>>();
List<(object, (Type, int))> m_AllocatedArrays = new List<(object, (Type, int))>();
List<MaterialPropertyBlock> m_AllocatedMaterialPropertyBlocks = new List<MaterialPropertyBlock>();
internal RenderGraphObjectPool() {}
/// <summary>
/// Allocate a temporary typed array of a specific size.
/// Unity releases the array at the end of the Render Pass.
/// </summary>
/// <typeparam name="T">Type of the array to be allocated.</typeparam>
/// <param name="size">Number of element in the array.</param>
/// <returns>A new array of type T with size number of elements.</returns>
public T[] GetTempArray<T>(int size)
{
if (!m_ArrayPool.TryGetValue((typeof(T), size), out var stack))
{
stack = new Stack<object>();
m_ArrayPool.Add((typeof(T), size), stack);
}
var result = stack.Count > 0 ? (T[])stack.Pop() : new T[size];
m_AllocatedArrays.Add((result, (typeof(T), size)));
return result;
}
/// <summary>
/// Allocate a temporary MaterialPropertyBlock for the Render Pass.
/// </summary>
/// <returns>A new clean MaterialPropertyBlock.</returns>
public MaterialPropertyBlock GetTempMaterialPropertyBlock()
{
var result = SharedObjectPool<MaterialPropertyBlock>.sharedPool.Get();
result.Clear();
m_AllocatedMaterialPropertyBlocks.Add(result);
return result;
}
internal void ReleaseAllTempAlloc()
{
foreach (var arrayDesc in m_AllocatedArrays)
{
bool result = m_ArrayPool.TryGetValue(arrayDesc.Item2, out var stack);
Debug.Assert(result, "Correct stack type should always be allocated.");
stack.Push(arrayDesc.Item1);
}
m_AllocatedArrays.Clear();
foreach (var mpb in m_AllocatedMaterialPropertyBlocks)
{
SharedObjectPool<MaterialPropertyBlock>.sharedPool.Release(mpb);
}
m_AllocatedMaterialPropertyBlocks.Clear();
}
// Regular pooling API. Only internal use for now
internal T Get<T>() where T : new()
{
var pool = SharedObjectPool<T>.sharedPool;
return pool.Get();
}
internal void Release<T>(T value) where T : new()
{
var pool = SharedObjectPool<T>.sharedPool;
pool.Release(value);
}
}
}

View File

@@ -0,0 +1,163 @@
using System;
using System.Diagnostics;
using System.Collections.Generic;
using UnityEngine.Rendering;
namespace UnityEngine.Experimental.Rendering.RenderGraphModule
{
[DebuggerDisplay("RenderPass: {name} (Index:{index} Async:{enableAsyncCompute})")]
abstract class RenderGraphPass
{
public RenderFunc<PassData> GetExecuteDelegate<PassData>()
where PassData : class, new() => ((RenderGraphPass<PassData>) this).renderFunc;
public abstract void Execute(RenderGraphContext renderGraphContext);
public abstract void Release(RenderGraphObjectPool pool);
public abstract bool HasRenderFunc();
public string name { get; protected set; }
public int index { get; protected set; }
public ProfilingSampler customSampler { get; protected set; }
public bool enableAsyncCompute { get; protected set; }
public bool allowPassCulling { get; protected set; }
public TextureHandle depthBuffer { get; protected set; }
public TextureHandle[] colorBuffers { get; protected set; } = new TextureHandle[RenderGraph.kMaxMRTCount];
public int colorBufferMaxIndex { get; protected set; } = -1;
public int refCount { get; protected set; }
public bool generateDebugData { get; protected set; }
public List<ResourceHandle>[] resourceReadLists = new List<ResourceHandle>[(int)RenderGraphResourceType.Count];
public List<ResourceHandle>[] resourceWriteLists = new List<ResourceHandle>[(int)RenderGraphResourceType.Count];
public List<ResourceHandle>[] transientResourceList = new List<ResourceHandle>[(int)RenderGraphResourceType.Count];
public List<RendererListHandle> usedRendererListList = new List<RendererListHandle>();
public RenderGraphPass()
{
for (int i = 0; i < (int)RenderGraphResourceType.Count; ++i)
{
resourceReadLists[i] = new List<ResourceHandle>();
resourceWriteLists[i] = new List<ResourceHandle>();
transientResourceList[i] = new List<ResourceHandle>();
}
}
public void Clear()
{
name = "";
index = -1;
customSampler = null;
for (int i = 0; i < (int)RenderGraphResourceType.Count; ++i)
{
resourceReadLists[i].Clear();
resourceWriteLists[i].Clear();
transientResourceList[i].Clear();
}
usedRendererListList.Clear();
enableAsyncCompute = false;
allowPassCulling = true;
generateDebugData = true;
refCount = 0;
// Invalidate everything
colorBufferMaxIndex = -1;
depthBuffer = TextureHandle.nullHandle;
for (int i = 0; i < RenderGraph.kMaxMRTCount; ++i)
{
colorBuffers[i] = TextureHandle.nullHandle;
}
}
public void AddResourceWrite(in ResourceHandle res)
{
resourceWriteLists[res.iType].Add(res);
}
public void AddResourceRead(in ResourceHandle res)
{
resourceReadLists[res.iType].Add(res);
}
public void AddTransientResource(in ResourceHandle res)
{
transientResourceList[res.iType].Add(res);
}
public void UseRendererList(RendererListHandle rendererList)
{
usedRendererListList.Add(rendererList);
}
public void EnableAsyncCompute(bool value)
{
enableAsyncCompute = value;
}
public void AllowPassCulling(bool value)
{
allowPassCulling = value;
}
public void GenerateDebugData(bool value)
{
generateDebugData = value;
}
public void SetColorBuffer(TextureHandle resource, int index)
{
Debug.Assert(index < RenderGraph.kMaxMRTCount && index >= 0);
colorBufferMaxIndex = Math.Max(colorBufferMaxIndex, index);
colorBuffers[index] = resource;
AddResourceWrite(resource.handle);
}
public void SetDepthBuffer(TextureHandle resource, DepthAccess flags)
{
depthBuffer = resource;
if ((flags & DepthAccess.Read) != 0)
AddResourceRead(resource.handle);
if ((flags & DepthAccess.Write) != 0)
AddResourceWrite(resource.handle);
}
}
[DebuggerDisplay("RenderPass: {name} (Index:{index} Async:{enableAsyncCompute})")]
internal sealed class RenderGraphPass<PassData> : RenderGraphPass
where PassData : class, new()
{
internal PassData data;
internal RenderFunc<PassData> renderFunc;
public override void Execute(RenderGraphContext renderGraphContext)
{
GetExecuteDelegate<PassData>()(data, renderGraphContext);
}
public void Initialize(int passIndex, PassData passData, string passName, ProfilingSampler sampler)
{
Clear();
index = passIndex;
data = passData;
name = passName;
customSampler = sampler;
}
public override void Release(RenderGraphObjectPool pool)
{
Clear();
pool.Release(data);
data = null;
renderFunc = null;
// We need to do the release from here because we need the final type.
pool.Release(this);
}
public override bool HasRenderFunc()
{
return renderFunc != null;
}
}
}

View File

@@ -0,0 +1,10 @@
using UnityEngine.Rendering;
namespace UnityEngine.Experimental.Rendering.RenderGraphModule
{
internal enum RenderGraphProfileId
{
RenderGraphClear,
RenderGraphClearDebug,
}
}

View File

@@ -0,0 +1,216 @@
using System;
using System.Diagnostics;
namespace UnityEngine.Experimental.Rendering.RenderGraphModule
{
/// <summary>
/// Compute Buffer resource handle.
/// </summary>
[DebuggerDisplay("ComputeBuffer ({handle.index})")]
public struct ComputeBufferHandle
{
private static ComputeBufferHandle s_NullHandle = new ComputeBufferHandle();
/// <summary>
/// Returns a null compute buffer handle
/// </summary>
/// <returns>A null compute buffer handle.</returns>
public static ComputeBufferHandle nullHandle { get { return s_NullHandle; } }
internal ResourceHandle handle;
internal ComputeBufferHandle(int handle, bool shared = false) { this.handle = new ResourceHandle(handle, RenderGraphResourceType.ComputeBuffer, shared); }
/// <summary>
/// Cast to ComputeBuffer
/// </summary>
/// <param name="buffer">Input ComputeBufferHandle</param>
/// <returns>Resource as a Compute Buffer.</returns>
public static implicit operator ComputeBuffer(ComputeBufferHandle buffer) => buffer.IsValid() ? RenderGraphResourceRegistry.current.GetComputeBuffer(buffer) : null;
/// <summary>
/// Return true if the handle is valid.
/// </summary>
/// <returns>True if the handle is valid.</returns>
public bool IsValid() => handle.IsValid();
}
/// <summary>
/// Descriptor used to create compute buffer resources
/// </summary>
public struct ComputeBufferDesc
{
///<summary>Number of elements in the buffer..</summary>
public int count;
///<summary>Size of one element in the buffer. Has to match size of buffer type in the shader.</summary>
public int stride;
///<summary>Type of the buffer, default is ComputeBufferType.Default (structured buffer).</summary>
public ComputeBufferType type;
/// <summary>Compute Buffer name.</summary>
public string name;
/// <summary>
/// ComputeBufferDesc constructor.
/// </summary>
/// <param name="count">Number of elements in the buffer.</param>
/// <param name="stride">Size of one element in the buffer.</param>
public ComputeBufferDesc(int count, int stride)
: this()
{
this.count = count;
this.stride = stride;
type = ComputeBufferType.Default;
}
/// <summary>
/// ComputeBufferDesc constructor.
/// </summary>
/// <param name="count">Number of elements in the buffer.</param>
/// <param name="stride">Size of one element in the buffer.</param>
/// <param name="type">Type of the buffer.</param>
public ComputeBufferDesc(int count, int stride, ComputeBufferType type)
: this()
{
this.count = count;
this.stride = stride;
this.type = type;
}
/// <summary>
/// Hash function
/// </summary>
/// <returns>The texture descriptor hash.</returns>
public override int GetHashCode()
{
int hashCode = 17;
hashCode = hashCode * 23 + count;
hashCode = hashCode * 23 + stride;
hashCode = hashCode * 23 + (int)type;
return hashCode;
}
}
[DebuggerDisplay("ComputeBufferResource ({desc.name})")]
class ComputeBufferResource : RenderGraphResource<ComputeBufferDesc, ComputeBuffer>
{
public override string GetName()
{
if (imported)
return "ImportedComputeBuffer"; // No getter for compute buffer name.
else
return desc.name;
}
// NOTE:
// Next two functions should have been implemented in RenderGraphResource<DescType, ResType> but for some reason,
// when doing so, it's impossible to break in the Texture version of the virtual function (with VS2017 at least), making this completely un-debuggable.
// To work around this, we just copy/pasted the implementation in each final class...
public override void CreatePooledGraphicsResource()
{
Debug.Assert(m_Pool != null, "CreatePooledGraphicsResource should only be called for regular pooled resources");
int hashCode = desc.GetHashCode();
if (graphicsResource != null)
throw new InvalidOperationException(string.Format("Trying to create an already created resource ({0}). Resource was probably declared for writing more than once in the same pass.", GetName()));
var pool = m_Pool as ComputeBufferPool;
if (!pool.TryGetResource(hashCode, out graphicsResource))
{
CreateGraphicsResource();
}
cachedHash = hashCode;
pool.RegisterFrameAllocation(cachedHash, graphicsResource);
}
public override void ReleasePooledGraphicsResource(int frameIndex)
{
if (graphicsResource == null)
throw new InvalidOperationException($"Tried to release a resource ({GetName()}) that was never created. Check that there is at least one pass writing to it first.");
// Shared resources don't use the pool
var pool = m_Pool as ComputeBufferPool;
if (pool != null)
{
pool.ReleaseResource(cachedHash, graphicsResource, frameIndex);
pool.UnregisterFrameAllocation(cachedHash, graphicsResource);
}
Reset(null);
}
public override void CreateGraphicsResource(string name = "")
{
graphicsResource = new ComputeBuffer(desc.count, desc.stride, desc.type);
graphicsResource.name = name == "" ? $"RenderGraphComputeBuffer_{desc.count}_{desc.stride}_{desc.type}" : name;
}
public override void ReleaseGraphicsResource()
{
if (graphicsResource != null)
graphicsResource.Release();
base.ReleaseGraphicsResource();
}
public override void LogCreation(RenderGraphLogger logger)
{
logger.LogLine($"Created ComputeBuffer: {desc.name}");
}
public override void LogRelease(RenderGraphLogger logger)
{
logger.LogLine($"Released ComputeBuffer: {desc.name}");
}
}
class ComputeBufferPool : RenderGraphResourcePool<ComputeBuffer>
{
protected override void ReleaseInternalResource(ComputeBuffer res)
{
res.Release();
}
protected override string GetResourceName(ComputeBuffer res)
{
return "ComputeBufferNameNotAvailable"; // ComputeBuffer.name is a setter only :(
}
protected override long GetResourceSize(ComputeBuffer res)
{
return res.count * res.stride;
}
override protected string GetResourceTypeName()
{
return "ComputeBuffer";
}
// Another C# nicety.
// We need to re-implement the whole thing every time because:
// - obj.resource.Release is Type specific so it cannot be called on a generic (and there's no shared interface for resources like RTHandle, ComputeBuffers etc)
// - We can't use a virtual release function because it will capture this in the lambda for RemoveAll generating GCAlloc in the process.
override public void PurgeUnusedResources(int currentFrameIndex)
{
// Update the frame index for the lambda. Static because we don't want to capture.
s_CurrentFrameIndex = currentFrameIndex;
foreach (var kvp in m_ResourcePool)
{
var list = kvp.Value;
list.RemoveAll(obj =>
{
if (ShouldReleaseResource(obj.frameIndex, s_CurrentFrameIndex))
{
obj.resource.Release();
return true;
}
return false;
});
}
}
}
}

View File

@@ -0,0 +1,143 @@
using System.Collections.Generic;
using UnityEngine.Rendering;
namespace UnityEngine.Experimental.Rendering.RenderGraphModule
{
abstract class IRenderGraphResourcePool
{
public abstract void PurgeUnusedResources(int currentFrameIndex);
public abstract void Cleanup();
public abstract void CheckFrameAllocation(bool onException, int frameIndex);
public abstract void LogResources(RenderGraphLogger logger);
}
abstract class RenderGraphResourcePool<Type> : IRenderGraphResourcePool where Type : class
{
// Dictionary tracks resources by hash and stores resources with same hash in a List (list instead of a stack because we need to be able to remove stale allocations, potentially in the middle of the stack).
protected Dictionary<int, List<(Type resource, int frameIndex)>> m_ResourcePool = new Dictionary<int, List<(Type resource, int frameIndex)>>();
// This list allows us to determine if all resources were correctly released in the frame.
// This is useful to warn in case of user error or avoid leaks when a render graph execution errors occurs for example.
List<(int, Type)> m_FrameAllocatedResources = new List<(int, Type)>();
protected static int s_CurrentFrameIndex;
const int kStaleResourceLifetime = 10;
// Release the GPU resource itself
protected abstract void ReleaseInternalResource(Type res);
protected abstract string GetResourceName(Type res);
protected abstract long GetResourceSize(Type res);
protected abstract string GetResourceTypeName();
public void ReleaseResource(int hash, Type resource, int currentFrameIndex)
{
if (!m_ResourcePool.TryGetValue(hash, out var list))
{
list = new List<(Type resource, int frameIndex)>();
m_ResourcePool.Add(hash, list);
}
list.Add((resource, currentFrameIndex));
}
public bool TryGetResource(int hashCode, out Type resource)
{
if (m_ResourcePool.TryGetValue(hashCode, out var list) && list.Count > 0)
{
resource = list[list.Count - 1].resource;
list.RemoveAt(list.Count - 1); // O(1) since it's the last element.
return true;
}
resource = null;
return false;
}
public override void Cleanup()
{
foreach (var kvp in m_ResourcePool)
{
foreach (var res in kvp.Value)
{
ReleaseInternalResource(res.resource);
}
}
}
public void RegisterFrameAllocation(int hash, Type value)
{
if (hash != -1)
m_FrameAllocatedResources.Add((hash, value));
}
public void UnregisterFrameAllocation(int hash, Type value)
{
if (hash != -1)
m_FrameAllocatedResources.Remove((hash, value));
}
public override void CheckFrameAllocation(bool onException, int frameIndex)
{
// In case of exception we need to release all resources to the pool to avoid leaking.
// If it's not an exception then it's a user error so we need to log the problem.
if (m_FrameAllocatedResources.Count != 0)
{
string logMessage = "";
if (!onException)
logMessage = $"RenderGraph: Not all resources of type {GetResourceTypeName()} were released. This can be caused by a resources being allocated but never read by any pass.";
foreach (var value in m_FrameAllocatedResources)
{
if (!onException)
logMessage = $"{logMessage}\n\t{GetResourceName(value.Item2)}";
ReleaseResource(value.Item1, value.Item2, frameIndex);
}
Debug.LogWarning(logMessage);
}
// If an error occurred during execution, it's expected that textures are not all released so we clear the tracking list.
m_FrameAllocatedResources.Clear();
}
struct ResourceLogInfo
{
public string name;
public long size;
}
public override void LogResources(RenderGraphLogger logger)
{
List<ResourceLogInfo> allocationList = new List<ResourceLogInfo>();
foreach (var kvp in m_ResourcePool)
{
foreach (var res in kvp.Value)
{
allocationList.Add(new ResourceLogInfo { name = GetResourceName(res.resource), size = GetResourceSize(res.resource) });
}
}
logger.LogLine($"== {GetResourceTypeName()} Resources ==");
allocationList.Sort((a, b) => a.size < b.size ? 1 : -1);
int index = 0;
float total = 0;
foreach (var element in allocationList)
{
float size = element.size / (1024.0f * 1024.0f);
total += size;
logger.LogLine($"[{index++:D2}]\t[{size:0.00} MB]\t{element.name}");
}
logger.LogLine($"\nTotal Size [{total:0.00}]");
}
static protected bool ShouldReleaseResource(int lastUsedFrameIndex, int currentFrameIndex)
{
// We need to have a delay of a few frames before releasing resources for good.
// Indeed, when having multiple off-screen cameras, they are rendered in a separate SRP render call and thus with a different frame index than main camera
// This causes texture to be deallocated/reallocated every frame if the two cameras don't need the same buffers.
return (lastUsedFrameIndex + kStaleResourceLifetime) < currentFrameIndex;
}
}
}

View File

@@ -0,0 +1,598 @@
using System;
using System.Diagnostics;
using System.Collections.Generic;
using UnityEngine.Rendering;
namespace UnityEngine.Experimental.Rendering.RenderGraphModule
{
class RenderGraphResourceRegistry
{
const int kSharedResourceLifetime = 30;
static RenderGraphResourceRegistry m_CurrentRegistry;
internal static RenderGraphResourceRegistry current
{
get
{
// We assume that it's enough to only check in editor because we don't want to pay the cost at runtime.
#if UNITY_EDITOR
if (m_CurrentRegistry == null)
{
throw new InvalidOperationException("Current Render Graph Resource Registry is not set. You are probably trying to cast a Render Graph handle to a resource outside of a Render Graph Pass.");
}
#endif
return m_CurrentRegistry;
}
set
{
m_CurrentRegistry = value;
}
}
delegate void ResourceCallback(RenderGraphContext rgContext, IRenderGraphResource res);
class RenderGraphResourcesData
{
public DynamicArray<IRenderGraphResource> resourceArray = new DynamicArray<IRenderGraphResource>();
public int sharedResourcesCount;
public IRenderGraphResourcePool pool;
public ResourceCallback createResourceCallback;
public ResourceCallback releaseResourceCallback;
public void Clear(bool onException, int frameIndex)
{
resourceArray.Resize(sharedResourcesCount); // First N elements are reserved for shared persistent resources and are kept as is.
pool.CheckFrameAllocation(onException, frameIndex);
}
public void Cleanup()
{
// Cleanup all shared resources.
for (int i = 0; i < sharedResourcesCount; ++i)
{
var resource = resourceArray[i];
if (resource != null)
{
resource.ReleaseGraphicsResource();
}
}
// Then cleanup the pool
pool.Cleanup();
}
public void PurgeUnusedGraphicsResources(int frameIndex)
{
pool.PurgeUnusedResources(frameIndex);
}
public int AddNewRenderGraphResource<ResType>(out ResType outRes, bool pooledResource = true)
where ResType : IRenderGraphResource, new()
{
// In order to not create garbage, instead of using Add, we keep the content of the array while resizing and we just reset the existing ref (or create it if it's null).
int result = resourceArray.size;
resourceArray.Resize(resourceArray.size + 1, true);
if (resourceArray[result] == null)
resourceArray[result] = new ResType();
outRes = resourceArray[result] as ResType;
outRes.Reset(pooledResource ? pool : null);
return result;
}
}
RenderGraphResourcesData[] m_RenderGraphResources = new RenderGraphResourcesData[(int)RenderGraphResourceType.Count];
DynamicArray<RendererListResource> m_RendererListResources = new DynamicArray<RendererListResource>();
RenderGraphDebugParams m_RenderGraphDebug;
RenderGraphLogger m_Logger;
int m_CurrentFrameIndex;
int m_ExecutionCount;
RTHandle m_CurrentBackbuffer;
#region Internal Interface
internal RTHandle GetTexture(in TextureHandle handle)
{
if (!handle.IsValid())
return null;
return GetTextureResource(handle.handle).graphicsResource;
}
internal bool TextureNeedsFallback(in TextureHandle handle)
{
if (!handle.IsValid())
return false;
return GetTextureResource(handle.handle).NeedsFallBack();
}
internal RendererList GetRendererList(in RendererListHandle handle)
{
if (!handle.IsValid() || handle >= m_RendererListResources.size)
return RendererList.nullRendererList;
return m_RendererListResources[handle].rendererList;
}
internal ComputeBuffer GetComputeBuffer(in ComputeBufferHandle handle)
{
if (!handle.IsValid())
return null;
return GetComputeBufferResource(handle.handle).graphicsResource;
}
private RenderGraphResourceRegistry()
{
}
internal RenderGraphResourceRegistry(RenderGraphDebugParams renderGraphDebug, RenderGraphLogger logger)
{
m_RenderGraphDebug = renderGraphDebug;
m_Logger = logger;
for (int i = 0; i < (int)RenderGraphResourceType.Count; ++i)
{
m_RenderGraphResources[i] = new RenderGraphResourcesData();
}
m_RenderGraphResources[(int)RenderGraphResourceType.Texture].createResourceCallback = CreateTextureCallback;
m_RenderGraphResources[(int)RenderGraphResourceType.Texture].releaseResourceCallback = ReleaseTextureCallback;
m_RenderGraphResources[(int)RenderGraphResourceType.Texture].pool = new TexturePool();
m_RenderGraphResources[(int)RenderGraphResourceType.ComputeBuffer].pool = new ComputeBufferPool();
}
internal void BeginRenderGraph(int executionCount)
{
m_ExecutionCount = executionCount;
ResourceHandle.NewFrame(executionCount);
}
internal void BeginExecute(int currentFrameIndex)
{
m_CurrentFrameIndex = currentFrameIndex;
ManageSharedRenderGraphResources();
current = this;
}
internal void EndExecute()
{
current = null;
}
void CheckHandleValidity(in ResourceHandle res)
{
CheckHandleValidity(res.type, res.index);
}
void CheckHandleValidity(RenderGraphResourceType type, int index)
{
var resources = m_RenderGraphResources[(int)type].resourceArray;
if (index >= resources.size)
throw new ArgumentException($"Trying to access resource of type {type} with an invalid resource index {index}");
}
internal void IncrementWriteCount(in ResourceHandle res)
{
CheckHandleValidity(res);
m_RenderGraphResources[res.iType].resourceArray[res.index].IncrementWriteCount();
}
internal string GetRenderGraphResourceName(in ResourceHandle res)
{
CheckHandleValidity(res);
return m_RenderGraphResources[res.iType].resourceArray[res.index].GetName();
}
internal string GetRenderGraphResourceName(RenderGraphResourceType type, int index)
{
CheckHandleValidity(type, index);
return m_RenderGraphResources[(int)type].resourceArray[index].GetName();
}
internal bool IsRenderGraphResourceImported(in ResourceHandle res)
{
CheckHandleValidity(res);
return m_RenderGraphResources[res.iType].resourceArray[res.index].imported;
}
internal bool IsRenderGraphResourceShared(RenderGraphResourceType type, int index)
{
CheckHandleValidity(type, index);
return index < m_RenderGraphResources[(int)type].sharedResourcesCount;
}
internal bool IsGraphicsResourceCreated(in ResourceHandle res)
{
CheckHandleValidity(res);
return m_RenderGraphResources[res.iType].resourceArray[res.index].IsCreated();
}
internal bool IsRendererListCreated(in RendererListHandle res)
{
return m_RendererListResources[res].rendererList.isValid;
}
internal bool IsRenderGraphResourceImported(RenderGraphResourceType type, int index)
{
CheckHandleValidity(type, index);
return m_RenderGraphResources[(int)type].resourceArray[index].imported;
}
internal int GetRenderGraphResourceTransientIndex(in ResourceHandle res)
{
CheckHandleValidity(res);
return m_RenderGraphResources[res.iType].resourceArray[res.index].transientPassIndex;
}
// Texture Creation/Import APIs are internal because creation should only go through RenderGraph
internal TextureHandle ImportTexture(RTHandle rt)
{
int newHandle = m_RenderGraphResources[(int)RenderGraphResourceType.Texture].AddNewRenderGraphResource(out TextureResource texResource);
texResource.graphicsResource = rt;
texResource.imported = true;
return new TextureHandle(newHandle);
}
internal TextureHandle CreateSharedTexture(in TextureDesc desc, bool explicitRelease)
{
var textureResources = m_RenderGraphResources[(int)RenderGraphResourceType.Texture];
int sharedTextureCount = textureResources.sharedResourcesCount;
Debug.Assert(textureResources.resourceArray.size <= sharedTextureCount);
// try to find an available slot.
TextureResource texResource = null;
int textureIndex = -1;
for (int i = 0; i < sharedTextureCount; ++i)
{
var resource = textureResources.resourceArray[i];
if (resource.shared == false) // unused
{
texResource = (TextureResource)textureResources.resourceArray[i];
textureIndex = i;
break;
}
}
// if none is available, add a new resource.
if (texResource == null)
{
textureIndex = m_RenderGraphResources[(int)RenderGraphResourceType.Texture].AddNewRenderGraphResource(out texResource, pooledResource: false);
textureResources.sharedResourcesCount++;
}
texResource.imported = true;
texResource.shared = true;
texResource.sharedExplicitRelease = explicitRelease;
texResource.desc = desc;
return new TextureHandle(textureIndex, shared: true);
}
internal void ReleaseSharedTexture(TextureHandle texture)
{
var texResources = m_RenderGraphResources[(int)RenderGraphResourceType.Texture];
if (texture.handle >= texResources.sharedResourcesCount)
throw new InvalidOperationException("Tried to release a non shared texture.");
// Decrement if we release the last one.
if (texture.handle == (texResources.sharedResourcesCount - 1))
texResources.sharedResourcesCount--;
var texResource = GetTextureResource(texture.handle);
texResource.ReleaseGraphicsResource();
texResource.Reset(null);
}
internal TextureHandle ImportBackbuffer(RenderTargetIdentifier rt)
{
if (m_CurrentBackbuffer != null)
m_CurrentBackbuffer.SetTexture(rt);
else
m_CurrentBackbuffer = RTHandles.Alloc(rt, "Backbuffer");
int newHandle = m_RenderGraphResources[(int)RenderGraphResourceType.Texture].AddNewRenderGraphResource(out TextureResource texResource);
texResource.graphicsResource = m_CurrentBackbuffer;
texResource.imported = true;
return new TextureHandle(newHandle);
}
internal TextureHandle CreateTexture(in TextureDesc desc, int transientPassIndex = -1)
{
ValidateTextureDesc(desc);
int newHandle = m_RenderGraphResources[(int)RenderGraphResourceType.Texture].AddNewRenderGraphResource(out TextureResource texResource);
texResource.desc = desc;
texResource.transientPassIndex = transientPassIndex;
texResource.requestFallBack = desc.fallBackToBlackTexture;
return new TextureHandle(newHandle);
}
internal int GetTextureResourceCount()
{
return m_RenderGraphResources[(int)RenderGraphResourceType.Texture].resourceArray.size;
}
TextureResource GetTextureResource(in ResourceHandle handle)
{
return m_RenderGraphResources[(int)RenderGraphResourceType.Texture].resourceArray[handle] as TextureResource;
}
internal TextureDesc GetTextureResourceDesc(in ResourceHandle handle)
{
return (m_RenderGraphResources[(int)RenderGraphResourceType.Texture].resourceArray[handle] as TextureResource).desc;
}
internal RendererListHandle CreateRendererList(in RendererListDesc desc)
{
ValidateRendererListDesc(desc);
int newHandle = m_RendererListResources.Add(new RendererListResource(desc));
return new RendererListHandle(newHandle);
}
internal ComputeBufferHandle ImportComputeBuffer(ComputeBuffer computeBuffer)
{
int newHandle = m_RenderGraphResources[(int)RenderGraphResourceType.ComputeBuffer].AddNewRenderGraphResource(out ComputeBufferResource bufferResource);
bufferResource.graphicsResource = computeBuffer;
bufferResource.imported = true;
return new ComputeBufferHandle(newHandle);
}
internal ComputeBufferHandle CreateComputeBuffer(in ComputeBufferDesc desc, int transientPassIndex = -1)
{
ValidateComputeBufferDesc(desc);
int newHandle = m_RenderGraphResources[(int)RenderGraphResourceType.ComputeBuffer].AddNewRenderGraphResource(out ComputeBufferResource bufferResource);
bufferResource.desc = desc;
bufferResource.transientPassIndex = transientPassIndex;
return new ComputeBufferHandle(newHandle);
}
internal ComputeBufferDesc GetComputeBufferResourceDesc(in ResourceHandle handle)
{
return (m_RenderGraphResources[(int)RenderGraphResourceType.ComputeBuffer].resourceArray[handle] as ComputeBufferResource).desc;
}
internal int GetComputeBufferResourceCount()
{
return m_RenderGraphResources[(int)RenderGraphResourceType.ComputeBuffer].resourceArray.size;
}
ComputeBufferResource GetComputeBufferResource(in ResourceHandle handle)
{
return m_RenderGraphResources[(int)RenderGraphResourceType.ComputeBuffer].resourceArray[handle] as ComputeBufferResource;
}
internal void UpdateSharedResourceLastFrameIndex(int type, int index)
{
m_RenderGraphResources[type].resourceArray[index].sharedResourceLastFrameUsed = m_ExecutionCount;
}
void ManageSharedRenderGraphResources()
{
for (int type = 0; type < (int)RenderGraphResourceType.Count; ++type)
{
var resources = m_RenderGraphResources[type];
for (int i = 0; i < resources.sharedResourcesCount; ++i)
{
var resource = m_RenderGraphResources[type].resourceArray[i];
bool isCreated = resource.IsCreated();
// Alloc if needed.
if (resource.sharedResourceLastFrameUsed == m_ExecutionCount && !isCreated)
{
// Here we want the resource to have the name given by users because we know that it won't be reused at all.
// So no need for an automatic generic name.
resource.CreateGraphicsResource(resource.GetName());
}
// Release if not used anymore.
else if (isCreated && !resource.sharedExplicitRelease && ((resource.sharedResourceLastFrameUsed + kSharedResourceLifetime) < m_ExecutionCount))
{
resource.ReleaseGraphicsResource();
}
}
}
}
internal void CreatePooledResource(RenderGraphContext rgContext, int type, int index)
{
var resource = m_RenderGraphResources[type].resourceArray[index];
if (!resource.imported)
{
resource.CreatePooledGraphicsResource();
if (m_RenderGraphDebug.logFrameInformation)
resource.LogCreation(m_Logger);
m_RenderGraphResources[type].createResourceCallback?.Invoke(rgContext, resource);
}
}
void CreateTextureCallback(RenderGraphContext rgContext, IRenderGraphResource res)
{
var resource = res as TextureResource;
#if UNITY_2020_2_OR_NEWER
var fastMemDesc = resource.desc.fastMemoryDesc;
if (fastMemDesc.inFastMemory)
{
resource.graphicsResource.SwitchToFastMemory(rgContext.cmd, fastMemDesc.residencyFraction, fastMemDesc.flags);
}
#endif
if (resource.desc.clearBuffer || m_RenderGraphDebug.clearRenderTargetsAtCreation)
{
bool debugClear = m_RenderGraphDebug.clearRenderTargetsAtCreation && !resource.desc.clearBuffer;
using (new ProfilingScope(rgContext.cmd, ProfilingSampler.Get(debugClear ? RenderGraphProfileId.RenderGraphClearDebug : RenderGraphProfileId.RenderGraphClear)))
{
var clearFlag = resource.desc.depthBufferBits != DepthBits.None ? ClearFlag.Depth : ClearFlag.Color;
var clearColor = debugClear ? Color.magenta : resource.desc.clearColor;
CoreUtils.SetRenderTarget(rgContext.cmd, resource.graphicsResource, clearFlag, clearColor);
}
}
}
internal void ReleasePooledResource(RenderGraphContext rgContext, int type, int index)
{
var resource = m_RenderGraphResources[type].resourceArray[index];
if (!resource.imported)
{
m_RenderGraphResources[type].releaseResourceCallback?.Invoke(rgContext, resource);
if (m_RenderGraphDebug.logFrameInformation)
{
resource.LogRelease(m_Logger);
}
resource.ReleasePooledGraphicsResource(m_CurrentFrameIndex);
}
}
void ReleaseTextureCallback(RenderGraphContext rgContext, IRenderGraphResource res)
{
var resource = res as TextureResource;
if (m_RenderGraphDebug.clearRenderTargetsAtRelease)
{
using (new ProfilingScope(rgContext.cmd, ProfilingSampler.Get(RenderGraphProfileId.RenderGraphClearDebug)))
{
var clearFlag = resource.desc.depthBufferBits != DepthBits.None ? ClearFlag.Depth : ClearFlag.Color;
CoreUtils.SetRenderTarget(rgContext.cmd, resource.graphicsResource, clearFlag, Color.magenta);
}
}
}
void ValidateTextureDesc(in TextureDesc desc)
{
#if DEVELOPMENT_BUILD || UNITY_EDITOR
if (desc.colorFormat == GraphicsFormat.None && desc.depthBufferBits == DepthBits.None)
{
throw new ArgumentException("Texture was created with an invalid color format.");
}
if (desc.dimension == TextureDimension.None)
{
throw new ArgumentException("Texture was created with an invalid texture dimension.");
}
if (desc.slices == 0)
{
throw new ArgumentException("Texture was created with a slices parameter value of zero.");
}
if (desc.sizeMode == TextureSizeMode.Explicit)
{
if (desc.width == 0 || desc.height == 0)
throw new ArgumentException("Texture using Explicit size mode was create with either width or height at zero.");
if (desc.enableMSAA)
throw new ArgumentException("enableMSAA TextureDesc parameter is not supported for textures using Explicit size mode.");
}
if (desc.sizeMode == TextureSizeMode.Scale || desc.sizeMode == TextureSizeMode.Functor)
{
if (desc.msaaSamples != MSAASamples.None)
throw new ArgumentException("msaaSamples TextureDesc parameter is not supported for textures using Scale or Functor size mode.");
}
#endif
}
void ValidateRendererListDesc(in RendererListDesc desc)
{
#if DEVELOPMENT_BUILD || UNITY_EDITOR
if (desc.passName != ShaderTagId.none && desc.passNames != null
|| desc.passName == ShaderTagId.none && desc.passNames == null)
{
throw new ArgumentException("Renderer List creation descriptor must contain either a single passName or an array of passNames.");
}
if (desc.renderQueueRange.lowerBound == 0 && desc.renderQueueRange.upperBound == 0)
{
throw new ArgumentException("Renderer List creation descriptor must have a valid RenderQueueRange.");
}
if (desc.camera == null)
{
throw new ArgumentException("Renderer List creation descriptor must have a valid Camera.");
}
#endif
}
void ValidateComputeBufferDesc(in ComputeBufferDesc desc)
{
#if DEVELOPMENT_BUILD || UNITY_EDITOR
if (desc.stride % 4 != 0)
{
throw new ArgumentException("Invalid Compute Buffer creation descriptor: Compute Buffer stride must be at least 4.");
}
if (desc.count == 0)
{
throw new ArgumentException("Invalid Compute Buffer creation descriptor: Compute Buffer count must be non zero.");
}
#endif
}
internal void CreateRendererLists(List<RendererListHandle> rendererLists)
{
// For now we just create a simple structure
// but when the proper API is available in trunk we'll kick off renderer lists creation jobs here.
foreach (var rendererList in rendererLists)
{
ref var rendererListResource = ref m_RendererListResources[rendererList];
ref var desc = ref rendererListResource.desc;
RendererList newRendererList = RendererList.Create(desc);
rendererListResource.rendererList = newRendererList;
}
}
internal void Clear(bool onException)
{
LogResources();
for (int i = 0; i < (int)RenderGraphResourceType.Count; ++i)
m_RenderGraphResources[i].Clear(onException, m_CurrentFrameIndex);
m_RendererListResources.Clear();
}
internal void PurgeUnusedGraphicsResources()
{
// TODO RENDERGRAPH: Might not be ideal to purge stale resources every frame.
// In case users enable/disable features along a level it might provoke performance spikes when things are reallocated...
// Will be much better when we have actual resource aliasing and we can manage memory more efficiently.
for (int i = 0; i < (int)RenderGraphResourceType.Count; ++i)
m_RenderGraphResources[i].PurgeUnusedGraphicsResources(m_CurrentFrameIndex);
}
internal void Cleanup()
{
for (int i = 0; i < (int)RenderGraphResourceType.Count; ++i)
m_RenderGraphResources[i].Cleanup();
RTHandles.Release(m_CurrentBackbuffer);
}
void LogResources()
{
if (m_RenderGraphDebug.logResources)
{
m_Logger.LogLine("==== Allocated Resources ====\n");
for (int type = 0; type < (int)RenderGraphResourceType.Count; ++type)
{
m_RenderGraphResources[type].pool.LogResources(m_Logger);
m_Logger.LogLine("");
}
}
}
#endregion
}
}

View File

@@ -0,0 +1,47 @@
using System.Diagnostics;
using UnityEngine.Rendering;
namespace UnityEngine.Experimental.Rendering.RenderGraphModule
{
/// <summary>
/// Renderer List resource handle.
/// </summary>
[DebuggerDisplay("RendererList ({handle})")]
public struct RendererListHandle
{
bool m_IsValid;
internal int handle { get; private set; }
internal RendererListHandle(int handle) { this.handle = handle; m_IsValid = true; }
/// <summary>
/// Conversion to int.
/// </summary>
/// <param name="handle">Renderer List handle to convert.</param>
/// <returns>The integer representation of the handle.</returns>
public static implicit operator int(RendererListHandle handle) { return handle.handle; }
/// <summary>
/// Cast to RendererList
/// </summary>
/// <param name="rendererList">Input RendererListHandle.</param>
/// <returns>Resource as a RendererList.</returns>
public static implicit operator RendererList(RendererListHandle rendererList) => rendererList.IsValid() ? RenderGraphResourceRegistry.current.GetRendererList(rendererList) : RendererList.nullRendererList;
/// <summary>
/// Return true if the handle is valid.
/// </summary>
/// <returns>True if the handle is valid.</returns>
public bool IsValid() => m_IsValid;
}
internal struct RendererListResource
{
public RendererListDesc desc;
public RendererList rendererList;
internal RendererListResource(in RendererListDesc desc)
{
this.desc = desc;
this.rendererList = new RendererList(); // Invalid by default
}
}
}

View File

@@ -0,0 +1,426 @@
using System;
using System.Diagnostics;
using UnityEngine.Rendering;
namespace UnityEngine.Experimental.Rendering.RenderGraphModule
{
/// <summary>
/// Texture resource handle.
/// </summary>
[DebuggerDisplay("Texture ({handle.index})")]
public struct TextureHandle
{
private static TextureHandle s_NullHandle = new TextureHandle();
/// <summary>
/// Returns a null texture handle
/// </summary>
/// <returns>A null texture handle.</returns>
public static TextureHandle nullHandle { get { return s_NullHandle; } }
internal ResourceHandle handle;
internal TextureHandle(int handle, bool shared = false) { this.handle = new ResourceHandle(handle, RenderGraphResourceType.Texture, shared); }
/// <summary>
/// Cast to RenderTargetIdentifier
/// </summary>
/// <param name="texture">Input TextureHandle.</param>
/// <returns>Resource as a RenderTargetIdentifier.</returns>
public static implicit operator RenderTargetIdentifier(TextureHandle texture) => texture.IsValid() ? RenderGraphResourceRegistry.current.GetTexture(texture) : default(RenderTargetIdentifier);
/// <summary>
/// Cast to Texture
/// </summary>
/// <param name="texture">Input TextureHandle.</param>
/// <returns>Resource as a Texture.</returns>
public static implicit operator Texture(TextureHandle texture) => texture.IsValid() ? RenderGraphResourceRegistry.current.GetTexture(texture) : null;
/// <summary>
/// Cast to RenderTexture
/// </summary>
/// <param name="texture">Input TextureHandle.</param>
/// <returns>Resource as a RenderTexture.</returns>
public static implicit operator RenderTexture(TextureHandle texture) => texture.IsValid() ? RenderGraphResourceRegistry.current.GetTexture(texture) : null;
/// <summary>
/// Cast to RTHandle
/// </summary>
/// <param name="texture">Input TextureHandle.</param>
/// <returns>Resource as a RTHandle.</returns>
public static implicit operator RTHandle(TextureHandle texture) => texture.IsValid() ? RenderGraphResourceRegistry.current.GetTexture(texture) : null;
/// <summary>
/// Return true if the handle is valid.
/// </summary>
/// <returns>True if the handle is valid.</returns>
public bool IsValid() => handle.IsValid();
}
/// <summary>
/// The mode that determines the size of a Texture.
/// </summary>
public enum TextureSizeMode
{
///<summary>Explicit size.</summary>
Explicit,
///<summary>Size automatically scaled by a Vector.</summary>
Scale,
///<summary>Size automatically scaled by a Functor.</summary>
Functor
}
#if UNITY_2020_2_OR_NEWER
/// <summary>
/// Subset of the texture desc containing information for fast memory allocation (when platform supports it)
/// </summary>
public struct FastMemoryDesc
{
///<summary>Whether the texture will be in fast memory.</summary>
public bool inFastMemory;
///<summary>Flag to determine what parts of the render target is spilled if not fully resident in fast memory.</summary>
public FastMemoryFlags flags;
///<summary>How much of the render target is to be switched into fast memory (between 0 and 1).</summary>
public float residencyFraction;
}
#endif
/// <summary>
/// Descriptor used to create texture resources
/// </summary>
public struct TextureDesc
{
///<summary>Texture sizing mode.</summary>
public TextureSizeMode sizeMode;
///<summary>Texture width.</summary>
public int width;
///<summary>Texture height.</summary>
public int height;
///<summary>Number of texture slices..</summary>
public int slices;
///<summary>Texture scale.</summary>
public Vector2 scale;
///<summary>Texture scale function.</summary>
public ScaleFunc func;
///<summary>Depth buffer bit depth.</summary>
public DepthBits depthBufferBits;
///<summary>Color format.</summary>
public GraphicsFormat colorFormat;
///<summary>Filtering mode.</summary>
public FilterMode filterMode;
///<summary>Addressing mode.</summary>
public TextureWrapMode wrapMode;
///<summary>Texture dimension.</summary>
public TextureDimension dimension;
///<summary>Enable random UAV read/write on the texture.</summary>
public bool enableRandomWrite;
///<summary>Texture needs mip maps.</summary>
public bool useMipMap;
///<summary>Automatically generate mip maps.</summary>
public bool autoGenerateMips;
///<summary>Texture is a shadow map.</summary>
public bool isShadowMap;
///<summary>Anisotropic filtering level.</summary>
public int anisoLevel;
///<summary>Mip map bias.</summary>
public float mipMapBias;
///<summary>Textre is multisampled. Only supported for Scale and Functor size mode.</summary>
public bool enableMSAA;
///<summary>Number of MSAA samples. Only supported for Explicit size mode.</summary>
public MSAASamples msaaSamples;
///<summary>Bind texture multi sampled.</summary>
public bool bindTextureMS;
///<summary>Texture uses dynamic scaling.</summary>
public bool useDynamicScale;
///<summary>Memory less flag.</summary>
public RenderTextureMemoryless memoryless;
///<summary>Texture name.</summary>
public string name;
#if UNITY_2020_2_OR_NEWER
///<summary>Descriptor to determine how the texture will be in fast memory on platform that supports it.</summary>
public FastMemoryDesc fastMemoryDesc;
#endif
///<summary>Determines whether the texture will fallback to a black texture if it is read without ever writing to it.</summary>
public bool fallBackToBlackTexture;
// Initial state. Those should not be used in the hash
///<summary>Texture needs to be cleared on first use.</summary>
public bool clearBuffer;
///<summary>Clear color.</summary>
public Color clearColor;
void InitDefaultValues(bool dynamicResolution, bool xrReady)
{
useDynamicScale = dynamicResolution;
// XR Ready
if (xrReady)
{
slices = TextureXR.slices;
dimension = TextureXR.dimension;
}
else
{
slices = 1;
dimension = TextureDimension.Tex2D;
}
}
/// <summary>
/// TextureDesc constructor for a texture using explicit size
/// </summary>
/// <param name="width">Texture width</param>
/// <param name="height">Texture height</param>
/// <param name="dynamicResolution">Use dynamic resolution</param>
/// <param name="xrReady">Set this to true if the Texture is a render texture in an XR setting.</param>
public TextureDesc(int width, int height, bool dynamicResolution = false, bool xrReady = false)
: this()
{
// Size related init
sizeMode = TextureSizeMode.Explicit;
this.width = width;
this.height = height;
// Important default values not handled by zero construction in this()
msaaSamples = MSAASamples.None;
InitDefaultValues(dynamicResolution, xrReady);
}
/// <summary>
/// TextureDesc constructor for a texture using a fixed scaling
/// </summary>
/// <param name="scale">RTHandle scale used for this texture</param>
/// <param name="dynamicResolution">Use dynamic resolution</param>
/// <param name="xrReady">Set this to true if the Texture is a render texture in an XR setting.</param>
public TextureDesc(Vector2 scale, bool dynamicResolution = false, bool xrReady = false)
: this()
{
// Size related init
sizeMode = TextureSizeMode.Scale;
this.scale = scale;
// Important default values not handled by zero construction in this()
msaaSamples = MSAASamples.None;
dimension = TextureDimension.Tex2D;
InitDefaultValues(dynamicResolution, xrReady);
}
/// <summary>
/// TextureDesc constructor for a texture using a functor for scaling
/// </summary>
/// <param name="func">Function used to determnine the texture size</param>
/// <param name="dynamicResolution">Use dynamic resolution</param>
/// <param name="xrReady">Set this to true if the Texture is a render texture in an XR setting.</param>
public TextureDesc(ScaleFunc func, bool dynamicResolution = false, bool xrReady = false)
: this()
{
// Size related init
sizeMode = TextureSizeMode.Functor;
this.func = func;
// Important default values not handled by zero construction in this()
msaaSamples = MSAASamples.None;
dimension = TextureDimension.Tex2D;
InitDefaultValues(dynamicResolution, xrReady);
}
/// <summary>
/// Copy constructor
/// </summary>
/// <param name="input"></param>
public TextureDesc(TextureDesc input)
{
this = input;
}
/// <summary>
/// Hash function
/// </summary>
/// <returns>The texture descriptor hash.</returns>
public override int GetHashCode()
{
int hashCode = 17;
unchecked
{
switch (sizeMode)
{
case TextureSizeMode.Explicit:
hashCode = hashCode * 23 + width;
hashCode = hashCode * 23 + height;
hashCode = hashCode * 23 + (int)msaaSamples;
break;
case TextureSizeMode.Functor:
if (func != null)
hashCode = hashCode * 23 + func.GetHashCode();
hashCode = hashCode * 23 + (enableMSAA ? 1 : 0);
break;
case TextureSizeMode.Scale:
hashCode = hashCode * 23 + scale.x.GetHashCode();
hashCode = hashCode * 23 + scale.y.GetHashCode();
hashCode = hashCode * 23 + (enableMSAA ? 1 : 0);
break;
}
hashCode = hashCode * 23 + mipMapBias.GetHashCode();
hashCode = hashCode * 23 + slices;
hashCode = hashCode * 23 + (int)depthBufferBits;
hashCode = hashCode * 23 + (int)colorFormat;
hashCode = hashCode * 23 + (int)filterMode;
hashCode = hashCode * 23 + (int)wrapMode;
hashCode = hashCode * 23 + (int)dimension;
hashCode = hashCode * 23 + (int)memoryless;
hashCode = hashCode * 23 + anisoLevel;
hashCode = hashCode * 23 + (enableRandomWrite ? 1 : 0);
hashCode = hashCode * 23 + (useMipMap ? 1 : 0);
hashCode = hashCode * 23 + (autoGenerateMips ? 1 : 0);
hashCode = hashCode * 23 + (isShadowMap ? 1 : 0);
hashCode = hashCode * 23 + (bindTextureMS ? 1 : 0);
hashCode = hashCode * 23 + (useDynamicScale ? 1 : 0);
#if UNITY_2020_2_OR_NEWER
hashCode = hashCode * 23 + (fastMemoryDesc.inFastMemory ? 1 : 0);
#endif
}
return hashCode;
}
}
[DebuggerDisplay("TextureResource ({desc.name})")]
class TextureResource : RenderGraphResource<TextureDesc, RTHandle>
{
static int m_TextureCreationIndex;
public override string GetName()
{
if (imported && !shared)
return graphicsResource != null ? graphicsResource.name : "null resource";
else
return desc.name;
}
// NOTE:
// Next two functions should have been implemented in RenderGraphResource<DescType, ResType> but for some reason,
// when doing so, it's impossible to break in the Texture version of the virtual function (with VS2017 at least), making this completely un-debuggable.
// To work around this, we just copy/pasted the implementation in each final class...
public override void CreatePooledGraphicsResource()
{
Debug.Assert(m_Pool != null, "CreatePooledGraphicsResource should only be called for regular pooled resources");
int hashCode = desc.GetHashCode();
if (graphicsResource != null)
throw new InvalidOperationException(string.Format("Trying to create an already created resource ({0}). Resource was probably declared for writing more than once in the same pass.", GetName()));
var pool = m_Pool as TexturePool;
if (!pool.TryGetResource(hashCode, out graphicsResource))
{
CreateGraphicsResource();
}
cachedHash = hashCode;
pool.RegisterFrameAllocation(cachedHash, graphicsResource);
}
public override void ReleasePooledGraphicsResource(int frameIndex)
{
if (graphicsResource == null)
throw new InvalidOperationException($"Tried to release a resource ({GetName()}) that was never created. Check that there is at least one pass writing to it first.");
// Shared resources don't use the pool
var pool = m_Pool as TexturePool;
if (pool != null)
{
pool.ReleaseResource(cachedHash, graphicsResource, frameIndex);
pool.UnregisterFrameAllocation(cachedHash, graphicsResource);
}
Reset(null);
}
public override void CreateGraphicsResource(string name = "")
{
// Textures are going to be reused under different aliases along the frame so we can't provide a specific name upon creation.
// The name in the desc is going to be used for debugging purpose and render graph visualization.
if (name == "")
name = $"RenderGraphTexture_{m_TextureCreationIndex++}";
switch (desc.sizeMode)
{
case TextureSizeMode.Explicit:
graphicsResource = RTHandles.Alloc(desc.width, desc.height, desc.slices, desc.depthBufferBits, desc.colorFormat, desc.filterMode, desc.wrapMode, desc.dimension, desc.enableRandomWrite,
desc.useMipMap, desc.autoGenerateMips, desc.isShadowMap, desc.anisoLevel, desc.mipMapBias, desc.msaaSamples, desc.bindTextureMS, desc.useDynamicScale, desc.memoryless, name);
break;
case TextureSizeMode.Scale:
graphicsResource = RTHandles.Alloc(desc.scale, desc.slices, desc.depthBufferBits, desc.colorFormat, desc.filterMode, desc.wrapMode, desc.dimension, desc.enableRandomWrite,
desc.useMipMap, desc.autoGenerateMips, desc.isShadowMap, desc.anisoLevel, desc.mipMapBias, desc.enableMSAA, desc.bindTextureMS, desc.useDynamicScale, desc.memoryless, name);
break;
case TextureSizeMode.Functor:
graphicsResource = RTHandles.Alloc(desc.func, desc.slices, desc.depthBufferBits, desc.colorFormat, desc.filterMode, desc.wrapMode, desc.dimension, desc.enableRandomWrite,
desc.useMipMap, desc.autoGenerateMips, desc.isShadowMap, desc.anisoLevel, desc.mipMapBias, desc.enableMSAA, desc.bindTextureMS, desc.useDynamicScale, desc.memoryless, name);
break;
}
}
public override void ReleaseGraphicsResource()
{
if (graphicsResource != null)
graphicsResource.Release();
base.ReleaseGraphicsResource();
}
public override void LogCreation(RenderGraphLogger logger)
{
logger.LogLine($"Created Texture: {desc.name} (Cleared: {desc.clearBuffer})");
}
public override void LogRelease(RenderGraphLogger logger)
{
logger.LogLine($"Released Texture: {desc.name}");
}
}
class TexturePool : RenderGraphResourcePool<RTHandle>
{
protected override void ReleaseInternalResource(RTHandle res)
{
res.Release();
}
protected override string GetResourceName(RTHandle res)
{
return res.rt.name;
}
protected override long GetResourceSize(RTHandle res)
{
return Profiling.Profiler.GetRuntimeMemorySizeLong(res.rt);
}
override protected string GetResourceTypeName()
{
return "Texture";
}
// Another C# nicety.
// We need to re-implement the whole thing every time because:
// - obj.resource.Release is Type specific so it cannot be called on a generic (and there's no shared interface for resources like RTHandle, ComputeBuffers etc)
// - We can't use a virtual release function because it will capture 'this' in the lambda for RemoveAll generating GCAlloc in the process.
override public void PurgeUnusedResources(int currentFrameIndex)
{
// Update the frame index for the lambda. Static because we don't want to capture.
s_CurrentFrameIndex = currentFrameIndex;
foreach (var kvp in m_ResourcePool)
{
var list = kvp.Value;
list.RemoveAll(obj =>
{
if (ShouldReleaseResource(obj.frameIndex, s_CurrentFrameIndex))
{
obj.resource.Release();
return true;
}
return false;
});
}
}
}
}

View File

@@ -0,0 +1,147 @@
using System;
using System.Diagnostics;
using UnityEngine.Rendering;
namespace UnityEngine.Experimental.Rendering.RenderGraphModule
{
// RendererList is a different case so not represented here.
internal enum RenderGraphResourceType
{
Texture = 0,
ComputeBuffer,
Count
}
internal struct ResourceHandle
{
// Note on handles validity.
// PassData classes used during render graph passes are pooled and because of that, when users don't fill them completely,
// they can contain stale handles from a previous render graph execution that could still be considered valid if we only checked the index.
// In order to avoid using those, we incorporate the execution index in a 16 bits hash to make sure the handle is coming from the current execution.
// If not, it's considered invalid.
// We store this validity mask in the upper 16 bits of the index.
const uint kValidityMask = 0xFFFF0000;
const uint kIndexMask = 0xFFFF;
uint m_Value;
static uint s_CurrentValidBit = 1 << 16;
static uint s_SharedResourceValidBit = 0x7FFF << 16;
public int index { get { return (int)(m_Value & kIndexMask); } }
public RenderGraphResourceType type { get; private set; }
public int iType { get { return (int)type; } }
internal ResourceHandle(int value, RenderGraphResourceType type, bool shared)
{
Debug.Assert(value <= 0xFFFF);
m_Value = ((uint)value & kIndexMask) | (shared ? s_SharedResourceValidBit : s_CurrentValidBit);
this.type = type;
}
public static implicit operator int(ResourceHandle handle) => handle.index;
public bool IsValid()
{
var validity = m_Value & kValidityMask;
return validity != 0 && (validity == s_CurrentValidBit || validity == s_SharedResourceValidBit);
}
static public void NewFrame(int executionIndex)
{
// Scramble frame count to avoid collision when wrapping around.
s_CurrentValidBit = (uint)(((executionIndex >> 16) ^ (executionIndex & 0xffff) * 58546883) << 16);
// In case the current valid bit is 0, even though perfectly valid, 0 represents an invalid handle, hence we'll
// trigger an invalid state incorrectly. To account for this, we actually skip 0 as a viable s_CurrentValidBit and
// start from 1 again.
if (s_CurrentValidBit == 0)
{
s_CurrentValidBit = 1 << 16;
}
}
}
class IRenderGraphResource
{
public bool imported;
public bool shared;
public bool sharedExplicitRelease;
public bool requestFallBack;
public uint writeCount;
public int cachedHash;
public int transientPassIndex;
public int sharedResourceLastFrameUsed;
protected IRenderGraphResourcePool m_Pool;
public virtual void Reset(IRenderGraphResourcePool pool)
{
imported = false;
shared = false;
sharedExplicitRelease = false;
cachedHash = -1;
transientPassIndex = -1;
sharedResourceLastFrameUsed = -1;
requestFallBack = false;
writeCount = 0;
m_Pool = pool;
}
public virtual string GetName()
{
return "";
}
public virtual bool IsCreated()
{
return false;
}
public virtual void IncrementWriteCount()
{
writeCount++;
}
public virtual bool NeedsFallBack()
{
return requestFallBack && writeCount == 0;
}
public virtual void CreatePooledGraphicsResource() {}
public virtual void CreateGraphicsResource(string name = "") {}
public virtual void ReleasePooledGraphicsResource(int frameIndex) {}
public virtual void ReleaseGraphicsResource() {}
public virtual void LogCreation(RenderGraphLogger logger) {}
public virtual void LogRelease(RenderGraphLogger logger) {}
}
[DebuggerDisplay("Resource ({GetType().Name}:{GetName()})")]
abstract class RenderGraphResource<DescType, ResType>
: IRenderGraphResource
where DescType : struct
where ResType : class
{
public DescType desc;
public ResType graphicsResource;
protected RenderGraphResource()
{
}
public override void Reset(IRenderGraphResourcePool pool)
{
base.Reset(pool);
graphicsResource = null;
}
public override bool IsCreated()
{
return graphicsResource != null;
}
public override void ReleaseGraphicsResource()
{
graphicsResource = null;
}
}
}

Some files were not shown because too many files have changed in this diff Show More