如何调整这个近战脚本以提高响应速度?



我按照这个视频得到了一个损坏脚本:https://www.youtube.com/watch?v=aSeE7u8Cs-I&list=PLZ1b66Z1KFKiaTYwyayb8-L7D6bdiaHzc&index=11

问题是,这是一把枪,出于某种原因,即使光线投射在前方,有时刀击中也不会记录。有没有办法让它使我面前的任何东西在点击/攻击时受到伤害?

这是我拥有的当前代码:

void Start()
{
animator = GetComponentInChildren<Animator>();
}

// Update is called once per frame
void Update()
{
if (Input.GetButtonDown("Attack"))
{
StartCoroutine(Poke());
}
else
{
}
IEnumerator Poke()
{
RaycastHit knife;
//this line was causing weird delay but I can't remember 100% what it was for and if it's still needed
//isAttacking = true;
if (Physics.Raycast(transform.position, transform.TransformDirection(Vector3.forward), out knife))
{
knife.transform.SendMessage("DamageZombie", DamageAmount, SendMessageOptions.DontRequireReceiver);
}
animator.SetBool("isAttacking", true);
yield return new WaitForSeconds(.1f);
animator.SetBool("isAttacking", false);
}
}
} ```

试试这个:

bool isAttacking = false;
void Start() {
animator = GetComponentInChildren<Animator>();
}
void Update() {
if (Input.GetButtonDown("Attack")) {
StartCoroutine(Poke());
}
}
IEnumerator Poke() {
if(!isAttacking){
isAttacking = true;
RaycastHit knife;
if (Physics.Raycast(transform.position, transform.TransformDirection(Vector3.forward), out knife)) {
knife.transform.SendMessage("DamageZombie", DamageAmount, SendMessageOptions.DontRequireReceiver);
}
animator.SetBool("isAttacking", true);
yield return new WaitForSeconds(.1f);
animator.SetBool("isAttacking", false);
isAttacking = false;
}
}

还要记住,Physics.Raycast可能会使用LayerMask来检测物体,如果没有任何效果,请看一下。

好吧,您可能正在碰到其他碰撞体,一些没有附加任何组件的游戏对象,该组件具有称为DamageZombie的方法。

有多种方法可以将光线投射限制为特定目标:

  1. Physics.Raycast需要其他参数

    最大距离 光线应检查碰撞的最大距离

    layerMask图层蒙版
    ,用于在投射光线时有选择地忽略碰撞体。

    因此,将目标敌人放在特定图层上,您已经可以将Raycast限制为仅击中这些,并且仅在它们足够接近时才击中它们:

    // Adjust here which layer(s) you want to hit via the Inspector
    public LayerMask targetLayers;
    ...
    if (Physics.Raycast(new Ray(transform.position, transform.forward), out var hit, 1f, (int)targetLayers))
    {
    // Do something
    }
    

    因此,这已经过滤了光线投射,并且仅击中1单位范围内找到的第一个对象,并且仅在targetLayers中配置的图层上

  2. 正如您所说,您想hit everything实际上可以使用Physics.RaycastAll然后遍历所有命中

    var hits = Physics.RaycastAll(new Ray(transform.position, transform.forward), 1f, targetLayers);
    foreach(var hit in hits)
    {
    // Do something
    }
    

    现在这基本上与以前相同,但现在击中1单元范围内和targetLayers中配置的层上的每个对象。

  3. 使用标签,您可以进一步限制,并在光线投射后检查您击中的内容。

    foreach(var hit in hits)
    {
    if(!hit.CompareTag("Zombie")) continue;
    // Do something
    }
    

最后一般不要使用SendMessage!这是非常低效和不安全的..你永远不会知道你击中的对象是否有实现这种方法的组件......或者如果您在重命名方法后在每个地方都更改了此字符串......

而是真正获得您想要命中的组件!

var damageScript = hit.GetComponent<YOURSCRIPT>();
if(damageScript)
{
damageScript.DamageZombie(DamageAmount);
}

最新更新