Keep local version of files

This commit is contained in:
2026-10-08 00:49:10 +05:30
parent 7fa0621ff8
commit 053665c690
7343 changed files with 5470578 additions and 5470528 deletions
@@ -1,14 +1,14 @@
{
"name": "CFXREditor",
"references": [],
"optionalUnityReferences": [],
"includePlatforms": [
"Editor"
],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": []
{
"name": "CFXREditor",
"references": [],
"optionalUnityReferences": [],
"includePlatforms": [
"Editor"
],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": []
}
@@ -1,14 +1,14 @@
fileFormatVersion: 2
guid: eb5cb7c323a395242a81960087292f3c
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 109565
packageName: Cartoon FX Remaster Free
packageVersion: R 1.5.0
assetPath: Assets/JMO Assets/Cartoon FX Remaster/CFXR Assets/Editor/CFXR Editor.asmdef
uploadId: 836238
fileFormatVersion: 2
guid: eb5cb7c323a395242a81960087292f3c
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 109565
packageName: Cartoon FX Remaster Free
packageVersion: R 1.5.0
assetPath: Assets/JMO Assets/Cartoon FX Remaster/CFXR Assets/Editor/CFXR Editor.asmdef
uploadId: 836238
@@ -1,275 +1,275 @@
//--------------------------------------------------------------------------------------------------------------------------------
// Cartoon FX
// (c) 2012-2025 Jean Moreno
//--------------------------------------------------------------------------------------------------------------------------------
using System.Collections.Generic;
using System.IO;
// Parse conditional expressions from CFXR_MaterialInspector to show/hide some parts of the UI easily
namespace CartoonFX
{
public static class ExpressionParser
{
public delegate bool EvaluateFunction(string content);
//--------------------------------------------------------------------------------------------------------------------------------
// Main Function to use
static public bool EvaluateExpression(string expression, EvaluateFunction evalFunction)
{
//Remove white spaces and double && ||
string cleanExpr = "";
for(int i = 0; i < expression.Length; i++)
{
switch(expression[i])
{
case ' ': break;
case '&': cleanExpr += expression[i]; i++; break;
case '|': cleanExpr += expression[i]; i++; break;
default: cleanExpr += expression[i]; break;
}
}
List<Token> tokens = new List<Token>();
StringReader reader = new StringReader(cleanExpr);
Token t = null;
do
{
t = new Token(reader);
tokens.Add(t);
} while(t.type != Token.TokenType.EXPR_END);
List<Token> polishNotation = Token.TransformToPolishNotation(tokens);
var enumerator = polishNotation.GetEnumerator();
enumerator.MoveNext();
Expression root = MakeExpression(ref enumerator, evalFunction);
return root.Evaluate();
}
//--------------------------------------------------------------------------------------------------------------------------------
// Expression Token
public class Token
{
static Dictionary<char, KeyValuePair<TokenType, string>> typesDict = new Dictionary<char, KeyValuePair<TokenType, string>>()
{
{'(', new KeyValuePair<TokenType, string>(TokenType.OPEN_PAREN, "(")},
{')', new KeyValuePair<TokenType, string>(TokenType.CLOSE_PAREN, ")")},
{'!', new KeyValuePair<TokenType, string>(TokenType.UNARY_OP, "NOT")},
{'&', new KeyValuePair<TokenType, string>(TokenType.BINARY_OP, "AND")},
{'|', new KeyValuePair<TokenType, string>(TokenType.BINARY_OP, "OR")}
};
public enum TokenType
{
OPEN_PAREN,
CLOSE_PAREN,
UNARY_OP,
BINARY_OP,
LITERAL,
EXPR_END
}
public TokenType type;
public string value;
public Token(StringReader s)
{
int c = s.Read();
if(c == -1)
{
type = TokenType.EXPR_END;
value = "";
return;
}
char ch = (char)c;
//Special case: solve bug where !COND_FALSE_1 && COND_FALSE_2 would return True
bool embeddedNot = (ch == '!' && s.Peek() != '(');
if(typesDict.ContainsKey(ch) && !embeddedNot)
{
type = typesDict[ch].Key;
value = typesDict[ch].Value;
}
else
{
string str = "";
str += ch;
while(s.Peek() != -1 && !typesDict.ContainsKey((char)s.Peek()))
{
str += (char)s.Read();
}
type = TokenType.LITERAL;
value = str;
}
}
static public List<Token> TransformToPolishNotation(List<Token> infixTokenList)
{
Queue<Token> outputQueue = new Queue<Token>();
Stack<Token> stack = new Stack<Token>();
int index = 0;
while(infixTokenList.Count > index)
{
Token t = infixTokenList[index];
switch(t.type)
{
case Token.TokenType.LITERAL:
outputQueue.Enqueue(t);
break;
case Token.TokenType.BINARY_OP:
case Token.TokenType.UNARY_OP:
case Token.TokenType.OPEN_PAREN:
stack.Push(t);
break;
case Token.TokenType.CLOSE_PAREN:
while(stack.Peek().type != Token.TokenType.OPEN_PAREN)
{
outputQueue.Enqueue(stack.Pop());
}
stack.Pop();
if(stack.Count > 0 && stack.Peek().type == Token.TokenType.UNARY_OP)
{
outputQueue.Enqueue(stack.Pop());
}
break;
default:
break;
}
index++;
}
while(stack.Count > 0)
{
outputQueue.Enqueue(stack.Pop());
}
var list = new List<Token>(outputQueue);
list.Reverse();
return list;
}
}
//--------------------------------------------------------------------------------------------------------------------------------
// Boolean Expression Classes
public abstract class Expression
{
public abstract bool Evaluate();
}
public class ExpressionLeaf : Expression
{
private string content;
private EvaluateFunction evalFunction;
public ExpressionLeaf(EvaluateFunction _evalFunction, string _content)
{
this.evalFunction = _evalFunction;
this.content = _content;
}
override public bool Evaluate()
{
//embedded not, see special case in Token declaration
if(content.StartsWith("!"))
{
return !this.evalFunction(content.Substring(1));
}
return this.evalFunction(content);
}
}
public class ExpressionAnd : Expression
{
private Expression left;
private Expression right;
public ExpressionAnd(Expression _left, Expression _right)
{
this.left = _left;
this.right = _right;
}
override public bool Evaluate()
{
return left.Evaluate() && right.Evaluate();
}
}
public class ExpressionOr : Expression
{
private Expression left;
private Expression right;
public ExpressionOr(Expression _left, Expression _right)
{
this.left = _left;
this.right = _right;
}
override public bool Evaluate()
{
return left.Evaluate() || right.Evaluate();
}
}
public class ExpressionNot : Expression
{
private Expression expr;
public ExpressionNot(Expression _expr)
{
this.expr = _expr;
}
override public bool Evaluate()
{
return !expr.Evaluate();
}
}
static public Expression MakeExpression(ref List<Token>.Enumerator polishNotationTokensEnumerator, EvaluateFunction _evalFunction)
{
if(polishNotationTokensEnumerator.Current.type == Token.TokenType.LITERAL)
{
Expression lit = new ExpressionLeaf(_evalFunction, polishNotationTokensEnumerator.Current.value);
polishNotationTokensEnumerator.MoveNext();
return lit;
}
else
{
if(polishNotationTokensEnumerator.Current.value == "NOT")
{
polishNotationTokensEnumerator.MoveNext();
Expression operand = MakeExpression(ref polishNotationTokensEnumerator, _evalFunction);
return new ExpressionNot(operand);
}
else if(polishNotationTokensEnumerator.Current.value == "AND")
{
polishNotationTokensEnumerator.MoveNext();
Expression left = MakeExpression(ref polishNotationTokensEnumerator, _evalFunction);
Expression right = MakeExpression(ref polishNotationTokensEnumerator, _evalFunction);
return new ExpressionAnd(left, right);
}
else if(polishNotationTokensEnumerator.Current.value == "OR")
{
polishNotationTokensEnumerator.MoveNext();
Expression left = MakeExpression(ref polishNotationTokensEnumerator, _evalFunction);
Expression right = MakeExpression(ref polishNotationTokensEnumerator, _evalFunction);
return new ExpressionOr(left, right);
}
}
return null;
}
}
//--------------------------------------------------------------------------------------------------------------------------------
// Cartoon FX
// (c) 2012-2025 Jean Moreno
//--------------------------------------------------------------------------------------------------------------------------------
using System.Collections.Generic;
using System.IO;
// Parse conditional expressions from CFXR_MaterialInspector to show/hide some parts of the UI easily
namespace CartoonFX
{
public static class ExpressionParser
{
public delegate bool EvaluateFunction(string content);
//--------------------------------------------------------------------------------------------------------------------------------
// Main Function to use
static public bool EvaluateExpression(string expression, EvaluateFunction evalFunction)
{
//Remove white spaces and double && ||
string cleanExpr = "";
for(int i = 0; i < expression.Length; i++)
{
switch(expression[i])
{
case ' ': break;
case '&': cleanExpr += expression[i]; i++; break;
case '|': cleanExpr += expression[i]; i++; break;
default: cleanExpr += expression[i]; break;
}
}
List<Token> tokens = new List<Token>();
StringReader reader = new StringReader(cleanExpr);
Token t = null;
do
{
t = new Token(reader);
tokens.Add(t);
} while(t.type != Token.TokenType.EXPR_END);
List<Token> polishNotation = Token.TransformToPolishNotation(tokens);
var enumerator = polishNotation.GetEnumerator();
enumerator.MoveNext();
Expression root = MakeExpression(ref enumerator, evalFunction);
return root.Evaluate();
}
//--------------------------------------------------------------------------------------------------------------------------------
// Expression Token
public class Token
{
static Dictionary<char, KeyValuePair<TokenType, string>> typesDict = new Dictionary<char, KeyValuePair<TokenType, string>>()
{
{'(', new KeyValuePair<TokenType, string>(TokenType.OPEN_PAREN, "(")},
{')', new KeyValuePair<TokenType, string>(TokenType.CLOSE_PAREN, ")")},
{'!', new KeyValuePair<TokenType, string>(TokenType.UNARY_OP, "NOT")},
{'&', new KeyValuePair<TokenType, string>(TokenType.BINARY_OP, "AND")},
{'|', new KeyValuePair<TokenType, string>(TokenType.BINARY_OP, "OR")}
};
public enum TokenType
{
OPEN_PAREN,
CLOSE_PAREN,
UNARY_OP,
BINARY_OP,
LITERAL,
EXPR_END
}
public TokenType type;
public string value;
public Token(StringReader s)
{
int c = s.Read();
if(c == -1)
{
type = TokenType.EXPR_END;
value = "";
return;
}
char ch = (char)c;
//Special case: solve bug where !COND_FALSE_1 && COND_FALSE_2 would return True
bool embeddedNot = (ch == '!' && s.Peek() != '(');
if(typesDict.ContainsKey(ch) && !embeddedNot)
{
type = typesDict[ch].Key;
value = typesDict[ch].Value;
}
else
{
string str = "";
str += ch;
while(s.Peek() != -1 && !typesDict.ContainsKey((char)s.Peek()))
{
str += (char)s.Read();
}
type = TokenType.LITERAL;
value = str;
}
}
static public List<Token> TransformToPolishNotation(List<Token> infixTokenList)
{
Queue<Token> outputQueue = new Queue<Token>();
Stack<Token> stack = new Stack<Token>();
int index = 0;
while(infixTokenList.Count > index)
{
Token t = infixTokenList[index];
switch(t.type)
{
case Token.TokenType.LITERAL:
outputQueue.Enqueue(t);
break;
case Token.TokenType.BINARY_OP:
case Token.TokenType.UNARY_OP:
case Token.TokenType.OPEN_PAREN:
stack.Push(t);
break;
case Token.TokenType.CLOSE_PAREN:
while(stack.Peek().type != Token.TokenType.OPEN_PAREN)
{
outputQueue.Enqueue(stack.Pop());
}
stack.Pop();
if(stack.Count > 0 && stack.Peek().type == Token.TokenType.UNARY_OP)
{
outputQueue.Enqueue(stack.Pop());
}
break;
default:
break;
}
index++;
}
while(stack.Count > 0)
{
outputQueue.Enqueue(stack.Pop());
}
var list = new List<Token>(outputQueue);
list.Reverse();
return list;
}
}
//--------------------------------------------------------------------------------------------------------------------------------
// Boolean Expression Classes
public abstract class Expression
{
public abstract bool Evaluate();
}
public class ExpressionLeaf : Expression
{
private string content;
private EvaluateFunction evalFunction;
public ExpressionLeaf(EvaluateFunction _evalFunction, string _content)
{
this.evalFunction = _evalFunction;
this.content = _content;
}
override public bool Evaluate()
{
//embedded not, see special case in Token declaration
if(content.StartsWith("!"))
{
return !this.evalFunction(content.Substring(1));
}
return this.evalFunction(content);
}
}
public class ExpressionAnd : Expression
{
private Expression left;
private Expression right;
public ExpressionAnd(Expression _left, Expression _right)
{
this.left = _left;
this.right = _right;
}
override public bool Evaluate()
{
return left.Evaluate() && right.Evaluate();
}
}
public class ExpressionOr : Expression
{
private Expression left;
private Expression right;
public ExpressionOr(Expression _left, Expression _right)
{
this.left = _left;
this.right = _right;
}
override public bool Evaluate()
{
return left.Evaluate() || right.Evaluate();
}
}
public class ExpressionNot : Expression
{
private Expression expr;
public ExpressionNot(Expression _expr)
{
this.expr = _expr;
}
override public bool Evaluate()
{
return !expr.Evaluate();
}
}
static public Expression MakeExpression(ref List<Token>.Enumerator polishNotationTokensEnumerator, EvaluateFunction _evalFunction)
{
if(polishNotationTokensEnumerator.Current.type == Token.TokenType.LITERAL)
{
Expression lit = new ExpressionLeaf(_evalFunction, polishNotationTokensEnumerator.Current.value);
polishNotationTokensEnumerator.MoveNext();
return lit;
}
else
{
if(polishNotationTokensEnumerator.Current.value == "NOT")
{
polishNotationTokensEnumerator.MoveNext();
Expression operand = MakeExpression(ref polishNotationTokensEnumerator, _evalFunction);
return new ExpressionNot(operand);
}
else if(polishNotationTokensEnumerator.Current.value == "AND")
{
polishNotationTokensEnumerator.MoveNext();
Expression left = MakeExpression(ref polishNotationTokensEnumerator, _evalFunction);
Expression right = MakeExpression(ref polishNotationTokensEnumerator, _evalFunction);
return new ExpressionAnd(left, right);
}
else if(polishNotationTokensEnumerator.Current.value == "OR")
{
polishNotationTokensEnumerator.MoveNext();
Expression left = MakeExpression(ref polishNotationTokensEnumerator, _evalFunction);
Expression right = MakeExpression(ref polishNotationTokensEnumerator, _evalFunction);
return new ExpressionOr(left, right);
}
}
return null;
}
}
}
@@ -1,17 +1,17 @@
fileFormatVersion: 2
guid: ce7d96d3a4d4f3b4681ab437a9710d60
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 109565
packageName: Cartoon FX Remaster Free
packageVersion: R 1.5.0
assetPath: Assets/JMO Assets/Cartoon FX Remaster/CFXR Assets/Editor/CFXR_ExpressionParser.cs
uploadId: 836238
fileFormatVersion: 2
guid: ce7d96d3a4d4f3b4681ab437a9710d60
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 109565
packageName: Cartoon FX Remaster Free
packageVersion: R 1.5.0
assetPath: Assets/JMO Assets/Cartoon FX Remaster/CFXR Assets/Editor/CFXR_ExpressionParser.cs
uploadId: 836238
File diff suppressed because it is too large Load Diff
@@ -1,19 +1,19 @@
fileFormatVersion: 2
guid: 4fb4c15e772a1cc4baecc7a958bf9cc7
timeCreated: 1486392341
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 109565
packageName: Cartoon FX Remaster Free
packageVersion: R 1.5.0
assetPath: Assets/JMO Assets/Cartoon FX Remaster/CFXR Assets/Editor/CFXR_MaterialInspector.cs
uploadId: 836238
fileFormatVersion: 2
guid: 4fb4c15e772a1cc4baecc7a958bf9cc7
timeCreated: 1486392341
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 109565
packageName: Cartoon FX Remaster Free
packageVersion: R 1.5.0
assetPath: Assets/JMO Assets/Cartoon FX Remaster/CFXR Assets/Editor/CFXR_MaterialInspector.cs
uploadId: 836238
@@ -1,423 +1,423 @@
// #define SHOW_EXPORT_BUTTON
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Reflection;
using UnityEditor;
using UnityEditor.Rendering;
using UnityEngine;
#if UNITY_2020_2_OR_NEWER
using UnityEditor.AssetImporters;
#else
using UnityEditor.Experimental.AssetImporters;
#endif
using UnityEngine.Rendering;
namespace CartoonFX
{
namespace CustomShaderImporter
{
static class Utils
{
public static bool IsUsingURP()
{
#if UNITY_2019_3_OR_NEWER
var renderPipeline = GraphicsSettings.currentRenderPipeline;
#else
var renderPipeline = GraphicsSettings.renderPipelineAsset;
#endif
return renderPipeline != null && renderPipeline.GetType().Name.Contains("Universal");
}
}
[ScriptedImporter(0, FILE_EXTENSION)]
public class CFXR_ShaderImporter : ScriptedImporter
{
public enum RenderPipeline
{
Auto,
ForceBuiltInRenderPipeline,
ForceUniversalRenderPipeline
}
public const string FILE_EXTENSION = "cfxrshader";
[Tooltip("In case of errors when building the project or with addressables, you can try forcing a specific render pipeline")]
public RenderPipeline renderPipelineDetection = RenderPipeline.Auto;
public string detectedRenderPipeline = "Built-In Render Pipeline";
public int strippedLinesCount = 0;
public string shaderSourceCode;
public string shaderName;
public string[] shaderErrors;
public ulong variantCount;
public ulong variantCountUsed;
enum ComparisonOperator
{
Equal,
Greater,
GreaterOrEqual,
Less,
LessOrEqual
}
#if UNITY_2022_2_OR_NEWER
const int URP_VERSION = 14;
#elif UNITY_2021_2_OR_NEWER
const int URP_VERSION = 12;
#elif UNITY_2021_1_OR_NEWER
const int URP_VERSION = 11;
#elif UNITY_2020_3_OR_NEWER
const int URP_VERSION = 10;
#else
const int URP_VERSION = 7;
#endif
static ComparisonOperator ParseComparisonOperator(string symbols)
{
switch (symbols)
{
case "==": return ComparisonOperator.Equal;
case "<=": return ComparisonOperator.LessOrEqual;
case "<": return ComparisonOperator.Less;
case ">": return ComparisonOperator.Greater;
case ">=": return ComparisonOperator.GreaterOrEqual;
default: throw new Exception("Invalid comparison operator: " + symbols);
}
}
static bool CompareWithOperator(int value1, int value2, ComparisonOperator comparisonOperator)
{
switch (comparisonOperator)
{
case ComparisonOperator.Equal: return value1 == value2;
case ComparisonOperator.Greater: return value1 > value2;
case ComparisonOperator.GreaterOrEqual: return value1 >= value2;
case ComparisonOperator.Less: return value1 < value2;
case ComparisonOperator.LessOrEqual: return value1 <= value2;
default: throw new Exception("Invalid comparison operator value: " + comparisonOperator);
}
}
bool StartsOrEndWithSpecialTag(string line)
{
bool startsWithTag = (line.Length > 4 && line[0] == '/' && line[1] == '*' && line[2] == '*' && line[3] == '*');
if (startsWithTag) return true;
int l = line.Length-1;
bool endsWithTag = (line.Length > 4 && line[l] == '/' && line[l-1] == '*' && line[l-2] == '*' && line[l-3] == '*');
return endsWithTag;
}
public override void OnImportAsset(AssetImportContext context)
{
bool isUsingURP;
switch (renderPipelineDetection)
{
default:
case RenderPipeline.Auto:
{
isUsingURP = Utils.IsUsingURP();
detectedRenderPipeline = isUsingURP ? "Universal Render Pipeline" : "Built-In Render Pipeline";
break;
}
case RenderPipeline.ForceBuiltInRenderPipeline:
{
detectedRenderPipeline = "Built-In Render Pipeline";
isUsingURP = false;
break;
}
case RenderPipeline.ForceUniversalRenderPipeline:
{
detectedRenderPipeline = "Universal Render Pipeline";
isUsingURP = true;
break;
}
}
StringWriter shaderSource = new StringWriter();
string[] sourceLines = File.ReadAllLines(context.assetPath);
Stack<bool> excludeCurrentLines = new Stack<bool>();
strippedLinesCount = 0;
for (int i = 0; i < sourceLines.Length; i++)
{
bool excludeThisLine = excludeCurrentLines.Count > 0 && excludeCurrentLines.Peek();
string line = sourceLines[i];
if (StartsOrEndWithSpecialTag(line))
{
if (line.StartsWith("/*** BIRP ***/"))
{
excludeCurrentLines.Push(excludeThisLine || isUsingURP);
}
else if (line.StartsWith("/*** URP ***/"))
{
excludeCurrentLines.Push(excludeThisLine || !isUsingURP);
}
else if (line.StartsWith("/*** URP_VERSION "))
{
string subline = line.Substring("/*** URP_VERSION ".Length);
int spaceIndex = subline.IndexOf(' ');
string version = subline.Substring(spaceIndex, subline.LastIndexOf(' ') - spaceIndex);
string op = subline.Substring(0, spaceIndex);
var compOp = ParseComparisonOperator(op);
int compVersion = int.Parse(version);
bool isCorrectURP = CompareWithOperator(URP_VERSION, compVersion, compOp);
excludeCurrentLines.Push(excludeThisLine || !isCorrectURP);
}
else if (excludeThisLine && line.StartsWith("/*** END"))
{
excludeCurrentLines.Pop();
}
else if (!excludeThisLine && line.StartsWith("/*** #define URP_VERSION ***/"))
{
shaderSource.WriteLine("\t\t\t#define URP_VERSION " + URP_VERSION);
}
}
else
{
if (excludeThisLine)
{
strippedLinesCount++;
continue;
}
shaderSource.WriteLine(line);
}
}
// Get source code and extract name
shaderSourceCode = shaderSource.ToString();
int idx = shaderSourceCode.IndexOf("Shader \"", StringComparison.InvariantCulture) + 8;
int idx2 = shaderSourceCode.IndexOf('"', idx);
shaderName = shaderSourceCode.Substring(idx, idx2 - idx);
shaderErrors = null;
Shader shader = ShaderUtil.CreateShaderAsset(context, shaderSourceCode, true);
if (ShaderUtil.ShaderHasError(shader))
{
string[] shaderSourceLines = shaderSourceCode.Split(new [] {'\n'}, StringSplitOptions.None);
var errors = ShaderUtil.GetShaderMessages(shader);
shaderErrors = Array.ConvertAll(errors, err => $"{err.message} (line {err.line})");
foreach (ShaderMessage error in errors)
{
string message = error.line <= 0 ?
string.Format("Shader Error in '{0}' (in file '{2}')\nError: {1}\n", shaderName, error.message, error.file) :
string.Format("Shader Error in '{0}' (line {2} in file '{3}')\nError: {1}\nLine: {4}\n", shaderName, error.message, error.line, error.file, shaderSourceLines[error.line-1]);
if (error.severity == ShaderCompilerMessageSeverity.Warning)
{
Debug.LogWarning(message);
}
else
{
Debug.LogError(message);
}
}
}
else
{
ShaderUtil.ClearShaderMessages(shader);
}
context.AddObjectToAsset("MainAsset", shader);
context.SetMainObject(shader);
// Try to count variant using reflection:
// internal static extern ulong GetVariantCount(Shader s, bool usedBySceneOnly);
variantCount = 0;
variantCountUsed = 0;
MethodInfo getVariantCountReflection = typeof(ShaderUtil).GetMethod("GetVariantCount", BindingFlags.Static | BindingFlags.NonPublic);
if (getVariantCountReflection != null)
{
try
{
object result = getVariantCountReflection.Invoke(null, new object[] {shader, false});
variantCount = (ulong)result;
result = getVariantCountReflection.Invoke(null, new object[] {shader, true});
variantCountUsed = (ulong)result;
}
catch
{
// ignored
}
}
}
}
namespace Inspector
{
[CustomEditor(typeof(CFXR_ShaderImporter)), CanEditMultipleObjects]
public class TCP2ShaderImporter_Editor : Editor
{
CFXR_ShaderImporter Importer => (CFXR_ShaderImporter) this.target;
// From: UnityEditor.ShaderInspectorPlatformsPopup
static string FormatCount(ulong count)
{
bool flag = count > 1000000000uL;
string result;
if (flag)
{
result = (count / 1000000000.0).ToString("f2", CultureInfo.InvariantCulture.NumberFormat) + "B";
}
else
{
bool flag2 = count > 1000000uL;
if (flag2)
{
result = (count / 1000000.0).ToString("f2", CultureInfo.InvariantCulture.NumberFormat) + "M";
}
else
{
bool flag3 = count > 1000uL;
if (flag3)
{
result = (count / 1000.0).ToString("f2", CultureInfo.InvariantCulture.NumberFormat) + "k";
}
else
{
result = count.ToString();
}
}
}
return result;
}
static GUIStyle _HelpBoxRichTextStyle;
static GUIStyle HelpBoxRichTextStyle
{
get
{
if (_HelpBoxRichTextStyle == null)
{
_HelpBoxRichTextStyle = new GUIStyle("HelpBox");
_HelpBoxRichTextStyle.richText = true;
_HelpBoxRichTextStyle.margin = new RectOffset(4, 4, 0, 0);
_HelpBoxRichTextStyle.padding = new RectOffset(4, 4, 4, 4);
}
return _HelpBoxRichTextStyle;
}
}
public override void OnInspectorGUI()
{
bool multipleValues = serializedObject.isEditingMultipleObjects;
CFXR_ShaderImporter.RenderPipeline detection = ((CFXR_ShaderImporter)target).renderPipelineDetection;
bool isUsingURP = Utils.IsUsingURP();
serializedObject.Update();
GUILayout.Label(Importer.shaderName);
string variantsText = "";
if (Importer.variantCount > 0 && Importer.variantCountUsed > 0)
{
string variantsCount = multipleValues ? "-" : FormatCount(Importer.variantCount);
string variantsCountUsed = multipleValues ? "-" : FormatCount(Importer.variantCountUsed);
variantsText = $"\nVariants (currently used): <b>{variantsCountUsed}</b>\nVariants (including unused): <b>{variantsCount}</b>";
}
string strippedLinesCount = multipleValues ? "-" : Importer.strippedLinesCount.ToString();
string renderPipeline = Importer.detectedRenderPipeline;
if (targets is { Length: > 1 })
{
foreach (CFXR_ShaderImporter importer in targets)
{
if (importer.detectedRenderPipeline != renderPipeline)
{
renderPipeline = "-";
break;
}
}
}
GUILayout.Label($"{(detection == CFXR_ShaderImporter.RenderPipeline.Auto ? "Detected" : "Forced")} render pipeline: <b>{renderPipeline}</b>\nStripped lines: <b>{strippedLinesCount}</b>{variantsText}", HelpBoxRichTextStyle);
if (Importer.shaderErrors != null && Importer.shaderErrors.Length > 0)
{
GUILayout.Space(4);
var color = GUI.color;
GUI.color = new Color32(0xFF, 0x80, 0x80, 0xFF);
GUILayout.Label($"<b>Errors:</b>\n{string.Join("\n", Importer.shaderErrors)}", HelpBoxRichTextStyle);
GUI.color = color;
}
bool shouldReimportShader = false;
bool compiledForURP = Importer.detectedRenderPipeline.Contains("Universal");
if (detection == CFXR_ShaderImporter.RenderPipeline.Auto
&& ((isUsingURP && !compiledForURP) || (!isUsingURP && compiledForURP)))
{
GUILayout.Space(4);
Color guiColor = GUI.color;
GUI.color *= Color.yellow;
EditorGUILayout.HelpBox("The detected render pipeline doesn't match the pipeline this shader was compiled for!\nPlease reimport the shaders for them to work in the current render pipeline.", MessageType.Warning);
if (GUILayout.Button("Reimport Shader"))
{
shouldReimportShader = true;
}
GUI.color = guiColor;
}
GUILayout.Space(4);
EditorGUI.BeginChangeCheck();
EditorGUILayout.PropertyField(serializedObject.FindProperty(nameof(CFXR_ShaderImporter.renderPipelineDetection)));
if (EditorGUI.EndChangeCheck())
{
shouldReimportShader = true;
}
if (GUILayout.Button("View Source", GUILayout.ExpandWidth(false)))
{
string path = Application.temporaryCachePath + "/" + Importer.shaderName.Replace("/", "-") + "_Source.shader";
if (File.Exists(path))
{
File.SetAttributes(path, FileAttributes.Normal);
}
File.WriteAllText(path, Importer.shaderSourceCode);
File.SetAttributes(path, FileAttributes.ReadOnly);
UnityEditorInternal.InternalEditorUtility.OpenFileAtLineExternal(path, 0);
}
#if SHOW_EXPORT_BUTTON
GUILayout.Space(8);
EditorGUI.BeginDisabledGroup(string.IsNullOrEmpty(importer.shaderSourceCode));
{
if (GUILayout.Button("Export .shader file", GUILayout.ExpandWidth(false)))
{
string savePath = EditorUtility.SaveFilePanel("Export CFXR shader", Application.dataPath, "CFXR Shader","shader");
if (!string.IsNullOrEmpty(savePath))
{
File.WriteAllText(savePath, importer.shaderSourceCode);
}
}
}
EditorGUI.EndDisabledGroup();
#endif
serializedObject.ApplyModifiedProperties();
if (shouldReimportShader)
{
ReimportShader();
}
}
void ReimportShader()
{
foreach (UnityEngine.Object t in targets)
{
string path = AssetDatabase.GetAssetPath(t);
AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceSynchronousImport);
}
}
}
}
}
// #define SHOW_EXPORT_BUTTON
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Reflection;
using UnityEditor;
using UnityEditor.Rendering;
using UnityEngine;
#if UNITY_2020_2_OR_NEWER
using UnityEditor.AssetImporters;
#else
using UnityEditor.Experimental.AssetImporters;
#endif
using UnityEngine.Rendering;
namespace CartoonFX
{
namespace CustomShaderImporter
{
static class Utils
{
public static bool IsUsingURP()
{
#if UNITY_2019_3_OR_NEWER
var renderPipeline = GraphicsSettings.currentRenderPipeline;
#else
var renderPipeline = GraphicsSettings.renderPipelineAsset;
#endif
return renderPipeline != null && renderPipeline.GetType().Name.Contains("Universal");
}
}
[ScriptedImporter(0, FILE_EXTENSION)]
public class CFXR_ShaderImporter : ScriptedImporter
{
public enum RenderPipeline
{
Auto,
ForceBuiltInRenderPipeline,
ForceUniversalRenderPipeline
}
public const string FILE_EXTENSION = "cfxrshader";
[Tooltip("In case of errors when building the project or with addressables, you can try forcing a specific render pipeline")]
public RenderPipeline renderPipelineDetection = RenderPipeline.Auto;
public string detectedRenderPipeline = "Built-In Render Pipeline";
public int strippedLinesCount = 0;
public string shaderSourceCode;
public string shaderName;
public string[] shaderErrors;
public ulong variantCount;
public ulong variantCountUsed;
enum ComparisonOperator
{
Equal,
Greater,
GreaterOrEqual,
Less,
LessOrEqual
}
#if UNITY_2022_2_OR_NEWER
const int URP_VERSION = 14;
#elif UNITY_2021_2_OR_NEWER
const int URP_VERSION = 12;
#elif UNITY_2021_1_OR_NEWER
const int URP_VERSION = 11;
#elif UNITY_2020_3_OR_NEWER
const int URP_VERSION = 10;
#else
const int URP_VERSION = 7;
#endif
static ComparisonOperator ParseComparisonOperator(string symbols)
{
switch (symbols)
{
case "==": return ComparisonOperator.Equal;
case "<=": return ComparisonOperator.LessOrEqual;
case "<": return ComparisonOperator.Less;
case ">": return ComparisonOperator.Greater;
case ">=": return ComparisonOperator.GreaterOrEqual;
default: throw new Exception("Invalid comparison operator: " + symbols);
}
}
static bool CompareWithOperator(int value1, int value2, ComparisonOperator comparisonOperator)
{
switch (comparisonOperator)
{
case ComparisonOperator.Equal: return value1 == value2;
case ComparisonOperator.Greater: return value1 > value2;
case ComparisonOperator.GreaterOrEqual: return value1 >= value2;
case ComparisonOperator.Less: return value1 < value2;
case ComparisonOperator.LessOrEqual: return value1 <= value2;
default: throw new Exception("Invalid comparison operator value: " + comparisonOperator);
}
}
bool StartsOrEndWithSpecialTag(string line)
{
bool startsWithTag = (line.Length > 4 && line[0] == '/' && line[1] == '*' && line[2] == '*' && line[3] == '*');
if (startsWithTag) return true;
int l = line.Length-1;
bool endsWithTag = (line.Length > 4 && line[l] == '/' && line[l-1] == '*' && line[l-2] == '*' && line[l-3] == '*');
return endsWithTag;
}
public override void OnImportAsset(AssetImportContext context)
{
bool isUsingURP;
switch (renderPipelineDetection)
{
default:
case RenderPipeline.Auto:
{
isUsingURP = Utils.IsUsingURP();
detectedRenderPipeline = isUsingURP ? "Universal Render Pipeline" : "Built-In Render Pipeline";
break;
}
case RenderPipeline.ForceBuiltInRenderPipeline:
{
detectedRenderPipeline = "Built-In Render Pipeline";
isUsingURP = false;
break;
}
case RenderPipeline.ForceUniversalRenderPipeline:
{
detectedRenderPipeline = "Universal Render Pipeline";
isUsingURP = true;
break;
}
}
StringWriter shaderSource = new StringWriter();
string[] sourceLines = File.ReadAllLines(context.assetPath);
Stack<bool> excludeCurrentLines = new Stack<bool>();
strippedLinesCount = 0;
for (int i = 0; i < sourceLines.Length; i++)
{
bool excludeThisLine = excludeCurrentLines.Count > 0 && excludeCurrentLines.Peek();
string line = sourceLines[i];
if (StartsOrEndWithSpecialTag(line))
{
if (line.StartsWith("/*** BIRP ***/"))
{
excludeCurrentLines.Push(excludeThisLine || isUsingURP);
}
else if (line.StartsWith("/*** URP ***/"))
{
excludeCurrentLines.Push(excludeThisLine || !isUsingURP);
}
else if (line.StartsWith("/*** URP_VERSION "))
{
string subline = line.Substring("/*** URP_VERSION ".Length);
int spaceIndex = subline.IndexOf(' ');
string version = subline.Substring(spaceIndex, subline.LastIndexOf(' ') - spaceIndex);
string op = subline.Substring(0, spaceIndex);
var compOp = ParseComparisonOperator(op);
int compVersion = int.Parse(version);
bool isCorrectURP = CompareWithOperator(URP_VERSION, compVersion, compOp);
excludeCurrentLines.Push(excludeThisLine || !isCorrectURP);
}
else if (excludeThisLine && line.StartsWith("/*** END"))
{
excludeCurrentLines.Pop();
}
else if (!excludeThisLine && line.StartsWith("/*** #define URP_VERSION ***/"))
{
shaderSource.WriteLine("\t\t\t#define URP_VERSION " + URP_VERSION);
}
}
else
{
if (excludeThisLine)
{
strippedLinesCount++;
continue;
}
shaderSource.WriteLine(line);
}
}
// Get source code and extract name
shaderSourceCode = shaderSource.ToString();
int idx = shaderSourceCode.IndexOf("Shader \"", StringComparison.InvariantCulture) + 8;
int idx2 = shaderSourceCode.IndexOf('"', idx);
shaderName = shaderSourceCode.Substring(idx, idx2 - idx);
shaderErrors = null;
Shader shader = ShaderUtil.CreateShaderAsset(context, shaderSourceCode, true);
if (ShaderUtil.ShaderHasError(shader))
{
string[] shaderSourceLines = shaderSourceCode.Split(new [] {'\n'}, StringSplitOptions.None);
var errors = ShaderUtil.GetShaderMessages(shader);
shaderErrors = Array.ConvertAll(errors, err => $"{err.message} (line {err.line})");
foreach (ShaderMessage error in errors)
{
string message = error.line <= 0 ?
string.Format("Shader Error in '{0}' (in file '{2}')\nError: {1}\n", shaderName, error.message, error.file) :
string.Format("Shader Error in '{0}' (line {2} in file '{3}')\nError: {1}\nLine: {4}\n", shaderName, error.message, error.line, error.file, shaderSourceLines[error.line-1]);
if (error.severity == ShaderCompilerMessageSeverity.Warning)
{
Debug.LogWarning(message);
}
else
{
Debug.LogError(message);
}
}
}
else
{
ShaderUtil.ClearShaderMessages(shader);
}
context.AddObjectToAsset("MainAsset", shader);
context.SetMainObject(shader);
// Try to count variant using reflection:
// internal static extern ulong GetVariantCount(Shader s, bool usedBySceneOnly);
variantCount = 0;
variantCountUsed = 0;
MethodInfo getVariantCountReflection = typeof(ShaderUtil).GetMethod("GetVariantCount", BindingFlags.Static | BindingFlags.NonPublic);
if (getVariantCountReflection != null)
{
try
{
object result = getVariantCountReflection.Invoke(null, new object[] {shader, false});
variantCount = (ulong)result;
result = getVariantCountReflection.Invoke(null, new object[] {shader, true});
variantCountUsed = (ulong)result;
}
catch
{
// ignored
}
}
}
}
namespace Inspector
{
[CustomEditor(typeof(CFXR_ShaderImporter)), CanEditMultipleObjects]
public class TCP2ShaderImporter_Editor : Editor
{
CFXR_ShaderImporter Importer => (CFXR_ShaderImporter) this.target;
// From: UnityEditor.ShaderInspectorPlatformsPopup
static string FormatCount(ulong count)
{
bool flag = count > 1000000000uL;
string result;
if (flag)
{
result = (count / 1000000000.0).ToString("f2", CultureInfo.InvariantCulture.NumberFormat) + "B";
}
else
{
bool flag2 = count > 1000000uL;
if (flag2)
{
result = (count / 1000000.0).ToString("f2", CultureInfo.InvariantCulture.NumberFormat) + "M";
}
else
{
bool flag3 = count > 1000uL;
if (flag3)
{
result = (count / 1000.0).ToString("f2", CultureInfo.InvariantCulture.NumberFormat) + "k";
}
else
{
result = count.ToString();
}
}
}
return result;
}
static GUIStyle _HelpBoxRichTextStyle;
static GUIStyle HelpBoxRichTextStyle
{
get
{
if (_HelpBoxRichTextStyle == null)
{
_HelpBoxRichTextStyle = new GUIStyle("HelpBox");
_HelpBoxRichTextStyle.richText = true;
_HelpBoxRichTextStyle.margin = new RectOffset(4, 4, 0, 0);
_HelpBoxRichTextStyle.padding = new RectOffset(4, 4, 4, 4);
}
return _HelpBoxRichTextStyle;
}
}
public override void OnInspectorGUI()
{
bool multipleValues = serializedObject.isEditingMultipleObjects;
CFXR_ShaderImporter.RenderPipeline detection = ((CFXR_ShaderImporter)target).renderPipelineDetection;
bool isUsingURP = Utils.IsUsingURP();
serializedObject.Update();
GUILayout.Label(Importer.shaderName);
string variantsText = "";
if (Importer.variantCount > 0 && Importer.variantCountUsed > 0)
{
string variantsCount = multipleValues ? "-" : FormatCount(Importer.variantCount);
string variantsCountUsed = multipleValues ? "-" : FormatCount(Importer.variantCountUsed);
variantsText = $"\nVariants (currently used): <b>{variantsCountUsed}</b>\nVariants (including unused): <b>{variantsCount}</b>";
}
string strippedLinesCount = multipleValues ? "-" : Importer.strippedLinesCount.ToString();
string renderPipeline = Importer.detectedRenderPipeline;
if (targets is { Length: > 1 })
{
foreach (CFXR_ShaderImporter importer in targets)
{
if (importer.detectedRenderPipeline != renderPipeline)
{
renderPipeline = "-";
break;
}
}
}
GUILayout.Label($"{(detection == CFXR_ShaderImporter.RenderPipeline.Auto ? "Detected" : "Forced")} render pipeline: <b>{renderPipeline}</b>\nStripped lines: <b>{strippedLinesCount}</b>{variantsText}", HelpBoxRichTextStyle);
if (Importer.shaderErrors != null && Importer.shaderErrors.Length > 0)
{
GUILayout.Space(4);
var color = GUI.color;
GUI.color = new Color32(0xFF, 0x80, 0x80, 0xFF);
GUILayout.Label($"<b>Errors:</b>\n{string.Join("\n", Importer.shaderErrors)}", HelpBoxRichTextStyle);
GUI.color = color;
}
bool shouldReimportShader = false;
bool compiledForURP = Importer.detectedRenderPipeline.Contains("Universal");
if (detection == CFXR_ShaderImporter.RenderPipeline.Auto
&& ((isUsingURP && !compiledForURP) || (!isUsingURP && compiledForURP)))
{
GUILayout.Space(4);
Color guiColor = GUI.color;
GUI.color *= Color.yellow;
EditorGUILayout.HelpBox("The detected render pipeline doesn't match the pipeline this shader was compiled for!\nPlease reimport the shaders for them to work in the current render pipeline.", MessageType.Warning);
if (GUILayout.Button("Reimport Shader"))
{
shouldReimportShader = true;
}
GUI.color = guiColor;
}
GUILayout.Space(4);
EditorGUI.BeginChangeCheck();
EditorGUILayout.PropertyField(serializedObject.FindProperty(nameof(CFXR_ShaderImporter.renderPipelineDetection)));
if (EditorGUI.EndChangeCheck())
{
shouldReimportShader = true;
}
if (GUILayout.Button("View Source", GUILayout.ExpandWidth(false)))
{
string path = Application.temporaryCachePath + "/" + Importer.shaderName.Replace("/", "-") + "_Source.shader";
if (File.Exists(path))
{
File.SetAttributes(path, FileAttributes.Normal);
}
File.WriteAllText(path, Importer.shaderSourceCode);
File.SetAttributes(path, FileAttributes.ReadOnly);
UnityEditorInternal.InternalEditorUtility.OpenFileAtLineExternal(path, 0);
}
#if SHOW_EXPORT_BUTTON
GUILayout.Space(8);
EditorGUI.BeginDisabledGroup(string.IsNullOrEmpty(importer.shaderSourceCode));
{
if (GUILayout.Button("Export .shader file", GUILayout.ExpandWidth(false)))
{
string savePath = EditorUtility.SaveFilePanel("Export CFXR shader", Application.dataPath, "CFXR Shader","shader");
if (!string.IsNullOrEmpty(savePath))
{
File.WriteAllText(savePath, importer.shaderSourceCode);
}
}
}
EditorGUI.EndDisabledGroup();
#endif
serializedObject.ApplyModifiedProperties();
if (shouldReimportShader)
{
ReimportShader();
}
}
void ReimportShader()
{
foreach (UnityEngine.Object t in targets)
{
string path = AssetDatabase.GetAssetPath(t);
AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceSynchronousImport);
}
}
}
}
}
}
@@ -1,18 +1,18 @@
fileFormatVersion: 2
guid: fe56ec25963759b49955809beeb4324b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 109565
packageName: Cartoon FX Remaster Free
packageVersion: R 1.5.0
assetPath: Assets/JMO Assets/Cartoon FX Remaster/CFXR Assets/Editor/CFXR_ShaderImporter.cs
uploadId: 836238
fileFormatVersion: 2
guid: fe56ec25963759b49955809beeb4324b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 109565
packageName: Cartoon FX Remaster Free
packageVersion: R 1.5.0
assetPath: Assets/JMO Assets/Cartoon FX Remaster/CFXR Assets/Editor/CFXR_ShaderImporter.cs
uploadId: 836238
@@ -1,38 +1,38 @@
using System;
using UnityEditor;
using UnityEngine;
namespace CartoonFX
{
namespace CustomShaderImporter
{
public class CFXR_ShaderPostProcessor : AssetPostprocessor
{
static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths)
{
CleanCFXRShaders(importedAssets);
}
static void CleanCFXRShaders(string[] paths)
{
foreach (var assetPath in paths)
{
if (!assetPath.EndsWith(CFXR_ShaderImporter.FILE_EXTENSION, StringComparison.InvariantCultureIgnoreCase))
{
continue;
}
var shader = AssetDatabase.LoadMainAssetAtPath(assetPath) as Shader;
if (shader != null)
{
ShaderUtil.ClearShaderMessages(shader);
if (!ShaderUtil.ShaderHasError(shader))
{
ShaderUtil.RegisterShader(shader);
}
}
}
}
}
}
using System;
using UnityEditor;
using UnityEngine;
namespace CartoonFX
{
namespace CustomShaderImporter
{
public class CFXR_ShaderPostProcessor : AssetPostprocessor
{
static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths)
{
CleanCFXRShaders(importedAssets);
}
static void CleanCFXRShaders(string[] paths)
{
foreach (var assetPath in paths)
{
if (!assetPath.EndsWith(CFXR_ShaderImporter.FILE_EXTENSION, StringComparison.InvariantCultureIgnoreCase))
{
continue;
}
var shader = AssetDatabase.LoadMainAssetAtPath(assetPath) as Shader;
if (shader != null)
{
ShaderUtil.ClearShaderMessages(shader);
if (!ShaderUtil.ShaderHasError(shader))
{
ShaderUtil.RegisterShader(shader);
}
}
}
}
}
}
}
@@ -1,18 +1,18 @@
fileFormatVersion: 2
guid: 29d46695388f9a84d9ae71b5140727a3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 109565
packageName: Cartoon FX Remaster Free
packageVersion: R 1.5.0
assetPath: Assets/JMO Assets/Cartoon FX Remaster/CFXR Assets/Editor/CFXR_ShaderPostProcessor.cs
uploadId: 836238
fileFormatVersion: 2
guid: 29d46695388f9a84d9ae71b5140727a3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 109565
packageName: Cartoon FX Remaster Free
packageVersion: R 1.5.0
assetPath: Assets/JMO Assets/Cartoon FX Remaster/CFXR Assets/Editor/CFXR_ShaderPostProcessor.cs
uploadId: 836238
@@ -1,362 +1,362 @@
//--------------------------------------------------------------------------------------------------------------------------------
// Cartoon FX
// (c) 2012-2025 Jean Moreno
//--------------------------------------------------------------------------------------------------------------------------------
using UnityEngine;
using UnityEditor;
// GUI Styles and UI methods
namespace CartoonFX
{
public static class Styles
{
//================================================================================================================================
// GUI Styles
//================================================================================================================================
//================================================================================================================================
// (x) close button
static GUIStyle _closeCrossButton;
public static GUIStyle CloseCrossButton
{
get
{
if(_closeCrossButton == null)
{
//Try to load GUISkin according to its GUID
//Assumes that its .meta file should always stick with it!
string guiSkinPath = AssetDatabase.GUIDToAssetPath("02d396fa782e5d7438e231ea9f8be23c");
var gs = AssetDatabase.LoadAssetAtPath<GUISkin>(guiSkinPath);
if(gs != null)
{
_closeCrossButton = System.Array.Find<GUIStyle>(gs.customStyles, x => x.name == "CloseCrossButton");
}
//Else fall back to minibutton
if(_closeCrossButton == null)
_closeCrossButton = EditorStyles.miniButton;
}
return _closeCrossButton;
}
}
//================================================================================================================================
// Shuriken Toggle with label alignment fix
static GUIStyle _shurikenToggle;
public static GUIStyle ShurikenToggle
{
get
{
if(_shurikenToggle == null)
{
_shurikenToggle = new GUIStyle("ShurikenToggle");
_shurikenToggle.fontSize = 9;
_shurikenToggle.contentOffset = new Vector2(16, -1);
if(EditorGUIUtility.isProSkin)
{
var textColor = new Color(.8f, .8f, .8f);
_shurikenToggle.normal.textColor = textColor;
_shurikenToggle.active.textColor = textColor;
_shurikenToggle.focused.textColor = textColor;
_shurikenToggle.hover.textColor = textColor;
_shurikenToggle.onNormal.textColor = textColor;
_shurikenToggle.onActive.textColor = textColor;
_shurikenToggle.onFocused.textColor = textColor;
_shurikenToggle.onHover.textColor = textColor;
}
}
return _shurikenToggle;
}
}
//================================================================================================================================
// Bold mini-label (the one from EditorStyles isn't actually "mini")
static GUIStyle _miniBoldLabel;
public static GUIStyle MiniBoldLabel
{
get
{
if(_miniBoldLabel == null)
{
_miniBoldLabel = new GUIStyle(EditorStyles.boldLabel);
_miniBoldLabel.fontSize = 10;
_miniBoldLabel.margin = new RectOffset(0, 0, 0, 0);
}
return _miniBoldLabel;
}
}
//================================================================================================================================
// Bold mini-foldout
static GUIStyle _miniBoldFoldout;
public static GUIStyle MiniBoldFoldout
{
get
{
if(_miniBoldFoldout == null)
{
_miniBoldFoldout = new GUIStyle(EditorStyles.foldout);
_miniBoldFoldout.fontSize = 10;
_miniBoldFoldout.fontStyle = FontStyle.Bold;
_miniBoldFoldout.margin = new RectOffset(0, 0, 0, 0);
}
return _miniBoldFoldout;
}
}
//================================================================================================================================
// Gray right-aligned label for Orderable List (Material Animator)
static GUIStyle _PropertyTypeLabel;
public static GUIStyle PropertyTypeLabel
{
get
{
if(_PropertyTypeLabel == null)
{
_PropertyTypeLabel = new GUIStyle(EditorStyles.label);
_PropertyTypeLabel.alignment = TextAnchor.MiddleRight;
_PropertyTypeLabel.normal.textColor = Color.gray;
_PropertyTypeLabel.fontSize = 9;
}
return _PropertyTypeLabel;
}
}
// Dark Gray right-aligned label for Orderable List (Material Animator)
static GUIStyle _PropertyTypeLabelFocused;
public static GUIStyle PropertyTypeLabelFocused
{
get
{
if(_PropertyTypeLabelFocused == null)
{
_PropertyTypeLabelFocused = new GUIStyle(EditorStyles.label);
_PropertyTypeLabelFocused.alignment = TextAnchor.MiddleRight;
_PropertyTypeLabelFocused.normal.textColor = new Color(.2f, .2f, .2f);
_PropertyTypeLabelFocused.fontSize = 9;
}
return _PropertyTypeLabelFocused;
}
}
//================================================================================================================================
// Rounded Box
static GUIStyle _roundedBox;
public static GUIStyle RoundedBox
{
get
{
if(_roundedBox == null)
{
_roundedBox = new GUIStyle(EditorStyles.helpBox);
}
return _roundedBox;
}
}
//================================================================================================================================
// Center White Label ("Editing Spline" label in Scene View)
static GUIStyle _CenteredWhiteLabel;
public static GUIStyle CenteredWhiteLabel
{
get
{
if(_CenteredWhiteLabel == null)
{
_CenteredWhiteLabel = new GUIStyle(EditorStyles.centeredGreyMiniLabel);
_CenteredWhiteLabel.fontSize = 20;
_CenteredWhiteLabel.normal.textColor = Color.white;
}
return _CenteredWhiteLabel;
}
}
//================================================================================================================================
// Used to draw lines for separators
static public GUIStyle _LineStyle;
static public GUIStyle LineStyle
{
get
{
if(_LineStyle == null)
{
_LineStyle = new GUIStyle();
_LineStyle.normal.background = EditorGUIUtility.whiteTexture;
_LineStyle.stretchWidth = true;
}
return _LineStyle;
}
}
//================================================================================================================================
// HelpBox with rich text formatting support
static GUIStyle _HelpBoxRichTextStyle;
static public GUIStyle HelpBoxRichTextStyle
{
get
{
if(_HelpBoxRichTextStyle == null)
{
_HelpBoxRichTextStyle = new GUIStyle("HelpBox");
_HelpBoxRichTextStyle.richText = true;
}
return _HelpBoxRichTextStyle;
}
}
//================================================================================================================================
// Material Blue Header
static public GUIStyle _MaterialHeaderStyle;
static public GUIStyle MaterialHeaderStyle
{
get
{
if(_MaterialHeaderStyle == null)
{
_MaterialHeaderStyle = new GUIStyle(EditorStyles.label);
_MaterialHeaderStyle.fontStyle = FontStyle.Bold;
_MaterialHeaderStyle.fontSize = 11;
_MaterialHeaderStyle.padding.top = 0;
_MaterialHeaderStyle.padding.bottom = 0;
_MaterialHeaderStyle.normal.textColor = EditorGUIUtility.isProSkin ? new Color32(75, 128, 255, 255) : new Color32(0, 50, 230, 255);
_MaterialHeaderStyle.stretchWidth = true;
}
return _MaterialHeaderStyle;
}
}
//================================================================================================================================
// Material Header emboss effect
static public GUIStyle _MaterialHeaderStyleHighlight;
static public GUIStyle MaterialHeaderStyleHighlight
{
get
{
if(_MaterialHeaderStyleHighlight == null)
{
_MaterialHeaderStyleHighlight = new GUIStyle(MaterialHeaderStyle);
_MaterialHeaderStyleHighlight.contentOffset = new Vector2(1, 1);
_MaterialHeaderStyleHighlight.normal.textColor = EditorGUIUtility.isProSkin ? new Color32(255, 255, 255, 16) : new Color32(255, 255, 255, 32);
}
return _MaterialHeaderStyleHighlight;
}
}
//================================================================================================================================
// Filled rectangle
static private GUIStyle _WhiteRectangleStyle;
static public void DrawRectangle(Rect position, Color color)
{
var col = GUI.color;
GUI.color *= color;
DrawRectangle(position);
GUI.color = col;
}
static public void DrawRectangle(Rect position)
{
if(_WhiteRectangleStyle == null)
{
_WhiteRectangleStyle = new GUIStyle();
_WhiteRectangleStyle.normal.background = EditorGUIUtility.whiteTexture;
}
if(Event.current != null && Event.current.type == EventType.Repaint)
{
_WhiteRectangleStyle.Draw(position, false, false, false, false);
}
}
//================================================================================================================================
// Methods
//================================================================================================================================
static public void DrawLine(float height = 2f)
{
DrawLine(Color.black, height);
}
static public void DrawLine(Color color, float height = 1f)
{
Rect position = GUILayoutUtility.GetRect(0f, float.MaxValue, height, height, LineStyle);
DrawLine(position, color);
}
static public void DrawLine(Rect position, Color color)
{
if(Event.current.type == EventType.Repaint)
{
Color orgColor = GUI.color;
GUI.color = orgColor * color;
LineStyle.Draw(position, false, false, false, false);
GUI.color = orgColor;
}
}
static public void MaterialDrawHeader(GUIContent guiContent)
{
var rect = GUILayoutUtility.GetRect(guiContent, MaterialHeaderStyle);
GUI.Label(rect, guiContent, MaterialHeaderStyleHighlight);
GUI.Label(rect, guiContent, MaterialHeaderStyle);
}
static public void MaterialDrawSeparator()
{
GUILayout.Space(4);
if(EditorGUIUtility.isProSkin)
DrawLine(new Color(.3f, .3f, .3f, 1f), 1);
else
DrawLine(new Color(.6f, .6f, .6f, 1f), 1);
GUILayout.Space(4);
}
static public void MaterialDrawSeparatorDouble()
{
GUILayout.Space(6);
if(EditorGUIUtility.isProSkin)
{
DrawLine(new Color(.1f, .1f, .1f, 1f), 1);
DrawLine(new Color(.4f, .4f, .4f, 1f), 1);
}
else
{
DrawLine(new Color(.3f, .3f, .3f, 1f), 1);
DrawLine(new Color(.9f, .9f, .9f, 1f), 1);
}
GUILayout.Space(6);
}
//built-in console icons, also used in help box
static Texture2D warnIcon;
static Texture2D infoIcon;
static Texture2D errorIcon;
static public void HelpBoxRichText(Rect position, string message, MessageType msgType)
{
Texture2D icon = null;
switch(msgType)
{
case MessageType.Warning: icon = warnIcon ?? (warnIcon = EditorGUIUtility.Load("console.warnicon") as Texture2D); break;
case MessageType.Info: icon = infoIcon ?? (infoIcon = EditorGUIUtility.Load("console.infoicon") as Texture2D); break;
case MessageType.Error: icon = errorIcon ?? (errorIcon = EditorGUIUtility.Load("console.erroricon") as Texture2D); break;
}
EditorGUI.LabelField(position, GUIContent.none, new GUIContent(message, icon), HelpBoxRichTextStyle);
}
static public void HelpBoxRichText(string message, MessageType msgType)
{
Texture2D icon = null;
switch(msgType)
{
case MessageType.Warning: icon = warnIcon ?? (warnIcon = EditorGUIUtility.Load("console.warnicon") as Texture2D); break;
case MessageType.Info: icon = infoIcon ?? (infoIcon = EditorGUIUtility.Load("console.infoicon") as Texture2D); break;
case MessageType.Error: icon = errorIcon ?? (errorIcon = EditorGUIUtility.Load("console.erroricon") as Texture2D); break;
}
EditorGUILayout.LabelField(GUIContent.none, new GUIContent(message, icon), HelpBoxRichTextStyle);
}
}
}
//--------------------------------------------------------------------------------------------------------------------------------
// Cartoon FX
// (c) 2012-2025 Jean Moreno
//--------------------------------------------------------------------------------------------------------------------------------
using UnityEngine;
using UnityEditor;
// GUI Styles and UI methods
namespace CartoonFX
{
public static class Styles
{
//================================================================================================================================
// GUI Styles
//================================================================================================================================
//================================================================================================================================
// (x) close button
static GUIStyle _closeCrossButton;
public static GUIStyle CloseCrossButton
{
get
{
if(_closeCrossButton == null)
{
//Try to load GUISkin according to its GUID
//Assumes that its .meta file should always stick with it!
string guiSkinPath = AssetDatabase.GUIDToAssetPath("02d396fa782e5d7438e231ea9f8be23c");
var gs = AssetDatabase.LoadAssetAtPath<GUISkin>(guiSkinPath);
if(gs != null)
{
_closeCrossButton = System.Array.Find<GUIStyle>(gs.customStyles, x => x.name == "CloseCrossButton");
}
//Else fall back to minibutton
if(_closeCrossButton == null)
_closeCrossButton = EditorStyles.miniButton;
}
return _closeCrossButton;
}
}
//================================================================================================================================
// Shuriken Toggle with label alignment fix
static GUIStyle _shurikenToggle;
public static GUIStyle ShurikenToggle
{
get
{
if(_shurikenToggle == null)
{
_shurikenToggle = new GUIStyle("ShurikenToggle");
_shurikenToggle.fontSize = 9;
_shurikenToggle.contentOffset = new Vector2(16, -1);
if(EditorGUIUtility.isProSkin)
{
var textColor = new Color(.8f, .8f, .8f);
_shurikenToggle.normal.textColor = textColor;
_shurikenToggle.active.textColor = textColor;
_shurikenToggle.focused.textColor = textColor;
_shurikenToggle.hover.textColor = textColor;
_shurikenToggle.onNormal.textColor = textColor;
_shurikenToggle.onActive.textColor = textColor;
_shurikenToggle.onFocused.textColor = textColor;
_shurikenToggle.onHover.textColor = textColor;
}
}
return _shurikenToggle;
}
}
//================================================================================================================================
// Bold mini-label (the one from EditorStyles isn't actually "mini")
static GUIStyle _miniBoldLabel;
public static GUIStyle MiniBoldLabel
{
get
{
if(_miniBoldLabel == null)
{
_miniBoldLabel = new GUIStyle(EditorStyles.boldLabel);
_miniBoldLabel.fontSize = 10;
_miniBoldLabel.margin = new RectOffset(0, 0, 0, 0);
}
return _miniBoldLabel;
}
}
//================================================================================================================================
// Bold mini-foldout
static GUIStyle _miniBoldFoldout;
public static GUIStyle MiniBoldFoldout
{
get
{
if(_miniBoldFoldout == null)
{
_miniBoldFoldout = new GUIStyle(EditorStyles.foldout);
_miniBoldFoldout.fontSize = 10;
_miniBoldFoldout.fontStyle = FontStyle.Bold;
_miniBoldFoldout.margin = new RectOffset(0, 0, 0, 0);
}
return _miniBoldFoldout;
}
}
//================================================================================================================================
// Gray right-aligned label for Orderable List (Material Animator)
static GUIStyle _PropertyTypeLabel;
public static GUIStyle PropertyTypeLabel
{
get
{
if(_PropertyTypeLabel == null)
{
_PropertyTypeLabel = new GUIStyle(EditorStyles.label);
_PropertyTypeLabel.alignment = TextAnchor.MiddleRight;
_PropertyTypeLabel.normal.textColor = Color.gray;
_PropertyTypeLabel.fontSize = 9;
}
return _PropertyTypeLabel;
}
}
// Dark Gray right-aligned label for Orderable List (Material Animator)
static GUIStyle _PropertyTypeLabelFocused;
public static GUIStyle PropertyTypeLabelFocused
{
get
{
if(_PropertyTypeLabelFocused == null)
{
_PropertyTypeLabelFocused = new GUIStyle(EditorStyles.label);
_PropertyTypeLabelFocused.alignment = TextAnchor.MiddleRight;
_PropertyTypeLabelFocused.normal.textColor = new Color(.2f, .2f, .2f);
_PropertyTypeLabelFocused.fontSize = 9;
}
return _PropertyTypeLabelFocused;
}
}
//================================================================================================================================
// Rounded Box
static GUIStyle _roundedBox;
public static GUIStyle RoundedBox
{
get
{
if(_roundedBox == null)
{
_roundedBox = new GUIStyle(EditorStyles.helpBox);
}
return _roundedBox;
}
}
//================================================================================================================================
// Center White Label ("Editing Spline" label in Scene View)
static GUIStyle _CenteredWhiteLabel;
public static GUIStyle CenteredWhiteLabel
{
get
{
if(_CenteredWhiteLabel == null)
{
_CenteredWhiteLabel = new GUIStyle(EditorStyles.centeredGreyMiniLabel);
_CenteredWhiteLabel.fontSize = 20;
_CenteredWhiteLabel.normal.textColor = Color.white;
}
return _CenteredWhiteLabel;
}
}
//================================================================================================================================
// Used to draw lines for separators
static public GUIStyle _LineStyle;
static public GUIStyle LineStyle
{
get
{
if(_LineStyle == null)
{
_LineStyle = new GUIStyle();
_LineStyle.normal.background = EditorGUIUtility.whiteTexture;
_LineStyle.stretchWidth = true;
}
return _LineStyle;
}
}
//================================================================================================================================
// HelpBox with rich text formatting support
static GUIStyle _HelpBoxRichTextStyle;
static public GUIStyle HelpBoxRichTextStyle
{
get
{
if(_HelpBoxRichTextStyle == null)
{
_HelpBoxRichTextStyle = new GUIStyle("HelpBox");
_HelpBoxRichTextStyle.richText = true;
}
return _HelpBoxRichTextStyle;
}
}
//================================================================================================================================
// Material Blue Header
static public GUIStyle _MaterialHeaderStyle;
static public GUIStyle MaterialHeaderStyle
{
get
{
if(_MaterialHeaderStyle == null)
{
_MaterialHeaderStyle = new GUIStyle(EditorStyles.label);
_MaterialHeaderStyle.fontStyle = FontStyle.Bold;
_MaterialHeaderStyle.fontSize = 11;
_MaterialHeaderStyle.padding.top = 0;
_MaterialHeaderStyle.padding.bottom = 0;
_MaterialHeaderStyle.normal.textColor = EditorGUIUtility.isProSkin ? new Color32(75, 128, 255, 255) : new Color32(0, 50, 230, 255);
_MaterialHeaderStyle.stretchWidth = true;
}
return _MaterialHeaderStyle;
}
}
//================================================================================================================================
// Material Header emboss effect
static public GUIStyle _MaterialHeaderStyleHighlight;
static public GUIStyle MaterialHeaderStyleHighlight
{
get
{
if(_MaterialHeaderStyleHighlight == null)
{
_MaterialHeaderStyleHighlight = new GUIStyle(MaterialHeaderStyle);
_MaterialHeaderStyleHighlight.contentOffset = new Vector2(1, 1);
_MaterialHeaderStyleHighlight.normal.textColor = EditorGUIUtility.isProSkin ? new Color32(255, 255, 255, 16) : new Color32(255, 255, 255, 32);
}
return _MaterialHeaderStyleHighlight;
}
}
//================================================================================================================================
// Filled rectangle
static private GUIStyle _WhiteRectangleStyle;
static public void DrawRectangle(Rect position, Color color)
{
var col = GUI.color;
GUI.color *= color;
DrawRectangle(position);
GUI.color = col;
}
static public void DrawRectangle(Rect position)
{
if(_WhiteRectangleStyle == null)
{
_WhiteRectangleStyle = new GUIStyle();
_WhiteRectangleStyle.normal.background = EditorGUIUtility.whiteTexture;
}
if(Event.current != null && Event.current.type == EventType.Repaint)
{
_WhiteRectangleStyle.Draw(position, false, false, false, false);
}
}
//================================================================================================================================
// Methods
//================================================================================================================================
static public void DrawLine(float height = 2f)
{
DrawLine(Color.black, height);
}
static public void DrawLine(Color color, float height = 1f)
{
Rect position = GUILayoutUtility.GetRect(0f, float.MaxValue, height, height, LineStyle);
DrawLine(position, color);
}
static public void DrawLine(Rect position, Color color)
{
if(Event.current.type == EventType.Repaint)
{
Color orgColor = GUI.color;
GUI.color = orgColor * color;
LineStyle.Draw(position, false, false, false, false);
GUI.color = orgColor;
}
}
static public void MaterialDrawHeader(GUIContent guiContent)
{
var rect = GUILayoutUtility.GetRect(guiContent, MaterialHeaderStyle);
GUI.Label(rect, guiContent, MaterialHeaderStyleHighlight);
GUI.Label(rect, guiContent, MaterialHeaderStyle);
}
static public void MaterialDrawSeparator()
{
GUILayout.Space(4);
if(EditorGUIUtility.isProSkin)
DrawLine(new Color(.3f, .3f, .3f, 1f), 1);
else
DrawLine(new Color(.6f, .6f, .6f, 1f), 1);
GUILayout.Space(4);
}
static public void MaterialDrawSeparatorDouble()
{
GUILayout.Space(6);
if(EditorGUIUtility.isProSkin)
{
DrawLine(new Color(.1f, .1f, .1f, 1f), 1);
DrawLine(new Color(.4f, .4f, .4f, 1f), 1);
}
else
{
DrawLine(new Color(.3f, .3f, .3f, 1f), 1);
DrawLine(new Color(.9f, .9f, .9f, 1f), 1);
}
GUILayout.Space(6);
}
//built-in console icons, also used in help box
static Texture2D warnIcon;
static Texture2D infoIcon;
static Texture2D errorIcon;
static public void HelpBoxRichText(Rect position, string message, MessageType msgType)
{
Texture2D icon = null;
switch(msgType)
{
case MessageType.Warning: icon = warnIcon ?? (warnIcon = EditorGUIUtility.Load("console.warnicon") as Texture2D); break;
case MessageType.Info: icon = infoIcon ?? (infoIcon = EditorGUIUtility.Load("console.infoicon") as Texture2D); break;
case MessageType.Error: icon = errorIcon ?? (errorIcon = EditorGUIUtility.Load("console.erroricon") as Texture2D); break;
}
EditorGUI.LabelField(position, GUIContent.none, new GUIContent(message, icon), HelpBoxRichTextStyle);
}
static public void HelpBoxRichText(string message, MessageType msgType)
{
Texture2D icon = null;
switch(msgType)
{
case MessageType.Warning: icon = warnIcon ?? (warnIcon = EditorGUIUtility.Load("console.warnicon") as Texture2D); break;
case MessageType.Info: icon = infoIcon ?? (infoIcon = EditorGUIUtility.Load("console.infoicon") as Texture2D); break;
case MessageType.Error: icon = errorIcon ?? (errorIcon = EditorGUIUtility.Load("console.erroricon") as Texture2D); break;
}
EditorGUILayout.LabelField(GUIContent.none, new GUIContent(message, icon), HelpBoxRichTextStyle);
}
}
}
@@ -1,19 +1,19 @@
fileFormatVersion: 2
guid: 26306333afc273640814fd7a7b3968e0
timeCreated: 1501149213
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 109565
packageName: Cartoon FX Remaster Free
packageVersion: R 1.5.0
assetPath: Assets/JMO Assets/Cartoon FX Remaster/CFXR Assets/Editor/CFXR_Styles.cs
uploadId: 836238
fileFormatVersion: 2
guid: 26306333afc273640814fd7a7b3968e0
timeCreated: 1501149213
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 109565
packageName: Cartoon FX Remaster Free
packageVersion: R 1.5.0
assetPath: Assets/JMO Assets/Cartoon FX Remaster/CFXR Assets/Editor/CFXR_Styles.cs
uploadId: 836238