unity3d 可视化状态机_unity3d 可视化行为状态机 - CSDN
  • 原文地址:blog.liujunliang.com.cn在之前有过介绍一个可视化有限状态机编辑器插件PlayerMaker在这里也可以在我们的代码中实现一个状态机本文源码地址:点击打开链接首先创建一个脚本,来管理我们的各个状态using ...

    原文地址:blog.liujunliang.com.cn

    在之前有过介绍一个可视化有限状态机编辑器插件PlayerMaker

    在这里也可以在我们的代码中实现一个状态机

    本文源码地址:点击打开链接

    首先创建一个脚本,来管理我们的各个状态

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using System.Linq;
    
    /// <summary>
    /// 状态ID
    /// </summary>
    public enum FSMStateID
    {
        NullFSMStateID,
        PatrolFSMStateID,//巡逻状态
        ChaseFSMStateID,//追逐状态
    }
    
    
    /// <summary>
    /// 状态转化条件
    /// </summary>
    public enum FSMTransition
    {
        SeePlayer,//看到主角(目标)
        LeavePlayer,//远离敌人(目标)
    }
    
    public class FSMSystem
    {
        private FSMStateID mCurrentStateID;
        private FSMBaseState mCurrentState;
    
        private Dictionary<FSMStateID, FSMBaseState> mFSMStateDic = new Dictionary<FSMStateID, FSMBaseState>();
    
    
        public void AddFSMSate(FSMBaseState state)
        {
            if (state == null)
            {
                Debug.Log("角色状态为空,无法添加");
                return;
            }
            if (mCurrentState == null)
            {
                //第一个添加的状态被作为系统首个运行的状态
                mCurrentStateID = state.mStateID;
                mCurrentState = state;
                mCurrentState.StateStart();
            }
            if (mFSMStateDic.ContainsValue(state))
            {
                Debug.Log("容器内存在该状态");
                return;
            }
            mFSMStateDic.Add(state.mStateID, state);
        }
    
        public void DeleteFSMSate(FSMBaseState state)
        {
            if (state == null)
            {
                Debug.Log("角色状态为空,无法添加");
                return;
            }
            if (!mFSMStateDic.ContainsValue(state))
            {
                Debug.Log("容器内不存在该状态");
                return;
            }
            mFSMStateDic.Remove(state.mStateID);
        }
    
        //更新(执行)系统
        public void UpdateSystem()
        {
            if (mCurrentState != null)
            {
                mCurrentState.StateUpdate();
                mCurrentState.TransitionReason();
            }
        }
    
        //转换状态
        public void TransitionFSMState(FSMTransition transition)
        {
            FSMStateID stateID = mCurrentState.GetStateIdByTransition(transition);
            if (stateID != FSMStateID.NullFSMStateID)
            {
                mCurrentStateID = stateID;
                mCurrentState.StateEnd();
                //换状态
                mCurrentState = mFSMStateDic.FirstOrDefault(q => q.Key == stateID).Value;
                mCurrentState.StateStart();
            }
        }
    }
    



    各个状态(巡逻状态、追逐状态)抽象理解为一个对象

    创建一个状态基类,各个状态子类中可以继承重写这个基类方法

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using System.Linq;
    
    public abstract class FSMBaseState
    {
        public FSMStateID mStateID { get; set; }    //状态ID
        public FSMSystem mFSMSystem { get; set; }   //该对象属于在哪个状态机
    
        public Dictionary<FSMTransition, FSMStateID> mFSMStateIdDic = new Dictionary<FSMTransition, FSMStateID>();
    
        public FSMBaseState(FSMSystem fsmSystem, FSMStateID stateID)
        {
            this.mFSMSystem = fsmSystem;
            this.mStateID = stateID;
        }
    
        public void AddTransition(FSMTransition transition, FSMStateID stateID)
        {
            if (mFSMStateIdDic.ContainsKey(transition))
            {
                Debug.Log("本状态已经包含了该转换条件");
                return;
            }
            mFSMStateIdDic.Add(transition, stateID);
        }
    
        public void DeleteTransition(FSMTransition transition)
        {
            if (!mFSMStateIdDic.ContainsKey(transition))
            {
                Debug.Log("容器中没有该转换条件");
                return;
            }
            mFSMStateIdDic.Remove(transition);
        }
    
        public FSMStateID GetStateIdByTransition(FSMTransition transition)
        {
            if (!mFSMStateIdDic.ContainsKey(transition))
            {
                Debug.Log("容器内没有该转换条件,无法获取状态");
                return FSMStateID.NullFSMStateID;
            }
    
            return mFSMStateIdDic.FirstOrDefault(q => q.Key == transition).Value;
        }
    
        public abstract void StateStart();
        public abstract void StateUpdate();
        public abstract void StateEnd();
        //转化状态条件
        public abstract void TransitionReason();
    }
    


    以下是巡逻状态

    using System;
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class FSMPatrolState : FSMBaseState
    {
        //路径点
        private List<Transform> mStargetPointTransform = new List<Transform>();
        //路径点索引
        private int mPointIndex = 0;
        //士兵
        private GameObject mSliderObj { get; set; }
        //主角
        private GameObject mPlayerObj { get; set; }
        //士兵移动速度
        private float mMoveSpeed = 4f;
    
        public FSMPatrolState(FSMSystem fsmSystem) : base(fsmSystem, FSMStateID.PatrolFSMStateID) { }
    
        public override void StateStart()
        {
            //获取路径点
            Transform[] transforms = GameObject.Find("Points").GetComponentsInChildren<Transform>();
            foreach (var m_transform in transforms)
            {
                if (m_transform != GameObject.Find("Points").transform)
                {
                    mStargetPointTransform.Add(m_transform);
                    Debug.Log(m_transform.position);
                }
            }
    
            //获取士兵对象
            mSliderObj = GameObject.Find("Slider");
            //获取主角对象
            mPlayerObj = GameObject.Find("Player");
        }
    
        public override void StateUpdate()
        {
            //确实目标点并移动  
            mSliderObj.transform.LookAt(this.mStargetPointTransform[this.mPointIndex].position);
            mSliderObj.transform.Translate(Vector3.forward * Time.deltaTime * mMoveSpeed);
    
            if (Vector3.Distance(mSliderObj.transform.position, this.mStargetPointTransform[this.mPointIndex].position) < 0.5f)
            {
                //切换目标点
                this.mPointIndex++;
                if (this.mPointIndex >= this.mStargetPointTransform.Count)
                {
                    this.mPointIndex = 0;
                }    
            }
        }
    
        public override void StateEnd()
        {
            
        }
    
        public override void TransitionReason()
        {
            if (Vector3.Distance(mSliderObj.transform.position, mPlayerObj.transform.position) <= 2.0f)
            {
                //转化状态
                if (this.mFSMSystem == null)
                {
                    Debug.Log("目标状态机为空");
                    return;
                }
                mFSMSystem.TransitionFSMState(FSMTransition.SeePlayer);
            }
        }
    }
    


    以下是追逐状态

    using System;
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class FSMChaseState : FSMBaseState
    {
        private GameObject mPlayerObj { get; set; }
        private GameObject mSliderObj { get; set; }
        private float mSliderMoveSpeed = 6.0f;
    
        public FSMChaseState(FSMSystem fsmSystem) : base(fsmSystem, FSMStateID.ChaseFSMStateID) { }
    
        public override void StateStart()
        {
            mPlayerObj = GameObject.Find("Player");
            mSliderObj = GameObject.Find("Slider");
        }
    
        public override void StateUpdate()
        {
            if (Vector3.Distance(mPlayerObj.transform.position, mSliderObj.transform.position) <= 10.0f)
            {
                //开始面向主角
                mSliderObj.transform.LookAt(mPlayerObj.transform.position);
                //开始追逐
                mSliderObj.transform.Translate(Vector3.forward * Time.deltaTime * mSliderMoveSpeed);
            }
        }
    
        public override void StateEnd()
        {
            
        }
    
        public override void TransitionReason()
        {
            //当主角远离敌人
            if (Vector3.Distance(mPlayerObj.transform.position, mSliderObj.transform.position) > 10.0f)
            {
                //转化状态
                if (this.mFSMSystem == null)
                {
                    Debug.Log("目标状态机为空");
                    return;
                }
                mFSMSystem.TransitionFSMState(FSMTransition.LeavePlayer);
            }
        }
    }
    

    该状态机的优点在于当有不同类型的状态时候,可以直接添加到状态系统内,而不要需要状态系统内部的运行逻辑

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class Slider : MonoBehaviour
    {
        private FSMSystem fsmSystem { get; set; }
    
    	void Start ()
        {
            fsmSystem = new FSMSystem();
    
            //巡逻状态,在构造参数传一个系统参数,确定该状态是在哪个状态系统中管理的,状态转换的时候调用
            FSMBaseState patrolState = new FSMPatrolState(fsmSystem);
            patrolState.AddTransition(FSMTransition.SeePlayer, FSMStateID.ChaseFSMStateID);//巡逻状态转化条件
    
            //追逐状态
            FSMBaseState chaseState = new FSMChaseState(fsmSystem);
            chaseState.AddTransition(FSMTransition.LeavePlayer, FSMStateID.PatrolFSMStateID);
            
            fsmSystem.AddFSMSate(patrolState);
            fsmSystem.AddFSMSate(chaseState);
    	}
    	
    	void Update ()
        {
            fsmSystem.UpdateSystem();	
    	}
    }
    

    原文地址:blog.liujunliang.com.cn



    展开全文
  • Unity 可视化状态机

    2020-07-30 23:31:51
    包含状态机逻辑以及状态机可视化界面的unity package。
  • 1.这是State的实现:public class State{ private readonly List&lt;StateTransition&gt; transitions = new List&lt;StateTransition&gt;(); protected Action StartAction { get;...

    1.这是State的实现:

    public class State
    {
        private readonly List<StateTransition> transitions = new List<StateTransition>();
     
        protected Action StartAction { get; set; }
        protected Action StopAction { get; set; }
        protected Action UpdateAction { get; set; }
     
        protected internal bool IsStarted { get; set; }
     
        protected internal void Start()
        {
            if (!IsStarted && StartAction != null)
            {
                StartAction();
                IsStarted = true;
            }
        }
     
        protected internal void Update()
        {
            if (IsStarted && UpdateAction != null)
            {
                UpdateAction();
            }
        }
     
        protected internal void Stop()
        {
            if (IsStarted && StopAction != null)
            {
                StopAction();
                IsStarted = false;
            }
        }
     
        public State AddStartAction(Action startAction)
        {
            StartAction += startAction;
            return this;
        }
     
        public State AddUpdateAction(Action updateAction)
        {
            UpdateAction += updateAction;
            return this;
        }
     
        public State AddStopAction(Action stopAction)
        {
            StopAction += stopAction;
            return this;
        }
     
        public State AddTransition(Predicate<State> condition, State nextState)
        {
            transitions.Add(new StateTransition(condition, nextState));
            return this;
        }
     
        public bool CanGoToNextState(out State nextState)
        {
            for (int i = 0; i < transitions.Count; i++)
            {
                if (transitions[i].Condition(this))
                {
                    nextState = transitions[i].NextState;
                    return true;
                }
            }
     
            nextState = null;
            return false;
        }
     
        public bool HasNextState()
        {
            return transitions.Count != 0;
        }
    }

    public class StateTransition{

    public Predicate<State> Condition;

    public State NextState;

    public StateTransition(Predicate<State> condition,State nextState){

    Condition=condition;

    NextState=nextState;

    }

    2.这是StateMachine的实现:

    public class StateMachine : State
    {
        private readonly State initialState;
        public State CurrenState { get; private set; }
     
        public StateMachine(State initialState)
        {
            this.initialState = initialState;
            StartAction = Start;
            UpdateAction = Update;
            StopAction = Stop;
        }
     
        public new void Start()
        {
            if (IsStarted)
            {
                return;
            }
     
            CurrenState = initialState;
            CurrenState.Start();
            IsStarted = true;
        }
     
        public new void Update()
        {
            if (CurrenState == null)
            {
                return;
            }
     
            if (!CurrenState.IsStarted)
            {
                CurrenState.Start();
            }
     
            CurrenState.Update();
     
            State nextState;
            while (CurrenState.CanGoToNextState(out nextState))
            {
                if (CurrenState.IsStarted)
                {
                    CurrenState.Stop();
                }
     
                CurrenState = nextState;
     
                if (!CurrenState.IsStarted)
                {
                    CurrenState.Start();
                }
     
                CurrenState.Update();
            }
     
            if (!CurrenState.HasNextState())
            {
                Stop();
            }
        }
     
        public new void Stop()
        {
            if (CurrenState == null)
            {
                return;
            }
     
            if (CurrenState.IsStarted)
            {
                CurrenState.Stop();
            }
     
            CurrenState = null;
        }
    }


    Test:

    public class Test : MonoBehaviour
    {
        private StateMachine stateMachine;
     
        private State firstState = new State();
        private State secondState = new CustomState();
        private State finishState = new State();
     
        // Use this for initialization
        void Start ()
        {
            var initChild = new State()
                .AddStartAction(() => Debug.Log(Time.frameCount + " childInit Start"))
                .AddUpdateAction(() => Debug.Log(Time.frameCount + " childInit Update"))
                .AddStopAction(() => Debug.Log(Time.frameCount + " childInit Stop"));
            var childStateMachine = new StateMachine(initChild);
            stateMachine = new StateMachine(firstState);
     
            firstState
                .AddStartAction(() => Debug.Log(Time.frameCount + " 1 Start"))
                .AddUpdateAction(() => Debug.Log(Time.frameCount + " 1 Update"))
                .AddStopAction(() => Debug.Log(Time.frameCount + " 1 Stop"))
                .AddTransition(
                    state => Time.frameCount == 5,
                    secondState)
                .AddTransition(
                    state => Time.frameCount == 15,
                    secondState);
     
            secondState
                .AddTransition(
                    state => Time.frameCount == 10,
                    firstState)
                .AddTransition(
                    state => Input.GetKey(KeyCode.Q),
                    childStateMachine);
     
            childStateMachine
                .AddTransition(s => Input.GetKey(KeyCode.Y), finishState);
     
            finishState
                .AddStartAction(() => Debug.Log(Time.frameCount + " finish Start"));
     
            stateMachine.Start();
        }
     
        void Update()
        {
            stateMachine.Update();
        }
    }
     
    public class CustomState : State
    {
        public CustomState()
        {
            StartAction = CustomStart;
            UpdateAction = CustomUpdate;
            StopAction = CustomStop;
        }
     
        public void CustomStart()
        {
            Debug.Log(Time.frameCount + " custom start");
        }
     
        public void CustomUpdate()
        {
            Debug.Log(Time.frameCount + " custom update");
        }
     
        public void CustomStop()
        {
            Debug.Log(Time.frameCount + " custom stop");
        }
    }


    展开全文
  • 1.什么是有限状态机 有限状态机是把一个对象的行为分解称为易于处理的“块”或状态。例如,灯的开关,就是一个简单的有限状态机。它有两种状态:开和关。 假想一个机器小猫。它在肚子有一个插槽,放有很多模块...

    1.什么是有限状态机

    有限状态机是把一个对象的行为分解称为易于处理的“块”或状态。例如,灯的开关,就是一个简单的有限状态机。它有两种状态:开和关。

    假想一个机器小猫。它在肚子有一个插槽,放有很多模块(用来控制小猫的状态)。这些模块里包含这小猫的不同行为。例如:玩毛线、吃鱼,或者睡觉。如果没有一个模块,小猫就会是一个死气沉沉的金属雕塑品,只会静静坐着。猫在玩毛线的状态时,会监控小猫饥饿的等级,当它感到饥饿等级上升时,会自己把模块转换到吃鱼。吃鱼模块运行,直到小猫吃饱后,再跳回玩毛线状态。这只小猫就是我们的程序,里面的模块就是程序里的各种状态。

    2.为什么要用有限状态机

    通常,在一个程序里面,转换各种状态,需要使用一系列的if-then语句或者switch语句。比如:While(游戏未结束)

    {
    
      Switch(游戏状态)
    
      Case 资源加载:
    
      Case 进入关卡:
    
      Load_gate();//加载背景、飞机、炮弹的图片。
    
      Case 游戏菜单:
    
      If (游戏结束) 计算游戏结果
    
      ase 游戏进行:
    
      New_paodan();//产生新炮弹
    
      Move();//计算出该时刻飞机以及所有炮弹所在的位置
    
      Is_pengzhuang();//碰撞判断
    
      ase 游戏暂停:
    
      Thread_pause();//游戏暂停操作。
    
      • Draw()函数框架的伪代码如下:
    
      Draw()
    
      {
    
      Switch(游戏状态)
    
      Case 游戏进行:
    
      Draw_background();//绘制背景
    
      Draw_paodan();//画炮弹
    
      Draw_feiji();//画飞机
    
      Case 其他:
    
      略....
    
      } 
    

    这种方法容易理解,让人也觉得合理,但是当应用的再稍微复杂一点点,switch/if-then 这种方法就变成了一个怪物,它会潜伏起来等着突袭。随着更多状态和条件被加入,这种结构就像意大利面条一样跳来跳去,使得程序流程很难理解,你调试它也会是个噩梦。此外,它不灵活,当你第一次计划好整个程序时,你几乎肯定会发现,你需要经常的、频繁的修改switch/if-then语句(除非你是天才)。

    此外,当你想让对象处于初始进入状态或者退出状态时,你会常常需要一个状态完成一个制定的行动。例如,一个(敌人)对象进入逃跑状态,你可能会希望它挥着胳膊还道:啊!,当他最后逃脱并进入巡逻状态,你可能会希望它发出一声叹息,擦去额头的汗水。这些行为都只能是在进入或退出某个状态时出现的,而不会发生在通常的更新步骤中。因此,这个附加的函数必须理想地建立在你的switch/if-then语句中。在这个架构中你想做到这些,必定会咬牙切齿、恶心反胃,并且写出相当糟糕的代码。

    3.如何使用有限状态机

    整个程序的世界由BaseGameEntity继承来。它用来储存每个对象的ID号码,并且定义一个Update函数,在每个更新步骤被调用(unity3d中每个对象都自带了update函数,所以基类不需要再有)。

    BaseGameEntity类声明如下:

    public class BaseGameEntity : MonoBehaviour
    {
    
    	private int m_ID;//每个对象具有一个唯一的识别数字
    	
    	private static ArrayList m_idArray = new ArrayList();
    	public int ID ()
    	{
    		return m_ID;
    	}
    
    	protected void SetID (int val)
    	{
    		
    		//这个函数用来确认ID是否正确设置
    		if (m_idArray.Contains(val)) {
    			Debug.LogError ("id cuo wu ");
    			return;
    		}
    		
    		m_idArray.Add(val);
    		m_ID = val;
    	}
    	
    	public int getID(){
    		return m_ID;
    	}
    } 
    

    对象类从BaseGameEntity类继承,包含该对象的各种各样特性数据成员,例如这个对象是个人物角色,类中就包含它的健康、疲劳程度、它的位置,等等。一个对象有一个指向state(状态)类的实力,还有一个方法来改变指针指向的状态。

    public class People : BaseGameEntity {
    	//指向一个状态实例的指针
    	StateMachine m_pStateMachine;
    	//角色当前的位置
    	public location_type m_Location;
    	//矿工角色包中装了多少金块
    	public int m_iGoldCarried;
    	//矿工角色在银行存了多少钱
    	public int m_iMontyInBank;
    	//矿工角色口渴程度
    	public int m_iThirst;
    	//矿工角色疲劳程度
    	public int m_iFatigue;
    	
    	void Start () {
    		// 设置ID
    		SetID((int) People);
    		
    		//设置状态接口,并指向一个状态
    		m_pStateMachine = new StateMachine(this);
    		m_pStateMachine.SetCurrentState(People_GloballState .Instance());
    	}
    	
    	void Update ()
    	{	
    		//调用正在使用的状态		
    		m_pStateMachine.SMUpdate();
    	}
    	
    	public StateMachine GetFSM ()
    	{
    		//返回状态管理机
    		return m_pStateMachine;
    	}
    } 
    

    下面介绍角色的状态类。

    先看看状态基类:

    //C# 范型
    public class State
    {
    	
    	public entity_type Target ;
    	//进入状态  
    	public virtual void Enter (entity_type entityType)
    	{
    		
    	}
    
    	//状态正常执行
    	public virtual void Execute (entity_type entityType)
    	{
    		
    	}
    
    	//退出状态
    	public virtual void Exit (entity_type entityType)
    	{
    		
    	}
    } 
    

    再看看状态控制机的类:

    using UnityEngine;
    using System.Collections;
    
    public class StateMachine
    {
    	//entity 实体
    	private entity_type m_pOwner;
    
    	private State m_pCurrentState;
    	private State m_pPreviousState;
    	private State m_pGlobalState;
    
    	public StateMachine (entity_type owner)
    	{
    		m_pOwner = owner;
    		m_pCurrentState = null;
    		m_pPreviousState = null;
    		m_pGlobalState = null;
    	}
    	
    	public void GlobalStateEnter()
    	{
    		m_pGlobalState.Enter(m_pOwner);
    	}
    	
    	public void SetGlobalStateState(State GlobalState)
    	{
    		m_pGlobalState = GlobalState;
    		m_pGlobalState.Target = m_pOwner;
    		m_pGlobalState.Enter(m_pOwner);
    	}
    	
    	public void SetCurrentState(State CurrentState)
    	{
    		m_pCurrentState = CurrentState;
    		m_pCurrentState.Target = m_pOwner;
    		m_pCurrentState.Enter(m_pOwner);
    	}
    	public void SMUpdate ()
    	{
    		//全局状态的运行
    		if (m_pGlobalState != null)
    			m_pGlobalState.Execute (m_pOwner);
    		
    		//一般当前状态的运行
    		if (m_pCurrentState != null)
    			m_pCurrentState.Execute (m_pOwner);
    	}
    
    	public void ChangeState (State pNewState)
    	{
    		if (pNewState == null) {
    			
    			Debug.LogError ("该状态不存在");
    		}
    
    		//退出之前状态
    		m_pCurrentState.Exit(m_pOwner);
    		//保存之前状态
    		m_pPreviousState = m_pCurrentState;
    		
    		//设置当前状态
    		m_pCurrentState = pNewState;
    		m_pCurrentState.Target = m_pOwner;
    		//进入当前状态
    		m_pCurrentState.Enter (m_pOwner);
    	}
    
    	public void RevertToPreviousState ()
    	{
    		//qie huan dao qian yi ge zhuang tai 
    		ChangeState (m_pPreviousState);
    		
    	}
    
    	public State CurrentState ()
    	{
    		//fan hui dang qian zhuang tai 
    		return m_pCurrentState;
    	}
    	public State GlobalState ()
    	{
    		//fan hui quan ju zhuang tai 
    		return m_pGlobalState;
    	}
    	public State PreviousState ()
    	{
    		//fan hui qian yi ge zhuang tai 
    		return m_pPreviousState;
    	}
    
    	public bool HandleMessage (Telegram msg)
    	{
    		//the message
    		if (m_pCurrentState!=null && m_pCurrentState.OnMessage (m_pOwner, msg)) {
    			return true;
    		}
    		// message to the global state
    		if (m_pGlobalState!=null && m_pGlobalState.OnMessage (m_pOwner, msg)) {
    			return true;
    		}
    		
    		return false;
    	}
    } 
    

    角色的状态类继承自State基类:

    public class People_GloballState :State<People >
    {
    	private static People_GloballState instance;
    
    	//Singleton设计模式,确保了一个对象只能实例化一次,它是全局可访问的。
    	public static People_GloballState Instance ()
    	{
    		if (instance == null)
    			instance = new People_GloballState ();
    		
    		return instance;
    	}
    
    
    	public override void Enter (People Entity)
    	{
    		//base.Enter (Entity);
    	}
    
    	public override void Execute (People Entity)
    	{
    		//base.Execute (Entity);	
    	}
    
    	public override void Exit (People Entity)
    	{
    		//base.Exit (Entity);
    	}
    } 
    

    这是角色对象的全局状态,其它状态与之类似。

    如有任何疑问,可以发邮件给我讨论:liyuan0331@gmail.com。


    (转自:http://express.ruanko.com/ruanko-express_50/tech-overnight2.html)

    展开全文
  • PCL点云unity3D可视化

    2020-03-31 23:07:04
    下面这种方式是通过unity3D先构建出3D地图,将固定的物体大楼,交通灯,标志牌,等构建出来, 根据车辆当前位置,速度,传送到unity中,和当前的点云包,发送到unity进行解析,并通过画射线的方式展示...

            激光雷达采集出的点云一般使用pcl_view或相关工具查看,复杂点的是和相机的联合标定,将点画到图片上,

    两种方法展示都不够友好,也会限制算法人员的思路。

            下面这种方式是通过unity3D先构建出3D地图,将固定的物体大楼,交通灯,标志牌,等构建出来,

    根据车辆当前位置,速度,传送到unity中,和当前的点云包,发送到unity进行解析,并通过画射线的方式展示,

    可以更直观的查看点云在真实世界中的状态,也可直接做最终用户的展示。

    实现起来也很简单,用gl进行画线就可实现。

     

    有需要进一步了解的debugos@163.com

                                    qq:947956378

     

    展开全文
  • unity3d 简单状态机

    2018-07-24 23:38:47
    看了几篇文章,感觉还是看不太懂,几篇文章的写法都是不一样的。 本文参考该篇文章: https://blog.csdn.net/poem_qianmo/article/details/52824776 以下2篇可以看下: https://www.jianshu.com/p/ebabe7a9f61e...

    看了几篇文章,感觉还是看不太懂,几篇文章的写法都是不一样的。

    本文参考该篇文章:

    https://blog.csdn.net/poem_qianmo/article/details/52824776

    以下2篇可以看下:

    https://www.jianshu.com/p/ebabe7a9f61e 比较简单的一篇文章

    https://blog.csdn.net/ios_song/article/details/52327417 比较简单的一篇纯理论文章

    状态机有2中实现:

    switch:简单状态时使用。

    状态模式实现:用多态与虚函数,当有复制的状态和逻辑时使用。

     

    本篇文章写的很差,本人还是感觉没有理解状态机,之后会再看一次,理解之后再做修改。

    Switch实现如下:

    using UnityEngine;
    //几种不同的状态
    public enum EnemyState
    {
        idle,run,dead
    }
    //提供几种转换不同状态的方法,以及相应的行为动作
    public class EnemyFSMState : MonoBehaviour {

        private EnemyState currentState;
        // Use this for initialization
        void Start () {
            currentState = EnemyState.idle;
        }

        public void ChangeState(EnemyState state)
        {
            switch (currentState)
            {
                case EnemyState.idle:
                    currentState = state;
                    if (state == EnemyState.run)
                    {
                        print("过渡行为 idle -> run");
                        Action(EnemyState.run);
                    }
                    break;
                case EnemyState.run:
                    currentState = state;
                    if (state == EnemyState.dead)
                    {
                        print("过渡行为 run -> dead");
                        Action(EnemyState.dead);
                    }
                    break;
                case EnemyState.dead:
                    currentState = state;
                    Action(EnemyState.dead);
                    break;
            }
        }

        void Action(EnemyState state)
        {
            print("做出不同的动作 "+ state);
        }
        
        // Update is called once per frame
        void Update () {
            //switch (currentState)
            //{
            //    case EnemyState.idle:
            //        Action(EnemyState.idle);
            //        break;
            //    case EnemyState.run:
            //        Action(EnemyState.run);
            //        break;
            //    case EnemyState.dead:
            //        Action(EnemyState.dead);
            //        break;
            //}
        }
    }

     

    using UnityEngine;
    //发出动作,触发改变状态
    public class EnemyTigger : MonoBehaviour
    {
        private EnemyFSMState state;
        private void Start()
        {
            state = GetComponent<EnemyFSMState>();
        }
        private void Update()
        {
            if (Input.GetKeyDown(KeyCode.J))
            {
                state.ChangeState(EnemyState.idle);
            }
            else if (Input.GetKeyDown(KeyCode.K))
            {
                state.ChangeState(EnemyState.run);
            }
            else if (Input.GetKeyDown(KeyCode.L))
            {
                state.ChangeState(EnemyState.dead);
            }
        }
    }

     

    使用状态模式实现如下:

    using UnityEngine;

    //几种不同的状态
    public enum PlayerState
    {
        idle, run, dead
    }

    //几种不同的状态相同行为的部分
    public interface IStateAction
    {
        void Action(EnemyState state);
    }
    //不同状态的不同行为
    public class IdleState : IStateAction
    {
        public void Action(EnemyState state)
        {
            Debug.Log(" idle action ");
            if (state == EnemyState.run)
            {
                Debug.Log("过渡行为 run -> idle");
            }
        }
    }
    //不同状态的不同行为
    public class RunState : IStateAction
    {
        public void Action(EnemyState state)
        {
            Debug.Log(" run action ");
            if (state == EnemyState.idle)
            {
                Debug.Log("过渡行为 idle -> run");
            }
        }
    }
    //不同状态的不同行为
    public class DeadState : IStateAction
    {
        public void Action(EnemyState state)
        {
            Debug.Log(" dead action ");
        }
    }
    //状态的切换
    public class FSMState : MonoBehaviour
    {
        private EnemyState currentState;
        // Use this for initialization
        void Start()
        {
            currentState = EnemyState.idle;
        }
        public void ChangeState(IStateAction action, EnemyState state)
        {
            action.Action(state);
        }
    }

    using UnityEngine;

    //发出动作,触发改变状态
    public class PlayerTigger : MonoBehaviour
    {
        private FSMState state;
        private void Start()
        {
            state = GetComponent<FSMState>();
        }
        private void Update()
        {
            if (Input.GetKeyDown(KeyCode.J))
            {
                state.ChangeState(new IdleState(), EnemyState.run);
            }
            else if (Input.GetKeyDown(KeyCode.K))
            {
                state.ChangeState(new RunState(), EnemyState.dead);
            }
            else if (Input.GetKeyDown(KeyCode.L))
            {
                state.ChangeState(new DeadState(), EnemyState.dead);
            }
        }
    }

    展开全文
  • 有限状态机的基本思路(个人理解)  有限状态机,(英语:Finite-state machine,FSM),又称有限状态自动机,简称状态机,是表示有限个状态以及在这些状态之间的转移和动作等行为的数学模型。它反映从系统开始到...
  • 它既是一个可视化脚本工具,又是一个分层逻辑框架。设计师、程序员使用PlayMaker能够很快的完成游戏原型动作,既适合独立开发者,又适合团队合作。 Playmaker插件特点 1.很多动作行为(例如:跑,跳,攻击等)只...
  • Unity实现3D立体仓储可视化介绍视频介绍项目介绍登陆验证提升模拟穿梭车模拟项目结果及应用项目资料: 介绍 随着物流领域的发展,立体仓储技术越来越成熟。在物流装备的发展过程中,3D技术逐渐应用到物流控制系统...
  • Unity 下简易状态机的实现国庆到处都是人,我的建议是要么出国旅游,要么就宅在家把时间留给自己或家人。朋友约我去星巴克坐着重构代码,想想也是程序猿之间才有的默契。关于状态机,我想都知道它很常用,就像单例...
  • 洪流学堂,学Unity快人几步 欢迎一起进入2019年,在新的一年里Unity有什么大动作呢?本文带你浏览你最关心的Unity2019的核心功能! 你可能最关心的功能有哪些呢? 在Unity2019中,将会更加强调Package Manager这种...
  • 在UI界面制作过程中,一些复杂的界面...但具体到Unity里,利用GameObject的可视化编辑,可以把不同的界面状态通过编辑器的配置来完成,这样代码只需要一句话状态切换就可以完成繁琐的界面元素控制。 public class Game
  • 给角色调试动作,经常会用到状态机,那么一般来说如果就几个角色,那么用Unity可视化状态机编辑就挺方便了,但是如果有几十个甚至上百个角色的模型,要生成状态机,一个一个调试,不知道要花费多少时间精力,幸好...
  • Playmaker可视化脚本插件导入到Unity后,开始学习。一 、基本使用1.打开编辑器界面 顶部的菜单栏点击:PlayMaker-PlayMaker Editor打开状态机编辑器界面:2.添加状态机 根据提示,选择Hierarchy面板里一个物体,...
  •  为了更好地理解游戏的软件架构和对象模型,它获得更好的外观仅有一名Unity3D的游戏引擎和编辑器是非常有用的,它的主要原则。 Unity3D 引擎  Unity3D的是一个屡获殊荣的工具,用于创建交互式3D应用程序在多个...
  • 有限状态机算是Unity开发中一个比较重要的技巧了。在游戏中,我们可能会遇到各种各样的状态,这里我以一个人物为例,我们可能要经常判断人物的生命状态或者人物的运动状态,然后做相应的操作。 简单的有限状态机....
  • 过去的 2018 年,我们认为是国内工业互联网可视化的元年,图扑软件作为在工业可视化领域的重度参与者,一线见证了众多 HTML5/Web 化、2D/3D 化的项目在工业界应用落地,我们...数百个工业互联网2D/3D可视化案例集:...
  • 在之前有过介绍一个可视化有限状态机编辑器插件PlayerMaker 在这里也可以在我们的代码中实现一个状态机 本文源码地址:点击打开链接 首先创建一个脚本,来管理我们的各个状态 using System.Collections; ...
  • 过去的 2018 年,我们认为是国内工业互联网可视化的元年,图扑软件作为在工业可视化领域的重度参与者,一线见证了众多 HTML5/Web 化、2D/3D 化的项目在工业界应用落地,我们...数百个工业互联网2D/3D可视化案例集...
  • 3D可视化,就是把复杂抽象的数据信息,以合适的视觉元素及视角去呈现,方便大家理解、记忆、传递!因此,我们需要将影响应用系统稳定运行的几个要素数据可视化。比如:机房信息使用情况;配线管理运行情况,管线运行...
1 2 3 4 5 ... 20
收藏数 1,716
精华内容 686
关键字:

unity3d 可视化状态机