阻止Navmesh障碍物避免其他代理人互相撞到周围的方法
我正在使用Unity的NavMesh系统来制作带有坦克的RTS游戏。
当坦克彼此接近时,回避系统就会开始,他们试图摆脱彼此的方式。但是,他们经常互相碰到,最终将他人推开。像坦克一样沉重的车辆看起来不可能,而且看起来不自然。
有没有办法让Navmesh代理商尝试互相避免,但不会互相碰到,如果这样做,绝对不会互相推动?
我试图改变避免障碍的优先级,但至少仍然有一个坦克将其他坦克推开。
我还尝试更改刚性体,例如使固定坦克与重力一起工作并使其变得非常重。我还冻结了所有僵化的限制。但是,其他坦克仍然能够轻松地将它们推开。
目前,当坦克停止移动时,我在他们的下面出现了纳沃梅什障碍物,这有助于避免。但是,这只有在静止的情况下才起作用 - 其他人仍然可以将移动的坦克推到四处。
关于如何解决这一问题的任何想法或建议将不胜感激!
I am using Unity's navmesh system to make an RTS game with tanks.
When the tanks get close to each other, the avoidance system kicks in and they try to get out of each other's way. However, they often bump into each other and end up pushing others out of the way. This shouldn't be possible with vehicles as heavy as tanks, and it looks unnatural.
Is there a way to have the navmesh agents try and avoid each other, but not bump into each other, and if they do, definitely not push each other around?
I have tried altering the obstacle avoidance priority, but there is still at least always one tank that pushes others out of the way.
I have also tried altering the rigidbody, for example making stationary tanks work with gravity and making them really heavy. I have also frozen all rigidbody constraints. However, other tanks are still able to push them out of the way with ease.
At the moment, when tanks stop moving I have made a navmesh obstacle appear under them, which helps with avoidance. However, this only works if they are stationary - moving tanks can still be pushed around by others.
Any ideas or suggestions for how to solve this would be greatly appreciated!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
尽管不是Unity或Navmeshagents的专家,但我最近也一直在为代理商不切实际地互相推动的类似问题而苦苦挣扎。就我而言,这是在机场排队扫描登机通行证的人们,但我向您保证,它看起来还不算荒谬。
花了几个小时在互联网上进行搜寻和经过几个小时的反复试验,我很遗憾地说没有快速或简单的解决方案。坦率地说,Unity的嵌入路径AI系统既粗略又抽搐。还记得回到2006年的“英雄公司”中,坦克会备份而不是只有一小段距离而转身?是的,15年后,如果没有大量的自定义脚本,Unity的Navermeshagents仍然无法做到这一点……
但是有几个想法!
思想#1:在我们提出可能的建议之前,对此问题的不同评估是要使环境或游戏玩法阻止坦克互相碰到彼此。我的意思是,确保它可能有时会发生在城市空间中心混乱的战斗中的混乱之中,但是从我对现实生活中的坦克战争的理解来看,它们几乎从来没有真正彼此碰到……如果您的巨大的远程大炮具有全地形轨道的移动性,那么另一个坦克像一些停车场挡泥板弯曲者一样,将其淹没。想到这是我在围绕问题的纳维敏人看到的更大的问题是,当步兵推动坦克时。在现实生活中,他们会更有可能在胎面旁边奔跑,或者靠在坦克后面,或者在主炮塔桶下方鸭子。因此,如果您的RTS游戏同时具有坦克和步兵,并且所有人都有通过Navmesh和Navmeshagents进行的探索,那么您还有其他几个原因。
无论如何,我的意思是您也许您可以实施某种脚本,以使坦克在同一侧保持形成?尽力而为,以保持与盟军坦克的最小距离?也许将脚本降低到离另一个的距离时,将其向前速度降低到零,或者其他形式的硬/软检查以防止相关坦克甚至试图彼此之间的颠簸距离。至于敌方坦克,只有在非常卡通的情况下,当两个坦克处于积极的战斗状态时,他们才会彼此撞到彼此。如果一个坦克是瓦砾的吸烟堆或被其机组人员遗弃,那么在其位置禁用了Navmeshagent并堵塞Navmesh障碍物将可以正常工作。
实际上,您是否曾经玩过/看过2005年任天堂游戏“营战”?现在,我认为可以公平地描述出一款游戏,因为对坦克战的解释很松散,更不用说物理定律了……甚至在那个愚蠢的游戏坦克中也很少彼此相撞。还记得2003年的游戏“智囊团”吗?一个非常快速的粗糙坦克混战,在极少数情况下,一个坦克撞到了另一个人,有人翻了过去,每个人都笑了。
如果您正在制作抽象的游戏或轻松的愚蠢游戏,那么没有人会在乎一个或两个坦克是否有些轻描淡写。如果这是一个严肃的游戏或历史模拟类型的RTS,为什么坦克会互相碰撞?
我离题。我的观点是,这一问题不切实际地互相推动,可以通过游戏策略或幕后代码限制限制坦克的距离,甚至限制了坦克的距离。那么他们是否假设会互相推动都没关系,因为它很少会出现,而且当玩家极不可能注意到或关心时,它很可能处于非常活跃和短暂的情况。
以为#2:,但是我知道什么?因此,这里有一些限制颠簸的想法!我已经看到了一些论坛主题和博客文章,这些论坛线程和博客文章仅使用navMeshagent组件来确定路径,并使用单独的脚本与实际动画师一起制作对象,或者您无休止地“追逐” navmeshagent。这通常是在汽车的背景下提出的。但是,汽车和坦克没有那么不同,以一种根本的运动方式。 “追逐”看不见的Navmeshagent可能在狭窄的空间中有点笨拙,但是与步行的人形生物相比,坦克几乎不会敏捷,大概是为组件设计的。也许这对您来说可能是一个可行的解决方案,具体取决于您期望在任何给定时间活跃的坦克数量。刚性物理和其他碰撞的东西将更可预测,更容易控制,而您唯一依靠NavMeshagent的东西就是“转向”一个使用其他脚本移动的坦克。
以为#3:完全不同的想法将部分将Navmeshagent与主游戏对象的根位置分离。官方在线统一手册甚至提到了以下内容在这里最小化脚滑动的技巧。坦克没有脚,但是整个坦克滑行基本上是同一问题吗?也许您可以故意允许坦克互相推动一点,如果从视觉上讲,坦克实际上没有移动,因为您正在通过脚本重置其变换位置。
以为#4:我发现NavMeshagent组件的优先设置非常毫无用处。仅当您非常确定要代理人移动的确切顺序(几乎是预先标记的方式)时,它才会产生实际的不同。在动态的程序RTS游戏中并不是很有帮助。也就是说,是否可以根据一些战场标准实施某种更改单个坦克的设定优先级的脚本?当然,它不会完全阻止坦克互相推动,但可能会动态限制它。例如,您可以有两个移动的坦克互相碰撞会自动将坦克移动到更低的优先级。或一个比附近任何储罐大的储罐,可能由某些标签值确定,将优先级低于其他标签。这将有助于所有在开始时分配静态默认优先级值的储罐,因为储罐的优先级会根据其他储罐在物理附近和相关变量而改变。
因此,受损的坦克不太可能在新鲜的坦克上推。倒退的坦克比向前前进的坦克不太可能推其他坦克。浅河中间的坦克或任何无法将坦克坐在河岸上的坦克。如果您可以通过脚本在NavMeshagent组件中实现动态优先设置,则可能会有所帮助。明智的游戏玩法最终比视觉现实主义更重要吗?
以为#5:我不喜欢告诉人们通过使用第三方插件来解决他们的问题。尤其是我个人不使用的。也就是说,您还可以考虑研究Unity Asset商店项目的功能,例如A*(发音为A-Star)或其他旨在替换或至少改善内置统一系统的插件。 100usd左右是昂贵的,并且盗版这些插件是不道德的,因此,如果您确实采取了这样的路线,我建议您与他们直接与他们联系并询问您的特定问题,然后再进行此次跌落。同样,我个人不使用它们,但是我不必在这里提及它们是不负责任的。
如果他们来找我,我会通过编辑此回应来添加更多想法,但我希望我可能会给您一些您可以做的事情。而且,如果您确实找出有效的解决方案,请告诉我们!!! RTS游戏开发人员需要他们能获得的所有帮助,许多其他人与不是坦克的代理商也有类似的问题。祝你好运。
Though not an expert at either Unity or NavMeshAgents, I have also recently been struggling with a similar issue of agents unrealistically shoving each other around. In my case it's people lining up to scan boarding passes at an airport, but it looks no less ridiculous than tanks I assure you.
Having spent several hours scouring the internet and several more hours in trial and error, I regret to say that there is no quick or simple solution. Frankly put, Unity's inbuilt pathfinding AI system is both crude and twitchy. Remember how way back in 2006's "Company of Heroes" the tanks would back up rather than turn around if only going a short distance? Yeah, 15 years later Unity's NavMeshAgents still can't do that without extensive custom scripting...
A couple of thoughts though!
Thought #1: Before we get into possible suggestions, a different appraoch to this issue would be to have the environment or gameplay discourage tanks from bumping into each other to begin with. I mean, sure it may occasionally happen during the messy heat of a chaotic battle in the center of an urban space, but from my personal understanding of real-life tank warfare they almost never actually physically touch each other... Something has gone terribly wrong if your huge long-range artillery with all-terrain-tread-based mobility has been dented by another tank like some parking lot fender-bender. Come to think of it the bigger issue I see with this NavMeshAgents shoving around issue would be when infantry push the tank around. They would, in a real-life scenario, be vastly more likely to run right next to the treads, or lean out of cover behind the tank, or duck under the main turret barrel. So if your RTS game has both tanks and infantry, and all of them have the pathfinding dealt with via NavMesh and NavMeshAgents, you have several other reasons to be concerned.
Anyhows, my point is perhaps you could implement some sort of script that makes tanks on the same side keep formation? Try as best they can to maintain a minimum distance from allied tanks? Maybe have the script lower their forward speed to zero when too close to another one, or some other form of hard/soft check to keep allied tanks from even attempting to get within bumping distance of each other. As to enemy tanks, again only in a very cartoony situation would they ever ram into each other when both tanks are in active fighting condition. If one tank is a smoking heap of rubble or has been abandoned by its crew, then disabling the NavMeshAgent and plopping a NavMesh Obstacle in its place would work fine.
Actually have you ever played/seen the 2005 Nintendo game "Battalion Wars"? Now there is a game that I think can be fairly described as following a loose interpretation of tank warfare, let alone the laws of physics... And even in that silly game tanks very rarely collided with one another. Remember the 2003-ish game "Think Tanks"? A very fast-paced rough-and-tumble tank melee, and on the rare occasion a tank bumped into another one somebody got flipped over and everyone had a good chuckle.
If you are making an abstracted game or a light-hearted silly one, nobody is going to care if a tank or two is nudged a little bit. If it's a serious game or a historical simulation type RTS, why are the tanks bumping into each other at all?
I digress. My point is that this issue of tanks unrealistically pushing each other can be minimized by either gameplay strategy or behind-the-scenes code limiting how close tanks even get to other tanks. Then it doesn't matter if they hypothetically would push each other, because it will very rarely come up and when it does come up, it is likely to be in a very active and brief situation when the player is highly unlikely to notice or care.
Thought #2: But what do I know? So here's a few ideas to limit the bumping! I've seen a few forum threads and blog posts that discuss the idea of only using the NavMeshAgent component to determine the path, and using a separate script to make the object with the actual Animator or what-have-you endlessly "chase" the NavMeshAgent. This is usually brought up in the context of cars. But cars and tanks are not so different, in a fundamental movement way. "Chasing" an invisible NavMeshAgent might be a little clunky in tight spaces, but tanks are hardly nimble compared to the humanoids on foot the component was presumably designed for. Perhaps this might be a viable solution for you, depending on the number of tanks you expect to be active at any given time. The RigidBody physics and other collision stuff would be more predictable and easier to control, and the only thing you'd rely on the NavMeshAgent for would be "steering" a tank which moves using some other script.
Thought #3: Completely different idea would be partially decoupling the NavMeshAgent from the root position of the main GameObject. The official online Unity manual even mentions this here, where they give a few simple tricks to minimize foot sliding. Tanks don't have feet, but the entire tank sliding around is basically the same problem right? Perhaps you can knowingly allow the tanks to shove each other a bit, if visually speaking the tank does not actually move because you are resetting its transform location by script.
Thought #4: I found that the Priority setting of the NavMeshAgent component was pretty useless. It only made a practical difference when you were very sure the exact order you wanted agents to move, almost in a pre-scripted way. Not very helpful in a dynamic procedural RTS game. That said, would it be possible to implement some sort of script that changes the set Priority of individual tanks based on a few battlefield criteria? It wouldn't completely stop tanks from shoving each other around of course, but might dynamically limit it. For example, you could have two moving tanks which bump into each other automatically set the tank moving faster to the lower Priority. Or a tank which is larger than any nearby tanks, determined by some tag value perhaps, be set to a Priority lower than the other ones. This would help more than all the tanks having a static default Priority value assigned at the start, because the Priorities of tanks would change depending on which other tanks are physically nearby and relevant variables.
Damaged tanks would thus be less likely to push around fresh ones. Tanks going backwards would be less likely to push other tanks than ones going forwards. Tanks in the middle of a shallow river or whatever would not be able to push tanks sitting on firmer ground up on the bank. If you can implement a dynamic Priority setting in the NavMeshAgent component via script, it might help. Sensible gameplay is ultimately more important than visual realism anyways right?
Thought #5: I don't like telling people to solve their problems by using third-party plugins. Especially ones I don't personally use. That said you could also consider looking into the capabilities of Unity Asset Store items such as A* (Pronounced A-Star) or other plugins designed to either replace or at least improve the in-built Unity system. 100USD or so is expensive and pirating these plugins is unethical, so if you do pursue such a route I'd suggest contacting the people that make them directly and asking about your specific issue before taking that plunge. Again, I don't personally use them but it would be irresponsible of me to not mention them here.
I'll add more thoughts via editing this response if they come to me, but I hope I might have given you a few inklings of what you can do. And please, if you do figure out a solution that works please let us know!!! RTS game developers need all the help they can get and many other people have similar issues with Agents that are not tanks. Good luck.