Class CharacterAppearanceManager
Manages character visual appearance: bone scaling for body proportions, blend shape synchronization, and appearance data serialization.
Bone scaling is separated into a global Height pass and individual body-part adjustments. Height scales all height-affecting bones uniformly. Individual sliders (TorsoLength, LegLength, ArmLength) apply additional proportional tweaks on top. This means a Dwarf with Height=0.75 and LegLength=0.70 has legs at 0.75 * 0.70 = 0.525x scale — intentionally shorter than the already reduced height.
All operations are client-only.
public class CharacterAppearanceManager : CharacterBehaviour, ICharacterAppearanceManager, ICharacterBehaviour, IModelReadyHandler
- Inheritance
-
ObjectComponentBehaviourMonoBehaviourNetworkBehaviourCharacterAppearanceManager
- Implements
- Inherited Members
-
NetworkBehaviour.IsSpawnedNetworkBehaviour.ComponentIndexNetworkBehaviour.NetworkObjectNetworkBehaviour.MAXIMUM_NETWORKBEHAVIOURSNetworkBehaviour.UNSET_NETWORKBEHAVIOUR_IDNetworkBehaviour.ToString()NetworkBehaviour.Reset()NetworkBehaviour.OnValidate()NetworkBehaviour.IsBehaviourReconcilingNetworkBehaviour.ClearReplicateCache()NetworkBehaviour.CreateReconcile()NetworkBehaviour.Reconcile_Reader<T>(PooledReader, ref T)NetworkBehaviour.OnStartServerCalledNetworkBehaviour.OnStartClientCalledNetworkBehaviour.WritePayload(NetworkConnection, Writer)NetworkBehaviour.ReadPayload(NetworkConnection, Reader)NetworkBehaviour.OnStartNetwork()NetworkBehaviour.OnStopNetwork()NetworkBehaviour.OnStartServer()NetworkBehaviour.OnStopServer()NetworkBehaviour.OnOwnershipServer(NetworkConnection)NetworkBehaviour.OnSpawnServer(NetworkConnection)NetworkBehaviour.OnDespawnServer(NetworkConnection)NetworkBehaviour.OnStartClient()NetworkBehaviour.OnStopClient()NetworkBehaviour.OnOwnershipClient(NetworkConnection)NetworkBehaviour.ClearBuffedRpcs()NetworkBehaviour.ExcludeOwnerFromUnbufferedObserversRpcsNetworkBehaviour.IsClientOnlyNetworkBehaviour.IsServerOnlyNetworkBehaviour.IsHostNetworkBehaviour.IsClientNetworkBehaviour.IsServerNetworkBehaviour.IsDeinitializingNetworkBehaviour.NetworkManagerNetworkBehaviour.ServerManagerNetworkBehaviour.ClientManagerNetworkBehaviour.ObserverManagerNetworkBehaviour.TransportManagerNetworkBehaviour.TimeManagerNetworkBehaviour.SceneManagerNetworkBehaviour.PredictionManagerNetworkBehaviour.RollbackManagerNetworkBehaviour.NetworkObserverNetworkBehaviour.IsClientInitializedNetworkBehaviour.IsClientStartedNetworkBehaviour.IsClientOnlyInitializedNetworkBehaviour.IsClientOnlyStartedNetworkBehaviour.IsServerInitializedNetworkBehaviour.IsServerStartedNetworkBehaviour.IsServerOnlyInitializedNetworkBehaviour.IsServerOnlyStartedNetworkBehaviour.IsHostInitializedNetworkBehaviour.IsHostStartedNetworkBehaviour.IsOfflineNetworkBehaviour.IsNetworkedNetworkBehaviour.GetIsNetworked()NetworkBehaviour.IsManagerReconcilingNetworkBehaviour.ObserversNetworkBehaviour.IsOwnerNetworkBehaviour.IsControllerNetworkBehaviour.HasAuthorityNetworkBehaviour.OwnerNetworkBehaviour.OwnerIdNetworkBehaviour.ObjectIdNetworkBehaviour.LocalConnectionNetworkBehaviour.OwnerMatches(NetworkConnection)NetworkBehaviour.Despawn(GameObject, DespawnType?)NetworkBehaviour.Despawn(NetworkObject, DespawnType?)NetworkBehaviour.Despawn(DespawnType?)NetworkBehaviour.Spawn(GameObject, NetworkConnection, Scene)NetworkBehaviour.Spawn(NetworkObject, NetworkConnection, Scene)NetworkBehaviour.RemoveOwnership()NetworkBehaviour.GiveOwnership(NetworkConnection)NetworkBehaviour.GetInstance<T>()NetworkBehaviour.TryRegisterInstance<T>(T)NetworkBehaviour.UnregisterInstance<T>()NetworkBehaviour.CanLog(LoggingType)MonoBehaviour.IsInvoking()MonoBehaviour.CancelInvoke()MonoBehaviour.StopCoroutine(Coroutine)MonoBehaviour.StopAllCoroutines()MonoBehaviour.destroyCancellationTokenMonoBehaviour.useGUILayoutMonoBehaviour.didStartMonoBehaviour.didAwakeMonoBehaviour.runInEditModeBehaviour.enabledBehaviour.isActiveAndEnabledComponent.GetComponent<T>()Component.TryGetComponent<T>(out T)Component.GetComponentInChildren<T>()Component.GetComponentsInChildren<T>()Component.GetComponentInParent<T>()Component.GetComponentsInParent<T>()Component.GetComponents<T>()Component.GetComponentIndex()Component.CompareTag(TagHandle)Component.transformComponent.transformHandleComponent.gameObjectComponent.tagObject.GetEntityId()Object.GetInstanceID()Object.GetHashCode()Object.InstantiateAsync<T>(T)Object.InstantiateAsync<T>(T, Transform)Object.InstantiateAsync<T>(T, Vector3, Quaternion)Object.InstantiateAsync<T>(T, Transform, Vector3, Quaternion)Object.Instantiate(Object, Vector3, Quaternion)Object.Instantiate(Object, Vector3, Quaternion, Transform)Object.Instantiate(Object)Object.Instantiate(Object, Scene)Object.Instantiate<T>(T, InstantiateParameters)Object.Instantiate<T>(T, Vector3, Quaternion, InstantiateParameters)Object.Instantiate(Object, Transform)Object.Instantiate<T>(T)Object.Instantiate<T>(T, Vector3, Quaternion)Object.Instantiate<T>(T, Vector3, Quaternion, Transform)Object.Instantiate<T>(T, Transform)Object.Destroy(Object)Object.DestroyImmediate(Object)Object.DontDestroyOnLoad(Object)Object.DestroyObject(Object)Object.FindObjectsOfType<T>()Object.FindObjectsByType<T>(FindObjectsSortMode)Object.FindObjectsByType<T>(FindObjectsInactive, FindObjectsSortMode)Object.FindObjectOfType<T>()Object.FindFirstObjectByType<T>()Object.FindAnyObjectByType<T>()Object.FindFirstObjectByType<T>(FindObjectsInactive)Object.FindAnyObjectByType<T>(FindObjectsInactive)Object.FindObjectsByType<T>()Object.FindObjectsByType<T>(FindObjectsInactive)Object.nameObject.hideFlags
Methods
ApplyAppearanceData(CharacterAppearanceData)
Restores appearance from a serialized data snapshot.
public void ApplyAppearanceData(CharacterAppearanceData data)
Parameters
dataCharacterAppearanceDataThe appearance data to apply.
ApplyRaceProportions(RaceProportions)
Applies race default proportions via bone scaling. Called once when the character model is instantiated.
public void ApplyRaceProportions(RaceProportions proportions)
Parameters
proportionsRaceProportionsThe race proportion values to apply.
GetAppearanceData()
Returns a snapshot of the character's current appearance.
public CharacterAppearanceData GetAppearanceData()
Returns
- CharacterAppearanceData
A snapshot with all proportions, blend shapes, and equipped item IDs.
OnModelReady()
Called when the character model has finished loading. At this point, the skeleton, Animator, and body region renderers are available.
public void OnModelReady()
OnStartCharacter()
Initial discovery attempt. May not find everything if model hasn't loaded. Full initialization deferred to OnModelReady().
public override void OnStartCharacter()
RegisterEquipmentRenderer(SkinnedMeshRenderer)
Registers an equipment renderer for blend shape syncing. Called by EquipmentVisualController when an item is equipped.
public void RegisterEquipmentRenderer(SkinnedMeshRenderer renderer)
Parameters
rendererSkinnedMeshRenderer
ResetState(bool)
Drops the appearance discovered from the current model before the object is pooled.
public override void ResetState(bool asServer)
Parameters
asServerboolTrue if called on the server.
Remarks
OnModelReady() clears the body renderers and the skeleton on its way to
re-discovering them, but it only runs once the NEXT model has finished loading, and the
three things it does not touch have no other writer at all: the blend shape values, the
equipment renderers registered by EquipmentVisualController, and
FishMMO.Shared.CharacterAppearanceManager.currentAppearance itself.
Left in place, the blend shapes are re-applied wholesale to the next occupant's model —
ReapplyBlendShapes walks that dictionary and writes every entry — so a recycled
object carried the previous character's face and body sliders onto a different character.
The equipment renderer list is worse than stale: its entries belong to renderers that the
visual controller destroys on teardown, so every later blend shape write iterated a list
of dead Unity objects.
SetBlendShape(string, float)
Sets a blend shape value on all body region renderers and all equipped equipment renderers that have a matching blend shape name.
public void SetBlendShape(string name, float value)
Parameters
SyncBlendShapesToEquipment(SkinnedMeshRenderer)
Pushes current body blend shape values to an equipment SkinnedMeshRenderer. Only applies blend shapes that exist on the equipment mesh. Called when new equipment is equipped.
public void SyncBlendShapesToEquipment(SkinnedMeshRenderer equipmentRenderer)
Parameters
equipmentRendererSkinnedMeshRendererThe newly equipped item's SkinnedMeshRenderer.
UnregisterEquipmentRenderer(SkinnedMeshRenderer)
Unregisters an equipment renderer. Called by EquipmentVisualController when an item is unequipped.
public void UnregisterEquipmentRenderer(SkinnedMeshRenderer renderer)
Parameters
rendererSkinnedMeshRenderer