做不出来

This commit is contained in:
SoulliesOfficial
2026-06-30 01:48:58 -04:00
parent 9a9e48f8a5
commit ddd387ef35
132 changed files with 8945 additions and 2943 deletions

View File

@@ -130,7 +130,7 @@ namespace Cielonos.MainGame.Characters
float currentMaxAngle = state.isWeak ? maxShakeAngle * weakShakeMultiplier : maxShakeAngle;
// ③ 高频正弦波,三轴不同频率 + 骨骼唯一种子
float t = Time.time * shakeFrequency;
float t = deltaTime * shakeFrequency;
float aX = currentMaxAngle * p * Mathf.Sin(t + state.seedX);
float aY = currentMaxAngle * p * Mathf.Sin(t * 1.3f + state.seedY);
float aZ = currentMaxAngle * p * Mathf.Sin(t * 0.7f + state.seedZ);

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 9af2cadfa58fe0443a1272f0e8521c3d
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,8 +1,11 @@
using System;
using DG.Tweening;
using Sirenix.OdinInspector;
using SLSUtilities.General;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.Serialization;
using Cielonos.MainGame.Effects;
namespace Cielonos.MainGame.Characters
{
@@ -48,7 +51,7 @@ namespace Cielonos.MainGame.Characters
}
}
public void SmartTurnToTarget(CharacterBase target, float maxTurnAngle = 360f)
public void SmartTurnToTarget(CharacterBase target, float maxTurnAngle = 360f, bool isInstant = false)
{
Vector3 directionToTarget = (target.CenterPoint.position - owner.CenterPoint.position).Flatten();
if (directionToTarget.sqrMagnitude < 0.001f) return;
@@ -68,7 +71,8 @@ namespace Cielonos.MainGame.Characters
else
{
float duration = Mathf.Lerp(0.1f, 0.2f, (absAngle - 45f) / 135f);
owner.transform.DORotateQuaternion(Quaternion.LookRotation(directionToTarget), duration).Play();
if(!isInstant) owner.transform.DORotateQuaternion(Quaternion.LookRotation(directionToTarget), duration).Play();
else owner.transform.rotation = Quaternion.LookRotation(directionToTarget);
}
}
@@ -184,4 +188,5 @@ namespace Cielonos.MainGame.Characters
ByMovement,
}
}
}

View File

