国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

Unity手游之路<十>自動尋路Navmesh之跳躍,攀爬,斜坡

2019-11-17 02:30:10
字體:
來源:轉載
供稿:網友

Unity手游之路<十>自動尋路Navmesh之跳躍,攀爬,斜坡

轉載

Unity手游之路<十>自動尋路Navmesh之跳躍,攀爬,斜坡

分類:unity2013-12-27 00:506545人閱讀評論(5)收藏舉報unity3dNavmesh手游自動尋路

在之前的幾篇Blog總,我們已經系統學習了自動尋路插件Navmesh的相關概念和細節。然而,如果要做一個場景精美的手游,需要用到各種復雜的場景地形,而不僅僅是平地上的自動尋路。今天我們將通過一個完整的復雜的實例,來貫穿各個細節。我們將實現一個復雜的場景,角色可以在里面攀爬,跳躍,爬坡。是不是感覺很像當年的CS游戲呢?本案例將會用得一些基本的動畫函數,大家可以先結合文檔有個大概的了解。本實例是在官方的范例上加工而成。

(轉載請注明原文地址http://blog.csdn.net/janeky/article/details/17598113)

  • 步驟
1.在場景中擺放各種模型,包括地板,斜坡,山體,扶梯等2.為所有的模型加上Navigation Static和OffMeshLink Generatic(這個根據需要,例如地板與斜坡相連,斜坡就不需要添加OffMeshLink)3.特殊處理扶梯,需要手動添加Off Mesh Link,設置好開始點和結束點4.保存場景,烘焙場景5.添加角色模型,為其加Nav Mesh Agent組件6.為角色添加一個新腳本,AgentLocomotion.cs,用來處理自動尋路,已經角色動畫變換。代碼比較長,大家可以結合注釋來理解[csharp]view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. using UnityEngine;  using System.Collections;    public class AgentLocomotion : MonoBehaviour  {      PRivate Vector3 target;//目標位置      private NavMeshAgent agent;      private Animation anim;//動畫      private string locoState = "Locomotion_Stand";      private Vector3 linkStart;//OffMeshLink的開始點      private Vector3 linkEnd;//OffMeshLink的結束點      private Quaternion linkRotate;//OffMeshLink的旋轉      private bool begin;//是否開始尋路        // Use this for initialization      void Start()      {          agent = GetComponent<NavMeshAgent>();          //自動移動并關閉OffMeshLinks,即在兩個隔離障礙物直接生成的OffMeshLink,agent不會自動越過          agent.autoTraverSEOffMeshLink = false;          //創建動畫          AnimationSetup();          //起一個協程,處理動畫狀態機          StartCoroutine(AnimationStateMachine());      }        void Update()      {          //鼠標左鍵點擊          if (Input.GetMouseButtonDown(0))          {              //攝像機到點擊位置的的射線              Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);              RaycastHit hit;              if (Physics.Raycast(ray, out hit))              {                  //判斷點擊的是否地形                  if (hit.collider.tag.Equals("Obstacle"))                  {                      begin = true;                      //點擊位置坐標                      target = hit.point;                  }              }          }          //每一幀,設置目標點          if (begin)          {              agent.SetDestination(target);          }      }        IEnumerator AnimationStateMachine()      {          //根據locoState不同的狀態來處理,調用相關的函數          while (application.isPlaying)          {              yield return StartCoroutine(locoState);          }      }        //站立      IEnumerator Locomotion_Stand()      {          do          {              UpdateAnimationBlend();              yield return new WaitForSeconds(0);          } while (agent.remainingDistance == 0);          //未到達目標點,轉到下一個狀態Locomotion_Move          locoState = "Locomotion_Move";          yield return null;      }        IEnumerator Locomotion_Move()      {          do          {              UpdateAnimationBlend();              yield return new WaitForSeconds(0);              //角色處于OffMeshLink,根據不同的地點,選擇不同動畫              if (agent.isOnOffMeshLink)              {                  locoState = SelectLinkAnimation();                  return (true);              }          } while (agent.remainingDistance != 0);          //已經到達目標點,狀態轉為Stand          locoState = "Locomotion_Stand";          yield return null;      }        IEnumerator Locomotion_Jump()      {          //播放跳躍動畫          string linkAnim = "RunJump";          Vector3 posStart = transform.position;            agent.Stop(true);          anim.CrossFade(linkAnim, 0.1f, PlayMode.StopAll);          transform.rotation = linkRotate;            do          {              //計算新的位置              float tlerp = anim[linkAnim].normalizedTime;              Vector3 newPos = Vector3.Lerp(posStart, linkEnd, tlerp);              newPos.y += 0.4f * Mathf.Sin(3.14159f * tlerp);              transform.position = newPos;                yield return new WaitForSeconds(0);          } while (anim[linkAnim].normalizedTime < 1);          //動畫恢復到Idle          anim.Play("Idle");          agent.CompleteOffMeshLink();          agent.Resume();          //下一個狀態為Stand          transform.position = linkEnd;          locoState = "Locomotion_Stand";          yield return null;      }      //梯子      IEnumerator Locomotion_Ladder()      {          //梯子的中心位置          Vector3 linkCenter = (linkStart + linkEnd) * 0.5f;          string linkAnim;          //判斷是在梯子上還是梯子下          if (transform.position.y > linkCenter.y)              linkAnim = "Ladder Down";          else              linkAnim = "Ladder Up";            agent.Stop(true);            Quaternion startRot = transform.rotation;          Vector3 startPos = transform.position;          float blendTime = 0.2f;          float tblend = 0f;            //角色的位置插值變化(0.2內變化)          do          {              transform.position = Vector3.Lerp(startPos, linkStart, tblend / blendTime);              transform.rotation = Quaternion.Lerp(startRot, linkRotate, tblend / blendTime);                yield return new WaitForSeconds(0);              tblend += Time.deltaTime;          } while (tblend < blendTime);          //設置位置          transform.position = linkStart;          //播放動畫          anim.CrossFade(linkAnim, 0.1f, PlayMode.StopAll);          agent.ActivateCurrentOffMeshLink(false);          //等待動畫結束          do          {              yield return new WaitForSeconds(0);          } while (anim[linkAnim].normalizedTime < 1);          agent.ActivateCurrentOffMeshLink(true);          //恢復Idle狀態          anim.Play("Idle");          transform.position = linkEnd;          agent.CompleteOffMeshLink();          agent.Resume();          //下一個狀態Stand          locoState = "Locomotion_Stand";          yield return null;      }        private string SelectLinkAnimation()      {          //獲得當前的OffMeshLink數據          OffMeshLinkData link = agent.currentOffMeshLinkData;          //計算角色當前是在link的開始點還是結束點(因為OffMeshLink是雙向的)          float distS = (transform.position - link.startPos).magnitude;          float distE = (transform.position - link.endPos).magnitude;            if (distS < distE)          {              linkStart = link.startPos;              linkEnd = link.endPos;          }          else          {              linkStart = link.endPos;              linkEnd = link.startPos;          }          //OffMeshLink的方向          Vector3 alignDir = linkEnd - linkStart;          //忽略y軸          alignDir.y = 0;          //計算旋轉角度          linkRotate = Quaternion.LookRotation(alignDir);            //判斷OffMeshLink是手動的(樓梯)還是自動生成的(跳躍)          if (link.linkType == OffMeshLinkType.LinkTypeManual)          {              return ("Locomotion_Ladder");          }          else          {              return ("Locomotion_Jump");          }      }        private void AnimationSetup()      {          anim = GetComponent<Animation>();            // 把walk和run動畫放到同一層,然后同步他們的速度。          anim["Walk"].layer = 1;          anim["Run"].layer = 1;          anim.SyncLayer(1);            //設置“跳躍”,“爬樓梯”,“下樓梯”的動畫模式和速度          anim["RunJump"].wrapMode = WrapMode.ClampForever;          anim["RunJump"].speed = 2;          anim["Ladder Up"].wrapMode = WrapMode.ClampForever;          anim["Ladder Up"].speed = 2;          anim["Ladder Down"].wr
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 彭泽县| 浪卡子县| 韩城市| 澄城县| 政和县| 四川省| 吉木乃县| 玉树县| 清徐县| 宁远县| 延长县| 克什克腾旗| 威信县| 青海省| 陈巴尔虎旗| 靖江市| 丰镇市| 宁河县| 宁夏| 贺兰县| 凤山县| 滨海县| 禄丰县| 扎鲁特旗| 晴隆县| 正定县| 阿拉尔市| 金门县| 长寿区| 荣昌县| 建阳市| 离岛区| 镇坪县| 宁明县| 宜兰县| 龙江县| 庐江县| 乡城县| 会宁县| 东至县| 曲阳县|