您当前的位置: 首页 >  unity

染指流年灬

暂无认证

  • 3浏览

    0关注

    194博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

Unity 物体简单多边形绕圈实现

染指流年灬 发布时间:2020-02-20 22:08:38 ,浏览量:3

这里的代码的功能有

  • 给出矩形四个转角点
  • 生成若干个物体(这里是广告牌)围绕这四个转角点匀速转圈
  • 转角呈圆角形状 过度自然

这段代码可以简单拓展到绕多边形形状转动,应该不需要改什么代码,后面有时间会拓展玩玩看

下面的代码放好之后挂载脚本然后在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             
关注
打赏
1665909078
查看更多评论
0.0417s