这几天一直沉迷于戴森球计划,每晚奔波于各种货物的分拣与运输,觉得里面运输物品的运输带很好玩,便试着实现一个简单的运输带效果

首先摆放几个物体,为其设定名称与标签,并添加刚体和碰撞体

给运输带添加一个脚本

规定在运输带上移动一段的时间和连接的下一个节点,并设定物体标签

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Wheel : MonoBehaviour {
    //移动时间 
    public float moveTime;
    //节点
    public List<Transform> paths;
    void Start () {
        transform.tag = StringNames.ObjTags.transportWheel;
    }
}

并在属性面板绑定下一个节点的物体

接着给运输的物品写脚本,需要用到DoTween插件

与运输带碰撞就获取其节点,执行移动动画

与运输物品碰撞就使其停止移动,先让另一个物品通过

void OnCollisionEnter (Collision other) {
    switch (other.transform.tag) {
        case StringNames.ObjTags.transportWheel:
            Wheel wheel = other.transform.GetComponent<Wheel> ();
            if (wheel.paths.Count > 0) {
                //如果有连接点就播放移动动画
                startTransport (wheel.paths, wheel.moveTime);
            }
            break;
        case StringNames.ObjTags.transportObj:
            //如果接触另一个物品就暂停移动动画
            if (other.transform.GetComponent<Transport> ().isMove) {
            //计算距离
                if (Vector2.Distance (new Vector2 (transform.position.x, transform.position.z), new Vector2 (moveToPos.x, moveToPos.z)) >
                    Vector2.Distance (new Vector2 (other.transform.position.x, other.transform.position.z),
                                      new Vector2 (other.transform.GetComponent<Transport> ().moveToPos.x, other.transform.GetComponent<Transport> ().moveToPos.z))
                   ) {
                    transform.DOPause ();
                }

            }
    }
}

停止接触就播放移动动画

void OnCollisionExit (Collision other) {
    switch (other.transform.tag) {
        case StringNames.ObjTags.transportObj:
            //停止接触就播放移动动画
            transform.DOPlay ();
            break;
    }
}

物体移动部分

使用一个布尔变量判断移动状态

private void startTransport (List<Transform> paths, float time) {
    Vector3[] path = new Vector3[paths.Count];
    for (int i = 0; i < paths.Count; i++) {
        path[i] = new Vector3 (paths[i].position.x, transform.position.y, paths[i].position.z);
    }
    if (path.Length > 0) {
        moveToPos = path[1];
    }
    transform.DOPath (path, time, PathType.Linear, PathMode.Full3D).OnPause (delegate () {
        //回调函数  DoTween暂停时调用
        isMove = false;
    });
    isMove = true;
}

完整脚本

using System.Collections;
using System.Collections.Generic;

using DG.Tweening;

using UnityEngine;

public class Transport : MonoBehaviour {
    public bool isMove;
    //要移动到的坐标
    private Vector3 moveToPos;

    void Start () {
        transform.tag = StringNames.ObjTags.transportObj;
    }

    void Update () {

    }

    void OnCollisionEnter (Collision other) {
        switch (other.transform.tag) {
        case StringNames.ObjTags.transportWheel:
            Wheel wheel = other.transform.GetComponent<Wheel> ();
            if (wheel.paths.Count > 0) {
                //如果有连接点就播放移动动画
                startTransport (wheel.paths, wheel.moveTime);
            }
            break;
        case StringNames.ObjTags.transportObj:
            //如果接触另一个物品就暂停移动动画
            if (other.transform.GetComponent<Transport> ().isMove) {
                //计算距离
                if (Vector2.Distance (new Vector2 (transform.position.x, transform.position.z), new Vector2 (moveToPos.x, moveToPos.z)) >
                    Vector2.Distance (new Vector2 (other.transform.position.x, other.transform.position.z),
                        new Vector2 (other.transform.GetComponent<Transport> ().moveToPos.x, other.transform.GetComponent<Transport> ().moveToPos.z))
                ) {
                    transform.DOPause ();
                }

            }
            break;
        }
    }
    void OnCollisionExit (Collision other) {
        switch (other.transform.tag) {
        case StringNames.ObjTags.transportObj:
            //停止接触就播放移动动画
            transform.DOPlay ();
            break;
        }
    }
    private void startTransport (List<Transform> paths, float time) {
        Vector3[] path = new Vector3[paths.Count];
        for (int i = 0; i < paths.Count; i++) {
            path[i] = new Vector3 (paths[i].position.x, transform.position.y, paths[i].position.z);
        }
        if (path.Length > 0) {
            moveToPos = path[1];
        }

        transform.DOPath (path, time, PathType.Linear, PathMode.Full3D).OnPause (delegate () {
            //回调函数  DoTween暂停时调用
            isMove = false;
        });
        isMove = true;
    }
}

最终效果如图

Last modification:January 29th, 2021 at 01:45 am