unity3d-游戏实战突出重围,第四天 添加角色

1:添加unity自带的第一人称角色控制器,命名为hreo

2:添加第三人称角色控制器。这里是添加源文件Sources下面的。如箭头指示:而不是“3rd Person Controller”。并命名为NPC。并设置预设,和加上BOX碰撞器。产生多个NPC。结构图:

3:修改hreo自带的Mouse Look脚本

   

 1 using UnityEngine;
 2 using System.Collections;
 3 
 4 /// MouseLook rotates the transform based on the mouse delta.
 5 /// Minimum and Maximum values can be used to constrain the possible rotation
 6 
 7 /// To make an FPS style character:
 8 /// - Create a capsule.
 9 /// - Add the MouseLook script to the capsule.
10 ///   -> Set the mouse look to use LookX. (You want to only turn character but not tilt it)
11 /// - Add FPSInputController script to the capsule
12 ///   -> A CharacterMotor and a CharacterController component will be automatically added.
13 
14 /// - Create a camera. Make the camera a child of the capsule. Reset it's transform.
15 /// - Add a MouseLook script to the camera.
16 ///   -> Set the mouse look to use LookY. (You want the camera to tilt up and down like a head. The character already turns.)
17 [AddComponentMenu("Camera-Control/Mouse Look")]
18 public class MouseLook : MonoBehaviour {
19 
20     public enum RotationAxes { MouseXAndY = 0, MouseX = 1, MouseY = 2 }
21     public RotationAxes axes = RotationAxes.MouseXAndY;
22     public float sensitivityX = 15F;
23     public float sensitivityY = 15F;
24 
25     public float minimumX = -360F;
26     public float maximumX = 360F;
27 
28     public float minimumY = -60F;
29     public float maximumY = 60F;
30 
31     float rotationY = 0F;
32 
33     //鼠标准心
34     public Texture2D tex_fire;
35 
36     void Update ()
37     {
38         if (axes == RotationAxes.MouseXAndY)
39         {
40             //float rotationX = transform.localEulerAngles.y + Input.GetAxis("Mouse X") * sensitivityX;
41             
42             //rotationY += Input.GetAxis("Mouse Y") * sensitivityY;
43             //rotationY = Mathf.Clamp (rotationY, minimumY, maximumY);
44             
45             //transform.localEulerAngles = new Vector3(-rotationY, rotationX, 0);
46         }
47         else if (axes == RotationAxes.MouseX)
48         {
49             transform.Rotate(0, Input.GetAxis("Mouse X") , 0);
50         }
51         else
52         {
53             //rotationY += Input.GetAxis("Mouse Y") * sensitivityY;
54             //rotationY = Mathf.Clamp (rotationY, minimumY, maximumY);
55             
56             transform.localEulerAngles = new Vector3(-rotationY, transform.localEulerAngles.y, 0);
57         }
58     }
59 
60     void OnGUI()
61     {
62         if (tex_fire)
63         {
64             //绘制鼠标准心
65             float x = Input.mousePosition.x - tex_fire.width / 2;
66             float y = Screen.height - Input.mousePosition.y - tex_fire.height / 2;
67 
68             GUI.DrawTexture(new Rect(x, y, tex_fire.width, tex_fire.height), tex_fire);
69         }
70     }
71 
72     void Start ()
73     {
74         // Make the rigid body not change rotation
75         if (GetComponent<Rigidbody>())
76             GetComponent<Rigidbody>().freezeRotation = true;
77 
78         //取消鼠标默认状态
79         Screen.showCursor = false;
80     }
81 }

5 :编写脚本命名为dr.cs绑定到NPC上

 1 using UnityEngine;
 2 using System.Collections;
 3 
 4 public class dr : MonoBehaviour
 5 {
 6 
 7     //是否绘制敌人血条
 8     bool showBlood = false;
 9     //血条资源贴图
10     public Texture2D tex_red;
11     public Texture2D tex_black;
12     //生命值
13     private int HP = 100;
14     //主角对象
15     private GameObject hero;
16     // Use this for initialization
17     void Start()
18     {
19         hero = GameObject.Find("Hero");
20     }
21 
22     // Update is called once per frame
23     void Update()
24     {
25         //设置始终朝向
26         transform.LookAt(hero.transform);
27     }
28 
29     void OnGUI()
30     {
31         if (showBlood)
32         {
33             //绘制敌人血条
34             int blood_widht = tex_red.width * HP / 100;
35             GUI.DrawTexture(new Rect(5, 5, tex_black.width, tex_black.height), tex_black);
36             GUI.DrawTexture(new Rect(5, 5, blood_widht, tex_red.height), tex_red);
37         }
38     }
39 
40     /// <summary>
41     /// 当鼠标在GUIElement(GUI元素)或Collider(碰撞体)上点击时调用OnMouseDown。
42     /// </summary>
43     void OnMouseDown()
44     {
45         //敌人击中目标
46         if (HP > 0)
47         {
48             //减血
49             HP -= 5;
50             //击打回馈
51         }
52     }
53     /// <summary>
54     /// 当用户释放鼠标按钮时调用OnMouseUp。
55     /// </summary>
56     void OnMouseUp()
57     {
58         //击打敌人后移动一段距离
59         transform.Translate(Vector3.back * 0.1f);
60     }
61     /// <summary>
62     /// 当鼠标悬浮在GUIElement(GUI元素)或Collider(碰撞体)上时调用 OnMouseOver 。
63     /// </summary>
64     void OnMouseOver()
65     {
66         //当对着敌人时,开始绘制血条,即显示敌人当前的血条
67         showBlood = true;
68 
69     }
70     /// <summary>
71     /// 当Collider(碰撞体)停止触发trigger(触发器)时调用OnTriggerExit。
72     /// </summary>
73     void OnMouseExit()
74     {
75         //结束绘制血条
76         showBlood = false;
77     }
78 }

