(Feat) Add Animation Fps Charater
This commit is contained in:
@@ -0,0 +1,194 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Engine/DataAsset.h"
|
||||
#include "CharacterAppearanceTypes.h"
|
||||
#include "CharacterPartsDataAsset.generated.h"
|
||||
|
||||
class UAnimInstance;
|
||||
class UMaterialInterface;
|
||||
class USkeletalMesh;
|
||||
class UTexture2D;
|
||||
|
||||
/**
|
||||
* Tout ce qui compose une silhouette : ses meshes de corps, son AnimBP, et les
|
||||
* pieces disponibles pour chaque categorie.
|
||||
*/
|
||||
USTRUCT(BlueprintType)
|
||||
struct FCharacterBodySet
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
/** La vignette du bouton de silhouette, meme role que celle d'une piece. */
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Body")
|
||||
TObjectPtr<UTexture2D> Icon;
|
||||
|
||||
/**
|
||||
* Les morceaux du corps, dans l'ordre. Le PREMIER est le porteur : c'est lui
|
||||
* qui va sur le composant Mesh du Character et qui joue l'animation, les
|
||||
* suivants deviennent des composants enfants en leader pose.
|
||||
*
|
||||
* Une LISTE alors qu'il n'y a qu'une case aujourd'hui, et ce n'est pas de la
|
||||
* sur-conception : le pack livre exprès `SKM_BodyA_torso`, `_arms`,
|
||||
* `_legs_01/02/03`, `_hands`, `_feet`, precisement pour qu'une armure puisse
|
||||
* eteindre les segments qu'elle recouvre. Le jour venu, la case 0 deviendra
|
||||
* `SKM_BodyA_empty` -- invisible, porteur d'animation -- et les huit segments
|
||||
* suivront derriere, SANS que ce code change. Un TObjectPtr unique, lui,
|
||||
* imposerait de tout reprendre au premier plastron.
|
||||
*/
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Body")
|
||||
TArray<TObjectPtr<USkeletalMesh>> BodyMeshes;
|
||||
|
||||
/** L'AnimBP du porteur. Il change avec la silhouette, d'ou sa place ici. */
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Body")
|
||||
TSubclassOf<UAnimInstance> AnimClass;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Parts")
|
||||
TArray<FCharacterPartEntry> Heads;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Parts")
|
||||
TArray<FCharacterPartEntry> Hairstyles;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Parts")
|
||||
TArray<FCharacterPartEntry> Eyebrows;
|
||||
|
||||
/** Vide pour une silhouette qui n'en porte pas -- le pack n'en donne qu'a A. */
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Parts")
|
||||
TArray<FCharacterPartEntry> Beards;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Parts")
|
||||
TArray<FCharacterPartEntry> Mustaches;
|
||||
|
||||
/**
|
||||
* Fragment cherche dans le NOM des slots de materiau du mesh de tete pour y
|
||||
* trouver celui des yeux.
|
||||
*
|
||||
* Les yeux ne sont pas un mesh : le pack les livre comme un element du mesh
|
||||
* de tete. Il ne suffit donc pas de poser un parametre de couleur, il faut
|
||||
* REMPLACER le materiau de ce slot -- encore faut-il savoir lequel.
|
||||
*
|
||||
* Un fragment de nom et pas un index, parce qu'un index est faux deux fois :
|
||||
* il oblige a le verifier a la main dans l'editeur, et il suppose surtout
|
||||
* que les six tetes rangent leurs slots dans le MEME ordre. Les slots du
|
||||
* pack s'appellent `M_Eye_A_01`, `M_Eye`, `M_Eyes_02`... tous contiennent
|
||||
* « Eye », aucun slot de peau ne le contient.
|
||||
*
|
||||
* Si le fragment ne trouve rien, le materiau n'est PAS pose et un
|
||||
* avertissement part dans le log. C'est volontaire : poser l'oeil sur un
|
||||
* slot au hasard repeindrait le visage entier, un symptome qu'on met bien
|
||||
* plus longtemps a diagnostiquer qu'une ligne de log.
|
||||
*/
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Parts")
|
||||
FName EyeMaterialSlotHint = TEXT("Eye");
|
||||
};
|
||||
|
||||
/**
|
||||
* Le catalogue : la table de correspondance entre les index d'une
|
||||
* FCharacterAppearance et les assets reels.
|
||||
*
|
||||
* Un seul asset a remplir, et le SEUL endroit a toucher pour ajouter une
|
||||
* coiffure. C'est aussi lui qui borne ce qu'un client peut demander : une
|
||||
* apparence arrivee du reseau est passee a Sanitize(), qui ramene tout index
|
||||
* hors bornes a une valeur sure.
|
||||
*/
|
||||
UCLASS(BlueprintType)
|
||||
class EMBERWILD_API UCharacterPartsDataAsset : public UPrimaryDataAsset
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
/**
|
||||
* Une entree par valeur d'ECharacterBodyType, dans l'ordre de l'enum.
|
||||
* L'ordre EST le contrat : c'est lui qui donne son sens a BodyType.
|
||||
*/
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Catalog")
|
||||
TArray<FCharacterBodySet> BodySets;
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Palettes : une couleur = un bouton a l'ecran, sans reglage entre les
|
||||
// deux. L'ordre EST l'ordre d'affichage, et l'index qui part sur le reseau.
|
||||
//
|
||||
// Partagees par les deux silhouettes : deux nuanciers de peau a tenir a
|
||||
// jour divergeraient au premier ajout.
|
||||
// ------------------------------------------------------------------
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Catalog|Palettes")
|
||||
TArray<FLinearColor> SkinColors;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Catalog|Palettes")
|
||||
TArray<FLinearColor> HairColors;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Catalog|Palettes")
|
||||
TArray<FLinearColor> EyeColors;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Catalog|Palettes")
|
||||
TArray<FLinearColor> UnderwearColors;
|
||||
|
||||
/** Les materiaux d'iris, un par forme d'oeil proposee. */
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Catalog|Palettes")
|
||||
TArray<TObjectPtr<UMaterialInterface>> EyeMaterials;
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Noms des parametres des materiaux du pack.
|
||||
//
|
||||
// Ici et pas en dur dans le C++ : ils appartiennent aux assets, pas au
|
||||
// code. Changer de pack de personnages ne doit demander qu'un nouveau
|
||||
// catalogue -- et ces noms contiennent des ESPACES, ce qu'on n'invente
|
||||
// pas de memoire.
|
||||
// ------------------------------------------------------------------
|
||||
|
||||
/** `M_Body_Base`. */
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Catalog|Material Parameters")
|
||||
FName SkinColorParameter = TEXT("Skin color");
|
||||
|
||||
/**
|
||||
* `M_Head_Base` -- le meme role que ci-dessus, mais l'autre master, et
|
||||
* surtout un NOM DIFFERENT : `Skin` cote tete, `Skin color` cote corps.
|
||||
*
|
||||
* Le master contient bien la chaine « Skin Base color », mais ce n'est pas
|
||||
* le nom du parametre expose -- verifie dans `MI_HeadA_01_a`, ou le chercher
|
||||
* ne rend aucun resultat alors que `Skin` apparait dans le groupe
|
||||
* « Base colors ». Morale : un nom de parametre se lit dans l'editeur du
|
||||
* Material Instance, jamais dans les chaines du binaire du master.
|
||||
*/
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Catalog|Material Parameters")
|
||||
FName HeadSkinColorParameter = TEXT("Skin");
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Catalog|Material Parameters")
|
||||
FName UnderwearColorParameter = TEXT("Underware color");
|
||||
|
||||
/** `M_Hairstyle_Base`, parent des cheveux, barbes, moustaches ET sourcils. */
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Catalog|Material Parameters")
|
||||
FName HairColorParameter = TEXT("Color");
|
||||
|
||||
/** `M_Eyes_Base`. */
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Catalog|Material Parameters")
|
||||
FName EyeColorParameter = TEXT("Eye color");
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Lecture
|
||||
// ------------------------------------------------------------------
|
||||
|
||||
/** Le jeu de pieces d'une silhouette, ou nullptr si l'index est hors bornes. */
|
||||
const FCharacterBodySet* GetBodySet(ECharacterBodyType BodyType) const;
|
||||
|
||||
/** La liste d'une categorie pour une silhouette, vide si rien n'est defini. */
|
||||
const TArray<FCharacterPartEntry>& GetParts(ECharacterBodyType BodyType, ECharacterPartCategory Category) const;
|
||||
|
||||
/** Nombre d'options d'une categorie. Sert a borner l'UI comme la console. */
|
||||
UFUNCTION(BlueprintPure, Category = "Catalog")
|
||||
int32 GetPartCount(ECharacterBodyType BodyType, ECharacterPartCategory Category) const;
|
||||
|
||||
/**
|
||||
* Ramene une apparence dans les bornes du catalogue.
|
||||
*
|
||||
* Appelee sur le SERVEUR a la reception d'une apparence client, et au
|
||||
* chargement des reglages -- un catalogue ampute entre deux versions du jeu
|
||||
* laisserait sinon des index qui ne designent plus rien. Les pieces
|
||||
* facultatives (barbe, moustache) retombent sur NoPart, les obligatoires
|
||||
* sur 0 : mieux vaut la mauvaise tete que pas de tete.
|
||||
*/
|
||||
void Sanitize(FCharacterAppearance& InOut) const;
|
||||
};
|
||||
Reference in New Issue
Block a user