zoukankan      html  css  js  c++  java
  • AI 学习

    极简状态机:

     1 /*
     2 脚本名称:
     3 脚本作者:
     4 建立时间:
     5 脚本功能:
     6 版本号:
     7 */
     8 using UnityEngine;
     9 using System.Collections;
    10 
    11 namespace VoidGame {
    12 
    13     public class Player : MonoBehaviour {
    14 
    15         /// <summary>
    16         /// 移动速度
    17         /// </summary>
    18         public float m_moveSpeed = 10.0f;
    19 
    20         private void Update() {
    21             Move();
    22         }
    23 
    24         private void Move() {
    25             Vector3 direction = Vector3.zero;
    26             if(Input.GetKey(KeyCode.W)) {
    27                 direction = transform.forward;
    28             }
    29             if(Input.GetKey(KeyCode.S)) {
    30                 direction = -transform.forward;
    31             }
    32             if(Input.GetKey(KeyCode.A)) {
    33                 direction = -transform.right;
    34             }
    35             if(Input.GetKey(KeyCode.D)) {
    36                 direction = transform.right;
    37             }
    38             transform.Translate(direction * Time.deltaTime * m_moveSpeed,Space.World);
    39         }
    40     }
    41 }
    Player
      1 /*
      2 脚本名称:
      3 脚本作者:
      4 建立时间:
      5 脚本功能:
      6 版本号:
      7 */
      8 using UnityEngine;
      9 using UnityEngine.UI;
     10 using System.Collections;
     11 
     12 namespace VoidGame {
     13 
     14     /// <summary>
     15     /// 状态
     16     /// </summary>
     17     public enum FSMState {
     18         /// <summary>
     19         /// 巡逻
     20         /// </summary>
     21         Patrol,
     22         /// <summary>
     23         /// 追逐
     24         /// </summary>
     25         Chase,
     26         /// <summary>
     27         /// 攻击
     28         /// </summary>
     29         Attack,
     30         /// <summary>
     31         /// 死亡
     32         /// </summary>
     33         Dead
     34     }
     35 
     36     public class Enemy : MonoBehaviour {
     37 
     38         /// <summary>
     39         /// 玩家
     40         /// </summary>
     41         public Transform m_player;
     42 
     43         /// <summary>
     44         /// 路标列表
     45         /// </summary>
     46         public Transform[] m_waypoints;
     47         /// <summary>
     48         /// 目标路标索引
     49         /// </summary>
     50         private int m_targetWaypointIndex;
     51 
     52         /// <summary>
     53         /// 移动速度
     54         /// </summary>
     55         public float m_moveSpeed = 0.1f;
     56 
     57         /// <summary>
     58         /// 状态
     59         /// </summary>
     60         public FSMState m_fsmState;
     61 
     62         /// <summary>
     63         /// 和玩家的距离
     64         /// </summary>
     65         public float m_distance;
     66 
     67         /// <summary>
     68         /// 追逐距离
     69         /// </summary>
     70         private float m_chaseDistance = 5f;
     71         /// <summary>
     72         /// 攻击距离
     73         /// </summary>
     74         private float m_attackDistance = 2f;
     75 
     76         [Space(10)]
     77         public Text m_text;
     78 
     79         private void Start() {
     80             //初始状态:巡逻
     81             m_fsmState = FSMState.Patrol;
     82             //设置初始目标路标索引
     83             m_targetWaypointIndex = 0;
     84         }
     85 
     86         private void Update() {
     87             //根据状态切换
     88             switch(m_fsmState) {
     89             case FSMState.Patrol:
     90                 UpdatePatrolState();
     91                 break;
     92             case FSMState.Chase:
     93                 UpdateChaseState();
     94                 break;
     95             case FSMState.Attack:
     96                 UpdateAttackState();
     97                 break;
     98             case FSMState.Dead:
     99                 break;
    100             }
    101 
    102             DisplayDistance();
    103         }
    104 
    105         private void OnDrawGizmos() {
    106             //画自身的前方向
    107             iTween.DrawLine(new Vector3[] { transform.position,transform.position + transform.forward },Color.yellow);
    108 
    109             //根据状态画和玩家之间的关联线
    110             switch(m_fsmState) {
    111             case FSMState.Patrol:
    112                 
    113                 break;
    114             case FSMState.Chase:
    115                 DrawLine(Color.green);
    116                 break;
    117             case FSMState.Attack:
    118                 DrawLine(Color.red);
    119                 break;
    120             case FSMState.Dead:
    121                 break;
    122             }
    123             
    124 
    125         }
    126 
    127         /// <summary>
    128         /// 更新巡逻状态
    129         /// </summary>
    130         private void UpdatePatrolState() {
    131             if(!IsArrived()) {
    132                 Move(m_waypoints[m_targetWaypointIndex]);
    133             }
    134             if(CalculateDistance() <= m_chaseDistance) {
    135                 m_fsmState = FSMState.Chase;
    136             }
    137         }
    138 
    139         /// <summary>
    140         /// 更新追逐状态
    141         /// </summary>
    142         private void UpdateChaseState() {
    143             Move(m_player);
    144             //小于等于攻击距离,攻击
    145             if(CalculateDistance() <= m_attackDistance) {
    146                 m_fsmState = FSMState.Attack;
    147             //大于攻击距离并且小于等于追逐距离,追逐
    148             } else if(CalculateDistance() > m_attackDistance && CalculateDistance() <= m_chaseDistance) {
    149                 m_fsmState = FSMState.Chase;
    150             //其余情况也就是大于追逐距离,巡逻
    151             } else {
    152                 m_fsmState = FSMState.Patrol;
    153             }
    154         }
    155 
    156         /// <summary>
    157         /// 更新攻击状态
    158         /// </summary>
    159         private void UpdateAttackState() {
    160             //大于攻击距离并且小于等于追逐距离,追逐
    161             if(CalculateDistance() > m_attackDistance && CalculateDistance() <= m_chaseDistance) {
    162                 m_fsmState = FSMState.Chase;
    163             //大于追逐距离,巡逻
    164             } else if(CalculateDistance() > m_chaseDistance) {
    165                 m_fsmState = FSMState.Patrol;
    166             }
    167         }
    168 
    169         private void UpdateDeadState() {
    170 
    171         }
    172 
    173         /// <summary>
    174         /// 画和玩家之间的线
    175         /// </summary>
    176         private void DrawLine(Color color) {
    177             iTween.DrawLine(new Transform[] { transform,m_player.transform },color);
    178         }
    179 
    180         /// <summary>
    181         /// 显示玩家的距离
    182         /// </summary>
    183         private void DisplayDistance() {
    184             float distance = Vector3.Distance(transform.position,m_player.position);
    185             m_text.text = "State:"+m_fsmState+"
    Distance:"+ distance.ToString();
    186         }
    187 
    188         /// <summary>
    189         /// 计算和玩家的距离
    190         /// </summary>
    191         private float CalculateDistance() {
    192             return Vector3.Distance(transform.position,m_player.position);
    193         }
    194         
    195         /// <summary>
    196         /// 是否到达路标
    197         /// </summary>
    198         private bool IsArrived() {
    199             float distance = Vector3.Distance(transform.position,m_waypoints[m_targetWaypointIndex].position);
    200             if(distance < 0.1f) {
    201                 m_targetWaypointIndex++;
    202                 m_targetWaypointIndex = m_targetWaypointIndex % 4;
    203                 return true;
    204             }
    205             return false;
    206         }
    207 
    208         private void Move(Transform target) {
    209             transform.LookAt(target);
    210             transform.Translate(transform.forward * Time.deltaTime * m_moveSpeed,Space.World);
    211         }
    212     }
    213 }
    Enemy

    视频:https://pan.baidu.com/s/1mioIk6c

    项目:https://pan.baidu.com/s/1cpc9T8

    SlotMachineWeighted

      1 using UnityEngine;
      2 using System.Collections;
      3 
      4 public class SlotMachineWeighted : MonoBehaviour {
      5     
      6     public float spinDuration = 2.0f;
      7     public int numberOfSym = 10;
      8     public GameObject betResult;
      9     
     10     private bool startSpin = false;
     11     private bool firstReelSpinned = false;
     12     private bool secondReelSpinned = false;
     13     private bool thirdReelSpinned = false;
     14     
     15     private int betAmount = 100;
     16     
     17     private int creditBalance = 1000;
     18     private ArrayList weightedReelPoll = new ArrayList();    
     19     private int zeroProbability = 30;
     20     
     21     private int firstReelResult = 0;
     22     private int secondReelResult = 0;
     23     private int thirdReelResult = 0;
     24     
     25     private float elapsedTime = 0.0f;
     26     
     27     // Use this for initialization
     28     void Start () {
     29         betResult.GetComponent<GUIText>().text = "";
     30         
     31         for (int i = 0; i < zeroProbability; i++) {
     32             weightedReelPoll.Add(0);        
     33         }
     34         
     35         int remainingValuesProb = (100 - zeroProbability)/9;
     36         
     37         for (int j = 1; j < 10; j++) {
     38             for (int k = 0; k < remainingValuesProb; k++) {
     39                 weightedReelPoll.Add(j);
     40             }
     41         }
     42     }
     43     
     44     void OnGUI() {
     45         
     46         GUI.Label(new Rect(150, 40, 100, 20), "Your bet: ");
     47         betAmount = int.Parse(GUI.TextField(new Rect(220, 40, 50, 20), betAmount.ToString(), 25));        
     48         
     49         GUI.Label(new Rect(300, 40, 100, 20), "Credits: " + creditBalance.ToString());
     50         
     51         if (GUI.Button(new Rect(200,300,150,40), "Pull Lever")) {
     52             betResult.GetComponent<GUIText>().text = "";            
     53             startSpin = true;
     54         }
     55     }
     56     
     57     void checkBet() {
     58         if (firstReelResult == secondReelResult && secondReelResult == thirdReelResult) {
     59             betResult.GetComponent<GUIText>().text = "JACKPOT!";
     60             creditBalance += betAmount * 50;
     61         }
     62         else if (firstReelResult == 0 && thirdReelResult == 0) {            
     63             betResult.GetComponent<GUIText>().text = "YOU WIN " + (betAmount/2).ToString();
     64             creditBalance -= (betAmount/2);
     65         }
     66         else if (firstReelResult == secondReelResult) {            
     67             betResult.GetComponent<GUIText>().text = "AWW... ALMOST JACKPOT!";
     68         }
     69         else if (firstReelResult == thirdReelResult) {            
     70             betResult.GetComponent<GUIText>().text = "YOU WIN " + (betAmount*2).ToString();
     71             creditBalance -= (betAmount*2);
     72         }
     73         else {
     74             betResult.GetComponent<GUIText>().text = "YOU LOSE!";
     75             creditBalance -= betAmount;
     76         }
     77     }
     78     
     79     // Update is called once per frame
     80     void FixedUpdate () {        
     81         if (startSpin) {
     82             elapsedTime += Time.deltaTime;
     83             int randomSpinResult = Random.Range(0, numberOfSym);
     84             if (!firstReelSpinned) {
     85                 GameObject.Find("firstReel").GetComponent<GUIText>().text = randomSpinResult.ToString();
     86                 if (elapsedTime >= spinDuration) {
     87                     int weightedRandom = Random.Range(0, weightedReelPoll.Count);    
     88                     GameObject.Find("firstReel").GetComponent<GUIText>().text = weightedReelPoll[weightedRandom].ToString();
     89                     firstReelResult = (int)weightedReelPoll[weightedRandom];
     90                     firstReelSpinned = true;
     91                     elapsedTime = 0;
     92                 }
     93             }
     94             else if (!secondReelSpinned) {
     95                 GameObject.Find("secondReel").GetComponent<GUIText>().text = randomSpinResult.ToString();
     96                 if (elapsedTime >= spinDuration) {
     97                     secondReelResult = randomSpinResult;
     98                     secondReelSpinned = true;
     99                     elapsedTime = 0;
    100                 }
    101             }
    102             else if (!thirdReelSpinned) {
    103                 GameObject.Find("thirdReel").GetComponent<GUIText>().text = randomSpinResult.ToString();
    104                 if (elapsedTime >= spinDuration) {                        
    105                     if ((firstReelResult == secondReelResult) &&
    106                         randomSpinResult != firstReelResult) {
    107                         //the first two reels have resulted the same symbol
    108                         //but unfortunately the third reel missed
    109                         //so instead of giving a random number we'll return a symbol which is one less than the other 2
    110                         
    111                         randomSpinResult = firstReelResult - 1;
    112                         if (randomSpinResult < firstReelResult) randomSpinResult = firstReelResult - 1;
    113                         if (randomSpinResult > firstReelResult) randomSpinResult = firstReelResult + 1;
    114                         if (randomSpinResult < 0) randomSpinResult = 0;
    115                         if (randomSpinResult > 9) randomSpinResult = 9;
    116                         
    117                         GameObject.Find("thirdReel").GetComponent<GUIText>().text = randomSpinResult.ToString();    
    118                         thirdReelResult = randomSpinResult;
    119                     }
    120                     else {
    121                         int weightedRandom = Random.Range(0, weightedReelPoll.Count);    
    122                         GameObject.Find("thirdReel").GetComponent<GUIText>().text = weightedReelPoll[weightedRandom].ToString();
    123                         thirdReelResult = (int)weightedReelPoll[weightedRandom];
    124                     }
    125                     
    126                     startSpin = false;
    127                     elapsedTime = 0;
    128                     firstReelSpinned = false;
    129                     secondReelSpinned = false;
    130                     
    131                     checkBet();
    132                 }
    133             }
    134         }
    135     }
    136 }
    SlotMachineWeighted

     极简感应器:

     

     1 /*
     2 脚本名称:
     3 脚本作者:
     4 建立时间:
     5 脚本功能:
     6 版本号:
     7 */
     8 using UnityEngine;
     9 using System.Collections;
    10 
    11 namespace VoidGame {
    12 
    13     /// <summary>
    14     /// 玩家
    15     /// </summary>
    16     public class Player : MonoBehaviour {
    17 
    18         /// <summary>
    19         /// 移动目标
    20         /// </summary>
    21         public Transform m_target;
    22 
    23         /// <summary>
    24         /// 移动速度
    25         /// </summary>
    26         public float m_moveSpeed = 10f;
    27 
    28         private void Update() {
    29             Move();
    30         }
    31 
    32         /// <summary>
    33         /// 移动
    34         /// </summary>
    35         private void Move() {
    36             if(Vector3.Distance(transform.position,m_target.position) < 1.0f) {
    37                 return;
    38             }
    39 
    40             Vector3 position = m_target.position;
    41             position.y = transform.position.y;
    42 
    43             Quaternion lookQuaternion = Quaternion.LookRotation(position - transform.position);
    44             transform.rotation = Quaternion.Slerp(transform.rotation,lookQuaternion,0.1f);
    45             transform.Translate(Vector3.forward * Time.deltaTime * 10);
    46         }
    47 
    48         private void OnDrawGizmos() {
    49             iTween.DrawLine(new Vector3[] { transform.position,transform.position + transform.forward });
    50         }
    51     }
    52 }
    Player
     1 /*
     2 脚本名称:
     3 脚本作者:
     4 建立时间:
     5 脚本功能:
     6 版本号:
     7 */
     8 using UnityEngine;
     9 using System.Collections;
    10 
    11 namespace VoidGame {
    12 
    13     /// <summary>
    14     /// 鼠标点击指示
    15     /// </summary>
    16     public class Target : MonoBehaviour {
    17 
    18         private void Update() {
    19             if(Input.GetMouseButtonDown(0)) {
    20                 Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
    21                 RaycastHit hitInfo;
    22                 if(Physics.Raycast(ray.origin,ray.direction,out hitInfo)) {
    23                     Vector3 position = hitInfo.point;
    24                     position.y = 1;
    25                     transform.position = position;
    26                 }
    27             }
    28         }
    29     }
    30 }
    Target
     1 /*
     2 脚本名称:
     3 脚本作者:
     4 建立时间:
     5 脚本功能:
     6 版本号:
     7 */
     8 using UnityEngine;
     9 using System.Collections;
    10 
    11 namespace VoidGame {
    12 
    13     /// <summary>
    14     /// 漫游
    15     /// </summary>
    16     public class Wander : MonoBehaviour {
    17 
    18         /// <summary>
    19         /// 目标位置
    20         /// </summary>
    21         private Vector3 m_targetPosition;
    22         /// <summary>
    23         /// 移动速度
    24         /// </summary>
    25         private float m_moveSpeed = 5.0f;
    26         //private float rotSpeed = 2.0f;
    27         /// <summary>
    28         /// 移动范围
    29         /// </summary>
    30         private float minX, maxX, minZ, maxZ;
    31 
    32         void Start() {
    33             minX = -20.0f;
    34             maxX = 20.0f;
    35 
    36             minZ = -20.0f;
    37             maxZ = 20.0f;
    38 
    39             GetNextPosition();
    40         }
    41 
    42         void Update() {
    43             if(Vector3.Distance(m_targetPosition,transform.position) <= 1.0f)
    44                 GetNextPosition();
    45 
    46             Vector3 position = transform.position;
    47             position.y = 0.5f;
    48 
    49             Quaternion targetRotation = Quaternion.LookRotation(m_targetPosition - position);
    50             transform.rotation = Quaternion.Slerp(transform.rotation,targetRotation,Time.deltaTime);
    51 
    52             transform.Translate(new Vector3(0,0,m_moveSpeed * Time.deltaTime));
    53         }
    54 
    55         void GetNextPosition() {
    56             m_targetPosition = new Vector3(Random.Range(minX,maxX),0.5f,Random.Range(minZ,maxZ));
    57         }
    58     }
    59 }
    Wander
     1 /*
     2 脚本名称:
     3 脚本作者:
     4 建立时间:
     5 脚本功能:
     6 版本号:
     7 */
     8 using UnityEngine;
     9 using System.Collections;
    10 
    11 namespace VoidGame {
    12 
    13     /// <summary>
    14     /// 感观
    15     /// </summary>
    16     public class Sense : MonoBehaviour {
    17 
    18         public Aspect.aspect aspectName = Aspect.aspect.Enemy;
    19 
    20         /// <summary>
    21         /// 检测频率
    22         /// </summary>
    23         public float detectionRate = 1.0f;
    24         /// <summary>
    25         /// 距上一次检测经过的时间
    26         /// </summary>
    27         protected float elapsedTime = 0.0f;
    28 
    29         /// <summary>
    30         /// 初始化
    31         /// </summary>
    32         protected virtual void Initialise() { }
    33         /// <summary>
    34         /// 更新感官
    35         /// </summary>
    36         protected virtual void UpdateSense() { }
    37 
    38         void Start() {
    39             elapsedTime = 0.0f;
    40             Initialise();
    41         }
    42         void Update() {
    43             UpdateSense();
    44         }
    45     }
    46 }
    Sense
     1 /*
     2 脚本名称:
     3 脚本作者:
     4 建立时间:
     5 脚本功能:
     6 版本号:
     7 */
     8 using UnityEngine;
     9 using System.Collections;
    10 
    11 namespace VoidGame {
    12 
    13     /// <summary>
    14     /// 视觉
    15     /// </summary>
    16     public class Perspective : Sense {
    17 
    18         /// <summary>
    19         /// 视场角度
    20         /// </summary>
    21         public int FieldOfView = 45;
    22         /// <summary>
    23         /// 视野距离
    24         /// </summary>
    25         public int ViewDistance = 100;
    26 
    27         /// <summary>
    28         /// 玩家
    29         /// </summary>
    30         private Transform playerTrans;
    31         /// <summary>
    32         /// 射线方向
    33         /// </summary>
    34         private Vector3 rayDirection;
    35 
    36         protected override void Initialise() {
    37             playerTrans = GameObject.FindGameObjectWithTag("Player").transform;
    38             aspectName = Aspect.aspect.Player;
    39         }
    40 
    41         protected override void UpdateSense() {
    42             elapsedTime += Time.deltaTime;
    43 
    44             if(elapsedTime >= detectionRate) {
    45                 //elapsedTime = 0;
    46                 DetectAspect();
    47             }
    48         }
    49 
    50         /// <summary>
    51         /// 检测切面
    52         /// </summary>
    53         void DetectAspect() {
    54             RaycastHit hit;
    55             //射线方向位从自身到玩家的方向
    56             rayDirection = playerTrans.position - transform.position;
    57 
    58             //如果自身的朝向和从自身到玩家的方向之间的夹角小于视场角度,射线检测
    59             if((Vector3.Angle(rayDirection,transform.forward)) < FieldOfView) {
    60                 if(Physics.Raycast(transform.position,rayDirection,out hit,ViewDistance)) {
    61                     Aspect aspect = hit.collider.GetComponent<Aspect>();
    62                     if(aspect != null) {
    63                         if(aspect.aspectName == aspectName) {
    64                             print("Enemy Detected");
    65                         }
    66                     }
    67                 }
    68             }
    69         }
    70 
    71         void OnDrawGizmos() {
    72 
    73             //红线连接自身和玩家
    74             Debug.DrawLine(transform.position,playerTrans.position,Color.red);
    75 
    76             //正前方射线
    77             Vector3 frontRayPoint = transform.position + (transform.forward * ViewDistance);
    78             Debug.DrawLine(transform.position,frontRayPoint,Color.green);
    79 
    80             //左前方射线
    81             Vector3 leftRayPoint = frontRayPoint;
    82             leftRayPoint.x += FieldOfView * 0.5f;
    83             Debug.DrawLine(transform.position,leftRayPoint,Color.green);
    84 
    85             //右前方射线
    86             Vector3 rightRayPoint = frontRayPoint;
    87             rightRayPoint.x -= FieldOfView * 0.5f;
    88             Debug.DrawLine(transform.position,rightRayPoint,Color.green);
    89         }
    90     }
    91 }
    Perspective
     1 /*
     2 脚本名称:
     3 脚本作者:
     4 建立时间:
     5 脚本功能:
     6 版本号:
     7 */
     8 using UnityEngine;
     9 using System.Collections;
    10 
    11 namespace VoidGame {
    12 
    13     /// <summary>
    14     /// 切面
    15     /// </summary>
    16     public class Aspect : MonoBehaviour {
    17 
    18         /// <summary>
    19         /// 角色
    20         /// </summary>
    21         public enum aspect {
    22             Player,
    23             Enemy
    24         }
    25         public aspect aspectName;
    26     }
    27 }
    Aspect

    项目:https://pan.baidu.com/s/1i581isP

    路径跟随和引导

      1 using UnityEngine;
      2 using System.Collections;
      3 
      4 /// <summary>
      5 /// 跟随脚本
      6 /// </summary>
      7 public class VehicleFollowing : MonoBehaviour 
      8 {
      9     /// <summary>
     10     /// 路径
     11     /// </summary>
     12     public Path path;
     13     /// <summary>
     14     /// 速度
     15     /// </summary>
     16     public float speed = 20.0f;
     17     /// <summary>
     18     /// 质量
     19     /// </summary>
     20     public float mass = 5.0f;
     21     /// <summary>
     22     /// 是否循环
     23     /// </summary>
     24     public bool isLooping = true;
     25 
     26     /// <summary>
     27     /// 当前速度
     28     /// </summary>
     29     private float curSpeed;
     30 
     31     /// <summary>
     32     /// 当前路径索引
     33     /// </summary>
     34     private int curPathIndex;
     35     /// <summary>
     36     /// 路径长度
     37     /// </summary>
     38     private float pathLength;
     39     /// <summary>
     40     /// 目标位置
     41     /// </summary>
     42     private Vector3 targetPoint;
     43 
     44     Vector3 velocity;
     45 
     46     void Start () 
     47     {
     48         pathLength = path.Length;
     49         curPathIndex = 0;
     50 
     51         velocity = transform.forward;
     52     }
     53     
     54     // Update is called once per frame
     55     void Update () 
     56     {
     57         
     58         curSpeed = speed * Time.deltaTime;
     59 
     60         //根据当前路径点索引获取路径的位置
     61         targetPoint = path.GetPoint(curPathIndex);
     62 
     63         //如果自身位置和目标位置的距离小于路径点的半径,则表示到达位置
     64         if(Vector3.Distance(transform.position, targetPoint) < path.Radius)
     65         {
     66             //如果不是最后一个路径点
     67             if (curPathIndex < pathLength - 1)
     68                 curPathIndex ++;
     69             //如果是循环模式,重置下一个路标位置为0
     70             else if (isLooping)
     71                 curPathIndex = 0;
     72             //停止
     73             else
     74                 return;
     75         }
     76 
     77         if (curPathIndex >= pathLength )
     78             return;
     79 
     80         if(curPathIndex >= pathLength - 1 && !isLooping)
     81             velocity += Steer(targetPoint, true);
     82         else
     83             velocity += Steer(targetPoint);
     84 
     85         //应用速度
     86         transform.position += velocity;
     87         //应用旋转
     88         transform.rotation = Quaternion.LookRotation(velocity);
     89     }
     90 
     91     public Vector3 Steer(Vector3 target, bool bFinalPoint = false)
     92     {
     93         //计算自身朝向
     94         Vector3 desiredVelocity = (target - transform.position);
     95         //获取距离长度
     96         float dist = desiredVelocity.magnitude;
     97 
     98         //归一化速度
     99         desiredVelocity.Normalize();
    100 
    101         if (bFinalPoint && dist < 10.0f)
    102             desiredVelocity *= (curSpeed * (dist / 10.0f));
    103         else 
    104             desiredVelocity *= curSpeed;
    105         
    106         Vector3 steeringForce = desiredVelocity - velocity; 
    107         Vector3 acceleration = steeringForce / mass;
    108 
    109         return acceleration;
    110     }
    111 }
    VehicleFollowing
     1 using UnityEngine;
     2 using System.Collections;
     3 
     4 public class Path: MonoBehaviour
     5 {
     6     /// <summary>
     7     /// 路径点半径
     8     /// </summary>
     9     public float Radius = 2.0f;
    10     /// <summary>
    11     /// 路径点
    12     /// </summary>
    13     public Vector3[] pointA;
    14 
    15     /// <summary>
    16     /// 路径长度
    17     /// </summary>
    18     public float Length
    19     {
    20         get
    21         {
    22             return pointA.Length;
    23         }
    24     }
    25 
    26     public Vector3 GetPoint(int index)
    27     {
    28         return pointA[index];
    29     }
    30 
    31     /// <summary>
    32     /// Show Debug Grids and obstacles inside the editor
    33     /// </summary>
    34     void OnDrawGizmos()
    35     {
    36         for (int i = 0; i < pointA.Length; i++)
    37         {
    38             if (i + 1 < pointA.Length)
    39             {
    40                 Debug.DrawLine(pointA[i], pointA[i + 1], Color.red);
    41             }
    42         }
    43     }
    44 }
    Path
     1 using UnityEngine;
     2 using System.Collections;
     3 
     4 public class VehicleAvoidance : MonoBehaviour 
     5 {
     6     /// <summary>
     7     /// 移动速度
     8     /// </summary>
     9     public float speed = 20.0f;
    10     /// <summary>
    11     /// 质量
    12     /// </summary>
    13     public float mass = 5.0f;
    14     /// <summary>
    15     ///16     /// </summary>
    17     public float force = 50.0f;
    18     /// <summary>
    19     /// 避开障碍的最小距离
    20     /// </summary>
    21     public float minimumDistToAvoid = 20.0f;
    22 
    23     /// <summary>
    24     /// 当前速度
    25     /// </summary>
    26     private float curSpeed;
    27     /// <summary>
    28     /// 目标位置
    29     /// </summary>
    30     private Vector3 targetPoint;
    31 
    32     void Start () 
    33     {
    34         mass = 5.0f;        
    35         targetPoint = Vector3.zero;
    36     }
    37 
    38     void Update () 
    39     {
    40         RaycastHit hit;
    41         var ray = Camera.main.ScreenPointToRay (Input.mousePosition);
    42 
    43         if(Input.GetMouseButtonDown(0) && Physics.Raycast(ray, out hit, 100.0f))
    44         {
    45             targetPoint = hit.point;
    46         }
    47 
    48         //计算自身朝向
    49         Vector3 dir = (targetPoint - transform.position);
    50         //归一化
    51         dir.Normalize();
    52 
    53         AvoidObstacles(ref dir);
    54 
    55         //判断和目标的距离
    56         if(Vector3.Distance(targetPoint, transform.position) < 3.0f)
    57             return;
    58 
    59         curSpeed = speed * Time.deltaTime;
    60 
    61         var rot = Quaternion.LookRotation(dir);
    62         transform.rotation = Quaternion.Slerp(transform.rotation, rot, 5.0f *  Time.deltaTime);
    63 
    64         transform.position += transform.forward * curSpeed;
    65     }
    66 
    67     /// <summary>
    68     /// 避开障碍
    69     /// </summary>
    70     public void AvoidObstacles(ref Vector3 dir)
    71     {
    72         RaycastHit hit;
    73 
    74         //只检测障碍物层
    75         int layerMask = 1 << 8;
    76 
    77         if (Physics.Raycast(transform.position, transform.forward, out hit, minimumDistToAvoid, layerMask))
    78         {
    79             //获取碰撞点的法向量
    80             Vector3 hitNormal = hit.normal;
    81             //不改变y轴
    82             hitNormal.y = 0.0f;
    83 
    84             //计算新的方向
    85             dir = transform.forward + hitNormal * force;
    86         }
    87     }
    88 
    89     private void OnDrawGizmos() {
    90         Debug.DrawLine(transform.position,transform.position + transform.forward * minimumDistToAvoid,Color.red);
    91     }
    92 }
    VehicleAvoidance

     项目:https://pan.baidu.com/s/1pL0N6OV

  • 相关阅读:
    2016.10.15先占坑
    2016.10.11先占坑
    2016.10.13先占坑
    2016.10.7先占坑
    main()里面为什么要放String[] args
    对于一个给定的正整数 n ,请你找出一共有多少种方式使 n 表示为若干个连续正整数的和,要求至少包括两个正整数。
    求两个数的最大公约数的三种算法总结
    C++
    Dev-c5.11的使用
    客户端和服务器端的交互(未完待续)
  • 原文地址:https://www.cnblogs.com/revoid/p/6519313.html
Copyright © 2011-2022 走看看