CharacterArchetypeFactory

Anonymous
csharp
07/18/2026 10:24 AM
11.7 KB
26
No Index
using Leopotam.EcsProto;
using Unity.Collections;
using UnityEngine;

namespace ShiftedRealms.IsoRift.GameWorld
{
    public sealed class CharacterArchetypeFactory
    {
        private readonly Dependencies services;

        private int charactersCounter;

        public CharacterArchetypeFactory(Dependencies services)
        {
            this.services = services;
        }

        public void SetupHumanoidCharacter(
            ProtoEntity characterEntity,
            Vector3 position,
            Quaternion rotation,
            ulong characterDefinitionId,
            string overrideName = null)
        {
            ref WorldPose pose = ref services.SpatialAspect.PosePool.Add(characterEntity);
            pose.Position = position;
            pose.Rotation = rotation;
            services.SpatialAspect.AddPoseFixedHistory(
                characterEntity,
                pose);

            var definition = services.CharacterDefinitionsLibrary.DefinitionsById[characterDefinitionId];

            FixedString32Bytes fixedName;
            if (!string.IsNullOrEmpty(overrideName))
            {
                fixedName = new FixedString32Bytes(overrideName);
            }
            else
            {
                fixedName = string.IsNullOrEmpty(definition.DisplayName) ?
                    new FixedString32Bytes($"Character #{charactersCounter}") :
                    new FixedString32Bytes(definition.DisplayName);
            }

            services.NamingAspect.AddOrSetName(characterEntity, fixedName);

            LosStats losStats = BuildLosStats(
                definition.GetModule<CharacterLosModule>());

            CharacterVisionFocusModule visionFocusModule =
                definition.GetModule<CharacterVisionFocusModule>();

            CharacterVisionPerceptionModule visionPerceptionModule =
                definition.GetModule<CharacterVisionPerceptionModule>();

            VisionPerceptionStats visionPerceptionStats =
                BuildVisionPerceptionStats(visionPerceptionModule);

            Vector3 initialVisionDirection = rotation * Vector3.forward;
            Vector3 initialEyePosition =
                position +
                Vector3.up * losStats.EyeHeightMeters +
                initialVisionDirection * losStats.EyeForwardOffsetMeters;

            services.PhysicsAspect.AddPhysicalComponents(characterEntity);
            services.CharacterAspect.AddCharacterComponents(characterEntity, characterDefinitionId);
            services.CombatReadinessAspect.AddCombatReadinessComponents(characterEntity);
            services.AimingAspect.AddAimingComponents(characterEntity);
            services.RangedWeaponShootingAspect.AddShootingComponents(characterEntity);

            services.VisionFocusAspect.AddVisionFocusComponents(
                characterEntity,
                initialEyePosition + initialVisionDirection,
                initialVisionDirection,
                visionFocusModule.TurnSpeedDegreesPerSecond);

            ref VisionFocusState visionFocusState =
                ref services.VisionFocusAspect.StatesPool.Get(characterEntity);

            services.LosAspect.AddLosComponents(
                characterEntity,
                losStats,
                pose,
                visionFocusState);

            services.VisionPerceptionAspect.AddObserverComponents(
                characterEntity,
                visionPerceptionStats);

            CharacterLocomotionModule locomotionStats = definition.GetModule<CharacterLocomotionModule>();

            services.MovementAspect.AddMovementComponents(
                characterEntity,
                locomotionStats.MaxMoveSpeed,
                locomotionStats.Acceleration,
                locomotionStats.Deceleration);

            services.FacingAspect.AddFacingComponents(
                characterEntity,
                locomotionStats.NormalTurnSpeedDegreesPerSecond);

            services.ItemPlacementAspect.AddItemSlotsContainer(characterEntity);

            services.ItemPlacementAspect.AddSlot(
                characterEntity,
                services.ItemSlotDefinitionsLibrary
                    .DefinitionsByKey[ItemSlotDefinitionKeys.HUMANOID_HANDS_GRIP]
                    .Id);

            services.ItemPlacementAspect.AddSlot(
                characterEntity,
                services.ItemSlotDefinitionsLibrary
                    .DefinitionsByKey[ItemSlotDefinitionKeys.HUMANOID_BACK_RIFLE_SLOT]
                    .Id);

            charactersCounter++;
        }

        private static LosStats BuildLosStats(CharacterLosModule module)
        {
            return new LosStats
            {
                RangeMeters = Mathf.Max(module.RangeMeters, LosShapeUtility.MIN_RANGE_METERS),
                VerticalFieldOfViewDegrees = module.VerticalFieldOfViewDegrees,
                AspectRatio = module.AspectRatio,
                EyeHeightMeters = module.EyeHeightMeters,
                EyeForwardOffsetMeters = module.EyeForwardOffsetMeters,
                HasNearVisibilityCapsule = module.HasNearVisibilityCapsule,
                NearVisibilityCapsuleStartHeightMeters = module.NearVisibilityCapsuleStartHeightMeters,
                NearVisibilityCapsuleEndHeightMeters = module.NearVisibilityCapsuleEndHeightMeters,
                NearVisibilityCapsuleRadiusMeters = module.NearVisibilityCapsuleRadiusMeters,
                ObstacleLayerMask = module.ObstacleLayerMask,
            };
        }

        private static VisionPerceptionStats BuildVisionPerceptionStats(
            CharacterVisionPerceptionModule module)
        {
            return new VisionPerceptionStats
            {
                RecognitionGainPerSecond = module.RecognitionGainPerSecond,
                RecognitionDecayPerSecond = module.RecognitionDecayPerSecond,
                VisibilityForFullRecognition = module.VisibilityForFullRecognition,
                RecognizedThreshold = module.RecognizedThreshold,
            };
        }

        public class Dependencies
        {
            public readonly NamingAspect NamingAspect;
            public readonly SpatialAspect SpatialAspect;
            public readonly PhysicsAspect PhysicsAspect;
            public readonly CharacterAspect CharacterAspect;
            public readonly CombatReadinessAspect CombatReadinessAspect;
            public readonly MovementAspect MovementAspect;
            public readonly VisionFocusAspect VisionFocusAspect;
            public readonly LosAspect LosAspect;
            public readonly VisionPerceptionAspect VisionPerceptionAspect;
            public readonly FacingAspect FacingAspect;
            public readonly AimingAspect AimingAspect;
            public readonly RangedWeaponShootingAspect RangedWeaponShootingAspect;
            public readonly ItemPlacementAspect ItemPlacementAspect;
            public readonly ItemSlotDefinitionsLibrary ItemSlotDefinitionsLibrary;
            public readonly CharacterDefinitionsLibrary CharacterDefinitionsLibrary;

            public Dependencies(
                NamingAspect namingAspect,
                SpatialAspect spatialAspect,
                PhysicsAspect physicsAspect,
                CharacterAspect characterAspect,
                CombatReadinessAspect combatReadinessAspect,
                MovementAspect movementAspect,
                VisionFocusAspect visionFocusAspect,
                LosAspect losAspect,
                VisionPerceptionAspect visionPerceptionAspect,
                FacingAspect facingAspect,
                AimingAspect aimingAspect,
                RangedWeaponShootingAspect rangedWeaponShootingAspect,
                ItemPlacementAspect itemPlacementAspect,
                ItemSlotDefinitionsLibrary itemSlotDefinitionsLibrary,
                CharacterDefinitionsLibrary characterDefinitionsLibrary)
            {
                NamingAspect = namingAspect;
                SpatialAspect = spatialAspect;
                PhysicsAspect = physicsAspect;
                CharacterAspect = characterAspect;
                CombatReadinessAspect = combatReadinessAspect;
                MovementAspect = movementAspect;
                VisionFocusAspect = visionFocusAspect;
                LosAspect = losAspect;
                VisionPerceptionAspect = visionPerceptionAspect;
                FacingAspect = facingAspect;
                AimingAspect = aimingAspect;
                RangedWeaponShootingAspect = rangedWeaponShootingAspect;
                ItemPlacementAspect = itemPlacementAspect;
                ItemSlotDefinitionsLibrary = itemSlotDefinitionsLibrary;
                CharacterDefinitionsLibrary = characterDefinitionsLibrary;
            }
        }
    }
}
Editor is loading...
Leave a Comment