这里的代码的功能有
- 给出矩形四个转角点
- 生成若干个物体(这里是广告牌)围绕这四个转角点匀速转圈
- 转角呈圆角形状 过度自然
这段代码可以简单拓展到绕多边形形状转动,应该不需要改什么代码,后面有时间会拓展玩玩看
下面的代码放好之后挂载脚本然后在inspector面板弄好参数以及脚本中的下面这段话改成能找到你要生成的物体的代码,运行就可以看效果了
adPref = GameObject.Find("cycladgo");
上代码: Util工具类
///
/// 已知两个点 求他们连线的中点
///
///
///
///
public static Vector3 GetTwoVctrMiddle(Vector3 vctrOne, Vector3 vctrTwo)
{
Vector3 mid = new Vector3((vctrOne.x + vctrTwo.x) / 2,
(vctrOne.y + vctrTwo.y) / 2,
(vctrOne.z + vctrTwo.z) / 2);
return mid;
}
public delegate IEnumerator IenumDelegate(params object[] bc);
public static void ReStartCoroutine(MonoBehaviour o, ref Coroutine cor, IenumDelegate eFun, params object[] bc)
{
//Debug.LogError(" Util ReStartCoroutine ");
StopCoroutine(o, ref cor);
//Debug.Log("cor == null " + (cor == null));
cor = o.StartCoroutine(eFun(bc));
}
public static void DisableMRAndMC(Transform trn)
{
MeshRenderer mr = trn.GetComponent();
if (mr)
{
mr.enabled = false;
}
MeshCollider mc = trn.GetComponent();
if (mc)
{
mc.enabled = false;
}
}
单个广告牌对象类
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using DG.Tweening;
public class SingleADInfo : MonoBehaviour
{
///
/// 当前运行所在轨道信息
///
SinglePathMsg curTracePathMsg;
///
/// 将要运行的轨道信息
///
SinglePathMsg nextTracePathMsg;
SphereCollider selfInsideCol;
public SphereCollider SelfInsideCol { get => selfInsideCol; }
bool isInTurnCrnrState = false;
Collider lastCrossCol;
Rigidbody selfRigidBody;
public Rigidbody SelfRigidBody { get => selfRigidBody; }
float turnCrnrTime;
float straightPathTraceTime;
Coroutine turnCrnrLookRotAdjustCor;
Coroutine directLineLookRotAdjustCor;
Vector3 turningLastFramePos;
// Start is called before the first frame update
void Start()
{
selfInsideCol = gameObject.AddCompIfNone();
selfInsideCol.radius = HallADLoopMgr.Instance.adSelfColRadius;
selfInsideCol.isTrigger = true;
selfRigidBody = gameObject.AddCompIfNone();
selfRigidBody.useGravity = false;
selfRigidBody.isKinematic = true;
}
public void FirstLaunch()
{
gameObject.SetActive(true);
float time = curTracePathMsg.GetStartTraceTime();
gameObject.transform.position = curTracePathMsg.PortPointStartTrn.position;
transform.LookAt(curTracePathMsg.DirectLineTracePathPosEnd);
StraightPathMove(time);
}
public void SetInfo(SinglePathMsg singlePathMsg, float pathTraceTime, float crnrTurnTime)
{
curTracePathMsg = singlePathMsg;
nextTracePathMsg = curTracePathMsg.NextPathInfo;
turnCrnrTime = crnrTurnTime;
straightPathTraceTime = pathTraceTime;
}
bool IsTouchDirectPathEndPt(Collider other)
{
// Debug.LogError(" SingleADInfo " +
//"IsTouchDirectPathEndPt curTracePathMsg.CrnrContainsThisCol(other) " +
//curTracePathMsg.CrnrContainsThisCol(other));
// Debug.LogError(" isInTurnCrnrState " + isInTurnCrnrState);
if (curTracePathMsg.ThisColDirectPathEndPos(other) &&
!isInTurnCrnrState)
{
return true;
}
return false;
}
bool IsTouchCrnrPathEndPt(Collider other)
{
if (curTracePathMsg.NextPathInfo.ThisColDirectPathStartPos(other) &&
isInTurnCrnrState)
{
return true;
}
return false;
}
void OnTriggerEnter(Collider other)
{
//Debug.LogError("SingleADInfo OnTriggerEnter ");
//转弯过程中如果路径太鬼畜 可能会多次重复碰到同一个碰撞体
//直线行走过程中直线行走的结束点
if (IsTouchDirectPathEndPt(other))
{
isInTurnCrnrState = true;
CornerTurn();
}
else if (IsTouchCrnrPathEndPt(other))//转弯过程中 碰到了转弯的结束点
{
isInTurnCrnrState = false;
curTracePathMsg = nextTracePathMsg;
nextTracePathMsg = curTracePathMsg.NextPathInfo;
StraightPathMove();
}
lastCrossCol = other;
}
private void StraightPathMove(float time = 0)
{
transform.DOPause();
if (directLineLookRotAdjustCor == null)
{
Util.ReStartCoroutine(this, ref directLineLookRotAdjustCor, DirectLineLookAdjust);
}
transform.DOMove(curTracePathMsg.DirectLineTracePathPosEnd,
time nextPathInfo; }
Transform portPointStart;
public Transform PortPointStartTrn { get => portPointStart; }
Transform portPointEnd;
public Transform PortPointEndTrn { get => portPointEnd; }
Vector3 directLineTracePathPosStart;
public Vector3 DirectLineTracePathPosStart { get => directLineTracePathPosStart; }
Vector3 directLineTracePathPosEnd;
public Vector3 DirectLineTracePathPosEnd { get => directLineTracePathPosEnd; }
GameObject directLineTracePathPosStartColGo;
public GameObject DirectLineTracePathPosStartColGo { get => directLineTracePathPosStartColGo; }
GameObject directLineTracePathPosEndColGo;
public GameObject DirectLineTracePathPosEndColGo { get => directLineTracePathPosEndColGo; }
Vector3 portSrartToEndNormalizedDir;
public Vector3 PortStartToEndNormalizedDir { get => portSrartToEndNormalizedDir; }
float crnrToCrnrDis;
public float CrnrToCrnrDis { get => crnrToCrnrDis; }
float portToPortDis;
public float PortToPortDis { get => portToPortDis; }
float cornerPosColRadius;
public float CornerPosColRadius { get => cornerPosColRadius; }
public SinglePathMsg(Transform ptStart, Transform ptEnd,
float directLinePercent, float cornerPosColRadius)
{
portPointStart = ptStart;
portPointEnd = ptEnd;
portSrartToEndNormalizedDir = (ptEnd.position - ptStart.position).normalized;
portToPortDis = (ptEnd.position - ptStart.position).magnitude;
this.cornerPosColRadius = cornerPosColRadius;
SetTurnCorner(directLinePercent);
//Debug.LogError(" HallADLoopMgr SinglePathMsg cornerPosColRadius " +
// cornerPosColRadius);
//Debug.LogError(" HallADLoopMgr SinglePathMsg this.cornerPosColRadius " +
// this.cornerPosColRadius);
}
public bool ThisColDirectPathEndPos(Collider collider)
{
if (collider == null)
{
return false;
}
if (collider.gameObject == directLineTracePathPosEndColGo)
{
return true;
}
return false;
}
public bool ThisColDirectPathStartPos(Collider collider)
{
if (collider == null)
{
return false;
}
if (collider.gameObject == directLineTracePathPosStartColGo)
{
return true;
}
return false;
}
public bool CrnrContainsThisCol(Collider collider)
{
if (collider == null)
{
return false;
}
if (collider.gameObject == directLineTracePathPosStartColGo ||
collider.gameObject == directLineTracePathPosEndColGo)
{
return true;
}
return false;
}
public void SetNextPathInfo(SinglePathMsg nextPathInfo)
{
this.nextPathInfo = nextPathInfo;
}
public Vector3 GetClosestPortPos(Vector3 pos)
{
float dis1 = Vector3.Distance(pos, directLineTracePathPosStart);
float dis2 = Vector3.Distance(pos, directLineTracePathPosEnd);
if (dis1 instance;
}
public List loopPortTrns = new List();
public Transform startSpawnPort;
List pathMsgs = new List();
SinglePathMsg startPathMsg;
///
/// 一条直线路径上的两个端点之间直线行走部分的百分比
///
public float directLinePercent = 0.8f;
///
/// 广告牌行走路径顶视图看下去是否顺时针
///
public bool clockWise = true;
///
/// 广告牌直线行走的时间
///
public float singlePathADMoveTime = 10f;
///
/// 广告牌转角行走的时间
///
float aDTurnCrnrTime;
///
/// 转角部分的碰撞体的半径 不能太小 速度大而半径小容易导致检测不到
///
public float cornerPosColRadius = 1f;
public float adSelfColRadius = 1f;
///
/// 每隔几秒生成一个广告牌
///
float spawnTime;
///
/// 总的广告牌生成数量
///
public float spawnCount = 10;
Coroutine spawnCor;
GameObject adPref;
// Start is called before the first frame update
void Start()
{
instance = this;
adPref = GameObject.Find("cycladgo");
if (adPref == null)
{
Debug.LogError(" HallADLoopMgr Start not found ad go ");
return;
}
adPref.gameObject.SetActive(false);
for (int i = 0; i
关注
打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?