7:dr.cs脚本实现了。当鼠标指向敌人时,显示敌人当前的血条情况,

当击中敌人时候。敌人会后退几步。

dr.cs脚本升级:敌人AI即人工智能

 实现功能:让NPC有自己的生命周期:就是自己巡逻。当在巡逻范围内看到hero,即跑向hero开始攻击(这里暂为实现)

 1 using UnityEngine;
 2 using System.Collections;
 3 
 4 public class drAI : MonoBehaviour
 5 {
 6 
 7     //敌人状态
 8 
 9 
10     //敌人站立状态
11     public const int STATE_STAND = 0;
12     //敌人行走状态
13     public const int STATE_WALK = 1;
14     //敌人奔跑状态
15     public const int STATE_RUN = 2;
16     //记录敌人的当前状态
17     private int enemyState;
18     //主角对象
19     private GameObject hero;
20     //备份上一次的敌人思考时间
21     private float backUptime;
22     //敌人思考下一次行为的时间
23     public const int AI_THINK_TIME = 2;
24     //敌人的巡逻范围
25     public const int AI_ATTACK_DISTANCE = 10;
26 
27 
28     // Use this for initialization
29     void Start()
30     {
31         //得到主角对象
32         hero = GameObject.Find("/Hero");
33         //设置敌人的默认状态为站立
34         enemyState = STATE_WALK;
35     }
36 
37     // Update is called once per frame
38     void Update()
39     {
40         //判断敌人与主角的距离 当在巡逻范围内
41         if (Vector3.Distance(transform.position, hero.transform.position) < AI_ATTACK_DISTANCE)
42         {
43             //敌人进入奔跑状态
44             gameObject.animation.Play("run");
45             enemyState = STATE_RUN;
46             //设置敌人面朝主角方向
47             transform.LookAt(hero.transform);
48         }
49             //敌人进入巡逻状态
50         else
51         { 
52             //计算敌人的思考时间
53             if (Time.time - backUptime >= AI_THINK_TIME)
54             {
55                 //敌人开始思考
56                 backUptime = Time.time;
57                 //取得0~2之间的随机数
58                 int rand = Random.Range(0, 2);
59                 if (rand == 0)
60                 {
61                     //敌人进入站立状态
62                     gameObject.animation.Play("idle");
63                     enemyState = STATE_STAND;
64                 }
65                 else if (rand == 1)
66                 {
67                     //敌人进入行走状态
68                     //敌人随机旋转角度
69                     Quaternion rotate = Quaternion.Euler(0, Random.Range(1, 5) * 90, 0);
70                     //1秒内完成敌人旋转
71                     transform.rotation = Quaternion.Slerp(transform.rotation, rotate, Time.deltaTime * 1000);
72                     //播放行走动画
73                     gameObject.animation.Play("walk");
74                     enemyState = STATE_WALK;
75                 }
76             }
77         }
78         switch (enemyState)
79         {
80             case STATE_STAND: break;
81             case STATE_WALK:
82                 //敌人行走
83                 transform.Translate(Vector3.forward * Time.deltaTime);
84                 break;
85             case STATE_RUN:
86                 //敌人朝向主角奔跑
87                 if (Vector3.Distance(transform.position, hero.transform.position) > 3)
88                 {
89                     transform.Translate(Vector3.forward * Time.deltaTime * 3);
90                 }
91                 break;
92             default:
93                 break;
94         }
95     }
96 }

 知识点:

    Quaternion四元素表示旋转。Quaternion.Euler()方法返回一个旋转的四元素。该方法参数表示旋转的三维角度。执行该方法后,将

四元素赋值给一个对象的旋转变量

transform.rotation = rotate

即可在一帧内完成旋转,若想在一段时间内完成旋转,就需要用到
Quaternion.Slerp()方法:
第一个参数表示模型旋转的起始角度
第二参数表示模型的结束角度
第三个参数表示旋转消耗的时间
原文地址:https://www.cnblogs.com/niboy/p/4264504.html