Created
July 19, 2017 21:12
-
-
Save onionmk2/82094e3c6cc2fc2e13af05368ca49810 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public override TaskStatus OnUpdate() | |
{ | |
var playerTransform = GetComponent<EnemyStore>().playerTransform; | |
var distanceFromPlayer = Vector3.Distance(playerTransform.position, transform.position); | |
// slow down until speed becomes zero. | |
if (distanceFromPlayer <= GlobalConst.maxRangeOfPlayerNear) | |
{ | |
GetComponent<Animator>().applyRootMotion = false; | |
//減速を始めた場合、以降プレイヤーが移動したとしても、agentの目的地を更新しない(パス検索は重いので1回で済ませたいため。)。 | |
if (!slowDownSetupFinished) | |
{ | |
// 初速 | |
var initialSpeed = navMeshAgent.velocity.magnitude; | |
// 終末速度 | |
var endSpeed = 0f; | |
// 変位(減速を開始する地点から静止する地点の間の距離) | |
var deltaOfDistance = GlobalConst.maxRangeOfPlayerNear - GlobalConst.maxRangeOfPlayerAround; | |
acceleration = (Mathf.Pow(endSpeed, 2) - Mathf.Pow(initialSpeed, 2)) / (2 * deltaOfDistance); | |
slowDownStartTime = Time.time; | |
slowDownStartSpeed = initialSpeed; | |
SetDestinationAtPlayerAround(); | |
slowDownSetupFinished = true; | |
} | |
// 等加速度運動の公式を用いて、「初速, 終末速, 変位」の3つから加速度を求める。 | |
// 「初速、求めた加速度、経過時刻」から、現在の速さを求める。 | |
var currentTime = Time.time - slowDownStartTime; | |
navMeshAgent.speed = slowDownStartSpeed + acceleration * currentTime; | |
if (navMeshAgent.speed < Mathf.Epsilon) | |
{ | |
navMeshAgent.isStopped = true; | |
} | |
return TaskStatus.Running; | |
} | |
// Run | |
else | |
{ | |
GetComponent<Animator>().applyRootMotion = false; | |
slowDownSetupFinished = false; | |
navMeshAgent.speed = GlobalConst.maxEnemyRunVelocity; | |
navMeshAgent.SetDestination(playerTransform.position); | |
navMeshAgent.isStopped = false; | |
return TaskStatus.Running; | |
} | |
} | |
///<summary>以下の条件を満たす点に<see cref="NavMeshAgent.SetDestination"/>する。 | |
/// 1. NavMeshPath上にある。 | |
/// 2. <see cref="GlobalConst.maxRangeOfPlayerAround"/>地点に最も近い。 | |
/// </summary> | |
/// <remarks> | |
/// 「Destinationはプレイヤー位置にして、距離が<see cref="GlobalConst.maxRangeOfPlayerAround"/> | |
/// 以下の場合<see cref="NavMeshAgent.isStopped"/>で止める」 という実装では、滑りが発生する。 | |
/// </remarks> | |
private void SetDestinationAtPlayerAround() | |
{ | |
var playerPosition = GetComponent<EnemyStore>().playerTransform.position; | |
NavMeshPath path = new NavMeshPath(); | |
var hasPath = navMeshAgent.CalculatePath(playerPosition, path); | |
if(!hasPath) Debug.Log("敵も自機もnavMesh上にしか居れないので、ここにはこないはず"); | |
var distancesBetweenCornerPointAndAroundPoint = path.corners | |
.Select((corner) => Vector3.Distance(corner, playerPosition)) | |
.Select(distance => Mathf.Abs(distance - GlobalConst.maxRangeOfPlayerAround)) | |
.ToArray(); | |
var minDistIndex = Array.IndexOf(distancesBetweenCornerPointAndAroundPoint, distancesBetweenCornerPointAndAroundPoint.Min()); | |
var closestCornerFromAroundPoint = path.corners[minDistIndex]; | |
navMeshAgent.SetDestination(closestCornerFromAroundPoint); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment