Unity数字孪生开发笔记——轿厢基本运动实现

  • 一、轿厢实例说明
  • 二、需求分析
    • 1、轿厢移动
      • 1>楼层信息
      • 2>轿厢运动
    • 2、对重移动
    • 3、开关门动画
      • 1>挂载到物体上的动画类
      • 2>普通C#动画类
    • 4、轿厢AI
  • 三、效果图

一、轿厢实例说明

  • 楼层信息获取----包括楼层名和在各楼层时轿厢的位置;
  • 轿厢上下移动----判断当前位置与目标点的距离,通过距离的正负来决定移动方向;
  • 对重移动----对重的移动取决于轿厢,同时与轿厢应保持速度相同和运动方向相反;
  • 开关层门与轿厢门----根据轿厢的状态以及轿厢当前位置判断是否停靠在某一层,播放动画;
  • 轿厢AI----根据情况自动调用以上各部分。

二、需求分析

1、轿厢移动

  • 定义列表变量----楼层信息
  • 轿厢运动状态判断及运行----上行、下行、停止

1>楼层信息

using System.Collections;
using System.Collections.Generic;
using UnityEngine;/// <summary>
/// 定义状态信息类,定义轿厢人员信息,
/// </summary>
public class StatusInfo : MonoBehaviour
{/// <summary>/// 当前电梯人数/// </summary>public int people = 2;/// <summary>/// 电梯可承载人数最大值/// </summary>public int maxPeople = 12;/// <summary>/// 当前正在走进或走出电梯的人数/// </summary>public int amountPeople = 2;/// <summary>/// 人员流动/// </summary>public bool MovePeople(){int currentPeople = people + amountPeople;//如果当前电梯没人或者没有人员流动if (people == 0 || currentPeople == people)return false;//如果电梯当前人数大于最大承载量else if (currentPeople > maxPeople)return false;elsereturn true;}}

2>轿厢运动

using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;/// <summary>
/// 控制轿厢移动
/// </summary>
public class Move : MonoBehaviour
{public Transform[] points;public WayLine line;//当前路点索引private int currentPointIndex=0;public float MoveSpeed = 5;/// <summary>/// 定义轿厢运行状态/// </summary>public enum CarState{up,down,stop}public CarState carCurrentState = CarState.stop;/// <summary>/// 轿厢状态判断/// </summary>/// <param name="point">目标点坐标</param>public CarState CarStateJudge(Vector3 point){if (this.transform.position.y < point.y && (decimal)Vector3.Distance(this.transform.position, point) > 0.05m)return carCurrentState = CarState.up;else if (this.transform.position.y > point.y && (decimal)Vector3.Distance(this.transform.position, point) > 0.05m)return carCurrentState = CarState.down;elsereturn carCurrentState = CarState.stop;}/// <summary>/// 轿厢上行、下行、停止/// </summary>/// <param name="point">目标点</param>public void CarMovement(){try{//如果当前楼层的索引小于存储的楼层数if (currentPointIndex < points.Length){CarStateJudge(points[currentPointIndex].position);switch (carCurrentState){case CarState.up:this.transform.Translate(0, MoveSpeed * Time.deltaTime, 0);break;case CarState.down:this.transform.Translate(0, -MoveSpeed * Time.deltaTime, 0);break;case CarState.stop:this.transform.Translate(0, 0, 0);break;}}            }catch { }}/// <summary>/// 寻路,沿路线(Vector3[])移动/// </summary>/// <returns></returns>public bool Pathfinding(){//如果到达目标点(判断 当前位置 与 目标点间距 Vector3.Distance)//更新目标点(向下一个路点移动)if (points == null || currentPointIndex >= points.Length){this.transform.Translate(0, 0, 0);return false;}else{//移动CarMovement();//如果到达目标点(当前位置 趋近于 目标点)if ((decimal)Vector3.Distance(this.transform.position, points[currentPointIndex].position) < 0.05m)currentPointIndex++;return true;//可以继续寻路}                }}

2、对重移动

  • 对重移动与轿厢移动相反,同时要跟随轿厢移动
  • 欠缺:只能将轿厢的位置放在最高,对重的位置放在最低,后期可能会想着将这两个对象的位置时刻关联(估计有难度)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;/// <summary>
/// 对重移动
/// </summary>
public class CWMove : MonoBehaviour
{/// <summary>/// 根据轿厢状态判断对重运行状态/// </summary>/// <param name="car">轿厢</param>public void CwMoveByCar(bool IsRun,Move carmove){//轿厢是否在移动if (IsRun == true){//轿厢往上还是往下移动if (carmove.carCurrentState == Move.CarState.down){this.transform.Translate(0,0, -carmove.MoveSpeed*3 * Time.deltaTime);}else if (carmove.carCurrentState == Move.CarState.up)this.transform.Translate(0, 0,carmove.MoveSpeed *3* Time.deltaTime);}elsethis.transform.Translate(0, 0, 0);}
}

3、开关门动画

1>挂载到物体上的动画类

using System.Collections;
using System.Collections.Generic;
using UnityEngine;/// <summary>
/// 开关门动画,定义需要播放的动画片段名称
/// </summary>
public class DoorAnimation : MonoBehaviour
{public string[] BuildingDoor; /// <summary>/// 行为类/// </summary>public Animations action;private void Awake(){//查找后代中具有Animation组件的子物体(有则返回第一个,无返回null)action = new Animations(GetComponentInChildren<Animation>());}
}

2>普通C#动画类

  • 目前遇到问题----如何将同一个动画正播后停止在最后一帧,在过几秒钟后将该动画倒播回去
using System.Collections;
using System.Collections.Generic;
using UnityEngine;/// <summary>
/// 动画行为类,提供有关动画的行为
/// </summary>
public class Animations
{//附加在敌人模型上的动画组件引用private Animation anim;/// <summary>/// 创建动画行为类/// </summary>/// <param name="anim">附加在敌人模型上的动画组件引用</param>public Animations(Animation anim){this.anim = anim;}//播放动画public void Play(string animName){//anim.CrossFade(animName);anim.Play(animName);}/// <summary>/// 判断指定动画是否正在播放/// </summary>/// <param name="animName">动画片段名称</param>/// <returns></returns>public bool IsPlaying(string animName){return anim.IsPlaying(animName);}
}

4、轿厢AI

  • 定义电梯状态信息----运动、停止、待机、检修
  • 根据每个状态来定义各自实现的功能
  • 运行过程如果到达目标层----状态改为停止
  • 若不在规定的楼层停止----状态改为检修,在规定的楼层停止----播放开关门动画,没人后状态改为待机
  • 若在待机过程中,目标位置发生改变----运行状态改为运动
  • 欠缺:停止过程的动画只能播放一次(目前是倒播),DeBug过程他也能进去,但实际就是不管用,试了好几个函数都没用(气的暂停这步了)
  • 欠缺:检修状态的事件暂时没想到
using System.Collections;
using System.Collections.Generic;
using UnityEngine;/// <summary>
/// 轿厢AI
/// </summary>
[RequireComponent(typeof(DoorAnimation))]
[RequireComponent(typeof(StatusInfo))]public class CarAI : MonoBehaviour
{//定义轿厢状态的枚举类型public enum State{Run,//运行Stop,//停止Check,//故障Rest//休息}private State currentState = State.Run;private DoorAnimation anim;private Move move;private CWMove cw;private FloorInfo floor;private StatusInfo stf;private void Start(){anim = GetComponent<DoorAnimation>();move = GetComponentInChildren<Move>();cw = GetComponentInChildren<CWMove>();floor = GetComponentInChildren<FloorInfo>();floor.AddFloor();stf = GetComponent<StatusInfo>();}private void Update(){//判断switch(currentState){case State.Run:Run();break;case State.Stop:Stop();break;case State.Rest:Rest();break;case State.Check:Check();break;}}/// <summary>/// 判断在电梯停在哪层/// </summary>private void Stop(){//判断电梯是否停好了bool IsStopOk = false;int fl = 0;//运行停止//播放轿厢开门动画foreach (KeyValuePair<int,Vector3>kv in floor.Floor){//判断当前位置与某一楼层的位置是否接近if((decimal)Vector3.Distance(move.transform.position, kv.Value) < 0.05m){if (kv.Key == -1){anim.action.Play(anim.BuildingDoor[0]);}                    else{anim.action.Play(anim.BuildingDoor[kv.Key]);//播放开门动画fl = kv.Key;//拿到楼层信息}IsStopOk = true;//电梯停好了break;}}if(IsStopOk==true){float i = 0;while (true){   i += Time.deltaTime;//如果超过2秒没人,播放关门动画if (i >= 2 && stf.MovePeople() == false){anim.action.Close(anim.BuildingDoor[fl]);currentState = State.Rest;break;}}                      }else{currentState = State.Check;//将电梯标记为出故障}}private void Run(){//执行寻路(调用move中的寻路方法)move.Pathfinding();cw.CwMoveByCar(move.Pathfinding(), move);//如果寻路结束,修改状态为停止if (move.Pathfinding() == false) currentState = State.Stop;}private void Rest(){//Debug.Log("电梯处于待机状态");move.carCurrentState = Move.CarState.stop;move.CarMovement();if (move.CarStateJudge(move.points[0].position) != Move.CarState.stop)currentState = State.Run;}private void Check(){//Debug.Log("电梯故障,请及时处理");}
}

三、效果图

  • 整体缺陷:
    1、使用Translate进行移动,会存在到了指定楼层后一直上下抖动的情况,导致动画不播放(其实把判断的距离设大就行,但是看起来就不贴合实际了)
    2、同一个动画的正播和反播问题
    3、初步想法,后期有待完善

Unity数字孪生开发笔记——轿厢基本运动实现相关推荐

  1. Unity3D数字孪生开发笔记——网络篇

    Unity3D数字孪生开发笔记(一) 一.网络连接的端点:Socket 二.端口 三.Socket通信流程 四.TCP和UDP 一.网络连接的端点:Socket 1.网络上的两个程序通过一个双向的通信 ...

  2. 大爱 unity 数字孪生 老卵了 Unity 数字孪生笔记1 工具介绍

    Unity 数字孪生笔记1 工具介绍 火锅肥牛 2020-05-16 20:19:10   106   收藏 1 展开 前言 工欲善其事必先利其器 流程思考 数字孪生本质上一种基于实际物理数据的可视化 ...

  3. Unity 数字孪生笔记1 工具介绍

    前言 工欲善其事必先利其器 流程思考 数字孪生本质上一种基于实际物理数据的可视化方案,通过对接实际数据,在三维界面中展示孪生结果. 那么这个流程就很简单了. 整个流程分为三块:数据来源->数据分 ...

  4. Unity 3D引擎助力新城建发展,Unity数字孪生驱动智慧城市的未来

    今年是十四五的开局之年,也是数字中国建设的重要节点,在这个"新城建"时代,Unity数字孪生逐渐获得了更多的应用场景.在近日举办的第七届工程建设行业互联网大会上,Unity携市政基 ...

  5. 数字孪生开发 数字孪生用什么软件实现

    无论你是否知道,数字孪生真的很火.将智慧城市作为技术基础,其发展日新月异,2016年时,全国已有300多个城市在数字孪生建设智慧城市:2019年,这一数字为500,再过一年,就有700座数字孪生进行试 ...

  6. 数字孪生开发公司 数字孪生开发团队 智慧工厂开发

    数字孪生开发智慧城市,数字孪生开发智慧城管,数字孪生开发智慧电力,数字孪生开发智慧高速,数字孪生开发智慧气象,数字孪生开发智慧水务,数字孪生开发公共安全,数字孪生开发智慧警务,数字孪生开发智慧安保,数 ...

  7. Unity 数字孪生笔记2.1 PiXYZ Studio 工作流简介

    前言 UnReferenceException 为什么引入Pixyz Studio Pixyz是Unity的模型导入工具之一,但是Pixyz作为业界领先的模型处理工具,其产品不止有Pixyz plug ...

  8. P2【商业级MMORPG大型网游】Unity全栈开发 笔记

    入门unity开发笔记 已报名,见评论.刚刚开始学习unity3d,今天我将开发我的第一个项目.一是项目的规划. 1. 游戏玩法是一种冒险玩法,类似于<马里奥>,但它是基于3D视角开发的. ...

  9. 数字孪生开发平台 数字孪生开发成本 数字孪生开发平台cortona3d

    数字孪生新型智慧城市开发设计,数字孪生交互平台开发,数字孪生智慧工厂开发设计,数字孪生智慧社区开发设计,数字孪生系统软件开发,数字孪生体开发设计,数字孪生模块开发设计,数字孪生应用领域,数字孪生运用实 ...

最新文章

  1. cn.hutool.poi.excel.ExcelUtil 时不时没有数据列
  2. Winform中选取指定文件夹并获取其下所有文件
  3. 对我影响最大的三个老师
  4. win7 计算器 android,教你巧妙应用Win7计算器和时钟
  5. idea中删除java类并提交_IDEA 删除java类的3种提示
  6. C++实现简单的二叉树
  7. iptables 命令详解
  8. VSTO安装卸载方法
  9. eclipse插件下载速度慢,可以这样解决
  10. Swiper参数说明(swiper参数配置)
  11. PowerBI系列之什么是PowerBI
  12. android 通话自动录音服务
  13. 【大数据离线开发】1、大数据准备环境之Linux配置
  14. 解决java关键字和bean变量名内容冲突的神器
  15. web前端期末大作业 html+css+javascript网页设计实例 企业网站制作 (绿色植物网站设计)...
  16. 互联网java常见面试题
  17. 计算机网络自顶向下方法笔记01
  18. 钉钉小程序快照技术初窥
  19. 关于Vue的就地复用
  20. 做人做事的艺术html,人生三会:会做人、会说话、会做事

热门文章

  1. select下拉框的动态加载
  2. 太好玩了,我用Python写了个火影忍者版的连连看 !
  3. 利用Python爬取年终总结等文字,并保存为公文格式的word文档
  4. 记一次添加桌面二次元人物的经历
  5. 多闪上线满月 中国区iOS下载量已超500万
  6. 吐槽 依赖倒置原则/DIP
  7. Linux基础 个人VPS安全
  8. MW4530R升级openwrt
  9. 正大国际期货:恒生指数交易平台
  10. XP下岗,忽悠方案不靠谱