当前位置:网站首页>Some preliminary explorations of avoiding obstacles and finding paths by rays in unity
Some preliminary explorations of avoiding obstacles and finding paths by rays in unity
2022-06-22 18:29:00 【Tomato ape】
I learned the method of ray pathfinding a few days ago , By sending a ray forward , If the normal of the obstacle location point hit by the ray is on the right side of the ray , Turn to the right , If it's on the left , Turn left . As shown in the figure below :

// The following method is to avoid obstacles by comparing the normals in the ray
if (Physics.Raycast (transform.position + Vector3.up * 0.5f, transform.forward, out hit, 10f, lmBarrier)) { // Fire a line in front of the character who is half a meter higher 10 Meter ray , If there is an object hitting the obstacle level
float rotateDir = Vector3.Dot (transform.right, hit.normal); // Get the point multiplication result of the normal of the right direction of the character and the hit position , It is mainly used to judge the position of obstacles , Is it on the left or right side of the character
Debug.DrawRay (transform.position + Vector3.up * 0.5f, transform.forward * 7, Color.red);
Debug.DrawRay (hit.point, hit.normal, Color.blue);
if (rotateDir >= 0) { // If greater than or equal to 0
transform.Rotate (transform.up * 90 * Time.deltaTime); // In clockwise direction 90 Degrees per second
lookReTime = 0; // Avoid avoiding obstacles , It also faces the player , Prone to reverse steering
} else {
transform.Rotate (transform.up * -90 * Time.deltaTime); // Then turn counterclockwise to 90 Degrees per second
lookReTime = 0;
} It really can avoid some simple obstacles , But we will soon find out , There will be some problems : When two obstacles form an included angle , It is likely to cause you to turn back and forth in this corner , I can't get out of this corner anymore

So I think of some ways to solve this problem , Added a judge whether to enter the dead end mode :
1、 A preliminary and simple determination , When you encounter the obstacles you encountered before ( It doesn't include the one just met ), Enter dead end mode ;
2、 After entering the dead end mode , Monsters have only one behavior , Is to try to follow the wall in one direction to escape the dead end ;
3、 It is necessary to confirm whether to leave the dead end , Restore the normal behavior of the monster after leaving the dead end

How to judge whether the monster has left the dead end , I use two conditions here , One is that there must be no more obstacles between the monster and the target , The angle between the monster's forward direction and the target direction must be less than 90 degree .

RaycastHit hit; // It is used to detect whether there are obstacles ahead
if (!Physics.Raycast(transform.position + Vector3.up * 0.5f, player.position - transform.position, out hit, Vector3.Distance(player.position, transform.position), lmBarrier))
{// If the radiation from the target doesn't touch the obstacle
transform.LookAt(player);
isDilemma = false; // Dead end mode is off
lookReTime = 0;
Debug.Log("haha, Look where you're going ");
}
else
{
if (!isDilemma) // If you are not in dead end mode , entering
{
if (Physics.Raycast(transform.position + Vector3.up * 0.5f, transform.forward, out hit, rayDis, lmBarrier))
{ // Fire a line in front of the character who is half a meter higher 10 Meter ray , If there is an object hitting the obstacle level
barrier03 = barrier02; //barrier01-03 These are all stated GameObject type
barrier02 = barrier01;
barrier01 = hit.transform.gameObject;
if (barrier01 == barrier02)
{ // If the next one is the same
rotateDir = Vector3.Dot(transform.right, hit.transform.position - transform.position);
if (rotateDir >= 0)
{
transform.Rotate(transform.up * -180 * Time.deltaTime);
lookReTime = 0; // Avoid avoiding obstacles , It also faces the player , Prone to reverse steering
}
else
{
transform.Rotate(transform.up * 180 * Time.deltaTime);
lookReTime = 0; // Avoid avoiding obstacles , It also faces the player , Prone to reverse steering
}
Debug.Log(" I'll find you soon ");
}else if (barrier03 == barrier01) // If the one you just met is the same as the one you met before , The dead end mode is triggered
{ // Enter dead end mode
barrier04 = barrier01.transform;
rotateDir = Vector3.Dot(transform.right, barrier04.position - transform.position);
if (rotateDir >= 0)
{ // If the obstacle is on the right side of the forward direction
for (int i = 0; i < 72; i++) // Quickly find the edge of the obstacle , Walk to its edge
{
transform.Rotate(transform.up * 5);
if (!Physics.Raycast(transform.position + Vector3.up * 0.5f, transform.forward, out hit, rayDis, lmBarrier))
{
break;
}
}
}
else
{
for (int i = 0; i < 72; i++)
{
transform.Rotate(transform.up * -5);
if (!Physics.Raycast(transform.position + Vector3.up * 0.5f, transform.forward, out hit, rayDis, lmBarrier))
{
break;
}
}
}
isDilemma = true; // Turn on dead end mode
Debug.Log (" Enter the dead end mode ");
}
}
}
else
{
rotateDir = Vector3.Dot(transform.forward, player.position - transform.position);
if (Physics.Raycast(transform.position + Vector3.up * 0.5f, player.position - transform.position, out hit, rayDis, lmBarrier))
{
//Debug.DrawRay(transform.position + Vector3.up * 0.5f, player.position - transform.position, Color.red);
if (hit.transform.gameObject != barrier04.transform.gameObject && rotateDir > 0)
{
isDilemma = false;
// Debug.Log(" The dead end mode is disabled ");
transform.LookAt(player);
lookReTime = 0;
}
if (Physics.Raycast(transform.position + Vector3.up * 0.5f, transform.forward, out hit, rayDis, lmBarrier))
{
if (hit.transform.gameObject != barrier01 && hit.transform.gameObject != barrier02)
{
isDilemma = false;
//Debug.Log(" Temporarily remove the dead end mode ");
}
}
}
else if (rotateDir > 0)
{
isDilemma = false;
//Debug.Log(" The dead end mode is disabled ");
transform.LookAt(player);
lookReTime = 0;
}
else
{
rotateDir = Vector3.Dot(transform.right, barrier04.position - transform.position);
if (rotateDir >= 0)
{
for (int i = 0; i < 72; i++)
{
transform.Rotate(transform.up * 5f);
if (Physics.Raycast(transform.position + Vector3.up * 0.5f, transform.forward, out hit, rayDis, lmBarrier))
{
transform.Rotate(transform.up * -5f);
break;
}
}
}
else
{
for (int i = 0; i < 72; i++)
{
transform.Rotate(transform.up * -5f);
if (Physics.Raycast(transform.position + Vector3.up * 0.5f, transform.forward, out hit, rayDis, lmBarrier))
{
transform.Rotate(transform.up * 5f);
break;
}
}
}
//Debug.Log(" When will there be a dead end ");
}
}
} Although the problem of included angle is solved , But when faced with more complicated situations , Still very clumsy , So I'm going to learn something later AI Algorithm , Better to solve these problems . And the code is written in a mess , I have to work harder in the future .
边栏推荐
猜你喜欢

Behind the fall of the first Seberg: the extreme race between technology and frostbite

巴比特 | 元宇宙每日必读:传腾讯成立XR部门,元宇宙板块再次上涨,多家券商发报告关注虚拟人的投资机会...

零基础学编程/学逆向/过检测(frida实战)

Nuxt - Universal (SSR / SSG) / single page app (rendering mode)

How can the new generation of HTAP databases be reshaped in the cloud? Tidb V6 online conference will be announced soon!

Traitement des valeurs manquantes

缺失值處理

< JVM part I: memory and garbage collection part > 08 object instantiation and direct memory

TypeScript(7)泛型

详解openGauss多线程架构启动过程
随机推荐
Grafana 9 is officially released, which is easier to use and more cool!
传统图像--LBP特征
测试组的任务职责和测试的基本概念
In May, 2022, China's game manufacturers and applications went to sea, with top 30 revenue in EMEA region
Some difficulties in making web pages
线程池:ThreadPoolExcutor源码阅读
Source code of live video system, hiding and Title Modification of the top title bar
【 outils】 utilisation de PIP et de conda
Filebeat收集日志数据传输到Redis,通过Logstash来根据日志字段创建不同的ES索引
传输层 知识点总结
Jenkins配置项目集成钉钉通知
Pytorch——报错解决:“torch/optim/adamw.py” beta1, UnboundLocalError: local variable ‘beta1‘
如何持续突破性能表现? | DX研发模式
Jenkins configuration project integration pin notification
视频直播系统源码,顶部标题栏的隐藏和标题修改
缺失值處理
Jenkins容器安装ruby-runtime插件失败报错解决
This article takes you to master the use of tcpdump command
第四届青年生命科学论坛 | 第一轮通知
[fpga+pwm] design and implementation of phase shift trigger circuit for three-phase PWM rectifier based on FPGA