【问题标题】:List recording player movement列出记录播放器动作
【发布时间】:2021-02-17 07:15:04
【问题描述】:

我目前正在尝试测试我的 3D 概念,该概念涉及使用“过去的自己”或玩家的克隆来完成关卡。

我的第一个想法是只记录变换位置并相应地移动克隆,但这不允许你与过去的自己互动并创造一个悖论(这是你失败的一种方式)

所以我需要记录玩家的输入(左、右、抓取、跳跃和蹲伏),然后将它们实例化在玩家的克隆上,该克隆只会播放记录列表中的输入,而不是键盘。唯一的问题是我仍在努力掌握列表,所以我需要有关如何添加到列表的帮助。

CloneMovement(bool Jump,bool Crouch, bool Left, bool Right, bool Grab, bool Check)

【问题讨论】:

  • 在标签中省略统一对您没有帮助,并非所有 C# 程序员都编写游戏或统一编写游戏,因此大部分术语都会丢失和未知
  • 如果您只是想知道如何添加到列表中,那么我可以为您提供一个非常简单的答案。但是,如果您想知道如何使用列表来存储和播放游戏中的一系列事件,那么这个问题实际上是巨大的..
  • 我主要想知道如何将每个列表添加到具有多个变量的列表中。例如,我有一个 6 个布尔变量列表,与只有 1 个变量的列表相比,我只是对如何添加到该列表感到困惑

标签: c# unity3d


【解决方案1】:

创建和添加到列表非常简单。

创建列表:

List<float> listOfFloats = new List<float>();

尖括号中的数据类型可以是任何类型,例如List&lt;Vector3&gt;List&lt;MyCustomClass&gt;。重要的是列表只能保存一种数据类型的对象或值。你不能有一个包含整数、字符串和布尔值的列表。

添加到列表:

listOfFloats.Add(10f);

从列表中删除:

listOfFloats.Remove(10f); // this will remove the FIRST 10f value it finds
listOfFloats.RemoveAll(10f) // this remove all 10f values

Remove 方法也有返回值是毫无价值的。他们将返回他们删除的值、对象或列表。

现在,重要的是......列表可能不是解决您的问题的最佳集合类型。

您正在处理一系列事件。事件按顺序发生,除非该顺序需要是可变的,否则最好使用队列。

使用队列,您始终知道队列中的第一项是添加到队列中的第一个项目。因此,如果您从头到尾遍历队列,您将按顺序读取内容。

注意:如果您真的想知道如何记录一系列事件并在以后的某个任意时间以正确的顺序和正确的时间播放。这是一个非常非常大的问题。

