chore: Assets 디렉토리 구조 정리 및 네이밍 컨벤션 적용
- Assets/_Game/ 하위로 게임 에셋 통합 - External/ 패키지 벤더별 분류 (Synty, Animations, UI) - 에셋 네이밍 컨벤션 확립 및 적용 (Data_Skill_, Data_SkillEffect_, Prefab_, Anim_, Model_, BT_ 등) - pre-commit hook으로 네이밍 컨벤션 자동 검사 추가 - RESTRUCTURE_CHECKLIST.md 작성 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
167
Assets/External/Models/SidekickCharacters/_Demos/Scripts/ExpressionSwitcher.cs
vendored
Normal file
167
Assets/External/Models/SidekickCharacters/_Demos/Scripts/ExpressionSwitcher.cs
vendored
Normal file
@@ -0,0 +1,167 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using System.Collections.Generic;
|
||||
|
||||
public class ExpressionSwitcher : MonoBehaviour
|
||||
{
|
||||
private Animator _animator;
|
||||
|
||||
// Define a list of expression names (will be dynamically populated)
|
||||
private List<string> _expressionNames = new List<string>();
|
||||
|
||||
private int _currentIndex = 0;
|
||||
|
||||
// Reference to the UI text to display the current emotion
|
||||
[SerializeField] private Text _emotionText;
|
||||
|
||||
// Reference to the button to cycle expressions
|
||||
[SerializeField] private Button _cycleButton;
|
||||
|
||||
// Reference to the UI slider to adjust transition time
|
||||
[SerializeField] private Slider _transitionTimeSlider;
|
||||
|
||||
private float _transitionTime = 0.2f; // Default transition time
|
||||
|
||||
void Start()
|
||||
{
|
||||
_animator = GetComponent<Animator>();
|
||||
|
||||
// Ensure the Animator is assigned
|
||||
if (_animator == null)
|
||||
{
|
||||
Debug.LogWarning("[ExpressionSwitcher] No Animator component found on the GameObject.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Populate the expression names from the Animator states in the specified layer
|
||||
PopulateExpressionNames();
|
||||
|
||||
// Debug: Check what was found
|
||||
Debug.Log($"[ExpressionSwitcher] Found {_expressionNames.Count} expressions:");
|
||||
foreach (var expr in _expressionNames)
|
||||
Debug.Log($" - {expr}");
|
||||
|
||||
// Debug: Check the layer
|
||||
int layerIndex = _animator.GetLayerIndex("Emotion_Additive");
|
||||
Debug.Log($"[ExpressionSwitcher] Layer 'Emotion_Additive' index: {layerIndex}");
|
||||
|
||||
// Wire up the button
|
||||
if (_cycleButton != null)
|
||||
{
|
||||
_cycleButton.onClick.AddListener(CycleExpressions);
|
||||
Debug.Log("[ExpressionSwitcher] Button wired up successfully");
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning("[ExpressionSwitcher] No button assigned in Inspector!");
|
||||
}
|
||||
|
||||
// Ensure the slider is assigned
|
||||
if (_transitionTimeSlider != null)
|
||||
{
|
||||
_transitionTimeSlider.minValue = 0.0f;
|
||||
_transitionTimeSlider.maxValue = 1.0f;
|
||||
_transitionTimeSlider.value = _transitionTime;
|
||||
|
||||
// Read the initial value from the slider to set the transition time
|
||||
UpdateTransitionTime(_transitionTimeSlider.value);
|
||||
|
||||
// Add a listener to handle value changes
|
||||
_transitionTimeSlider.onValueChanged.AddListener(UpdateTransitionTime);
|
||||
}
|
||||
}
|
||||
|
||||
private void PopulateExpressionNames()
|
||||
{
|
||||
RuntimeAnimatorController ac = _animator.runtimeAnimatorController;
|
||||
|
||||
if (ac != null)
|
||||
{
|
||||
Debug.Log($"[ExpressionSwitcher] Scanning {ac.animationClips.Length} animation clips...");
|
||||
|
||||
foreach (AnimationClip clip in ac.animationClips)
|
||||
{
|
||||
if (clip.name.Contains("A_FacePose") && !_expressionNames.Contains(clip.name) && !clip.name.Contains("Neutral"))
|
||||
{
|
||||
_expressionNames.Add(clip.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError("[ExpressionSwitcher] AnimatorController is not found.");
|
||||
}
|
||||
}
|
||||
|
||||
public void CycleExpressions()
|
||||
{
|
||||
Debug.Log("[ExpressionSwitcher] CycleExpressions() called");
|
||||
|
||||
if (_animator == null)
|
||||
{
|
||||
Debug.LogError("[ExpressionSwitcher] Animator is null!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (_expressionNames.Count == 0)
|
||||
{
|
||||
Debug.LogError("[ExpressionSwitcher] No expressions found in list!");
|
||||
return;
|
||||
}
|
||||
|
||||
string layerName = "Emotion_Additive";
|
||||
int layerIndex = _animator.GetLayerIndex(layerName);
|
||||
|
||||
if (layerIndex == -1)
|
||||
{
|
||||
Debug.LogError($"[ExpressionSwitcher] Layer '{layerName}' not found!");
|
||||
return;
|
||||
}
|
||||
|
||||
string expressionName = _expressionNames[_currentIndex];
|
||||
int stateHash = Animator.StringToHash(expressionName);
|
||||
bool hasState = _animator.HasState(layerIndex, stateHash);
|
||||
|
||||
Debug.Log($"[ExpressionSwitcher] Trying expression: '{expressionName}' (index {_currentIndex})");
|
||||
Debug.Log($"[ExpressionSwitcher] State hash: {stateHash}, HasState: {hasState}");
|
||||
|
||||
if (hasState)
|
||||
{
|
||||
_animator.CrossFadeInFixedTime(expressionName, _transitionTime, layerIndex);
|
||||
Debug.Log($"[ExpressionSwitcher] Playing '{expressionName}'");
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning($"[ExpressionSwitcher] State '{expressionName}' not found, trying 'Neutral'");
|
||||
_animator.CrossFadeInFixedTime("Neutral", _transitionTime, layerIndex);
|
||||
}
|
||||
|
||||
// Update the emotion text after playing the animation
|
||||
UpdateEmotionText();
|
||||
|
||||
// Move to the next expression in the list
|
||||
_currentIndex = (_currentIndex + 1) % _expressionNames.Count;
|
||||
}
|
||||
|
||||
private void UpdateEmotionText()
|
||||
{
|
||||
if (_emotionText != null && _expressionNames.Count > 0)
|
||||
{
|
||||
string expressionName = _expressionNames[_currentIndex];
|
||||
int underscoreIndex = expressionName.LastIndexOf('_');
|
||||
if (underscoreIndex != -1 && underscoreIndex < expressionName.Length - 1)
|
||||
{
|
||||
_emotionText.text = expressionName.Substring(underscoreIndex + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
_emotionText.text = expressionName; // Fallback if no underscore found
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateTransitionTime(float value)
|
||||
{
|
||||
_transitionTime = value;
|
||||
}
|
||||
}
|
||||
11
Assets/External/Models/SidekickCharacters/_Demos/Scripts/ExpressionSwitcher.cs.meta
vendored
Normal file
11
Assets/External/Models/SidekickCharacters/_Demos/Scripts/ExpressionSwitcher.cs.meta
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 956373788f9dd55489810c0d6e6d9918
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
140
Assets/External/Models/SidekickCharacters/_Demos/Scripts/RandomisedLayerWeight.cs
vendored
Normal file
140
Assets/External/Models/SidekickCharacters/_Demos/Scripts/RandomisedLayerWeight.cs
vendored
Normal file
@@ -0,0 +1,140 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
public class RandomisedLayerWeight : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private Animator animator;
|
||||
|
||||
[Header("Random Variance Settings")]
|
||||
[SerializeField, Range(0f, 1f)] private float maxRandomVariance = 0.5f;
|
||||
[SerializeField] private Slider randomVarianceSlider;
|
||||
[SerializeField] private Text maxRandomVarianceText; // UI Text to display maxRandomVariance
|
||||
|
||||
[Header("Layer Weight Settings")] // Changed header name to "Layer Weight Settings"
|
||||
[SerializeField, Range(0f, 1f)] private float layerWeight = 1f; // Changed variable name to layerWeight
|
||||
[SerializeField] private Slider layerWeightSlider; // Changed slider name to layerWeightSlider
|
||||
[SerializeField] private Text layerWeightText; // Changed UI Text name to layerWeightText
|
||||
|
||||
[Header("Transition Settings")]
|
||||
[SerializeField] private string layerName = "Emotion_Additive"; // Adjust this layer name in the Inspector
|
||||
[SerializeField] private float averageTransitionTime = 0.4f;
|
||||
[SerializeField] private float transitionVariationAmount = 0.3f;
|
||||
|
||||
[Header("Hold Settings")]
|
||||
[SerializeField] private float averageHoldTime = 1.0f;
|
||||
[SerializeField] private float holdVariationAmount = 1.0f;
|
||||
|
||||
private int layerIndex;
|
||||
private float currentWeight = 0f;
|
||||
private float targetWeight = 0f;
|
||||
private float transitionTimer = 0f;
|
||||
private float holdTimer = 0f;
|
||||
|
||||
void Start()
|
||||
{
|
||||
if (animator == null)
|
||||
{
|
||||
Debug.LogError("Animator component is not assigned.");
|
||||
enabled = false;
|
||||
return;
|
||||
}
|
||||
|
||||
layerIndex = animator.GetLayerIndex(layerName);
|
||||
if (layerIndex == -1)
|
||||
{
|
||||
Debug.LogError($"Layer '{layerName}' not found in the Animator.");
|
||||
enabled = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// Initialize sliders and UI Texts
|
||||
if (randomVarianceSlider != null)
|
||||
{
|
||||
randomVarianceSlider.value = maxRandomVariance;
|
||||
randomVarianceSlider.onValueChanged.AddListener(SetMaxRandomVariance);
|
||||
}
|
||||
|
||||
if (layerWeightSlider != null) // Changed to layerWeightSlider
|
||||
{
|
||||
layerWeightSlider.value = layerWeight; // Changed to layerWeight
|
||||
layerWeightSlider.onValueChanged.AddListener(SetLayerWeight); // Changed to SetLayerWeight
|
||||
}
|
||||
|
||||
// Initialize UI Texts
|
||||
if (maxRandomVarianceText != null)
|
||||
{
|
||||
maxRandomVarianceText.text = $"Random Variance: {maxRandomVariance:P0}";
|
||||
}
|
||||
|
||||
if (layerWeightText != null) // Changed to layerWeightText
|
||||
{
|
||||
layerWeightText.text = $"Layer Weight: {layerWeight:P0}"; // Changed to Layer Weight
|
||||
}
|
||||
|
||||
// Initialize the weight to a random value between 0 and 1
|
||||
currentWeight = Random.value;
|
||||
animator.SetLayerWeight(layerIndex, currentWeight * layerWeight); // Changed to layerWeight
|
||||
|
||||
// Start the initial transition
|
||||
StartTransition();
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
// Update timers
|
||||
transitionTimer -= Time.deltaTime;
|
||||
holdTimer -= Time.deltaTime;
|
||||
|
||||
// Check if it's time to transition to a new weight
|
||||
if (transitionTimer <= 0f)
|
||||
{
|
||||
StartTransition();
|
||||
}
|
||||
// Otherwise, check if it's time to hold the current weight
|
||||
else if (holdTimer <= 0f)
|
||||
{
|
||||
holdTimer = GenerateHoldTime();
|
||||
}
|
||||
|
||||
// Smoothly adjust the weight towards the target weight
|
||||
currentWeight = Mathf.Lerp(currentWeight, targetWeight, Time.deltaTime / averageTransitionTime);
|
||||
animator.SetLayerWeight(layerIndex, currentWeight * layerWeight); // Changed to layerWeight
|
||||
}
|
||||
|
||||
private void StartTransition()
|
||||
{
|
||||
// Set a new target weight
|
||||
targetWeight = Random.Range(Mathf.Max(0f, 1f - maxRandomVariance), 1f) * layerWeight; // Changed to layerWeight
|
||||
transitionTimer = GenerateTransitionTime();
|
||||
}
|
||||
|
||||
private float GenerateTransitionTime()
|
||||
{
|
||||
float variation = Random.Range(-transitionVariationAmount, transitionVariationAmount);
|
||||
return Mathf.Max(0f, averageTransitionTime + variation);
|
||||
}
|
||||
|
||||
private float GenerateHoldTime()
|
||||
{
|
||||
float variation = Random.Range(-holdVariationAmount, holdVariationAmount);
|
||||
return Mathf.Max(0f, averageHoldTime + variation);
|
||||
}
|
||||
|
||||
private void SetMaxRandomVariance(float value)
|
||||
{
|
||||
maxRandomVariance = value;
|
||||
if (maxRandomVarianceText != null)
|
||||
{
|
||||
maxRandomVarianceText.text = $"Random Variance: {maxRandomVariance:P0}";
|
||||
}
|
||||
}
|
||||
|
||||
private void SetLayerWeight(float value) // Changed method name to SetLayerWeight
|
||||
{
|
||||
layerWeight = value; // Changed to layerWeight
|
||||
if (layerWeightText != null) // Changed to layerWeightText
|
||||
{
|
||||
layerWeightText.text = $"Layer Weight: {layerWeight:P0}"; // Changed to Layer Weight
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/External/Models/SidekickCharacters/_Demos/Scripts/RandomisedLayerWeight.cs.meta
vendored
Normal file
11
Assets/External/Models/SidekickCharacters/_Demos/Scripts/RandomisedLayerWeight.cs.meta
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3148f125cb16eb947885efc01b9cdff9
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
223
Assets/External/Models/SidekickCharacters/_Demos/Scripts/RuntimeColorDemo.cs
vendored
Normal file
223
Assets/External/Models/SidekickCharacters/_Demos/Scripts/RuntimeColorDemo.cs
vendored
Normal file
@@ -0,0 +1,223 @@
|
||||
using Synty.SidekickCharacters.API;
|
||||
using Synty.SidekickCharacters.Database;
|
||||
using Synty.SidekickCharacters.Database.DTO;
|
||||
using Synty.SidekickCharacters.Enums;
|
||||
using Synty.SidekickCharacters.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using Random = UnityEngine.Random;
|
||||
|
||||
namespace Synty.SidekickCharacters.Demo
|
||||
{
|
||||
/// <summary>
|
||||
/// An example script to show how to interact with the Sidekick API in regards to colors at runtime.
|
||||
/// </summary>
|
||||
public class RuntimeColorDemo : MonoBehaviour
|
||||
{
|
||||
private readonly string _OUTPUT_MODEL_NAME = "Sidekick Character";
|
||||
|
||||
private Dictionary<string, SidekickPartPreset> _availableHeadPresetDictionary = new Dictionary<string, SidekickPartPreset>();
|
||||
private Dictionary<string, SidekickPartPreset> _availableUpperBodyPresetDictionary = new Dictionary<string, SidekickPartPreset>();
|
||||
private Dictionary<string, SidekickPartPreset> _availableLowerBodyPresetDictionary = new Dictionary<string, SidekickPartPreset>();
|
||||
private List<SidekickBodyShapePreset> _availableBodyShapes = new List<SidekickBodyShapePreset>();
|
||||
private List<SidekickColorPreset> _availableColorPresets = new List<SidekickColorPreset>();
|
||||
|
||||
private int _currentHeadPresetIndex = 0;
|
||||
private int _currentUpperBodyPresetIndex = 0;
|
||||
private int _currentLowerBodyPresetIndex = 0;
|
||||
private int _currentBodyShapePresetIndex = 0;
|
||||
private int _currentColorPresetIndex = 0;
|
||||
|
||||
private DatabaseManager _dbManager;
|
||||
private SidekickRuntime _sidekickRuntime;
|
||||
|
||||
private Dictionary<CharacterPartType, Dictionary<string, SidekickPart>> _partLibrary;
|
||||
|
||||
public TextMeshProUGUI _loadingText;
|
||||
|
||||
/// <inheritdoc cref="Start"/>
|
||||
void Start()
|
||||
{
|
||||
_dbManager = new DatabaseManager();
|
||||
|
||||
GameObject model = Resources.Load<GameObject>("Meshes/SK_BaseModel");
|
||||
Material material = Resources.Load<Material>("Materials/M_BaseMaterial");
|
||||
|
||||
_sidekickRuntime = new SidekickRuntime(model, material, null, _dbManager);
|
||||
|
||||
SidekickRuntime.PopulateToolData(_sidekickRuntime);
|
||||
_partLibrary = _sidekickRuntime.MappedPartDictionary;
|
||||
|
||||
foreach (PartGroup partGroup in Enum.GetValues(typeof(PartGroup)))
|
||||
{
|
||||
// only filter head part presets by species
|
||||
List<SidekickPartPreset> presets = SidekickPartPreset.GetAllByGroup(_dbManager, partGroup);
|
||||
List<string> presetNames = new List<string>();
|
||||
if (presets.Count < 1)
|
||||
{
|
||||
Debug.LogWarning("No parts found for " + partGroup + ". Please add at least 1 Sidekicks content pack.");
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach (SidekickPartPreset preset in presets)
|
||||
{
|
||||
switch (partGroup)
|
||||
{
|
||||
case PartGroup.Head:
|
||||
_availableHeadPresetDictionary.Add(preset.Name, preset);
|
||||
break;
|
||||
case PartGroup.UpperBody:
|
||||
_availableUpperBodyPresetDictionary.Add(preset.Name, preset);
|
||||
break;
|
||||
case PartGroup.LowerBody:
|
||||
_availableLowerBodyPresetDictionary.Add(preset.Name, preset);
|
||||
break;
|
||||
}
|
||||
|
||||
presetNames.Add(preset.Name);
|
||||
}
|
||||
}
|
||||
|
||||
_availableBodyShapes = SidekickBodyShapePreset.GetAll(_dbManager);
|
||||
|
||||
// An example of how to retrieve color presets from the database. To retrieve presets for other areas of the material, use the ColorGroup
|
||||
// enum to retrieve other presets.
|
||||
_availableColorPresets = SidekickColorPreset.GetAllByColorGroup(_dbManager, ColorGroup.Outfits);
|
||||
|
||||
_currentHeadPresetIndex = Random.Range(0, _availableHeadPresetDictionary.Count - 1);
|
||||
_currentUpperBodyPresetIndex = Random.Range(0, _availableUpperBodyPresetDictionary.Count - 1);
|
||||
_currentLowerBodyPresetIndex = Random.Range(0, _availableLowerBodyPresetDictionary.Count - 1);
|
||||
_currentBodyShapePresetIndex = Random.Range(0, _availableBodyShapes.Count - 1);
|
||||
_currentColorPresetIndex = Random.Range(0, _availableColorPresets.Count - 1);
|
||||
|
||||
_loadingText.enabled = false;
|
||||
|
||||
UpdateModel();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Processes the change of the skin color on the character.
|
||||
/// </summary>
|
||||
/// <param name="image">The image tile that contains the color to change to.</param>
|
||||
public void ProcessSkinColorChange(Image image)
|
||||
{
|
||||
ColorType colorType = ColorType.MainColor;
|
||||
List<SidekickColorProperty> allProperties = SidekickColorProperty.GetAll(_dbManager);
|
||||
List<SidekickColorProperty> selectedProperties = allProperties.FindAll(scp => scp.Name.ToLower().Contains("skin"));
|
||||
foreach (SidekickColorProperty property in selectedProperties)
|
||||
{
|
||||
SidekickColorRow row = new SidekickColorRow()
|
||||
{
|
||||
ColorProperty = property,
|
||||
MainColor = ColorUtility.ToHtmlStringRGB(image.color),
|
||||
};
|
||||
_sidekickRuntime.UpdateColor(colorType, row);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Processes the change of the outfit color on the character.
|
||||
/// </summary>
|
||||
/// <param name="image">The image tile that contains the color to change to.</param>
|
||||
public void ProcessOutfitColorChange(Image image)
|
||||
{
|
||||
ColorType colorType = ColorType.MainColor;
|
||||
List<SidekickColorProperty> allProperties = SidekickColorProperty.GetAll(_dbManager);
|
||||
List<SidekickColorProperty> selectedProperties = allProperties.FindAll(scp => scp.Name.ToLower().Contains("outfit"));
|
||||
foreach (SidekickColorProperty property in selectedProperties)
|
||||
{
|
||||
SidekickColorRow row = new SidekickColorRow()
|
||||
{
|
||||
ColorProperty = property,
|
||||
MainColor = ColorUtility.ToHtmlStringRGB(image.color),
|
||||
};
|
||||
_sidekickRuntime.UpdateColor(colorType, row);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the created character model.
|
||||
/// </summary>
|
||||
private void UpdateModel()
|
||||
{
|
||||
// If there aren't enough presets, stop trying to update the model.
|
||||
if (_availableHeadPresetDictionary.Values.Count < 1
|
||||
|| _availableUpperBodyPresetDictionary.Values.Count < 1
|
||||
|| _availableLowerBodyPresetDictionary.Values.Count < 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Create and populate the list of parts to use from the parts list and the selected colors.
|
||||
List<SidekickPartPreset> presets = new List<SidekickPartPreset>()
|
||||
{
|
||||
_availableHeadPresetDictionary.Values.ToArray()[_currentHeadPresetIndex],
|
||||
_availableUpperBodyPresetDictionary.Values.ToArray()[_currentUpperBodyPresetIndex],
|
||||
_availableLowerBodyPresetDictionary.Values.ToArray()[_currentLowerBodyPresetIndex]
|
||||
};
|
||||
|
||||
List<SkinnedMeshRenderer> partsToUse = new List<SkinnedMeshRenderer>();
|
||||
|
||||
foreach (SidekickPartPreset preset in presets)
|
||||
{
|
||||
List<SidekickPartPresetRow> rows = SidekickPartPresetRow.GetAllByPreset(_dbManager, preset);
|
||||
foreach (SidekickPartPresetRow row in rows)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(row.PartName))
|
||||
{
|
||||
CharacterPartType type = Enum.Parse<CharacterPartType>(CharacterPartTypeUtils.GetTypeNameFromShortcode(row.PartType));
|
||||
Dictionary<string, SidekickPart> partLocationDictionary = _partLibrary[type];
|
||||
GameObject selectedPart = partLocationDictionary[row.PartName].GetPartModel();
|
||||
SkinnedMeshRenderer selectedMesh = selectedPart.GetComponentInChildren<SkinnedMeshRenderer>();
|
||||
partsToUse.Add(selectedMesh);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SidekickBodyShapePreset bodyPreset = _availableBodyShapes[_currentBodyShapePresetIndex];
|
||||
_sidekickRuntime.BodyTypeBlendValue = bodyPreset.BodyType;
|
||||
_sidekickRuntime.BodySizeHeavyBlendValue = bodyPreset.BodySize > 0 ? bodyPreset.BodySize : 0;
|
||||
_sidekickRuntime.BodySizeSkinnyBlendValue = bodyPreset.BodySize < 0 ? -bodyPreset.BodySize : 0;
|
||||
_sidekickRuntime.MusclesBlendValue = bodyPreset.Musculature;
|
||||
|
||||
List<SidekickColorPresetRow> colorRows = SidekickColorPresetRow.GetAllByPreset(_dbManager, _availableColorPresets[_currentColorPresetIndex]);
|
||||
foreach (SidekickColorPresetRow row in colorRows)
|
||||
{
|
||||
SidekickColorRow colorRow = SidekickColorRow.CreateFromPresetColorRow(row);
|
||||
foreach (ColorType property in Enum.GetValues(typeof(ColorType)))
|
||||
{
|
||||
_sidekickRuntime.UpdateColor(property, colorRow);
|
||||
}
|
||||
}
|
||||
|
||||
// Check for an existing copy of the model, if it exists, delete it so that we don't end up with duplicates.
|
||||
GameObject character = GameObject.Find(_OUTPUT_MODEL_NAME);
|
||||
|
||||
if (character != null)
|
||||
{
|
||||
Destroy(character);
|
||||
}
|
||||
|
||||
// Create a new character using the selected parts using the Sidekicks API.
|
||||
character = _sidekickRuntime.CreateCharacter(_OUTPUT_MODEL_NAME, partsToUse, false, true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a resource path for using with Resources.Load() from a full path.
|
||||
/// </summary>
|
||||
/// <param name="fullPath">The full path to get the resource path from.</param>
|
||||
/// <returns>The resource path.</returns>
|
||||
private string GetResourcePath(string fullPath)
|
||||
{
|
||||
string directory = Path.GetDirectoryName(fullPath);
|
||||
int startIndex = directory.IndexOf("Resources") + 10;
|
||||
directory = directory.Substring(startIndex, directory.Length - startIndex);
|
||||
return Path.Combine(directory, Path.GetFileNameWithoutExtension(fullPath));
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/External/Models/SidekickCharacters/_Demos/Scripts/RuntimeColorDemo.cs.meta
vendored
Normal file
11
Assets/External/Models/SidekickCharacters/_Demos/Scripts/RuntimeColorDemo.cs.meta
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d2982d8e931cbe9479bbce782487fa75
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
380
Assets/External/Models/SidekickCharacters/_Demos/Scripts/RuntimePartsDemo.cs
vendored
Normal file
380
Assets/External/Models/SidekickCharacters/_Demos/Scripts/RuntimePartsDemo.cs
vendored
Normal file
@@ -0,0 +1,380 @@
|
||||
using Synty.SidekickCharacters.API;
|
||||
using Synty.SidekickCharacters.Database;
|
||||
using Synty.SidekickCharacters.Database.DTO;
|
||||
using Synty.SidekickCharacters.Enums;
|
||||
using Synty.SidekickCharacters.Utils;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using Random = UnityEngine.Random;
|
||||
|
||||
namespace Synty.SidekickCharacters.Demo
|
||||
{
|
||||
/// <summary>
|
||||
/// An example script to show how to interact with the Sidekick API in regards to parts at runtime.
|
||||
/// </summary>
|
||||
public class RuntimePartsDemo : MonoBehaviour
|
||||
{
|
||||
private readonly string _OUTPUT_MODEL_NAME = "Sidekick Character";
|
||||
|
||||
Dictionary<CharacterPartType, int> _partIndexDictionary = new Dictionary<CharacterPartType, int>();
|
||||
Dictionary<CharacterPartType, Dictionary<string, SidekickPart>> _availablePartDictionary = new Dictionary<CharacterPartType, Dictionary<string, SidekickPart>>();
|
||||
|
||||
private DatabaseManager _dbManager;
|
||||
private SidekickRuntime _sidekickRuntime;
|
||||
|
||||
private Dictionary<CharacterPartType, Dictionary<string, SidekickPart>> _partLibrary;
|
||||
|
||||
public TextMeshProUGUI _loadingText;
|
||||
|
||||
/// <inheritdoc cref="Start"/>
|
||||
void Start()
|
||||
{
|
||||
// Create a new instance of the database manager to access database content.
|
||||
_dbManager = new DatabaseManager();
|
||||
|
||||
// Load the base model and material required to create an instance of the Sidekick Runtime API.
|
||||
GameObject model = Resources.Load<GameObject>("Meshes/SK_BaseModel");
|
||||
Material material = Resources.Load<Material>("Materials/M_BaseMaterial");
|
||||
|
||||
_sidekickRuntime = new SidekickRuntime(model, material, null, _dbManager);
|
||||
|
||||
// Populate the parts list for easy access.
|
||||
SidekickRuntime.PopulateToolData(_sidekickRuntime);
|
||||
_partLibrary = _sidekickRuntime.MappedPartDictionary;
|
||||
|
||||
// For this example we are only interested in Upper Body parts, so we filter the list of all parts to only get the ones we want.
|
||||
List<CharacterPartType> upperBodyParts = PartGroup.UpperBody.GetPartTypes();
|
||||
|
||||
foreach (CharacterPartType type in upperBodyParts)
|
||||
{
|
||||
_availablePartDictionary.Add(type, _partLibrary[type]);
|
||||
_partIndexDictionary.Add(type, Random.Range(0, _availablePartDictionary[type].Count - 1));
|
||||
}
|
||||
|
||||
_loadingText.enabled = false;
|
||||
|
||||
UpdateModel();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles the click on the forward button for the Torso part.
|
||||
/// </summary>
|
||||
public void ForwardTorso()
|
||||
{
|
||||
int index = _partIndexDictionary[CharacterPartType.Torso];
|
||||
index++;
|
||||
if (index >= _availablePartDictionary[CharacterPartType.Torso].Count)
|
||||
{
|
||||
index = 0;
|
||||
}
|
||||
|
||||
_partIndexDictionary[CharacterPartType.Torso] = index;
|
||||
UpdateModel();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles the click on the backward button for the Torso part.
|
||||
/// </summary>
|
||||
public void BackwardTorso()
|
||||
{
|
||||
int index = _partIndexDictionary[CharacterPartType.Torso];
|
||||
index--;
|
||||
if (index < 0)
|
||||
{
|
||||
index = _availablePartDictionary[CharacterPartType.Torso].Count - 1;
|
||||
}
|
||||
|
||||
_partIndexDictionary[CharacterPartType.Torso] = index;
|
||||
UpdateModel();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles the click on the forward button for the ArmUpperLeft part.
|
||||
/// </summary>
|
||||
public void ForwardUpperArmLeft()
|
||||
{
|
||||
int index = _partIndexDictionary[CharacterPartType.ArmUpperLeft];
|
||||
index++;
|
||||
if (index >= _availablePartDictionary[CharacterPartType.ArmUpperLeft].Count)
|
||||
{
|
||||
index = 0;
|
||||
}
|
||||
|
||||
_partIndexDictionary[CharacterPartType.ArmUpperLeft] = index;
|
||||
UpdateModel();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles the click on the backward button for the ArmUpperLeft part.
|
||||
/// </summary>
|
||||
public void BackwardUpperArmLeft()
|
||||
{
|
||||
int index = _partIndexDictionary[CharacterPartType.ArmUpperLeft];
|
||||
index--;
|
||||
if (index < 0)
|
||||
{
|
||||
index = _availablePartDictionary[CharacterPartType.ArmUpperLeft].Count - 1;
|
||||
}
|
||||
|
||||
_partIndexDictionary[CharacterPartType.ArmUpperLeft] = index;
|
||||
UpdateModel();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles the click on the forward button for the ArmUpperRight part.
|
||||
/// </summary>
|
||||
public void ForwardUpperArmRight()
|
||||
{
|
||||
int index = _partIndexDictionary[CharacterPartType.ArmUpperRight];
|
||||
index++;
|
||||
if (index >= _availablePartDictionary[CharacterPartType.ArmUpperRight].Count)
|
||||
{
|
||||
index = 0;
|
||||
}
|
||||
|
||||
_partIndexDictionary[CharacterPartType.ArmUpperRight] = index;
|
||||
UpdateModel();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles the click on the backward button for the ArmUpperRight part.
|
||||
/// </summary>
|
||||
public void BackwardUpperArmRight()
|
||||
{
|
||||
int index = _partIndexDictionary[CharacterPartType.ArmUpperRight];
|
||||
index--;
|
||||
if (index < 0)
|
||||
{
|
||||
index = _availablePartDictionary[CharacterPartType.ArmUpperRight].Count - 1;
|
||||
}
|
||||
|
||||
_partIndexDictionary[CharacterPartType.ArmUpperRight] = index;
|
||||
UpdateModel();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles the click on the forward button for the ArmLowerLeft part.
|
||||
/// </summary>
|
||||
public void ForwardLowerArmLeft()
|
||||
{
|
||||
int index = _partIndexDictionary[CharacterPartType.ArmLowerLeft];
|
||||
index++;
|
||||
if (index >= _availablePartDictionary[CharacterPartType.ArmLowerLeft].Count)
|
||||
{
|
||||
index = 0;
|
||||
}
|
||||
|
||||
_partIndexDictionary[CharacterPartType.ArmLowerLeft] = index;
|
||||
UpdateModel();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles the click on the backward button for the ArmLowerLeft part.
|
||||
/// </summary>
|
||||
public void BackwardLowerArmLeft()
|
||||
{
|
||||
int index = _partIndexDictionary[CharacterPartType.ArmLowerLeft];
|
||||
index--;
|
||||
if (index < 0)
|
||||
{
|
||||
index = _availablePartDictionary[CharacterPartType.ArmLowerLeft].Count - 1;
|
||||
}
|
||||
|
||||
_partIndexDictionary[CharacterPartType.ArmLowerLeft] = index;
|
||||
UpdateModel();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles the click on the forward button for the ArmLowerRight part.
|
||||
/// </summary>
|
||||
public void ForwardLowerArmRight()
|
||||
{
|
||||
int index = _partIndexDictionary[CharacterPartType.ArmLowerRight];
|
||||
index++;
|
||||
if (index >= _availablePartDictionary[CharacterPartType.ArmLowerRight].Count)
|
||||
{
|
||||
index = 0;
|
||||
}
|
||||
|
||||
_partIndexDictionary[CharacterPartType.ArmLowerRight] = index;
|
||||
UpdateModel();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles the click on the backward button for the ArmLowerRight part.
|
||||
/// </summary>
|
||||
public void BackwardLowerArmRight()
|
||||
{
|
||||
int index = _partIndexDictionary[CharacterPartType.ArmLowerRight];
|
||||
index--;
|
||||
if (index < 0)
|
||||
{
|
||||
index = _availablePartDictionary[CharacterPartType.ArmLowerRight].Count - 1;
|
||||
}
|
||||
|
||||
_partIndexDictionary[CharacterPartType.ArmLowerRight] = index;
|
||||
UpdateModel();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles the click on the forward button for the HandLeft part.
|
||||
/// </summary>
|
||||
public void ForwardHandLeft()
|
||||
{
|
||||
int index = _partIndexDictionary[CharacterPartType.HandLeft];
|
||||
index++;
|
||||
if (index >= _availablePartDictionary[CharacterPartType.HandLeft].Count)
|
||||
{
|
||||
index = 0;
|
||||
}
|
||||
|
||||
_partIndexDictionary[CharacterPartType.HandLeft] = index;
|
||||
UpdateModel();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles the click on the backward button for the HandLeft part.
|
||||
/// </summary>
|
||||
public void BackwardHandLeft()
|
||||
{
|
||||
int index = _partIndexDictionary[CharacterPartType.HandLeft];
|
||||
index--;
|
||||
if (index < 0)
|
||||
{
|
||||
index = _availablePartDictionary[CharacterPartType.HandLeft].Count - 1;
|
||||
}
|
||||
|
||||
_partIndexDictionary[CharacterPartType.HandLeft] = index;
|
||||
UpdateModel();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles the click on the forward button for the HandRight part.
|
||||
/// </summary>
|
||||
public void ForwardHandRight()
|
||||
{
|
||||
int index = _partIndexDictionary[CharacterPartType.HandRight];
|
||||
index++;
|
||||
if (index >= _availablePartDictionary[CharacterPartType.HandRight].Count)
|
||||
{
|
||||
index = 0;
|
||||
}
|
||||
|
||||
_partIndexDictionary[CharacterPartType.HandRight] = index;
|
||||
UpdateModel();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles the click on the backward button for the HandRight part.
|
||||
/// </summary>
|
||||
public void BackwardHandRight()
|
||||
{
|
||||
int index = _partIndexDictionary[CharacterPartType.HandRight];
|
||||
index--;
|
||||
if (index < 0)
|
||||
{
|
||||
index = _availablePartDictionary[CharacterPartType.HandRight].Count - 1;
|
||||
}
|
||||
|
||||
_partIndexDictionary[CharacterPartType.HandRight] = index;
|
||||
UpdateModel();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles the click on the forward button for the AttachmentBack part.
|
||||
/// </summary>
|
||||
public void ForwardBackAttachment()
|
||||
{
|
||||
int index = _partIndexDictionary[CharacterPartType.AttachmentBack];
|
||||
index++;
|
||||
if (index >= _availablePartDictionary[CharacterPartType.AttachmentBack].Count)
|
||||
{
|
||||
index = 0;
|
||||
}
|
||||
|
||||
_partIndexDictionary[CharacterPartType.AttachmentBack] = index;
|
||||
UpdateModel();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles the click on the backward button for the AttachmentBack part.
|
||||
/// </summary>
|
||||
public void BackwardBackAttachment()
|
||||
{
|
||||
int index = _partIndexDictionary[CharacterPartType.AttachmentBack];
|
||||
index--;
|
||||
if (index < 0)
|
||||
{
|
||||
index = _availablePartDictionary[CharacterPartType.AttachmentBack].Count - 1;
|
||||
}
|
||||
|
||||
_partIndexDictionary[CharacterPartType.AttachmentBack] = index;
|
||||
UpdateModel();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the body size blends based on the slider values.
|
||||
/// </summary>
|
||||
/// <param name="slider">The UI slider to get the values from.</param>
|
||||
public void UpdateBodySize(Slider slider)
|
||||
{
|
||||
// If the slider is greater than 0, then we update the Heavy blend and zero the Skinny.
|
||||
if (slider.value > 0)
|
||||
{
|
||||
_sidekickRuntime.BodySizeHeavyBlendValue = slider.value;
|
||||
_sidekickRuntime.BodySizeSkinnyBlendValue = 0;
|
||||
}
|
||||
// If the slider is 0 or below, we zero the Heavy blend, then we update the Skinny blend.
|
||||
else
|
||||
{
|
||||
_sidekickRuntime.BodySizeHeavyBlendValue = 0;
|
||||
_sidekickRuntime.BodySizeSkinnyBlendValue = -slider.value;
|
||||
}
|
||||
|
||||
UpdateModel();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the created character model.
|
||||
/// </summary>
|
||||
private void UpdateModel()
|
||||
{
|
||||
// Create and populate the list of parts to use from the parts list.
|
||||
List<SkinnedMeshRenderer> partsToUse = new List<SkinnedMeshRenderer>();
|
||||
|
||||
foreach (KeyValuePair<CharacterPartType, Dictionary<string, SidekickPart>> entry in _availablePartDictionary)
|
||||
{
|
||||
int index = _partIndexDictionary[entry.Key];
|
||||
List<SidekickPart> parts = entry.Value.Values.ToList();
|
||||
GameObject partContainer = null;
|
||||
if (parts.Count > 0 && index < parts.Count)
|
||||
{
|
||||
if (index > parts.Count)
|
||||
{
|
||||
index = parts.Count - 1;
|
||||
}
|
||||
partContainer = parts[index].GetPartModel();
|
||||
}
|
||||
|
||||
if (partContainer != null)
|
||||
{
|
||||
partsToUse.Add(partContainer.GetComponentInChildren<SkinnedMeshRenderer>());
|
||||
}
|
||||
}
|
||||
|
||||
// Check for an existing copy of the model, if it exists, delete it so that we don't end up with duplicates.
|
||||
GameObject character = GameObject.Find(_OUTPUT_MODEL_NAME);
|
||||
|
||||
if (character != null)
|
||||
{
|
||||
Destroy(character);
|
||||
}
|
||||
|
||||
// Create a new character using the selected parts using the Sidekicks API.
|
||||
character = _sidekickRuntime.CreateCharacter(_OUTPUT_MODEL_NAME, partsToUse, false, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/External/Models/SidekickCharacters/_Demos/Scripts/RuntimePartsDemo.cs.meta
vendored
Normal file
11
Assets/External/Models/SidekickCharacters/_Demos/Scripts/RuntimePartsDemo.cs.meta
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2f5d22b950f039748823633052820ad9
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
325
Assets/External/Models/SidekickCharacters/_Demos/Scripts/RuntimePresetDemo.cs
vendored
Normal file
325
Assets/External/Models/SidekickCharacters/_Demos/Scripts/RuntimePresetDemo.cs
vendored
Normal file
@@ -0,0 +1,325 @@
|
||||
using Synty.SidekickCharacters.API;
|
||||
using Synty.SidekickCharacters.Database;
|
||||
using Synty.SidekickCharacters.Database.DTO;
|
||||
using Synty.SidekickCharacters.Enums;
|
||||
using Synty.SidekickCharacters.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using Random = UnityEngine.Random;
|
||||
|
||||
namespace Synty.SidekickCharacters.Demo
|
||||
{
|
||||
/// <summary>
|
||||
/// An example script to show how to interact with the Sidekick API in regards to presets at runtime.
|
||||
/// </summary>
|
||||
public class RuntimePresetDemo : MonoBehaviour
|
||||
{
|
||||
private readonly string _OUTPUT_MODEL_NAME = "Sidekick Character";
|
||||
|
||||
private Dictionary<string, SidekickPartPreset> _availableHeadPresetDictionary = new Dictionary<string, SidekickPartPreset>();
|
||||
private Dictionary<string, SidekickPartPreset> _availableUpperBodyPresetDictionary = new Dictionary<string, SidekickPartPreset>();
|
||||
private Dictionary<string, SidekickPartPreset> _availableLowerBodyPresetDictionary = new Dictionary<string, SidekickPartPreset>();
|
||||
private List<SidekickBodyShapePreset> _availableBodyShapes = new List<SidekickBodyShapePreset>();
|
||||
private List<SidekickColorPreset> _availableColorPresets = new List<SidekickColorPreset>();
|
||||
|
||||
private int _currentHeadPresetIndex = 0;
|
||||
private int _currentUpperBodyPresetIndex = 0;
|
||||
private int _currentLowerBodyPresetIndex = 0;
|
||||
private int _currentBodyShapePresetIndex = 0;
|
||||
private int _currentColorPresetIndex = 0;
|
||||
|
||||
private DatabaseManager _dbManager;
|
||||
private SidekickRuntime _sidekickRuntime;
|
||||
|
||||
private Dictionary<CharacterPartType, Dictionary<string, SidekickPart>> _partLibrary;
|
||||
|
||||
public TextMeshProUGUI _loadingText;
|
||||
|
||||
/// <inheritdoc cref="Start"/>
|
||||
void Start()
|
||||
{
|
||||
_dbManager = new DatabaseManager();
|
||||
|
||||
GameObject model = Resources.Load<GameObject>("Meshes/SK_BaseModel");
|
||||
Material material = Resources.Load<Material>("Materials/M_BaseMaterial");
|
||||
|
||||
_sidekickRuntime = new SidekickRuntime(model, material, null, _dbManager);
|
||||
SidekickRuntime.PopulateToolData(_sidekickRuntime);
|
||||
_partLibrary = _sidekickRuntime.MappedPartDictionary;
|
||||
|
||||
foreach (PartGroup partGroup in Enum.GetValues(typeof(PartGroup)))
|
||||
{
|
||||
// only filter head part presets by species
|
||||
List<SidekickPartPreset> presets = SidekickPartPreset.GetAllByGroup(_dbManager, partGroup);
|
||||
List<string> presetNames = new List<string>();
|
||||
if (presets.Count < 1)
|
||||
{
|
||||
Debug.LogWarning("No parts found for " + partGroup + ". Please add at least 1 Sidekicks content pack.");
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach (SidekickPartPreset preset in presets)
|
||||
{
|
||||
if (preset.HasAllPartsAvailable(_dbManager))
|
||||
{
|
||||
switch (partGroup)
|
||||
{
|
||||
case PartGroup.Head:
|
||||
_availableHeadPresetDictionary.Add(preset.Name, preset);
|
||||
break;
|
||||
|
||||
case PartGroup.UpperBody:
|
||||
_availableUpperBodyPresetDictionary.Add(preset.Name, preset);
|
||||
break;
|
||||
|
||||
case PartGroup.LowerBody:
|
||||
_availableLowerBodyPresetDictionary.Add(preset.Name, preset);
|
||||
break;
|
||||
}
|
||||
presetNames.Add(preset.Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_availableBodyShapes = SidekickBodyShapePreset.GetAll(_dbManager);
|
||||
|
||||
// An example of how to retrieve color presets from the database. To retrieve presets for other areas of the material, use the ColorGroup
|
||||
// enum to retrieve other presets.
|
||||
_availableColorPresets = SidekickColorPreset.GetAllByColorGroup(_dbManager, ColorGroup.Outfits);
|
||||
|
||||
_currentHeadPresetIndex = Random.Range(0, _availableHeadPresetDictionary.Count - 1);
|
||||
_currentUpperBodyPresetIndex = Random.Range(0, _availableUpperBodyPresetDictionary.Count - 1);
|
||||
_currentLowerBodyPresetIndex = Random.Range(0, _availableLowerBodyPresetDictionary.Count - 1);
|
||||
_currentBodyShapePresetIndex = Random.Range(0, _availableBodyShapes.Count - 1);
|
||||
_currentColorPresetIndex = Random.Range(0, _availableColorPresets.Count - 1);
|
||||
|
||||
_loadingText.enabled = false;
|
||||
|
||||
UpdateModel();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles the click on the forward button for the Head Preset.
|
||||
/// </summary>
|
||||
public void ForwardHeadPreset()
|
||||
{
|
||||
_currentHeadPresetIndex++;
|
||||
if (_currentHeadPresetIndex >= _availableHeadPresetDictionary.Count)
|
||||
{
|
||||
_currentHeadPresetIndex = 0;
|
||||
}
|
||||
|
||||
UpdateModel();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles the click on the backward button for the Head Preset.
|
||||
/// </summary>
|
||||
public void BackwardHeadPreset()
|
||||
{
|
||||
_currentHeadPresetIndex--;
|
||||
if (_currentHeadPresetIndex < 0)
|
||||
{
|
||||
_currentHeadPresetIndex = _availableHeadPresetDictionary.Count - 1;
|
||||
}
|
||||
|
||||
UpdateModel();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles the click on the forward button for the Upper Body Preset.
|
||||
/// </summary>
|
||||
public void ForwardUpperBodyPreset()
|
||||
{
|
||||
_currentUpperBodyPresetIndex++;
|
||||
if (_currentUpperBodyPresetIndex >= _availableUpperBodyPresetDictionary.Count)
|
||||
{
|
||||
_currentUpperBodyPresetIndex = 0;
|
||||
}
|
||||
|
||||
UpdateModel();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles the click on the backward button for the Upper Body Preset.
|
||||
/// </summary>
|
||||
public void BackwardUpperBodyPreset()
|
||||
{
|
||||
_currentUpperBodyPresetIndex--;
|
||||
if (_currentUpperBodyPresetIndex < 0)
|
||||
{
|
||||
_currentUpperBodyPresetIndex = _availableUpperBodyPresetDictionary.Count - 1;
|
||||
}
|
||||
|
||||
UpdateModel();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles the click on the forward button for the Lower Body Preset.
|
||||
/// </summary>
|
||||
public void ForwardLowerBodyPreset()
|
||||
{
|
||||
_currentLowerBodyPresetIndex++;
|
||||
if (_currentLowerBodyPresetIndex >= _availableLowerBodyPresetDictionary.Count)
|
||||
{
|
||||
_currentLowerBodyPresetIndex = 0;
|
||||
}
|
||||
|
||||
UpdateModel();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles the click on the backward button for the Lower Body Preset.
|
||||
/// </summary>
|
||||
public void BackwardLowerBodyPreset()
|
||||
{
|
||||
_currentLowerBodyPresetIndex--;
|
||||
if (_currentLowerBodyPresetIndex < 0)
|
||||
{
|
||||
_currentLowerBodyPresetIndex = _availableLowerBodyPresetDictionary.Count - 1;
|
||||
}
|
||||
|
||||
UpdateModel();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles the click on the forward button for the Body Shape Preset.
|
||||
/// </summary>
|
||||
public void ForwardBodyShapePreset()
|
||||
{
|
||||
_currentBodyShapePresetIndex++;
|
||||
if (_currentBodyShapePresetIndex >= _availableBodyShapes.Count)
|
||||
{
|
||||
_currentBodyShapePresetIndex = 0;
|
||||
}
|
||||
|
||||
UpdateModel();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles the click on the backward button for the Body Shape Preset.
|
||||
/// </summary>
|
||||
public void BackwardBodyShapePreset()
|
||||
{
|
||||
_currentBodyShapePresetIndex--;
|
||||
if (_currentBodyShapePresetIndex < 0)
|
||||
{
|
||||
_currentBodyShapePresetIndex = _availableBodyShapes.Count - 1;
|
||||
}
|
||||
|
||||
UpdateModel();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles the click on the forward button for the Color Preset.
|
||||
/// </summary>
|
||||
public void ForwardColorPreset()
|
||||
{
|
||||
_currentColorPresetIndex++;
|
||||
if (_currentColorPresetIndex >= _availableColorPresets.Count)
|
||||
{
|
||||
_currentColorPresetIndex = 0;
|
||||
}
|
||||
|
||||
UpdateModel();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles the click on the backward button for the Color Preset.
|
||||
/// </summary>
|
||||
public void BackwardColorPreset()
|
||||
{
|
||||
_currentColorPresetIndex--;
|
||||
if (_currentColorPresetIndex < 0)
|
||||
{
|
||||
_currentColorPresetIndex = _availableColorPresets.Count - 1;
|
||||
}
|
||||
|
||||
UpdateModel();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the created character model.
|
||||
/// </summary>
|
||||
private void UpdateModel()
|
||||
{
|
||||
// If there aren't enough presets, stop trying to update the model.
|
||||
if (_availableHeadPresetDictionary.Values.Count < 1
|
||||
|| _availableUpperBodyPresetDictionary.Values.Count < 1
|
||||
|| _availableLowerBodyPresetDictionary.Values.Count < 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Create and populate the list of parts to use from the parts list, and the selected presets.
|
||||
List<SidekickPartPreset> presets = new List<SidekickPartPreset>()
|
||||
{
|
||||
_availableHeadPresetDictionary.Values.ToArray()[_currentHeadPresetIndex],
|
||||
_availableUpperBodyPresetDictionary.Values.ToArray()[_currentUpperBodyPresetIndex],
|
||||
_availableLowerBodyPresetDictionary.Values.ToArray()[_currentLowerBodyPresetIndex]
|
||||
};
|
||||
|
||||
List<SkinnedMeshRenderer> partsToUse = new List<SkinnedMeshRenderer>();
|
||||
|
||||
foreach (SidekickPartPreset preset in presets)
|
||||
{
|
||||
List<SidekickPartPresetRow> rows = SidekickPartPresetRow.GetAllByPreset(_dbManager, preset);
|
||||
foreach (SidekickPartPresetRow row in rows)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(row.PartName))
|
||||
{
|
||||
CharacterPartType type = Enum.Parse<CharacterPartType>(CharacterPartTypeUtils.GetTypeNameFromShortcode(row.PartType));
|
||||
Dictionary<string, SidekickPart> partLocationDictionary = _partLibrary[type];
|
||||
GameObject selectedPart = partLocationDictionary[row.PartName].GetPartModel();
|
||||
SkinnedMeshRenderer selectedMesh = selectedPart.GetComponentInChildren<SkinnedMeshRenderer>();
|
||||
partsToUse.Add(selectedMesh);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SidekickBodyShapePreset bodyPreset = _availableBodyShapes[_currentBodyShapePresetIndex];
|
||||
_sidekickRuntime.BodyTypeBlendValue = bodyPreset.BodyType;
|
||||
_sidekickRuntime.BodySizeHeavyBlendValue = bodyPreset.BodySize > 0 ? bodyPreset.BodySize : 0;
|
||||
_sidekickRuntime.BodySizeSkinnyBlendValue = bodyPreset.BodySize < 0 ? -bodyPreset.BodySize : 0;
|
||||
_sidekickRuntime.MusclesBlendValue = bodyPreset.Musculature;
|
||||
|
||||
List<SidekickColorPresetRow> colorRows = SidekickColorPresetRow.GetAllByPreset(_dbManager, _availableColorPresets[_currentColorPresetIndex]);
|
||||
foreach (SidekickColorPresetRow row in colorRows)
|
||||
{
|
||||
SidekickColorRow colorRow = SidekickColorRow.CreateFromPresetColorRow(row);
|
||||
foreach (ColorType property in Enum.GetValues(typeof(ColorType)))
|
||||
{
|
||||
_sidekickRuntime.UpdateColor(property, colorRow);
|
||||
}
|
||||
}
|
||||
|
||||
// Check for an existing copy of the model, if it exists, delete it so that we don't end up with duplicates.
|
||||
GameObject character = GameObject.Find(_OUTPUT_MODEL_NAME);
|
||||
|
||||
if (character != null)
|
||||
{
|
||||
Destroy(character);
|
||||
}
|
||||
|
||||
// Create a new character using the selected parts using the Sidekicks API.
|
||||
character = _sidekickRuntime.CreateCharacter(_OUTPUT_MODEL_NAME, partsToUse, false, true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a resource path for using with Resources.Load() from a full path.
|
||||
/// </summary>
|
||||
/// <param name="fullPath">The full path to get the resource path from.</param>
|
||||
/// <returns>The resource path.</returns>
|
||||
private string GetResourcePath(string fullPath)
|
||||
{
|
||||
string directory = Path.GetDirectoryName(fullPath);
|
||||
int startIndex = directory.IndexOf("Resources") + 10;
|
||||
directory = directory.Substring(startIndex, directory.Length - startIndex);
|
||||
return Path.Combine(directory, Path.GetFileNameWithoutExtension(fullPath));
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/External/Models/SidekickCharacters/_Demos/Scripts/RuntimePresetDemo.cs.meta
vendored
Normal file
11
Assets/External/Models/SidekickCharacters/_Demos/Scripts/RuntimePresetDemo.cs.meta
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7bd72354e145926468bfa3d99c0a2027
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user