0
votes

I'm currently trying to test out a 3D concept I had that involves working with "past selves" or clones of the player to finish the level.

My first thought was to just record transform positions and move the clone accordingly but this doesn't allow for you to interact with your past self and create a paradox (which is one of the ways you can fail a level)

So I need to record player inputs (left, right, grab, jump, and crouch) and then instantiate them on a clone of the player that will just play back the inputs from the list of records rather than the keyboard. The only problem is I'm still trying to grasp my head around lists so i need help with how to go about adding to the list.

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

2
Leaving unity out of your tags will not be helping you here, not all C# programmers write games or write them in unity, hence most of the terminology would be lost and unknown - TheGeneral
If you just want to know how to add to lists then I can provide you with a very simple answer. If, however, you want to know how you could use a list to store and playback a sequence of events from your game then this question is actually huge.. - HumanWrites
i want to mainly know how i can add to lists with multiple variables per listing. For example i have a 6 bool variable list and im just abit confused as to how to then add to that list compared to lists with only 1 variable - Josh

2 Answers

0
votes

I know its messy and alot to read through, but was able to figure out how to track based off the list. this works accurately when the game runs and the clones are able to follow. Let me know if you think queue would still be a better option to try

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 
    }
}
0
votes

Creating and adding to lists is pretty straight forward.

Creating a list:

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

The data type in the angle brackets can be anything e.g List<Vector3> or List<MyCustomClass>. The important thing is that Lists can only hold objects or values of one data type. You can't have a list that holds ints and strings and bools.

Adding to a list:

listOfFloats.Add(10f);

Removing from a list:

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

It's worth nothing that the Remove methods also have a return value. They will return the value, object or List that they removed.

Now, the important thing is... a list is probably not the best collection type for your problem.

You are dealing with an sequence of events. The events happen in an order and, unless that order needs to be mutable, you're probably better of using a Queue.

With a Queue, you always know that the first item in the Queue was the first thing that was added to the Queue. Therefore, if you iterate over the Queue from start to end, you will be reading the contents in order.

Note: If you actually really want to know how to record a sequence of events and play it back in the correct sequence and with the correct timing at some arbitrary time later. That is a very, very big question to answer.