chore: 외부 에셋 권한 및 줄바꿈 재기록 반영

- Assets/External 하위 샘플 및 서드파티 에셋 파일의 실행 비트 변경을 별도 커밋으로 분리
- PolygonGeneric, SidekickCharacters, Synty 도구 자산 전반의 줄바꿈 및 재직렬화 차이를 그대로 보존
- 프로젝트 고유 로직 변경과 분리해 이후 히스토리에서 외부 에셋 노이즈 범위를 식별하기 쉽게 정리
This commit is contained in:
2026-04-06 14:04:09 +09:00
parent c8edf838fd
commit cf103baf57
140 changed files with 15090 additions and 14829 deletions

View File

@@ -45,7 +45,7 @@ Material:
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
m_CustomRenderQueue: 2450
stringTagMap: {}
disabledShaderPasses:
- MOTIONVECTORS
@@ -57,6 +57,10 @@ Material:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _Alpha_Texture:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _Base_Texture:
m_Texture: {fileID: 2800000, guid: 9614e1c2eb9ea3240a97d2245414317b, type: 3}
m_Scale: {x: 1, y: 1}
@@ -158,6 +162,8 @@ Material:
- _AO_Intensity: 1
- _AlphaClip: 1
- _AlphaToMask: 1
- _Alpha_Clip_Threshold: 0.5
- _Alpha_Transparency: 1
- _BUILTIN_AlphaClip: 0
- _BUILTIN_Blend: 0
- _BUILTIN_CullMode: 2
@@ -179,12 +185,14 @@ Material:
- _Cutoff: 0.5
- _DetailNormalMapScale: 1
- _DstBlend: 0
- _DstBlendAlpha: 0
- _Enable_Ambient_Occlusion: 0
- _Enable_Base_Texture: 1
- _Enable_Emission_Texture: 0
- _Enable_Normal_Texture: 1
- _Enable_Overlay_Texture: 0
- _Enable_Snow: 0
- _Enable_Transparency: 0
- _Enable_Triplanar_Emission: 0
- _Enable_Triplanar_Normals: 0
- _Enable_Triplanar_Texture: 1
@@ -213,6 +221,7 @@ Material:
- _Snow_Use_World_Up: 1
- _SpecularHighlights: 1
- _SrcBlend: 1
- _SrcBlendAlpha: 1
- _Surface: 0
- _Top_Metallic: 0
- _Top_Smoothness: 0
@@ -228,6 +237,7 @@ Material:
- _Triplanar_Normal_Top_To_Side_Difference: 0.2
- _Triplanar_Top_To_Side_Difference: 0.2
- _UVSec: 0
- _Use_Separate_Alpha_Map: 0
- _WorkflowMode: 1
- _ZTest: 4
- _ZWrite: 1
@@ -235,6 +245,8 @@ Material:
m_Colors:
- _AO_Offset: {r: 0, g: 0, b: 0, a: 0}
- _AO_Tiling: {r: 1, g: 1, b: 0, a: 0}
- _Alpha_Offset: {r: 0, g: 0, b: 0, a: 0}
- _Alpha_Tiling: {r: 1, g: 1, b: 0, a: 0}
- _Base_Offset: {r: 0, g: 0, b: 0, a: 0}
- _Base_Tiling: {r: 1, g: 1, b: 0, a: 0}
- _Color: {r: 1, g: 1, b: 1, a: 1}

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

0
Assets/External/Models/PolygonGeneric/Materials/Skybox_01.mat.meta vendored Normal file → Executable file
View File

View File

70
Assets/External/Models/PolygonGeneric/Scripts/Generic_SimpleRotate.cs vendored Normal file → Executable file
View File