【讨论】:

    【解决方案2】:

    我知道它很乱而且需要通读,但能够根据列表找出如何跟踪。当游戏运行并且克隆能够跟随时,这可以准确地工作。如果您认为队列仍然是一个更好的选择,请告诉我

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.UI;
    
    public class FPS : MonoBehaviour
    {
        //movement
        public Rigidbody rigi;
        float hori, verti, mHori, mVerti;
        Vector3 movement;
        public float jumpForce;
        public float gravityMultiplier;
        public float moveSpeed;
        float currentSpeed;
    
    
        //data track
        public bool tracking;
        private bool finTrack;
        bool jumping;
        bool interact;
        private int trackIndex;
        public List <Vector6> trackData = new List<Vector6>();
        public GameObject clone;
        public Transform camera;
        public GameObject LM;
    
        //Raycasting
        public LayerMask doorLayer;
        RaycastHit other;
        public Text hud;
    
    
        [System.Serializable]
        public class Vector6{
    
            public float hori;
            public float verti;
            public float mHori;
            public float mVerti;
            public bool jumping;
            public bool interact;
    
    
            public Vector6 (float h, float v, float mh, float mv, bool j, bool i ){
                hori = h;
                verti = v;
                mHori = mh;
                mVerti = mv;
                jumping = j;
                interact = i;
            }
    
    
        }
    
    
        void Start()
        {
    
            currentSpeed = 1;
            Physics.gravity *= gravityMultiplier; //GRAVITY MULTIPLY!
            camera.gameObject.SetActive(true);
            StartCoroutine("Track");
            trackData.Clear();
            gameObject.transform.SetParent(LM.transform);
    
        }
    
        void Update()
        {
    
    
            if(Physics.Raycast(transform.position, transform.forward, out other, 50f, doorLayer))
            {
                hud.text = "Press E to use" + other.collider.gameObject.name;
            }
    
            else hud.text = "";
    
    
    
            //TRACKING VERSION
            if (!finTrack)
            {
                hori = Input.GetAxis("Horizontal");
                verti = Input.GetAxis("Vertical");
                mHori = Input.GetAxis("Mouse X");
                mVerti = Input.GetAxis("Mouse Y");
    
                //JUMPING
                if (Input.GetKeyDown(KeyCode.Space)){
                    rigi.AddForce(new Vector3(0, jumpForce, 0), ForceMode.Impulse);
                    jumping = true;
                }
                else jumping = false;
    
                if(Input.GetKeyDown(KeyCode.E))
                {
                    if(Physics.Raycast(transform.position, transform.forward, out other, 50f, doorLayer))
                    {
                    other.collider.SendMessage("Use");
                    interact = true;
                    }
                }
                else interact = false;
    
    
            }
    
            ///RECORDED VERSION
            else if(trackIndex < trackData.Count)
            {
                hori = trackData[trackIndex].hori;
                verti = trackData[trackIndex].verti;
                mHori = trackData[trackIndex].mHori;
                mVerti = trackData[trackIndex].mVerti;
    
    
    
    
                if (trackData[trackIndex].jumping)
                {
                    rigi.AddForce(new Vector3(0, jumpForce, 0), ForceMode.Impulse);
                }
    
                if (trackData[trackIndex].interact)
                {
                    if(Physics.Raycast(transform.position, transform.forward, out other, 70f, doorLayer))
                    {
                        other.collider.SendMessage("Use");
                    }
                }
    
                trackIndex++; 
    
    
            }
    
            movement.x = hori * moveSpeed * currentSpeed;
            movement.z = verti * moveSpeed * currentSpeed;
            movement.y = rigi.velocity.y;
    
    
            rigi.velocity = transform.TransformDirection(movement);
    
            //HEAD MOVEMENT
    
    
            camera.Rotate(-mVerti, 0, 0);
            transform.Rotate(0, mHori, 0);
    
    
    
    
    
    
        }
        void Reset()
        {
    
            Transform oriPos = GameObject.FindWithTag("OriPos").transform;
            transform.position = oriPos.position;
            transform.rotation = oriPos.rotation;
            trackIndex = 0;
    
        }
    
    
        //tracking 
        IEnumerator Track()
        {
            tracking = true;
            while ( tracking )
            {
                trackData.Add(new Vector6(hori,verti,mHori,mVerti,jumping,interact));
                if(Input.GetKeyDown(KeyCode.Q))
                {
                    tracking = false;
    
    
                }
                yield return null;
            }
            Transform oriPos = GameObject.FindWithTag("OriPos").transform;
            transform.position = oriPos.position;
            transform.rotation = oriPos.rotation;
            camera.gameObject.SetActive(false);
            Instantiate(clone, oriPos.position, oriPos.rotation);
            finTrack = true;
    
    
    
    
            //Restart 
        }
    }
    

    【讨论】:

    • 一个列表可以很好地说明你是如何实现的。我想象你以不同的方式实施它。队列不适合这种实现。
    猜你喜欢
    • 1970-01-01
    • 2012-02-03
    • 2013-05-10
    • 2016-05-23
    • 1970-01-01
    • 1970-01-01
    • 2016-12-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多