zoukankan      html  css  js  c++  java
  • 自定义OffMeshLink跳跃曲线

    upload_2015-3-25_13-57-30.png 

    很多时候我们需要做类似上图的OffMeshLink的跳跃功能,并方便添加跳跃动画,Unity本身没提供,但是有官方的案例提供了方法,很多人没找到,故贴出来

    原链接:https://github.com/Unity-Technologies/NavMeshComponents/blob/master/Assets/Examples/Scripts/AgentLinkMover.cs

    我在它的基础上添加了两个多播委托及快速转向(红字显示),用来检测跳跃开始及结束,方便用来做跳跃动画的,而且NavMeshAgentde转速太慢,我添加一个快速转向到落地点的方法。

    用不到的就用原版吧。

    using UnityEngine;
    using System.Collections;
    using UnityEngine.AI;
    
    public enum OffMeshLinkMoveMethod
    {
        Teleport,
        NormalSpeed,
        Parabola,
        Curve
    }
    
    [RequireComponent(typeof(NavMeshAgent))]
    public class AgentLinkMover : MonoBehaviour
    {
        public OffMeshLinkMoveMethod method = OffMeshLinkMoveMethod.Parabola;
        public AnimationCurve curve = new AnimationCurve();
        public float CurveTime = .5f;
        public float FaceTime = .1f;
    
        public delegate void OnStartEvent();
        public event OnStartEvent OnStart;
        public delegate void OnCompleteEvent ();
        public event OnCompleteEvent OnComplete;
    
        IEnumerator Start()
        {
            NavMeshAgent agent = GetComponent<NavMeshAgent>();
            agent.autoTraverseOffMeshLink = false;
            while (true)
            {
                if (agent.isOnOffMeshLink)
                {                
                    yield return StartCoroutine (FaceToTarget (agent, FaceTime));
                    if (method == OffMeshLinkMoveMethod.NormalSpeed)
                        yield return StartCoroutine(NormalSpeed(agent));
                    else if (method == OffMeshLinkMoveMethod.Parabola)
                        yield return StartCoroutine(Parabola(agent, 2.0f, 0.5f));
                    else if (method == OffMeshLinkMoveMethod.Curve)
                        yield return StartCoroutine(Curve(agent, CurveTime));
                    agent.CompleteOffMeshLink();
                    agent.updateRotation = true;
                    OnComplete ();
                }
                yield return null;
            }
        }
    
        IEnumerator FaceToTarget(NavMeshAgent agent,float duration){
            agent.updateRotation = false;
            OffMeshLinkData data = agent.currentOffMeshLinkData;
            Quaternion startRotation = agent.transform.rotation;
            Vector3 endPos = data.endPos + Vector3.up * agent.baseOffset;
            var endRotation = Quaternion.LookRotation (new Vector3 (endPos.x - agent.transform.position.x, 0, endPos.z - transform.position.z));
            float normalizedTime = 0.0f;
            while (normalizedTime < 1.0f)
            {
                agent.transform.rotation = Quaternion.Slerp(startRotation ,endRotation ,normalizedTime);
                normalizedTime += Time.deltaTime / duration;
                yield return null;
            }
            OnStart ();
        }
    
        IEnumerator NormalSpeed(NavMeshAgent agent)
        {
            OffMeshLinkData data = agent.currentOffMeshLinkData;
            Vector3 endPos = data.endPos + Vector3.up * agent.baseOffset;
            while (agent.transform.position != endPos)
            {
                agent.transform.position = Vector3.MoveTowards(agent.transform.position, endPos, agent.speed * Time.deltaTime);
                yield return null;
            }
        }
        IEnumerator Parabola(NavMeshAgent agent, float height, float duration)
        {
            OffMeshLinkData data = agent.currentOffMeshLinkData;
            Vector3 startPos = agent.transform.position;
            Vector3 endPos = data.endPos + Vector3.up * agent.baseOffset;
            float normalizedTime = 0.0f;
            while (normalizedTime < 1.0f)
            {
                float yOffset = height * 4.0f * (normalizedTime - normalizedTime * normalizedTime);
                agent.transform.position = Vector3.Lerp(startPos, endPos, normalizedTime) + yOffset * Vector3.up;
                normalizedTime += Time.deltaTime / duration;
                yield return null;
            }
        }
        IEnumerator Curve(NavMeshAgent agent, float duration)
        {
            OffMeshLinkData data = agent.currentOffMeshLinkData;
            Vector3 startPos = agent.transform.position;
            Vector3 endPos = data.endPos + Vector3.up * agent.baseOffset;
            float normalizedTime = 0.0f;
            while (normalizedTime < 1.0f)
            {
                float yOffset = curve.Evaluate(normalizedTime);
                agent.transform.position = Vector3.Lerp(startPos, endPos, normalizedTime) + yOffset * Vector3.up;
                normalizedTime += Time.deltaTime / duration;
                yield return null;
            }
        }
    }

    用法,附着到NavMeshAgent物体上,选择需要的移动方式即可,然后搭配一下代码食用更佳:

    AgentLinkMover mover = GetComponent<AgentLinkMover>();
    mover.OnStart += () => print("start");
    mover.OnComplete += () => print("complete");
  • 相关阅读:
    svn command line tag
    MDbg.exe(.NET Framework 命令行调试程序)
    Microsoft Web Deployment Tool
    sql server CI
    VS 2010 One Click Deployment Issue “Application Validation did not succeed. Unable to continue”
    mshtml
    大厂程序员站错队被架空,只拿着五折工资!苟活和离职,如何选择?
    揭秘!Windows 为什么会蓝屏?微软程序员竟说是这个原因...
    喂!千万别忘了这个C语言知识!(~0 == -1 问题)
    Linux 比 Windows 更好,谁反对?我有13个赞成理由
  • 原文地址:https://www.cnblogs.com/CodeSnippet/p/7835361.html
Copyright © 2011-2022 走看看