[WL-816t] 검기 크기 = 공격 범위 · 무기 위치 정합 (#816)
원인(실측): 검기 캘리브레이션 8행이 교체 전 캐릭터 Ai01(root scale 1 · 무기 원본 크기) 기준으로 구워져 있고, 런타임 캐릭터는 814n/814p 로 LH_M05(root scale 1.0527 = f_Scale 0.70 x heightComp 1.5038) + 무기 x0.54~0.66 로 바뀌었다. 로컬 프레임이 달라 호 중심이 0.36~0.88 m, 평면 법선이 6.9~61.0 deg 어긋난 채 고정돼 있었고, 이 오차 벡터가 캐릭터와 함께 돌아 화면에서는 가로 -0.50~+0.59 m / 세로 -0.46~+0.86 m 로 방향마다 다르게 보였다. - WL816t_Bake: 런타임과 같은 PC(swap resolve) x 같은 스케일 x 같은 무기 보정(WLWeaponFitter.Fit)으로 1/2/3 타 클립을 60 Hz 샘플 -> 런타임 ToLocalPos 규약(회전만)으로 12행 재베이크 (구 8행 대체) - SlashTrailSettings: arcFitAttackRange / arcRangeScale 신설 (기본 off = 무동작 · C8 롤백) - WeaponTrailDriver.PlaceArc: 스위치 on 이면 호 바깥 반지름 = 공격 범위 (stoppingDistance 양수 최솟값 + AttackRange_Up + immediateAttackMargin · WLRangeRing 과 같은 SOT · 상수 0개) - 8방향 x 3타 편차 0.525/0.361/0.864 m -> 0.000 m · 법선 61.0/20.5/23.5 deg -> 0.0 deg Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
ddf0e12655
commit
f35dab8542
|
|
@ -0,0 +1,305 @@
|
|||
// WL816t_Bake.cs — 검기 호 ↔ 무기 정합 실측·재베이크 (PD #816t)
|
||||
// unity command run_script --file AgentScripts/WL816t_Bake.cs --entry WL816t_Bake.Probe --args "[10101, false]"
|
||||
// unity command run_script --file AgentScripts/WL816t_Bake.cs --entry WL816t_Bake.Probe --args "[10101, true]" (SO 기록)
|
||||
//
|
||||
// WL804_Bake 와 같은 수식(SlashArcMeasure)·같은 프리뷰 샘플링을 쓰되 **런타임과 같은 캐릭터**로 잰다.
|
||||
// · WL804_Bake : Assets/Res_Addr/PC/Ai01.prefab · root scale 1 · 무기 localScale 1 · root.InverseTransformPoint(스케일 포함)
|
||||
// · 런타임 : WLCharacterSwapSettings.Resolve("Ai01") = LH_M05 · root scale = f_Scale × heightCompensation
|
||||
// · 무기 = WLWeaponFitter.Fit(targetRatio 0.6) · ToLocalPos = 회전만(스케일 제외)
|
||||
// 두 좌표계가 달라서 베이크 행이 현재 캐릭터의 칼끝 원과 어긋난다 — 그 편차를 재고 새 행을 만든다.
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEditor;
|
||||
using UnityEditor.SceneManagement;
|
||||
using UnityEngine;
|
||||
using WL.Combat;
|
||||
|
||||
public static class WL816t_Bake
|
||||
{
|
||||
const string SettingsPath = "Assets/WL/Settings/Resources/WL/SlashTrailSettings.asset";
|
||||
const string ClassConfigJson = "Assets/ResWork/Table/Export/ClassConfig.json";
|
||||
const string AnimDir = "Assets/Res_Addr/Animations/Animation/OneHand/Knight@Attack{0}_S.FBX";
|
||||
const float BakedQuality = 50f;
|
||||
|
||||
class Row
|
||||
{
|
||||
public int stage; public string clipName;
|
||||
public Vector3 pivot, normal, bisector, startDir; public float tipR, hiltR, sweep, path, fitQ, q;
|
||||
public Vector3 tipMid; // 스윙 중간 프레임의 칼끝(런타임 로컬)
|
||||
public string src;
|
||||
}
|
||||
|
||||
static readonly int[] Classes = { 10101, 10102, 10501, 10502 };
|
||||
|
||||
public static object Probe(int classId, bool apply) { return Run(classId, apply, true); }
|
||||
public static object ProbeAll()
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
foreach (var c in Classes) sb.AppendLine(Run(c, false, false));
|
||||
return sb.ToString();
|
||||
}
|
||||
public static object ApplyAll()
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
foreach (var c in Classes) sb.AppendLine(Run(c, true, false));
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
/// <summary>공격 범위 정합 스위치 on/off + 배수. 되돌리기 = Set(false, 1)</summary>
|
||||
public static object SetRangeFit(bool on, float rangeScale)
|
||||
{
|
||||
var s = AssetDatabase.LoadAssetAtPath<SlashTrailSettings>(SettingsPath);
|
||||
if (s == null) return "설정 에셋 없음";
|
||||
string before = string.Format("before: arcFitAttackRange={0} arcRangeScale={1:F2} arcSizeScale={2:F2}", s.arcFitAttackRange, s.arcRangeScale, s.arcSizeScale);
|
||||
s.arcFitAttackRange = on; s.arcRangeScale = rangeScale;
|
||||
EditorUtility.SetDirty(s); AssetDatabase.SaveAssets();
|
||||
return before + string.Format(" → after: arcFitAttackRange={0} arcRangeScale={1:F2} arcSizeScale={2:F2}", s.arcFitAttackRange, s.arcRangeScale, s.arcSizeScale);
|
||||
}
|
||||
|
||||
/// <summary>공격 범위(사거리) 정적 검산 — 런타임 ResolveAttackReach 와 같은 SOT.</summary>
|
||||
public static object Reach(int classId)
|
||||
{
|
||||
float atk = 0f;
|
||||
var arr = Newtonsoft.Json.Linq.JArray.Parse(System.IO.File.ReadAllText(ClassConfigJson));
|
||||
foreach (var row in arr) { if ((string)row["n_ClassID"] == classId.ToString()) { float.TryParse((string)row["f_AttackRange"], out atk); break; } }
|
||||
float margin = WL.Settings.WLTargetingSettings.ImmediateAttackMargin;
|
||||
return string.Format("class {0} · f_AttackRange={1:F2} + AttackRange_Up(평시 0) + immediateAttackMargin={2:F2} = reach {3:F2} m", classId, atk, margin, atk + margin);
|
||||
}
|
||||
|
||||
static string Run(int classId, bool apply, bool table)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
var settings = AssetDatabase.LoadAssetAtPath<SlashTrailSettings>(SettingsPath);
|
||||
if (settings == null) return "설정 에셋 없음";
|
||||
|
||||
// ── ClassConfig (C45 · 상수 금지) ────────────────────────────────────
|
||||
string weaponName = null; int socketIndex = -1; float fScale = 1f, atkRange = 0f;
|
||||
try
|
||||
{
|
||||
var arr = Newtonsoft.Json.Linq.JArray.Parse(System.IO.File.ReadAllText(ClassConfigJson));
|
||||
foreach (var row in arr)
|
||||
{
|
||||
if ((string)row["n_ClassID"] != classId.ToString()) continue;
|
||||
weaponName = (string)row["s_WeaponRHPrefab"]; socketIndex = int.Parse((string)row["n_WeaponRHIndex"]);
|
||||
if (string.IsNullOrEmpty(weaponName)) { weaponName = (string)row["s_WeaponLHPrefab"]; socketIndex = int.Parse((string)row["n_WeaponLHIndex"]); }
|
||||
float.TryParse((string)row["f_Scale"], out fScale);
|
||||
float.TryParse((string)row["f_AttackRange"], out atkRange);
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (System.Exception ex) { return "ClassConfig parse fail: " + ex.Message; }
|
||||
if (string.IsNullOrEmpty(weaponName) || socketIndex < 0) return "class " + classId + " weapon not found";
|
||||
|
||||
// ── 런타임과 같은 PC 프리팹·스케일 ──────────────────────────────────
|
||||
string pcName = WL.Character.WLCharacterSwapSettings.Resolve("Ai01");
|
||||
float heightComp = WL.Character.WLCharacterSwapSettings.HeightCompensation;
|
||||
string pcPath = "Assets/Res_Addr/PC/" + pcName + ".prefab";
|
||||
var model = AssetDatabase.LoadAssetAtPath<GameObject>(pcPath);
|
||||
var weaponPrefab = AssetDatabase.LoadAssetAtPath<GameObject>("Assets/Res_Addr/Weapon/" + weaponName + ".prefab");
|
||||
if (model == null || weaponPrefab == null) return "load fail pc=" + pcPath + " weapon=" + weaponName;
|
||||
|
||||
float rootScale = Mathf.Max(fScale, 0.01f) * Mathf.Max(heightComp, 0.01f);
|
||||
sb.AppendLine(string.Format("== class {0} · PC {1}(swap:{2}) rootScale={3:F4}(f_Scale {4:F2} × heightComp {5:F4}) · weapon {6}@{7} · f_AttackRange={8:F2}",
|
||||
classId, pcName, pcName != "Ai01", rootScale, fScale, heightComp, weaponName, socketIndex, atkRange));
|
||||
|
||||
var scene = EditorSceneManager.NewPreviewScene();
|
||||
bool animMode = false;
|
||||
var rows = new List<Row>();
|
||||
try
|
||||
{
|
||||
var go = (GameObject)PrefabUtility.InstantiatePrefab(model, scene);
|
||||
go.transform.position = Vector3.zero; go.transform.rotation = Quaternion.identity;
|
||||
go.transform.localScale = Vector3.one * rootScale;
|
||||
|
||||
var pc = go.GetComponentInChildren<PCActor>(true);
|
||||
if (pc == null || pc.tfs_weapon == null || socketIndex >= pc.tfs_weapon.Length) return sb + "\ntfs_weapon missing";
|
||||
var socket = pc.tfs_weapon[socketIndex];
|
||||
|
||||
var w = (GameObject)PrefabUtility.InstantiatePrefab(weaponPrefab, scene);
|
||||
w.transform.SetParent(socket, false);
|
||||
w.transform.localPosition = Vector3.zero; w.transform.localRotation = Quaternion.identity; w.transform.localScale = Vector3.one;
|
||||
|
||||
// ── 814p 무기 축소(런타임과 동일 경로) ──────────────────────────
|
||||
var fitter = go.GetComponent<WL.Character.WLWeaponFitter>();
|
||||
if (fitter == null) fitter = go.AddComponent<WL.Character.WLWeaponFitter>();
|
||||
float wk = fitter.Fit(w.transform, socket);
|
||||
sb.AppendLine(string.Format(" 무기 보정 ×{0:F4} (WLWeaponFitter.Fit · targetRatio={1:F2})", wk, WL.Character.WLWeaponFitSettings.ResolveRatio(w.name)));
|
||||
|
||||
// ── 칼자루/칼끝 로컬(WL804_Bake·MeasureSlot 과 같은 규칙) ────────
|
||||
Renderer best = null; Mesh bestMesh = null; float bestExtent = 0f;
|
||||
foreach (var r in socket.GetComponentsInChildren<Renderer>(true))
|
||||
{
|
||||
var mf2 = r.GetComponent<MeshFilter>(); var smr = r as SkinnedMeshRenderer;
|
||||
var mesh = smr != null ? smr.sharedMesh : (mf2 != null ? mf2.sharedMesh : null);
|
||||
if (mesh == null) continue;
|
||||
var ws = Vector3.Scale(mesh.bounds.size, Abs(r.transform.lossyScale));
|
||||
float longest = Mathf.Max(ws.x, Mathf.Max(ws.y, ws.z));
|
||||
if (longest > bestExtent) { bestExtent = longest; best = r; bestMesh = mesh; }
|
||||
}
|
||||
if (best == null) return sb + "\nno renderer under socket";
|
||||
var b = bestMesh.bounds; var size = Vector3.Scale(b.size, Abs(best.transform.lossyScale));
|
||||
int axis = size.x >= size.y && size.x >= size.z ? 0 : (size.y >= size.z ? 1 : 2);
|
||||
Vector3 axisDir = Vector3.zero; axisDir[axis] = 1f;
|
||||
Vector3 eA = best.transform.TransformPoint(b.center - axisDir * b.extents[axis]);
|
||||
Vector3 eB = best.transform.TransformPoint(b.center + axisDir * b.extents[axis]);
|
||||
bool aIsHilt = (eA - socket.position).sqrMagnitude <= (eB - socket.position).sqrMagnitude;
|
||||
Vector3 hiltLocal = socket.InverseTransformPoint(aIsHilt ? eA : eB);
|
||||
Vector3 tipLocal = socket.InverseTransformPoint(aIsHilt ? eB : eA);
|
||||
sb.AppendLine(string.Format(" 무기 월드 길이 {0:F3} m · 칼끝-자루 {1:F3} m", bestExtent,
|
||||
Vector3.Distance(socket.TransformPoint(tipLocal), socket.TransformPoint(hiltLocal))));
|
||||
|
||||
var anim = go.GetComponentInChildren<Animator>();
|
||||
var animGo = anim.gameObject; anim.applyRootMotion = false;
|
||||
var root = go.transform;
|
||||
|
||||
AnimationMode.StartAnimationMode(); animMode = true;
|
||||
for (int stage = 1; stage <= 3; stage++)
|
||||
{
|
||||
var fbx = string.Format(AnimDir, stage);
|
||||
var clips = AssetDatabase.LoadAllAssetsAtPath(fbx).OfType<AnimationClip>().Where(c => !c.name.StartsWith("__preview")).ToArray();
|
||||
var clip = clips.FirstOrDefault(c => c.name == "Attack" + stage + "_S_" + classId) ?? clips.FirstOrDefault(c => c.name.StartsWith("Attack" + stage));
|
||||
if (clip == null) { sb.AppendLine(" [" + stage + "타] 클립 없음 " + fbx); continue; }
|
||||
|
||||
// 클립 전체를 60 Hz 로 훑고 런타임과 같은 속도 트림으로 스윙 구간만 남긴다
|
||||
int n0 = Mathf.Max(8, Mathf.RoundToInt(clip.length * 60f) + 1);
|
||||
var tAll = new Vector3[n0]; var hAll = new Vector3[n0];
|
||||
for (int i = 0; i < n0; i++)
|
||||
{
|
||||
float t = clip.length * i / (n0 - 1);
|
||||
AnimationMode.BeginSampling();
|
||||
AnimationMode.SampleAnimationClip(animGo, clip, t);
|
||||
AnimationMode.EndSampling();
|
||||
// 🔴 런타임 ToLocalPos 와 동일 = 회전만(스케일 제외)
|
||||
tAll[i] = Quaternion.Inverse(root.rotation) * (socket.TransformPoint(tipLocal) - root.position);
|
||||
hAll[i] = Quaternion.Inverse(root.rotation) * (socket.TransformPoint(hiltLocal) - root.position);
|
||||
}
|
||||
int lo = 0, hi = n0 - 1;
|
||||
float ratio = settings.swingTrimSpeedRatio;
|
||||
if (ratio > 0f)
|
||||
{
|
||||
float maxStep = 0f; var step = new float[n0];
|
||||
for (int i = 1; i < n0; i++) { step[i] = Vector3.Distance(tAll[i], tAll[i - 1]); if (step[i] > maxStep) maxStep = step[i]; }
|
||||
float th = maxStep * ratio; int f = -1, l = -1;
|
||||
for (int i = 1; i < n0; i++) if (step[i] >= th) { if (f < 0) f = i - 1; l = i; }
|
||||
if (f >= 0 && l > f) { lo = f; hi = l; }
|
||||
}
|
||||
int n = hi - lo + 1;
|
||||
if (n < 3) { lo = 0; hi = n0 - 1; n = n0; }
|
||||
var tips = new Vector3[n]; var hilts = new Vector3[n];
|
||||
for (int i = 0; i < n; i++) { tips[i] = tAll[lo + i]; hilts[i] = hAll[lo + i]; }
|
||||
|
||||
float fullPath = 0f; Vector3 pd = (tips[0] - hilts[0]).normalized; float bladeAng = 0f;
|
||||
for (int i = 1; i < n; i++)
|
||||
{
|
||||
fullPath += Vector3.Distance(tips[i], tips[i - 1]);
|
||||
var d = (tips[i] - hilts[i]).normalized; bladeAng += Vector3.Angle(pd, d); pd = d;
|
||||
}
|
||||
|
||||
var fit = SlashArcMeasure.FitArcOrdered(tips, n);
|
||||
if (!fit.valid) { sb.AppendLine(" [" + stage + "타] 원 피팅 실패 (n=" + n + ")"); continue; }
|
||||
Vector3 nrm = fit.normal, pivot = fit.center;
|
||||
float tipR = SlashArcMeasure.MeanRadius(tips, n, pivot, nrm);
|
||||
float hiltR = SlashArcMeasure.MeanRadius(hilts, n, pivot, nrm);
|
||||
float dev = SlashArcMeasure.RadiusDeviation(tips, n, pivot, nrm, tipR);
|
||||
string pivotSrc = "칼끝원";
|
||||
if (tipR < 1e-3f || tipR <= hiltR * 1.15f || dev > tipR * 0.25f)
|
||||
{
|
||||
Vector3 tc = SlashArcMeasure.CentroidOnPlane(tips, n, nrm, tips[0]);
|
||||
pivot = SlashArcMeasure.CentroidOnPlane(hilts, n, nrm, tc);
|
||||
tipR = SlashArcMeasure.MeanRadius(tips, n, pivot, nrm);
|
||||
hiltR = SlashArcMeasure.MeanRadius(hilts, n, pivot, nrm);
|
||||
pivotSrc = "손잡이중심";
|
||||
}
|
||||
Vector3 sd2, bis; float sweep;
|
||||
if (!SlashArcMeasure.RecomputeAboutPivot(tips, n, pivot, ref nrm, out sd2, out bis, out sweep))
|
||||
{ sb.AppendLine(" [" + stage + "타] RecomputeAboutPivot 실패"); continue; }
|
||||
float fitQ = Mathf.Clamp01(1f - (dev / Mathf.Max(tipR, 1e-3f)) * 2f);
|
||||
|
||||
rows.Add(new Row
|
||||
{
|
||||
stage = stage, clipName = "Effect_Slash_" + classId + "_" + stage,
|
||||
pivot = pivot, normal = nrm, bisector = bis, startDir = sd2,
|
||||
tipR = tipR, hiltR = hiltR, sweep = sweep, path = fullPath, fitQ = fitQ,
|
||||
q = fullPath * Mathf.Max(fitQ, 0.05f), tipMid = tips[n / 2],
|
||||
src = string.Format("wl816t {0:yyyy-MM-dd HH:mm} {1} f{2}~f{3}/{4}@60Hz n={5} PC={6} rootScale={7:F4} weaponK={8:F4} path={9:F2} bladeAng={10:F0}° sweep={11:F1}° pivot={12} tipR={13:F3} hiltR={14:F3} dev={15:F3} fitQ={16:F2} (런타임 로컬=회전만)",
|
||||
System.DateTime.Now, clip.name, lo, hi, n0 - 1, n, pcName, rootScale, wk, fullPath, bladeAng, sweep, pivotSrc, tipR, hiltR, dev, fitQ)
|
||||
});
|
||||
}
|
||||
AnimationMode.StopAnimationMode(); animMode = false;
|
||||
|
||||
// ── 비교 + 8방향 편차 ───────────────────────────────────────────
|
||||
sb.AppendLine("");
|
||||
sb.AppendLine("clip | old pivot(로컬) tipR | new pivot(로컬) tipR | Δpivot(m) ΔtipR(m) Δnormal(°)");
|
||||
var cams = CamBasis();
|
||||
var devTable = new StringBuilder();
|
||||
foreach (var r in rows)
|
||||
{
|
||||
var old = settings.FindCalibration(classId, r.clipName);
|
||||
if (old == null) { sb.AppendLine(string.Format("{0,-23} | (없음) | {1} {2:F3} | -", r.clipName, V(r.pivot), r.tipR)); continue; }
|
||||
float dPiv = Vector3.Distance(old.pivot, r.pivot);
|
||||
float dTip = r.tipR - old.tipRadius;
|
||||
float dNrm = Vector3.Angle(old.planeNormal, r.normal);
|
||||
sb.AppendLine(string.Format("{0,-23} | {1} {2:F3} | {3} {4:F3} | {5:F3} {6:+0.000;-0.000} {7:F1}",
|
||||
r.clipName, V(old.pivot), old.tipRadius, V(r.pivot), r.tipR, dPiv, dTip, dNrm));
|
||||
|
||||
// 8방향: 구 행으로 배치한 호의 중심/테두리 vs 실제 칼끝
|
||||
if (!table) continue;
|
||||
devTable.AppendLine(" " + r.clipName);
|
||||
devTable.AppendLine(" yaw | Δ중심(m) 화면Δ가로(m) 화면Δ세로(m) | 칼끝-호테두리 반경차(m)");
|
||||
for (int k = 0; k < 8; k++)
|
||||
{
|
||||
float yaw = k * 45f;
|
||||
var rot = Quaternion.Euler(0f, yaw, 0f);
|
||||
Vector3 oldPivW = rot * old.pivot; // root at origin
|
||||
Vector3 newPivW = rot * r.pivot;
|
||||
Vector3 tipW = rot * r.tipMid;
|
||||
Vector3 d = oldPivW - newPivW;
|
||||
float radialGap = Vector3.Distance(tipW, oldPivW) - old.tipRadius * Mathf.Max(settings.arcSizeScale, 0.01f);
|
||||
devTable.AppendLine(string.Format(" {0,3:F0} | {1:F3} {2,8:+0.000;-0.000} {3,8:+0.000;-0.000} | {4,8:+0.000;-0.000}",
|
||||
yaw, d.magnitude, Vector3.Dot(d, cams[0]), Vector3.Dot(d, cams[1]), radialGap));
|
||||
}
|
||||
}
|
||||
sb.AppendLine("");
|
||||
sb.AppendLine("8방향 편차(카메라 기준 · PD 구도 yaw45 내려보기 45°)");
|
||||
sb.Append(devTable);
|
||||
|
||||
if (apply)
|
||||
{
|
||||
int removed = 0;
|
||||
foreach (var r in rows)
|
||||
{
|
||||
removed += settings.swingCalibrations.RemoveAll(c => c != null && c.classId == classId && c.clipName == r.clipName);
|
||||
settings.swingCalibrations.Add(new SwingCalibration
|
||||
{
|
||||
classId = classId, clipName = r.clipName, kind = SwingKind.Swing,
|
||||
planeNormal = r.normal, bisector = r.bisector, startDir = r.startDir,
|
||||
pivot = r.pivot, tipRadius = r.tipR, hiltRadius = r.hiltR, sweepDeg = r.sweep,
|
||||
stabAxis = Vector3.forward, stabStart = r.pivot, stabLength = Mathf.Max(r.tipR, 1e-3f),
|
||||
quality = Mathf.Max(BakedQuality, r.q), source = r.src
|
||||
});
|
||||
}
|
||||
EditorUtility.SetDirty(settings);
|
||||
AssetDatabase.SaveAssets();
|
||||
sb.AppendLine(string.Format("APPLIED {0}행 (기존 {1}행 교체 · 총 {2}행)", rows.Count, removed, settings.swingCalibrations.Count));
|
||||
}
|
||||
else sb.AppendLine("(dry)");
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (animMode) AnimationMode.StopAnimationMode();
|
||||
EditorSceneManager.ClosePreviewScene(scene);
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
/// <summary>PD 구도(비스듬히 내려보는 카메라)의 화면 가로·세로 축(월드).</summary>
|
||||
static Vector3[] CamBasis()
|
||||
{
|
||||
var rot = Quaternion.Euler(45f, 45f, 0f);
|
||||
return new[] { rot * Vector3.right, rot * Vector3.up };
|
||||
}
|
||||
|
||||
static string V(Vector3 v) { return string.Format("({0,6:F3},{1,6:F3},{2,6:F3})", v.x, v.y, v.z); }
|
||||
static Vector3 Abs(Vector3 v) { return new Vector3(Mathf.Abs(v.x), Mathf.Abs(v.y), Mathf.Abs(v.z)); }
|
||||
}
|
||||
|
|
@ -788,6 +788,15 @@ namespace WL.Combat
|
|||
[Tooltip("정합한 크기에 곱하는 배수. 1 = 칼끝 반경과 정확히 일치(기본 · C3-5)")]
|
||||
[Range(0.4f, 2.5f)] public float arcSizeScale = 1f;
|
||||
|
||||
[Tooltip("■ #816t — 호 바깥 반지름을 칼끝 반경 대신 **플레이어 공격 범위**(사거리)에 맞춘다. " +
|
||||
"출처 = NavMeshAgent.stoppingDistance 양수 최솟값(= ClassConfig f_AttackRange · PCActor.cs:381) " +
|
||||
"+ eStat.AttackRange_Up + WLTargetingSettings.immediateAttackMargin — WLRangeRing 과 같은 SOT(상수 0개 · C45). " +
|
||||
"끄면 즉시 이전(칼끝 반경 정합) 동작으로 돌아간다(C8 롤백)")]
|
||||
public bool arcFitAttackRange = false;
|
||||
|
||||
[Tooltip("공격 범위에 곱하는 배수. 1 = 사거리와 정확히 일치")]
|
||||
[Range(0.3f, 2f)] public float arcRangeScale = 1f;
|
||||
|
||||
[Tooltip("호를 스윙 평면에서 법선 방향으로 이만큼(m) 띄운다. 0 = 평면 위. " +
|
||||
"무기 메시와 Z-파이팅이 보이면 아주 작은 값을 준다")]
|
||||
public float arcPlaneOffset = 0f;
|
||||
|
|
|
|||
|
|
@ -1602,6 +1602,13 @@ namespace WL.Combat
|
|||
s = cal.tipRadius / mf.radiusOuter;
|
||||
break;
|
||||
}
|
||||
// ── #816t 공격 범위 정합 — 호 바깥 반지름을 플레이어 사거리에 맞춘다(PD 지시) ──
|
||||
// 출처는 WLRangeRing 과 같은 SOT(테이블 f_AttackRange + 버프 + 즉시공격 여유). 상수 0 개(C45).
|
||||
// 사거리를 못 읽으면(로비·스탯 미초기화) 0 → 위의 칼끝 반경 정합을 그대로 쓴다.
|
||||
float reach = settings.arcFitAttackRange ? ResolveAttackReach() : 0f;
|
||||
if (reach > 0.01f && mf.radiusOuter > 1e-4f)
|
||||
s = reach * Mathf.Max(settings.arcRangeScale, 0.01f) / mf.radiusOuter;
|
||||
|
||||
s *= Mathf.Max(settings.arcSizeScale, 0.01f);
|
||||
|
||||
// ── 회전 · 위치 ────────────────────────────────────────────────
|
||||
|
|
@ -1740,6 +1747,34 @@ namespace WL.Combat
|
|||
private Vector3 ToLocalPos(Vector3 world) { return Quaternion.Inverse(transform.rotation) * (world - transform.position); }
|
||||
private Vector3 ToWorldPos(Vector3 local) { return transform.position + transform.rotation * local; }
|
||||
|
||||
// ── #816t 공격 범위(사거리) 해석 — WLRangeRing.Poll 과 같은 출처·같은 수식 ──────
|
||||
// stoppingDistance 는 타겟 반경·크기 보정으로 커질 수 있어(MyActor.cs:207·212·213)
|
||||
// **양수 최솟값**을 기억한다 = 보정 없는 평시 값 = ClassConfig f_AttackRange(PCActor.cs:381).
|
||||
private float _baseStop;
|
||||
|
||||
/// <summary>마지막으로 해석한 공격 범위(m). 0 = 아직 못 읽음(검증용 읽기 전용 · 게임 로직은 쓰지 않는다).</summary>
|
||||
public static float LastAttackReach;
|
||||
|
||||
private float ResolveAttackReach()
|
||||
{
|
||||
if (_pc == null) return 0f;
|
||||
var agent = _pc.Get_Agent();
|
||||
if (agent != null)
|
||||
{
|
||||
float sd = agent.stoppingDistance;
|
||||
if (sd > 0.01f && (_baseStop <= 0f || sd < _baseStop)) _baseStop = sd;
|
||||
}
|
||||
if (_baseStop <= 0f) return 0f;
|
||||
|
||||
float up = 0f;
|
||||
var stat = _pc.Get_StatInfo();
|
||||
if (stat != null) up = (float)stat.Get_Stat(eStat.AttackRange_Up);
|
||||
|
||||
float reach = _baseStop + up + WL.Settings.WLTargetingSettings.ImmediateAttackMargin;
|
||||
LastAttackReach = reach;
|
||||
return reach;
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────
|
||||
// 수명 관리
|
||||
// ─────────────────────────────────────────────────────────────────────────
|
||||
|
|
|
|||
|
|
@ -407,150 +407,217 @@ MonoBehaviour:
|
|||
flipAxis: 0
|
||||
bakedAt: 2026-09-07 01:52:52
|
||||
swingCalibrations:
|
||||
- classId: 10501
|
||||
clipName: Effect_Slash_10501_2
|
||||
kind: 1
|
||||
planeNormal: {x: 0.15228733, y: 0.9881525, z: -0.01905872}
|
||||
pivot: {x: -0.01862258, y: 0.8349972, z: 0.039082136}
|
||||
bisector: {x: 0.9480554, y: -0.14060435, z: 0.28534392}
|
||||
startDir: {x: -0.9755819, y: 0.15338214, z: 0.15720595}
|
||||
tipRadius: 0.7859197
|
||||
hiltRadius: 0.2289177
|
||||
sweepDeg: 308.74216
|
||||
stabAxis: {x: 0.9878676, y: -0.07309146, z: -0.13702233}
|
||||
stabStart: {x: -0.84236026, y: 0.7775105, z: 0.17080714}
|
||||
stabLength: 1.5588787
|
||||
quality: 6.4799576
|
||||
source: "runtime 02:40:00 samples=30/33(trim 0~29) path=8.43 \uCE7C\uB0A0\uD68C\uC804=604\xB0
|
||||
\uCE7C\uB05D/\uC190\uC7A1\uC774=3.36 sweep=308.7\xB0 straight=0.60 fwd=-0.14
|
||||
chord=1.56 pivot=\uCE7C\uB05D\uC6D0 tipR=0.786 hiltR=0.229 dev=0.091 fitQ=0.77
|
||||
q=6.48"
|
||||
- classId: 10501
|
||||
clipName: Effect_Slash_10501_1
|
||||
kind: 1
|
||||
planeNormal: {x: 0.09609319, y: -0.69287807, z: 0.7146231}
|
||||
pivot: {x: 0.013419926, y: 0.6920113, z: -0.017135125}
|
||||
bisector: {x: -0.46833384, y: 0.6020381, z: 0.64669436}
|
||||
startDir: {x: 0.7837881, y: 0.49521428, z: 0.374752}
|
||||
tipRadius: 0.8682612
|
||||
hiltRadius: 0.19870256
|
||||
sweepDeg: 160.0273
|
||||
stabAxis: {x: -0.7661477, y: -0.63733035, z: -0.0826303}
|
||||
stabStart: {x: 0.65847033, y: 1.292506, z: 0.12008436}
|
||||
stabLength: 1.8009284
|
||||
quality: 5.0141697
|
||||
source: "runtime 02:26:58 samples=28/28(trim 0~27) path=5.21 \uCE7C\uB0A0\uD68C\uC804=366\xB0
|
||||
\uCE7C\uB05D/\uC190\uC7A1\uC774=4.43 sweep=160.0\xB0 straight=0.36 fwd=-0.08
|
||||
chord=1.80 pivot=\uCE7C\uB05D\uC6D0 tipR=0.868 hiltR=0.199 dev=0.016 fitQ=0.96
|
||||
q=5.01"
|
||||
- classId: 10101
|
||||
clipName: Effect_Slash_10101_1
|
||||
kind: 1
|
||||
planeNormal: {x: 0.3078961, y: -0.636374, z: -0.70726806}
|
||||
pivot: {x: -0.056650292, y: 0.74904346, z: 0.17702837}
|
||||
bisector: {x: 0.897873, y: -0.05152121, z: 0.43722925}
|
||||
startDir: {x: -0.6402187, y: 0.41131842, z: -0.6487967}
|
||||
tipRadius: 1.0059098
|
||||
hiltRadius: 0.20204122
|
||||
sweepDeg: 303.2123
|
||||
stabAxis: {x: 0.7060405, y: -0.4063584, z: 0.5799824}
|
||||
stabStart: {x: -0.7590293, y: 1.3011718, z: -0.30031368}
|
||||
stabLength: 1.9881575
|
||||
quality: 5.966149
|
||||
source: "runtime 02:41:31 samples=28/28(trim 0~27) path=6.15 \uCE7C\uB0A0\uD68C\uC804=363\xB0
|
||||
\uCE7C\uB05D/\uC190\uC7A1\uC774=4.65 sweep=303.2\xB0 straight=0.65 fwd=0.58
|
||||
chord=1.99 pivot=\uCE7C\uB05D\uC6D0 tipR=1.006 hiltR=0.202 dev=0.015 fitQ=0.97
|
||||
q=5.97"
|
||||
planeNormal: {x: 0.6155671, y: -0.7459609, z: 0.2542036}
|
||||
pivot: {x: -0.44185022, y: 0.90176433, z: -0.14577419}
|
||||
bisector: {x: -0.18893999, y: -0.452843, z: -0.8713409}
|
||||
startDir: {x: 0.4323041, y: 0.5893181, z: 0.6825082}
|
||||
tipRadius: 0.71769434
|
||||
hiltRadius: 0.2310255
|
||||
sweepDeg: 398.79218
|
||||
stabAxis: {x: 0, y: 0, z: 1}
|
||||
stabStart: {x: -0.44185022, y: 0.90176433, z: -0.14577419}
|
||||
stabLength: 0.71769434
|
||||
quality: 50
|
||||
source: "wl816t 2026-09-15 09:35 Attack1_S_10101 f12~f35/50@60Hz n=24 PC=LH_M05
|
||||
rootScale=1.0527 weaponK=0.5369 path=6.88 bladeAng=544\xB0 sweep=398.8\xB0
|
||||
pivot=\uC190\uC7A1\uC774\uC911\uC2EC tipR=0.718 hiltR=0.231 dev=0.195 fitQ=0.46
|
||||
(\uB7F0\uD0C0\uC784 \uB85C\uCEEC=\uD68C\uC804\uB9CC)"
|
||||
- classId: 10101
|
||||
clipName: Effect_Slash_10101_2
|
||||
kind: 1
|
||||
planeNormal: {x: 0.09728308, y: 0.9890535, z: -0.11094675}
|
||||
pivot: {x: -0.071887866, y: 0.80780745, z: 0.034430865}
|
||||
bisector: {x: 0.9841305, y: -0.078973934, z: 0.15890326}
|
||||
startDir: {x: -0.76585925, y: 0.14558588, z: 0.6263101}
|
||||
tipRadius: 0.9324841
|
||||
hiltRadius: 0.2528293
|
||||
sweepDeg: 263.46906
|
||||
stabAxis: {x: 0.8400051, y: -0.09362712, z: -0.5344393}
|
||||
stabStart: {x: -0.7618986, y: 0.83268386, z: 0.60202444}
|
||||
stabLength: 1.7789476
|
||||
quality: 5.7660966
|
||||
source: "runtime 02:28:34 samples=29/31(trim 0~28) path=6.25 \uCE7C\uB0A0\uD68C\uC804=385\xB0
|
||||
\uCE7C\uB05D/\uC190\uC7A1\uC774=3.35 sweep=263.5\xB0 straight=0.65 fwd=-0.53
|
||||
chord=1.78 pivot=\uCE7C\uB05D\uC6D0 tipR=0.932 hiltR=0.253 dev=0.036 fitQ=0.92
|
||||
q=5.77"
|
||||
planeNormal: {x: 0.04436424, y: 0.9695876, z: 0.24068981}
|
||||
pivot: {x: -0.07215572, y: 0.45991144, z: -0.0608187}
|
||||
bisector: {x: -0.8473422, y: -0.09110173, z: 0.52317464}
|
||||
startDir: {x: -0.20181037, y: 0.24465796, z: -0.9483749}
|
||||
tipRadius: 0.65453726
|
||||
hiltRadius: 0.3102
|
||||
sweepDeg: 220.66309
|
||||
stabAxis: {x: 0, y: 0, z: 1}
|
||||
stabStart: {x: -0.07215572, y: 0.45991144, z: -0.0608187}
|
||||
stabLength: 0.65453726
|
||||
quality: 50
|
||||
source: "wl816t 2026-09-15 09:35 Attack2_S_10101 f14~f44/52@60Hz n=31 PC=LH_M05
|
||||
rootScale=1.0527 weaponK=0.5369 path=7.36 bladeAng=614\xB0 sweep=220.7\xB0
|
||||
pivot=\uCE7C\uB05D\uC6D0 tipR=0.655 hiltR=0.310 dev=0.089 fitQ=0.73 (\uB7F0\uD0C0\uC784
|
||||
\uB85C\uCEEC=\uD68C\uC804\uB9CC)"
|
||||
- classId: 10101
|
||||
clipName: Effect_Slash_10101_3
|
||||
kind: 1
|
||||
planeNormal: {x: 0.16853563, y: -0.9836209, z: -0.06391966}
|
||||
pivot: {x: 0.09357196, y: 1.2423787, z: -0.1380892}
|
||||
bisector: {x: 0.94817513, y: 0.14405777, z: 0.28321597}
|
||||
startDir: {x: 0.25327274, y: 0.10588382, z: -0.9615829}
|
||||
tipRadius: 0.95663345
|
||||
hiltRadius: 0.40691212
|
||||
sweepDeg: 181.94073
|
||||
stabAxis: {x: -0.12657256, y: -0.108728364, z: 0.9859805}
|
||||
stabStart: {x: 0.3463071, y: 1.37269, z: -1.1111009}
|
||||
stabLength: 2.0542197
|
||||
planeNormal: {x: -0.23372532, y: -0.96444863, z: -0.12333438}
|
||||
pivot: {x: -0.37444147, y: 0.6109033, z: 0.22184418}
|
||||
bisector: {x: 0.95191514, y: -0.20113623, z: -0.2310883}
|
||||
startDir: {x: 0.61234134, y: -0.04747615, z: -0.7891667}
|
||||
tipRadius: 0.71797794
|
||||
hiltRadius: 0.51229453
|
||||
sweepDeg: 78.42377
|
||||
stabAxis: {x: 0, y: 0, z: 1}
|
||||
stabStart: {x: -0.37444147, y: 0.6109033, z: 0.22184418}
|
||||
stabLength: 0.71797794
|
||||
quality: 50
|
||||
source: "editbake 2026-09-07 09:58 Attack3_S_10101 f7~f11@60Hz n=9 path=3.03
|
||||
bladeAng=154\xB0 sweep=181.9\xB0 pivot=\uCE7C\uB05D\uC6D0 tipR=0.957 hiltR=0.407
|
||||
dev=0.071 fitQ=0.85 q=2.58 (WL804_Bake \xB7 \uB7F0\uD0C0\uC784 \uC7AC\uC2E4\uCE21\uC774
|
||||
\uB36E\uC9C0 \uC54A\uB3C4\uB85D quality \uACE0\uC815)"
|
||||
source: "wl816t 2026-09-15 09:35 Attack3_S_10101 f16~f54/64@60Hz n=39 PC=LH_M05
|
||||
rootScale=1.0527 weaponK=0.5369 path=3.97 bladeAng=257\xB0 sweep=78.4\xB0 pivot=\uCE7C\uB05D\uC6D0
|
||||
tipR=0.718 hiltR=0.512 dev=0.120 fitQ=0.66 (\uB7F0\uD0C0\uC784 \uB85C\uCEEC=\uD68C\uC804\uB9CC)"
|
||||
- classId: 10102
|
||||
clipName: Effect_Slash_10102_1
|
||||
kind: 1
|
||||
planeNormal: {x: 0.6155671, y: -0.7459609, z: 0.2542036}
|
||||
pivot: {x: -0.44185022, y: 0.90176433, z: -0.14577419}
|
||||
bisector: {x: -0.18893999, y: -0.452843, z: -0.8713409}
|
||||
startDir: {x: 0.4323041, y: 0.5893181, z: 0.6825082}
|
||||
tipRadius: 0.71769434
|
||||
hiltRadius: 0.2310255
|
||||
sweepDeg: 398.79218
|
||||
stabAxis: {x: 0, y: 0, z: 1}
|
||||
stabStart: {x: -0.44185022, y: 0.90176433, z: -0.14577419}
|
||||
stabLength: 0.71769434
|
||||
quality: 50
|
||||
source: "wl816t 2026-09-15 09:35 Attack1_S_10102 f12~f35/50@60Hz n=24 PC=LH_M05
|
||||
rootScale=1.0527 weaponK=0.5369 path=6.88 bladeAng=544\xB0 sweep=398.8\xB0
|
||||
pivot=\uC190\uC7A1\uC774\uC911\uC2EC tipR=0.718 hiltR=0.231 dev=0.195 fitQ=0.46
|
||||
(\uB7F0\uD0C0\uC784 \uB85C\uCEEC=\uD68C\uC804\uB9CC)"
|
||||
- classId: 10102
|
||||
clipName: Effect_Slash_10102_2
|
||||
kind: 1
|
||||
planeNormal: {x: 0.04436424, y: 0.9695876, z: 0.24068981}
|
||||
pivot: {x: -0.07215572, y: 0.45991144, z: -0.0608187}
|
||||
bisector: {x: -0.8473422, y: -0.09110173, z: 0.52317464}
|
||||
startDir: {x: -0.20181037, y: 0.24465796, z: -0.9483749}
|
||||
tipRadius: 0.65453726
|
||||
hiltRadius: 0.3102
|
||||
sweepDeg: 220.66309
|
||||
stabAxis: {x: 0, y: 0, z: 1}
|
||||
stabStart: {x: -0.07215572, y: 0.45991144, z: -0.0608187}
|
||||
stabLength: 0.65453726
|
||||
quality: 50
|
||||
source: "wl816t 2026-09-15 09:35 Attack2_S_10102 f14~f44/52@60Hz n=31 PC=LH_M05
|
||||
rootScale=1.0527 weaponK=0.5369 path=7.36 bladeAng=614\xB0 sweep=220.7\xB0
|
||||
pivot=\uCE7C\uB05D\uC6D0 tipR=0.655 hiltR=0.310 dev=0.089 fitQ=0.73 (\uB7F0\uD0C0\uC784
|
||||
\uB85C\uCEEC=\uD68C\uC804\uB9CC)"
|
||||
- classId: 10102
|
||||
clipName: Effect_Slash_10102_3
|
||||
kind: 1
|
||||
planeNormal: {x: 0.16853563, y: -0.9836209, z: -0.06391966}
|
||||
pivot: {x: 0.09357196, y: 1.2423787, z: -0.1380892}
|
||||
bisector: {x: 0.94817513, y: 0.14405777, z: 0.28321597}
|
||||
startDir: {x: 0.25327274, y: 0.10588382, z: -0.9615829}
|
||||
tipRadius: 0.95663345
|
||||
hiltRadius: 0.40691212
|
||||
sweepDeg: 181.94073
|
||||
stabAxis: {x: -0.12657256, y: -0.108728364, z: 0.9859805}
|
||||
stabStart: {x: 0.3463071, y: 1.37269, z: -1.1111009}
|
||||
stabLength: 2.0542197
|
||||
planeNormal: {x: -0.23372532, y: -0.96444863, z: -0.12333438}
|
||||
pivot: {x: -0.37444147, y: 0.6109033, z: 0.22184418}
|
||||
bisector: {x: 0.95191514, y: -0.20113623, z: -0.2310883}
|
||||
startDir: {x: 0.61234134, y: -0.04747615, z: -0.7891667}
|
||||
tipRadius: 0.71797794
|
||||
hiltRadius: 0.51229453
|
||||
sweepDeg: 78.42377
|
||||
stabAxis: {x: 0, y: 0, z: 1}
|
||||
stabStart: {x: -0.37444147, y: 0.6109033, z: 0.22184418}
|
||||
stabLength: 0.71797794
|
||||
quality: 50
|
||||
source: "editbake 2026-09-07 09:58 Attack3_S_10102 f7~f11@60Hz n=9 path=3.03
|
||||
bladeAng=154\xB0 sweep=181.9\xB0 pivot=\uCE7C\uB05D\uC6D0 tipR=0.957 hiltR=0.407
|
||||
dev=0.071 fitQ=0.85 q=2.58 (WL804_Bake \xB7 \uB7F0\uD0C0\uC784 \uC7AC\uC2E4\uCE21\uC774
|
||||
\uB36E\uC9C0 \uC54A\uB3C4\uB85D quality \uACE0\uC815)"
|
||||
source: "wl816t 2026-09-15 09:35 Attack3_S_10102 f16~f54/64@60Hz n=39 PC=LH_M05
|
||||
rootScale=1.0527 weaponK=0.5369 path=3.97 bladeAng=257\xB0 sweep=78.4\xB0 pivot=\uCE7C\uB05D\uC6D0
|
||||
tipR=0.718 hiltR=0.512 dev=0.120 fitQ=0.66 (\uB7F0\uD0C0\uC784 \uB85C\uCEEC=\uD68C\uC804\uB9CC)"
|
||||
- classId: 10501
|
||||
clipName: Effect_Slash_10501_1
|
||||
kind: 1
|
||||
planeNormal: {x: 0.6043122, y: -0.7630855, z: 0.22914462}
|
||||
pivot: {x: -0.5143255, y: 0.99384046, z: -0.13518894}
|
||||
bisector: {x: -0.2910512, y: -0.47915196, z: -0.8280716}
|
||||
startDir: {x: 0.60951185, y: 0.6279901, z: 0.48386335}
|
||||
tipRadius: 0.7389534
|
||||
hiltRadius: 0.23210584
|
||||
sweepDeg: 416.96194
|
||||
stabAxis: {x: 0, y: 0, z: 1}
|
||||
stabStart: {x: -0.5143255, y: 0.99384046, z: -0.13518894}
|
||||
stabLength: 0.7389534
|
||||
quality: 50
|
||||
source: "wl816t 2026-09-15 09:35 Attack1_S_10501 f12~f35/50@60Hz n=24 PC=LH_M05
|
||||
rootScale=1.0527 weaponK=0.6587 path=7.35 bladeAng=545\xB0 sweep=417.0\xB0
|
||||
pivot=\uC190\uC7A1\uC774\uC911\uC2EC tipR=0.739 hiltR=0.232 dev=0.204 fitQ=0.45
|
||||
(\uB7F0\uD0C0\uC784 \uB85C\uCEEC=\uD68C\uC804\uB9CC)"
|
||||
- classId: 10501
|
||||
clipName: Effect_Slash_10501_2
|
||||
kind: 1
|
||||
planeNormal: {x: 0.04244417, y: 0.97287947, z: 0.2273852}
|
||||
pivot: {x: -0.077203944, y: 0.43669456, z: -0.052627534}
|
||||
bisector: {x: -0.81407905, y: -0.098262936, z: 0.5723808}
|
||||
startDir: {x: -0.2501254, y: 0.23068981, z: -0.9403295}
|
||||
tipRadius: 0.7294197
|
||||
hiltRadius: 0.2821212
|
||||
sweepDeg: 221.86562
|
||||
stabAxis: {x: 0, y: 0, z: 1}
|
||||
stabStart: {x: -0.077203944, y: 0.43669456, z: -0.052627534}
|
||||
stabLength: 0.7294197
|
||||
quality: 50
|
||||
source: "wl816t 2026-09-15 09:35 Attack2_S_10501 f14~f44/52@60Hz n=31 PC=LH_M05
|
||||
rootScale=1.0527 weaponK=0.6587 path=8.04 bladeAng=616\xB0 sweep=221.9\xB0
|
||||
pivot=\uCE7C\uB05D\uC6D0 tipR=0.729 hiltR=0.282 dev=0.083 fitQ=0.77 (\uB7F0\uD0C0\uC784
|
||||
\uB85C\uCEEC=\uD68C\uC804\uB9CC)"
|
||||
- classId: 10501
|
||||
clipName: Effect_Slash_10501_3
|
||||
kind: 1
|
||||
planeNormal: {x: 0.16179384, y: -0.98433506, z: -0.070051745}
|
||||
pivot: {x: 0.06956807, y: 1.2031016, z: -0.17662044}
|
||||
bisector: {x: 0.98678565, y: 0.16074902, z: 0.020341488}
|
||||
startDir: {x: 0.019124245, y: 0.074101284, z: -0.99706733}
|
||||
tipRadius: 0.797171
|
||||
hiltRadius: 0.35618255
|
||||
sweepDeg: 178.7966
|
||||
stabAxis: {x: 0.11699972, y: -0.072316095, z: 0.99049556}
|
||||
stabStart: {x: 0.08246852, y: 1.288136, z: -1.0311682}
|
||||
stabLength: 1.7564142
|
||||
planeNormal: {x: 0.043638147, y: -0.9978227, z: -0.049451575}
|
||||
pivot: {x: -0.32562953, y: 0.5273627, z: 0.22276048}
|
||||
bisector: {x: 0.96429247, y: 0.05501082, z: -0.25906354}
|
||||
startDir: {x: 0.53950334, y: 0.06519729, z: -0.8394555}
|
||||
tipRadius: 0.80060536
|
||||
hiltRadius: 0.42106363
|
||||
sweepDeg: 84.31582
|
||||
stabAxis: {x: 0, y: 0, z: 1}
|
||||
stabStart: {x: -0.32562953, y: 0.5273627, z: 0.22276048}
|
||||
stabLength: 0.80060536
|
||||
quality: 50
|
||||
source: "editbake 2026-09-07 09:59 Attack3_S_10501 f7~f11@60Hz n=9 path=2.56
|
||||
bladeAng=153\xB0 sweep=178.8\xB0 pivot=\uCE7C\uB05D\uC6D0 tipR=0.797 hiltR=0.356
|
||||
dev=0.082 fitQ=0.79 q=2.03 (WL804_Bake \xB7 \uB7F0\uD0C0\uC784 \uC7AC\uC2E4\uCE21\uC774
|
||||
\uB36E\uC9C0 \uC54A\uB3C4\uB85D quality \uACE0\uC815)"
|
||||
source: "wl816t 2026-09-15 09:35 Attack3_S_10501 f16~f54/64@60Hz n=39 PC=LH_M05
|
||||
rootScale=1.0527 weaponK=0.6587 path=4.20 bladeAng=254\xB0 sweep=84.3\xB0 pivot=\uCE7C\uB05D\uC6D0
|
||||
tipR=0.801 hiltR=0.421 dev=0.120 fitQ=0.70 (\uB7F0\uD0C0\uC784 \uB85C\uCEEC=\uD68C\uC804\uB9CC)"
|
||||
- classId: 10502
|
||||
clipName: Effect_Slash_10502_1
|
||||
kind: 1
|
||||
planeNormal: {x: 0.6255864, y: -0.7492798, z: 0.21730489}
|
||||
pivot: {x: -0.4383909, y: 0.96184254, z: -0.13046789}
|
||||
bisector: {x: 0.32277644, y: 0.5021659, z: 0.80227476}
|
||||
startDir: {x: 0.6897078, y: 0.6613513, z: 0.29481786}
|
||||
tipRadius: 0.6846314
|
||||
hiltRadius: 0.21322028
|
||||
sweepDeg: 75.39421
|
||||
stabAxis: {x: 0, y: 0, z: 1}
|
||||
stabStart: {x: -0.4383909, y: 0.96184254, z: -0.13046789}
|
||||
stabLength: 0.6846314
|
||||
quality: 50
|
||||
source: "wl816t 2026-09-15 09:35 Attack1_S_10502 f12~f35/50@60Hz n=24 PC=LH_M05
|
||||
rootScale=1.0527 weaponK=0.5632 path=6.42 bladeAng=545\xB0 sweep=75.4\xB0 pivot=\uC190\uC7A1\uC774\uC911\uC2EC
|
||||
tipR=0.685 hiltR=0.213 dev=0.167 fitQ=0.51 (\uB7F0\uD0C0\uC784 \uB85C\uCEEC=\uD68C\uC804\uB9CC)"
|
||||
- classId: 10502
|
||||
clipName: Effect_Slash_10502_2
|
||||
kind: 1
|
||||
planeNormal: {x: 0.047004227, y: 0.97822416, z: 0.20215859}
|
||||
pivot: {x: -0.07373327, y: 0.44671315, z: -0.044609603}
|
||||
bisector: {x: -0.7875351, y: -0.08820486, z: 0.609925}
|
||||
startDir: {x: -0.28951094, y: 0.20703694, z: -0.9345154}
|
||||
tipRadius: 0.6426512
|
||||
hiltRadius: 0.30169082
|
||||
sweepDeg: 222.2306
|
||||
stabAxis: {x: 0, y: 0, z: 1}
|
||||
stabStart: {x: -0.07373327, y: 0.44671315, z: -0.044609603}
|
||||
stabLength: 0.6426512
|
||||
quality: 50
|
||||
source: "wl816t 2026-09-15 09:35 Attack2_S_10502 f14~f44/52@60Hz n=31 PC=LH_M05
|
||||
rootScale=1.0527 weaponK=0.5632 path=7.04 bladeAng=616\xB0 sweep=222.2\xB0
|
||||
pivot=\uCE7C\uB05D\uC6D0 tipR=0.643 hiltR=0.302 dev=0.076 fitQ=0.76 (\uB7F0\uD0C0\uC784
|
||||
\uB85C\uCEEC=\uD68C\uC804\uB9CC)"
|
||||
- classId: 10502
|
||||
clipName: Effect_Slash_10502_3
|
||||
kind: 1
|
||||
planeNormal: {x: 0.16322699, y: -0.9838918, z: -0.07289651}
|
||||
pivot: {x: 0.06879786, y: 1.1890548, z: -0.17932634}
|
||||
bisector: {x: 0.9864896, y: 0.16381113, z: -0.0020673866}
|
||||
startDir: {x: -0.012327602, y: 0.0718477, z: -0.9973394}
|
||||
tipRadius: 0.74294686
|
||||
hiltRadius: 0.5402583
|
||||
sweepDeg: 179.8086
|
||||
stabAxis: {x: 0.14303008, y: -0.07050567, z: 0.98720384}
|
||||
stabStart: {x: 0.055376478, y: 1.2679739, z: -0.98118037}
|
||||
stabLength: 1.6514131
|
||||
planeNormal: {x: 0.035052184, y: -0.99825996, z: -0.047418203}
|
||||
pivot: {x: -0.28646088, y: 0.51465774, z: 0.23871267}
|
||||
bisector: {x: 0.9424084, y: 0.04880832, z: -0.330884}
|
||||
startDir: {x: 0.4772259, y: 0.058407497, z: -0.8768375}
|
||||
tipRadius: 0.70055455
|
||||
hiltRadius: 0.39948177
|
||||
sweepDeg: 84.072044
|
||||
stabAxis: {x: 0, y: 0, z: 1}
|
||||
stabStart: {x: -0.28646088, y: 0.51465774, z: 0.23871267}
|
||||
stabLength: 0.70055455
|
||||
quality: 50
|
||||
source: "editbake 2026-09-07 09:59 Attack3_S_10502 f7~f11@60Hz n=9 path=2.41
|
||||
bladeAng=153\xB0 sweep=179.8\xB0 pivot=\uCE7C\uB05D\uC6D0 tipR=0.743 hiltR=0.540
|
||||
dev=0.083 fitQ=0.78 q=1.87 (WL804_Bake \xB7 \uB7F0\uD0C0\uC784 \uC7AC\uC2E4\uCE21\uC774
|
||||
\uB36E\uC9C0 \uC54A\uB3C4\uB85D quality \uACE0\uC815)"
|
||||
source: "wl816t 2026-09-15 09:35 Attack3_S_10502 f16~f54/64@60Hz n=39 PC=LH_M05
|
||||
rootScale=1.0527 weaponK=0.5632 path=3.83 bladeAng=254\xB0 sweep=84.1\xB0 pivot=\uCE7C\uB05D\uC6D0
|
||||
tipR=0.701 hiltR=0.399 dev=0.110 fitQ=0.69 (\uB7F0\uD0C0\uC784 \uB85C\uCEEC=\uD68C\uC804\uB9CC)"
|
||||
swingMinSweepDegrees: 150
|
||||
swingMinTipHiltRatio: 3
|
||||
stabMinStraightness: 0.86
|
||||
|
|
@ -559,6 +626,8 @@ MonoBehaviour:
|
|||
swingTrimSpeedRatio: 0.2
|
||||
arcRadiusFit: 0
|
||||
arcSizeScale: 1
|
||||
arcFitAttackRange: 1
|
||||
arcRangeScale: 1
|
||||
arcPlaneOffset: 0
|
||||
arcRadialOffset: 0
|
||||
arcLifetimeSeconds: 0
|
||||
|
|
|
|||
Loading…
Reference in New Issue