init
This commit is contained in:
@@ -0,0 +1,178 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using InfinityPBR.ModularCharacterHelper;
|
||||
using Sirenix.OdinInspector;
|
||||
using Sirenix.Utilities;
|
||||
using UnityEngine;
|
||||
using VOID.Generic.Dict;
|
||||
using VOID.Generic.Objects.Unit;
|
||||
using VOID.Generic.Util;
|
||||
using Random = UnityEngine.Random;
|
||||
|
||||
namespace VOID.ScriptableObjects
|
||||
{
|
||||
[CreateAssetMenu(menuName = "GAME DATA/Generator/Generator Jednostki")]
|
||||
public class UnitGenerator : ScriptableObject
|
||||
{
|
||||
[Title("Unit References")]
|
||||
[SerializeField] private UnitObject[] _unitPrefabs;
|
||||
[SerializeField] private Material[] _skinMaterials;
|
||||
[SerializeField] private Material[] _hairMaterials;
|
||||
|
||||
[Space(100)]
|
||||
[Title("Model")]
|
||||
[InfoBox("If prefab part can't be attached to unit prefab then it'll be skipped!")]
|
||||
[SerializeField] private bool _generateHair;
|
||||
[SerializeField, ShowIf(nameof(_generateHair)), Required] private ModularPart[] _hairPrefabs;
|
||||
|
||||
[Title("Colors")]
|
||||
[InfoBox("If colors list is empty then randomize new one!")]
|
||||
[SerializeField] private bool _generateSkinColor;
|
||||
[SerializeField, ShowIf(nameof(_generateSkinColor))] private Color[] _skinColors;
|
||||
[SerializeField] private bool _generateHairColor;
|
||||
[SerializeField, ShowIf(nameof(_generateHairColor))] private Color[] _hairColors;
|
||||
|
||||
[Title("Main Attributes")]
|
||||
[SerializeField] private bool _generateMainAttributes;
|
||||
[SerializeField, ShowIf(nameof(_generateMainAttributes)), MinMaxSlider(1, 50, true)] private Vector2Int _strength = new(4, 7);
|
||||
[SerializeField, ShowIf(nameof(_generateMainAttributes)), MinMaxSlider(1, 50, true)] private Vector2Int _dexterity = new(4, 7);
|
||||
[SerializeField, ShowIf(nameof(_generateMainAttributes)), MinMaxSlider(1, 50, true)] private Vector2Int _intelligence = new(4, 7);
|
||||
[SerializeField, ShowIf(nameof(_generateMainAttributes)), MinMaxSlider(1, 50, true)] private Vector2Int _constitution = new(4, 7);
|
||||
[SerializeField, ShowIf(nameof(_generateMainAttributes)), MinMaxSlider(1, 50, true)] private Vector2Int _speed = new(4, 7);
|
||||
[SerializeField, ShowIf(nameof(_generateMainAttributes)), MinMaxSlider(1, 50, true)] private Vector2Int _perception = new(4, 7);
|
||||
|
||||
private void OnValidate()
|
||||
{
|
||||
if (!_generateHair)
|
||||
{
|
||||
_hairPrefabs = null;
|
||||
}
|
||||
|
||||
if (!_generateSkinColor)
|
||||
{
|
||||
_skinColors = null;
|
||||
}
|
||||
|
||||
if (!_generateHairColor)
|
||||
{
|
||||
_hairColors = null;
|
||||
}
|
||||
|
||||
if (!_generateMainAttributes)
|
||||
{
|
||||
_strength = new Vector2Int(4, 7);
|
||||
_dexterity = new Vector2Int(4, 7);
|
||||
_intelligence = new Vector2Int(4, 7);
|
||||
_constitution = new Vector2Int(4, 7);
|
||||
_speed = new Vector2Int(4, 7);
|
||||
_perception = new Vector2Int(4, 7);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generate new <see cref="UnitObject"/>:<br/>
|
||||
/// 1. Selects random <see cref="UnitObject"/> prefab<br/>
|
||||
/// 2. Wait for full initialization of <see cref="UnitObject"/><br/>
|
||||
/// 3. Updates <see cref="UnitObject"/> with random things defined via inspector
|
||||
/// </summary>
|
||||
/// <returns>Instantiated random <see cref="UnitObject"/></returns>
|
||||
public UnitObject Generate(int? seed = null)
|
||||
{
|
||||
if (seed.HasValue) RandomUtil.InitState(seed.Value);
|
||||
var unit = Instantiate(RandomUtil.RandomElement(_unitPrefabs));
|
||||
Randomize(unit);
|
||||
return unit;
|
||||
}
|
||||
|
||||
private void Randomize(UnitObject unit)
|
||||
{
|
||||
RandomizeHair(unit);
|
||||
RandomizeSkinColor(unit);
|
||||
RandomizeHairColor(unit);
|
||||
RandomizeMainAttributes(unit);
|
||||
}
|
||||
|
||||
private void RandomizeHair(UnitObject unit)
|
||||
{
|
||||
if (!_generateHair) return;
|
||||
|
||||
var modularCharacter = unit.unitState.modularCharacter;
|
||||
var validHairPrefabs = _hairPrefabs.Where(hair => hair.avatar == modularCharacter.avatar).ToList();
|
||||
|
||||
if (validHairPrefabs.IsNullOrEmpty()) return;
|
||||
|
||||
modularCharacter.AttachPart(Instantiate(RandomUtil.RandomElement(validHairPrefabs), unit.transform));
|
||||
}
|
||||
|
||||
private void RandomizeSkinColor(UnitObject unit)
|
||||
{
|
||||
if (!_generateSkinColor) return;
|
||||
if (_skinMaterials.IsNullOrEmpty()) return;
|
||||
|
||||
ApplyTintToMaterials(unit, _skinColors, _skinMaterials);
|
||||
}
|
||||
|
||||
private void RandomizeHairColor(UnitObject unit)
|
||||
{
|
||||
if (!_generateHairColor) return;
|
||||
if (_hairMaterials.IsNullOrEmpty()) return;
|
||||
|
||||
ApplyTintToMaterials(unit, _hairColors, _hairMaterials);
|
||||
}
|
||||
|
||||
private void ApplyTintToMaterials(UnitObject unit, Color[] colors, Material[] forMaterials)
|
||||
{
|
||||
// Find renderers with this material to add tint color
|
||||
var foundRenderers = unit.GetComponentsInChildren<Renderer>()
|
||||
.Where(renderer => forMaterials.Any(material => renderer.sharedMaterials.Contains(material)))
|
||||
.ToList();
|
||||
|
||||
if (foundRenderers.IsNullOrEmpty()) return;
|
||||
|
||||
// Get random defined color if present OR randomize new one
|
||||
var color = colors.IsNullOrEmpty()
|
||||
? Random.ColorHSV(0, 1, 0, 1, 0, 1, 0, 1)
|
||||
: RandomUtil.RandomElement(colors);
|
||||
|
||||
// Normally renderers here will use shared materials, but we want to create colored "variants" thats why
|
||||
// we need to instantiate material and add tint color if this is matching material. Other materials will
|
||||
// instantiate too anyway even without our help so lets do all of them by ourselfs!
|
||||
foreach (var foundRenderer in foundRenderers)
|
||||
{
|
||||
var materials = new List<Material>();
|
||||
foreach (var sharedMaterial in foundRenderer.sharedMaterials)
|
||||
{
|
||||
if (forMaterials.Contains(sharedMaterial))
|
||||
{
|
||||
var material = Instantiate(sharedMaterial);
|
||||
material.color = color;
|
||||
materials.Add(material);
|
||||
}
|
||||
else
|
||||
{
|
||||
materials.Add(sharedMaterial);
|
||||
}
|
||||
}
|
||||
foundRenderer.sharedMaterials = materials.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
private void RandomizeMainAttributes(UnitObject unit)
|
||||
{
|
||||
if (!_generateMainAttributes) return;
|
||||
|
||||
unit.unitData.baseMainAttributes.Set(MainAttributeType.Strength,
|
||||
RandomUtil.RandomInteger(_strength.x, _strength.y));
|
||||
unit.unitData.baseMainAttributes.Set(MainAttributeType.Dexterity,
|
||||
RandomUtil.RandomInteger(_dexterity.x, _dexterity.y));
|
||||
unit.unitData.baseMainAttributes.Set(MainAttributeType.Intelligence,
|
||||
RandomUtil.RandomInteger(_intelligence.x, _intelligence.y));
|
||||
unit.unitData.baseMainAttributes.Set(MainAttributeType.Constitution,
|
||||
RandomUtil.RandomInteger(_constitution.x, _constitution.y));
|
||||
unit.unitData.baseMainAttributes.Set(MainAttributeType.Speed,
|
||||
RandomUtil.RandomInteger(_speed.x, _speed.y));
|
||||
unit.unitData.baseMainAttributes.Set(MainAttributeType.Perception,
|
||||
RandomUtil.RandomInteger(_perception.x, _perception.y));
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user