[英]transform.LookAt() issue
I am trying to make an AI that will follow the closest object, but the problem is that when the object gets close it will rotate vertically, which I think is because the transform.LookAt() rotates towards the center of the object.我正在尝试制作一个跟随最近的 object 的 AI,但问题是当 object 靠近时,它会垂直旋转,我认为这是因为 transform.LookAt() 向 ZA8CFDE6331BD59EB66AC96F8911 的中心旋转。 Is there a way to look at an object without rotating vertically?
有没有办法在不垂直旋转的情况下查看 object? Here's the code for the AI
这是AI的代码
using System.Collections.Generic;
using UnityEngine;
public class AI : MonoBehaviour
{
[SerializeField] public float speed = 2f;
public float SphereRadius;
public LayerMask mask;
private void FixedUpdate()
{
//Checks if theres any objects nearbye
Collider[] hitColliders = Physics.OverlapSphere(transform.position, SphereRadius, mask, QueryTriggerInteraction.UseGlobal);
//Gets all the transforms of the objects and stores them into an array
List<Transform> Transforms = new List<Transform>();
foreach (var hitCollider in hitColliders)
{
Transforms.Add(hitCollider.transform);
}
//Checks what's the closest object and rotates the AI towards that object
transform.LookAt(
GetClosestEnemy(
Transforms.ToArray()
)
);
transform.Translate(Vector3.forward * speed * Time.deltaTime);
}
Transform GetClosestEnemy(Transform[] enemies)
{
Transform tMin = null;
float minDist = Mathf.Infinity;
Vector3 currentPos = transform.position;
foreach (Transform t in enemies)
{
float dist = Vector3.Distance(t.position, currentPos);
if (dist < minDist)
{
tMin = t;
minDist = dist;
}
}
return tMin;
}
}
Instead of directly using the Transform
overload use the one taking a Vector3
target position you can completely customize like eg而不是直接使用
Transform
重载,而是使用采用Vector3
目标 position 您可以完全自定义,例如
var target = GetClosestEnemy(Transforms.ToArray());
var localDelta = transform.InverseTransformPoint(target.position);
// Now you can reset any of the axis you do not want to be taken into account e.g.
localDelta.z = 0;
transform.LookAt(transform.TransformPoint(localDelta));
Btw as a little tip magnitude
(which is internally used by Vector3.Distance
) is significantly slower than the sqrMagnitude
as the latter skips taking the square root.顺便说一句,作为一个小尖端
magnitude
(由Vector3.Distance
内部使用)比sqrMagnitude
慢得多,因为后者跳过了平方根。
For comparison both work the same so you can use为了比较两者的工作方式相同,因此您可以使用
Transform GetClosestEnemy(IEnumerable<Transform> enemies)
{
Transform tMin = null;
float minDist = Mathf.Infinity;
Vector3 currentPos = transform.position;
foreach (Transform t in enemies)
{
float dist = (t.position - currentPos).sqrMagnitude;
if (dist < minDist)
{
tMin = t;
minDist = dist;
}
}
return tMin;
}
or if you re a fan of Linq you could also do或者如果你是 Linq 的粉丝,你也可以这样做
Transform GetClosestEnemy(IEnumerable<Transform> enemies)
{
Vector3 currentPos = transform.position;
return enemies.OrderBy(enemy => (enemy.position - currentPos).sqrMagnitude).FirstOrDefault();
}
Then you could also shrink down the rest and do然后你也可以缩小 rest 并做
Collider[] hitColliders = Physics.OverlapSphere(transform.position, SphereRadius, mask, QueryTriggerInteraction.UseGlobal);
var target = GetClosestEnemy(hitColliders.Select(collider => collider.transform));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.