在角色

时间:2017-06-30 11:38:42

标签: c# unity3d collision-detection unity5 raycasting

我有自动攻击系统,我在攻击范围内的敌人。问题是我不想攻击我身后的敌人,但只是在前面所以我使用Physics.Raycast并且当我的对手触发器内有1个敌人但是当有更多的时候它会工作正常(让我们说2)其中一个敌人落后,一个在前面,首先我检查光线投射并且它返回真实,但是由于我身后的敌人首先进入对撞机,我的咒语正在向它投射到它的位置。那么我怎样才能施放在我面前的物体的拼写(获取位置)?

以下是我施法的代码:

public void castSpell(GameObject caster, GameObject other, float duration)
{
    var fwd = transform.TransformDirection(Vector3.forward);
    if(castOnlyForward && !Physics.Raycast(transform.position, fwd, 10))
    {
        return;
    }
    Debug.Log("ON");    
    if(animationEnabled)
    {
        foreach(var a in animator)
        {
            foreach(var b in a.bools)
            {
                a.animator.SetBool(b.parameterName, b.parameterValue);
            }
            foreach(var i in a.ints)
            {
                a.animator.SetInteger(i.parameterName, i.parameterValue);
            }
            foreach(var f in a.floats)
            {
                a.animator.SetFloat(f.parameterName, f.parameterValue);
            }
        }
    }

    GameObject Temporary_Spell_Handler;
    Temporary_Spell_Handler = Instantiate(_Spell, Spell_Emitter.transform.position, Spell_Emitter.transform.rotation) as GameObject;


    //Add Spell Script to the casted spell so it handes damage and everything about spells.
    Spell tempSpell = Temporary_Spell_Handler.GetComponent<Spell>();
    tempSpell.caster = caster;

    if(b_lenghtScale)
    {
        float percent = currentDistance / (maxDistance / 100);
        ParticleSystemRenderer pr = Temporary_Spell_Handler.GetComponent<ParticleSystemRenderer>();
        pr.lengthScale = -(((lenghtScale - Math.Abs(pr.lengthScale)) / 100) * percent);
        Vector3 newScale = new Vector3();
        newScale.x = (maxScale.x / 100) * percent;
        newScale.y = (maxScale.y / 100) * percent;
        newScale.z = (maxScale.z / 100) * percent;

        Temporary_Spell_Handler.transform.localScale = newScale;
    }

    if(lookAtEnemy)
    {
        if(other.transform.parent != null && other.transform.parent.gameObject.tag == "pivotChange")
        {
            Temporary_Spell_Handler.transform.LookAt(other.transform.parent.gameObject.transform);
        }
        else
        {
            Temporary_Spell_Handler.transform.LookAt(other.transform);
        }
    }

    Destroy(Temporary_Spell_Handler, duration);
}

在这里我施展castSpell

void OnTriggerStay(Collider col)
{
    if(caster.tag == "Player")
    {
        if(CharacterCommands.autoAttacking)
        {
            if(enemiesTags.Contains(col.tag))
            {
                if(!paused)
                {
                    currentDistance = Vector3.Distance(caster.transform.position, col.transform.position);
                    StartCoroutine(Repeat(castSpellEveryNSeconds, () => { castSpell(caster, col.gameObject, spellDuration); }));
                }
            }
        }
    }
    else
    {
        if(frequentlyCastSpell)
        {
            if(enemiesTags.Contains(col.tag))
            {
                if(!paused)
                {
                    currentDistance = Vector3.Distance(caster.transform.position, col.transform.position);
                    StartCoroutine(Repeat(castSpellEveryNSeconds, () => { castSpell(caster, col.gameObject, spellDuration); }));
                }
            }
        }
    }
}

如果您还有其他需要请告诉我。

2 个答案:

答案 0 :(得分:1)

<强>分析:

如果内部有多个碰撞器,则每帧多次调用OnTriggerStay。

然后您的代码启动2个调用

的协同程序
castSpell(caster, ...

因此,由于施法者在两种情况下都是相同的,所以第二次协程调用可能会覆盖第一个,因此总是在其中一个上施放咒语,而不是两者。

我的建议:

你伪造了一些视野系统。在开始Coroutine之前,检查来自player.transform.forward的{​​{3}}对抗模具Vector,它连接玩家和敌人的位置。也就是说,只是差异:player.transform.position - enemy.transform.position - 或者在你的情况下,collider.transform.position为敌人。

您可能需要在减法中切换操作数,现在无法测试。

我大脑的代码:

float angle = Vector3.Angle(player.transform.forward, player.transform.positon - collider.transform.position);
Debug.Log("the angle is: " + angle);
if(angle > -45 && angle < 45){
    // start your spell casting coroutine here
}

确保在测试时读取控制台,我不是100%确定角度值是如何出现的。尤其是0左右。

答案 1 :(得分:1)

您需要做的是按照here的说明计算Dot产品。这是一个更加可靠的解决方案,而不是使用可能导致奇怪行为的角度。