@@ -1,35 +1,35 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Generic_SimpleRotate : MonoBehaviour
{
public bool rotX;
public float rotXSpeed = 50f;
public bool rotY;
public float rotYSpeed = 50f;
public bool rotZ;
public float rotZSpeed = 50f;
// Update is called once per frame
void Update()
{
if (rotX == true)
{
transform.Rotate(Vector3.left * Time.deltaTime * rotXSpeed);
}
if (rotY == true)
{
transform.Rotate(Vector3.up * Time.deltaTime * rotYSpeed);
}
if (rotZ == true)
{
transform.Rotate(Vector3.back * Time.deltaTime * rotZSpeed);
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Generic_SimpleRotate : MonoBehaviour
{
public bool rotX;
public float rotXSpeed = 50f;
public bool rotY;
public float rotYSpeed = 50f;
public bool rotZ;
public float rotZSpeed = 50f;
// Update is called once per frame
void Update()
{
if (rotX == true)
{
transform.Rotate(Vector3.left * Time.deltaTime * rotXSpeed);
}
if (rotY == true)
{
transform.Rotate(Vector3.up * Time.deltaTime * rotYSpeed);
}
if (rotZ == true)
{
transform.Rotate(Vector3.back * Time.deltaTime * rotZSpeed);
}
}
}

View File

View File

@@ -1,31 +1,31 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Generic_SimpleTranslate : MonoBehaviour
{
public bool moveX;
public float moveXSpeed = 2f;
public bool moveY;
public float moveYSpeed = 2f;
public bool moveZ;
public float moveZSpeed = 2f;
void Update()
{
if (moveX == true)
{
transform.Translate(Vector3.left * Time.deltaTime * moveXSpeed);
}
if (moveY == true)
{
transform.Translate(Vector3.up * Time.deltaTime * moveYSpeed);
}
if (moveZ == true)
{
transform.Translate(Vector3.back * Time.deltaTime * moveZSpeed);
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Generic_SimpleTranslate : MonoBehaviour
{
public bool moveX;
public float moveXSpeed = 2f;
public bool moveY;
public float moveYSpeed = 2f;
public bool moveZ;
public float moveZSpeed = 2f;
void Update()
{
if (moveX == true)
{
transform.Translate(Vector3.left * Time.deltaTime * moveXSpeed);
}
if (moveY == true)
{
transform.Translate(Vector3.up * Time.deltaTime * moveYSpeed);
}
if (moveZ == true)
{
transform.Translate(Vector3.back * Time.deltaTime * moveZSpeed);
}
}
}

View File

88
Assets/External/Models/PolygonGeneric/Scripts/Generic_WaterBob.cs vendored Normal file → Executable file
View File

@@ -1,44 +1,44 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Generic_WaterBob : MonoBehaviour
{
public float bobbingHeight = 0.08f; // The height the object will bob up and down
public float bobbingSpeed = 1.5f; // The speed of the bobbing motion
public float rotationAmount = 0.8f; // The amount of rotation applied to the object
public bool randomOffset = true; // Determines if random offsets are applied to speed and rotation
public Vector2 randomRange = new Vector2(0.1f, 1f); // The range for the random offset
private Vector3 startPos;
private Quaternion startRotation;
void Start()
{
startPos = transform.position;
startRotation = transform.rotation; // Save the initial rotation
if (randomOffset)
{
bobbingSpeed += UnityEngine.Random.Range(randomRange.x, randomRange.y);
rotationAmount += UnityEngine.Random.Range(randomRange.x, randomRange.y);
}
}
void Update()
{
// Calculate the vertical bobbing motion
float newY = startPos.y + Mathf.Sin(Time.time * bobbingSpeed) * bobbingHeight;
Vector3 newPos = new Vector3(transform.position.x, newY, transform.position.z);
transform.position = newPos;
// Calculate rotation offsets based on time
float rotationX = Mathf.Sin(Time.time * bobbingSpeed * 0.5f) * rotationAmount;
float rotationY = Mathf.Sin(Time.time * bobbingSpeed * 0.7f) * rotationAmount;
float rotationZ = Mathf.Sin(Time.time * bobbingSpeed * 0.9f) * rotationAmount;
// Apply the incremental rotation as an offset to the existing rotation
Quaternion incrementalRotation = Quaternion.Euler(rotationX, rotationY, rotationZ);
transform.rotation = startRotation * incrementalRotation;
}
}
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Generic_WaterBob : MonoBehaviour
{
public float bobbingHeight = 0.08f; // The height the object will bob up and down
public float bobbingSpeed = 1.5f; // The speed of the bobbing motion
public float rotationAmount = 0.8f; // The amount of rotation applied to the object
public bool randomOffset = true; // Determines if random offsets are applied to speed and rotation
public Vector2 randomRange = new Vector2(0.1f, 1f); // The range for the random offset
private Vector3 startPos;
private Quaternion startRotation;
void Start()
{
startPos = transform.position;
startRotation = transform.rotation; // Save the initial rotation
if (randomOffset)
{
bobbingSpeed += UnityEngine.Random.Range(randomRange.x, randomRange.y);
rotationAmount += UnityEngine.Random.Range(randomRange.x, randomRange.y);
}
}
void Update()
{
// Calculate the vertical bobbing motion
float newY = startPos.y + Mathf.Sin(Time.time * bobbingSpeed) * bobbingHeight;
Vector3 newPos = new Vector3(transform.position.x, newY, transform.position.z);
transform.position = newPos;
// Calculate rotation offsets based on time
float rotationX = Mathf.Sin(Time.time * bobbingSpeed * 0.5f) * rotationAmount;
float rotationY = Mathf.Sin(Time.time * bobbingSpeed * 0.7f) * rotationAmount;
float rotationZ = Mathf.Sin(Time.time * bobbingSpeed * 0.9f) * rotationAmount;
// Apply the incremental rotation as an offset to the existing rotation
Quaternion incrementalRotation = Quaternion.Euler(rotationX, rotationY, rotationZ);
transform.rotation = startRotation * incrementalRotation;
}
}

View File

View File

@@ -1,204 +1,204 @@
using UnityEditor;
public class PolygonShaderGUI : ShaderGUI
{
private bool _showBaseTexture = false;
private bool _showOverlayTexture = false;
private bool _showAlphaTexture = false;
private bool _showNormalTexture = false;
private bool _showTriplanar = false;
private bool _showNormalTriplanar = false;
private bool _showEmissionTexture = false;
private bool _showSnow = false;
private bool _showWave = false;
private bool CreatePropertyGroup(string title, string[] groupProperties, bool foldout, MaterialEditor materialEditor, MaterialProperty[] allProperties)
{
foldout = EditorGUILayout.BeginFoldoutHeaderGroup(foldout, title);
if (foldout)
{
foreach (string property in groupProperties)
{
MaterialProperty propertyReference = FindProperty(property, allProperties);
materialEditor.ShaderProperty(propertyReference, propertyReference.displayName, 1);
}
}
EditorGUILayout.EndFoldoutHeaderGroup();
return foldout;
}
override public void OnGUI(MaterialEditor materialEditor, MaterialProperty[] properties)
{
EditorGUILayout.LabelField("Basic Parameters", EditorStyles.boldLabel);
// Ungrouped Basic Parameters
string[] shaderProperties =
{
"_Color_Tint",
"_Metallic",
"_Smoothness",
"_Metallic_Smoothness_Texture",
"_Ambient_Occlusion",
"_Specular_Color",
"_Alpha_Transparency"
};
foreach (string property in shaderProperties)
{
MaterialProperty propertyReference = FindProperty(property, properties);
materialEditor.ShaderProperty(propertyReference, propertyReference.displayName, 0);
}
EditorGUILayout.Separator();
// Base Texture Parameters
shaderProperties = new[]
{
"_Enable_Base_Texture",
"_Base_Texture",
"_Base_Tiling",
"_Base_Offset"
};
_showBaseTexture = CreatePropertyGroup("Base Texture", shaderProperties, _showBaseTexture, materialEditor, properties);
// Alpha Texture Parameters
shaderProperties = new[]
{
"_Enable_Alpha_Texture",
"_Alpha_Texture",
"_Alpha_Tiling",
"_Alpha_Offset"
};
_showAlphaTexture = CreatePropertyGroup("Alpha Texture", shaderProperties, _showAlphaTexture, materialEditor, properties);
// Normal Texture Parameters
shaderProperties = new[]
{
"_Enable_Normal_Texture",
"_Normal_Texture",
"_Normal_Tiling",
"_Normal_Offset"
};
_showNormalTexture = CreatePropertyGroup("Normal Texture", shaderProperties, _showNormalTexture, materialEditor, properties);
// Emission Texture Parameters
shaderProperties = new[]
{
"_Enable_Emission_Texture",
"_Emission_Texture",
"_Emission_Tiling",
"_Emission_Offset"
};
_showEmissionTexture = CreatePropertyGroup("Emission Texture", shaderProperties, _showEmissionTexture, materialEditor, properties);
EditorGUILayout.Separator();
EditorGUILayout.LabelField("Advanced Parameters", EditorStyles.boldLabel);
// Overlay Texture Parameters
shaderProperties = new[]
{
"_Enable_Overlay_Texture",
"_Overlay_Texture",
"_Overlay_Tiling",
"_Overlay_Offset",
"_OVERLAY_UV_CHANNEL",
"_Overlay_Intensity"
};
_showOverlayTexture = CreatePropertyGroup("Overlay Texture", shaderProperties, _showOverlayTexture, materialEditor, properties);
// Triplanar Texture Parameters
shaderProperties = new[]
{
"_Enable_Triplanar_Texture",
"_Triplanar_Texture_Top",
"_Triplanar_Tiling_Top",
"_Triplanar_Offset_Top",
"_Triplanar_Texture_Bottom",
"_Triplanar_Tiling_Bottom",
"_Triplanar_Offset_Bottom",
"_Triplanar_Texture_Side",
"_Triplanar_Tiling_Side",
"_Triplanar_Offset_Side",
"_Triplanar_Top_To_Side_Difference",
"_Triplanar_Fade", "_Triplanar_Intensity"
};
_showTriplanar = CreatePropertyGroup("Triplanar Texture", shaderProperties, _showTriplanar, materialEditor, properties);
// Triplanar Normal Texture Parameters
shaderProperties = new[]
{
"_Enable_Triplanar_Normals",
"_Triplanar_Normal_Texture_Top",
"_Triplanar_Normal_Intensity_Top",
"_Triplanar_Normal_Tiling_Top",
"_Triplanar_Normal_Offset_Top",
"_Triplanar_Normal_Texture_Bottom",
"_Triplanar_Normal_Intensity_Bottom",
"_Triplanar_Normal_Tiling_Bottom",
"_Triplanar_Normal_Offset_Bottom",
"_Triplanar_Normal_Texture_Side",
"_Triplanar_Normal_Intensity_Side",
"_Triplanar_Normal_Tiling_Side",
"_Triplanar_Normal_Offset_Side",
"_Triplanar_Normal_Top_To_Side_Difference",
"_Triplanar_Normal_Fade"
};
_showNormalTriplanar = CreatePropertyGroup("Triplanar Normal Texture", shaderProperties, _showNormalTriplanar, materialEditor, properties);
// Snow Parameters
shaderProperties = new[]
{
"_Enable_Snow",
"_Snow_Metallic",
"_Snow_Smoothness",
"_Snow_Level",
"_Snow_Transition",
"_Snow_Transition_Threshold",
"_Snow_Transition_Threshold_Steps",
"_Snow_Transition_Threshold_Step_Count",
"_Snow_Angle_Threshold",
"_Snow_Color",
"_Sea_Level",
"_Snow_Edge_Noise",
"_Snow_Noise_Tiling",
"_Snow_Noise_Offset",
"_Snow_Noise_Fade",
"_Snow_Noise_Top_To_Side_Difference",
"_Snow_Normal_Texture",
"_Snow_Overrides_Normals",
"_Snow_Normal_Intensity",
"_Snow_Normal_Tiling",
"_Snow_Normal_Offset",
"_Snow_Normal_Fade",
"_Snow_Metallic_Smoothness_Texture",
"_Snow_Metallic_Smoothness_Tiling",
"_Snow_Metallic_Smoothness_Offset"
};
_showSnow = CreatePropertyGroup("Snow", shaderProperties, _showSnow, materialEditor, properties);
// Wave Parameters
shaderProperties = new[]
{
"_Enable_Wave",
"_Wave_Direction_Vector",
"_Wave_Scale",
"_Wave_Noise_Tiling",
"_Wave_Speed",
"_Fade_Wave_To_Object_Origin",
"_Fade_Wave_Scale",
"_Fade_Wave_Vertical_Offset",
"_Wave_Object_Offset"
};
_showWave = CreatePropertyGroup("Wave", shaderProperties, _showWave, materialEditor, properties);
}
}
using UnityEditor;
public class PolygonShaderGUI : ShaderGUI
{
private bool _showBaseTexture = false;
private bool _showOverlayTexture = false;
private bool _showAlphaTexture = false;
private bool _showNormalTexture = false;
private bool _showTriplanar = false;
private bool _showNormalTriplanar = false;
private bool _showEmissionTexture = false;
private bool _showSnow = false;
private bool _showWave = false;
private bool CreatePropertyGroup(string title, string[] groupProperties, bool foldout, MaterialEditor materialEditor, MaterialProperty[] allProperties)
{
foldout = EditorGUILayout.BeginFoldoutHeaderGroup(foldout, title);
if (foldout)
{
foreach (string property in groupProperties)
{
MaterialProperty propertyReference = FindProperty(property, allProperties);
materialEditor.ShaderProperty(propertyReference, propertyReference.displayName, 1);
}
}
EditorGUILayout.EndFoldoutHeaderGroup();
return foldout;
}
override public void OnGUI(MaterialEditor materialEditor, MaterialProperty[] properties)
{
EditorGUILayout.LabelField("Basic Parameters", EditorStyles.boldLabel);
// Ungrouped Basic Parameters
string[] shaderProperties =
{
"_Color_Tint",
"_Metallic",
"_Smoothness",
"_Metallic_Smoothness_Texture",
"_Ambient_Occlusion",
"_Specular_Color",
"_Alpha_Transparency"
};
foreach (string property in shaderProperties)
{
MaterialProperty propertyReference = FindProperty(property, properties);
materialEditor.ShaderProperty(propertyReference, propertyReference.displayName, 0);
}
EditorGUILayout.Separator();
// Base Texture Parameters
shaderProperties = new[]
{
"_Enable_Base_Texture",
"_Base_Texture",
"_Base_Tiling",
"_Base_Offset"
};
_showBaseTexture = CreatePropertyGroup("Base Texture", shaderProperties, _showBaseTexture, materialEditor, properties);
// Alpha Texture Parameters
shaderProperties = new[]
{
"_Enable_Alpha_Texture",
"_Alpha_Texture",
"_Alpha_Tiling",
"_Alpha_Offset"
};
_showAlphaTexture = CreatePropertyGroup("Alpha Texture", shaderProperties, _showAlphaTexture, materialEditor, properties);
// Normal Texture Parameters
shaderProperties = new[]
{
"_Enable_Normal_Texture",
"_Normal_Texture",
"_Normal_Tiling",
"_Normal_Offset"
};
_showNormalTexture = CreatePropertyGroup("Normal Texture", shaderProperties, _showNormalTexture, materialEditor, properties);
// Emission Texture Parameters
shaderProperties = new[]
{
"_Enable_Emission_Texture",
"_Emission_Texture",
"_Emission_Tiling",
"_Emission_Offset"
};
_showEmissionTexture = CreatePropertyGroup("Emission Texture", shaderProperties, _showEmissionTexture, materialEditor, properties);
EditorGUILayout.Separator();
EditorGUILayout.LabelField("Advanced Parameters", EditorStyles.boldLabel);
// Overlay Texture Parameters
shaderProperties = new[]
{
"_Enable_Overlay_Texture",
"_Overlay_Texture",
"_Overlay_Tiling",
"_Overlay_Offset",
"_OVERLAY_UV_CHANNEL",
"_Overlay_Intensity"
};
_showOverlayTexture = CreatePropertyGroup("Overlay Texture", shaderProperties, _showOverlayTexture, materialEditor, properties);
// Triplanar Texture Parameters
shaderProperties = new[]
{
"_Enable_Triplanar_Texture",
"_Triplanar_Texture_Top",
"_Triplanar_Tiling_Top",
"_Triplanar_Offset_Top",
"_Triplanar_Texture_Bottom",
"_Triplanar_Tiling_Bottom",
"_Triplanar_Offset_Bottom",
"_Triplanar_Texture_Side",
"_Triplanar_Tiling_Side",
"_Triplanar_Offset_Side",
"_Triplanar_Top_To_Side_Difference",
"_Triplanar_Fade", "_Triplanar_Intensity"
};
_showTriplanar = CreatePropertyGroup("Triplanar Texture", shaderProperties, _showTriplanar, materialEditor, properties);
// Triplanar Normal Texture Parameters
shaderProperties = new[]
{
"_Enable_Triplanar_Normals",
"_Triplanar_Normal_Texture_Top",
"_Triplanar_Normal_Intensity_Top",
"_Triplanar_Normal_Tiling_Top",
"_Triplanar_Normal_Offset_Top",
"_Triplanar_Normal_Texture_Bottom",
"_Triplanar_Normal_Intensity_Bottom",
"_Triplanar_Normal_Tiling_Bottom",
"_Triplanar_Normal_Offset_Bottom",
"_Triplanar_Normal_Texture_Side",
"_Triplanar_Normal_Intensity_Side",
"_Triplanar_Normal_Tiling_Side",
"_Triplanar_Normal_Offset_Side",
"_Triplanar_Normal_Top_To_Side_Difference",
"_Triplanar_Normal_Fade"
};
_showNormalTriplanar = CreatePropertyGroup("Triplanar Normal Texture", shaderProperties, _showNormalTriplanar, materialEditor, properties);
// Snow Parameters
shaderProperties = new[]
{
"_Enable_Snow",
"_Snow_Metallic",
"_Snow_Smoothness",
"_Snow_Level",
"_Snow_Transition",
"_Snow_Transition_Threshold",
"_Snow_Transition_Threshold_Steps",
"_Snow_Transition_Threshold_Step_Count",
"_Snow_Angle_Threshold",
"_Snow_Color",
"_Sea_Level",
"_Snow_Edge_Noise",
"_Snow_Noise_Tiling",
"_Snow_Noise_Offset",
"_Snow_Noise_Fade",
"_Snow_Noise_Top_To_Side_Difference",
"_Snow_Normal_Texture",
"_Snow_Overrides_Normals",
"_Snow_Normal_Intensity",
"_Snow_Normal_Tiling",
"_Snow_Normal_Offset",
"_Snow_Normal_Fade",
"_Snow_Metallic_Smoothness_Texture",
"_Snow_Metallic_Smoothness_Tiling",
"_Snow_Metallic_Smoothness_Offset"
};
_showSnow = CreatePropertyGroup("Snow", shaderProperties, _showSnow, materialEditor, properties);
// Wave Parameters
shaderProperties = new[]
{
"_Enable_Wave",
"_Wave_Direction_Vector",
"_Wave_Scale",
"_Wave_Noise_Tiling",
"_Wave_Speed",
"_Fade_Wave_To_Object_Origin",
"_Fade_Wave_Scale",
"_Fade_Wave_Vertical_Offset",
"_Wave_Object_Offset"
};
_showWave = CreatePropertyGroup("Wave", shaderProperties, _showWave, materialEditor, properties);
}
}

View File

@@ -1,145 +1,145 @@
using UnityEditor;
public class PolygonTransparencyShaderGUI : ShaderGUI
{
private bool _showBaseTexture = false;
private bool _showOverlayTexture = false;
private bool _showAlphaTexture = false;
private bool _showNormalTexture = false;
private bool _showEmissionTexture = false;
private bool _showSnow = false;
private bool CreatePropertyGroup(string title, string[] groupProperties, bool foldout, MaterialEditor materialEditor, MaterialProperty[] allProperties)
{
foldout = EditorGUILayout.BeginFoldoutHeaderGroup(foldout, title);
if (foldout)
{
foreach (string property in groupProperties)
{
MaterialProperty propertyReference = FindProperty(property, allProperties);
materialEditor.ShaderProperty(propertyReference, propertyReference.displayName, 1);
}
}
EditorGUILayout.EndFoldoutHeaderGroup();
return foldout;
}
override public void OnGUI(MaterialEditor materialEditor, MaterialProperty[] properties)
{
EditorGUILayout.LabelField("Basic Parameters", EditorStyles.boldLabel);
// Ungrouped Basic Parameters
string[] shaderProperties =
{
"_Color_Tint",
"_Metallic",
"_Smoothness",
"_Metallic_Smoothness_Texture",
"_Ambient_Occlusion",
"_Alpha_Transparency",
"_Alpha_Clip_Threshold"
};
foreach (string property in shaderProperties)
{
MaterialProperty propertyReference = FindProperty(property, properties);
materialEditor.ShaderProperty(propertyReference, propertyReference.displayName, 0);
}
EditorGUILayout.Separator();
// Base Texture Parameters
shaderProperties = new[]
{
"_Enable_Base_Texture",
"_Base_Texture",
"_Base_Tiling",
"_Base_Offset"
};
_showBaseTexture = CreatePropertyGroup("Base Texture", shaderProperties, _showBaseTexture, materialEditor, properties);
// Alpha Texture Parameters
shaderProperties = new[]
{
"_Enable_Alpha_Texture",
"_Alpha_Texture",
"_Alpha_Tiling",
"_Alpha_Offset"
};
_showAlphaTexture = CreatePropertyGroup("Alpha Texture", shaderProperties, _showAlphaTexture, materialEditor, properties);
// Normal Texture Parameters
shaderProperties = new[]
{
"_Enable_Normal_Texture",
"_Normal_Texture",
"_Normal_Tiling",
"_Normal_Offset"
};
_showNormalTexture = CreatePropertyGroup("Normal Texture", shaderProperties, _showNormalTexture, materialEditor, properties);
// Emission Texture Parameters
shaderProperties = new[]
{
"_Enable_Emission_Texture",
"_Emission_Texture",
"_Emission_Tiling",
"_Emission_Offset"
};
_showEmissionTexture = CreatePropertyGroup("Emission Texture", shaderProperties, _showEmissionTexture, materialEditor, properties);
EditorGUILayout.Separator();
EditorGUILayout.LabelField("Advanced Parameters", EditorStyles.boldLabel);
// Overlay Texture Parameters
shaderProperties = new[]
{
"_Enable_Overlay_Texture",
"_Overlay_Texture",
"_Overlay_Tiling",
"_Overlay_Offset",
"_OVERLAY_UV_CHANNEL",
"_Overlay_Intensity"
};
_showOverlayTexture = CreatePropertyGroup("Overlay Texture", shaderProperties, _showOverlayTexture, materialEditor, properties);
// Snow Parameters
shaderProperties = new[]
{
"_Enable_Snow",
"_Snow_Metallic",
"_Snow_Smoothness",
"_Snow_Level",
"_Snow_Transition",
"_Snow_Transition_Threshold",
"_Snow_Transition_Threshold_Steps",
"_Snow_Transition_Threshold_Step_Count",
"_Snow_Angle_Threshold",
"_Snow_Color",
"_Sea_Level",
"_Snow_Edge_Noise",
"_Snow_Noise_Tiling",
"_Snow_Noise_Offset",
"_Snow_Noise_Fade",
"_Snow_Noise_Top_To_Side_Difference",
"_Snow_Normal_Texture",
"_Snow_Overrides_Normals",
"_Snow_Normal_Intensity",
"_Snow_Normal_Tiling",
"_Snow_Normal_Offset",
"_Snow_Normal_Fade",
"_Snow_Metallic_Smoothness_Texture",
"_Snow_Metallic_Smoothness_Tiling",
"_Snow_Metallic_Smoothness_Offset"
};
_showSnow = CreatePropertyGroup("Snow", shaderProperties, _showSnow, materialEditor, properties);
}
}
using UnityEditor;
public class PolygonTransparencyShaderGUI : ShaderGUI
{
private bool _showBaseTexture = false;
private bool _showOverlayTexture = false;
private bool _showAlphaTexture = false;
private bool _showNormalTexture = false;
private bool _showEmissionTexture = false;
private bool _showSnow = false;
private bool CreatePropertyGroup(string title, string[] groupProperties, bool foldout, MaterialEditor materialEditor, MaterialProperty[] allProperties)
{
foldout = EditorGUILayout.BeginFoldoutHeaderGroup(foldout, title);
if (foldout)
{
foreach (string property in groupProperties)
{
MaterialProperty propertyReference = FindProperty(property, allProperties);
materialEditor.ShaderProperty(propertyReference, propertyReference.displayName, 1);
}
}
EditorGUILayout.EndFoldoutHeaderGroup();
return foldout;
}
override public void OnGUI(MaterialEditor materialEditor, MaterialProperty[] properties)
{
EditorGUILayout.LabelField("Basic Parameters", EditorStyles.boldLabel);
// Ungrouped Basic Parameters
string[] shaderProperties =
{
"_Color_Tint",
"_Metallic",
"_Smoothness",
"_Metallic_Smoothness_Texture",
"_Ambient_Occlusion",
"_Alpha_Transparency",
"_Alpha_Clip_Threshold"
};
foreach (string property in shaderProperties)
{
MaterialProperty propertyReference = FindProperty(property, properties);
materialEditor.ShaderProperty(propertyReference, propertyReference.displayName, 0);
}
EditorGUILayout.Separator();
// Base Texture Parameters
shaderProperties = new[]
{
"_Enable_Base_Texture",
"_Base_Texture",
"_Base_Tiling",
"_Base_Offset"
};
_showBaseTexture = CreatePropertyGroup("Base Texture", shaderProperties, _showBaseTexture, materialEditor, properties);
// Alpha Texture Parameters
shaderProperties = new[]
{
"_Enable_Alpha_Texture",
"_Alpha_Texture",
"_Alpha_Tiling",
"_Alpha_Offset"
};
_showAlphaTexture = CreatePropertyGroup("Alpha Texture", shaderProperties, _showAlphaTexture, materialEditor, properties);
// Normal Texture Parameters
shaderProperties = new[]
{
"_Enable_Normal_Texture",
"_Normal_Texture",
"_Normal_Tiling",
"_Normal_Offset"
};
_showNormalTexture = CreatePropertyGroup("Normal Texture", shaderProperties, _showNormalTexture, materialEditor, properties);
// Emission Texture Parameters
shaderProperties = new[]
{
"_Enable_Emission_Texture",
"_Emission_Texture",
"_Emission_Tiling",
"_Emission_Offset"
};
_showEmissionTexture = CreatePropertyGroup("Emission Texture", shaderProperties, _showEmissionTexture, materialEditor, properties);
EditorGUILayout.Separator();
EditorGUILayout.LabelField("Advanced Parameters", EditorStyles.boldLabel);
// Overlay Texture Parameters
shaderProperties = new[]
{
"_Enable_Overlay_Texture",
"_Overlay_Texture",
"_Overlay_Tiling",
"_Overlay_Offset",
"_OVERLAY_UV_CHANNEL",
"_Overlay_Intensity"
};
_showOverlayTexture = CreatePropertyGroup("Overlay Texture", shaderProperties, _showOverlayTexture, materialEditor, properties);
// Snow Parameters
shaderProperties = new[]
{
"_Enable_Snow",
"_Snow_Metallic",
"_Snow_Smoothness",
"_Snow_Level",
"_Snow_Transition",
"_Snow_Transition_Threshold",
"_Snow_Transition_Threshold_Steps",
"_Snow_Transition_Threshold_Step_Count",
"_Snow_Angle_Threshold",
"_Snow_Color",
"_Sea_Level",
"_Snow_Edge_Noise",
"_Snow_Noise_Tiling",
"_Snow_Noise_Offset",
"_Snow_Noise_Fade",
"_Snow_Noise_Top_To_Side_Difference",
"_Snow_Normal_Texture",
"_Snow_Overrides_Normals",
"_Snow_Normal_Intensity",
"_Snow_Normal_Tiling",
"_Snow_Normal_Offset",
"_Snow_Normal_Fade",
"_Snow_Metallic_Smoothness_Texture",
"_Snow_Metallic_Smoothness_Tiling",
"_Snow_Metallic_Smoothness_Offset"
};
_showSnow = CreatePropertyGroup("Snow", shaderProperties, _showSnow, materialEditor, properties);
}
}

View File

@@ -8,16 +8,20 @@ Material:
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: FantasyKnights_01
m_Shader: {fileID: -6465566751694194690, guid: db628544640279b41a4a7aa5d75c0322,
type: 3}
m_Shader: {fileID: -6465566751694194690, guid: db628544640279b41a4a7aa5d75c0322, type: 3}
m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0
m_ValidKeywords: []
m_InvalidKeywords: []
m_InvalidKeywords:
- _EMISSION
m_LightmapFlags: 2
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
disabledShaderPasses:
- MOTIONVECTORS
m_LockedProperties:
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
@@ -164,6 +168,7 @@ Material:
- _Grey: {r: 0.59748423, g: 0.59748423, b: 0.59748423, a: 0}
- _SkinColor: {r: 0, g: 0, b: 0, a: 0}
m_BuildTextureStacks: []
m_AllowLocking: 1
--- !u!114 &1358846705396397422
MonoBehaviour:
m_ObjectHideFlags: 11
@@ -176,7 +181,7 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
m_Name:
m_EditorClassIdentifier:
version: 5
version: 10
--- !u!114 &7967226135815873431
MonoBehaviour:
m_ObjectHideFlags: 11

View File

@@ -8,16 +8,20 @@ Material:
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: FantasyKnights_02
m_Shader: {fileID: -6465566751694194690, guid: db628544640279b41a4a7aa5d75c0322,
type: 3}
m_Shader: {fileID: -6465566751694194690, guid: db628544640279b41a4a7aa5d75c0322, type: 3}
m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0
m_ValidKeywords: []
m_InvalidKeywords: []
m_InvalidKeywords:
- _EMISSION
m_LightmapFlags: 2
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
disabledShaderPasses:
- MOTIONVECTORS
m_LockedProperties:
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
@@ -164,6 +168,7 @@ Material:
- _Grey: {r: 0.59748423, g: 0.59748423, b: 0.59748423, a: 0}
- _SkinColor: {r: 0, g: 0, b: 0, a: 0}
m_BuildTextureStacks: []
m_AllowLocking: 1
--- !u!114 &7993738256033606102
MonoBehaviour:
m_ObjectHideFlags: 11
@@ -189,4 +194,4 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
m_Name:
m_EditorClassIdentifier:
version: 5
version: 10

View File

@@ -8,16 +8,20 @@ Material:
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: FantasyKnights_03
m_Shader: {fileID: -6465566751694194690, guid: db628544640279b41a4a7aa5d75c0322,
type: 3}
m_Shader: {fileID: -6465566751694194690, guid: db628544640279b41a4a7aa5d75c0322, type: 3}
m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0
m_ValidKeywords: []
m_InvalidKeywords: []
m_InvalidKeywords:
- _EMISSION
m_LightmapFlags: 2
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
disabledShaderPasses:
- MOTIONVECTORS
m_LockedProperties:
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
@@ -164,6 +168,7 @@ Material:
- _Grey: {r: 0.59748423, g: 0.59748423, b: 0.59748423, a: 0}
- _SkinColor: {r: 0, g: 0, b: 0, a: 0}
m_BuildTextureStacks: []
m_AllowLocking: 1
--- !u!114 &5122993062315569858
MonoBehaviour:
m_ObjectHideFlags: 11
@@ -176,7 +181,7 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
m_Name:
m_EditorClassIdentifier:
version: 5
version: 10
--- !u!114 &8780454250115516571
MonoBehaviour:
m_ObjectHideFlags: 11

View File

@@ -21,16 +21,20 @@ Material:
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: FantasyKnights_04
m_Shader: {fileID: -6465566751694194690, guid: db628544640279b41a4a7aa5d75c0322,
type: 3}
m_Shader: {fileID: -6465566751694194690, guid: db628544640279b41a4a7aa5d75c0322, type: 3}
m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0
m_ValidKeywords: []
m_InvalidKeywords: []
m_InvalidKeywords:
- _EMISSION
m_LightmapFlags: 2
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
disabledShaderPasses:
- MOTIONVECTORS
m_LockedProperties:
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
@@ -177,6 +181,7 @@ Material:
- _Grey: {r: 0.59748423, g: 0.59748423, b: 0.59748423, a: 0}
- _SkinColor: {r: 0, g: 0, b: 0, a: 0}
m_BuildTextureStacks: []
m_AllowLocking: 1
--- !u!114 &6809264838136373543
MonoBehaviour:
m_ObjectHideFlags: 11
@@ -189,4 +194,4 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
m_Name:
m_EditorClassIdentifier:
version: 5
version: 10

View File

@@ -25,7 +25,7 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
m_Name:
m_EditorClassIdentifier:
version: 5
version: 10
--- !u!21 &2100000
Material:
serializedVersion: 8
@@ -34,16 +34,20 @@ Material:
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: FantasyKnights_05
m_Shader: {fileID: -6465566751694194690, guid: db628544640279b41a4a7aa5d75c0322,
type: 3}
m_Shader: {fileID: -6465566751694194690, guid: db628544640279b41a4a7aa5d75c0322, type: 3}
m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0
m_ValidKeywords: []
m_InvalidKeywords: []
m_InvalidKeywords:
- _EMISSION
m_LightmapFlags: 2
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
disabledShaderPasses:
- MOTIONVECTORS
m_LockedProperties:
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
@@ -190,3 +194,4 @@ Material:
- _Grey: {r: 0.59748423, g: 0.59748423, b: 0.59748423, a: 0}
- _SkinColor: {r: 0, g: 0, b: 0, a: 0}
m_BuildTextureStacks: []
m_AllowLocking: 1

View File

@@ -8,16 +8,20 @@ Material:
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: FantasyKnights_06
m_Shader: {fileID: -6465566751694194690, guid: db628544640279b41a4a7aa5d75c0322,
type: 3}
m_Shader: {fileID: -6465566751694194690, guid: db628544640279b41a4a7aa5d75c0322, type: 3}
m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0
m_ValidKeywords: []
m_InvalidKeywords: []
m_InvalidKeywords:
- _EMISSION
m_LightmapFlags: 2
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
disabledShaderPasses:
- MOTIONVECTORS
m_LockedProperties:
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
@@ -164,6 +168,7 @@ Material:
- _Grey: {r: 0.59748423, g: 0.59748423, b: 0.59748423, a: 0}
- _SkinColor: {r: 0, g: 0, b: 0, a: 0}
m_BuildTextureStacks: []
m_AllowLocking: 1
--- !u!114 &1513622437145775386
MonoBehaviour:
m_ObjectHideFlags: 11
@@ -176,7 +181,7 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
m_Name:
m_EditorClassIdentifier:
version: 5
version: 10
--- !u!114 &5488310361178818670
MonoBehaviour:
m_ObjectHideFlags: 11

View File

@@ -21,16 +21,20 @@ Material:
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: HumanSpecies_01
m_Shader: {fileID: -6465566751694194690, guid: db628544640279b41a4a7aa5d75c0322,
type: 3}
m_Shader: {fileID: -6465566751694194690, guid: db628544640279b41a4a7aa5d75c0322, type: 3}
m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0
m_ValidKeywords: []
m_InvalidKeywords: []
m_InvalidKeywords:
- _EMISSION
m_LightmapFlags: 2
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
disabledShaderPasses:
- MOTIONVECTORS
m_LockedProperties:
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
@@ -177,6 +181,7 @@ Material:
- _Grey: {r: 0.59748423, g: 0.59748423, b: 0.59748423, a: 0}
- _SkinColor: {r: 0, g: 0, b: 0, a: 0}
m_BuildTextureStacks: []
m_AllowLocking: 1
--- !u!114 &153752790335324610
MonoBehaviour:
m_ObjectHideFlags: 11
@@ -189,4 +194,4 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
m_Name:
m_EditorClassIdentifier:
version: 5
version: 10

View File

@@ -21,16 +21,20 @@ Material:
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: HumanSpecies_02
m_Shader: {fileID: -6465566751694194690, guid: db628544640279b41a4a7aa5d75c0322,
type: 3}
m_Shader: {fileID: -6465566751694194690, guid: db628544640279b41a4a7aa5d75c0322, type: 3}
m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0
m_ValidKeywords: []
m_InvalidKeywords: []
m_InvalidKeywords:
- _EMISSION
m_LightmapFlags: 2
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
disabledShaderPasses:
- MOTIONVECTORS
m_LockedProperties:
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
@@ -148,6 +152,7 @@ Material:
- _DirtAmount: 0.306
- _DstBlend: 0
- _EnvironmentReflections: 1
- _EyelinerAmount: 0
- _FeminieAmount: 0
- _GlossMapScale: 1
- _Glossiness: 0.5
@@ -176,6 +181,7 @@ Material:
- _Grey: {r: 0.59748423, g: 0.59748423, b: 0.59748423, a: 0}
- _SkinColor: {r: 0, g: 0, b: 0, a: 0}
m_BuildTextureStacks: []
m_AllowLocking: 1
--- !u!114 &1793314631237679544
MonoBehaviour:
m_ObjectHideFlags: 11
@@ -188,4 +194,4 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
m_Name:
m_EditorClassIdentifier:
version: 5
version: 10

View File

@@ -21,16 +21,20 @@ Material:
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: HumanSpecies_03
m_Shader: {fileID: -6465566751694194690, guid: db628544640279b41a4a7aa5d75c0322,
type: 3}
m_Shader: {fileID: -6465566751694194690, guid: db628544640279b41a4a7aa5d75c0322, type: 3}
m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0
m_ValidKeywords: []
m_InvalidKeywords: []
m_InvalidKeywords:
- _EMISSION
m_LightmapFlags: 2
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
disabledShaderPasses:
- MOTIONVECTORS
m_LockedProperties:
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
@@ -177,6 +181,7 @@ Material:
- _Grey: {r: 0.59748423, g: 0.59748423, b: 0.59748423, a: 0}
- _SkinColor: {r: 0, g: 0, b: 0, a: 0}
m_BuildTextureStacks: []
m_AllowLocking: 1
--- !u!114 &7804425326570313428
MonoBehaviour:
m_ObjectHideFlags: 11
@@ -189,4 +194,4 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
m_Name:
m_EditorClassIdentifier:
version: 5
version: 10

View File

@@ -21,16 +21,20 @@ Material:
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: HumanSpecies_04
m_Shader: {fileID: -6465566751694194690, guid: db628544640279b41a4a7aa5d75c0322,
type: 3}
m_Shader: {fileID: -6465566751694194690, guid: db628544640279b41a4a7aa5d75c0322, type: 3}
m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0
m_ValidKeywords: []
m_InvalidKeywords: []
m_InvalidKeywords:
- _EMISSION
m_LightmapFlags: 2
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
disabledShaderPasses:
- MOTIONVECTORS
m_LockedProperties:
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
@@ -177,6 +181,7 @@ Material:
- _Grey: {r: 0.59748423, g: 0.59748423, b: 0.59748423, a: 0}
- _SkinColor: {r: 0, g: 0, b: 0, a: 0}
m_BuildTextureStacks: []
m_AllowLocking: 1
--- !u!114 &6958986610217973014
MonoBehaviour:
m_ObjectHideFlags: 11
@@ -189,4 +194,4 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
m_Name:
m_EditorClassIdentifier:
version: 5
version: 10

View File

View File

@@ -1,29 +1,29 @@
using System.Resources;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("SQLite-net Official Portable Library")]
[assembly: AssemblyDescription("Light weight library providing easy SQLite database storage")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Krueger Systems, Inc.")]
[assembly: AssemblyProduct("SQLite-net")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: NeutralResourcesLanguage("en")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
using System.Resources;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("SQLite-net Official Portable Library")]
[assembly: AssemblyDescription("Light weight library providing easy SQLite database storage")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Krueger Systems, Inc.")]
[assembly: AssemblyProduct("SQLite-net")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: NeutralResourcesLanguage("en")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,15 +1,15 @@
// Copyright (c) 2024 Synty Studios Limited. All rights reserved.
//
// Use of this software is subject to the terms and conditions of the Synty Studios End User Licence Agreement (EULA)
// available at: https://syntystore.com/pages/end-user-licence-agreement
//
// For additional details, see the LICENSE.MD file bundled with this software.
namespace Synty.SidekickCharacters
{
public class DatabaseUpdateController
{
// This class is no longer required, and will be deleted in the future.
// Included as an empty class to remove code dependencies to allow for deletion without causing project errors.
}
}
// Copyright (c) 2024 Synty Studios Limited. All rights reserved.
//
// Use of this software is subject to the terms and conditions of the Synty Studios End User Licence Agreement (EULA)
// available at: https://syntystore.com/pages/end-user-licence-agreement
//
// For additional details, see the LICENSE.MD file bundled with this software.
namespace Synty.SidekickCharacters
{
public class DatabaseUpdateController
{
// This class is no longer required, and will be deleted in the future.
// Included as an empty class to remove code dependencies to allow for deletion without causing project errors.
}
}

View File

@@ -1,396 +1,354 @@
// Copyright (c) 2025 Synty Studios Limited. All rights reserved.
//
// Use of this software is subject to the terms and conditions of the Synty Studios End User Licence Agreement (EULA)
// available at: https://syntystore.com/pages/end-user-licence-agreement
//
// For additional details, see the LICENSE.MD file bundled with this software.
using System;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;
namespace Synty.SidekickCharacters
{
public class ToolDownloader : EditorWindow
{
private const string _GIT_URL = "https://github.com/SyntyStudios/SidekicksToolRelease/releases/latest/download/Sidekicks.unitypackage";
private const string _GIT_DB_URL = "https://github.com/SyntyStudios/SidekicksToolRelease/releases/latest/download/SidekicksDatabase.unitypackage";
private const string _PACKAGE_CACHE = "Assets/DownloadCache/Sidekicks.unitypackage";
private const string _DB_PACKAGE_CACHE = "Assets/DownloadCache/SidekicksDatabase.unitypackage";
private const string _VERSION_FILE_NAME = "version.txt";
private const string _VERSION_TAG = "\"tag_name\":";
private const string _VERSION_KEY = "sk_current_tool_version";
private const string _SIDEKICK_TOOL_MENU_ITEM = "Synty/Sidekick Character Tool";
private string _version = "-";
private Label _latestVersion;
public void Awake()
{
BackgroundUpdateCheck();
}
public void CreateGUI()
{
VisualElement root = rootVisualElement;
root.Clear();
Button downloadButton = new Button(DownloadLatestDBVersion)
{
text = "Download and Install",
style =
{
height = 40
}
};
root.Add(downloadButton);
Label textPrompt = new Label("This tool will download and install the latest version of the Sidekicks Tool.");
Label textPrompt2 = new Label("Or you can manually download from this link:\nhttps://github.com/SyntyStudios/SidekicksToolRelease/releases/latest/");
root.Add(textPrompt);
root.Add(textPrompt2);
string version = LoadCurrentInstalledVersion();
Label currentVersion = new Label("Currently Installed: " + (string.IsNullOrEmpty(version) ? "N/A" : version))
{
style =
{
marginTop = 5
}
};
_latestVersion = new Label("Latest Version: " + _version);
root.Add(currentVersion);
root.Add(_latestVersion);
Button changeLogButton = new Button()
{
text = "Show Changelog"
};
root.Add(changeLogButton);
changeLogButton.clickable.clicked += delegate
{
Application.OpenURL("https://syntystore.com/pages/sidekicks-changelog");
};
}
public async void BackgroundUpdateCheck()
{
_version = await CheckAvailableVersion();
if (_latestVersion != null)
{
_latestVersion.text = "Latest Version: " + _version;
}
if (IsNewVersionAvailable(_version))
{
DownloaderBackgroundService.ShowToolDownloaderWindow();
}
}
private async Task<string> CheckAvailableVersion()
{
HttpClient client = new HttpClient();
string uri = "http://api.github.com/repos/SyntyStudios/SidekicksToolRelease/releases/latest";
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, uri);
request.Headers.Add("Accept", "application/vnd.github+json");
request.Headers.Add("X-GitHub-Api-Version", "2022-11-28");
request.Headers.Add("User-Agent", "Sidekicks Download Tool");
HttpResponseMessage response = await client.SendAsync(request);
response.EnsureSuccessStatusCode();
// Read the response content as a string
string responseBody = await response.Content.ReadAsStringAsync();
return GetVersionNumber(responseBody);
}
private string GetVersionNumber(string data)
{
int index = data.IndexOf(_VERSION_TAG, StringComparison.OrdinalIgnoreCase) + _VERSION_TAG.Length;
string portion = data.Substring(index, data.Length - index);
string number = portion.Substring(0, portion.IndexOf(',')).Replace("\"", "").Replace(" ", "");
return number;
}
private bool IsNewVersionAvailable(string version)
{
string currentVersion = LoadCurrentInstalledVersion();
if (string.IsNullOrEmpty(currentVersion))
{
return true;
}
if (!currentVersion.Contains('.') || !version.Contains('.'))
{
return false;
}
string[] currentSplitVersion = currentVersion.Split('.');
string[] newSplitVersion = version.Split('.');
if (currentSplitVersion.Length != newSplitVersion.Length)
{
return false;
}
for (int i = 0; i < newSplitVersion.Length; i++)
{
if (int.TryParse(currentSplitVersion[i], out int current))
{
if (int.TryParse(newSplitVersion[i], out int newVersion))
{
if (newVersion > current)
{
return true;
}
}
}
}
return false;
}
private void SaveCurrentInstalledVersion(string version)
{
string versionFilePath = GetVersionFilePath();
if (string.IsNullOrEmpty(versionFilePath))
{
Debug.LogWarning("Unable to resolve Sidekick version file path.");
return;
}
File.WriteAllText(versionFilePath, version);
}
private string LoadCurrentInstalledVersion()
{
string versionFilePath = GetVersionFilePath();
if (string.IsNullOrEmpty(versionFilePath))
{
return null;
}
if (File.Exists(versionFilePath))
{
return File.ReadAllText(versionFilePath);
}
return null;
}
private string GetVersionFilePath()
{
MonoScript currentScript = MonoScript.FromScriptableObject(this);
if (currentScript == null)
{
return null;
}
string scriptPath = AssetDatabase.GetAssetPath(currentScript);
if (string.IsNullOrEmpty(scriptPath))
{
return null;
}
string utilityDirectory = Path.GetDirectoryName(scriptPath);
if (string.IsNullOrEmpty(utilityDirectory))
{
return null;
}
string editorDirectory = Path.GetDirectoryName(utilityDirectory);
if (string.IsNullOrEmpty(editorDirectory))
{
return null;
}
return Path.GetFullPath(Path.Combine(editorDirectory, _VERSION_FILE_NAME));
}
private void DownloadLatestDBVersion()
{
WebClient client = new WebClient();
client.DownloadFileCompleted += (sender, e) =>
{
if (e.Error == null)
{
CloseOpenToolWindow();
AssetDatabase.ImportPackage(_DB_PACKAGE_CACHE, false);
AssetDatabase.importPackageCompleted += ProceedWithInstall;
}
else
{
Debug.LogError("Error downloading file: " + e.Error.Message);
}
};
// Ensure the directory exists
string directory = Path.GetDirectoryName(_DB_PACKAGE_CACHE);
if (!Directory.Exists(directory))
{
Directory.CreateDirectory(directory);
}
client.DownloadFileAsync(new System.Uri(_GIT_DB_URL), _DB_PACKAGE_CACHE);
}
private async void DownloadLatestToolVersion()
{
WebClient client = new WebClient();
_version = await CheckAvailableVersion();
client.DownloadFileCompleted += (sender, e) =>
{
if (e.Error == null)
{
SaveCurrentInstalledVersion(_version);
AssetDatabase.ImportPackage(_PACKAGE_CACHE, false);
AssetDatabase.importPackageCompleted += ProceedWithInstall;
}
else
{
Debug.LogError("Error downloading file: " + e.Error.Message);
}
};
// Ensure the directory exists
string directory = Path.GetDirectoryName(_PACKAGE_CACHE);
if (!Directory.Exists(directory))
{
Directory.CreateDirectory(directory);
}
client.DownloadFileAsync(new System.Uri(_GIT_URL), _PACKAGE_CACHE);
}
private void ProceedWithInstall(string packageName)
{
if (packageName == "SidekicksDatabase")
{
AssetDatabase.importPackageCompleted -= ProceedWithInstall;
DownloadLatestToolVersion();
}
else if (packageName == "Sidekicks")
{
AssetDatabase.importPackageCompleted -= ProceedWithInstall;
DownloaderBackgroundService.RefreshWindow();
if (EditorUtility.DisplayDialog("Installation Finished", "Sidekick Tool installation has completed.", "Re-open Sidekicks Tool",
"Close"))
{
ReopenToolWindow();
}
}
}
private bool CloseOpenToolWindow()
{
EditorWindow[] allWindows = Resources.FindObjectsOfTypeAll<EditorWindow>();
// Filter the windows to find the one with the desired type name
EditorWindow foundWindow = allWindows.FirstOrDefault(window => window.GetType().Name == "ModularCharacterWindow");
if (foundWindow != null)
{
foundWindow.Close();
Thread.Sleep(1500);
return true;
}
return false;
}
private void ReopenToolWindow()
{
try
{
EditorApplication.ExecuteMenuItem(_SIDEKICK_TOOL_MENU_ITEM);
}
catch (Exception ex)
{
Debug.LogWarning("Sidekicks Tool menu item not found. Please verify installation.");
Debug.LogWarning("Exception details: " + ex.Message);
}
}
}
/// <summary>
/// Creates an instance of the Downloader Tool, to allow checks for new versions on editor startup.
/// </summary>
[InitializeOnLoad]
public static class DownloaderBackgroundService
{
private static ToolDownloader _instance;
static DownloaderBackgroundService()
{
EditorApplication.update += CreateToolInstance;
}
static void CreateToolInstance()
{
EditorApplication.update -= CreateToolInstance;
EditorWindow[] allWindows = Resources.FindObjectsOfTypeAll<EditorWindow>();
// Filter the windows to find the one with the desired type name
EditorWindow foundWindow = allWindows.FirstOrDefault(window => window.GetType().Name == "ToolDownloader");
if (foundWindow != null)
{
_instance = (ToolDownloader) foundWindow;
}
else
{
_instance = ScriptableObject.CreateInstance<ToolDownloader>();
}
_instance.titleContent.text = "Sidekick Tool Downloader";
_instance.minSize = new Vector2(600, 150);
}
/// <summary>
/// Refreshes the Tool Downloader window to ensure it shows the latest version. Repaint is unreliable.
/// </summary>
public static void RefreshWindow()
{
if (_instance == null)
{
CreateToolInstance();
}
_instance.Close();
if (_instance == null)
{
CreateToolInstance();
}
_instance.Show();
}
[MenuItem("Synty/Sidekick Tool Downloader")]
public static void ShowToolDownloaderWindow()
{
if (_instance == null)
{
CreateToolInstance();
}
_instance.Show();
}
}
}
// Copyright (c) 2025 Synty Studios Limited. All rights reserved.
//
// Use of this software is subject to the terms and conditions of the Synty Studios End User Licence Agreement (EULA)
// available at: https://syntystore.com/pages/end-user-licence-agreement
//
// For additional details, see the LICENSE.MD file bundled with this software.
using System;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;
namespace Synty.SidekickCharacters
{
public class ToolDownloader : EditorWindow
{
private const string _GIT_URL = "https://github.com/SyntyStudios/SidekicksToolRelease/releases/latest/download/Sidekicks.unitypackage";
private const string _GIT_DB_URL = "https://github.com/SyntyStudios/SidekicksToolRelease/releases/latest/download/SidekicksDatabase.unitypackage";
private const string _PACKAGE_CACHE = "Assets/DownloadCache/Sidekicks.unitypackage";
private const string _DB_PACKAGE_CACHE = "Assets/DownloadCache/SidekicksDatabase.unitypackage";
private const string _VERSION_FILE = "Assets/External/Models/SidekickCharacters/Scripts/Editor/version.txt";
private const string _VERSION_TAG = "\"tag_name\":";
private const string _VERSION_KEY = "sk_current_tool_version";
private const string _SIDEKICK_TOOL_MENU_ITEM = "Synty/Sidekick Character Tool";
private string _version = "-";
private Label _latestVersion;
public void Awake()
{
BackgroundUpdateCheck();
}
public void CreateGUI()
{
VisualElement root = rootVisualElement;
root.Clear();
Button downloadButton = new Button(DownloadLatestDBVersion)
{
text = "Download and Install",
style =
{
height = 40
}
};
root.Add(downloadButton);
Label textPrompt = new Label("This tool will download and install the latest version of the Sidekicks Tool.");
Label textPrompt2 = new Label("Or you can manually download from this link:\nhttps://github.com/SyntyStudios/SidekicksToolRelease/releases/latest/");
root.Add(textPrompt);
root.Add(textPrompt2);
string version = LoadCurrentInstalledVersion();
Label currentVersion = new Label("Currently Installed: " + (string.IsNullOrEmpty(version) ? "N/A" : version))
{
style =
{
marginTop = 5
}
};
_latestVersion = new Label("Latest Version: " + _version);
root.Add(currentVersion);
root.Add(_latestVersion);
Button changeLogButton = new Button()
{
text = "Show Changelog"
};
root.Add(changeLogButton);
changeLogButton.clickable.clicked += delegate
{
Application.OpenURL("https://syntystore.com/pages/sidekicks-changelog");
};
}
public async void BackgroundUpdateCheck()
{
_version = await CheckAvailableVersion();
if (_latestVersion != null)
{
_latestVersion.text = "Latest Version: " + _version;
}
if (IsNewVersionAvailable(_version))
{
DownloaderBackgroundService.ShowToolDownloaderWindow();
}
}
private async Task<string> CheckAvailableVersion()
{
HttpClient client = new HttpClient();
string uri = "http://api.github.com/repos/SyntyStudios/SidekicksToolRelease/releases/latest";
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, uri);
request.Headers.Add("Accept", "application/vnd.github+json");
request.Headers.Add("X-GitHub-Api-Version", "2022-11-28");
request.Headers.Add("User-Agent", "Sidekicks Download Tool");
HttpResponseMessage response = await client.SendAsync(request);
response.EnsureSuccessStatusCode();
// Read the response content as a string
string responseBody = await response.Content.ReadAsStringAsync();
return GetVersionNumber(responseBody);
}
private string GetVersionNumber(string data)
{
int index = data.IndexOf(_VERSION_TAG, StringComparison.OrdinalIgnoreCase) + _VERSION_TAG.Length;
string portion = data.Substring(index, data.Length - index);
string number = portion.Substring(0, portion.IndexOf(',')).Replace("\"", "").Replace(" ", "");
return number;
}
private bool IsNewVersionAvailable(string version)
{
string currentVersion = LoadCurrentInstalledVersion();
if (string.IsNullOrEmpty(currentVersion))
{
return true;
}
if (!currentVersion.Contains('.') || !version.Contains('.'))
{
return false;
}
string[] currentSplitVersion = currentVersion.Split('.');
string[] newSplitVersion = version.Split('.');
if (currentSplitVersion.Length != newSplitVersion.Length)
{
return false;
}
for (int i = 0; i < newSplitVersion.Length; i++)
{
if (int.TryParse(currentSplitVersion[i], out int current))
{
if (int.TryParse(newSplitVersion[i], out int newVersion))
{
if (newVersion > current)
{
return true;
}
}
}
}
return false;
}
private void SaveCurrentInstalledVersion(string version)
{
File.WriteAllText(_VERSION_FILE, version);
}
private string LoadCurrentInstalledVersion()
{
if (File.Exists(_VERSION_FILE))
{
return File.ReadAllText(_VERSION_FILE);
}
return null;
}
private void DownloadLatestDBVersion()
{
WebClient client = new WebClient();
client.DownloadFileCompleted += (sender, e) =>
{
if (e.Error == null)
{
CloseOpenToolWindow();
AssetDatabase.ImportPackage(_DB_PACKAGE_CACHE, false);
AssetDatabase.importPackageCompleted += ProceedWithInstall;
}
else
{
Debug.LogError("Error downloading file: " + e.Error.Message);
}
};
// Ensure the directory exists
string directory = Path.GetDirectoryName(_DB_PACKAGE_CACHE);
if (!Directory.Exists(directory))
{
Directory.CreateDirectory(directory);
}
client.DownloadFileAsync(new System.Uri(_GIT_DB_URL), _DB_PACKAGE_CACHE);
}
private async void DownloadLatestToolVersion()
{
WebClient client = new WebClient();
_version = await CheckAvailableVersion();
client.DownloadFileCompleted += (sender, e) =>
{
if (e.Error == null)
{
SaveCurrentInstalledVersion(_version);
AssetDatabase.ImportPackage(_PACKAGE_CACHE, false);
AssetDatabase.importPackageCompleted += ProceedWithInstall;
}
else
{
Debug.LogError("Error downloading file: " + e.Error.Message);
}
};
// Ensure the directory exists
string directory = Path.GetDirectoryName(_PACKAGE_CACHE);
if (!Directory.Exists(directory))
{
Directory.CreateDirectory(directory);
}
client.DownloadFileAsync(new System.Uri(_GIT_URL), _PACKAGE_CACHE);
}
private void ProceedWithInstall(string packageName)
{
if (packageName == "SidekicksDatabase")
{
AssetDatabase.importPackageCompleted -= ProceedWithInstall;
DownloadLatestToolVersion();
}
else if (packageName == "Sidekicks")
{
AssetDatabase.importPackageCompleted -= ProceedWithInstall;
DownloaderBackgroundService.RefreshWindow();
if (EditorUtility.DisplayDialog("Installation Finished", "Sidekick Tool installation has completed.", "Re-open Sidekicks Tool",
"Close"))
{
ReopenToolWindow();
}
}
}
private bool CloseOpenToolWindow()
{
EditorWindow[] allWindows = Resources.FindObjectsOfTypeAll<EditorWindow>();
// Filter the windows to find the one with the desired type name
EditorWindow foundWindow = allWindows.FirstOrDefault(window => window.GetType().Name == "ModularCharacterWindow");
if (foundWindow != null)
{
foundWindow.Close();
Thread.Sleep(1500);
return true;
}
return false;
}
private void ReopenToolWindow()
{
try
{
EditorApplication.ExecuteMenuItem(_SIDEKICK_TOOL_MENU_ITEM);
}
catch (Exception ex)
{
Debug.LogWarning("Sidekicks Tool menu item not found. Please verify installation.");
Debug.LogWarning("Exception details: " + ex.Message);
}
}
}
/// <summary>
/// Creates an instance of the Downloader Tool, to allow checks for new versions on editor startup.
/// </summary>
[InitializeOnLoad]
public static class DownloaderBackgroundService
{
private static ToolDownloader _instance;
static DownloaderBackgroundService()
{
EditorApplication.update += CreateToolInstance;
}
static void CreateToolInstance()
{
EditorApplication.update -= CreateToolInstance;
EditorWindow[] allWindows = Resources.FindObjectsOfTypeAll<EditorWindow>();
// Filter the windows to find the one with the desired type name
EditorWindow foundWindow = allWindows.FirstOrDefault(window => window.GetType().Name == "ToolDownloader");
if (foundWindow != null)
{
_instance = (ToolDownloader) foundWindow;
}
else
{
_instance = ScriptableObject.CreateInstance<ToolDownloader>();
}
_instance.titleContent.text = "Sidekick Tool Downloader";
_instance.minSize = new Vector2(600, 150);
}
/// <summary>
/// Refreshes the Tool Downloader window to ensure it shows the latest version. Repaint is unreliable.
/// </summary>
public static void RefreshWindow()
{
if (_instance == null)
{
CreateToolInstance();
}
_instance.Close();
if (_instance == null)
{
CreateToolInstance();
}
_instance.Show();
}
[MenuItem("Synty/Sidekick Tool Downloader")]
public static void ShowToolDownloaderWindow()
{
if (_instance == null)
{
CreateToolInstance();
}
_instance.Show();
}
}
}

View File

@@ -1 +1 @@
1.0.37
1.0.38

View File

@@ -230,42 +230,6 @@ namespace Synty.SidekickCharacters.API
await runtime.PopulatePresetLibrary();
}
private static List<string> GetSidekickPartFiles()
{
string packageRootPath = DatabaseManager.GetPackageRootAbsolutePath();
if (!string.IsNullOrEmpty(packageRootPath))
{
string meshesRootPath = Path.Combine(packageRootPath, "Resources", "Meshes");
if (Directory.Exists(meshesRootPath))
{
return Directory
.GetFiles(meshesRootPath, "SK_*_*_*_*_*.fbx", SearchOption.AllDirectories)
.Select(ToAssetPath)
.ToList();
}
}
return Directory.GetFiles("Assets", "SK_*_*_*_*_*.fbx", SearchOption.AllDirectories).ToList();
}
private static string ToAssetPath(string fullPath)
{
if (string.IsNullOrWhiteSpace(fullPath))
{
return fullPath;
}
string normalizedFullPath = fullPath.Replace('\\', '/');
string normalizedAssetsPath = Application.dataPath.Replace('\\', '/');
if (!normalizedFullPath.StartsWith(normalizedAssetsPath, StringComparison.OrdinalIgnoreCase))
{
return normalizedFullPath;
}
return "Assets" + normalizedFullPath.Substring(normalizedAssetsPath.Length);
}
/// <summary>
/// Takes all the parts selected in the window, and combines them into a single model in the scene.
/// </summary>
@@ -548,7 +512,7 @@ namespace Synty.SidekickCharacters.API
_partOutfitToggleMap = new Dictionary<string, bool>();
_partCount = 0;
List<string> files = GetSidekickPartFiles();
List<string> files = Directory.GetFiles("Assets", "SK_*_*_*_*_*.fbx", SearchOption.AllDirectories).ToList();
foreach (CharacterPartType partType in Enum.GetValues(typeof(CharacterPartType)))
{
@@ -646,7 +610,7 @@ namespace Synty.SidekickCharacters.API
_speciesDictionary = new Dictionary<string, SidekickSpecies>();
_partCount = 0;
List<string> files = GetSidekickPartFiles();
List<string> files = Directory.GetFiles("Assets", "SK_*_*_*_*_*.fbx", SearchOption.AllDirectories).ToList();
Dictionary<string, string> filesOnDisk = new Dictionary<string, string>();
foreach (string file in files)
{

File diff suppressed because it is too large Load Diff

View File

@@ -1,11 +1,11 @@
fileFormatVersion: 2
guid: 37c1c136edf8d3744be383c6fac071a8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 37c1c136edf8d3744be383c6fac071a8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,347 +1,347 @@
// Copyright (c) 2024 Synty Studios Limited. All rights reserved.
//
// Use of this software is subject to the terms and conditions of the Synty Studios End User Licence Agreement (EULA)
// available at: https://syntystore.com/pages/end-user-licence-agreement
//
// For additional details, see the LICENSE.MD file bundled with this software.
using SQLite;
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UIElements;
namespace Synty.SidekickCharacters.Database.DTO
{
[Table("sk_color_row")]
public class SidekickColorRow
{
private SidekickColorSet _colorSet;
private SidekickColorProperty _colorProperty;
private Color? _niceColor;
private Color? _niceMetallic;
private Color? _niceSmoothness;
private Color? _niceReflection;
private Color? _niceEmission;
private Color? _niceOpacity;
[PrimaryKey, AutoIncrement, Column("id")]
public int ID { get; set; }
[Column("ptr_color_set")]
public int PtrColorSet { get; set; }
[Column("ptr_color_property")]
public int PtrColorProperty { get; set; }
[Column("color")]
public string MainColor { get; set; }
[Column("metallic")]
public string Metallic { get; set; }
[Column("smoothness")]
public string Smoothness { get; set; }
[Column("reflection")]
public string Reflection { get; set; }
[Column("emission")]
public string Emission { get; set; }
[Column("opacity")]
public string Opacity { get; set; }
[Ignore]
public SidekickColorSet ColorSet
{
get => _colorSet;
set
{
_colorSet = value;
PtrColorSet = value.ID;
}
}
[Ignore]
public SidekickColorProperty ColorProperty
{
get => _colorProperty;
set
{
_colorProperty = value;
PtrColorProperty = value.ID;
}
}
[Ignore]
public Color NiceColor
{
get
{
_niceColor ??= ColorUtility.TryParseHtmlString("#" + MainColor, out Color color) ? color : Color.white;
return (Color) _niceColor;
}
set
{
_niceColor = value;
MainColor = ColorUtility.ToHtmlStringRGB(value);
}
}
[Ignore]
public Color NiceMetallic
{
get
{
_niceMetallic ??= ColorUtility.TryParseHtmlString("#" + Metallic, out Color color) ? color : Color.white;
return (Color) _niceMetallic;
}
set
{
_niceMetallic = value;
Metallic = ColorUtility.ToHtmlStringRGB(value);
}
}
[Ignore]
public Color NiceSmoothness
{
get
{
_niceSmoothness ??= ColorUtility.TryParseHtmlString("#" + Smoothness, out Color color) ? color : Color.white;
return (Color) _niceSmoothness;
}
set
{
_niceSmoothness = value;
Smoothness = ColorUtility.ToHtmlStringRGB(value);
}
}
[Ignore]
public Color NiceReflection
{
get
{
_niceReflection ??= ColorUtility.TryParseHtmlString("#" + Reflection, out Color color) ? color : Color.white;
return (Color) _niceReflection;
}
set
{
_niceReflection = value;
Reflection = ColorUtility.ToHtmlStringRGB(value);
}
}
[Ignore]
public Color NiceEmission
{
get
{
_niceEmission ??= ColorUtility.TryParseHtmlString("#" + Emission, out Color color) ? color : Color.white;
return (Color) _niceEmission;
}
set
{
_niceEmission = value;
Emission = ColorUtility.ToHtmlStringRGB(value);
}
}
[Ignore]
public Color NiceOpacity
{
get
{
_niceOpacity ??= ColorUtility.TryParseHtmlString("#" + Opacity, out Color color) ? color : Color.white;
return (Color) _niceOpacity;
}
set
{
_niceOpacity = value;
Opacity = ColorUtility.ToHtmlStringRGB(value);
}
}
[Ignore]
public bool IsLocked { get; set; }
[Ignore]
public Image ButtonImage { get; set; }
/// <summary>
/// Gets a list of all the Color Rows in the database.
/// </summary>
/// <param name="dbManager">The Database Manager to use.</param>
/// <returns>A list of all Color Rows in the database.</returns>
public static List<SidekickColorRow> GetAll(DatabaseManager dbManager)
{
List<SidekickColorRow> rows = dbManager.GetCurrentDbConnection().Table<SidekickColorRow>().ToList();
foreach (SidekickColorRow row in rows)
{
Decorate(dbManager, row);
}
return rows;
}
/// <summary>
/// Gets a specific Color Row by its database ID.
/// </summary>
/// <param name="dbManager">The Database Manager to use.</param>
/// <param name="id">The id of the required Color Row.</param>
/// <returns>The specific Color Row if it exists; otherwise null.</returns>
public static SidekickColorRow GetByID(DatabaseManager dbManager, int id)
{
SidekickColorRow row = dbManager.GetCurrentDbConnection().Find<SidekickColorRow>(id);
Decorate(dbManager, row);
return row;
}
/// <summary>
/// Gets a list of all the Color Rows in the database that have the matching Property.
/// </summary>
/// <param name="dbManager">The Database Manager to use.</param>
/// <param name="property">The property to get all the color rows for.</param>
/// <returns>A list of all color rows in the database for the given property.</returns>
public static List<SidekickColorRow> GetAllByProperty(DatabaseManager dbManager, SidekickColorProperty property)
{
List<SidekickColorRow> rows = dbManager.GetCurrentDbConnection().Table<SidekickColorRow>()
.Where(row => row.PtrColorProperty == property.ID)
.ToList();
foreach (SidekickColorRow row in rows)
{
row.ColorProperty = property;
Decorate(dbManager, row);
}
return rows;
}
/// <summary>
/// Gets a list of all the Color Rows in the database that have the matching Set and Property.
/// </summary>
/// <param name="dbManager">The Database Manager to use.</param>
/// <param name="set">The color set to get the color rows for.</param>
/// <param name="property">The property to get all the color rows for.</param>
/// <returns>A list of all color rows in the database for the given set and property.</returns>
public static List<SidekickColorRow> GetAllBySetAndProperty(DatabaseManager dbManager, SidekickColorSet set, SidekickColorProperty property)
{
List<SidekickColorRow> rows = dbManager.GetCurrentDbConnection().Table<SidekickColorRow>()
.Where(row => row.PtrColorSet == set.ID && row.PtrColorProperty == property.ID)
.ToList();
foreach (SidekickColorRow row in rows)
{
row.ColorSet = set;
row.ColorProperty = property;
Decorate(dbManager, row);
}
return rows;
}
/// <summary>
/// Gets a list of all the Color Rows in the database that have the matching Set.
/// </summary>
/// <param name="dbManager">The Database Manager to use.</param>
/// <param name="set">The color set to get the color rows for.</param>
/// <returns>A list of all color rows in the database for the given set.</returns>
public static List<SidekickColorRow> GetAllBySet(DatabaseManager dbManager, SidekickColorSet set)
{
List<SidekickColorRow> rows = dbManager.GetCurrentDbConnection().Table<SidekickColorRow>()
.Where(row => row.PtrColorSet == set.ID)
.ToList();
foreach (SidekickColorRow row in rows)
{
row.ColorSet = set;
Decorate(dbManager, row);
}
return rows;
}
/// <summary>
/// Creates a SidekickColorRow from a SidekickColorPresetRow.
/// </summary>
/// <param name="row">The SidekickColorPresetRow to convert.</param>
/// <returns>A SidekickColorRow created from a SidekickColorPresetRow.</returns>
public static SidekickColorRow CreateFromPresetColorRow(SidekickColorPresetRow row)
{
SidekickColorRow newRow = new SidekickColorRow()
{
MainColor = row.MainColor,
Emission = row.Emission,
Metallic = row.Metallic,
Opacity = row.Opacity,
Reflection = row.Reflection,
Smoothness = row.Smoothness,
ColorProperty = row.ColorProperty
};
return newRow;
}
/// <summary>
/// Ensures that the given row has its nice DTO class properties set
/// </summary>
/// <param name="dbManager">The Database Manager to use.</param>
/// <param name="row">The color row to decorate</param>
/// <returns>A color row with all DTO class properties set</returns>
private static void Decorate(DatabaseManager dbManager, SidekickColorRow row)
{
// don't need PtrColorProperty check as should always be >= 0; if it's not, we have bad data and want the error
row.ColorProperty ??= SidekickColorProperty.GetByID(dbManager, row.PtrColorProperty);
if (row.ColorSet == null && row.PtrColorSet >= 0)
{
row.ColorSet = SidekickColorSet.GetByID(dbManager, row.PtrColorSet);
}
}
/// <summary>
/// Delete this color row from the database.
/// </summary>
/// <param name="dbManager">The Database Manager to use.</param>
public void Delete(DatabaseManager dbManager)
{
int deletedCount = dbManager.GetCurrentDbConnection().Delete<SidekickColorRow>(ID);
if (deletedCount == 0)
{
throw new Exception($"Could not delete color set with ID '{ID}'");
}
}
/// <summary>
/// Inserts, or updates the values in the database, depending on this object has been saved before or not.
/// </summary>
/// <param name="dbManager">The Database Manager to use.</param>
public void Save(DatabaseManager dbManager)
{
if (ID < 0)
{
SaveToDB(dbManager);
}
else
{
UpdateDB(dbManager);
}
}
/// <summary>
/// Saves this Color Set to the database with the current values.
/// </summary>
/// <param name="dbManager">The Database Manager to use.</param>
private void SaveToDB(DatabaseManager dbManager)
{
SQLiteConnection connection = dbManager.GetCurrentDbConnection();
int insertCount = connection.Insert(this);
if (insertCount == 0)
{
throw new Exception("Unable to save current color row");
}
// in theory this could return a different ID, but in practice it's highly unlikely
ID = (int) SQLite3.LastInsertRowid(connection.Handle);
}
/// <summary>
/// Updates this Color Set in the database with the current values.
/// </summary>
/// <param name="dbManager">The Database Manager to use.</param>
private void UpdateDB(DatabaseManager dbManager)
{
int updatedCount = dbManager.GetCurrentDbConnection().Update(this);
if (updatedCount == 0)
{
throw new Exception($"Could not update color row with ID '{ID}'");
}
}
}
}
// Copyright (c) 2024 Synty Studios Limited. All rights reserved.
//
// Use of this software is subject to the terms and conditions of the Synty Studios End User Licence Agreement (EULA)
// available at: https://syntystore.com/pages/end-user-licence-agreement
//
// For additional details, see the LICENSE.MD file bundled with this software.
using SQLite;
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UIElements;
namespace Synty.SidekickCharacters.Database.DTO
{
[Table("sk_color_row")]
public class SidekickColorRow
{
private SidekickColorSet _colorSet;
private SidekickColorProperty _colorProperty;
private Color? _niceColor;
private Color? _niceMetallic;
private Color? _niceSmoothness;
private Color? _niceReflection;
private Color? _niceEmission;
private Color? _niceOpacity;
[PrimaryKey, AutoIncrement, Column("id")]
public int ID { get; set; }
[Column("ptr_color_set")]
public int PtrColorSet { get; set; }
[Column("ptr_color_property")]
public int PtrColorProperty { get; set; }
[Column("color")]
public string MainColor { get; set; }
[Column("metallic")]
public string Metallic { get; set; }
[Column("smoothness")]
public string Smoothness { get; set; }
[Column("reflection")]
public string Reflection { get; set; }
[Column("emission")]
public string Emission { get; set; }
[Column("opacity")]
public string Opacity { get; set; }
[Ignore]
public SidekickColorSet ColorSet
{
get => _colorSet;
set
{
_colorSet = value;
PtrColorSet = value.ID;
}
}
[Ignore]
public SidekickColorProperty ColorProperty
{
get => _colorProperty;
set
{
_colorProperty = value;
PtrColorProperty = value.ID;
}
}
[Ignore]
public Color NiceColor
{
get
{
_niceColor ??= ColorUtility.TryParseHtmlString("#" + MainColor, out Color color) ? color : Color.white;
return (Color) _niceColor;
}
set
{
_niceColor = value;
MainColor = ColorUtility.ToHtmlStringRGB(value);
}
}
[Ignore]
public Color NiceMetallic
{
get
{
_niceMetallic ??= ColorUtility.TryParseHtmlString("#" + Metallic, out Color color) ? color : Color.white;
return (Color) _niceMetallic;
}
set
{
_niceMetallic = value;
Metallic = ColorUtility.ToHtmlStringRGB(value);
}
}
[Ignore]
public Color NiceSmoothness
{
get
{
_niceSmoothness ??= ColorUtility.TryParseHtmlString("#" + Smoothness, out Color color) ? color : Color.white;
return (Color) _niceSmoothness;
}
set
{
_niceSmoothness = value;
Smoothness = ColorUtility.ToHtmlStringRGB(value);
}
}
[Ignore]
public Color NiceReflection
{
get
{
_niceReflection ??= ColorUtility.TryParseHtmlString("#" + Reflection, out Color color) ? color : Color.white;
return (Color) _niceReflection;
}
set
{
_niceReflection = value;
Reflection = ColorUtility.ToHtmlStringRGB(value);
}
}
[Ignore]
public Color NiceEmission
{
get
{
_niceEmission ??= ColorUtility.TryParseHtmlString("#" + Emission, out Color color) ? color : Color.white;
return (Color) _niceEmission;
}
set
{
_niceEmission = value;
Emission = ColorUtility.ToHtmlStringRGB(value);
}
}
[Ignore]
public Color NiceOpacity
{
get
{
_niceOpacity ??= ColorUtility.TryParseHtmlString("#" + Opacity, out Color color) ? color : Color.white;
return (Color) _niceOpacity;
}
set
{
_niceOpacity = value;
Opacity = ColorUtility.ToHtmlStringRGB(value);
}
}
[Ignore]
public bool IsLocked { get; set; }
[Ignore]
public Image ButtonImage { get; set; }
/// <summary>
/// Gets a list of all the Color Rows in the database.
/// </summary>
/// <param name="dbManager">The Database Manager to use.</param>
/// <returns>A list of all Color Rows in the database.</returns>
public static List<SidekickColorRow> GetAll(DatabaseManager dbManager)
{
List<SidekickColorRow> rows = dbManager.GetCurrentDbConnection().Table<SidekickColorRow>().ToList();
foreach (SidekickColorRow row in rows)
{
Decorate(dbManager, row);
}
return rows;
}
/// <summary>
/// Gets a specific Color Row by its database ID.
/// </summary>
/// <param name="dbManager">The Database Manager to use.</param>
/// <param name="id">The id of the required Color Row.</param>
/// <returns>The specific Color Row if it exists; otherwise null.</returns>
public static SidekickColorRow GetByID(DatabaseManager dbManager, int id)
{
SidekickColorRow row = dbManager.GetCurrentDbConnection().Find<SidekickColorRow>(id);
Decorate(dbManager, row);
return row;
}
/// <summary>
/// Gets a list of all the Color Rows in the database that have the matching Property.
/// </summary>
/// <param name="dbManager">The Database Manager to use.</param>
/// <param name="property">The property to get all the color rows for.</param>
/// <returns>A list of all color rows in the database for the given property.</returns>
public static List<SidekickColorRow> GetAllByProperty(DatabaseManager dbManager, SidekickColorProperty property)
{
List<SidekickColorRow> rows = dbManager.GetCurrentDbConnection().Table<SidekickColorRow>()
.Where(row => row.PtrColorProperty == property.ID)
.ToList();
foreach (SidekickColorRow row in rows)
{
row.ColorProperty = property;
Decorate(dbManager, row);
}
return rows;
}
/// <summary>
/// Gets a list of all the Color Rows in the database that have the matching Set and Property.
/// </summary>
/// <param name="dbManager">The Database Manager to use.</param>
/// <param name="set">The color set to get the color rows for.</param>
/// <param name="property">The property to get all the color rows for.</param>
/// <returns>A list of all color rows in the database for the given set and property.</returns>
public static List<SidekickColorRow> GetAllBySetAndProperty(DatabaseManager dbManager, SidekickColorSet set, SidekickColorProperty property)
{
List<SidekickColorRow> rows = dbManager.GetCurrentDbConnection().Table<SidekickColorRow>()
.Where(row => row.PtrColorSet == set.ID && row.PtrColorProperty == property.ID)
.ToList();
foreach (SidekickColorRow row in rows)
{
row.ColorSet = set;
row.ColorProperty = property;
Decorate(dbManager, row);
}
return rows;
}
/// <summary>
/// Gets a list of all the Color Rows in the database that have the matching Set.
/// </summary>
/// <param name="dbManager">The Database Manager to use.</param>
/// <param name="set">The color set to get the color rows for.</param>
/// <returns>A list of all color rows in the database for the given set.</returns>
public static List<SidekickColorRow> GetAllBySet(DatabaseManager dbManager, SidekickColorSet set)
{
List<SidekickColorRow> rows = dbManager.GetCurrentDbConnection().Table<SidekickColorRow>()
.Where(row => row.PtrColorSet == set.ID)
.ToList();
foreach (SidekickColorRow row in rows)
{
row.ColorSet = set;
Decorate(dbManager, row);
}
return rows;
}
/// <summary>
/// Creates a SidekickColorRow from a SidekickColorPresetRow.
/// </summary>
/// <param name="row">The SidekickColorPresetRow to convert.</param>
/// <returns>A SidekickColorRow created from a SidekickColorPresetRow.</returns>
public static SidekickColorRow CreateFromPresetColorRow(SidekickColorPresetRow row)
{
SidekickColorRow newRow = new SidekickColorRow()
{
MainColor = row.MainColor,
Emission = row.Emission,
Metallic = row.Metallic,
Opacity = row.Opacity,
Reflection = row.Reflection,
Smoothness = row.Smoothness,
ColorProperty = row.ColorProperty
};
return newRow;
}
/// <summary>
/// Ensures that the given row has its nice DTO class properties set
/// </summary>
/// <param name="dbManager">The Database Manager to use.</param>
/// <param name="row">The color row to decorate</param>
/// <returns>A color row with all DTO class properties set</returns>
private static void Decorate(DatabaseManager dbManager, SidekickColorRow row)
{
// don't need PtrColorProperty check as should always be >= 0; if it's not, we have bad data and want the error
row.ColorProperty ??= SidekickColorProperty.GetByID(dbManager, row.PtrColorProperty);
if (row.ColorSet == null && row.PtrColorSet >= 0)
{
row.ColorSet = SidekickColorSet.GetByID(dbManager, row.PtrColorSet);
}
}
/// <summary>
/// Delete this color row from the database.
/// </summary>
/// <param name="dbManager">The Database Manager to use.</param>
public void Delete(DatabaseManager dbManager)
{
int deletedCount = dbManager.GetCurrentDbConnection().Delete<SidekickColorRow>(ID);
if (deletedCount == 0)
{
throw new Exception($"Could not delete color set with ID '{ID}'");
}
}
/// <summary>
/// Inserts, or updates the values in the database, depending on this object has been saved before or not.
/// </summary>
/// <param name="dbManager">The Database Manager to use.</param>
public void Save(DatabaseManager dbManager)
{
if (ID < 0)
{
SaveToDB(dbManager);
}
else
{
UpdateDB(dbManager);
}
}
/// <summary>
/// Saves this Color Set to the database with the current values.
/// </summary>
/// <param name="dbManager">The Database Manager to use.</param>
private void SaveToDB(DatabaseManager dbManager)
{
SQLiteConnection connection = dbManager.GetCurrentDbConnection();
int insertCount = connection.Insert(this);
if (insertCount == 0)
{
throw new Exception("Unable to save current color row");
}
// in theory this could return a different ID, but in practice it's highly unlikely
ID = (int) SQLite3.LastInsertRowid(connection.Handle);
}
/// <summary>
/// Updates this Color Set in the database with the current values.
/// </summary>
/// <param name="dbManager">The Database Manager to use.</param>
private void UpdateDB(DatabaseManager dbManager)
{
int updatedCount = dbManager.GetCurrentDbConnection().Update(this);
if (updatedCount == 0)
{
throw new Exception($"Could not update color row with ID '{ID}'");
}
}
}
}

View File

@@ -154,18 +154,6 @@ namespace Synty.SidekickCharacters.Database.DTO
/// <returns>A color set with all DTO class properties set</returns>
private static void Decorate(DatabaseManager dbManager, SidekickColorSet set)
{
if (set == null)
{
return;
}
set.SourceColorPath = DatabaseManager.NormalizeLegacyAssetPath(set.SourceColorPath);
set.SourceMetallicPath = DatabaseManager.NormalizeLegacyAssetPath(set.SourceMetallicPath);
set.SourceSmoothnessPath = DatabaseManager.NormalizeLegacyAssetPath(set.SourceSmoothnessPath);
set.SourceReflectionPath = DatabaseManager.NormalizeLegacyAssetPath(set.SourceReflectionPath);
set.SourceEmissionPath = DatabaseManager.NormalizeLegacyAssetPath(set.SourceEmissionPath);
set.SourceOpacityPath = DatabaseManager.NormalizeLegacyAssetPath(set.SourceOpacityPath);
if (set.Species == null && set.PtrSpecies >= 0)
{
set.Species = SidekickSpecies.GetByID(dbManager, set.PtrSpecies);

View File

@@ -222,8 +222,6 @@ namespace Synty.SidekickCharacters.Database.DTO
{
if (part != null)
{
part.Location = DatabaseManager.NormalizeLegacyAssetPath(part.Location);
if (part.Species == null && part.PtrSpecies >= 0)
{
part.Species = SidekickSpecies.GetByID(dbManager, part.PtrSpecies);

View File

@@ -1,285 +1,285 @@
// Copyright (c) 2024 Synty Studios Limited. All rights reserved.
//
// Use of this software is subject to the terms and conditions of the Synty Studios End User Licence Agreement (EULA)
// available at: https://syntystore.com/pages/end-user-licence-agreement
//
// For additional details, see the LICENSE.MD file bundled with this software.
using SQLite;
using Synty.SidekickCharacters.Enums;
using Synty.SidekickCharacters.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Synty.SidekickCharacters.Database.DTO
{
[Table("sk_part_preset")]
public class SidekickPartPreset
{
private SidekickSpecies _species;
[PrimaryKey]
[AutoIncrement]
[Column("id")]
public int ID { get; set; }
[Column("name")]
public string Name { get; set; }
[Column("part_group")]
public PartGroup PartGroup { get; set; }
[Column("ptr_species")]
public int PtrSpecies { get; set; }
[Column("outfit")]
public string Outfit { get; set; }
[Ignore]
public SidekickSpecies Species
{
get => _species;
set
{
_species = value;
PtrSpecies = value.ID;
}
}
/// <summary>
/// Gets a specific Preset by its database ID.
/// </summary>
/// <param name="dbManager">The Database Manager to use.</param>
/// <param name="id">The id of the required Preset.</param>
/// <returns>The specific Preset if it exists; otherwise null.</returns>
public static SidekickPartPreset GetByID(DatabaseManager dbManager, int id)
{
SidekickPartPreset partPreset = dbManager.GetCurrentDbConnection().Find<SidekickPartPreset>(id);
Decorate(dbManager, partPreset);
return partPreset;
}
/// <summary>
/// Gets a list of all the Presets in the database.
/// </summary>
/// <param name="dbManager">The Database Manager to use.</param>
/// <returns>A list of all presets in the database.</returns>
public static List<SidekickPartPreset> GetAll(DatabaseManager dbManager)
{
List<SidekickPartPreset> partPresets = dbManager.GetCurrentDbConnection().Table<SidekickPartPreset>().ToList();
foreach (SidekickPartPreset partPreset in partPresets)
{
Decorate(dbManager, partPreset);
}
return partPresets;
}
/// <summary>
/// Gets a list of all the Part Presets in the database that have the matching species.
/// </summary>
/// <param name="dbManager">The Database Manager to use.</param>
/// <param name="species">The species to get all the part presets for.</param>
/// <returns>A list of all part presets in the database for the given species.</returns>
public static List<SidekickPartPreset> GetAllBySpecies(DatabaseManager dbManager, SidekickSpecies species)
{
List<SidekickPartPreset> partPresets = dbManager.GetCurrentDbConnection().Table<SidekickPartPreset>()
.Where(partPreset => partPreset.PtrSpecies == species.ID)
.ToList();
foreach (SidekickPartPreset partPreset in partPresets)
{
partPreset.Species = species;
}
return partPresets;
}
/// <summary>
/// Gets a Part Presets in the database with the matching name if one exists.
/// </summary>
/// <param name="dbManager">The Database Manager to use.</param>
/// <param name="name">The name of the preset to retrieve.</param>
/// <returns>Returns a Part Presets in the database with the matching name if one exists; otherwise null.</returns>
public static SidekickPartPreset GetByName(DatabaseManager dbManager, string name)
{
SidekickPartPreset partPreset = dbManager.GetCurrentDbConnection()
.Table<SidekickPartPreset>()
.FirstOrDefault(partPreset => partPreset.Name == name);
if (partPreset != null)
{
Decorate(dbManager, partPreset);
}
return partPreset;
}
/// <summary>
/// Gets a list of all the Part Presets in the database that have the matching species and part group.
/// </summary>
/// <param name="dbManager">The Database Manager to use.</param>
/// <param name="partGroup">The part group to filter search by.</param>
/// <returns>A list of all part presets in the database for the given species and part group.</returns>
public static List<SidekickPartPreset> GetAllByGroup(DatabaseManager dbManager, PartGroup partGroup, bool excludeMissingParts = true)
{
List<SidekickPartPreset> partPresets = dbManager.GetCurrentDbConnection().Table<SidekickPartPreset>()
.Where(partPreset => partPreset.PartGroup == partGroup)
.ToList();
foreach (SidekickPartPreset partPreset in partPresets)
{
Decorate(dbManager, partPreset);
}
if (excludeMissingParts)
{
List<SidekickPartPreset> toRemove = new List<SidekickPartPreset>();
foreach (SidekickPartPreset partPreset in partPresets)
{
if (!partPreset.HasAllPartsAvailable(dbManager))
{
toRemove.Add(partPreset);
}
}
partPresets.RemoveAll(preset => toRemove.Contains(preset));
}
return partPresets;
}
/// <summary>
/// Gets a list of all the Part Presets in the database that have the matching species and part group.
/// </summary>
/// <param name="dbManager">The Database Manager to use.</param>
/// <param name="species">The species to get all the part presets for.</param>
/// <param name="partGroup">The part group to filter search by.</param>
/// <returns>A list of all part presets in the database for the given species and part group.</returns>
public static List<SidekickPartPreset> GetAllBySpeciesAndGroup(DatabaseManager dbManager, SidekickSpecies species, PartGroup partGroup)
{
List<SidekickPartPreset> partPresets = dbManager.GetCurrentDbConnection().Table<SidekickPartPreset>()
.Where(partPreset => partPreset.PtrSpecies == species.ID && partPreset.PartGroup == partGroup)
.ToList();
foreach (SidekickPartPreset partPreset in partPresets)
{
partPreset.Species = species;
}
return partPresets;
}
/// <summary>
/// Ensures that the given set has its nice DTO class properties set
/// </summary>
/// <param name="dbManager">The Database Manager to use.</param>
/// <param name="partPreset">The color set to decorate</param>
/// <returns>A color set with all DTO class properties set</returns>
private static void Decorate(DatabaseManager dbManager, SidekickPartPreset partPreset)
{
if (partPreset.Species == null && partPreset.PtrSpecies >= 0)
{
partPreset.Species = SidekickSpecies.GetByID(dbManager, partPreset.PtrSpecies);
}
}
/// <summary>
/// Updates or Inserts this item in the Database.
/// </summary>
/// <param name="dbManager">The database manager to use.</param>
public int Save(DatabaseManager dbManager)
{
if (ID < 0)
{
dbManager.GetCurrentDbConnection().Insert(this);
// in theory this could return a different ID, but in practice it's highly unlikely
ID = (int) SQLite3.LastInsertRowid(dbManager.GetCurrentDbConnection().Handle);
}
dbManager.GetCurrentDbConnection().Update(this);
return ID;
}
/// <summary>
/// Deletes this item from the database
/// </summary>
/// <param name="dbManager">The database manager to use.</param>
public void Delete(DatabaseManager dbManager)
{
foreach (SidekickPartPresetRow row in SidekickPartPresetRow.GetAllByPreset(dbManager, this))
{
row.Delete(dbManager);
}
foreach (SidekickPresetFilterRow row in SidekickPresetFilterRow.GetAllForPreset(dbManager, this))
{
row.Delete(dbManager);
}
SidekickPartPresetImage image = SidekickPartPresetImage.GetByPresetAndPartGroup(dbManager, this, PartGroup);
image?.Delete(dbManager);
dbManager.GetCurrentDbConnection().Delete<SidekickPartPreset>(ID);
}
/// <summary>
/// Determines if all the parts associated with this preset are valid (has a file in the project).
/// </summary>
/// <param name="dbManager">The database manager to use.</param>
/// <returns>True if all parts are valid; otherwise False.</returns>
public bool HasAllPartsAvailable(DatabaseManager dbManager)
{
List<SidekickPartPresetRow> allRows = SidekickPartPresetRow.GetAllByPreset(dbManager, this);
return allRows.Count > 0 && allRows.All(row => row.HasValidPart());
}
/// <summary>
/// Determines if all the parts associated with this preset are valid (has a file in the project).
/// </summary>
/// <param name="dbManager">The database manager to use.</param>
/// <returns>True if all parts are valid; otherwise False.</returns>
public bool HasOnlyBasePartsAndAllAvailable(DatabaseManager dbManager)
{
List<SidekickPartPresetRow> allRows = SidekickPartPresetRow.GetAllByPreset(dbManager, this);
return allRows.Count > 0 && allRows.All(row => row.HasValidPart() && (row.Part == null || PartUtils.IsBaseSpeciesPart(row.PartName)));
}
/// <summary>
/// Checks the equality of this preset to the given preset.
/// </summary>
/// <param name="other">The preset to check equality with.</param>
/// <returns>True if the presets are equal, otherwise false.</returns>
protected bool Equals(SidekickPartPreset other)
{
return ID == other.ID
&& Name == other.Name
&& PartGroup == other.PartGroup
&& PtrSpecies == other.PtrSpecies;
}
/// <inheritdoc cref="Equals"/>
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj))
{
return false;
}
if (ReferenceEquals(this, obj))
{
return true;
}
if (obj.GetType() != this.GetType())
{
return false;
}
return Equals((SidekickPartPreset) obj);
}
/// <inheritdoc cref="GetHashCode"/>
public override int GetHashCode()
{
return HashCode.Combine(ID, Name, (int) PartGroup, PtrSpecies);
}
}
}
// Copyright (c) 2024 Synty Studios Limited. All rights reserved.
//
// Use of this software is subject to the terms and conditions of the Synty Studios End User Licence Agreement (EULA)
// available at: https://syntystore.com/pages/end-user-licence-agreement
//
// For additional details, see the LICENSE.MD file bundled with this software.
using SQLite;
using Synty.SidekickCharacters.Enums;
using Synty.SidekickCharacters.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Synty.SidekickCharacters.Database.DTO
{
[Table("sk_part_preset")]
public class SidekickPartPreset
{
private SidekickSpecies _species;
[PrimaryKey]
[AutoIncrement]
[Column("id")]
public int ID { get; set; }
[Column("name")]
public string Name { get; set; }
[Column("part_group")]
public PartGroup PartGroup { get; set; }
[Column("ptr_species")]
public int PtrSpecies { get; set; }
[Column("outfit")]
public string Outfit { get; set; }
[Ignore]
public SidekickSpecies Species
{
get => _species;
set
{
_species = value;
PtrSpecies = value.ID;
}
}
/// <summary>
/// Gets a specific Preset by its database ID.
/// </summary>
/// <param name="dbManager">The Database Manager to use.</param>
/// <param name="id">The id of the required Preset.</param>
/// <returns>The specific Preset if it exists; otherwise null.</returns>
public static SidekickPartPreset GetByID(DatabaseManager dbManager, int id)
{
SidekickPartPreset partPreset = dbManager.GetCurrentDbConnection().Find<SidekickPartPreset>(id);
Decorate(dbManager, partPreset);
return partPreset;
}
/// <summary>
/// Gets a list of all the Presets in the database.
/// </summary>
/// <param name="dbManager">The Database Manager to use.</param>
/// <returns>A list of all presets in the database.</returns>
public static List<SidekickPartPreset> GetAll(DatabaseManager dbManager)
{
List<SidekickPartPreset> partPresets = dbManager.GetCurrentDbConnection().Table<SidekickPartPreset>().ToList();
foreach (SidekickPartPreset partPreset in partPresets)
{
Decorate(dbManager, partPreset);
}
return partPresets;
}
/// <summary>
/// Gets a list of all the Part Presets in the database that have the matching species.
/// </summary>
/// <param name="dbManager">The Database Manager to use.</param>
/// <param name="species">The species to get all the part presets for.</param>
/// <returns>A list of all part presets in the database for the given species.</returns>
public static List<SidekickPartPreset> GetAllBySpecies(DatabaseManager dbManager, SidekickSpecies species)
{
List<SidekickPartPreset> partPresets = dbManager.GetCurrentDbConnection().Table<SidekickPartPreset>()
.Where(partPreset => partPreset.PtrSpecies == species.ID)
.ToList();
foreach (SidekickPartPreset partPreset in partPresets)
{
partPreset.Species = species;
}
return partPresets;
}
/// <summary>
/// Gets a Part Presets in the database with the matching name if one exists.
/// </summary>
/// <param name="dbManager">The Database Manager to use.</param>
/// <param name="name">The name of the preset to retrieve.</param>
/// <returns>Returns a Part Presets in the database with the matching name if one exists; otherwise null.</returns>
public static SidekickPartPreset GetByName(DatabaseManager dbManager, string name)
{
SidekickPartPreset partPreset = dbManager.GetCurrentDbConnection()
.Table<SidekickPartPreset>()
.FirstOrDefault(partPreset => partPreset.Name == name);
if (partPreset != null)
{
Decorate(dbManager, partPreset);
}
return partPreset;
}
/// <summary>
/// Gets a list of all the Part Presets in the database that have the matching species and part group.
/// </summary>
/// <param name="dbManager">The Database Manager to use.</param>
/// <param name="partGroup">The part group to filter search by.</param>
/// <returns>A list of all part presets in the database for the given species and part group.</returns>
public static List<SidekickPartPreset> GetAllByGroup(DatabaseManager dbManager, PartGroup partGroup, bool excludeMissingParts = true)
{
List<SidekickPartPreset> partPresets = dbManager.GetCurrentDbConnection().Table<SidekickPartPreset>()
.Where(partPreset => partPreset.PartGroup == partGroup)
.ToList();
foreach (SidekickPartPreset partPreset in partPresets)
{
Decorate(dbManager, partPreset);
}
if (excludeMissingParts)
{
List<SidekickPartPreset> toRemove = new List<SidekickPartPreset>();
foreach (SidekickPartPreset partPreset in partPresets)
{
if (!partPreset.HasAllPartsAvailable(dbManager))
{
toRemove.Add(partPreset);
}
}
partPresets.RemoveAll(preset => toRemove.Contains(preset));
}
return partPresets;
}
/// <summary>
/// Gets a list of all the Part Presets in the database that have the matching species and part group.
/// </summary>
/// <param name="dbManager">The Database Manager to use.</param>
/// <param name="species">The species to get all the part presets for.</param>
/// <param name="partGroup">The part group to filter search by.</param>
/// <returns>A list of all part presets in the database for the given species and part group.</returns>
public static List<SidekickPartPreset> GetAllBySpeciesAndGroup(DatabaseManager dbManager, SidekickSpecies species, PartGroup partGroup)
{
List<SidekickPartPreset> partPresets = dbManager.GetCurrentDbConnection().Table<SidekickPartPreset>()
.Where(partPreset => partPreset.PtrSpecies == species.ID && partPreset.PartGroup == partGroup)
.ToList();
foreach (SidekickPartPreset partPreset in partPresets)
{
partPreset.Species = species;
}
return partPresets;
}
/// <summary>
/// Ensures that the given set has its nice DTO class properties set
/// </summary>
/// <param name="dbManager">The Database Manager to use.</param>
/// <param name="partPreset">The color set to decorate</param>
/// <returns>A color set with all DTO class properties set</returns>
private static void Decorate(DatabaseManager dbManager, SidekickPartPreset partPreset)
{
if (partPreset.Species == null && partPreset.PtrSpecies >= 0)
{
partPreset.Species = SidekickSpecies.GetByID(dbManager, partPreset.PtrSpecies);
}
}
/// <summary>
/// Updates or Inserts this item in the Database.
/// </summary>
/// <param name="dbManager">The database manager to use.</param>
public int Save(DatabaseManager dbManager)
{
if (ID < 0)
{
dbManager.GetCurrentDbConnection().Insert(this);
// in theory this could return a different ID, but in practice it's highly unlikely
ID = (int) SQLite3.LastInsertRowid(dbManager.GetCurrentDbConnection().Handle);
}
dbManager.GetCurrentDbConnection().Update(this);
return ID;
}
/// <summary>
/// Deletes this item from the database
/// </summary>
/// <param name="dbManager">The database manager to use.</param>
public void Delete(DatabaseManager dbManager)
{
foreach (SidekickPartPresetRow row in SidekickPartPresetRow.GetAllByPreset(dbManager, this))
{
row.Delete(dbManager);
}
foreach (SidekickPresetFilterRow row in SidekickPresetFilterRow.GetAllForPreset(dbManager, this))
{
row.Delete(dbManager);
}
SidekickPartPresetImage image = SidekickPartPresetImage.GetByPresetAndPartGroup(dbManager, this, PartGroup);
image?.Delete(dbManager);
dbManager.GetCurrentDbConnection().Delete<SidekickPartPreset>(ID);
}
/// <summary>
/// Determines if all the parts associated with this preset are valid (has a file in the project).
/// </summary>
/// <param name="dbManager">The database manager to use.</param>
/// <returns>True if all parts are valid; otherwise False.</returns>
public bool HasAllPartsAvailable(DatabaseManager dbManager)
{
List<SidekickPartPresetRow> allRows = SidekickPartPresetRow.GetAllByPreset(dbManager, this);
return allRows.Count > 0 && allRows.All(row => row.HasValidPart());
}
/// <summary>
/// Determines if all the parts associated with this preset are valid (has a file in the project).
/// </summary>
/// <param name="dbManager">The database manager to use.</param>
/// <returns>True if all parts are valid; otherwise False.</returns>
public bool HasOnlyBasePartsAndAllAvailable(DatabaseManager dbManager)
{
List<SidekickPartPresetRow> allRows = SidekickPartPresetRow.GetAllByPreset(dbManager, this);
return allRows.Count > 0 && allRows.All(row => row.HasValidPart() && (row.Part == null || PartUtils.IsBaseSpeciesPart(row.PartName)));
}
/// <summary>
/// Checks the equality of this preset to the given preset.
/// </summary>
/// <param name="other">The preset to check equality with.</param>
/// <returns>True if the presets are equal, otherwise false.</returns>
protected bool Equals(SidekickPartPreset other)
{
return ID == other.ID
&& Name == other.Name
&& PartGroup == other.PartGroup
&& PtrSpecies == other.PtrSpecies;
}
/// <inheritdoc cref="Equals"/>
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj))
{
return false;
}
if (ReferenceEquals(this, obj))
{
return true;
}
if (obj.GetType() != this.GetType())
{
return false;
}
return Equals((SidekickPartPreset) obj);
}
/// <inheritdoc cref="GetHashCode"/>
public override int GetHashCode()
{
return HashCode.Combine(ID, Name, (int) PartGroup, PtrSpecies);
}
}
}

View File

@@ -12,9 +12,7 @@
using SQLite;
using Synty.SidekickCharacters.Database.DTO;
using System;
using System.IO;
using System.Linq;
using UnityEngine;
namespace Synty.SidekickCharacters.Database
{
@@ -23,18 +21,11 @@ namespace Synty.SidekickCharacters.Database
/// </summary>
public class DatabaseManager
{
private const string _DATABASE_FILE_NAME = "Side_Kick_Data.db";
private const string _LEGACY_PACKAGE_ROOT = "Assets/Synty/SidekickCharacters";
private const string _LEGACY_TOOLS_PACKAGE_ROOT = "Assets/Synty/Tools/SidekickCharacters";
private const string _WORKING_DATABASE_DIRECTORY = "SidekickCharacters";
private static readonly string _DATABASE_PATH = "Assets/External/Models/SidekickCharacters/Database/Side_Kick_Data.db";
private readonly string _CURRENT_VERSION = "1.0.2";
private static SQLiteConnection _connection;
private static int _connectionHash;
private static string _databasePath;
private static string _seedDatabasePath;
private static string _packageRootAbsolutePath;
private static string _packageRootAssetPath;
/// <summary>
/// Gets the DB connection with the given connection details.
@@ -48,13 +39,7 @@ namespace Synty.SidekickCharacters.Database
{
if (_connection == null)
{
string databasePath = GetDatabasePath();
if (string.IsNullOrEmpty(databasePath))
{
throw new FileNotFoundException("Unable to locate Sidekick database file in this Unity project.");
}
_connection = new SQLiteConnection(databasePath, true);
_connection = new SQLiteConnection(_DATABASE_PATH, true);
}
else
{
@@ -115,12 +100,12 @@ namespace Synty.SidekickCharacters.Database
{
Species = new SidekickSpecies { ID = -1, Name = "None" },
Name = "Default",
SourceColorPath = GetPackageAssetPath("Resources", "Textures", "T_ColorMap.png"),
SourceMetallicPath = GetPackageAssetPath("Resources", "Textures", "T_MetallicMap.png"),
SourceSmoothnessPath = GetPackageAssetPath("Resources", "Textures", "T_SmoothnessMap.png"),
SourceReflectionPath = GetPackageAssetPath("Resources", "Textures", "T_ReflectionMap.png"),
SourceEmissionPath = GetPackageAssetPath("Resources", "Textures", "T_EmissionMap.png"),
SourceOpacityPath = GetPackageAssetPath("Resources", "Textures", "T_OpacityMap.png"),
SourceColorPath = "Assets/External/Models/SidekickCharacters/Resources/Textures/T_ColorMap.png",
SourceMetallicPath = "Assets/External/Models/SidekickCharacters/Resources/Textures/T_MetallicMap.png",
SourceSmoothnessPath = "Assets/External/Models/SidekickCharacters/Resources/Textures/T_SmoothnessMap.png",
SourceReflectionPath = "Assets/External/Models/SidekickCharacters/Resources/Textures/T_ReflectionMap.png",
SourceEmissionPath = "Assets/External/Models/SidekickCharacters/Resources/Textures/T_EmissionMap.png",
SourceOpacityPath = "Assets/External/Models/SidekickCharacters/Resources/Textures/T_OpacityMap.png",
};
newSet.Save(this);
@@ -221,216 +206,5 @@ namespace Synty.SidekickCharacters.Database
{
return new Version(GetCurrentDbConnection()?.Table<SidekickDBVersion>().FirstOrDefault().SemanticVersion ?? "0.0.1ea");
}
/// <summary>
/// Gets the absolute filesystem path to the Sidekick database file.
/// </summary>
/// <returns>The absolute path to the DB file, if found.</returns>
public static string GetDatabasePath()
{
if (!string.IsNullOrEmpty(_databasePath) && File.Exists(_databasePath))
{
return _databasePath;
}
string seedDatabasePath = GetSeedDatabasePath();
if (string.IsNullOrEmpty(seedDatabasePath))
{
return null;
}
string projectRoot = Directory.GetParent(Application.dataPath)?.FullName;
if (string.IsNullOrEmpty(projectRoot))
{
return null;
}
string workingDirectory = Path.Combine(projectRoot, "Library", _WORKING_DATABASE_DIRECTORY);
Directory.CreateDirectory(workingDirectory);
_databasePath = Path.Combine(workingDirectory, _DATABASE_FILE_NAME);
if (!File.Exists(_databasePath))
{
File.Copy(seedDatabasePath, _databasePath, false);
}
_databasePath = Path.GetFullPath(_databasePath);
CleanupLegacyDatabaseArtifacts(seedDatabasePath);
return _databasePath;
}
/// <summary>
/// Gets the absolute filesystem path to the Sidekick package root.
/// </summary>
/// <returns>The absolute path to the package root, if found.</returns>
public static string GetPackageRootAbsolutePath()
{
if (!string.IsNullOrEmpty(_packageRootAbsolutePath) && Directory.Exists(_packageRootAbsolutePath))
{
return _packageRootAbsolutePath;
}
string seedDatabasePath = GetSeedDatabasePath();
if (string.IsNullOrEmpty(seedDatabasePath))
{
return null;
}
string databaseDirectory = Path.GetDirectoryName(seedDatabasePath);
if (string.IsNullOrEmpty(databaseDirectory))
{
return null;
}
_packageRootAbsolutePath = Path.GetDirectoryName(databaseDirectory);
if (!string.IsNullOrEmpty(_packageRootAbsolutePath))
{
_packageRootAbsolutePath = Path.GetFullPath(_packageRootAbsolutePath);
}
return _packageRootAbsolutePath;
}
/// <summary>
/// Gets the project-relative asset path to the Sidekick package root.
/// </summary>
/// <returns>The asset path to the package root, if found.</returns>
public static string GetPackageRootAssetPath()
{
if (!string.IsNullOrEmpty(_packageRootAssetPath))
{
return _packageRootAssetPath;
}
string packageRootAbsolutePath = GetPackageRootAbsolutePath();
if (string.IsNullOrEmpty(packageRootAbsolutePath))
{
return null;
}
_packageRootAssetPath = ToAssetPath(packageRootAbsolutePath);
return _packageRootAssetPath;
}
/// <summary>
/// Builds a project-relative asset path under the Sidekick package root.
/// </summary>
/// <param name="relativeSegments">Path segments under the package root.</param>
/// <returns>The combined asset path, if the package root could be found.</returns>
public static string GetPackageAssetPath(params string[] relativeSegments)
{
string packageRootAssetPath = GetPackageRootAssetPath();
if (string.IsNullOrEmpty(packageRootAssetPath))
{
return null;
}
string combinedPath = packageRootAssetPath;
foreach (string segment in relativeSegments)
{
combinedPath = Path.Combine(combinedPath, segment);
}
return NormalizePathSeparators(combinedPath);
}
/// <summary>
/// Normalizes legacy Sidekick asset paths so moved packages still load correctly.
/// </summary>
/// <param name="assetPath">The asset path to normalize.</param>
/// <returns>The remapped path if it pointed at an old root; otherwise the original path.</returns>
public static string NormalizeLegacyAssetPath(string assetPath)
{
if (string.IsNullOrWhiteSpace(assetPath))
{
return assetPath;
}
string normalizedPath = NormalizePathSeparators(assetPath);
string packageRootAssetPath = GetPackageRootAssetPath();
if (string.IsNullOrEmpty(packageRootAssetPath))
{
return normalizedPath;
}
if (normalizedPath.StartsWith(_LEGACY_TOOLS_PACKAGE_ROOT, StringComparison.OrdinalIgnoreCase))
{
return packageRootAssetPath + normalizedPath.Substring(_LEGACY_TOOLS_PACKAGE_ROOT.Length);
}
if (normalizedPath.StartsWith(_LEGACY_PACKAGE_ROOT, StringComparison.OrdinalIgnoreCase))
{
return packageRootAssetPath + normalizedPath.Substring(_LEGACY_PACKAGE_ROOT.Length);
}
return normalizedPath;
}
private static string ToAssetPath(string fullPath)
{
string normalizedFullPath = NormalizePathSeparators(Path.GetFullPath(fullPath));
string normalizedAssetsPath = NormalizePathSeparators(Path.GetFullPath(Application.dataPath));
if (!normalizedFullPath.StartsWith(normalizedAssetsPath, StringComparison.OrdinalIgnoreCase))
{
return normalizedFullPath;
}
return "Assets" + normalizedFullPath.Substring(normalizedAssetsPath.Length);
}
private static string NormalizePathSeparators(string path)
{
return path?.Replace('\\', '/');
}
private static string GetSeedDatabasePath()
{
if (!string.IsNullOrEmpty(_seedDatabasePath) && File.Exists(_seedDatabasePath))
{
return _seedDatabasePath;
}
string[] databaseFiles = Directory.GetFiles(Application.dataPath, _DATABASE_FILE_NAME, SearchOption.AllDirectories);
_seedDatabasePath = databaseFiles
.OrderBy(path => path.Contains($"{Path.DirectorySeparatorChar}SidekickCharacters{Path.DirectorySeparatorChar}Database{Path.DirectorySeparatorChar}") ? 0 : 1)
.FirstOrDefault();
if (!string.IsNullOrEmpty(_seedDatabasePath))
{
_seedDatabasePath = Path.GetFullPath(_seedDatabasePath);
}
return _seedDatabasePath;
}
private static void CleanupLegacyDatabaseArtifacts(string seedDatabasePath)
{
if (string.IsNullOrEmpty(seedDatabasePath))
{
return;
}
DeleteIfExists(seedDatabasePath + "-journal");
DeleteIfExists(seedDatabasePath + "-journal.meta");
DeleteIfExists(seedDatabasePath + "-wal");
DeleteIfExists(seedDatabasePath + "-wal.meta");
DeleteIfExists(seedDatabasePath + "-shm");
DeleteIfExists(seedDatabasePath + "-shm.meta");
}
private static void DeleteIfExists(string path)
{
try
{
if (File.Exists(path))
{
File.Delete(path);
}
}
catch
{
}
}
}
}

View File

@@ -1,204 +1,204 @@
// Copyright (c) 2024 Synty Studios Limited. All rights reserved.
//
// Use of this software is subject to the terms and conditions of the Synty Studios End User Licence Agreement (EULA)
// available at: https://syntystore.com/pages/end-user-licence-agreement
//
// For additional details, see the LICENSE.MD file bundled with this software.
using Synty.SidekickCharacters.API;
using Synty.SidekickCharacters.Database;
using Synty.SidekickCharacters.Database.DTO;
using Synty.SidekickCharacters.Enums;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.EventSystems;
namespace Synty.SidekickCharacters.Filters
{
public class FilterGroup
{
public SidekickRuntime Runtime;
public FilterCombineType CombineType;
private Dictionary<CharacterPartType, List<string>> _filteredParts;
private List<FilterItem> _filterItems = new List<FilterItem>();
private List<FilterGroup> _subGroups = new List<FilterGroup>();
/// <summary>
/// Adds a sub group of filters to this group.
/// </summary>
/// <param name="subGroup">The group to add as a sub group.</param>
public void AddFilterSubGroup(FilterGroup subGroup)
{
if (_subGroups.Count < 1 || _subGroups[0].CombineType == subGroup.CombineType)
{
_subGroups.Add(subGroup);
}
else
{
Debug.LogWarning("Unable to add sub group as sub groups cannot have different combine types.");
}
}
/// <summary>
/// Adds a filter item to this group.
/// </summary>
/// <param name="filterItem">The filter item to add.</param>
public void AddFilterItem(FilterItem filterItem)
{
if (_filterItems.Count < 1 || _filterItems[0].CombineType == filterItem.CombineType)
{
_filterItems.Add(filterItem);
}
else
{
Debug.LogWarning("Unable to add filter as filters cannot have different combine types.");
}
}
/// <summary>
/// Removes the given filter item from this group, if it exists.
/// </summary>
/// <param name="filterItem">The filter item to remove.</param>
public void RemoveFilterItem(FilterItem filterItem)
{
_filterItems.RemoveAll(fi => fi.Filter == filterItem.Filter);
}
/// <summary>
/// Resets the part dictionaries for all filter items.
/// </summary>
public void ResetFiltersForSpeciesChange()
{
foreach (FilterItem item in _filterItems)
{
item.ResetPartsForSpeciesChange();
}
}
/// <summary>
/// Gets a list of all parts that the filters within this group evaluate to.
/// </summary>
/// <returns>The list of all filtered parts</returns>
public Dictionary<CharacterPartType, List<string>> GetFilteredParts()
{
_filteredParts = new Dictionary<CharacterPartType, List<string>>();
// If there are no filter items, it means that we aren't filtering any parts out. Return all parts.
if (_filterItems.Count < 1)
{
return Runtime.MappedBasePartDictionary[Runtime.CurrentSpecies];
}
if (_filterItems.Count > 1)
{
FilterCombineType filterCombineType = _filterItems[1].CombineType;
if (_filterItems[0].CombineType != FilterCombineType.Or)
{
_filteredParts = Runtime.MappedPartList;
}
foreach (FilterItem item in _filterItems)
{
Dictionary<CharacterPartType, List<string>> newFilteredParts = item.GetFilteredParts();
List<string> toRemove = new List<string>();
foreach (KeyValuePair<CharacterPartType, List<string>> entry in newFilteredParts)
{
switch (filterCombineType)
{
case FilterCombineType.And:
toRemove = new List<string>();
foreach (string part in _filteredParts[entry.Key])
{
if (!entry.Value.Contains(part))
{
toRemove.Add(part);
}
}
_filteredParts[entry.Key].RemoveAll(part => toRemove.Contains(part));
break;
case FilterCombineType.Or:
HashSet<string> uniqueList = entry.Value.ToHashSet();
HashSet<string> existingList = _filteredParts.TryGetValue(entry.Key, out List<string> filteredList) ? filteredList.ToHashSet() : new HashSet<string>();
existingList.UnionWith(uniqueList);
_filteredParts[entry.Key] = existingList.ToList();
break;
case FilterCombineType.Not:
toRemove = new List<string>();
foreach (string part in _filteredParts[entry.Key])
{
if (entry.Value.Contains(part))
{
toRemove.Add(part);
}
}
_filteredParts[entry.Key].RemoveAll(part => toRemove.Contains(part));
break;
}
}
}
}
else
{
_filteredParts = _filterItems[0].GetFilteredParts();
}
foreach (FilterGroup group in _subGroups)
{
FilterCombineType filterCombineType = group.CombineType;
Dictionary<CharacterPartType, List<string>> newFilteredParts = group.GetFilteredParts();
List<string> toRemove = new List<string>();
foreach (KeyValuePair<CharacterPartType, List<string>> entry in newFilteredParts)
{
switch (filterCombineType)
{
case FilterCombineType.And:
toRemove = new List<string>();
foreach (string part in _filteredParts[entry.Key])
{
if (!entry.Value.Contains(part))
{
toRemove.Add(part);
}
}
_filteredParts[entry.Key].RemoveAll(part => toRemove.Contains(part));
break;
case FilterCombineType.Or:
HashSet<string> uniqueList = entry.Value.ToHashSet();
HashSet<string> existingList = _filteredParts[entry.Key].ToHashSet();
existingList.UnionWith(uniqueList);
_filteredParts[entry.Key] = existingList.ToList();
break;
case FilterCombineType.Not:
toRemove = new List<string>();
foreach (string part in _filteredParts[entry.Key])
{
if (entry.Value.Contains(part))
{
toRemove.Add(part);
}
}
_filteredParts[entry.Key].RemoveAll(part => toRemove.Contains(part));
break;
}
}
}
return _filteredParts;
}
}
}
// Copyright (c) 2024 Synty Studios Limited. All rights reserved.
//
// Use of this software is subject to the terms and conditions of the Synty Studios End User Licence Agreement (EULA)
// available at: https://syntystore.com/pages/end-user-licence-agreement
//
// For additional details, see the LICENSE.MD file bundled with this software.
using Synty.SidekickCharacters.API;
using Synty.SidekickCharacters.Database;
using Synty.SidekickCharacters.Database.DTO;
using Synty.SidekickCharacters.Enums;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.EventSystems;
namespace Synty.SidekickCharacters.Filters
{
public class FilterGroup
{
public SidekickRuntime Runtime;
public FilterCombineType CombineType;
private Dictionary<CharacterPartType, List<string>> _filteredParts;
private List<FilterItem> _filterItems = new List<FilterItem>();
private List<FilterGroup> _subGroups = new List<FilterGroup>();
/// <summary>
/// Adds a sub group of filters to this group.
/// </summary>
/// <param name="subGroup">The group to add as a sub group.</param>
public void AddFilterSubGroup(FilterGroup subGroup)
{
if (_subGroups.Count < 1 || _subGroups[0].CombineType == subGroup.CombineType)
{
_subGroups.Add(subGroup);
}
else
{
Debug.LogWarning("Unable to add sub group as sub groups cannot have different combine types.");
}
}
/// <summary>
/// Adds a filter item to this group.
/// </summary>
/// <param name="filterItem">The filter item to add.</param>
public void AddFilterItem(FilterItem filterItem)
{
if (_filterItems.Count < 1 || _filterItems[0].CombineType == filterItem.CombineType)
{
_filterItems.Add(filterItem);
}
else
{
Debug.LogWarning("Unable to add filter as filters cannot have different combine types.");
}
}
/// <summary>
/// Removes the given filter item from this group, if it exists.
/// </summary>
/// <param name="filterItem">The filter item to remove.</param>
public void RemoveFilterItem(FilterItem filterItem)
{
_filterItems.RemoveAll(fi => fi.Filter == filterItem.Filter);
}
/// <summary>
/// Resets the part dictionaries for all filter items.
/// </summary>
public void ResetFiltersForSpeciesChange()
{
foreach (FilterItem item in _filterItems)
{
item.ResetPartsForSpeciesChange();
}
}
/// <summary>
/// Gets a list of all parts that the filters within this group evaluate to.
/// </summary>
/// <returns>The list of all filtered parts</returns>
public Dictionary<CharacterPartType, List<string>> GetFilteredParts()
{
_filteredParts = new Dictionary<CharacterPartType, List<string>>();
// If there are no filter items, it means that we aren't filtering any parts out. Return all parts.
if (_filterItems.Count < 1)
{
return Runtime.MappedBasePartDictionary[Runtime.CurrentSpecies];
}
if (_filterItems.Count > 1)
{
FilterCombineType filterCombineType = _filterItems[1].CombineType;
if (_filterItems[0].CombineType != FilterCombineType.Or)
{
_filteredParts = Runtime.MappedPartList;
}
foreach (FilterItem item in _filterItems)
{
Dictionary<CharacterPartType, List<string>> newFilteredParts = item.GetFilteredParts();
List<string> toRemove = new List<string>();
foreach (KeyValuePair<CharacterPartType, List<string>> entry in newFilteredParts)
{
switch (filterCombineType)
{
case FilterCombineType.And:
toRemove = new List<string>();
foreach (string part in _filteredParts[entry.Key])
{
if (!entry.Value.Contains(part))
{
toRemove.Add(part);
}
}
_filteredParts[entry.Key].RemoveAll(part => toRemove.Contains(part));
break;
case FilterCombineType.Or:
HashSet<string> uniqueList = entry.Value.ToHashSet();
HashSet<string> existingList = _filteredParts.TryGetValue(entry.Key, out List<string> filteredList) ? filteredList.ToHashSet() : new HashSet<string>();
existingList.UnionWith(uniqueList);
_filteredParts[entry.Key] = existingList.ToList();
break;
case FilterCombineType.Not:
toRemove = new List<string>();
foreach (string part in _filteredParts[entry.Key])
{
if (entry.Value.Contains(part))
{
toRemove.Add(part);
}
}
_filteredParts[entry.Key].RemoveAll(part => toRemove.Contains(part));
break;
}
}
}
}
else
{
_filteredParts = _filterItems[0].GetFilteredParts();
}
foreach (FilterGroup group in _subGroups)
{
FilterCombineType filterCombineType = group.CombineType;
Dictionary<CharacterPartType, List<string>> newFilteredParts = group.GetFilteredParts();
List<string> toRemove = new List<string>();
foreach (KeyValuePair<CharacterPartType, List<string>> entry in newFilteredParts)
{
switch (filterCombineType)
{
case FilterCombineType.And:
toRemove = new List<string>();
foreach (string part in _filteredParts[entry.Key])
{
if (!entry.Value.Contains(part))
{
toRemove.Add(part);
}
}
_filteredParts[entry.Key].RemoveAll(part => toRemove.Contains(part));
break;
case FilterCombineType.Or:
HashSet<string> uniqueList = entry.Value.ToHashSet();
HashSet<string> existingList = _filteredParts[entry.Key].ToHashSet();
existingList.UnionWith(uniqueList);
_filteredParts[entry.Key] = existingList.ToList();
break;
case FilterCombineType.Not:
toRemove = new List<string>();
foreach (string part in _filteredParts[entry.Key])
{
if (entry.Value.Contains(part))
{
toRemove.Add(part);
}
}
_filteredParts[entry.Key].RemoveAll(part => toRemove.Contains(part));
break;
}
}
}
return _filteredParts;
}
}
}

View File

@@ -1,59 +1,59 @@
// Copyright (c) 2024 Synty Studios Limited. All rights reserved.
//
// Use of this software is subject to the terms and conditions of the Synty Studios End User Licence Agreement (EULA)
// available at: https://syntystore.com/pages/end-user-licence-agreement
//
// For additional details, see the LICENSE.MD file bundled with this software.
using Synty.SidekickCharacters.API;
using Synty.SidekickCharacters.Database.DTO;
using Synty.SidekickCharacters.Enums;
using System;
using System.Collections.Generic;
namespace Synty.SidekickCharacters.Filters
{
public class FilterItem
{
public SidekickRuntime Runtime;
public SidekickPartFilter Filter;
public FilterCombineType CombineType;
private Dictionary<CharacterPartType, List<string>> _filteredParts = new Dictionary<CharacterPartType, List<string>>();
public FilterItem(SidekickRuntime runtime, SidekickPartFilter filter, FilterCombineType combineType)
{
Runtime = runtime;
Filter = filter;
CombineType = combineType;
}
/// <summary>
/// Resets the part dictionary when the species is changed.
/// </summary>
public void ResetPartsForSpeciesChange()
{
_filteredParts = new Dictionary<CharacterPartType, List<string>>();
}
/// <summary>
/// Gets a list of all the parts for this filter item.
/// </summary>
/// <returns>A list of all parts for this filter item.</returns>
public Dictionary<CharacterPartType, List<string>> GetFilteredParts()
{
if (_filteredParts == null || _filteredParts.Count < 1)
{
_filteredParts = new Dictionary<CharacterPartType, List<string>>();
foreach (CharacterPartType type in Enum.GetValues(typeof(CharacterPartType)))
{
List<string> parts = SidekickPartFilterRow.GetAllPartNamesForFilterSpeciesAndType(Runtime.DBManager, Filter, Runtime.CurrentSpecies, type);
_filteredParts[type] = parts;
}
}
return _filteredParts;
}
}
}
// Copyright (c) 2024 Synty Studios Limited. All rights reserved.
//
// Use of this software is subject to the terms and conditions of the Synty Studios End User Licence Agreement (EULA)
// available at: https://syntystore.com/pages/end-user-licence-agreement
//
// For additional details, see the LICENSE.MD file bundled with this software.
using Synty.SidekickCharacters.API;
using Synty.SidekickCharacters.Database.DTO;
using Synty.SidekickCharacters.Enums;
using System;
using System.Collections.Generic;
namespace Synty.SidekickCharacters.Filters
{
public class FilterItem
{
public SidekickRuntime Runtime;
public SidekickPartFilter Filter;
public FilterCombineType CombineType;
private Dictionary<CharacterPartType, List<string>> _filteredParts = new Dictionary<CharacterPartType, List<string>>();
public FilterItem(SidekickRuntime runtime, SidekickPartFilter filter, FilterCombineType combineType)
{
Runtime = runtime;
Filter = filter;
CombineType = combineType;
}
/// <summary>
/// Resets the part dictionary when the species is changed.
/// </summary>
public void ResetPartsForSpeciesChange()
{
_filteredParts = new Dictionary<CharacterPartType, List<string>>();
}
/// <summary>
/// Gets a list of all the parts for this filter item.
/// </summary>
/// <returns>A list of all parts for this filter item.</returns>
public Dictionary<CharacterPartType, List<string>> GetFilteredParts()
{
if (_filteredParts == null || _filteredParts.Count < 1)
{
_filteredParts = new Dictionary<CharacterPartType, List<string>>();
foreach (CharacterPartType type in Enum.GetValues(typeof(CharacterPartType)))
{
List<string> parts = SidekickPartFilterRow.GetAllPartNamesForFilterSpeciesAndType(Runtime.DBManager, Filter, Runtime.CurrentSpecies, type);
_filteredParts[type] = parts;
}
}
return _filteredParts;
}
}
}

View File

View File

@@ -1,36 +1,36 @@
// Copyright (c) 2024 Synty Studios Limited. All rights reserved.
//
// Use of this software is subject to the terms and conditions of the Synty Studios End User Licence Agreement (EULA)
// available at: https://syntystore.com/pages/end-user-licence-agreement
//
// For additional details, see the LICENSE.MD file bundled with this software.
using Synty.SidekickCharacters.Database;
using Synty.SidekickCharacters.Database.DTO;
using Synty.SidekickCharacters.Enums;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace Synty.SidekickCharacters.Filters
{
public class ParsedPart
{
public string Species;
public string Outfit1;
public string Outfit2;
public string PartArea;
public string Filename;
public string Name;
public ParsedPart(string partName, string name)
{
Species = partName.Substring(partName.LastIndexOf('_') + 1, 2);
Outfit1 = partName.Substring(3, 4);
Outfit2 = partName.Substring(8, 4);
PartArea = partName.Substring(18, 4);
Filename = partName;
Name = name;
}
}
}
// Copyright (c) 2024 Synty Studios Limited. All rights reserved.
//
// Use of this software is subject to the terms and conditions of the Synty Studios End User Licence Agreement (EULA)
// available at: https://syntystore.com/pages/end-user-licence-agreement
//
// For additional details, see the LICENSE.MD file bundled with this software.
using Synty.SidekickCharacters.Database;
using Synty.SidekickCharacters.Database.DTO;
using Synty.SidekickCharacters.Enums;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace Synty.SidekickCharacters.Filters
{
public class ParsedPart
{
public string Species;
public string Outfit1;
public string Outfit2;
public string PartArea;
public string Filename;
public string Name;
public ParsedPart(string partName, string name)
{
Species = partName.Substring(partName.LastIndexOf('_') + 1, 2);
Outfit1 = partName.Substring(3, 4);
Outfit2 = partName.Substring(8, 4);
PartArea = partName.Substring(18, 4);
Filename = partName;
Name = name;
}
}
}

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