让我先解释一下这个问题:)
我有英雄和敌人。这是一场格斗游戏。英雄和敌人在动画控制器中都有空闲,阻止,打击和getHit动画和状态。英雄和敌人附有脚本。英雄由玩家控制,然后敌人由AI控制。
现在我首先将剧本附加到英雄,然后是敌人。现在当敌人拳打脚踢,如果英雄没有捍卫英雄就会受到打击。但是如果敌人没有阻挡并且英雄击中敌人则不会受到攻击。 这是因为脚本首先附加到英雄。
现在,如果我从两者中删除脚本并且首先将敌人脚本附加到敌人,然后将英雄脚本附加到英雄。明智的是真实的。在敌人中,命中将被登记,而在英雄上的命中将不会被登记。
我不确定为什么会这样,我尝试了不同的事情,但问题仍然存在。
我也尝试在网上寻找解决方案,但没有一个能解决我的问题。
谢谢:)
下面是检查敌人可以采取命中的敌人脚本void Update () {
myTick++;
currentTick = myTick;
GameObject player = GameObject.Find("theDude");
Animator pAnim = player.GetComponent<Animator>();
//Getting Hit
if (pAnim.GetBool("tIsPunching"))
{
if (anim.GetBool("bEnemyIsDefending") == false)
{
Debug.Log("enemy got hit");
anim.SetTrigger("tEnemyGotHit");
anim.SetBool("bEnemyIsDefending", true);
}
}
}
这是英雄剧本,用于检查英雄是否可以击中。
void Update () {
totalTime += Time.deltaTime;
GameObject enemy = GameObject.Find("Enemy");
Animator eAnim = enemy.GetComponent<Animator>();
//Getting Hit
if (eAnim.GetBool("tEnemyIsPunching"))
{
if (anim.GetBool("bIsDefending") == false)
{
Debug.Log("player got hit");
anim.SetTrigger("tGotHit");
}
}
}
而不是获取对象,我曾经有一个公共GameObject,并在相应的类中附加了英雄和敌人。但它没有任何区别。
答案 0 :(得分:1)
我认为您的问题在于使用触发器java.lang.ClassCastException: org.apache.avro.mapred.AvroKey cannot be cast to my.package.containing.MyCustomClass
和tEnemyIsPunching
。只要触发器发生转换,触发器就会重置
(见:https://docs.unity3d.com/Manual/AnimationParameters.html)。
在您的情况下,tIsPunching
或(tIsEnemyPunching
)会在设置的同一帧中重置。下面是一个例子,说明如果首先添加英雄脚本,游戏中的更新循环可能会是什么样子:
tIsPunching
在下一次更新中,让我们看一下英雄更新中发生的事情:
Hero Update()
Check if enemy is punching
He is not, so don't do anything
Enemy Update()
Punch! Set 'bIsEnemyPunching' = true
Animation Update()
bIsEnemyPunching is true so transition to the punching animation
reset bIsEnemyPunching = false
所以Hero从来没有看过拳头因为Hero Update()
Check bIsEnemyPunching
bIsEnemyPunching was reset in the previous frame, so it is false
Since the enemy isn't punching don't do anything
在Hero改变检查之前被重置了。
这就是添加脚本的顺序很重要的原因。无论哪个脚本首先更新都能够打卡,因为第二个脚本会在重置之前看到触发器。但是,要更新的第二个脚本永远无法打卡,因为在其他脚本有机会更新之前触发器会重置。
一种解决方案是检查动画状态的名称而不是触发器值。
bIsEnemyPunching
或者,无论何时触发拳击,只需在任何角色被打孔时调用一个函数。因此,当敌人击打英雄时,敌人的static int punchStateHash = Animator.StringToHash("Punch");
AnimatorStateInfo enemyState = eAnim.GetCurrentAnimatorStateInfo(0);
if (enemyState.nameHash == punchStateHash){
//The enemy is punching!
}
功能应该在英雄上召唤Punch(...)
(或者你想要称之为那些功能的任何东西)。然后英雄检查他自己的状态,以确定他是否阻止。
附加说明
您应该避免在更新功能中使用以下代码:
TakePunch(...)
这些函数非常慢,因为Unity必须在所有对象中搜索名为GameObject player = GameObject.Find("theDude");
Animator pAnim = player.GetComponent<Animator>();
的对象,然后搜索它的所有组件以找到动画师。这样做一次并保存结果。