游戏人工智能(AI)开发(二)

是不是被上节的理论知识弄到头大?怀念使用 unity 的日子吧?哈哈……这节开始我们就要用以前学到的知识在unity中应用啦。今天我们先做一个简单的你追我跑的智能逻辑。程序的功能大概是这样的,场景中有一个角色和N个敌人。N个敌人根据角色的位置判断自己是该停止还是该躲避(逃跑)。如果角色距离某一个敌人距离小于该角色害怕(开始逃避)的距离,则敌人开始逃跑。否则,敌人保持站立。

1. 首先新建一个场景,在场景中新建一个Plane,命名为floor作为地面,然后创建一个点光源,调节点光源的位置和范围,照亮整个场景(这里作为我们教程的标配场景,以后新建一个场景如无特别说明,都以此场景为准)。完成场景如图:
 

2.导入所需要的敌人和角色的模型,这里提一点大家导入模型的时候注意的,在导模型的时候,一定先把模型贴图导进来,也就是拷贝到工程目录下。然后再拷贝模型,这样就不会出现贴图丢失的问题了。模型大家可以自己做也可以上网找,需要有两个动画状态的文件,一个是静止站立(idle)的,一个是跑步(run)。这里的动画设置问题,大家可以参考论坛的公开课教学。我就不多说了。

3.把导入的模型拖到场景中,为它们添加角色控制器代码(CharacterController),如果找不到这个脚本,说明你没有导入角色控制器插件包,在工程视图点击右键,import package-->Character Controller。注意把这个代码添加到所有的需要运动的角色身上,这里指一个角色模型,和N个敌人的模型。现在万事具备,只差让他们动起来了。场景完成如图:这里灰色的机器人是我们能够控制的角色,四个红色的机器人是敌人角色。  

4.由于角色运动是需要我们控制的,而敌人的运动是根据角色的位置自动判断的。所以我们只需要编写控制角色移动的代码即可。
首先我们要考虑角色移动方式,这里角色主要根据玩家按键是前后移动,并在移动的同时播放跑步动画。
首先是控制动画播放,新建一个C#代码PlayerAnim_CS。它的主要功能是根据玩家按键,控制角色播放相应的动画。
首先在开始的函数中添加如下代码:animation.wrapMode = WrapMode.Loop;             //控制动画播放方式为循环播放在Update函数中,我们希望系统能够实时检测用户输入,根据用户输入播放响应动画:
      
[C#]  纯文本查看  复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
if (Input.GetAxis( "Vertical" )>0.2f)           //向前移动
        {
            animation[ "run" ].speed = 1.0f;          //动画播放速度
            animation.CrossFade( "run" );            //播放向前跑动动画
        }
        else if (Input.GetAxis( "Vertical" )<-0.2f)    //向后移动
        {
            animation[ "run" ].speed = -1.0f;
            animation.CrossFade( "run" );
        }
        else
        {
            animation.CrossFade( "idle" );    //静止状态
        }
    }


5. 控制角色前后移动,新建一个C#代码RobotController_CS 定义变量:
   
[C#]  纯文本查看  复制代码
?
1
2
3
public int speed = 6;
    public int gravity = 20;
    private Vector3 moveDirection = Vector3.zero;

    
然后在FixedUpdate中添加如下方法:
   
[C#]  纯文本查看  复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
void FixedUpdate()
     {
         CharacterController controller = GetComponent<CharacterController>();
         if (controller.isGrounded)
         {
         //只计算Z轴方向的位移
         //也可以根据需要控制左右移动,现在为了简单考虑,我们没有做左右移动的控制
             moveDirection = new Vector3(0, 0, Input.GetAxis( "Vertical" ));
             moveDirection = transform.TransformDirection(moveDirection);
//叠加移动速度,以便我们能在编辑器窗口中控制角色移动速度。
             moveDirection *= speed;
         }
//根据鼠标X轴向,控制角色左右旋转
         float rotateY = (Input.GetAxis( "Mouse X" ) * 200) * Time.deltaTime;
         controller.transform.Rotate(0, rotateY, 0);
         moveDirection.y -= gravity * Time.deltaTime;
         controller.SimpleMove(moveDirection * Time.deltaTime);
 
     }

到现在为止,我们已经完成了角色的控制方法,把PlayerAnim_CS和RobotController_CS 添加给角色,并确保角色已经添加了CharacterController。点击运行,按下上下方向键或者W、S键,即可看到角色已经动起来了。

6.大家可能已经发现,现在只有角色自己在动,场景中其他的敌人并没有运动。我们来为敌人角色添加代码,让他们能够感知到角色的位置,并及时作出逃跑的动作。新建C#代码NeutralBot_CS。定义如下变量:

[C#]  纯文本查看  复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
public float awareDistance = 15.0f;   //敌人意识到角色的距离
     public float scaredDistance = 10.0f;   //敌人开始逃跑的距离
     public Transform player;     //角色
 
     public float runSpeed = 4.0f;  //逃跑速度
 
     public enum AIStatus { Idle=0,Scared=1}   //敌人状态,静止和害怕
 
     private AIStatus status = AIStatus.Idle;
 
     CharacterController controller;  //敌人本身的角色控制器
 
     private Vector3 moveDirection = Vector3.zero; 


首先在Awake函数中获取敌人的角色控制器 controller = GetComponent<CharacterController>();
在update函数中,我们首先要判断敌人当前所处状态,然后根据状态作出相应反应
[C#]  纯文本查看  复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
void  Update()
{
CheckStatus();   //检查角色状态的函数
 
         switch (status)          //根据不同状态作出相应行动
         {
             case AIStatus.Idle:      //静止
                 Idle();
                 break ;
             case AIStatus.Scared:    //逃跑
                 RunAway();
                 break ;
             default :
                 break ;
         }
 
}
 
//逃跑方法
private void RunAway()
     {
         transform.eulerAngles = new Vector3(transform.eulerAngles.x,  -player.transform.eulerAngles.y,transform.eulerAngles.z);
         moveDirection = new Vector3(0, 0, 40);
         moveDirection = transform.TransformDirection(moveDirection);
         moveDirection *= runSpeed;
         controller.SimpleMove(moveDirection * Time.deltaTime);
 
         animation.CrossFade( "run" );
     }
//静止方法
     private void Idle()
     {
         animation.CrossFade( "idle" );
     }
 
//根据自身和角色的距离,判断出自己是该逃跑还是该静止。
     private void CheckStatus()
     {
         float dist = (player.position - transform.position).magnitude;
 
         if (dist<scaredDistance)
         {
             status = AIStatus.Scared;
         }
         else if (dist>awareDistance)
         {
             status = AIStatus.Idle;
         }
 
     }



确保编译没有错误,将NeutralBot_CS代码添加到敌人物体这里指四个红色机器人身上,保存场景,运行程序。可以按下W键向前跑动机器人查看效果。最终结果如图:


 

本节我们通过一个实例讲解了如何通过距离判断角色运动状态的方法,并学习了播放动画的方式,动画播放速度控制等知识。大家可以自己做一个追击的小demo试验一下。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值