Merge branch 'wl/gameplay/WL-816za-dirt-round'
This commit is contained in:
commit
923881cff7
|
|
@ -109,6 +109,10 @@ MonoBehaviour:
|
|||
edgeInset: 0.15
|
||||
roadMargin: 0.15
|
||||
farmMargin: 0.35
|
||||
farmEdgeRoundEnabled: 1
|
||||
farmEdgeRadius: 1
|
||||
farmEdgeNoise: 0.4
|
||||
farmEdgeNoiseCell: 0.5
|
||||
propMargin: 0.05
|
||||
propMaxSize: 7.5
|
||||
maxInstances: 40000
|
||||
|
|
|
|||
|
|
@ -54,6 +54,8 @@ namespace WL.Look.Farm
|
|||
|
||||
Bounds _bounds = new Bounds(Vector3.zero, Vector3.one * 16f);
|
||||
readonly List<Rect> _blockers = new List<Rect>(128);
|
||||
// 816za — 밭 자리만 따로. 반듯한 사각형이 아니라 「모서리 둥글게 + 경계 노이즈」로 판정한다.
|
||||
readonly List<Rect> _farmRounds = new List<Rect>(8);
|
||||
|
||||
// ── 816o 캐시 — 한 번 뽑은 후보를 들고 있다가, 구름이 흐르면 「고르기」만 다시 한다 ──
|
||||
struct Cand { public float x, z, y; public int def; public float sc; public float yaw; }
|
||||
|
|
@ -570,6 +572,8 @@ namespace WL.Look.Farm
|
|||
void BuildBlockers(List<TileRef> tiles)
|
||||
{
|
||||
_blockers.Clear();
|
||||
_farmRounds.Clear();
|
||||
bool round = cfg.farmEdgeRoundEnabled != 0 && cfg.farmEdgeRadius > 0f;
|
||||
var scene = tiles.Count > 0 ? tiles[0].tf.gameObject.scene : default(UnityEngine.SceneManagement.Scene);
|
||||
|
||||
// ① 농사 — Farm 이 Awake 에서 만드는 BoxCollider(size = (length,2,width))가 밭의 정확한 넓이다.
|
||||
|
|
@ -579,17 +583,21 @@ namespace WL.Look.Farm
|
|||
var f = farms[i];
|
||||
if (f == null || f.gameObject.scene != scene) continue;
|
||||
var bc = f.GetComponent<BoxCollider>();
|
||||
if (bc != null) AddBox(f.transform, bc.center, bc.size, cfg.farmMargin);
|
||||
else AddRect(f.transform.position.x, f.transform.position.z, 6f, 5f, cfg.farmMargin);
|
||||
Rect r = bc != null
|
||||
? BoxRect(f.transform, bc.center, bc.size, cfg.farmMargin)
|
||||
: MakeRect(f.transform.position.x, f.transform.position.z, 6f, 5f, cfg.farmMargin);
|
||||
if (round) _farmRounds.Add(r); else _blockers.Add(r);
|
||||
}
|
||||
|
||||
// ② 농사 타일 하나하나(1×1) — Farm 이 런타임에 만든다. 이중 안전.
|
||||
// 라운드 모드에서는 ① 안에 든 타일을 빼야 한다. 안 그러면 반듯한 1×1 사각형들이 깎아낸 모서리를 도로 메운다.
|
||||
var soils = Object.FindObjectsByType<FISoil>(FindObjectsInactive.Include, FindObjectsSortMode.None);
|
||||
for (int i = 0; i < soils.Length; i++)
|
||||
{
|
||||
var s = soils[i];
|
||||
if (s == null || s.gameObject.scene != scene) continue;
|
||||
var p = s.transform.position;
|
||||
if (round && InAnyFarmRect(p.x, p.z)) continue;
|
||||
AddRect(p.x, p.z, 1f, 1f, cfg.farmMargin);
|
||||
}
|
||||
|
||||
|
|
@ -626,10 +634,47 @@ namespace WL.Look.Farm
|
|||
var r = _blockers[i];
|
||||
if (x >= r.xMin && x <= r.xMax && z >= r.yMin && z <= r.yMax) return true;
|
||||
}
|
||||
for (int i = 0; i < _farmRounds.Count; i++)
|
||||
if (InRoundedFarm(_farmRounds[i], x, z)) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void AddBox(Transform tf, Vector3 center, Vector3 size, float margin)
|
||||
// 밭 사각형 안인가 — 타일을 어느 밭에 딸린 것으로 볼지 가르는 데만 쓴다(모서리·노이즈 무시).
|
||||
bool InAnyFarmRect(float x, float z)
|
||||
{
|
||||
for (int i = 0; i < _farmRounds.Count; i++)
|
||||
{
|
||||
var r = _farmRounds[i];
|
||||
if (x >= r.xMin && x <= r.xMax && z >= r.yMin && z <= r.yMax) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// 816za — 밭 자리 판정. 네 모서리를 반지름만큼 깎고, 경계 전체를 노이즈로 흔든다.
|
||||
// 노이즈가 (−) 면 흙이 물러나 풀이 파고들고, (+) 면 흙이 조금 넓어진다. 평균 0 이라 총량은 그대로다.
|
||||
bool InRoundedFarm(Rect r, float x, float z)
|
||||
{
|
||||
float hx = r.width * 0.5f, hz = r.height * 0.5f;
|
||||
float cx = r.xMin + hx, cz = r.yMin + hz;
|
||||
|
||||
if (cfg.farmEdgeNoise > 0f && cfg.farmEdgeNoiseCell > 0.0001f)
|
||||
{
|
||||
float n = (CellNoise(x / cfg.farmEdgeNoiseCell, z / cfg.farmEdgeNoiseCell) * 2f - 1f) * cfg.farmEdgeNoise;
|
||||
hx += n; hz += n;
|
||||
}
|
||||
if (hx <= 0f || hz <= 0f) return false;
|
||||
|
||||
float dx = Mathf.Abs(x - cx), dz = Mathf.Abs(z - cz);
|
||||
if (dx > hx || dz > hz) return false;
|
||||
|
||||
float rad = Mathf.Min(cfg.farmEdgeRadius, Mathf.Min(hx, hz));
|
||||
if (rad <= 0f) return true;
|
||||
float ox = dx - (hx - rad), oz = dz - (hz - rad);
|
||||
if (ox <= 0f || oz <= 0f) return true; // 모서리 원호 밖 = 십자 몸통 = 안쪽
|
||||
return ox * ox + oz * oz <= rad * rad;
|
||||
}
|
||||
|
||||
static Rect BoxRect(Transform tf, Vector3 center, Vector3 size, float margin)
|
||||
{
|
||||
// 콜라이더가 disabled 여도 안전하게 — bounds 대신 직접 계산한다.
|
||||
var c = tf.TransformPoint(center);
|
||||
|
|
@ -637,12 +682,17 @@ namespace WL.Look.Farm
|
|||
var ez = tf.TransformVector(new Vector3(0f, 0f, size.z * 0.5f));
|
||||
float hx = Mathf.Abs(ex.x) + Mathf.Abs(ez.x);
|
||||
float hz = Mathf.Abs(ex.z) + Mathf.Abs(ez.z);
|
||||
AddRect(c.x, c.z, hx * 2f, hz * 2f, margin);
|
||||
return MakeRect(c.x, c.z, hx * 2f, hz * 2f, margin);
|
||||
}
|
||||
|
||||
static Rect MakeRect(float cx, float cz, float w, float h, float margin)
|
||||
{
|
||||
return new Rect(cx - w * 0.5f - margin, cz - h * 0.5f - margin, w + margin * 2f, h + margin * 2f);
|
||||
}
|
||||
|
||||
void AddRect(float cx, float cz, float w, float h, float margin)
|
||||
{
|
||||
_blockers.Add(new Rect(cx - w * 0.5f - margin, cz - h * 0.5f - margin, w + margin * 2f, h + margin * 2f));
|
||||
_blockers.Add(MakeRect(cx, cz, w, h, margin));
|
||||
}
|
||||
|
||||
static Rect Inflate(Rect r, float m)
|
||||
|
|
@ -700,5 +750,23 @@ namespace WL.Look.Farm
|
|||
uint v = Hash(h + (uint)(k * 0x9E3779B9U));
|
||||
return (v & 0xFFFFFF) / 16777215f;
|
||||
}
|
||||
|
||||
// 816za — 셀 격자 값 노이즈 [0,1]. 셀 네 귀퉁이 난수를 부드럽게 섞어 경계를 들쭉날쭉하게 만든다.
|
||||
static float CellNoise(float fx, float fz)
|
||||
{
|
||||
int x0 = Mathf.FloorToInt(fx), z0 = Mathf.FloorToInt(fz);
|
||||
float tx = fx - x0, tz = fz - z0;
|
||||
tx = tx * tx * (3f - 2f * tx);
|
||||
tz = tz * tz * (3f - 2f * tz);
|
||||
float a = CellRand(x0, z0), b = CellRand(x0 + 1, z0);
|
||||
float c = CellRand(x0, z0 + 1), d = CellRand(x0 + 1, z0 + 1);
|
||||
return Mathf.Lerp(Mathf.Lerp(a, b, tx), Mathf.Lerp(c, d, tx), tz);
|
||||
}
|
||||
|
||||
static float CellRand(int x, int z)
|
||||
{
|
||||
uint h = Hash(unchecked((uint)x * 73856093U) ^ unchecked((uint)z * 19349663U) ^ 0x9E3779B9U);
|
||||
return (h & 0xFFFFFF) / 16777215f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -263,6 +263,19 @@ namespace WL.Look.Farm
|
|||
[Tooltip("농사 타일(Farm 트리거 · Soil 1×1)에서 이만큼(m) 떨어뜨린다.")]
|
||||
public float farmMargin = 0.35f;
|
||||
|
||||
[Tooltip("1 이면 밭 자리 제외 사각형의 네 모서리를 깎고 경계를 노이즈로 흔들어 " +
|
||||
"풀이 흙 가장자리로 파고들게 한다. 0 이면 예전처럼 반듯한 사각형.")]
|
||||
public int farmEdgeRoundEnabled = 1;
|
||||
|
||||
[Tooltip("밭 자리 모서리를 깎는 반지름(m). 클수록 둥글게 읽힌다.")]
|
||||
public float farmEdgeRadius = 1.0f;
|
||||
|
||||
[Tooltip("밭 자리 경계를 흔드는 진폭(m). 이만큼 풀이 파고들거나 물러난다.")]
|
||||
public float farmEdgeNoise = 0.4f;
|
||||
|
||||
[Tooltip("경계 노이즈의 셀 크기(m). 작을수록 잘게 들쭉날쭉해진다.")]
|
||||
public float farmEdgeNoiseCell = 0.5f;
|
||||
|
||||
[Tooltip("건물·소품 콜라이더에서 이만큼(m) 떨어뜨린다.")]
|
||||
public float propMargin = 0.05f;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue