Too Long Didn’t Read / TL;DR: I wanted to add a tag team feature similar to Donkey Kong Country (SNES), asked Unity Answers a while ago, was given a script to work with, I don’t understand why a few things are written the way they are, and how they work. Want to know how to fully learn C# to make the needed changes I know I need to make to the script. Current version of the script is posted below.
Background: Self taught, and been using Unity3D for 2.5 yrs. Started with Javascript/Unityscript. Decided to learn C# and convert all of my Javascripts on a project to C#. I’ve been working on this project for 2 years. I believe I did so correctly because everything works as it should. Learned how to script through YouTube tutorials, forums, Google searching problems, going to a college game dev club (graduated college with a different degree, and moved, so I can’t visit with the Game Dev instructors anymore. They are busy.), and Unity’s learning section on their website.
Issue: I wanted to add a tag team feature similar to Donkey Kong Country’s follower in a 2D platformer. Searched online for ways to logically understand how it works in the game, but for some reason it seems to be hard to find. A year ago I thought to use this as a visual health system. Couldn’t get the feature to happen after 3 months of trying and decided not to use it to continue working on other features.
I believe 2 months ago I decided it is needed. Gave 1 month to try and figure it out myself, and last month (Feb) asked here on Unity Answers for guidance. Was given a script to work with yet I did not know why somethings were where they were and how somethings worked. I will add notes to the script below on what parts I do not understand fully below. It didn’t work completely the way I needed it to but it was close enough for me to tweak and edit around to get the result I needed. Tried to stayed in touch with the user who the example script, and update when I could.
I’m at a point where I feel I know logically what needs to be added, but I don’t know where to add these lines of code yet.
Question 2: I know that some users help in their free time, and are kind enough to give their time, but I know no one wants to “work” for free. Is there another effective way to get help or a second brain to help rethink the issue, or scan through a script? Like a Unity tutor program or paid bounty method? Thank you.
Current Version of Script (TargetFollower.cs):
using UnityEngine;
using System.Collections;
using System;
public class TargetFollower : MonoBehaviour
{
public Transform target = null; // This is the Player. In editor drag the Player here for now. Will script how to search for the Player later on.
public float followSpeed = 5f; // follow speed
public float targetDistance = 1.25f; // This value sets the distance the Player is from the Follower.
public bool targetDistanceY = true; // if near then update y only
[Serializable] //Shows in inspector ////####### Looked this up. Still not sure what this does entirely. With out it will the variables not show in the editor.
public class TargetRecord
{
public Vector3 position; // world position
public TargetRecord(Vector3 position) ////####### Not sure why "Vector3 position" is in (). What does this do?
{
this.position = position; ////####### Why does "this.position = position" need to be here? What does "this.position" do?
}
}
public TargetRecord[] _records = null; // keeps target data in time // type[] nameOfArray = lengthOfArray
////####### How does this create an array? and why is "_records = null" after TargetRecord[]?
private int _i = 0; // keeps current index for recorder
private int _j = 1; // keeps current index for follower
private TargetRecord _record = null; // current record
////####### Why is this some what repeated? Why have "public TargetRecord[] _records = null;" and then "private TargetRecord _record = null;"? Are they not the same thing?
private bool _recording = true; // stop recording if true
private int _arraySize = 6; // This needs to change to frames per second that way the follower follows at a specific distance on any frame rate on different devices.
public bool followSwitch = false; //Decide when to start following the player.
public bool recordData = false; //Start or stop recording data
public void Start()
{
_records = new TargetRecord[_arraySize]; ////####### What does this do? Why is it needed in the Start function?
}
// update Follower transform data
public void Update()
{
if (recordData)
{
RecordData(Time.deltaTime); ////####### How does this work exactly?
}
// move to the target
if ((target.position - transform.position).magnitude >= targetDistance)
{
followSwitch = true;
}
if (followSwitch == true)
{
//This triggers when the follower moves.
if (!_recording)
{
ResetRecordArray();
_recording = true;
////####### Never happens so not sure if this if statement is needed.
}
if (_record != null)
transform.position = Vector3.Lerp(_records[_i].position, _records[_j].position, Time.deltaTime); //Player is moving and they're position is being recorded. The follower then moves to the
//Debug.Log("1 - _records[_jiposition = " + _records[_i].position);
//Debug.Log("2 - _records[_j].position = " + _records[_j].position);
}
if (targetDistanceY && Mathf.Abs(target.position.y - transform.position.y) > targetDistance)
{
followSwitch = false;
if (_record != null) ////####### When would this be true? Only when "_record" is empty?
transform.position = Vector3.Lerp(transform.position, new Vector3(transform.position.x, target.position.y, transform.position.z), Time.deltaTime); //The follower is adjusting its Y axis because the Player is close and not moving.
}
}
private void RecordData(float deltaTime)
{
if (!_recording)
return; ////####### Never understood how "return" worked.
// record target data
_records[_i] = new TargetRecord(target.position); ////####### I am not sure how this works.
// set next record index
if (_i < _records.Length - 1)
_i++;
else
_i = 0;
// set next follow index
if (_j < _records.Length - 1)
_j++;
else
_j = 0;
// handle current record
_record = _records[_j];
}
// used if distance is small
private void ResetRecordArray()
{
_i = 0;
_j = 1;
_records = new TargetRecord[_arraySize];
for (int i = 0; i < _records.Length; i++)
{
_records *= new TargetRecord(transform.position);*
}
_record = _records[_j];
}
/// Gets the current record.
public TargetRecord currentRecord
{
get
{
return _record;
}
}
}