다이얼로그 작업중
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 32a9038ef099d5a4d87f583d4b99d0b4
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,91 @@
|
||||
using System.Linq;
|
||||
using Unity.GraphToolkit.Editor;
|
||||
using UnityEditor.AssetImporters;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Unity.GraphToolkit.Samples.TextureMaker.Editor
|
||||
{
|
||||
/// <summary>
|
||||
/// TextureMakerImporter is a <see cref="ScriptedImporter"/> responsible for creating the texture and adding the
|
||||
/// texture to the asset, so the graph can be used directly as a texture in the scene.
|
||||
/// It contains all the Texture logic of the tool.
|
||||
/// </summary>
|
||||
[ScriptedImporter(1, TextureMakerGraph.AssetExtension)]
|
||||
internal class TextureMakerImporter : ScriptedImporter
|
||||
{
|
||||
/// <summary>
|
||||
/// The name of the texture identifier in the asset.
|
||||
/// </summary>
|
||||
private const string OutputTextureAssetIdName = "OutputTexture";
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the output Texture2D.
|
||||
/// </summary>
|
||||
private Texture2D OutputTexture { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Called when the asset is imported. This method processes the graph object and creates the texture.
|
||||
/// </summary>
|
||||
/// <param name="ctx">The asset import context.</param>
|
||||
public override void OnImportAsset(AssetImportContext ctx)
|
||||
{
|
||||
// The loaded graph may be null if the `Graph.LoadForImporter` method fails to load the asset from the
|
||||
// specified `ctx.assetPath`.
|
||||
// This can occur under the following circumstances:
|
||||
// - The asset path is incorrect, or the asset does not exist at the specified location.
|
||||
// - The asset located at the specified path is not of type `TextureMakerGraph`.
|
||||
// - The asset file itself is problematic, such as being corrupted or stored in an unsupported format.
|
||||
//
|
||||
// Best practice when dealing with serialization is to account for potential deserialization issues
|
||||
// by thoroughly validating and safeguarding against impaired or incomplete data.
|
||||
var graph = GraphDatabase.LoadGraphForImporter<TextureMakerGraph>(ctx.assetPath);
|
||||
if (graph == null)
|
||||
{
|
||||
Debug.LogError($"Failed to load texture maker graph object: {ctx.assetPath}");
|
||||
return;
|
||||
}
|
||||
|
||||
CompileGraph(graph);
|
||||
|
||||
// Adding the texture to the graph object and setting it to be the main asset.
|
||||
// This allows the generated texture to be used directly in the project and referenced in a material or a scene.
|
||||
if (OutputTexture != null)
|
||||
{
|
||||
ctx.AddObjectToAsset(OutputTextureAssetIdName, OutputTexture);
|
||||
ctx.SetMainObject(OutputTexture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compiles the provided texture maker graph and updates the output texture based on its evaluated nodes.
|
||||
/// </summary>
|
||||
/// <param name="graph">The texture maker graph to compile.</param>
|
||||
private void CompileGraph(TextureMakerGraph graph)
|
||||
{
|
||||
// Get the first CreateTexture Node
|
||||
// (Only using the first one is a tool design simplification we made for this sample)
|
||||
var createTextureNode = graph.GetNodes().OfType<CreateTextureNode>().FirstOrDefault();
|
||||
if (createTextureNode == null)
|
||||
{
|
||||
// No need to log an error here, as an error is already logged in the console (see the `OnGraphChanged` method
|
||||
// overriden in the TextureMakerGraph class).
|
||||
return;
|
||||
}
|
||||
|
||||
// Initialize the output texture to a default texture
|
||||
// This enables the graph object to use a default texture when a valid texture evaluator node is not yet available.
|
||||
OutputTexture = new Texture2D(CreateTextureNode.OutputWidth, CreateTextureNode.OutputHeight);
|
||||
OutputTexture.name = OutputTextureAssetIdName;
|
||||
|
||||
// Get the input port of the CreateTextureNode
|
||||
var inputPort = createTextureNode.GetInputPortByName(CreateTextureNode.TextureInputName);
|
||||
// Resolve the texture from the input port
|
||||
var texture = TextureMakerGraph.ResolvePortValue<Texture2D>(inputPort);
|
||||
if (texture != null)
|
||||
{
|
||||
OutputTexture = new Texture2D(texture.width, texture.height);
|
||||
OutputTexture.SetPixels(texture.GetPixels());
|
||||
} // else can happen when the input port is not connected and no embedded value is set
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e14cbdfe3bad40dc9e5cf791df184d43
|
||||
timeCreated: 1740674216
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 51ff29566e157cc42a82d110da3fa57f
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2145001d8b7b79d4d90138544650514d
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,38 @@
|
||||
using System;
|
||||
using JetBrains.Annotations;
|
||||
using Unity.GraphToolkit.Editor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Unity.GraphToolkit.Samples.TextureMaker.Editor
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the result node in a Texture Maker Graph.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The result node serves as the end node in the texture graph, where the final texture is evaluated.
|
||||
/// </remarks>
|
||||
[Serializable]
|
||||
[UsedImplicitly]
|
||||
internal class CreateTextureNode : Node
|
||||
{
|
||||
/// Using constants for port ids provides type safety and ensures consistent references across the implementation
|
||||
internal const string TextureInputName = "InTexture";
|
||||
/// <summary>
|
||||
/// The width of the output texture.
|
||||
/// </summary>
|
||||
public const int OutputWidth = 16;
|
||||
|
||||
/// <summary>
|
||||
/// The height of the output texture.
|
||||
/// </summary>
|
||||
public const int OutputHeight = 16;
|
||||
|
||||
/// <summary>
|
||||
/// Defines the input for the node.
|
||||
/// </summary>
|
||||
protected override void OnDefinePorts(IPortDefinitionContext context)
|
||||
{
|
||||
context.AddInputPort<Texture2D>(TextureInputName).Build();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5bbd857d07214e2b97256039bbd713f7
|
||||
timeCreated: 1740675943
|
||||
@@ -0,0 +1,22 @@
|
||||
using Unity.GraphToolkit.Editor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Unity.GraphToolkit.Samples.TextureMaker.Editor
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines an interface for evaluating Texture ports.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This interface is defined by nodes with the ability to output a Texture2D.
|
||||
/// Implementations of this interface should provide the logic to evaluate a given port model and return the resulting Texture.
|
||||
/// </remarks>
|
||||
internal interface ITextureEvaluatorNode
|
||||
{
|
||||
/// <summary>
|
||||
/// Evaluates the specified port and returns the resulting Texture.
|
||||
/// </summary>
|
||||
/// <param name="port">The port to evaluate.</param>
|
||||
/// <returns>The result of the evaluation.</returns>
|
||||
public Texture2D EvaluateTexturePort(IPort port);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 184980cc4753403d96db0011e12a78b2
|
||||
timeCreated: 1742204057
|
||||
@@ -0,0 +1,75 @@
|
||||
using System;
|
||||
using JetBrains.Annotations;
|
||||
using Unity.GraphToolkit.Editor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Unity.GraphToolkit.Samples.TextureMaker.Editor
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a node that combines two input textures and produces an output texture where pixel values are the mean
|
||||
/// of the two input values at the same position.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
[UsedImplicitly]
|
||||
internal class MeanColorNode : Node, ITextureEvaluatorNode
|
||||
{
|
||||
/// Using constants for port ids provides type safety and ensures consistent references across the implementation
|
||||
internal const string Texture1InputName = "InTexture1";
|
||||
internal const string Texture2InputName = "InTexture2";
|
||||
internal const string TextureOutputName = "OutTexture";
|
||||
|
||||
/// <summary>
|
||||
/// Defines the input and output port for the Mean node.
|
||||
/// This node takes two textures as input and outputs a Texture2D.
|
||||
/// </summary>
|
||||
protected override void OnDefinePorts(IPortDefinitionContext context)
|
||||
{
|
||||
context.AddInputPort<Texture2D>(Texture1InputName).Build();
|
||||
context.AddInputPort<Texture2D>(Texture2InputName).Build();
|
||||
context.AddOutputPort<Texture2D>(TextureOutputName).Build();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Evaluates the specified port and returns the result.
|
||||
/// </summary>
|
||||
/// <param name="port">The port model to evaluate.</param>
|
||||
/// <returns>The result of the evaluation.</returns>
|
||||
public Texture2D EvaluateTexturePort(IPort port)
|
||||
{
|
||||
// Only the output port can be evaluated for this node.
|
||||
if (port != GetOutputPortByName(TextureOutputName))
|
||||
return null;
|
||||
|
||||
// Get the textures from the ports or the embedded value
|
||||
Texture2D firstTexture = TextureMakerGraph.ResolvePortValue<Texture2D>(GetInputPortByName(Texture1InputName));
|
||||
Texture2D secondTexture = TextureMakerGraph.ResolvePortValue<Texture2D>(GetInputPortByName(Texture2InputName));
|
||||
|
||||
if (firstTexture != null && secondTexture != null)
|
||||
{
|
||||
// Using min dimensions to prevent out-of-bounds access; simplified for learning (production code would handle varying texture sizes)
|
||||
int width = Math.Min(firstTexture.width, secondTexture.width);
|
||||
int height = Math.Min(firstTexture.height, secondTexture.height);
|
||||
|
||||
Texture2D resultTexture = new Texture2D(width, height);
|
||||
|
||||
for (var j = 0; j < height; j++)
|
||||
{
|
||||
for (var i = 0; i < width; i++)
|
||||
{
|
||||
// Set the color of each pixel in the texture
|
||||
Color firstColor = firstTexture.GetPixel(i, j);
|
||||
Color secondColor = secondTexture.GetPixel(i, j);
|
||||
Color color = (firstColor + secondColor) / 2;
|
||||
resultTexture.SetPixel(i, j, color);
|
||||
}
|
||||
}
|
||||
return resultTexture;
|
||||
}
|
||||
|
||||
// If one of the input ports have no resolved value, return a default texture
|
||||
return new Texture2D(CreateTextureNode.OutputWidth, CreateTextureNode.OutputHeight);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2866fff3cefe46638f8fe6860cb86b5e
|
||||
timeCreated: 1742380071
|
||||
@@ -0,0 +1,57 @@
|
||||
using System;
|
||||
using JetBrains.Annotations;
|
||||
using Unity.GraphToolkit.Editor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Unity.GraphToolkit.Samples.TextureMaker.Editor
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a node that generates a uniform texture from a specified color.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
[UsedImplicitly]
|
||||
internal class UniformNode : Node, ITextureEvaluatorNode
|
||||
{
|
||||
/// Using constants for port ids provides type safety and ensures consistent references across the implementation
|
||||
internal const string ColorInputName = "InColor";
|
||||
internal const string TextureOutputName = "OutTexture";
|
||||
/// <summary>
|
||||
/// Defines the input and output port for the Uniform node.
|
||||
/// This nodes takes a color as input and outputs a Texture2D.
|
||||
/// </summary>
|
||||
protected override void OnDefinePorts(IPortDefinitionContext context)
|
||||
{
|
||||
context.AddInputPort<Color>(ColorInputName).Build();
|
||||
context.AddOutputPort<Texture2D>(TextureOutputName).Build();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Evaluates the specified port and returns the result.
|
||||
/// </summary>
|
||||
/// <param name="port">The port model to evaluate.</param>
|
||||
/// <returns>The result of the evaluation.</returns>
|
||||
public Texture2D EvaluateTexturePort(IPort port)
|
||||
{
|
||||
// Only the Texture output port can be evaluated for this node.
|
||||
if (port != GetOutputPortByName(TextureOutputName))
|
||||
return null;
|
||||
|
||||
// Gets the color port.
|
||||
var colorPort = GetInputPortByName(ColorInputName);
|
||||
|
||||
// Get the color from the connected port or the embedded value
|
||||
var color = TextureMakerGraph.ResolvePortValue<Color>(colorPort);
|
||||
|
||||
var texture = new Texture2D(CreateTextureNode.OutputWidth, CreateTextureNode.OutputHeight);
|
||||
// Set the color of each pixel in the texture
|
||||
for (var j = 0; j < CreateTextureNode.OutputHeight; j++)
|
||||
{
|
||||
for (var i = 0; i < CreateTextureNode.OutputWidth; i++)
|
||||
{
|
||||
texture.SetPixel(i, j, color);
|
||||
}
|
||||
}
|
||||
return texture;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5b8ad780581240939565c81dd3d40ce5
|
||||
timeCreated: 1740675943
|
||||
@@ -0,0 +1,120 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Unity.GraphToolkit.Editor;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Unity.GraphToolkit.Samples.TextureMaker.Editor
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the Texture Maker graph.
|
||||
/// </summary>
|
||||
/// <remarks> This is the entry point for the Texture Maker tool, it represents a Texture Maker graph.
|
||||
/// This class extends the Graph Toolkit <see cref="Graph"/> class, which provides a range of default behaviors,
|
||||
/// reducing the amount of code required to quickly implement a basic graph tool.
|
||||
/// It also provides customization by allowing you to override specific methods and can be decorated by attributes to
|
||||
/// tailor the tool's functionality.
|
||||
/// For example, in this class, we override the OnGraphChanged method to add our custom handling for graph errors and warnings.
|
||||
/// We also decorated it with the <see cref="GraphAttribute"/>, which specifies the asset extension.
|
||||
/// </remarks>
|
||||
[Graph(AssetExtension)]
|
||||
[Serializable]
|
||||
internal class TextureMakerGraph : Graph
|
||||
{
|
||||
/// <summary>
|
||||
/// The file extension for Texture Maker graph assets.
|
||||
/// </summary>
|
||||
/// <remarks> In Unity, the extension is used to select the right importer, so it must be unique.</remarks>
|
||||
internal const string AssetExtension = "texmkr";
|
||||
|
||||
/// <summary>
|
||||
/// Create a texture maker asset file.
|
||||
/// </summary>
|
||||
[MenuItem("Assets/Create/Graph Toolkit Samples/Texture Maker Graph", false)]
|
||||
static void CreateAssetFile()
|
||||
{
|
||||
GraphDatabase.PromptInProjectBrowserToCreateNewAsset<TextureMakerGraph>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks the graph for errors and warnings and adds them to the result object.
|
||||
/// </summary>
|
||||
/// <param name="infos">Object implementing <see cref="GraphLogger"/> interface and containing
|
||||
/// collected errors and warnings</param>
|
||||
/// <remarks>Errors and warnings are reported by adding them to the GraphLogger object,
|
||||
/// which is the default reporting mechanism for a Graph Toolkit tool. </remarks>
|
||||
private void CheckGraphErrors(GraphLogger infos)
|
||||
{
|
||||
// Get all CreateTextureNode instances in the graph
|
||||
var createTextureNodes = GetNodes().OfType<CreateTextureNode>().ToList();
|
||||
switch (createTextureNodes.Count)
|
||||
{
|
||||
case 0:
|
||||
// This is a tool design choice to log an error if no CreateTextureNode is found in the graph.
|
||||
// This will result in an error message being logged in the console.
|
||||
infos.LogError("Add a CreateTextureNode in your Texture graph.");
|
||||
break;
|
||||
case > 1:
|
||||
{
|
||||
foreach (var createTextureNode in createTextureNodes.Skip(1))
|
||||
{
|
||||
// This will result in a warning message being logged in the console and a warning marker being displayed on the node
|
||||
infos.LogWarning($"TextureMaker only supports one {nameof(CreateTextureNode)} by graph. " +
|
||||
"Only the first created one will be used.", createTextureNode);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when the graph changes.
|
||||
/// </summary>
|
||||
/// <param name="infos">The GraphLogger object to which errors and warnings are added.</param>
|
||||
/// <remarks>
|
||||
/// This method is triggered whenever the graph is modified. It calls `CheckGraphErrors` to validate the graph
|
||||
/// and report any issues.
|
||||
/// </remarks>
|
||||
public override void OnGraphChanged(GraphLogger infos)
|
||||
{
|
||||
CheckGraphErrors(infos);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resolves the value from the given port by determining the type of node connected.
|
||||
/// For constant, variable, and texture evaluator nodes, it extracts the corresponding value.
|
||||
/// If no connected source is available, it attempts to resolve an embedded value from the port.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The expected type of the port value.</typeparam>
|
||||
/// <param name="port">The port from which to resolve the value.</param>
|
||||
/// <returns>
|
||||
/// The resolved value of type <typeparamref name="T"/> if successful; otherwise, the default value of <typeparamref name="T"/>.
|
||||
/// </returns>
|
||||
public static T ResolvePortValue<T>(IPort port)
|
||||
{
|
||||
// Get the source port providing input to "port" (null if no connection exists)
|
||||
var sourcePort = port.firstConnectedPort;
|
||||
|
||||
switch (sourcePort?.GetNode())
|
||||
{
|
||||
case IConstantNode node:
|
||||
node.TryGetValue(out T constantValue);
|
||||
return constantValue;
|
||||
case IVariableNode node:
|
||||
node.variable.TryGetDefaultValue(out T variableValue);
|
||||
return variableValue;
|
||||
case ITextureEvaluatorNode textureEvaluatorNode:
|
||||
if (typeof(T).IsAssignableFrom(typeof(Texture2D)))
|
||||
{
|
||||
return (T)(object)textureEvaluatorNode.EvaluateTexturePort(sourcePort);
|
||||
}
|
||||
break;
|
||||
case null:
|
||||
// If no connection exists, try to get "port" 's embedded value (returns type default if unavailable)
|
||||
port.TryGetValue(out T embeddedValue);
|
||||
return embeddedValue;
|
||||
}
|
||||
return default;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ed470a2448996694b915fbb1456339f6
|
||||
timeCreated: 1647523327
|
||||
Reference in New Issue
Block a user