negitamago
12/21/2018 - 11:26 AM

TargetSearch

Behavior Designer の Conditonal タスク。視界の角度・距離内にターゲットがいるかをチェックし、TaskStatus.Sucess または Failure を返す

using UnityEngine;
using BehaviorDesigner.Runtime;
using BehaviorDesigner.Runtime.Tasks;

/// <summary>
/// MyTargetSearch
/// Behavior Designer の Conditonal タスク
/// 視界の角度・距離内にターゲットがいるかをチェックし、TaskStatus.Sucess または Failure を返す
/// </summary>
[TaskCategory ( "MyConditionals" )]  // Add Task > Conditonals > MyConditonals の中に MyTargetSearch が入る
public class TargetSearch : Conditional
{
    [SerializeField] float sightDistance;
    [SerializeField] float sightAngle;

    [SerializeField] Transform target;


    public override TaskStatus OnUpdate ()
    {
        if ( Search () == true ) return TaskStatus.Success;

        return TaskStatus.Failure;
    }

    /// <summary>
    /// 視界の角度・距離内にターゲットがいるか
    /// </summary>
    /// <returns>true:いる false:いない</returns>
    private bool Search ()
    {
        if ( CheckAngle () == false ) return false;
        if ( CheckDistance () == false ) return false;

        return true;
    }

    /// <summary>
    /// 対象が視界の角度内にいるか
    /// </summary>
    /// <returns>true:いる false:いない</returns>
    private bool CheckAngle ()
    {
        // 対象との角度
        var angle = Vector3.Angle (target.position - this.transform.position, this.transform.forward);
        // Debug.Log ( "angle: " + angle );

        return angle < sightAngle;
    }

    /// <summary>
    /// 対象が視界の距離内にいるか(XZ平面上で距離を比較する)
    /// </summary>
    /// <returns>true:いる false:いない</returns>
    private bool CheckDistance ()
    {
        var targetPosOnGround = new Vector2(target.position.x, target.position.z);
        var myPosOnGround = new Vector2(this.transform.position.x, this.transform.position.z);
        var distance = Vector2.Distance(targetPosOnGround, myPosOnGround);

        return distance < sightDistance;
    }
}