在 Collider 上隨機找一個著彈點.

在 Collider 上隨機找一個著彈點.

為了不浪費 NPC 射的子彈, 又不希望玩家身中多槍, 我們很多時候會在玩家週遭找一些障礙物來給 NPC 射擊.

一方面給玩家給成緊張感, 另一方面著彈點也可以合理的播放particle 效果.
提升找入感.

那麼如何標示這些著彈點就要花點心思了.

 

private bool GetInterestShootablePoint(Vector3 playerHeadPos, Vector3 firedPoint, out Vector3 point)
	{
		int hitted = aroundPlayerHead.OverlapNonAlloc(playerHeadPos, _attractFieldArea, ref markedObjs, _bulletAttractLayer, QueryTriggerInteraction.Ignore);

		if (_debugDeviation)
			DebugExtend.DrawCircle(playerHeadPos, Vector3.up, s_AimTarget, _attractFieldArea, s_DebugShootingLine, true);

		if (hitted == 0)
		{
			point = default;
			 // can't find anything interest shoot point in range.
			return false;
		}
		else
		{
			int rnd = UnityEngine.Random.Range(0, hitted);
			Collider selected = markedObjs[rnd];
			Quaternion quat = Quaternion.LookRotation(playerHeadPos - firedPoint);
			Vector3 boxCenter = selected.bounds.center;
			Vector3 factor = selected.bounds.extents;
			float hFactor = Mathf.Max(factor.x, factor.z);
			float vFactor = factor.y;
			float rndHor = UnityEngine.Random.Range(-hFactor, hFactor);
			float rndVert = UnityEngine.Random.Range(-vFactor, vFactor);
			Matrix4x4 matrix = Matrix4x4.TRS(boxCenter, quat, Vector3.one);
			point = matrix.MultiplyPoint(MemoryManager.V3(rndHor, rndVert, 0f));
			if (_debugDeviation)
			{
				DebugExtend.DrawPoint(matrix.MultiplyPoint(MemoryManager.V3(0f, vFactor,0f)), s_ColorSizeDetection, 0.2f, s_DebugShootingLine);
				DebugExtend.DrawPoint(matrix.MultiplyPoint(MemoryManager.V3(0f,-vFactor, 0f)), s_ColorSizeDetection, 0.2f, s_DebugShootingLine);
				DebugExtend.DrawPoint(matrix.MultiplyPoint(MemoryManager.V3(hFactor, 0f, 0f)), s_ColorSizeDetection, 0.2f, s_DebugShootingLine);
				DebugExtend.DrawPoint(matrix.MultiplyPoint(MemoryManager.V3(-hFactor, 0f, 0f)), s_ColorSizeDetection, 0.2f, s_DebugShootingLine);
			}

			point = selected.ClosestPoint(point);
			if (_debugDeviation)
			{
				Debug.DrawLine(firedPoint, playerHeadPos, s_AimTarget, s_DebugShootingLine, true); // Org path.
				Debug.DrawLine(firedPoint, point, s_ColorSafeAttack, s_DebugShootingLine, true); // final selection.
			}
			return true;
		}
	}

功能很簡單, 

提供 playerHeadPos 玩家的頭部位置, 以其圓週範圍取得附近可用的障礙物,
在 NPC 需要 “射不中” 玩家時即以週遭的 Collider 為目標發射.

 

Enemies shoot near by player

取得 Collider 後才是有趣的地方, 總不成永遠打 Collider 中某一個位置, 所以我們要做點隨機, 這要求到計算 Collider 中可用的體積.

取得 `Collider.Bound` 為參考, 這東西只是顯示層面上的 bound box, 不是這東西 (Mesh) 的實際體積,
取得 bound 後 center + extents 就能夠知道這東西的三維體積了.

就可以用 X, Y 來決定射擊這個 Mesh 中有效的範圍.
決定好位置後, 因為我們是用投映來運算這隨機點,

把這個 bound box 以 NPC 面向 Player 的vector角度為軸, 投影成平面.
把這個 bound box 轉換為 Matrix 後就可以用 multilypoint() 來換算 world position.

最後就只是把子彈依著新的著彈點角度發射即可.

The blue circle showing that slice plane based on NPC perspective

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

*

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料