Initial Combat Implementation
This commit is contained in:
@@ -1,21 +1,32 @@
|
||||
using ProjectM.Simulation;
|
||||
using Unity.Entities;
|
||||
using Unity.Mathematics;
|
||||
using UnityEngine;
|
||||
|
||||
namespace ProjectM.Authoring
|
||||
{
|
||||
/// <summary>
|
||||
/// Authoring for the player ghost prefab. Bakes the gameplay components onto the entity and
|
||||
/// exposes movement tunables for designers. Ghost replication, <c>GhostOwner</c> and
|
||||
/// AutoCommandTarget are supplied by the GhostAuthoringComponent added on the same prefab
|
||||
/// GameObject. <c>GetEntity(TransformUsageFlags.Dynamic)</c> ensures a runtime-mutable
|
||||
/// LocalTransform exists.
|
||||
/// Authoring for the player ghost prefab. As of M3 the numeric tunables live in data
|
||||
/// (<see cref="CharacterStatsDefinition"/> / <see cref="AbilityDefinition"/> ScriptableObjects);
|
||||
/// this authoring only selects which definitions the player uses and bakes the light id refs, the
|
||||
/// (empty) replicated modifier buffer, and the zeroed effective-stat components that
|
||||
/// StatRecomputeSystem fills each predicted tick. Health is seeded from the character definition's
|
||||
/// MaxHealth (single source). Ghost replication, <c>GhostOwner</c> and AutoCommandTarget come from
|
||||
/// the GhostAuthoringComponent on the same prefab GameObject; <c>GetEntity(TransformUsageFlags.Dynamic)</c>
|
||||
/// ensures a runtime-mutable LocalTransform exists.
|
||||
/// </summary>
|
||||
public class PlayerAuthoring : MonoBehaviour
|
||||
{
|
||||
[Min(0f)] public float MoveSpeed = 6f;
|
||||
[Min(0f)] public float TurnRateDegreesPerSec = 720f;
|
||||
[Tooltip("Character-stats definition (move speed, turn rate, max health). Single source of those values.")]
|
||||
public CharacterStatsDefinition Character;
|
||||
|
||||
[Tooltip("Ability definition occupying the player's primary slot.")]
|
||||
public AbilityDefinition PrimaryAbility;
|
||||
|
||||
[Header("Fallbacks (used only if a definition above is unassigned)")]
|
||||
[Min(0f)] public float FallbackMaxHealth = 100f;
|
||||
|
||||
/// <summary>Projectile hit-test radius for the player as a damageable target, in world units.</summary>
|
||||
[Min(0f)] public float HitRadius = 0.6f;
|
||||
|
||||
private class PlayerBaker : Baker<PlayerAuthoring>
|
||||
{
|
||||
@@ -23,14 +34,38 @@ namespace ProjectM.Authoring
|
||||
{
|
||||
var entity = GetEntity(authoring, TransformUsageFlags.Dynamic);
|
||||
|
||||
// Re-bake when a referenced definition's serialized values change.
|
||||
if (authoring.Character != null) DependsOn(authoring.Character);
|
||||
if (authoring.PrimaryAbility != null) DependsOn(authoring.PrimaryAbility);
|
||||
|
||||
byte characterId = authoring.Character != null
|
||||
? (byte)authoring.Character.Id : (byte)CharacterId.Default;
|
||||
byte abilityId = authoring.PrimaryAbility != null
|
||||
? (byte)authoring.PrimaryAbility.Id : (byte)AbilityId.Primary;
|
||||
float maxHealth = authoring.Character != null
|
||||
? authoring.Character.MaxHealth : authoring.FallbackMaxHealth;
|
||||
|
||||
AddComponent<PlayerTag>(entity);
|
||||
AddComponent(entity, new PlayerMoveStats
|
||||
{
|
||||
MoveSpeed = authoring.MoveSpeed,
|
||||
TurnRateRadiansPerSec = math.radians(authoring.TurnRateDegreesPerSec)
|
||||
});
|
||||
AddComponent<PlayerFacing>(entity);
|
||||
AddComponent<PlayerInput>(entity);
|
||||
|
||||
// Data-driven stat refs (replace M2's inlined PlayerMoveStats / AbilityStats values).
|
||||
AddComponent(entity, new CharacterStatsRef { Id = characterId });
|
||||
AddComponent(entity, new AbilityRef { Id = abilityId });
|
||||
|
||||
// Effective stats: zeroed at bake, recomputed every predicted tick by StatRecomputeSystem.
|
||||
AddComponent(entity, new EffectiveAbilityStats());
|
||||
AddComponent(entity, new EffectiveCharacterStats());
|
||||
|
||||
// Empty replicated modifier stack (grown by upgrades/pickups/debug hook, server-authoritative).
|
||||
AddBuffer<StatModifier>(entity);
|
||||
|
||||
// Combat: server-authoritative health (Current replicated for display), the player's
|
||||
// damageable hit radius, predicted cooldown state, and the per-tick damage inbox.
|
||||
AddComponent(entity, new Health { Current = maxHealth, Max = maxHealth });
|
||||
AddComponent(entity, new HitRadius { Value = authoring.HitRadius });
|
||||
AddComponent<AbilityCooldown>(entity);
|
||||
AddBuffer<DamageEvent>(entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user