[Unity] Unity3D如何通过指令控制角色

查看:523 |回复:4 | 2021-2-23 10:19:43

您需要 登录 才可以下载或查看,没有账号?注册

x
本帖最后由 源数之力 于 2021-3-2 14:42 编辑

作为Unity3D的初学者,在目前学习开发中遇到一个困扰一周的问题。
目前要实现这样一个功能:对物体输入一连串的指令来控制物体移动,物体会按照指令依次执行下去,但是目前想实现一个循环和判断指令,就类似于while和if语句。
没想到一个比较好的处理方法,求指教!
2021-2-23 10:19:43  
 赞 赞 0

使用道具 登录

4个回答,把该问题分享到群,邀请大神一起回答。
2#

使用命令模式 把命令封成对象 然后不管用Update还是协程 都行

也可以将行为都做成一个协程

下面结构可以参考一下

    public class PlayQueuedSystem {        static Dictionary<CoroutineQueued, PlayQueuedSystem> coroutineQueueds;        /// <summary>        /// 协程队列组        /// </summary>        public static Dictionary<CoroutineQueued, PlayQueuedSystem> CoroutineQueueds {            get {                if (coroutineQueueds == null)                    coroutineQueueds = new Dictionary<CoroutineQueued, PlayQueuedSystem>();                return coroutineQueueds;            }                    }        /// <summary>        /// 所有者        /// </summary>        MonoBehaviour sender;        public Queue<PlayQueueItem> PlayQueue { get; private set; }        /// <summary>        /// 是否正在运行        /// </summary>        public bool Runing {            get { return runing; }        }        private bool runing = false;        public PlayQueuedSystem(MonoBehaviour sender, CoroutineQueued queued) {            PlayQueue = new Queue<PlayQueueItem>();            this.sender = sender;            if (!CoroutineQueueds.ContainsKey(queued))            {                CoroutineQueueds.Add(queued, this);            }            else                Debug.LogError ("重复的CoroutineQueued");        }        public PlayQueuedSystem(MonoBehaviour sender)        {            PlayQueue = new Queue<PlayQueueItem>();            this.sender = sender;        }        public void AddQueueItem(PlayQueueItem queueItem) {            if (PlayQueue == null)                PlayQueue = new Queue<PlayQueueItem>();            PlayQueue.Enqueue(queueItem);        }        /// <summary>        /// 开始运行协程队列        /// </summary>        public void StartQueue() {            runing = true;            IEnumerator queueRuning = QueueRuning();            MonoTools.AddCoroutines(sender, this, sender.StartCoroutine(queueRuning), queueRuning);        }        /// <summary>        /// 停止队列执行,不会影响正在实行的内容        /// </summary>        public void StopQueue() {            runing = false;        }        Coroutine nowIEnumerator;        IEnumerator QueueRuning() {            while (runing) {                if (PlayQueue.Count > 0)                {                    nowIEnumerator = sender.StartCoroutine(MonoTools.QueueItem(PlayQueue.Dequeue(), null));                    yield return nowIEnumerator;                }                else                    yield return new WaitForSeconds(0.5f);            }        }        /// <summary>        /// 略过当前执行协程        /// </summary>        /// <param name="nowIEnumerator"></param>        public void IgnoreNowCoroutine(Coroutine nowIEnumerator) {            if(nowIEnumerator!=null)                sender.StopCoroutine(nowIEnumerator);        }    }}
回复 收起回复
2021-2-23 10:29:53   回复
 赞 赞 0

使用道具 登录

3#
楼上的回答太专业了吧
回复 收起回复
2021-8-28 07:47:13   回复
 赞 赞 2

使用道具 登录

4#
Unity3D 控制角色(一)
最简单的移动 脚本挂到需要控制的角色上
    public float MoveSpeed = 15.0f;
    public float RotateSpeed = 80.0f;

    void Update () {
        if (Input.GetKey(KeyCode.W) || Input.GetKey(KeyCode.UpArrow))
        {
            transform.Translate(0, 0, 1 * MoveSpeed * Time.deltaTime, Space.Self);
        }
        if (Input.GetKey(KeyCode.S) || Input.GetKey(KeyCode.DownArrow))
        {
            transform.Translate(0, 0, -1 * MoveSpeed * Time.deltaTime, Space.Self);
        }
        if (Input.GetKey(KeyCode.A) || Input.GetKey(KeyCode.LeftArrow))
        {
            transform.Translate(-1 * MoveSpeed * Time.deltaTime, 0, 0, Space.Self);
        }
        if (Input.GetKey(KeyCode.D) || Input.GetKey(KeyCode.RightArrow))
        {
            transform.Translate(1 * MoveSpeed * Time.deltaTime, 0, 0, Space.Self);
        }


        if (Input.GetKey(KeyCode.Q))
        {
            transform.Rotate(0, -1 * RotateSpeed * Time.deltaTime, 0, Space.Self);
        }
        if (Input.GetKey(KeyCode.E))
        {
            transform.Rotate(0, 1 * RotateSpeed * Time.deltaTime, 0, Space.Self);
        }
    }


所在代码
ControlCharacter001.cs

对上述方法的说明
方法直接操作对象的tranform组件
写在Update中每帧调用
translate中的三个坐标值表示的是相对当前位置的位移向量 位移(距离)=速度*时间 时间则是time.deltaTime(单位是秒 表述的是从上一帧到本帧经过的时间 是变化的 速度的单位是米每秒)
对外部暴露2个速度变量可修改(移动和旋转)
Time.deltaTime用于协调线性,保证帧与帧之间速度一致,因为帧间隔随机器性能不同,使用Time.deltaTime可以保证是匀速运动
不使用Time.deltaTime的后果是在前端表现出卡顿 速度虽然可以通过2个公有变量进行调整
关于Time.deltaTime参看 https://blog.csdn.net/wdjhzw/art ... locationNum=7&fps=1
————————————————
版权声明:本文为CSDN博主「coldwind811201」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/coldwind811201/article/details/80882593
回复 收起回复
2021-8-28 13:02:40   回复
 赞 赞 1

使用道具 登录

5#
元素是个好家园,加油啊
回复 收起回复
2022-11-3 17:59:59   回复
 赞 赞 1

使用道具 登录

CG 游戏行业专业问题

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表