极简状态机:

  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()]
  77. public Text m_text;
  78.  
  79. private void Start() {
  80. //初始状态:巡逻
  81. m_fsmState = FSMState.Patrol;
  82. //设置初始目标路标索引
  83. m_targetWaypointIndex = ;
  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. /// <summary>
  127. /// 更新巡逻状态
  128. /// </summary>
  129. private void UpdatePatrolState() {
  130. if(!IsArrived()) {
  131. Move(m_waypoints[m_targetWaypointIndex]);
  132. }
  133. if(CalculateDistance() <= m_chaseDistance) {
  134. m_fsmState = FSMState.Chase;
  135. }
  136. }
  137.  
  138. /// <summary>
  139. /// 更新追逐状态
  140. /// </summary>
  141. private void UpdateChaseState() {
  142. Move(m_player);
  143. //小于等于攻击距离,攻击
  144. if(CalculateDistance() <= m_attackDistance) {
  145. m_fsmState = FSMState.Attack;
  146. //大于攻击距离并且小于等于追逐距离,追逐
  147. } else if(CalculateDistance() > m_attackDistance && CalculateDistance() <= m_chaseDistance) {
  148. m_fsmState = FSMState.Chase;
  149. //其余情况也就是大于追逐距离,巡逻
  150. } else {
  151. m_fsmState = FSMState.Patrol;
  152. }
  153. }
  154.  
  155. /// <summary>
  156. /// 更新攻击状态
  157. /// </summary>
  158. private void UpdateAttackState() {
  159. //大于攻击距离并且小于等于追逐距离,追逐
  160. if(CalculateDistance() > m_attackDistance && CalculateDistance() <= m_chaseDistance) {
  161. m_fsmState = FSMState.Chase;
  162. //大于追逐距离,巡逻
  163. } else if(CalculateDistance() > m_chaseDistance) {
  164. m_fsmState = FSMState.Patrol;
  165. }
  166. }
  167.  
  168. private void UpdateDeadState() {
  169.  
  170. }
  171.  
  172. /// <summary>
  173. /// 画和玩家之间的线
  174. /// </summary>
  175. private void DrawLine(Color color) {
  176. iTween.DrawLine(new Transform[] { transform,m_player.transform },color);
  177. }
  178.  
  179. /// <summary>
  180. /// 显示玩家的距离
  181. /// </summary>
  182. private void DisplayDistance() {
  183. float distance = Vector3.Distance(transform.position,m_player.position);
  184. m_text.text = "State:"+m_fsmState+"\nDistance:"+ distance.ToString();
  185. }
  186.  
  187. /// <summary>
  188. /// 计算和玩家的距离
  189. /// </summary>
  190. private float CalculateDistance() {
  191. return Vector3.Distance(transform.position,m_player.position);
  192. }
  193.  
  194. /// <summary>
  195. /// 是否到达路标
  196. /// </summary>
  197. private bool IsArrived() {
  198. float distance = Vector3.Distance(transform.position,m_waypoints[m_targetWaypointIndex].position);
  199. if(distance < 0.1f) {
  200. m_targetWaypointIndex++;
  201. m_targetWaypointIndex = m_targetWaypointIndex % ;
  202. return true;
  203. }
  204. return false;
  205. }
  206.  
  207. private void Move(Transform target) {
  208. transform.LookAt(target);
  209. transform.Translate(transform.forward * Time.deltaTime * m_moveSpeed,Space.World);
  210. }
  211. }
  212. }

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 = ;
  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 = ;
  16.  
  17. private int creditBalance = ;
  18. private ArrayList weightedReelPoll = new ArrayList();
  19. private int zeroProbability = ;
  20.  
  21. private int firstReelResult = ;
  22. private int secondReelResult = ;
  23. private int thirdReelResult = ;
  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 = ; i < zeroProbability; i++) {
  32. weightedReelPoll.Add();
  33. }
  34.  
  35. int remainingValuesProb = ( - zeroProbability)/;
  36.  
  37. for (int j = ; j < ; j++) {
  38. for (int k = ; k < remainingValuesProb; k++) {
  39. weightedReelPoll.Add(j);
  40. }
  41. }
  42. }
  43.  
  44. void OnGUI() {
  45.  
  46. GUI.Label(new Rect(, , , ), "Your bet: ");
  47. betAmount = int.Parse(GUI.TextField(new Rect(, , , ), betAmount.ToString(), ));
  48.  
  49. GUI.Label(new Rect(, , , ), "Credits: " + creditBalance.ToString());
  50.  
  51. if (GUI.Button(new Rect(,,,), "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 * ;
  61. }
  62. else if (firstReelResult == && thirdReelResult == ) {
  63. betResult.GetComponent<GUIText>().text = "YOU WIN " + (betAmount/).ToString();
  64. creditBalance -= (betAmount/);
  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*).ToString();
  71. creditBalance -= (betAmount*);
  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(, numberOfSym);
  84. if (!firstReelSpinned) {
  85. GameObject.Find("firstReel").GetComponent<GUIText>().text = randomSpinResult.ToString();
  86. if (elapsedTime >= spinDuration) {
  87. int weightedRandom = Random.Range(, weightedReelPoll.Count);
  88. GameObject.Find("firstReel").GetComponent<GUIText>().text = weightedReelPoll[weightedRandom].ToString();
  89. firstReelResult = (int)weightedReelPoll[weightedRandom];
  90. firstReelSpinned = true;
  91. elapsedTime = ;
  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 = ;
  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 - ;
  112. if (randomSpinResult < firstReelResult) randomSpinResult = firstReelResult - ;
  113. if (randomSpinResult > firstReelResult) randomSpinResult = firstReelResult + ;
  114. if (randomSpinResult < ) randomSpinResult = ;
  115. if (randomSpinResult > ) randomSpinResult = ;
  116.  
  117. GameObject.Find("thirdReel").GetComponent<GUIText>().text = randomSpinResult.ToString();
  118. thirdReelResult = randomSpinResult;
  119. }
  120. else {
  121. int weightedRandom = Random.Range(, weightedReelPoll.Count);
  122. GameObject.Find("thirdReel").GetComponent<GUIText>().text = weightedReelPoll[weightedRandom].ToString();
  123. thirdReelResult = (int)weightedReelPoll[weightedRandom];
  124. }
  125.  
  126. startSpin = false;
  127. elapsedTime = ;
  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 * );
  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()) {
  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 = ;
  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(,,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 = ;
  22. /// <summary>
  23. /// 视野距离
  24. /// </summary>
  25. public int ViewDistance = ;
  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 = ;
  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 - )
  68. curPathIndex ++;
  69. //如果是循环模式,重置下一个路标位置为0
  70. else if (isLooping)
  71. curPathIndex = ;
  72. //停止
  73. else
  74. return;
  75. }
  76.  
  77. if (curPathIndex >= pathLength )
  78. return;
  79.  
  80. if(curPathIndex >= pathLength - && !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 = ; i < pointA.Length; i++)
  37. {
  38. if (i + < pointA.Length)
  39. {
  40. Debug.DrawLine(pointA[i], pointA[i + ], 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() && 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 = << ;
  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

AI 学习的更多相关文章

  1. DeepLearning.ai学习笔记汇总

    第一章 神经网络与深度学习(Neural Network & Deeplearning) DeepLearning.ai学习笔记(一)神经网络和深度学习--Week3浅层神经网络 DeepLe ...

  2. DeepLearning.ai学习笔记(三)结构化机器学习项目--week2机器学习策略(2)

    一.进行误差分析 很多时候我们发现训练出来的模型有误差后,就会一股脑的想着法子去减少误差.想法固然好,但是有点headlong~ 这节视频中吴大大介绍了一个比较科学的方法,具体的看下面的例子 还是以猫 ...

  3. AI 学习路线

    [导读] 本文由知名开源平台,AI技术平台以及领域专家:Datawhale,ApacheCN,AI有道和黄海广博士联合整理贡献,内容涵盖AI入门基础知识.数据分析挖掘.机器学习.深度学习.强化学习.前 ...

  4. AI - 学习路径(Learning Path)

    初见 机器学习图解 错过了这一篇,你学机器学习可能要走很多弯路 这3张脑图,带你清晰人工智能学习路线 一些课程 Andrew Ng的网络课程 HomePage:http://www.deeplearn ...

  5. AI学习---数据读取&神经网络

    AI学习---数据读取&神经网络 fa

  6. AI学习吧

    一:AI学习吧 项目描述 系统使用前后端分离的模式,前端使用vue框架,后端使用restframework实现. 项目需求 公司开发AI学习吧,由于公司需要一款线上学习平台,要开发具有线上视频学习.支 ...

  7. UE4的AI学习(1)——基本概念

    AI学习当中,不学习行为树基本概念就不能明白具体实例中的操作意义,但是没有经过具体实例实验,又觉得基本概念抽象难以理解.建议先泛读(1)(2)后再对具体的细节进行死磕,能较深的理解行为树的具体概念.第 ...

  8. AI学习经验总结

    我的人工智能学习之路-从无到有精进之路 https://blog.csdn.net/sinox2010p1/article/details/80467475 如何自学人工智能路径规划(附资源,百分百亲 ...

  9. AI学习笔记(02)

    AI学习笔记   第一个黑箭头是用于挑选物体和移 动物体.在绘图是选中一个物体,就可以将它自由的移动.和其他的绘图软件相同当你选 中物体的时候物体周围就会出现八个方形的控制点,你可以通过这些控制点对物 ...

  10. AI学习笔记:特征工程

    一.概述 Andrew Ng:Coming up with features is difficult, time-consuming, requires expert knowledge. &quo ...

随机推荐

  1. DevExpress WinForms v18.2新版亮点(六)

    行业领先的.NET界面控件2018年第二次重大更新——DevExpress v18.2日前正式发布,本站将以连载的形式为大家介绍各版本新增内容.本文将介绍了DevExpress WinForms v1 ...

  2. Android开发 ---如何操作资源目录中的资源文件5 ---Raw资源管理与国际化

    效果图: 1.activity_main.xml 描述: 定义两个按钮,一个是Raw资源管理,一个是处理国际化语言,其中i18n表示简体中文 <?xml version="1.0&qu ...

  3. nginx 更改用户组

    为什么要更改 Nginx 服务的默认用户:就像更改 ssh 的默认 22 端口一样,增加安全性,Nginx 服务的默认用户是 nobody ,我们更改为 nginx 1) 添加 nginx 用户 us ...

  4. C#清理所有正在使用的资源

    namespace QQFrm{    partial class Form1    {        /// <summary>        /// 必需的设计器变量.        ...

  5. Js代码一些要素

    ---恢复内容开始--- 条件语句 is(条件){ 语句 }else { 语句 } {}在js中我们把他叫代码块.如果代码块里内容没有执行完,语句就不会向下执行. 代码块是一个独立的整体.如果js中莫 ...

  6. Python 时间

    import time # 时间戳: 从1970-01-01 00:00:00开始计算. 未来存储的时候用是时间戳 print(time.time()) # 格式化时间 print(time.strf ...

  7. angular 项目 error TS2451: Cannot redeclare block-scoped variable 'ngDevMode'

    删除  node_modules ,用 npm install 就可以了, cnpm install (竟然不行)

  8. SQL注入之Sqli-labs系列第二十八关(过滤空格、注释符、union select)和第二十八A关

    开始挑战第二十八关(Trick with SELECT & UNION) 第二十八A关(Trick with SELECT & UNION) 0x1看看源代码 (1)与27关一样,只是 ...

  9. Git 创建分支与合并分支

    下面以branchName=>aiMdTest为例介绍 1.  下载code git clone masterUrl iva(另存文件名) 2.  创建并切换分支 cd iva git chec ...

  10. Python学习笔记第二十二周(前端知识点补充)

    目录: 一.伪类 二.样式 1.字体 2.背景图片 3.margin和padding 4.列表属性 5.float 6.clear 7.position 8.text-decoration(a标签下划 ...