@@ -0,0 +1,217 @@
using System;
using UnityEngine;
using UnityEngine.AI;
using Cielonos.MainGame.Effects;
using SLSUtilities.General;
namespace Cielonos.MainGame.Characters
{
public partial class MovementSubcontrollerBase
{
/// <summary>
/// 根据目标敌人的碰撞体边缘,计算不产生重叠/挤压的安全折跃落脚点。
/// </summary>
/// <param name="target">折跃目标</param>
/// <param name="stopDistance">目标表面前的停止缓冲距离(默认为 1.0f</param>
/// <returns>安全世界坐标</returns>
public Vector3 GetSafePositionNearTarget(CharacterBase target, float stopDistance = 1.0f)
{
if (target == null)
{
return owner.transform.position;
}
Vector3 selfPos = owner.transform.position;
Vector3 targetPos = target.transform.position;
// 计算平面方向向量
Vector3 dir = (targetPos - selfPos).Flatten();
if (dir.sqrMagnitude < 0.001f)
{
dir = owner.transform.forward;
}
else
{
dir.Normalize();
}
// 获取双方的碰撞半径(如果有 CharacterController
float selfRadius = 0.5f;
float targetRadius = 0.5f;
if (owner.collisionSc != null && owner.collisionSc.characterController != null)
{
selfRadius = owner.collisionSc.characterController.radius;
}
else
{
var cc = owner.GetComponent<CharacterController>();
if (cc != null) selfRadius = cc.radius;
}
if (target.collisionSc != null && target.collisionSc.characterController != null)
{
targetRadius = target.collisionSc.characterController.radius;
}
else
{
var cc = target.GetComponent<CharacterController>();
if (cc != null) targetRadius = cc.radius;
}
// 安全距离 = 双方半径之和 + 额外的缓冲停止距离
float safeDistance = selfRadius + targetRadius + stopDistance;
// 目标点位于:目标中心 沿着 玩家至目标的方向 往回拉 safeDistance 距离
Vector3 finalDest = targetPos - dir * safeDistance;
// 保持 Y 轴与目标地面或自身对齐(避免陷地或腾空)
finalDest.y = targetPos.y;
return finalDest;
}
/// <summary>
/// 瞬移/闪现至目标位置(支持高速移动过程)
/// </summary>
/// <param name="destination">目标位置</param>
/// <param name="duration">移动时间(秒)。若为 0 则为即时瞬移</param>
/// <param name="onComplete">瞬移完成后(或即时瞬移时)的回调函数,可用于生成 VFX/音效</param>
public void Teleport(Vector3 destination, float duration, Action onComplete = null)
{
// 1. 进行 NavMesh 采样验证(寻找最近的可行进点)
Vector3 validDestination = destination;
if (NavMesh.SamplePosition(destination, out NavMeshHit hit, 5.0f, NavMesh.AllAreas))
{
validDestination = hit.position;
}
// 2. 如果是即时瞬移duration <= 0
if (duration <= 0f)
{
PerformMove(validDestination);
onComplete?.Invoke();
return;
}
// 3. 带有延迟/移动过程的瞬移
// 记录起始点
Vector3 startPos = owner.transform.position;
// 赋予无敌状态(防受击)
owner.statusSm.AddStatus(StatusType.Invincible, duration);
// 锁定移动和旋转输入(使用高优先级 99 隔离普通移动控制)
canMove.Modify(false, 99);
canRotate.Modify(false, 99);
// 开启残影生成(位移开始时生成单个残影)
var afterImageGen = owner.GetComponent<AfterImageGenerator>();
if (afterImageGen != null)
{
afterImageGen.CreateAfterImageSnapshot();
}
// 获取并临时关闭物理/寻路组件,避免移动中碰撞卡顿或位置拉回
var agent = owner.GetComponent<NavMeshAgent>();
bool wasAgentActive = agent != null && agent.isActiveAndEnabled;
if (wasAgentActive)
{
agent.enabled = false;
}
var cc = owner.collisionSc != null ? owner.collisionSc.characterController : null;
bool wasCcActive = cc != null && cc.enabled;
if (wasCcActive)
{
cc.enabled = false;
}
var rb = owner.collisionSc != null ? owner.collisionSc.mainRigidbody : null;
bool wasRbKinematic = rb != null && rb.isKinematic;
if (rb != null)
{
rb.isKinematic = true;
}
// 使用本地计时器,更新过程中的插值位移
float elapsed = 0f;
owner.selfTimeSm.AddLocalTimer(duration,
onComplete: () =>
{
// 确保移动完毕并最终强制对齐
owner.transform.position = validDestination;
// 恢复组件状态
if (rb != null)
{
rb.isKinematic = wasRbKinematic;
}
if (cc != null && wasCcActive)
{
cc.enabled = true;
}
if (agent != null && wasAgentActive)
{
agent.enabled = true;
agent.Warp(validDestination);
}
// 解锁移动和旋转输入
canMove.Modify(true, 99);
canRotate.Modify(true, 99);
// 触发完成回调
onComplete?.Invoke();
},
onUpdate: () =>
{
elapsed += DeltaTime;
float t = Mathf.Clamp01(elapsed / duration);
Vector3 currentPos = Vector3.Lerp(startPos, validDestination, t);
// 平滑设置物理和变换位置
if (rb != null)
{
rb.position = currentPos;
}
owner.transform.position = currentPos;
}
);
}
/// <summary>
/// 底层物理突变移动处理
/// </summary>
private void PerformMove(Vector3 targetPos)
{
var agent = owner.GetComponent<NavMeshAgent>();
if (agent != null && agent.isActiveAndEnabled)
{
agent.Warp(targetPos);
}
else if (owner.collisionSc != null)
{
if (owner.collisionSc.useCharacterController && owner.collisionSc.characterController != null)
{
owner.collisionSc.characterController.enabled = false;
owner.transform.position = targetPos;
owner.collisionSc.characterController.enabled = true;
}
else if (owner.collisionSc.mainRigidbody != null)
{
owner.collisionSc.mainRigidbody.position = targetPos;
owner.transform.position = targetPos;
}
else
{
owner.transform.position = targetPos;
}
}
else
{
owner.transform.position = targetPos;
}
}
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 5d9130106184f0142a4fdf38d6a574e6