网页资讯视频图片知道文库贴吧地图采购
进入贴吧全吧搜索

 
 
 
日一二三四五六
       
       
       
       
       
       

签到排名:今日本吧第个签到,

本吧因你更精彩,明天继续来努力!

本吧签到人数:0

一键签到
成为超级会员,使用一键签到
一键签到
本月漏签0次!
0
成为超级会员,赠送8张补签卡
如何使用?
点击日历上漏签日期,即可进行补签。
连续签到:天  累计签到:天
0
超级会员单次开通12个月以上,赠送连续签到卡3张
使用连续签到卡
01月15日漏签0天
unity3d吧 关注:116,871贴子:562,161
  • 看贴

  • 图片

  • 吧主推荐

  • 视频

  • 游戏

  • 1 2 下一页 尾页
  • 46回复贴,共2页
  • ,跳到 页  
<<返回unity3d吧
>0< 加载中...

关于FPS游戏开发的一些个人理解(2)

  • 只看楼主
  • 收藏

  • 回复
  • 影随我殇化为劫
  • Collider
    7
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
因为大号登录不上,只能建个新帖继续谈谈个人对Unity3D中fps游戏开发的一些见解,觉得不对的欢迎大家来怼。
原贴地址:http://tieba.baidu.com/p/4112821232?pn=2


  • 影随我殇化为劫
  • Collider
    7
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
关于源码的问题,本帖只简单介绍一些开发技巧和细节,之后lz会推出一系列视频教程,详细讲解该如何开发一款成熟,高效的射击游戏,欢迎大家加QQ群: 146025605 进行技术交流。


2026-01-15 04:32:20
广告
不感兴趣
开通SVIP免广告
  • 影随我殇化为劫
  • Collider
    7
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
要开发一款完整的FPS游戏,除了射击算法以外,在联机游戏中我们需要给玩家提供服务器,在单机游戏中我们需要给玩家提供有趣的AI,这就需要用到我们的游戏服务端开发与游戏AI的开发,包括提前设定的硬编码AI与进行人类行为模拟的机器学习,而一款大游戏最重要一点就是优化,所以我们需要拥有一套完善的数据结构,还有一些可以给游戏本身大大加分的操作,诸如场景物体破坏,场景物理模拟等,都在我们本次讨论的范畴内。
开发使用的引擎版本为Unity 2017.3f3,本次版本更新提供了一些十分重要的物理系统的优化,可以让我们的游戏性能大大提升,所以我们选择发帖时最新版本为开发默认版本。


  • 零下36的冰
  • Animator
    9
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
支持支持


  • 影随我殇化为劫
  • Collider
    7
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
在理解了多线程的用处以后,接下来就是数据结构了,除了刚才提到的concurrent数据结构以外,我们常用的非线程安全的数据结构有LinkedList, Stack, List, Dictionary等等,LinkedList属于双向链表,具体使用方法可以查阅微软官方文档,Dictionary我们可以用来缓存数据库信息,如玩家信息,子弹信息等,这些都是较为简单的


  • 影随我殇化为劫
  • Collider
    7
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
度娘吞楼,补上上一层:在unity中由于无法在分线程调用API,只能在分线程中使用数据类型如Vector3等,因此我们可以把较为复杂的数学运算,迭代运算等放到分线程里进行计算,而通过委托将需要调用API的任务堆到线程安全的容器中,等待主线程的调用,这里给出一段示例代码,使用.Net4.x新出的高效,方便的Task而不是老的Thread,可以大幅度提高线程调用效率:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Concurrent;
using System;
using System.Threading;
using System.Linq;
using System.Threading.Tasks;
public class Loom : MonoBehaviour
{
private static Loom _current;
public static bool initialized {
get {
return _initialized;
}
}
public static Loom Current {
get {
Initialize ();
return _current;
}
}
void Awake ()
{
if (_current) {
Destroy (this);
return;
}
_current = this;
_initialized = true;
updateLink = new ConcurrentQueue<Action> ();
fixedUpdateLink = new ConcurrentQueue<Action> ();
}
void OnDestroy ()
{
_current = null;
_initialized = false;
}
public static void Sleep (int millisecond)
{
Thread.Sleep (millisecond);
}
static bool _initialized;
public static void Initialize ()
{
if (!_initialized && Application.isPlaying) {
_initialized = true;
GameObject g = new GameObject ("Loom");
_current = g.AddComponent<Loom> ();
}
}
/*
* 在分线程内调用该函数
* 将需要用到unity API的代码堆到主线程
*
*/
public static void QueueOnUpdate (Action action)
{
updateLink.Enqueue (action);
}
public static void QueueOnFixedUpdate (Action action)
{
fixedUpdateLink.Enqueue (action);
}
public static async void RunThread (Action a)
{
Task.Run (a);
}
public static void WaitAll (params Action[] actions)
{
Task[] tasks = new Task[actions.Length];
for (int i = 0; i < tasks.Length; ++i) {
using (Task t = Task.Run (actions [i])) {
tasks [i] = t;
}
}
Task.WaitAll (tasks);
}
public static void WaitAny (Action[] actions)
{
Task[] tasks = new Task[actions.Length];
for (int i = 0; i < tasks.Length; ++i) {
using (Task t = Task.Run (actions [i])) {
tasks [i] = t;
}
}
Task.WaitAny (tasks);
}
static ConcurrentQueue<Action> updateLink = new ConcurrentQueue<Action> ();
static ConcurrentQueue<Action> fixedUpdateLink = new ConcurrentQueue<Action> ();
void FixedUpdate ()
{
Action a;
while (fixedUpdateLink.TryDequeue (out a)) {
a ();
}
}
void LateUpdate ()
{
Action a;
while (updateLink.TryDequeue (out a)) {
a ();
}
}
}


  • 影随我殇化为劫
  • Collider
    7
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
NPC AI的编写:可以说第一人称视角是最接近现实的,AI主要分为两部分,较为初级的硬编码AI和进阶的机器学习,首先来说一下硬编码AI,所谓硬编码,就是指使用行为树,状态机等代码实现的AI,行为都是可预知的,由游戏设计师设计的。一个NPC的AI一定会满足“输入-->思考-->行为”这三部分,比如这里的这幅图,我们假设绿色球为NPC,而红色球为玩家:

