我正在尝试锁定我的第三人称游戏的功能。使用我正在使用的脚本,我得到了不同的效果。通常它可以正常关闭和打开。然而,在看似随机的点上,它不再锁定。对不起,如果它有点乱。我反复测试不同的点。
public class PlayerLockOn : MonoBehaviour
{
public bool lockOn = false;
float maxLockDist = 65;
List<GameObject> availableTars = new List<GameObject>();
float shortestDist = Mathf.Infinity;
public GameObject closestLockOnTarget;
public GameObject currentTarget;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
//Get Input
if (lockOn)
{
GetTargets();
ManageTargets();
if (currentTarget == null)
{
CameraMovement.instance.camRecenter();
lockOn = false;
}
else
{
PlayerStateManager.instance.camState = 1;
CameraMovement.instance.lockOnTarget = currentTarget;
}
}
else
{
availableTars.Clear();
currentTarget = null;
CameraMovement.instance.lockOnTarget = null;
closestLockOnTarget = null;
PlayerStateManager.instance.camState = 0;
}
}
void GetTargets()
{
Collider[] colliders = Physics.OverlapSphere(transform.position, 25);
for (int b = 0; b < colliders.Length; b++)
{
var tag = colliders[b].tag;
if (tag == "Enemy")
{
Transform tarTransform = colliders[b].transform;
Vector3 TargetDir = transform.position - tarTransform.position;
float distance = Vector3.Distance(tarTransform.position, transform.position);
if (PlayerStateManager.instance.Player.transform.root != tarTransform.root && distance <= maxLockDist)
{
availableTars.Add(colliders[b].gameObject);
}
}
}
}
void ManageTargets()
{
for (int i = 0; i < availableTars.Count; i++)
{
float dist = Vector3.Distance(transform.position, availableTars[i].transform.position);
if (dist <= shortestDist)
{
shortestDist = dist;
closestLockOnTarget = availableTars[i];
currentTarget = closestLockOnTarget;
}
}
}
public void lockOnUpdate()
{
lockOn = !lockOn;
}
}
我尝试过将目标转移到不同的点。这并没有产生太大的影响。虽然当我四处移动我的角色时,我有时可以根据角色的角度再恢复一次。但是代码中没有对此的引用,所以我不知道为什么它会产生这种效果。除此之外,我没有其他问题。这是相当可靠的。我只需要添加目视检查以确保它在大多数时间都可见。谢谢你,如果你看过它,只是尝试是一个很大的帮助。
您正在实现 LockOn 功能,同时它与现有的 CameraMovement 对象分离,因此您使用单例模式让它们进行通信。相反,如果您使一个对象控制另一个对象,在简单的情况下,只需向具有类似职责的现有类添加功能:
class CameraController {
...
public LockOnTarget(Transform target){...}
public void StopLockOn(){...}
}
目标搜索不应由 LockOnFeature 或 CameraMovement 对象负责,而应使用其自己的逻辑创建单独的 TargetSearcher 行为。此外,在 Update() 中进行 spherecasts 并不是一个好主意 - 已经有一个物理引擎,让它使用触发器来完成它的工作并且只订阅它的事件来更新你的 HashSet(不要使用列表来不断添加/删除东西,他们在这方面很慢)。
使用 UnityEvent 和 UnityEvent
public UnityEvent<int> OnDamageReceived;
并且通过编辑器连接任何其他脚本的任何方法的能力比所有那些讨厌的单例要好得多,这些单例会迅速使您的应用程序变得僵化且难以更改,同时还保持开发人员的坏习惯。
开发人员的黄金法则:不要发明可以使用无障碍解决方案的地方。使用
Window -> Package Manager
菜单安装Cinemaching,进入用户手册一点,你可以改变你的相机视角,程序视图运动和脚本路径,零代码编写。编写你自己的很酷的相机控制器,它可以做到这一点,这对获得经验和找出背后的一些数学很好,但如果你需要可行的解决方案——使用世界提供的任何东西,它只会节省你的时间。