Unity3d

Unity基础(22)-Navigation导航系统

2018-09-21  本文已影响199人  元宇宙协会

导航系统

using UnityEngine;
using System.Collections;
 
public class Move : MonoBehaviour {
    public float speed = 6.0F;
    private Vector3 moveDirection = Vector3.zero;
    public CharacterController controller;
    void Start() {
       controller = GetComponent<CharacterController>();
    }
    void Update() {
      
        if (controller.isGrounded) {
            moveDirection = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
            moveDirection = transform.TransformDirection(moveDirection);
            moveDirection *= speed;
            controller.Move(moveDirection * Time.deltaTime);
    }
}
public class CameraFollow : MonoBehaviour {

    public Vector3 cameraV;
    public Vector3 ObjV;
    void Start () {
        
    }
    
    void Update () {
        cameraV = Camera.main.transform.position;
        ObjV = transform.position;
        cameraV = new Vector3(ObjV.x, ObjV.y + 6, ObjV.z - 8);
        Camera.main.transform.position = cameraV;
    }
}
去群空间找动画资源,代码直接Copy
角色身上脚本一览
public class AnimaPlay : MonoBehaviour {
    public Vector3 mousePos; // 鼠标位置
    public Animation ani;  // 动画组建
    public CharacterController cha;  // 角色控制器
    public float speed = 5f;  // 移动速度
    public bool state = false; // 状态
    void Start () {
        ani = GetComponent<Animation>();
        cha = GetComponent<CharacterController>();
    }

    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 == "Plane")
                {
                    mousePos = hit.point;
                    state = true;
                }
            }
        }
        //判断角色是否到达目的地
        float distance = Vector3.Distance(mousePos, transform.position);
        if (distance > 1f && state == true)
        {
            Vector3 setp = Vector3.ClampMagnitude(mousePos - transform.position, speed);
            transform.LookAt(mousePos);
            ani.Play("Run");
            cha.SimpleMove(setp);       
        }
        else
        {
            ani.Play("Idle");
            state = false;
        }
    }

    // 当角色控制器碰撞的物体,打印其名字
    private void OnControllerColliderHit(ControllerColliderHit hit)
    {
        if (hit.collider.name == "Cube")
        {
            // 创建特效
        }
    }
}
Base offset :碰撞模型和实体模型之间的垂直偏移量
Speed: 物体的行进最大速度
Angular Speed 行进过程中转向时的角速度。
Acceleration 加速度
Stopping distance:离目标距离还有多远时停止。
Auto Braking : 自动制动
Radius :物体的半径
Height :物体的高度
Quality : 代理躲避的水平,一般我们选默认的High Quality就行了
Priority :躲避优先级

Auto Traverse OffMesh Link :是否采用默认方式度过链接路径。
自动移动并关闭OffMeshLinks,
Auto Repath 自动重新寻路
Area mask : 区域模板

方法

1.SetDestination( Vector3 v )�设置目的地,与nma.destination = v一样的,你想怎么用都行,只是这个函数在设置目的地成功后返回***e,
  否则返回false,就只比调用属性多了一个返回值
2.Move( Vector3 v )�让导航网格代理朝向量v的世界坐标系方向平移v的长度
3.Stop()�让导航网格代理停止寻路,但此寻路状态可以靠下面一个函数恢复到寻路状态,并且目的地也与上次一样
4.Resume()�恢复寻路状态,此时角色会在上一次执行了Stop函数停下来后恢复当时的状态,目的地为上一次的目的地
5.ActivateCurrentOffMeshLink( bool activated )�返回值为空�与OffMeshLink有关
6.CompleteOffMeshLink ()�让导航网格代理完成在OffMeshLink上的周游,后面会讲的

导航网格烘焙须知
使用此控件要注意静态物体设置为NavagationStatic



同时设置为不阻碍行走-Walkable ,即可以在障碍物上行走。



但关于障碍物即需要设置为NavagationStatic,同时设置为NotWalkable,即不可以在障碍物上行走

设置完毕后,进行烘焙即可
使用Bake进行导航网格烘焙
public class NavAgentMove : MonoBehaviour
{

    public UnityEngine.AI.NavMeshAgent agent;
    void Start()
    {
        agent = GetComponent<UnityEngine.AI.NavMeshAgent>();
    }


    void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            RaycastHit hit;
            if (Physics.Raycast(ray, out hit))
            {
                if (!(hit.collider.name == "Plane"))
                {
                    return;
                }
                Vector3 pos = hit.point;
                transform.LookAt(new Vector3(hit.point.x, transform.position.y, hit.point.z));
                //agent.Move(pos);
                agent.SetDestination(pos);
            }
        }
        if (Input.GetMouseButtonDown(1))
        {
            Debug.Log("1");
            agent.Stop();
        }
        if (Input.GetMouseButtonDown(2))
        {
            Debug.Log("2");
            agent.Resume();
        }
   }
}
开始 (Start)  分离网格链接的开始对象。
结束 (End)    分离网格链接的结束对象。
成本覆盖 (Cost Override)    如果值为正,则在路径请求处理中计算路径成本时使用该属性。否则,我们使用默认成本(此游戏对象所属的层的成本)。
如果“成本覆盖”(Cost Override) 设置为值 3.0,则在分离网格链接上移动的成本比在默认导航网格区域中移动相同距离的成本高三倍。 
此属性可在运行时编辑,无需重新烘焙''
双向 (Bi Directional) 如果此属性为“开”(on),则可以双向穿越链接,如果它为“关”(off),则只能按从“开始”(Start) 到“结束”(End) 的方向穿越链接。
已激活 (Activated) 指定寻路器是否实际使用此链接。此属性可在运行时编辑,无需重新烘焙。
图2

使用此控件要注意静态物体设置为NavagationStatic,offMashLinks,同时设置为Walkable,即可以在障碍物上行走,如果不可以在障碍物上行走,那么就没有导航了。一定要注意!!!


Radius 半径 : 障碍物圆柱的半径
Height 高度 : 障碍物圆柱的高度
Carve:是否打开在导航网格 的模式
Move Threshold:当模式为Carve时,此物体的移动距离超过这个阀值后,更新当前的导航网格(重新挖洞)

Carve模式的一些总结:
1.在Bake场景的时候,Navigation窗口的Bake页面有一个高度值,场景中的导航网格通常作为一个平面,当NavMeshObstacle 距离小于这个高度时,
才会在导航网格上挖洞,否则NavMeshObstacle 还是以普通模式存在的。
2.NavMeshObstacle 在刚创建的时候最好先关闭NavMeshObstacle 这个组件,但需要是再打开,在跟NavMeshAgent混用时,不能共用(同时激活状态),只能选其一,不然有bug。
3.碰撞还是使用trigger
4.最好不要同时使用RigidBody,有bug,新版本可能改好了.
5.在挖洞时,设备掉帧比较明显。善用Move Threshold。

上一篇下一篇

猜你喜欢

热点阅读