Files
Cielonos/Assets/Opsive/BehaviorDesigner/Add-Ons/CielonosPack/Conditionals/IsCenterVisibleOnScreen.cs
SoulliesOfficial 39b43680a9 爆更
2026-07-18 03:16:20 -04:00

78 lines
2.9 KiB
C#

using Opsive.BehaviorDesigner.Runtime.Tasks;
using Opsive.Shared.Utility;
using UnityEngine;
namespace Cielonos.MainGame.Characters.AI
{
[Description("Checks whether this enemy's center point is visible inside the player's screen viewport.")]
[Category("Cielonos")]
public class IsCenterVisibleOnScreen : AutomataConditionalBase
{
[Tooltip("Use MainGameManager.Player.viewSc.playerCamera. If disabled, Camera Override is used first, then Camera.main.")]
public bool usePlayerCamera = true;
[Tooltip("Optional camera override for tests or special behavior trees.")]
public Camera cameraOverride;
[Tooltip("Viewport margin. X/Y are normalized 0-0.5 values. A small margin avoids attacks starting at the exact screen edge.")]
public Vector2 viewportPadding = new(0.03f, 0.04f);
[Tooltip("Extra world-space offset added to the enemy center point before testing visibility.")]
public Vector3 worldOffset = Vector3.zero;
[Tooltip("Return Success when visible if true, or when not visible if false.")]
public bool expectedVisible = true;
public override TaskStatus OnUpdate()
{
Camera camera = GetCamera();
if (self == null || camera == null)
{
return expectedVisible ? TaskStatus.Failure : TaskStatus.Success;
}
Vector3 viewportPoint = camera.WorldToViewportPoint(GetCenterPosition());
bool isVisible = viewportPoint.z > camera.nearClipPlane &&
viewportPoint.x >= viewportPadding.x &&
viewportPoint.x <= 1f - viewportPadding.x &&
viewportPoint.y >= viewportPadding.y &&
viewportPoint.y <= 1f - viewportPadding.y;
return isVisible == expectedVisible ? TaskStatus.Success : TaskStatus.Failure;
}
public override void Reset()
{
base.Reset();
usePlayerCamera = true;
cameraOverride = null;
viewportPadding = new Vector2(0.03f, 0.04f);
worldOffset = Vector3.zero;
expectedVisible = true;
}
private Camera GetCamera()
{
if (usePlayerCamera &&
MainGameManager.Player != null &&
MainGameManager.Player.viewSc != null &&
MainGameManager.Player.viewSc.playerCamera != null)
{
return MainGameManager.Player.viewSc.playerCamera;
}
return cameraOverride != null ? cameraOverride : Camera.main;
}
private Vector3 GetCenterPosition()
{
if (self.bodyPartsSc != null && self.bodyPartsSc.flexibleCenterPoint != null)
{
return self.bodyPartsSc.flexibleCenterPoint.position + worldOffset;
}
return transform.position + worldOffset;
}
}
}