这几天一直沉迷于戴森球计划,每晚奔波于各种货物的分拣与运输,觉得里面运输物品的运输带很好玩,便试着实现一个简单的运输带效果
首先摆放几个物体,为其设定名称与标签,并添加刚体和碰撞体
给运输带添加一个脚本
规定在运输带上移动一段的时间和连接的下一个节点,并设定物体标签
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;
}
}
最终效果如图