即使AI的背后是程序控制,是上帝视角,时刻知道玩家位置,他也不应该像开透视挂一样直接冲过去打死玩家,也应该加上一个思考时间,所以我们需要模拟的是一个视锥体,从而给NPC一个感知,一般距离越远感知时间越长(需要花掉更多时间),角度偏差越大,感知时间越长。比方说这幅图内,玩家距离NPC我们假设是10m,NPC面朝前方,玩家大概在NPC右侧40度左右,我们就可以通过计算NPC方向和两者距离两向量(注意化为单位向量)的点积和距离向量的模长来给出一个NPC反映时间,而这些感知都是可以使用分线程来计算,最后再同步到主线程的。


  • 影随我殇化为劫
  • Collider
    7
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
那么真实的场景肯定是错综复杂的,而不是一个方形或者圆形,因此我们需要考虑遮挡问题,比如这里两玩家之间有个墙,而很显然NPC作为上帝视角拥有者是知道玩家在墙后的,所以我们可以使用Physics.Raycast或者Physics.SphereCast来进行射线检测(不知道的同学自行查文档吧),如果两者之间无遮挡,NPC可以直接向玩家开枪,否则NPC这里可以做出决策,比如通过一个0-1的随机数,当随机大于0.5时去墙后看看,否则在其他地方转悠,这就是一个较为简单的有限状态机的实现


2026-01-15 04:26:20
广告
不感兴趣
开通SVIP免广告
  • 影随我殇化为劫
  • Collider
    7
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼

补上图


  • 红毛僵尸
  • Script
    11
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
大佬,请继续


  • 影随我殇化为劫
  • Collider
    7
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
接下来就是较为复杂的行为树系统,就像二叉树一样,行为树本身也是由逻辑判断+行为节点组成,在人类的大脑中,由数亿神经元组成网络,其层数多达11层,非常复杂,其中逻辑判断是神经网络重要的一个功能。这里给出一段伪代码,简单的讲述了行为树的一个基本操作:
Switch(Behave):
case 站立:
通过视觉侦测敌人方向(采用越远越难发现,越偏越难发现的原则,切换到怀疑状态)
通过听觉侦测敌人方向(靠近时听脚步声确定位置,远处时听诸如枪声或打碎物品的声音判断敌人出现的最后位置,听到后切换到怀疑状态)
通过触觉侦测敌人位置(敌人特别接近时切换状态到攻击状态)
case 巡逻:
在提前设置好的几个点之间移动,移动结束后切换回站立状态
case 怀疑:
较慢的速度前往事件发生的点(如玩家开枪的点),如发现敌人,切换到攻击状态,否则切换到巡逻或站立。
case 攻击:
利用周边掩体,与敌人对射,如敌人消失,切换到追逐状态,如敌人死亡,切换到巡逻状态。
case 追逐:
跑步追逐敌人,若消失时间太长,切换到怀疑状态,若距离小于一定值,切换到攻击状态。
这段利用一个有限状态机表现的一个行为树系统,反映了各个状态之间的切换,实际状态一般会复杂的多,不过原理大致如此


  • 影随我殇化为劫
  • Collider
    7
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
机器学习是较为高阶的AI,通过在服务端搭建图形工作站,或在开发者的机器上进行训练,然后将已经训练好的AI给玩家,这里给出本人的强化学习环境安装教程:
https://www.bilibili.com/video/av17127696/
以及视频中用到的机器学习的下载地址:
https://pan.baidu.com/s/1cmAP2m


  • 影随我殇化为劫
  • Collider
    7
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
接下来呢说一下服务端这一块的一个设计思路,假设我们的游戏采用C/S架构,服务端的作用就主要是将其他玩家信息,场景信息传递给每一个玩家,首先,最最基本的一个原则就是,在服务端与客户端高频交流时尽量避免使用TCP,无论信息是否要求可靠,都尽量避免使用TCP而是使用UDP,若信息要求可靠,我们可以在应用层中实现可靠传输,而不是依赖于TCP的可靠传输,因为TCP的时序对游戏信息的动态更新是很不利的,丢包率5%左右延迟就已经非常高了,而可靠UDP实现在20%丢包率时延迟都不高。所以我们首先来讲一下如何使用可靠的UDP


  • 影随我殇化为劫
  • Collider
    7
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
晚些写点代码再更吧,有点累


2026-01-15 04:20:20
广告
不感兴趣
开通SVIP免广告
  • damage
  • Animator
    9
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
好帖顶了


登录百度账号

扫二维码下载贴吧客户端

下载贴吧APP
看高清直播、视频!
  • 贴吧页面意见反馈
  • 违规贴吧举报反馈通道
  • 贴吧违规信息处理公示
  • 1 2 下一页 尾页
  • 46回复贴,共2页
  • ,跳到 页  
<<返回unity3d吧
分享到:
©2026 Baidu贴吧协议|隐私政策|吧主制度|意见反馈|网络谣言警示