447 lines
15 KiB
C#
447 lines
15 KiB
C#
|
using System.Collections;
|
||
|
using System.Collections.Generic;
|
||
|
using UnityEngine;
|
||
|
using UnityEngine.InputSystem;
|
||
|
using RPGCreationKit;
|
||
|
using UnityEngine.UI;
|
||
|
using TMPro;
|
||
|
using RPGCreationKit.SaveSystem;
|
||
|
using System.IO;
|
||
|
|
||
|
public class CharacterCreationManager : MonoBehaviour
|
||
|
{
|
||
|
[Header("SETTINGS")]
|
||
|
public Race[] playableRaces;
|
||
|
public Race defaultRace;
|
||
|
|
||
|
public Race selectedRace;
|
||
|
public RuntimeAnimatorController animControllerMale;
|
||
|
public RuntimeAnimatorController animControllerFemale;
|
||
|
|
||
|
|
||
|
[SerializeField] private PlayerInput input;
|
||
|
[SerializeField] private Animator camAnimator;
|
||
|
|
||
|
[SerializeField] public bool isCreatingMale = true;
|
||
|
|
||
|
public BodyData currentCharacter;
|
||
|
|
||
|
[SerializeField] private GameObject LeftPanelMenu;
|
||
|
[SerializeField] private GameObject LeftPanelSaveLoad;
|
||
|
[SerializeField] private GameObject LeftPanelFaceMenu;
|
||
|
[SerializeField] private GameObject PanelHairMenu;
|
||
|
[SerializeField] private GameObject PanelSkinMenu;
|
||
|
[SerializeField] private GameObject PanelLipsMenu;
|
||
|
[SerializeField] private GameObject ColorMenu;
|
||
|
[SerializeField] private GameObject PlayerSexManu;
|
||
|
[SerializeField] private List<TextMeshProUGUI> SetStats;
|
||
|
|
||
|
[SerializeField] private TMP_InputField characterNameField;
|
||
|
|
||
|
[SerializeField] private GameObject messagePanel;
|
||
|
[SerializeField] private GameObject messageBoxErrorName;
|
||
|
[SerializeField] private GameObject messageBoxConfirmation;
|
||
|
|
||
|
[SerializeField] private Transform characterT;
|
||
|
|
||
|
[SerializeField] private Toggle maleToggle;
|
||
|
[SerializeField] private Toggle editFaceButton;
|
||
|
|
||
|
[SerializeField] private GameObject headBlendshapePrefab;
|
||
|
[SerializeField] public Transform headBlendshapeContent;
|
||
|
|
||
|
[SerializeField] public Color HairColor = new Color(255, 255, 255);
|
||
|
[SerializeField] public Color LipsColor = new Color(255, 255, 255);
|
||
|
[SerializeField] public Color SkinColor = new Color(255, 255, 255);
|
||
|
|
||
|
[SerializeField] private TextMeshProUGUI raceNameText;
|
||
|
[SerializeField] private TextMeshProUGUI hairTypeText;
|
||
|
[SerializeField] private TextMeshProUGUI eyesTypeText;
|
||
|
[SerializeField] public int selectedHair = 0;
|
||
|
[SerializeField] public int selectedEyes = 0;
|
||
|
[SerializeField] private int selectedRaceIndex = 0;
|
||
|
[SerializeField] private int BlendshapeCounted = 0;
|
||
|
public FlexibleColorPicker HairColorChanger;
|
||
|
public FlexibleColorPicker SkinColorChanger;
|
||
|
public FlexibleColorPicker LipsColorChanger;
|
||
|
|
||
|
// Start is called before the first frame update
|
||
|
void Start()
|
||
|
{
|
||
|
RckInput.LoadInputSave();
|
||
|
RckInput.SetPlayerInputInstance(input);
|
||
|
|
||
|
// Add color changers
|
||
|
HairColorChanger.onColorChange.AddListener(OnChangeHairColor);
|
||
|
SkinColorChanger.onColorChange.AddListener(OnChangeSkinColor);
|
||
|
LipsColorChanger.onColorChange.AddListener(OnChangeLipsColor);
|
||
|
|
||
|
selectedRace = defaultRace;
|
||
|
|
||
|
// Load default race
|
||
|
LoadRaceCharacter(selectedRace);
|
||
|
}
|
||
|
|
||
|
|
||
|
public void LoadRaceCharacter(Race race)
|
||
|
{
|
||
|
selectedHair = 0;
|
||
|
selectedEyes = 0;
|
||
|
|
||
|
// Destroy all in character T
|
||
|
foreach (Transform T in characterT)
|
||
|
Destroy(T.gameObject);
|
||
|
|
||
|
// Spawn the character
|
||
|
GameObject toSpawn = (isCreatingMale) ? race.maleModel.gameObject : race.femaleModel.gameObject;
|
||
|
|
||
|
GameObject character = Instantiate(toSpawn, characterT);
|
||
|
currentCharacter = character.GetComponent<BodyData>();
|
||
|
|
||
|
Animator anim = character.GetComponent<Animator>();
|
||
|
|
||
|
if(anim != null)
|
||
|
{
|
||
|
var animController = (isCreatingMale) ? animControllerMale : animControllerFemale;
|
||
|
anim.runtimeAnimatorController = animController;
|
||
|
anim.enabled = true;
|
||
|
}
|
||
|
raceNameText.text = race.raceName;
|
||
|
}
|
||
|
|
||
|
public void OnChangeHairColor(Color co) {
|
||
|
HairColor = co;
|
||
|
SkinnedMeshRenderer Hair = currentCharacter.hair;
|
||
|
Material[] MyMats = Hair.materials;
|
||
|
for (int i = 0; i < MyMats.Length; i++)
|
||
|
MyMats[i].SetColor("_Diffuse", co);
|
||
|
}
|
||
|
|
||
|
public void OnChangeLipsColor(Color co) {
|
||
|
LipsColor = co;
|
||
|
SkinnedMeshRenderer Lips = currentCharacter.Lips;
|
||
|
Material[] MyMats = Lips.materials;
|
||
|
for (int i = 0; i < MyMats.Length; i++)
|
||
|
MyMats[i].SetColor("_Diffuse", co);
|
||
|
}
|
||
|
|
||
|
public void OnChangeSkinColor(Color co) {
|
||
|
SkinColor = co;
|
||
|
SkinnedMeshRenderer Torso = currentCharacter.upperbody;
|
||
|
SkinnedMeshRenderer Legs = currentCharacter.lowerbody;
|
||
|
SkinnedMeshRenderer Head = currentCharacter.head;
|
||
|
SkinnedMeshRenderer Arms = currentCharacter.arms;
|
||
|
SkinnedMeshRenderer Hands = currentCharacter.hands;
|
||
|
SkinnedMeshRenderer Feet = currentCharacter.feet;
|
||
|
SkinnedMeshRenderer Lips = currentCharacter.Lips;
|
||
|
|
||
|
Material[] MyTorsoMats = Torso.materials;
|
||
|
Material[] MyLegsMats = Legs.materials;
|
||
|
Material[] MyHeadMats = Head.materials;
|
||
|
Material[] MyArmsMats = Arms.materials;
|
||
|
Material[] MyHandsMats = Hands.materials;
|
||
|
Material[] MyFeetMats = Feet.materials;
|
||
|
Material[] MyLipsMats = Lips.materials;
|
||
|
|
||
|
for (int i = 0; i < MyTorsoMats.Length; i++)
|
||
|
MyTorsoMats[i].SetColor("_Diffuse", co);
|
||
|
for (int i = 0; i < MyLegsMats.Length; i++)
|
||
|
MyLegsMats[i].SetColor("_Diffuse", co);
|
||
|
for (int i = 0; i < MyHeadMats.Length; i++)
|
||
|
MyHeadMats[i].SetColor("_Diffuse", co);
|
||
|
for (int i = 0; i < MyArmsMats.Length; i++)
|
||
|
MyArmsMats[i].SetColor("_Diffuse", co);
|
||
|
for (int i = 0; i < MyHandsMats.Length; i++)
|
||
|
MyHandsMats[i].SetColor("_Diffuse", co);
|
||
|
for (int i = 0; i < MyFeetMats.Length; i++)
|
||
|
MyFeetMats[i].SetColor("_Diffuse", co);
|
||
|
}
|
||
|
|
||
|
public void OnMaleToggleChanges()
|
||
|
{
|
||
|
isCreatingMale = maleToggle.isOn;
|
||
|
LoadRaceCharacter(selectedRace);
|
||
|
if (LeftPanelFaceMenu.activeSelf)
|
||
|
foreach (Transform T in headBlendshapeContent)
|
||
|
Destroy(T.gameObject);
|
||
|
|
||
|
MakeBlendShapes();
|
||
|
}
|
||
|
|
||
|
public void ToggleSkinColor()
|
||
|
{
|
||
|
PanelLipsMenu.SetActive(false);
|
||
|
PanelHairMenu.SetActive(false);
|
||
|
PanelSkinMenu.SetActive(true);
|
||
|
}
|
||
|
|
||
|
public void ToggleLips()
|
||
|
{
|
||
|
PanelSkinMenu.SetActive(false);
|
||
|
PanelHairMenu.SetActive(false);
|
||
|
PanelLipsMenu.SetActive(true);
|
||
|
}
|
||
|
public void ToggleHairColor()
|
||
|
{
|
||
|
PanelLipsMenu.SetActive(false);
|
||
|
PanelHairMenu.SetActive(true);
|
||
|
PanelSkinMenu.SetActive(false);
|
||
|
}
|
||
|
|
||
|
public void EditFaceButton()
|
||
|
{
|
||
|
LeftPanelMenu.SetActive(false);
|
||
|
LeftPanelFaceMenu.SetActive(true);
|
||
|
PlayerSexManu.SetActive(true);
|
||
|
ColorMenu.SetActive(true);
|
||
|
LeftPanelSaveLoad.SetActive(false);
|
||
|
MakeBlendShapes();
|
||
|
}
|
||
|
|
||
|
public void SaveLoadButton()
|
||
|
{
|
||
|
LeftPanelMenu.SetActive(false);
|
||
|
LeftPanelFaceMenu.SetActive(false);
|
||
|
PlayerSexManu.SetActive(false);
|
||
|
ColorMenu.SetActive(false);
|
||
|
LeftPanelSaveLoad.SetActive(true);
|
||
|
}
|
||
|
|
||
|
public void MakeBlendShapes()
|
||
|
{
|
||
|
// Cam_BodyToFace();
|
||
|
|
||
|
SkinnedMeshRenderer Face = currentCharacter.head;
|
||
|
|
||
|
faceBlendshapes.Clear();
|
||
|
|
||
|
// Display all blendshapes
|
||
|
bool FoundEnd = false;
|
||
|
for (int i = 0; ((i < Face.sharedMesh.blendShapeCount) && (FoundEnd == false)); i++)
|
||
|
{
|
||
|
if (Face.sharedMesh.GetBlendShapeName(i).ToString().Contains("===")) {
|
||
|
FoundEnd = true;
|
||
|
BlendshapeCounted = i;
|
||
|
} else {
|
||
|
GameObject newBlendshape = Instantiate(headBlendshapePrefab, headBlendshapeContent);
|
||
|
BlendshapeInCreationList newBlendshapeScript = newBlendshape.GetComponent<BlendshapeInCreationList>();
|
||
|
newBlendshapeScript.usesHeadBlendshapes = true;
|
||
|
|
||
|
faceBlendshapes.Add(newBlendshapeScript.slider);
|
||
|
newBlendshapeScript.AssignBlendshape(Face, i, Face.sharedMesh.GetBlendShapeName(i).ToString());
|
||
|
}
|
||
|
}
|
||
|
if(faceBlendshapes.Count > 0 && RckInput.isUsingGamepad)
|
||
|
faceBlendshapes[0].Select();
|
||
|
|
||
|
}
|
||
|
|
||
|
public void BackFromFaceButton()
|
||
|
{
|
||
|
foreach (Transform T in headBlendshapeContent)
|
||
|
Destroy(T.gameObject);
|
||
|
|
||
|
LeftPanelMenu.SetActive(true);
|
||
|
LeftPanelFaceMenu.SetActive(false);
|
||
|
PlayerSexManu.SetActive(false);
|
||
|
ColorMenu.SetActive(false);
|
||
|
LeftPanelSaveLoad.SetActive(false);
|
||
|
|
||
|
// Cam_FaceToBody();
|
||
|
|
||
|
if (RckInput.isUsingGamepad)
|
||
|
editFaceButton.Select();
|
||
|
}
|
||
|
|
||
|
[ContextMenu("Face Button")]
|
||
|
public void Cam_BodyToFace()
|
||
|
{
|
||
|
// camAnimator.SetBool("isMale", isCreatingMale);
|
||
|
camAnimator.SetTrigger("bodyToFace");
|
||
|
}
|
||
|
|
||
|
[ContextMenu("Back Button")]
|
||
|
public void Cam_FaceToBody()
|
||
|
{
|
||
|
// camAnimator.SetBool("isMale", isCreatingMale);
|
||
|
camAnimator.SetTrigger("faceToBody");
|
||
|
}
|
||
|
|
||
|
public FaceBlendshapesSaveData GenerateFaceBlendshapeSaveData()
|
||
|
{
|
||
|
FaceBlendshapesSaveData data = new RPGCreationKit.SaveSystem.FaceBlendshapesSaveData();
|
||
|
|
||
|
for (int i = 0; i < currentCharacter.head.sharedMesh.blendShapeCount; i++)
|
||
|
data.allShapes.Add(new FaceBlendshapeSaveData(i, currentCharacter.head.GetBlendShapeWeight(i)));
|
||
|
|
||
|
|
||
|
return data;
|
||
|
}
|
||
|
|
||
|
public void ContinueButton()
|
||
|
{
|
||
|
messagePanel.SetActive(true);
|
||
|
|
||
|
if (characterNameField.text.Length <= 0)
|
||
|
messageBoxErrorName.SetActive(true);
|
||
|
else
|
||
|
messageBoxConfirmation.SetActive(true);
|
||
|
}
|
||
|
|
||
|
public void ConfirmCreation()
|
||
|
{
|
||
|
|
||
|
// Create savegame
|
||
|
Savegame newSave = SaveSystemManager.instance.CreateNewCharacter(characterNameField.text, !isCreatingMale, selectedRace.ID, GenerateFaceBlendshapeSaveData(), selectedHair, selectedEyes);
|
||
|
messageBoxConfirmation.SetActive(false);
|
||
|
messagePanel.SetActive(false);
|
||
|
|
||
|
//Set the stats
|
||
|
newSave.saveFile.PlayerData.playerAttributes.attributes.Strength = int.Parse(SetStats[0].text);
|
||
|
newSave.saveFile.PlayerData.playerAttributes.attributes.Agility = int.Parse(SetStats[1].text);
|
||
|
newSave.saveFile.PlayerData.playerAttributes.attributes.Constitution = int.Parse(SetStats[2].text);
|
||
|
newSave.saveFile.PlayerData.playerAttributes.attributes.Speed = int.Parse(SetStats[3].text);
|
||
|
newSave.saveFile.PlayerData.playerAttributes.attributes.Endurance = int.Parse(SetStats[4].text);
|
||
|
newSave.saveFile.PlayerData.playerAttributes.attributes.Dexterity = int.Parse(SetStats[5].text);
|
||
|
newSave.saveFile.PlayerData.playerAttributes.attributes.Charisma = int.Parse(SetStats[6].text);
|
||
|
newSave.saveFile.PlayerData.playerAttributes.attributes.Intelligence = int.Parse(SetStats[7].text);
|
||
|
newSave.saveFile.PlayerData.playerAttributes.attributes.Willpower = int.Parse(SetStats[8].text);
|
||
|
newSave.saveFile.PlayerData.HairColor = HairColor;
|
||
|
newSave.saveFile.PlayerData.SkinColor = SkinColor;
|
||
|
newSave.saveFile.PlayerData.LipsColor = LipsColor;
|
||
|
|
||
|
// Load new character
|
||
|
SaveSystemManager.instance.LoadSaveGame(newSave.fileInfo, newSave.saveFile);
|
||
|
}
|
||
|
|
||
|
public void HairRightButton()
|
||
|
{
|
||
|
List<Hair> hair = (isCreatingMale) ? selectedRace.maleHairTypes : selectedRace.femaleHairTypes;
|
||
|
|
||
|
if (selectedHair + 1 < hair.Count)
|
||
|
selectedHair++;
|
||
|
else if (selectedHair == hair.Count - 1)
|
||
|
selectedHair = -1;
|
||
|
else if (selectedHair == -1)
|
||
|
selectedHair = 0;
|
||
|
|
||
|
OnHairChanges();
|
||
|
}
|
||
|
|
||
|
public void HairLeftButton()
|
||
|
{
|
||
|
List<Hair> hair = (isCreatingMale) ? selectedRace.maleHairTypes : selectedRace.femaleHairTypes;
|
||
|
|
||
|
if (selectedHair - 1 >= 0)
|
||
|
selectedHair--;
|
||
|
else if (selectedHair == 0)
|
||
|
selectedHair = -1;
|
||
|
else if (selectedHair == -1)
|
||
|
selectedHair = hair.Count - 1;
|
||
|
|
||
|
OnHairChanges();
|
||
|
}
|
||
|
|
||
|
public void RaceRightButton()
|
||
|
{
|
||
|
List<Hair> hair = (isCreatingMale) ? selectedRace.maleHairTypes : selectedRace.femaleHairTypes;
|
||
|
|
||
|
if (selectedRaceIndex + 1 < playableRaces.Length)
|
||
|
selectedRaceIndex++;
|
||
|
else if (selectedRaceIndex == hair.Count - 1)
|
||
|
selectedRaceIndex = -1;
|
||
|
else if (selectedRaceIndex == -1)
|
||
|
selectedRaceIndex = 0;
|
||
|
|
||
|
selectedRace = playableRaces[selectedRaceIndex];
|
||
|
LoadRaceCharacter(selectedRace);
|
||
|
}
|
||
|
|
||
|
public void RaceLeftButton()
|
||
|
{
|
||
|
if (selectedRaceIndex - 1 >= 0)
|
||
|
selectedRaceIndex--;
|
||
|
else if (selectedRaceIndex == 0)
|
||
|
selectedRaceIndex = -1;
|
||
|
else if (selectedRaceIndex == -1)
|
||
|
selectedRaceIndex = playableRaces.Length - 1;
|
||
|
|
||
|
selectedRace = playableRaces[selectedRaceIndex];
|
||
|
LoadRaceCharacter(selectedRace);
|
||
|
}
|
||
|
|
||
|
public void EyesRightButton()
|
||
|
{
|
||
|
List<Eye> eyes = selectedRace.eyeTypes;
|
||
|
|
||
|
if (selectedEyes + 1 < eyes.Count)
|
||
|
selectedEyes++;
|
||
|
else if (selectedEyes == eyes.Count - 1)
|
||
|
selectedEyes = 0;
|
||
|
|
||
|
OnEyesChanges();
|
||
|
}
|
||
|
|
||
|
public void EyesLeftButton()
|
||
|
{
|
||
|
List<Eye> eyes = selectedRace.eyeTypes;
|
||
|
|
||
|
if (selectedEyes - 1 >= 0)
|
||
|
selectedEyes--;
|
||
|
else if (selectedEyes == 0)
|
||
|
selectedEyes = eyes.Count - 1;
|
||
|
|
||
|
OnEyesChanges();
|
||
|
}
|
||
|
|
||
|
public void OnEyesChanges()
|
||
|
{
|
||
|
Eye eyesType = selectedRace.eyeTypes[selectedEyes];
|
||
|
|
||
|
try
|
||
|
{
|
||
|
var materials = currentCharacter.eyes.sharedMaterials;
|
||
|
|
||
|
for (int i = 0; i < materials.Length; i++)
|
||
|
{
|
||
|
materials[i] = eyesType.eyes.sharedMaterials[i];
|
||
|
}
|
||
|
|
||
|
currentCharacter.eyes.sharedMaterials = materials;
|
||
|
}
|
||
|
catch { }
|
||
|
|
||
|
//currentCharacter.eyes.sharedMaterial = eyesType.eyes.sharedMaterial;
|
||
|
eyesTypeText.text = eyesType.eyesName;
|
||
|
}
|
||
|
|
||
|
|
||
|
public void OnHairChanges()
|
||
|
{
|
||
|
if (currentCharacter.hair != null)
|
||
|
Destroy(currentCharacter.hair.gameObject);
|
||
|
|
||
|
// Spawn new hair
|
||
|
Hair hair = (isCreatingMale) ? selectedRace.maleHairTypes[selectedHair] : selectedRace.femaleHairTypes[selectedHair];
|
||
|
|
||
|
currentCharacter.hair = Instantiate(hair.mesh.gameObject, currentCharacter.transform).GetComponent<SkinnedMeshRenderer>();
|
||
|
|
||
|
// Attach
|
||
|
currentCharacter.hair.transform.parent = currentCharacter.head.transform;
|
||
|
currentCharacter.hair.rootBone = currentCharacter.head.rootBone;
|
||
|
currentCharacter.hair.bones = currentCharacter.head.bones;
|
||
|
|
||
|
hairTypeText.text = hair.hairName;
|
||
|
|
||
|
// Set the blendshapes for the hair
|
||
|
currentCharacter.head.GetComponent<HeadBlendshapesManager>().HairMesh = currentCharacter.hair;
|
||
|
currentCharacter.head.GetComponent<HeadBlendshapesManager>().SetBlendShapes(currentCharacter.hair);
|
||
|
}
|
||
|
|
||
|
public List<Slider> faceBlendshapes;
|
||
|
public void RandomizeFace() {
|
||
|
for (int i = 0; i < faceBlendshapes.Count; i++) {
|
||
|
faceBlendshapes[i].value = Random.Range(-100, 100);
|
||
|
}
|
||
|
}
|
||
|
}
|