• 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()方法:
    第一个参数表示模型旋转的起始角度
    第二参数表示模型的结束角度
    第三个参数表示旋转消耗的时间
  • 相关阅读:
    Java代码检测工具
    java编程工具
    100-days: The one day
    前端书籍整理
    vue 学习笔记(二)
    从零开始写一个npm包及上传
    Vue Baidu Map 插件的使用
    对数组对象进行过滤
    使用css方法使footer保持在页面的最底部
    判断是第一次打开界面?还是刷新
  • 原文地址:https://www.cnblogs.com/niboy/p/4264504.html
Copyright © 2020-2023  润新知