• unity3d 赛车游戏——复位点检测


    一直没有时间写博客

    昨天我的CarWaypoints插件也告一段落了

    今年没回家,过年就我一个人

    挺无聊的,那就休息一天写几篇博客吧

    我的代码可能很少,但是思路很重要

    希望不懂的朋友别只copy代码

    赛车游戏的话赛车难免会冲出跑道、掉入水坑、卡在障碍物上....等情况

    那么问题来了,遇到这些情况怎么办呢?

    玩家玩得好好的,难道就因为遇到这些情况要退出游戏重新进入吗?

    那当然是不现实的,要是我的话果断卸载游戏

    还要骂一句做游戏的人是脑残啊

    我想你不希望玩家骂你是脑残吧,哈哈哈

    新技能,赶快GET起来

    遇到这类情况通常的赛车游戏做法是复位到赛道中央

    这个功能听起来貌似挺简单的,但实际上做起来还是有些小复杂的

    让我们脱掉衣服直奔主题吧

    首先,我们需要waypoint

    我昨天刚做好这个插件

    CarWaypoint插件教程以及下载地址:http://www.cnblogs.com/shenggege/p/4295616.html

    ok,编辑好路标点数据后我们整理一下复位功能的思路

     当赛车复位时

    我们需要获得离赛车距离最近的一个路标点

    然后设置赛车的车头朝向为当前最近路标点的朝向

    当然,我们也要把赛车的移动速度和角速度归零

    以保证赛车复位后不会自动向前冲(你也可以不归零)

    思路就是这么简单,下面我们来看看代码怎么实现

     1     /// 获取距离最近的路径点 <summary>
     2     /// 获取距离最近的路径点
     3     /// </summary>
     4     /// <param name="DPs">路径点集合</param>
     5     /// <param name="myPosition">当前坐标</param>
     6     /// <returns>返回最近距离的路标点</returns>
     7     private WaypointsModel GetClosestWP(List<WaypointsModel> all, Vector3 myPosition)
     8     {
     9         WaypointsModel tMin = null;
    10         float minDist = Mathf.Infinity;//正无穷
    11 
    12         for (int i = 0; i < all.Count; i++)
    13         {
    14             float dist = Vector3.Distance(all[i].Position, myPosition);
    15             if (dist < minDist)
    16             {
    17                 tMin = all[i];
    18                 minDist = dist;
    19             }
    20         }
    21         return tMin;
    22     }

    这是一个获取距离最近的路标点的方法
    用for循环计算所有路标点距离当前赛车位置的距离

    取出最小距离的路标点,这个不难理解吧,我们继续!

     1     /// 重置赛车 <summary>
     2     /// 重置赛车
     3     /// </summary>
     4     private void RecoverCar()
     5     {
     6         //获取距离最近的路标点
     7         WaypointsModel ClosestWP = GetClosestWP(WaypointsModelAll, transform.position);
     8 
     9         //置赛车位置
    10         transform.position = ClosestWP.Position;
    11 
    12         //置车头朝向
    13         transform.rotation = Quaternion.LookRotation(ClosestWP.Rotation * Vector3.forward);
    14 
    15         //移动速度归零
    16         rigidbody.velocity = Vector3.zero;
    17 
    18         //角速度归零
    19         rigidbody.angularVelocity = Vector3.zero;
    20     }

    这个方法更简单了是吧!

    获取到最近的路标点后在设置赛车的位置朝向,归零参数即可

    这样做的确而已复位了,但是运行游戏跑一局发现还是有一些小问题

    什么问题呢?你的赛车明明跑到某路标点之前了,但是复位之后,居然倒退到这个路标点的位置了

    不知道我这么说能不能理解,如果不理解马上运行你的游戏跑一局试试就知道了

    那我们要怎么解决这个问题呢

    当我们复位的时候,赛车不仅仅是复位到赛道中央,还缩短了一段距离

    为了解决这个问题,我们在写一个新的方法,并且修改刚才写的代码,如下:

     1     /// 重置赛车 <summary>
     2     /// 重置赛车
     3     /// </summary>
     4     private void RecoverCar()
     5     {
     6         //获取距离最近的路标点
     7         WaypointsModel ClosestWP = GetClosestWP(WaypointsModelAll, transform.position);
     8 
     9         //下个路标点索引
    10         int nextIndex = ClosestWP.Index + 1;
    11 
    12         //最近路标点
    13         Vector3 nearestPoint;
    14 
    15         //下一个复位点索引 小于 路标点数量 - 1
    16         if (nextIndex < WaypointsModelAll.Count - 1)
    17         {
    18             //获取两个路标点间离赛车最近的点
    19             nearestPoint = NearestPoint(
    20                 ClosestWP.Position,
    21                 WaypointsModelAll[nextIndex].Position, 
    22                 transform.position);
    23         }
    24         else
    25         {
    26             //最后一个点和起点之间时取最后一个点的位置
    27             nearestPoint = WaypointsModelAll[WaypointsModelAll.Count - 1].Position;
    28         }
    29 
    30         transform.position = nearestPoint;
    31         transform.rotation = Quaternion.LookRotation(ClosestWP.Rotation * Vector3.forward);
    32         rigidbody.velocity = Vector3.zero;
    33         rigidbody.angularVelocity = Vector3.zero;
    34     }
    35 
    36     /// 获取两点之间离赛车的最近点 <summary>
    37     /// 获取两点之间离赛车的最近点
    38     /// </summary>
    39     /// <param name="lineStart">最近路标点</param>
    40     /// <param name="lineEnd">下一个路标点</param>
    41     /// <param name="point">赛车位置</param>
    42     /// <returns></returns>
    43     private Vector3 NearestPoint(Vector3 lineStart, Vector3 lineEnd, Vector3 point)
    44     {
    45         //线方向
    46         Vector3 lineDirection = Vector3.Normalize(lineEnd - lineStart);
    47 
    48         //最近点
    49         float closestPoint = Vector3.Dot((point - lineStart), lineDirection);
    50 
    51         //返回最近点
    52         return lineStart + (closestPoint * lineDirection);
    53     }

    思路看下图:

    ok,现在保存代码,在运行游戏复位试试

    怎么样,是不是会自动计算出最近的点了!

    复位点功能就这样轻松实现了

    我的游戏中是不需要计算出最近的点,只需要得到最近的路标点位置就可以了

    所以具体的实现方案按照你的需求来做,这里我提供的仅仅是思路

    先发布这篇文章到首页,每发一次首页都要间隔六小时比较蛋疼

    我在写两篇关于赛车游戏的检测文章,一会儿直接把地址贴到这篇文章中

    复位点优化以及其他功能地址:http://www.cnblogs.com/shenggege/p/4295986.html 

    文中不足之处欢迎批评指正,如果本文对你有帮助请点一下右下角的推荐

    本文链接:http://www.cnblogs.com/shenggege/p/4295617.html

  • 相关阅读:
    使用MyBatis时接收值和返回值选择Map类型或者实体类型
    如何在开发时部署和运行前后端分离的JavaWeb项目
    6月22日项目CodeReview问题及总结
    【转载】CSRF攻击及其应对之道
    【转载】MySQL事务以及SELECT ... FOR UPDATE的使用
    win10打开SQLServer, SQL Server 配置管理器
    iframe标签和frame标签异同
    8款让你耳目一新的软件开发工具
    快速开发平台的比较
    CSDN:Java Web 开发平台 WebBuilder 专访
  • 原文地址:https://www.cnblogs.com/shenggege/p/4295617.html
Copyright © 2020-2023  润新知