攻击角色前方的敌人
Attack enemy in front of character
我有自动攻击系统,可以攻击范围内的敌人。问题是我不想攻击我身后的敌人,而只想攻击前面的敌人,所以我使用了 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); }));
}
}
}
}
}
如果您还需要什么,请告诉我。
分析:
如果内部有多个碰撞器,OnTriggerStay 每帧调用多次。
然后您的代码启动 2 个调用
的协程
castSpell(caster, ...
因此,由于施法者在两种情况下都是相同的,因此第二次协程调用可能会覆盖第一个,因此总是对其中一个而不是两者施法。
我的建议:
你伪造了一些视场系统。在启动协同程序之前,您检查 player.transform.forward
中的 Vector3.Angle 是否与连接玩家和敌人位置的向量向量相对应。也就是说,只是区别: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 左右。
您要做的就是按照说明 here 计算点积。这是一个更可靠的解决方案,而不是使用可能导致奇怪行为的角度。
我有自动攻击系统,可以攻击范围内的敌人。问题是我不想攻击我身后的敌人,而只想攻击前面的敌人,所以我使用了 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); }));
}
}
}
}
}
如果您还需要什么,请告诉我。
分析:
如果内部有多个碰撞器,OnTriggerStay 每帧调用多次。
然后您的代码启动 2 个调用
的协程castSpell(caster, ...
因此,由于施法者在两种情况下都是相同的,因此第二次协程调用可能会覆盖第一个,因此总是对其中一个而不是两者施法。
我的建议:
你伪造了一些视场系统。在启动协同程序之前,您检查 player.transform.forward
中的 Vector3.Angle 是否与连接玩家和敌人位置的向量向量相对应。也就是说,只是区别: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 左右。
您要做的就是按照说明 here 计算点积。这是一个更可靠的解决方案,而不是使用可能导致奇怪行为的角度。