Unity - 让相机锁定敌人并留在玩家身后?
Unity - Making Camera Lock on To Enemy and stay behind player?
我正在尝试创建一个随玩家移动但在玩家单击锁定按钮时锁定敌人的摄像机。行为几乎如我所愿,相机锁定目标。当玩家站在目标前面时,它工作正常。然而,一旦玩家跑过目标,相机就会表现得很奇怪。它仍然看着敌人,但它不会留在玩家身后。这是指示行为的代码:
if(MouseLock.MouseLocked && !lockedOn){ // MOUSE CONTROL:
Data.Azimuth += Input.GetAxis("Mouse X") * OrbitSpeed.x;
Data.Zenith += Input.GetAxis("Mouse Y") * OrbitSpeed.y;
} else if(lockedOn) { // LOCKON BEHAVIOUR:
FindClosestEnemy();
}
if (Target != null) {
lookAt += Target.transform.position;
base.Update ();
gameObject.transform.position += lookAt;
if(!lockedOn){
gameObject.transform.LookAt (lookAt);
} else if(enemyTarget != null) {
Vector3 pos1 = Target.transform.position ;
Vector3 pos2 = enemyTarget.transform.position ;
Vector3 dir = (pos2 - pos1).normalized ;
Vector3 perpDir = Vector3.Cross(dir, Vector3.right) ;
Vector3 midPoint = (pos1 + pos2) / 2f;
gameObject.transform.LookAt (midPoint);
}
}
以及寻找最近敌人的代码:
void FindClosestEnemy () {
int numEnemies = 0;
var hitColliders = Physics.OverlapSphere(transform.position, lockOnRange);
foreach (var hit in hitColliders) {
if (!hit || hit.gameObject == this.gameObject || hit.gameObject.tag == this.gameObject.tag){
continue;
}
if(hit.tag != "Enemy") // IF NOT AN ENEMY: DONT LOCK ON
continue;
var relativePoint = Camera.main.transform.InverseTransformPoint(hit.transform.position);
if(relativePoint.z < 0){
continue;
}
numEnemies += 1;
if(enemyTarget == null){
print ("TARGET FOUND");
enemyTarget = hit;
}
}
if(numEnemies < 1){
lockedOn = false;
enemyTarget = null;
}
}
正如我所说,行为几乎按预期工作,但是我需要相机在锁定时留在玩家身后,并且它必须面对敌人和玩家之间的enemy/midPoint。如何才能做到这一点?谢谢你的时间。
澄清你的意图:你想锁定相对于目标(玩家)的位置,同时设置相机旋转以查看目标或次要目标(敌人)?您当前的代码正确执行了旋转,但定位有问题?
相对于另一个 object 固定相机的最简单方法是在场景中 parent 它。在您的情况下,您可以在玩家游戏 object.
下将相机添加为 child
如果您不想这样做,请再次查看您的定位代码:
lookAt += Target.transform.position;
base.Update ();
gameObject.transform.position += lookAt;
我不知道 lookAt
最初来自哪里,但对我来说这看起来完全不对。叫做 lookAt
的东西应该与位置无关,我怀疑你想要 +=
定位代码中的任何东西,因为你想要一个固定的相对位置。试试这个:
public float followDistance; // class instance variable = distance back from target
public float followHeight; // class instance variable = camera height
...
if (Target != null) {
Vector3 newPos = target.position + (-Target.transform.forward * followDistance);
newPos.y += followHeight;
transform.position = newPos;
}
这应该可以解决定位问题。将 followDistance 和 followHeight 设置为您想要的任何值。假设您的旋转代码有效,这应该可以解决问题。
我正在尝试创建一个随玩家移动但在玩家单击锁定按钮时锁定敌人的摄像机。行为几乎如我所愿,相机锁定目标。当玩家站在目标前面时,它工作正常。然而,一旦玩家跑过目标,相机就会表现得很奇怪。它仍然看着敌人,但它不会留在玩家身后。这是指示行为的代码:
if(MouseLock.MouseLocked && !lockedOn){ // MOUSE CONTROL:
Data.Azimuth += Input.GetAxis("Mouse X") * OrbitSpeed.x;
Data.Zenith += Input.GetAxis("Mouse Y") * OrbitSpeed.y;
} else if(lockedOn) { // LOCKON BEHAVIOUR:
FindClosestEnemy();
}
if (Target != null) {
lookAt += Target.transform.position;
base.Update ();
gameObject.transform.position += lookAt;
if(!lockedOn){
gameObject.transform.LookAt (lookAt);
} else if(enemyTarget != null) {
Vector3 pos1 = Target.transform.position ;
Vector3 pos2 = enemyTarget.transform.position ;
Vector3 dir = (pos2 - pos1).normalized ;
Vector3 perpDir = Vector3.Cross(dir, Vector3.right) ;
Vector3 midPoint = (pos1 + pos2) / 2f;
gameObject.transform.LookAt (midPoint);
}
}
以及寻找最近敌人的代码:
void FindClosestEnemy () {
int numEnemies = 0;
var hitColliders = Physics.OverlapSphere(transform.position, lockOnRange);
foreach (var hit in hitColliders) {
if (!hit || hit.gameObject == this.gameObject || hit.gameObject.tag == this.gameObject.tag){
continue;
}
if(hit.tag != "Enemy") // IF NOT AN ENEMY: DONT LOCK ON
continue;
var relativePoint = Camera.main.transform.InverseTransformPoint(hit.transform.position);
if(relativePoint.z < 0){
continue;
}
numEnemies += 1;
if(enemyTarget == null){
print ("TARGET FOUND");
enemyTarget = hit;
}
}
if(numEnemies < 1){
lockedOn = false;
enemyTarget = null;
}
}
正如我所说,行为几乎按预期工作,但是我需要相机在锁定时留在玩家身后,并且它必须面对敌人和玩家之间的enemy/midPoint。如何才能做到这一点?谢谢你的时间。
澄清你的意图:你想锁定相对于目标(玩家)的位置,同时设置相机旋转以查看目标或次要目标(敌人)?您当前的代码正确执行了旋转,但定位有问题?
相对于另一个 object 固定相机的最简单方法是在场景中 parent 它。在您的情况下,您可以在玩家游戏 object.
下将相机添加为 child如果您不想这样做,请再次查看您的定位代码:
lookAt += Target.transform.position;
base.Update ();
gameObject.transform.position += lookAt;
我不知道 lookAt
最初来自哪里,但对我来说这看起来完全不对。叫做 lookAt
的东西应该与位置无关,我怀疑你想要 +=
定位代码中的任何东西,因为你想要一个固定的相对位置。试试这个:
public float followDistance; // class instance variable = distance back from target
public float followHeight; // class instance variable = camera height
...
if (Target != null) {
Vector3 newPos = target.position + (-Target.transform.forward * followDistance);
newPos.y += followHeight;
transform.position = newPos;
}
这应该可以解决定位问题。将 followDistance 和 followHeight 设置为您想要的任何值。假设您的旋转代码有效,这应该可以解决问题。