添加 SepCore.Runtime 和 SepCore.Base 程序集

- 暂时将 Entity 全部归进 Runtime 程序集里
- 调整部分 UI 的 UseCase/RawData/Context 之间的关系,让 RawData 更接近业务原始数据,Context 更接近 UI 直接可读的数据
- 调整其他程序集的引用关系
This commit is contained in:
SepComet
2026-06-03 11:15:58 +08:00
parent d5893ac52b
commit 91f70dd783
176 changed files with 245 additions and 231 deletions
@@ -0,0 +1,124 @@
using GameFramework.ObjectPool;
using UnityEngine;
namespace Entity.Weapon
{
public sealed class HandgunHitMarkerAttackEffect : IWeaponAttackEffect
{
private const string PoolName = "Weapon.HandgunHitMarker";
private const float PoolAutoReleaseInterval = 60f;
private const int PoolCapacity = 128;
private const float PoolExpireTime = 120f;
private const int PoolPriority = 0;
private static IObjectPool<HandgunHitMarkerPoolObject> s_Pool;
private readonly float _size;
private readonly float _yOffset;
private readonly float _duration;
private readonly Color _color;
private Material _sharedMaterial;
public HandgunHitMarkerAttackEffect(float size, float yOffset, float duration, Color color)
{
_size = size;
_yOffset = yOffset;
_duration = duration;
_color = color;
}
public void Play(WeaponBase weapon, Vector3 position, EntityBase target, float radius)
{
if (target == null) return;
if (!TrySpawnMarker(out HandgunHitMarkerPooledInstance markerInstance))
{
return;
}
Transform targetTransform = target.CachedTransform;
Vector3 worldPosition = targetTransform != null ? targetTransform.position : position;
markerInstance.transform.SetParent(null, false);
markerInstance.transform.position = worldPosition + Vector3.up * _yOffset;
markerInstance.transform.localScale = Vector3.one * Mathf.Max(0.01f, _size);
markerInstance.ApplyMaterial(GetSharedMaterial());
markerInstance.Activate(Mathf.Max(0.01f, _duration), s_Pool);
}
private bool TrySpawnMarker(out HandgunHitMarkerPooledInstance markerInstance)
{
markerInstance = null;
IObjectPool<HandgunHitMarkerPoolObject> pool = EnsurePool();
if (pool == null)
{
return false;
}
HandgunHitMarkerPoolObject pooledObject = pool.Spawn();
if (pooledObject != null)
{
markerInstance = pooledObject.Target as HandgunHitMarkerPooledInstance;
if (markerInstance != null)
{
return true;
}
}
GameObject markerGameObject = GameObject.CreatePrimitive(PrimitiveType.Sphere);
markerGameObject.name = "HandgunHitMarker";
Collider collider = markerGameObject.GetComponent<Collider>();
if (collider != null)
{
Object.Destroy(collider);
}
markerInstance = markerGameObject.AddComponent<HandgunHitMarkerPooledInstance>();
markerGameObject.SetActive(false);
pool.Register(HandgunHitMarkerPoolObject.Create(markerInstance), true);
return true;
}
private static IObjectPool<HandgunHitMarkerPoolObject> EnsurePool()
{
var poolComponent = GameEntry.ObjectPool;
if (poolComponent == null)
{
return null;
}
if (s_Pool != null && poolComponent.HasObjectPool<HandgunHitMarkerPoolObject>(PoolName))
{
return s_Pool;
}
s_Pool = poolComponent.HasObjectPool<HandgunHitMarkerPoolObject>(PoolName)
? poolComponent.GetObjectPool<HandgunHitMarkerPoolObject>(PoolName)
: poolComponent.CreateSingleSpawnObjectPool<HandgunHitMarkerPoolObject>(
PoolName,
PoolAutoReleaseInterval,
PoolCapacity,
PoolExpireTime,
PoolPriority);
return s_Pool;
}
private Material GetSharedMaterial()
{
if (_sharedMaterial != null)
{
return _sharedMaterial;
}
Shader shader = Shader.Find("Sprites/Default");
if (shader == null)
{
shader = Shader.Find("Unlit/Color");
}
_sharedMaterial = new Material(shader)
{
color = _color
};
return _sharedMaterial;
}
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: d944f33383dc4c1ebe850a12d4211afa
timeCreated: 1771481130
@@ -0,0 +1,27 @@
using GameFramework;
using GameFramework.ObjectPool;
using UnityEngine;
namespace Entity.Weapon
{
public sealed class HandgunHitMarkerPoolObject : ObjectBase
{
public static HandgunHitMarkerPoolObject Create(object target)
{
HandgunHitMarkerPoolObject pooledObject = ReferencePool.Acquire<HandgunHitMarkerPoolObject>();
pooledObject.Initialize(target);
return pooledObject;
}
protected override void Release(bool isShutdown)
{
HandgunHitMarkerPooledInstance markerInstance = Target as HandgunHitMarkerPooledInstance;
if (markerInstance == null)
{
return;
}
Object.Destroy(markerInstance.gameObject);
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 966d34a18f5d00c49bddea3c7c5ec13d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,78 @@
using GameFramework.ObjectPool;
using UnityEngine;
namespace Entity.Weapon
{
public sealed class HandgunHitMarkerPooledInstance : MonoBehaviour
{
private Renderer _renderer;
private IObjectPool<HandgunHitMarkerPoolObject> _ownerPool;
private float _expireTime;
private bool _isActive;
private void Awake()
{
_renderer = GetComponent<Renderer>();
}
private void Update()
{
if (!_isActive)
{
return;
}
if (Time.time < _expireTime)
{
return;
}
ReturnToPool();
}
public void ApplyMaterial(Material material)
{
if (_renderer == null)
{
_renderer = GetComponent<Renderer>();
}
if (_renderer == null)
{
return;
}
_renderer.sharedMaterial = material;
}
public void Activate(float duration, IObjectPool<HandgunHitMarkerPoolObject> pool)
{
_ownerPool = pool;
_expireTime = Time.time + Mathf.Max(0.01f, duration);
_isActive = true;
gameObject.SetActive(true);
}
private void OnDisable()
{
_isActive = false;
_ownerPool = null;
}
private void ReturnToPool()
{
_isActive = false;
IObjectPool<HandgunHitMarkerPoolObject> pool = _ownerPool;
_ownerPool = null;
transform.SetParent(null, false);
if (pool == null)
{
gameObject.SetActive(false);
return;
}
pool.Unspawn(this);
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7ff8a67466d8f0643845c41fd5952f50
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,9 @@
using UnityEngine;
namespace Entity.Weapon
{
public interface IWeaponAttackEffect
{
void Play(WeaponBase weapon, Vector3 position, EntityBase target, float radius);
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 231a935a484c4351b707b3e359074a47
timeCreated: 1771481068
@@ -0,0 +1,63 @@
using UnityEngine;
namespace Entity.Weapon
{
public sealed class KnifeRangeAttackEffect : IWeaponAttackEffect
{
private readonly float _duration = 0.2f;
private readonly float _yOffset = 0.05f;
private readonly float _lineWidth = 0.05f;
private readonly int _segments = 48;
private readonly Color _color = new(0.1f, 1f, 0.1f, 0.9f);
public KnifeRangeAttackEffect()
{
}
public KnifeRangeAttackEffect(float duration, float yOffset, float lineWidth, int segments, Color color)
{
_duration = duration;
_yOffset = yOffset;
_lineWidth = lineWidth;
_segments = Mathf.Max(8, segments);
_color = color;
}
public void Play(WeaponBase weapon, Vector3 position, EntityBase target, float radius)
{
float safeRadius = Mathf.Max(0.1f, radius);
GameObject indicator = new GameObject("KnifeRangeIndicator");
indicator.transform.position = new Vector3(position.x, position.y + _yOffset, position.z);
LineRenderer line = indicator.AddComponent<LineRenderer>();
line.loop = true;
line.useWorldSpace = true;
line.positionCount = _segments;
line.startWidth = _lineWidth;
line.endWidth = _lineWidth;
line.startColor = _color;
line.endColor = _color;
Shader shader = Shader.Find("Sprites/Default");
if (shader == null)
{
shader = Shader.Find("Unlit/Color");
}
Material material = new Material(shader);
material.color = _color;
line.material = material;
float step = Mathf.PI * 2f / _segments;
for (int i = 0; i < _segments; i++)
{
float angle = i * step;
Vector3 offset = new Vector3(Mathf.Cos(angle) * safeRadius, 0f, Mathf.Sin(angle) * safeRadius);
line.SetPosition(i, indicator.transform.position + offset);
}
Object.Destroy(indicator, Mathf.Max(0.01f, _duration));
}
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 8f48328040644546bf0a866cc337d3b2
timeCreated: 1771481100
@@ -0,0 +1,82 @@
using UnityEngine;
namespace Entity.Weapon
{
public sealed class LanceThrustAttackEffect : IWeaponAttackEffect
{
private readonly float _duration = 0.18f;
private readonly float _yOffset = 0.06f;
private readonly float _lineWidth = 0.05f;
private readonly Color _color = new(0.2f, 0.95f, 0.7f, 0.92f);
public LanceThrustAttackEffect()
{
}
public LanceThrustAttackEffect(float duration, float yOffset, float lineWidth, Color color)
{
_duration = duration;
_yOffset = yOffset;
_lineWidth = lineWidth;
_color = color;
}
public void Play(WeaponBase weapon, Vector3 position, EntityBase target, float radius)
{
if (weapon is not WeaponLance lance) return;
Vector3 forward = lance.StrikeDirection;
forward.y = 0f;
if (forward.sqrMagnitude <= Mathf.Epsilon)
{
forward = Vector3.forward;
}
forward.Normalize();
Vector3 right = Vector3.Cross(Vector3.up, forward);
float halfWidth = Mathf.Max(0.1f, lance.HitHalfWidth);
float halfLength = Mathf.Max(0.1f, lance.PierceLength * 0.5f);
Vector3 center = position + Vector3.up * _yOffset;
Vector3 frontCenter = center + forward * halfLength;
Vector3 backCenter = center - forward * halfLength;
Vector3[] corners =
{
frontCenter - right * halfWidth,
frontCenter + right * halfWidth,
backCenter + right * halfWidth,
backCenter - right * halfWidth,
};
GameObject indicator = new GameObject("LanceThrustIndicator");
indicator.transform.position = center;
LineRenderer line = indicator.AddComponent<LineRenderer>();
line.loop = true;
line.useWorldSpace = true;
line.positionCount = corners.Length;
line.startWidth = _lineWidth;
line.endWidth = _lineWidth;
line.startColor = _color;
line.endColor = _color;
Shader shader = Shader.Find("Sprites/Default");
if (shader == null)
{
shader = Shader.Find("Unlit/Color");
}
Material material = new Material(shader);
material.color = _color;
line.material = material;
for (int i = 0; i < corners.Length; i++)
{
line.SetPosition(i, corners[i]);
}
Object.Destroy(indicator, Mathf.Max(0.01f, _duration));
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 8c77c590c7233e544a9295ed41ff8827
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,81 @@
using UnityEngine;
namespace Entity.Weapon
{
public sealed class LightningStrikeAttackEffect : IWeaponAttackEffect
{
private readonly float _duration = 0.22f;
private readonly float _yOffset = 0.2f;
private readonly float _ringLineWidth = 0.045f;
private readonly float _boltLineWidth = 0.08f;
private readonly int _ringSegments = 32;
private readonly float _boltHeight = 3f;
private readonly Color _ringColor = new(0.35f, 0.82f, 1f, 0.92f);
private readonly Color _boltColor = new(0.85f, 0.96f, 1f, 0.97f);
public void Play(WeaponBase weapon, Vector3 position, EntityBase target, float radius)
{
float safeRadius = Mathf.Max(0.1f, radius);
Vector3 center = new Vector3(position.x, position.y + _yOffset, position.z);
GameObject root = new GameObject("LightningStrikeEffect");
root.transform.position = center;
Shader shader = Shader.Find("Sprites/Default");
if (shader == null)
{
shader = Shader.Find("Unlit/Color");
}
Material ringMaterial = new Material(shader);
ringMaterial.color = _ringColor;
LineRenderer ring = root.AddComponent<LineRenderer>();
ring.loop = true;
ring.useWorldSpace = true;
ring.positionCount = _ringSegments;
ring.startWidth = _ringLineWidth;
ring.endWidth = _ringLineWidth;
ring.startColor = _ringColor;
ring.endColor = _ringColor;
ring.material = ringMaterial;
float step = Mathf.PI * 2f / _ringSegments;
for (int i = 0; i < _ringSegments; i++)
{
float angle = i * step;
Vector3 offset = new Vector3(Mathf.Cos(angle) * safeRadius, 0f, Mathf.Sin(angle) * safeRadius);
ring.SetPosition(i, center + offset);
}
GameObject bolt = new GameObject("Bolt");
bolt.transform.SetParent(root.transform, false);
Material boltMaterial = new Material(shader);
boltMaterial.color = _boltColor;
LineRenderer boltLine = bolt.AddComponent<LineRenderer>();
boltLine.loop = false;
boltLine.useWorldSpace = true;
boltLine.positionCount = 4;
boltLine.startWidth = _boltLineWidth;
boltLine.endWidth = _boltLineWidth * 0.55f;
boltLine.startColor = _boltColor;
boltLine.endColor = _boltColor;
boltLine.material = boltMaterial;
Vector3 top = center + Vector3.up * _boltHeight;
Vector3 middleA = center + Vector3.up * (_boltHeight * 0.66f) +
new Vector3(Random.Range(-0.18f, 0.18f), 0f, Random.Range(-0.18f, 0.18f));
Vector3 middleB = center + Vector3.up * (_boltHeight * 0.3f) +
new Vector3(Random.Range(-0.12f, 0.12f), 0f, Random.Range(-0.12f, 0.12f));
boltLine.SetPosition(0, top);
boltLine.SetPosition(1, middleA);
boltLine.SetPosition(2, middleB);
boltLine.SetPosition(3, center);
Object.Destroy(root, Mathf.Max(0.01f, _duration));
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 81cbdf8961ad419c91b989d56ca782d0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,86 @@
using UnityEngine;
namespace Entity.Weapon
{
public sealed class SlashSectorAttackEffect : IWeaponAttackEffect
{
private readonly float _duration = 0.2f;
private readonly float _yOffset = 0.06f;
private readonly float _lineWidth = 0.05f;
private readonly int _segments = 24;
private readonly Color _color = new(1f, 0.45f, 0.2f, 0.9f);
public SlashSectorAttackEffect()
{
}
public SlashSectorAttackEffect(float duration, float yOffset, float lineWidth, int segments, Color color)
{
_duration = duration;
_yOffset = yOffset;
_lineWidth = lineWidth;
_segments = Mathf.Max(6, segments);
_color = color;
}
public void Play(WeaponBase weapon, Vector3 position, EntityBase target, float radius)
{
if (weapon is not WeaponSlash slash) return;
float safeRadius = Mathf.Max(0.1f, radius);
float sectorAngle = Mathf.Clamp(slash.SectorAngle, 1f, 360f);
GameObject indicator = new GameObject("SlashSectorIndicator");
Vector3 center = new Vector3(position.x, position.y + _yOffset, position.z);
indicator.transform.position = center;
LineRenderer line = indicator.AddComponent<LineRenderer>();
line.loop = false;
line.useWorldSpace = true;
line.startWidth = _lineWidth;
line.endWidth = _lineWidth;
line.startColor = _color;
line.endColor = _color;
Shader shader = Shader.Find("Sprites/Default");
if (shader == null)
{
shader = Shader.Find("Unlit/Color");
}
Material material = new Material(shader);
material.color = _color;
line.material = material;
float half = sectorAngle * 0.5f;
int arcPoints = _segments + 1;
int positionCount = arcPoints + 2;
line.positionCount = positionCount;
Vector3 forward = weapon.CachedTransform.forward;
forward.y = 0f;
if (forward.sqrMagnitude <= Mathf.Epsilon)
{
forward = Vector3.forward;
}
forward.Normalize();
Quaternion baseRotation = Quaternion.LookRotation(forward, Vector3.up);
line.SetPosition(0, center);
for (int i = 0; i < arcPoints; i++)
{
float t = arcPoints <= 1 ? 0f : i / (float)(arcPoints - 1);
float angle = Mathf.Lerp(-half, half, t);
Vector3 dir = Quaternion.Euler(0f, angle, 0f) * Vector3.forward;
Vector3 worldDir = baseRotation * dir;
line.SetPosition(i + 1, center + worldDir * safeRadius);
}
line.SetPosition(positionCount - 1, center);
UnityEngine.Object.Destroy(indicator, Mathf.Max(0.01f, _duration));
}
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 329af2c156b345f28a7465ef29c943da
timeCreated: 1771485834