Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by z7x9r0 · Mar 24, 2016 at 07:45 PM · c#2dplatformer

Any way to completely learn to script in C# using Unity?

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[i] = new TargetRecord(transform.position);
         }
 
         _record = _records[_j];
     }
 
     /// Gets the current record.
     public TargetRecord currentRecord
     {
         get
         {
             return _record;
         }
     }
 }
Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

3 Replies

· Add your reply
  • Sort: 
avatar image
2

Answer by Graphics_Dev · Mar 24, 2016 at 08:27 PM

https://store.unity3d.com/products/support

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image z7x9r0 · Apr 09, 2016 at 06:03 PM 0
Share

Thank you for the link. I had no idea this existed.

avatar image
1

Answer by Masterio · Mar 24, 2016 at 08:39 PM

First you need to learn structural and object programming. I am learning too btw so my code is not perfect for sure:) but it works for settings: fps 60 and speed 500+.

I pasted my oryginal code posted on this forum some time ago. With answers for your questions.

 using UnityEngine;
 using System.Collections;
 using System;
 
 /// Author: Matthew Mazan [Masterio]
 public class TargetFollower : MonoBehaviour 
 {
     public Transform target = null;                    // follow by target
     public float reactDelay = 1f;                    // how fast it react to target moves [edit it in edit mode only]
     public float recordFPS = 60f;                    // how many record data in one second [edit it in edit mode only]
     public float followSpeed = 500f;                    // follow speed
     public float targetDistance = 0f;                // don't move closer than this value
     public bool targetDistanceY = false;            // if near then update y only
     public bool targetPositionOnStart = false;        // set the same position as target on start
     public bool start = false;                        // start or stop follow    
     #if UNITY_EDITOR
     public bool gizmo = true;                        // draw gizmos
     #endif
     
     // ### I am serailze that only for one reason, _records array with values will be visible in debug mode in unity inspector.
     [Serializable] 
     public class TargetRecord
     {
         public Vector3 position;                    // world position
         
         // we can add more data if we need here
         
         public TargetRecord(Vector3 position)
         {
             this.position = position;
         }
     }
     
     // ### The _recrods is not initialized here so this is why it is null, you can do the same thing with: TargetRecord[] _record;
     private TargetRecord[] _records = null;            // keeps target data in time
     private float _t = 0f;
     private int _i = 0;                                // keeps current index for recorder
     private int _j = 1;                                // keeps current index for follower
     private float _interval = 0f;
     // ### No these variables have another names (_record != _records). The _record keeps last recorded 'frame' this is reference to the _records array value at some index like: _records[i].
     private TargetRecord _record = null;            // current record
     private bool _recording = true;                    // stop recording if true
     private int _arraySize = 1;
     
     public void Start()
     {
         // ### As you can see here we have an Initialize method so _records array initialized inside. First some statements must be checked. You have reworked version of my script.
         Initialize();
     }
     
     public void Initialize()
     {
         if(targetPositionOnStart)
             transform.position = target.position;
         
         _interval = 1 / recordFPS;
         
         _arraySize = Mathf.CeilToInt(recordFPS * reactDelay);
         if(_arraySize == 0)
             _arraySize = 1;
         
         _records = new TargetRecord[_arraySize];
     }
     
     // update this transform data
     public void LateUpdate()
     {
         if(start)
         {
             // ### RecordData method add current position of target to the _records array.
             RecordData(Time.deltaTime);
             
             // move to the target
             if(targetDistance <= 0f)
             {
                 if(_record != null)
                     transform.position = Vector3.MoveTowards(transform.position, _record.position, Time.deltaTime * followSpeed);
             }
             else if((target.position - transform.position).magnitude > targetDistance)
             {
                 if(!_recording)
                 {
                     // ### resets whole _records array becouse we dont need to remember if follower is not moving. It must be cleared before next recording.
                     ResetRecordArray();
                     _recording = true;
                     // ### in next statements _recording can be false
                 }
                 
                 if(_record != null)
                     transform.position = Vector3.MoveTowards(transform.position, _record.position, Time.deltaTime * followSpeed);
             }
             else if(targetDistanceY && Mathf.Abs(target.position.y - transform.position.y) > 0.05f)
             {
                 // ### It check an _record reference if it is null (empty) then dont apply an position. Some kind of error protection.
                 if(_record != null)
                     transform.position = Vector3.Lerp(transform.position, new Vector3(transform.position.x, target.position.y, transform.position.z), Time.deltaTime * followSpeed);
             }
             else
             {
                 _recording = false;
             }
         }
     }
     
     private void RecordData(float deltaTime)
     {
         if(!_recording)
             return;            // ### return; is breaking the method in this place. Next lines of code in method will be skipped after this command.
         
         // check intervals
         if(_t < _interval)
         {
             _t += deltaTime;
         }
         // record this frame
         else
         {
             // ### here we make an new instance of the TargetRecord class. We are usung custom constructor from this class. Definition of this class is in line 22.
             // record target data
             _records[_i] = new TargetRecord(target.position);
 
             // 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];
             
             _t = 0f;
         }
     }
     
     // used if distance is small
     private void ResetRecordArray()
     {
         _i = 0;
         _j = 1;
         _t = 0f;
         
         _records = new TargetRecord[_arraySize];
         
         for(int i = 0; i < _records.Length; i++)
         {
             _records[i] = new TargetRecord(transform.position);
         }
         
         _record = _records[_j];
     }
 
     /// <summary>
     /// Gets the current record.
     /// </summary>
     public TargetRecord currentRecord 
     {
         get {
             return _record;
         }
     }
     
     #if UNITY_EDITOR
     public void OnDrawGizmos()
     {
         if(gizmo)
         {
             if(_records == null || _records.Length < 2)
                 return;
             
             Gizmos.color = Color.red;
             for(int i = 0; i < _i-1; i++)
             {
                 if(_records[i] != null && _records[i+1] != null)
                     Gizmos.DrawLine(_records[i].position, _records[i+1].position);
             }
             
             //Gizmos.color = Color.green;
             for(int j = _j; j < _records.Length-1; j++)
             {
                 if(_records[j] != null && _records[j+1] != null)
                     Gizmos.DrawLine(_records[j].position, _records[j+1].position);
             }
             
             //Gizmos.color = Color.yellow;
             if(_records[0] != null && _records[_records.Length-1] != null)
                 Gizmos.DrawLine(_records[0].position, _records[_records.Length-1].position);
             
             Gizmos.color = Color.white;
             if(_record != null)
                 Gizmos.DrawLine(_record.position, transform.position);
         }
     }
     
     #endif
 }
 
 
             
 
Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image z7x9r0 · Apr 09, 2016 at 07:44 PM 0
Share

Thanks again. I decided to look into buying a book that would walk through how to write and read C#, similar to a classroom. I got "Learning C# Program$$anonymous$$g with Unity 3D" by $$anonymous$$ Okita. Read 225 pages and now understand your script a lot better, and how to think about my scripts structure when writing.

I made some edits to your script to mold it into the result I am trying to create. I also renamed some variables to make it clearer for me to see where they are being used.

With the script you have provided, have you noticed that the array size deter$$anonymous$$es the distance the Helper is from the Player?

I know the frames per second (fps) can fluctuate depending on the specs of the hardware being used, or the amount of tasks being processed increasing or decreasing. I felt this might affect the Helpers distance from the Player while the game is running.

I'll post the most up-to-date script in the old Question link below to be dragged and dropped into a project. I'll also create a Sample Game Project folder to make faster to setup, but this will take a few hours. Going to make the Game Project as barebones as possible.

http://answers.unity3d.com/questions/1142547/2d-platformer-sidekick-helper-follower.html#comment-1144304

avatar image
1

Answer by lassade · Mar 24, 2016 at 08:49 PM

I use c# and unity for about 3 years now as far i know using scripting in c# is very similar to javascript, the most differences are in syntax of both languages. So you can just learn c#, most of learn for me is programing, the more you do the more you will learn.

Btw i learn most of c# and basic Object-Oriented (OO) concepts in the Microsoft S2B program. You should look at the OO to understand how c# works.

About the script here my best answers about your questions:

  • Line 12: [Serializable] is an attribute and tells to unity that this class can be saved into a xml format or other. This also allows the variable _records to be visible on inspector try to comment [Serializable] to see.

  • Line 16: public TargetRecord(Vector3 position) this is called a constructor this tells how this object will be created and what it needs as parameters to be build (in this case it need the position).

  • Line 18: this.position = position; the this.position is used to differentiate from the parameter position. So using this.position actually changes the world position field (line 15)

  • Line 26 and 35: _record array is created in the start function at line 35

For now i dont have more time.

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image z7x9r0 · Apr 09, 2016 at 08:04 PM 0
Share

Thanks for mentioning the $$anonymous$$icrosoft S2B program. I will look into it after I finish reading a book I got, "Learning C# Program$$anonymous$$g with Unity 3D" by $$anonymous$$ Okita.

The book covered OO to a point where I feel much more confident knowing what is happening and why. And thank you for covering a few questions I had. There was too much to cover and 225 pages later I finally was able to go back and understand exactly what is happening.

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

129 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

How to make character stop at wall? 1 Answer

I'm making a 2D mobile platformer and I just figured out how to make the mobile buttons work. But I can't get the jump limit to work. Does anyone know how to create maybe a ground detection with this script? 1 Answer

Way to have 2D Sprites lit by Lights? 3 Answers

Unity 2D Platformer Enemy follow Player on X-axis only, c# 1 Answer

Unity 2D Platfomer Enemy follow player only on x-axis, c# 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges